From 80bb0ebcc11fb9cb5904d490640408b3d7003a17 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 22 Jun 2026 12:59:16 -0400 Subject: [PATCH 001/481] pgcrypto: avoid recursive ResourceOwnerForget(). Raising an error within a function using an OSSLCipher object led to a complaint from ResourceOwnerForget and then a double-free crash, because ResOwnerReleaseOSSLCipher forgot to unhook the OSSLCipher object from its owner. (The sibling logic for OSSLDigest objects got this right, as did every other ReleaseResource function AFAICS.) Oversight in cd694f60d. Bug: #19527 Reported-by: Yuelin Wang <3020001251@tju.edu.cn> Author: Yuelin Wang <3020001251@tju.edu.cn> Reviewed-by: Tom Lane Discussion: https://postgr.es/m/19527-6e7686960c6dce78@postgresql.org Backpatch-through: 17 --- contrib/pgcrypto/openssl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c index d3c12e7fda3..c4ab2d6c714 100644 --- a/contrib/pgcrypto/openssl.c +++ b/contrib/pgcrypto/openssl.c @@ -832,7 +832,10 @@ px_find_cipher(const char *name, PX_Cipher **res) static void ResOwnerReleaseOSSLCipher(Datum res) { - free_openssl_cipher((OSSLCipher *) DatumGetPointer(res)); + OSSLCipher *cipher = (OSSLCipher *) DatumGetPointer(res); + + cipher->owner = NULL; + free_openssl_cipher(cipher); } /* From ef01ca6dbca54e9bf3abea01c357b346847ebcf3 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 22 Jun 2026 18:03:23 -0400 Subject: [PATCH 002/481] Fix unsafe order of operations in ResourceOwnerReleaseAll(). This function called the resource-kind-specific ReleaseResource() method for each item before deleting that item from the resowner. That's backwards from the ordering in ResourceOwnerReleaseAllOfKind, and it's not very safe. If ReleaseResource throws an error then the subsequent abort cleanup will come back here and try to release that item again, possibly leading to a double-free or similar crash, and in any case risking an infinite error cleanup loop. This mistake explains why the pgcrypto bug just fixed in 80bb0ebcc led to a crash rather than something more benign. Remove the item from the resowner, then call ReleaseResource, matching the way things were done before b8bff07da. If there is a problem of this sort, we'd prefer to leak the item than suffer the other likely consequences. Per further analysis of bug #19527. Author: Tom Lane Discussion: https://postgr.es/m/646741.1782157515@sss.pgh.pa.us Backpatch-through: 17 --- src/backend/utils/resowner/resowner.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c index 06e1121c5ff..03d2f5a0334 100644 --- a/src/backend/utils/resowner/resowner.c +++ b/src/backend/utils/resowner/resowner.c @@ -347,6 +347,7 @@ ResourceOwnerReleaseAll(ResourceOwner owner, ResourceReleasePhase phase, { ResourceElem *items; uint32 nitems; + bool using_arr; /* * ResourceOwnerSort must've been called already. All the resources are @@ -358,12 +359,14 @@ ResourceOwnerReleaseAll(ResourceOwner owner, ResourceReleasePhase phase, { items = owner->arr; nitems = owner->narr; + using_arr = true; } else { Assert(owner->narr == 0); items = owner->hash; nitems = owner->nhash; + using_arr = false; } /* @@ -392,13 +395,20 @@ ResourceOwnerReleaseAll(ResourceOwner owner, ResourceReleasePhase phase, elog(WARNING, "resource was not closed: %s", res_str); pfree(res_str); } - kind->ReleaseResource(value); + + /* + * Update stored count to forget the item before calling its + * ReleaseResource method. This avoids double-free crashes in case an + * error gets thrown within ReleaseResource. + */ nitems--; + if (using_arr) + owner->narr = nitems; + else + owner->nhash = nitems; + + kind->ReleaseResource(value); } - if (owner->nhash == 0) - owner->narr = nitems; - else - owner->nhash = nitems; } From f0a4f280b4d3cd16c368c524fe0c212643615f46 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 23 Jun 2026 08:20:11 +0900 Subject: [PATCH 003/481] doc: Update pg_dump/dumpall/upgrade about handling of external statistics The pages of pg_dump, pg_dumpall and pg_upgrade mentioned that their --no-statistics and --statistics options did not include the handling of statistics created by CREATE STATISTICS, which was wrong. Oversight in c32fb29e979d. Reported-by: Igi Izumi Discussion: https://postgr.es/m/19529-c7eb1e7a0b07eae6@postgresql.org --- doc/src/sgml/ref/pg_dump.sgml | 1 - doc/src/sgml/ref/pg_dumpall.sgml | 1 - doc/src/sgml/ref/pgupgrade.sgml | 3 +-- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..0e0d53926af 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -1703,7 +1703,6 @@ CREATE DATABASE foo WITH TEMPLATE template0; When is specified, pg_dump will include most optimizer statistics in the resulting dump file. This does not include all statistics, such as - those created explicitly with , custom statistics added by an extension, or statistics collected by the cumulative statistics system. Therefore, it may still be useful to run ANALYZE after restoring from a dump file to ensure diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml index 8834b7ec141..238c87c13f5 100644 --- a/doc/src/sgml/ref/pg_dumpall.sgml +++ b/doc/src/sgml/ref/pg_dumpall.sgml @@ -893,7 +893,6 @@ exclude database PATTERN When is specified, pg_dumpall will include most optimizer statistics in the resulting dump file. This does not include all statistics, such as - those created explicitly with , custom statistics added by an extension, or statistics collected by the cumulative statistics system. Therefore, it may still be useful to run ANALYZE on each database after restoring from a dump diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml index 38ca09b423c..cc44983a9a8 100644 --- a/doc/src/sgml/ref/pgupgrade.sgml +++ b/doc/src/sgml/ref/pgupgrade.sgml @@ -834,8 +834,7 @@ psql --username=postgres --file=script.sql postgres Unless the option is specified, pg_upgrade will transfer most optimizer statistics from the old cluster to the new cluster. This does not transfer - all statistics, such as those created explicitly with - , custom statistics added by + all statistics, such as custom statistics added by an extension, or statistics collected by the cumulative statistics system. From 2a7e95b659df2903420e27542e9127c50e8f2a17 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 23 Jun 2026 08:58:16 +0200 Subject: [PATCH 004/481] Readable identity strings for property graph objects The "identity" column of pg_identify_object() for property graph objects can be long string of names connected by "of", e.g. "a of l of e of g". The type of the first named object is given by column "type". But the types of intermediate objects are not easy to find from the identity string especially when some of them share the same name. Some objects, like user mappings or authorization identifier members, add types of objects other than the first one in the identity string. Do the same for property graph objects. Author: Ashutosh Bapat Reviewed-by: Michael Paquier Discussion: https://www.postgresql.org/message-id/flat/aej1DkLwhyZWmtxJ%40bdtpg --- src/backend/catalog/objectaddress.c | 10 ++-- .../expected/create_property_graph.out | 50 +++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index de3ab11dd34..af0e4703616 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -6172,7 +6172,7 @@ getObjectIdentityParts(const ObjectAddress *object, break; } pge = (Form_pg_propgraph_element) GETSTRUCT(tup); - appendStringInfo(&buffer, "%s of ", quote_identifier(NameStr(pge->pgealias))); + appendStringInfo(&buffer, "%s of property graph ", quote_identifier(NameStr(pge->pgealias))); getRelationIdentity(&buffer, pge->pgepgid, objname, false); if (objname) @@ -6196,7 +6196,7 @@ getObjectIdentityParts(const ObjectAddress *object, } pgl = (Form_pg_propgraph_label) GETSTRUCT(tup); - appendStringInfo(&buffer, "%s of ", quote_identifier(NameStr(pgl->pgllabel))); + appendStringInfo(&buffer, "%s of property graph ", quote_identifier(NameStr(pgl->pgllabel))); getRelationIdentity(&buffer, pgl->pglpgid, objname, false); if (objname) *objname = lappend(*objname, pstrdup(NameStr(pgl->pgllabel))); @@ -6218,7 +6218,7 @@ getObjectIdentityParts(const ObjectAddress *object, } pgp = (Form_pg_propgraph_property) GETSTRUCT(tup); - appendStringInfo(&buffer, "%s of ", quote_identifier(NameStr(pgp->pgpname))); + appendStringInfo(&buffer, "%s of property graph ", quote_identifier(NameStr(pgp->pgpname))); getRelationIdentity(&buffer, pgp->pgppgid, objname, false); if (objname) *objname = lappend(*objname, pstrdup(NameStr(pgp->pgpname))); @@ -6251,7 +6251,7 @@ getObjectIdentityParts(const ObjectAddress *object, pgelform = (Form_pg_propgraph_element_label) GETSTRUCT(tup); labelname = get_propgraph_label_name(pgelform->pgellabelid); - appendStringInfo(&buffer, "%s of ", quote_identifier(labelname)); + appendStringInfo(&buffer, "%s of element ", quote_identifier(labelname)); ObjectAddressSet(oa, PropgraphElementRelationId, pgelform->pgelelid); appendStringInfoString(&buffer, getObjectIdentityParts(&oa, objname, objargs, false)); @@ -6289,7 +6289,7 @@ getObjectIdentityParts(const ObjectAddress *object, plpform = (Form_pg_propgraph_label_property) GETSTRUCT(tup); propname = get_propgraph_property_name(plpform->plppropid); - appendStringInfo(&buffer, "%s of ", quote_identifier(propname)); + appendStringInfo(&buffer, "%s of label ", quote_identifier(propname)); ObjectAddressSet(oa, PropgraphElementLabelRelationId, plpform->plpellabelid); appendStringInfoString(&buffer, getObjectIdentityParts(&oa, objname, objargs, false)); diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out index 86c0957dcc7..2f06c7ce5a8 100644 --- a/src/test/regress/expected/create_property_graph.out +++ b/src/test/regress/expected/create_property_graph.out @@ -751,31 +751,31 @@ SELECT (pg_identify_object_as_address(classid, objid, objsubid)).* SELECT (pg_identify_object(classid, objid, objsubid)).* FROM (SELECT DISTINCT classid, objid, objsubid FROM deps_tree) ORDER BY 1, 2, 3, 4; - type | schema | name | identity --------------------------------+--------+------+------------------------------------------------- - property graph element | | | e of create_property_graph_tests.gt - property graph element | | | v1 of create_property_graph_tests.gt - property graph element | | | v2 of create_property_graph_tests.gt - property graph element label | | | e of e of create_property_graph_tests.gt - property graph element label | | | v1 of v1 of create_property_graph_tests.gt - property graph element label | | | v2 of v2 of create_property_graph_tests.gt - property graph label | | | e of create_property_graph_tests.gt - property graph label | | | v1 of create_property_graph_tests.gt - property graph label | | | v2 of create_property_graph_tests.gt - property graph label property | | | a of v1 of v1 of create_property_graph_tests.gt - property graph label property | | | b of v1 of v1 of create_property_graph_tests.gt - property graph label property | | | c of e of e of create_property_graph_tests.gt - property graph label property | | | k1 of e of e of create_property_graph_tests.gt - property graph label property | | | k2 of e of e of create_property_graph_tests.gt - property graph label property | | | m of v2 of v2 of create_property_graph_tests.gt - property graph label property | | | n of v2 of v2 of create_property_graph_tests.gt - property graph property | | | a of create_property_graph_tests.gt - property graph property | | | b of create_property_graph_tests.gt - property graph property | | | c of create_property_graph_tests.gt - property graph property | | | k1 of create_property_graph_tests.gt - property graph property | | | k2 of create_property_graph_tests.gt - property graph property | | | m of create_property_graph_tests.gt - property graph property | | | n of create_property_graph_tests.gt + type | schema | name | identity +-------------------------------+--------+------+------------------------------------------------------------------------------ + property graph element | | | e of property graph create_property_graph_tests.gt + property graph element | | | v1 of property graph create_property_graph_tests.gt + property graph element | | | v2 of property graph create_property_graph_tests.gt + property graph element label | | | e of element e of property graph create_property_graph_tests.gt + property graph element label | | | v1 of element v1 of property graph create_property_graph_tests.gt + property graph element label | | | v2 of element v2 of property graph create_property_graph_tests.gt + property graph label | | | e of property graph create_property_graph_tests.gt + property graph label | | | v1 of property graph create_property_graph_tests.gt + property graph label | | | v2 of property graph create_property_graph_tests.gt + property graph label property | | | a of label v1 of element v1 of property graph create_property_graph_tests.gt + property graph label property | | | b of label v1 of element v1 of property graph create_property_graph_tests.gt + property graph label property | | | c of label e of element e of property graph create_property_graph_tests.gt + property graph label property | | | k1 of label e of element e of property graph create_property_graph_tests.gt + property graph label property | | | k2 of label e of element e of property graph create_property_graph_tests.gt + property graph label property | | | m of label v2 of element v2 of property graph create_property_graph_tests.gt + property graph label property | | | n of label v2 of element v2 of property graph create_property_graph_tests.gt + property graph property | | | a of property graph create_property_graph_tests.gt + property graph property | | | b of property graph create_property_graph_tests.gt + property graph property | | | c of property graph create_property_graph_tests.gt + property graph property | | | k1 of property graph create_property_graph_tests.gt + property graph property | | | k2 of property graph create_property_graph_tests.gt + property graph property | | | m of property graph create_property_graph_tests.gt + property graph property | | | n of property graph create_property_graph_tests.gt (23 rows) \a\t From 56f2b0b5334df68b16964d4f9a0cbe9dae913227 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 23 Jun 2026 16:49:34 +0900 Subject: [PATCH 005/481] doc: Describe better handling of indexes in ALTER TABLE ATTACH PARTITION When ALTER TABLE ... ATTACH PARTITION matches partition indexes to the parent table's indexes, invalid indexes are skipped. This commit improves the documentation to describe what e90e9275f56 has changed: invalid indexes are skipped, and only valid indexes are considered for a match. Author: Mohamed Ali Reviewed-by: Sami Imseih Discussion: https://postgr.es/m/CAGnOmWpAMaE-BOkpwM6mJnHcpS2QZ8yLSSaqmz+vryEsbCWWWA@mail.gmail.com Backpatch-through: 14 --- doc/src/sgml/ref/alter_table.sgml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index dec34337d1a..4ca91f81d34 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -1054,10 +1054,11 @@ WITH ( MODULUS numeric_literal, REM as a partition of the target table. The table can be attached as a partition for specific values using FOR VALUES or as a default partition by using DEFAULT. - For each index in the target table, a corresponding - one will be created in the attached table; or, if an equivalent - index already exists, it will be attached to the target table's index, - as if ALTER INDEX ATTACH PARTITION had been executed. + For each index in the target table, if a valid equivalent index + already exists in the partition, it will be attached to the target + table's index, as if ALTER INDEX ATTACH PARTITION had been executed; + otherwise, a new corresponding index will be created. Invalid indexes + on the partition are skipped. Note that if the existing table is a foreign table, it is currently not allowed to attach the table as a partition of the target table if there are UNIQUE indexes on the target table. (See also From 049b742daad0965be4a846035408ae27ce1f9e14 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 23 Jun 2026 14:12:03 -0400 Subject: [PATCH 006/481] psql: Tighten heuristics for BEGIN/END within CREATE SCHEMA. Since d51697484, psql's scanner treats CREATE SCHEMA as a command that may contain SQL-standard routine bodies, so that semicolons inside BEGIN ATOMIC ... END blocks do not terminate the command too early. However, the code counted BEGIN/END throughout CREATE SCHEMA, so that it could be fooled by valid (and previously accepted) code such as CREATE SCHEMA s CREATE VIEW begin AS SELECT 1; Improve this by explicitly checking whether each CREATE sub-clause is CREATE [OR REPLACE] {FUNCTION|PROCEDURE}, and only counting BEGIN/END within those clauses. Since CREATE FUNCTION/PROCEDURE wasn't allowed in CREATE SCHEMA before d51697484, this will not risk failure on any cases that worked before v19. There remain cases that fool the top-level CREATE FUNCTION/PROCEDURE heuristic and thus also the CREATE SCHEMA case, for example CREATE FUNCTION begin () ... But that's been true all along with no field complaints, so we'll leave that issue for another day. In the name of keeping things readable, move the logic supporting this out of the {identifier} flex rule and into some small new subroutines. Also rename existing related PsqlScanState fields to help distinguish them from the added fields. This patch also fixes what seems to me (tgl) a small bug: \; would reset BEGIN/END detection even when inside parens or BEGIN. That's unlike what a plain semicolon would do, and no such effect is suggested by the documentation. Author: Chao Li Reviewed-by: Tom Lane Discussion: https://postgr.es/m/8E03BB8D-003D-4850-9772-5F8015A5A0C7@gmail.com --- src/fe_utils/psqlscan.l | 202 ++++++++++++++------ src/include/fe_utils/psqlscan_int.h | 7 +- src/test/regress/expected/create_schema.out | 11 +- src/test/regress/sql/create_schema.sql | 7 +- 4 files changed, 161 insertions(+), 66 deletions(-) diff --git a/src/fe_utils/psqlscan.l b/src/fe_utils/psqlscan.l index d29dda4d8e1..bbfafbc5223 100644 --- a/src/fe_utils/psqlscan.l +++ b/src/fe_utils/psqlscan.l @@ -61,6 +61,9 @@ typedef int YYSTYPE; #define ECHO psqlscan_emit(cur_state, yytext, yyleng) +static void psqlscan_track_identifier(PsqlScanState state, + const char *identifier); + %} %option reentrant @@ -677,11 +680,12 @@ other . ";" { ECHO; - if (cur_state->paren_depth == 0 && cur_state->begin_depth == 0) + if (cur_state->paren_depth == 0 && + cur_state->begin_depth == 0) { /* Terminate lexing temporarily */ cur_state->start_state = YY_START; - cur_state->identifier_count = 0; + cur_state->init_idents_count = 0; return LEXRES_SEMI; } } @@ -694,8 +698,11 @@ other . "\\"[;:] { /* Force a semi-colon or colon into the query buffer */ psqlscan_emit(cur_state, yytext + 1, 1); - if (yytext[1] == ';') - cur_state->identifier_count = 0; + /* Reset BEGIN/END tracking if semi at outer level */ + if (yytext[1] == ';' && + cur_state->paren_depth == 0 && + cur_state->begin_depth == 0) + cur_state->init_idents_count = 0; } "\\" { @@ -921,61 +928,7 @@ other . {identifier} { - /* - * We need to track if we are inside a BEGIN .. END block - * in a function definition, so that semicolons contained - * therein don't terminate the whole statement. Short of - * writing a full parser here, the following heuristic - * should work. First, we track whether the beginning of - * the statement matches CREATE [OR REPLACE] - * {FUNCTION|PROCEDURE|SCHEMA}. (Allowing this in - * CREATE SCHEMA, without tracking whether we're within a - * CREATE FUNCTION/PROCEDURE subcommand, is a bit shaky - * but should be okay with the present set of valid - * subcommands.) - */ - - if (cur_state->identifier_count == 0) - memset(cur_state->identifiers, 0, sizeof(cur_state->identifiers)); - - if (cur_state->identifier_count < sizeof(cur_state->identifiers)) - { - if (pg_strcasecmp(yytext, "create") == 0 || - pg_strcasecmp(yytext, "function") == 0 || - pg_strcasecmp(yytext, "procedure") == 0 || - pg_strcasecmp(yytext, "or") == 0 || - pg_strcasecmp(yytext, "replace") == 0 || - pg_strcasecmp(yytext, "schema") == 0) - cur_state->identifiers[cur_state->identifier_count] = pg_tolower((unsigned char) yytext[0]); - } - - cur_state->identifier_count++; - - if (cur_state->identifiers[0] == 'c' && - (cur_state->identifiers[1] == 'f' || cur_state->identifiers[1] == 'p' || - (cur_state->identifiers[1] == 'o' && cur_state->identifiers[2] == 'r' && - (cur_state->identifiers[3] == 'f' || cur_state->identifiers[3] == 'p')) || - cur_state->identifiers[1] == 's') && - cur_state->paren_depth == 0) - { - if (pg_strcasecmp(yytext, "begin") == 0) - cur_state->begin_depth++; - else if (pg_strcasecmp(yytext, "case") == 0) - { - /* - * CASE also ends with END. We only need to track - * this if we are already inside a BEGIN. - */ - if (cur_state->begin_depth >= 1) - cur_state->begin_depth++; - } - else if (pg_strcasecmp(yytext, "end") == 0) - { - if (cur_state->begin_depth > 0) - cur_state->begin_depth--; - } - } - + psqlscan_track_identifier(cur_state, yytext); ECHO; } @@ -1002,6 +955,135 @@ other . /* LCOV_EXCL_STOP */ +/* + * Record the first few keywords/identifiers of a statement or CREATE + * SCHEMA sub-statement in the idents[] array, of length idents_size. + * *idents_count is the number of entries filled so far. + * + * We record the interesting keywords using their first character, which + * works so long as those are all different. We could switch to an enum + * if that stops being true, but for now this is easy and compact. + */ +static void +psqlscan_record_initial_keyword(const char *identifier, + char *idents, + int idents_size, + int *idents_count) +{ + if (*idents_count < idents_size) + { + /* + * What we need to recognize is CREATE [OR REPLACE] FUNCTION/PROCEDURE + * and CREATE SCHEMA. Checking for SCHEMA is useless but not harmful + * in the CREATE SCHEMA sub-statement case. + */ + if (pg_strcasecmp(identifier, "create") == 0 || + pg_strcasecmp(identifier, "function") == 0 || + pg_strcasecmp(identifier, "procedure") == 0 || + pg_strcasecmp(identifier, "or") == 0 || + pg_strcasecmp(identifier, "replace") == 0 || + pg_strcasecmp(identifier, "schema") == 0) + idents[*idents_count] = pg_tolower((unsigned char) identifier[0]); + /* For other keywords or identifiers, leave '\0' in the array entry */ + (*idents_count)++; + } +} + +/* + * Does the current input match CREATE [OR REPLACE] {FUNCTION|PROCEDURE}? + */ +static bool +psqlscan_is_create_routine(const char *idents) +{ + return idents[0] == 'c' && + (idents[1] == 'f' || idents[1] == 'p' || + (idents[1] == 'o' && idents[2] == 'r' && + (idents[3] == 'f' || idents[3] == 'p'))); +} + +/* + * Track whether we are inside a BEGIN .. END block in a function definition, + * so that semicolons contained therein don't terminate the whole statement. + * Short of writing a full parser here, the following heuristic should work. + * + * We track whether the beginning of the statement matches CREATE [OR REPLACE] + * {FUNCTION|PROCEDURE}. For CREATE SCHEMA, track BEGIN .. END blocks only + * after recognizing an embedded CREATE [OR REPLACE] {FUNCTION|PROCEDURE} + * subcommand. Once one of these conditions holds, count BEGIN and END + * pairs. We also have to account for CASE ... END. + */ +static void +psqlscan_track_identifier(PsqlScanState state, const char *identifier) +{ + bool is_create_schema; + + /* None of this needs to happen when we're inside parentheses */ + if (state->paren_depth != 0) + return; + + /* Reset all my state at the start of each new statement */ + if (state->init_idents_count == 0) + { + memset(state->init_idents, 0, sizeof(state->init_idents)); + state->sub_idents_count = 0; + memset(state->sub_idents, 0, sizeof(state->sub_idents)); + } + + /* Record initial keywords if init_idents_count is small enough */ + psqlscan_record_initial_keyword(identifier, + state->init_idents, + lengthof(state->init_idents), + &state->init_idents_count); + + /* + * In CREATE SCHEMA, track identifiers from each top-level CREATE schema + * element separately, so that BEGIN/END tracking is enabled only within + * CREATE [OR REPLACE] {FUNCTION|PROCEDURE} clauses. + */ + is_create_schema = (state->init_idents[0] == 'c' && + state->init_idents[1] == 's'); + if (is_create_schema && + state->begin_depth == 0) + { + /* Reset sub-clause state at each top-level CREATE keyword */ + if (pg_strcasecmp(identifier, "create") == 0) + { + state->sub_idents_count = 0; + memset(state->sub_idents, 0, sizeof(state->sub_idents)); + } + /* ... and record the first few keywords following that */ + psqlscan_record_initial_keyword(identifier, + state->sub_idents, + lengthof(state->sub_idents), + &state->sub_idents_count); + } + + /* + * Track BEGIN/CASE/END only when within an appropriate (sub) statement. + */ + if (psqlscan_is_create_routine(state->init_idents) || + (is_create_schema && + psqlscan_is_create_routine(state->sub_idents))) + { + if (pg_strcasecmp(identifier, "begin") == 0) + state->begin_depth++; + else if (pg_strcasecmp(identifier, "case") == 0) + { + /* + * CASE also ends with END. We only need to track this if we are + * already inside a BEGIN. + */ + if (state->begin_depth >= 1) + state->begin_depth++; + } + else if (pg_strcasecmp(identifier, "end") == 0) + { + if (state->begin_depth > 0) + state->begin_depth--; + } + } +} + /* * Create a lexer working state struct. * @@ -1292,8 +1374,8 @@ psql_scan_reset(PsqlScanState state) if (state->dolqstart) free(state->dolqstart); state->dolqstart = NULL; - state->identifier_count = 0; state->begin_depth = 0; + state->init_idents_count = 0; } /* diff --git a/src/include/fe_utils/psqlscan_int.h b/src/include/fe_utils/psqlscan_int.h index 488f416f0e5..8b0d153261b 100644 --- a/src/include/fe_utils/psqlscan_int.h +++ b/src/include/fe_utils/psqlscan_int.h @@ -117,9 +117,12 @@ typedef struct PsqlScanStateData * State to track boundaries of BEGIN ... END blocks in function * definitions, so that semicolons do not send query too early. */ - int identifier_count; /* identifiers since start of statement */ - char identifiers[4]; /* records the first few identifiers */ int begin_depth; /* depth of begin/end pairs */ + int init_idents_count; /* # identifiers since start of statement */ + char init_idents[4]; /* records the first few identifiers */ + int sub_idents_count; /* # identifiers since start of a CREATE + * SCHEMA element */ + char sub_idents[4]; /* records the first few of those identifiers */ /* * Callback functions provided by the program making use of the lexer, diff --git a/src/test/regress/expected/create_schema.out b/src/test/regress/expected/create_schema.out index bfe211338ab..b9ae4c402fd 100644 --- a/src/test/regress/expected/create_schema.out +++ b/src/test/regress/expected/create_schema.out @@ -195,7 +195,11 @@ CREATE SCHEMA regress_schema_misc as 'select $1 + $2' CREATE OPERATOR + (function = cs_add, leftarg = int4, rightarg = int4) CREATE PROCEDURE cs_proc(int4, int4) - BEGIN ATOMIC SELECT cs_add($1,$2); END + BEGIN ATOMIC + SELECT cs_add($1,$2); + END + -- this checks that psql is not fooled by an irrelevant BEGIN + CREATE VIEW begin AS SELECT 1 AS one CREATE TEXT SEARCH CONFIGURATION cs_ts_conf (copy=english) CREATE TEXT SEARCH DICTIONARY cs_ts_dict (template=simple) CREATE TEXT SEARCH PARSER cs_ts_prs @@ -222,7 +226,7 @@ CREATE SCHEMA regress_schema_misc ; NOTICE: return type cs_type is only a shell NOTICE: argument type cs_type is only a shell -LINE 29: CREATE FUNCTION cs_type_out(cs_type) +LINE 33: CREATE FUNCTION cs_type_out(cs_type) ^ \df regress_schema_misc.cs_add List of functions @@ -300,13 +304,14 @@ LINE 29: CREATE FUNCTION cs_type_out(cs_type) (1 row) DROP SCHEMA regress_schema_misc CASCADE; -NOTICE: drop cascades to 16 other objects +NOTICE: drop cascades to 17 other objects DETAIL: drop cascades to function regress_schema_misc.cs_sum(integer) drop cascades to collation regress_schema_misc.cs_builtin_c drop cascades to type regress_schema_misc.cs_positive drop cascades to function regress_schema_misc.cs_add(integer,integer) drop cascades to operator regress_schema_misc.+(integer,integer) drop cascades to function regress_schema_misc.cs_proc(integer,integer) +drop cascades to view regress_schema_misc.begin drop cascades to text search configuration regress_schema_misc.cs_ts_conf drop cascades to text search dictionary regress_schema_misc.cs_ts_dict drop cascades to text search parser regress_schema_misc.cs_ts_prs diff --git a/src/test/regress/sql/create_schema.sql b/src/test/regress/sql/create_schema.sql index ebe05d5110e..526bb3cb065 100644 --- a/src/test/regress/sql/create_schema.sql +++ b/src/test/regress/sql/create_schema.sql @@ -120,7 +120,12 @@ CREATE SCHEMA regress_schema_misc CREATE OPERATOR + (function = cs_add, leftarg = int4, rightarg = int4) CREATE PROCEDURE cs_proc(int4, int4) - BEGIN ATOMIC SELECT cs_add($1,$2); END + BEGIN ATOMIC + SELECT cs_add($1,$2); + END + + -- this checks that psql is not fooled by an irrelevant BEGIN + CREATE VIEW begin AS SELECT 1 AS one CREATE TEXT SEARCH CONFIGURATION cs_ts_conf (copy=english) From 2af70e9374789913c4d474e6fce2e69d7060202e Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 23 Jun 2026 15:06:34 -0400 Subject: [PATCH 007/481] Fix incorrect declarations of variadic pg_get_*_ddl() functions. The final parameter of an ordinary variadic function should be an array type. CREATE FUNCTION won't accept a declaration that isn't like that, but it's possible to put an incorrect combination into a pg_proc.dat entry. Sadly, the opr_sanity test that was supposed to check that is broken and does not report functions with non-array final parameters. This allowed exactly such a thinko to sneak into the recently-added pg_get_*_ddl() functions: their last argument should be declared text[] but was declared text. (We'd probably have noticed eventually, when somebody tried to actually pass a variadic array to one of those functions. But their regression tests do not do that.) Fix those functions, and fix the opr_sanity test so we'll notice next time. Bump catversion for new pg_proc contents. Author: Chao Li Reviewed-by: Tom Lane Discussion: https://postgr.es/m/D41A334E-ED9E-42EE-830D-28D4D36E9317@gmail.com --- doc/src/sgml/func/func-info.sgml | 8 ++++---- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 14 +++++++------- src/test/regress/expected/opr_sanity.out | 2 +- src/test/regress/sql/opr_sanity.sql | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml index 8ffa7e83275..34f4019690f 100644 --- a/doc/src/sgml/func/func-info.sgml +++ b/doc/src/sgml/func/func-info.sgml @@ -3882,7 +3882,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} pg_get_role_ddl ( role regrole , VARIADIC options - text ) + text[] ) setof text @@ -3904,14 +3904,14 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} pg_get_tablespace_ddl ( tablespace oid , VARIADIC options - text ) + text[] ) setof text pg_get_tablespace_ddl ( tablespace name , VARIADIC options - text ) + text[] ) setof text @@ -3932,7 +3932,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} pg_get_database_ddl ( database regdatabase , VARIADIC options - text ) + text[] ) setof text diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index c4e94a3a09e..fba78c20733 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202606091 +#define CATALOG_VERSION_NO 202606231 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index be157a5fbe9..fa76c7923f0 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -8593,26 +8593,26 @@ { oid => '6501', descr => 'get DDL to recreate a role', proname => 'pg_get_role_ddl', prorows => '10', provariadic => 'text', proisstrict => 'f', proretset => 't', provolatile => 's', - pronargdefaults => '1', prorettype => 'text', proargtypes => 'regrole text', - proallargtypes => '{regrole,text}', proargmodes => '{i,v}', + pronargdefaults => '1', prorettype => 'text', proargtypes => 'regrole _text', + proallargtypes => '{regrole,_text}', proargmodes => '{i,v}', proargdefaults => '{NULL}', prosrc => 'pg_get_role_ddl' }, { oid => '6499', descr => 'get DDL to recreate a tablespace', proname => 'pg_get_tablespace_ddl', prorows => '10', provariadic => 'text', proisstrict => 'f', proretset => 't', provolatile => 's', - pronargdefaults => '1', prorettype => 'text', proargtypes => 'oid text', - proallargtypes => '{oid,text}', proargmodes => '{i,v}', + pronargdefaults => '1', prorettype => 'text', proargtypes => 'oid _text', + proallargtypes => '{oid,_text}', proargmodes => '{i,v}', proargdefaults => '{NULL}', prosrc => 'pg_get_tablespace_ddl_oid' }, { oid => '6500', descr => 'get DDL to recreate a tablespace', proname => 'pg_get_tablespace_ddl', prorows => '10', provariadic => 'text', proisstrict => 'f', proretset => 't', provolatile => 's', - pronargdefaults => '1', prorettype => 'text', proargtypes => 'name text', - proallargtypes => '{name,text}', proargmodes => '{i,v}', + pronargdefaults => '1', prorettype => 'text', proargtypes => 'name _text', + proallargtypes => '{name,_text}', proargmodes => '{i,v}', proargdefaults => '{NULL}', prosrc => 'pg_get_tablespace_ddl_name' }, { oid => '6502', descr => 'get DDL to recreate a database', proname => 'pg_get_database_ddl', prorows => '10', provariadic => 'text', proisstrict => 'f', proretset => 't', provolatile => 's', pronargdefaults => '1', prorettype => 'text', - proargtypes => 'regdatabase text', proallargtypes => '{regdatabase,text}', + proargtypes => 'regdatabase _text', proallargtypes => '{regdatabase,_text}', proargmodes => '{i,v}', proargdefaults => '{NULL}', prosrc => 'pg_get_database_ddl' }, { oid => '2509', diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index cfdc6b1a17a..80400a33734 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -487,7 +487,7 @@ AND case proargtypes[array_length(proargtypes, 1)-1] ELSE (SELECT t.oid FROM pg_type t WHERE t.typarray = proargtypes[array_length(proargtypes, 1)-1]) - END != provariadic; + END IS DISTINCT FROM provariadic; oid | provariadic | proargtypes -----+-------------+------------- (0 rows) diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql index cd674d7dbca..5670bb14193 100644 --- a/src/test/regress/sql/opr_sanity.sql +++ b/src/test/regress/sql/opr_sanity.sql @@ -360,7 +360,7 @@ AND case proargtypes[array_length(proargtypes, 1)-1] ELSE (SELECT t.oid FROM pg_type t WHERE t.typarray = proargtypes[array_length(proargtypes, 1)-1]) - END != provariadic; + END IS DISTINCT FROM provariadic; -- Check that all and only those functions with a variadic type have -- a variadic argument. From 4cc02b80774ecdc4cf2a2d5df09c07df36d68ca5 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Tue, 23 Jun 2026 12:06:33 -0700 Subject: [PATCH 008/481] Nail pg_parameter_acl in relcache. Previously, a parameter specified in the startup packet for a physical replication connection could encounter an error trying to perform an ACL check for the setting. Problem was introduced in a0ffa885e4, but no reasonable back-patchable solution was found, so fixing only in master. Bumps catversion. Discussion: https://postgr.es/m/d8f8e11f06d692fff89e6be0f22732d30cf695a0.camel%40j-davis.com Reviewed-by: John Naylor Reviewed-by: Mark Dilger --- src/backend/utils/cache/catcache.c | 2 ++ src/backend/utils/cache/relcache.c | 19 ++++++++++++++----- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_parameter_acl.h | 2 +- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index a8e7bf649d2..6fb35dedf95 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -1335,6 +1335,8 @@ IndexScanOK(CatCache *cache) case AUTHOID: case AUTHMEMMEMROLE: case DATABASEOID: + case PARAMETERACLNAME: + case PARAMETERACLOID: /* * Protect authentication lookups occurring before relcache has diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 0572ab424e7..fb4e042be8a 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -56,6 +56,7 @@ #include "catalog/pg_proc.h" #include "catalog/pg_publication.h" #include "catalog/pg_rewrite.h" +#include "catalog/pg_parameter_acl.h" #include "catalog/pg_shseclabel.h" #include "catalog/pg_statistic_ext.h" #include "catalog/pg_subscription.h" @@ -120,6 +121,7 @@ static const FormData_pg_attribute Desc_pg_auth_members[Natts_pg_auth_members] = static const FormData_pg_attribute Desc_pg_index[Natts_pg_index] = {Schema_pg_index}; static const FormData_pg_attribute Desc_pg_shseclabel[Natts_pg_shseclabel] = {Schema_pg_shseclabel}; static const FormData_pg_attribute Desc_pg_subscription[Natts_pg_subscription] = {Schema_pg_subscription}; +static const FormData_pg_attribute Desc_pg_parameter_acl[Natts_pg_parameter_acl] = {Schema_pg_parameter_acl}; /* * Hash tables that index the relation cache @@ -4084,8 +4086,10 @@ RelationCacheInitializePhase2(void) Natts_pg_shseclabel, Desc_pg_shseclabel); formrdesc("pg_subscription", SubscriptionRelation_Rowtype_Id, true, Natts_pg_subscription, Desc_pg_subscription); + formrdesc("pg_parameter_acl", ParameterAclRelation_Rowtype_Id, true, + Natts_pg_parameter_acl, Desc_pg_parameter_acl); -#define NUM_CRITICAL_SHARED_RELS 5 /* fix if you change list above */ +#define NUM_CRITICAL_SHARED_RELS 6 /* fix if you change list above */ } MemoryContextSwitchTo(oldcxt); @@ -4206,9 +4210,10 @@ RelationCacheInitializePhase3(void) * non-shared catalogs at all. Autovacuum calls InitPostgres with a * database OID, so it instead depends on DatabaseOidIndexId. We also * need to nail up some indexes on pg_authid and pg_auth_members for use - * during client authentication. SharedSecLabelObjectIndexId isn't - * critical for the core system, but authentication hooks might be - * interested in it. + * during client authentication. We need indexes on pg_parameter_acl for + * ACL checks on settings specified in the startup packet for a physical + * replication connection. SharedSecLabelObjectIndexId isn't critical for + * the core system, but authentication hooks might be interested in it. */ if (!criticalSharedRelcachesBuilt) { @@ -4224,8 +4229,12 @@ RelationCacheInitializePhase3(void) AuthMemRelationId); load_critical_index(SharedSecLabelObjectIndexId, SharedSecLabelRelationId); + load_critical_index(ParameterAclParnameIndexId, + ParameterAclRelationId); + load_critical_index(ParameterAclOidIndexId, + ParameterAclRelationId); -#define NUM_CRITICAL_SHARED_INDEXES 6 /* fix if you change list above */ +#define NUM_CRITICAL_SHARED_INDEXES 8 /* fix if you change list above */ criticalSharedRelcachesBuilt = true; } diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index fba78c20733..04eb2af2ac8 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202606231 +#define CATALOG_VERSION_NO 202606232 #endif diff --git a/src/include/catalog/pg_parameter_acl.h b/src/include/catalog/pg_parameter_acl.h index a26b05a9bf2..902e2666069 100644 --- a/src/include/catalog/pg_parameter_acl.h +++ b/src/include/catalog/pg_parameter_acl.h @@ -29,7 +29,7 @@ */ BEGIN_CATALOG_STRUCT -CATALOG(pg_parameter_acl,6243,ParameterAclRelationId) BKI_SHARED_RELATION +CATALOG(pg_parameter_acl,6243,ParameterAclRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2173,ParameterAclRelation_Rowtype_Id) BKI_SCHEMA_MACRO { Oid oid; /* oid */ From b43f8aa4cb302c3f74fd1ed611e3548d4e03dce1 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Tue, 23 Jun 2026 21:07:13 +0900 Subject: [PATCH 009/481] Re-index ModifyTable FDW arrays when pruning result relations ExecInitModifyTable() rebuilds the per-result-relation lists after dropping result relations removed by initial runtime pruning. The re-indexing was done for withCheckOptionLists, returningLists, updateColnosLists, mergeActionLists and mergeJoinConditions, but fdwPrivLists and fdwDirectModifyPlans were missed. As a result, a kept foreign result relation could be handed the wrong fdw_private, or ri_usesFdwDirectModify could be set from the wrong plan index, leading to wrong behavior or a crash in BeginForeignModify() and in the direct-modify path. show_modifytable_info() had the same problem: it indexed the plan-ordered node->fdwPrivLists with the post-pruning executor position, so once initial pruning removed a result relation it could read a different relation's fdw_private (often a NIL entry), producing wrong EXPLAIN output or a crash. Fix by re-indexing fdwPrivLists and fdwDirectModifyPlans alongside the other lists, saving the re-indexed private lists in ModifyTableState.mt_fdwPrivLists and reading from there in both nodeModifyTable.c and explain.c. Reported-by: Chi Zhang <798604270@qq.com> Author: Ayush Tiwari Author: Rafia Sabih Reviewed-by: Matheus Alcantara Reviewed-by: Etsuro Fujita Discussion: https://postgr.es/m/19484-a3cb82c8cde3c8fa%40postgresql.org Backpatch-through: 18 --- .../postgres_fdw/expected/postgres_fdw.out | 64 +++++++++++++++++++ contrib/postgres_fdw/sql/postgres_fdw.sql | 34 ++++++++++ src/backend/commands/explain.c | 2 +- src/backend/executor/nodeModifyTable.c | 22 ++++++- src/include/nodes/execnodes.h | 8 ++- 5 files changed, 124 insertions(+), 6 deletions(-) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index e90289e4ab1..13853b8b720 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -7197,6 +7197,70 @@ RESET enable_material; DROP FOREIGN TABLE remt2; DROP TABLE loct1; DROP TABLE loct2; +-- Test that direct modify and foreign modify work with runtime pruning of +-- result relations (bug #19484) +create table fdw_part_update (a int not null, b int) partition by list (a); +create table fdw_part_update_p1 partition of fdw_part_update for values in (1); +create table fdw_part_update_remote (a int not null, b int); +create foreign table fdw_part_update_p2 partition of fdw_part_update + for values in (2) + server loopback options (table_name 'fdw_part_update_remote'); +insert into fdw_part_update_p1 values (1, 10); +insert into fdw_part_update_remote values (2, 20); +set plan_cache_mode = force_generic_plan; +-- Check DirectModify case +prepare fdw_part_upd(int) as + update fdw_part_update set b = b + 1 where a = $1 + returning tableoid::regclass, a, b; +explain (verbose, costs off) + execute fdw_part_upd(2); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Update on public.fdw_part_update + Output: (fdw_part_update_1.tableoid)::regclass, fdw_part_update_1.a, fdw_part_update_1.b + Foreign Update on public.fdw_part_update_p2 fdw_part_update_2 + -> Append + Subplans Removed: 1 + -> Foreign Update on public.fdw_part_update_p2 fdw_part_update_2 + Remote SQL: UPDATE public.fdw_part_update_remote SET b = (b + 1) WHERE ((a = $1::integer)) RETURNING a, b +(7 rows) + +execute fdw_part_upd(2); + tableoid | a | b +--------------------+---+---- + fdw_part_update_p2 | 2 | 21 +(1 row) + +deallocate fdw_part_upd; +-- Check ForeignModify case +prepare fdw_part_upd2(int) as + update fdw_part_update set b = b + random()::int * 0 + 1 where a = $1 + returning tableoid::regclass, a, b; +explain (verbose, costs off) + execute fdw_part_upd2(2); + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------- + Update on public.fdw_part_update + Output: (fdw_part_update_1.tableoid)::regclass, fdw_part_update_1.a, fdw_part_update_1.b + Foreign Update on public.fdw_part_update_p2 fdw_part_update_2 + Remote SQL: UPDATE public.fdw_part_update_remote SET b = $2 WHERE ctid = $1 RETURNING a, b + -> Append + Subplans Removed: 1 + -> Foreign Scan on public.fdw_part_update_p2 fdw_part_update_2 + Output: ((fdw_part_update_2.b + ((random())::integer * 0)) + 1), fdw_part_update_2.tableoid, fdw_part_update_2.ctid, fdw_part_update_2.* + Remote SQL: SELECT a, b, ctid FROM public.fdw_part_update_remote WHERE ((a = $1::integer)) FOR UPDATE +(9 rows) + +execute fdw_part_upd2(2); + tableoid | a | b +--------------------+---+---- + fdw_part_update_p2 | 2 | 22 +(1 row) + +deallocate fdw_part_upd2; +reset plan_cache_mode; +drop table fdw_part_update; +drop table fdw_part_update_remote; -- =================================================================== -- test check constraints -- =================================================================== diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index dfc58beb0d2..697c4a92e2d 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -1778,6 +1778,40 @@ DROP FOREIGN TABLE remt2; DROP TABLE loct1; DROP TABLE loct2; +-- Test that direct modify and foreign modify work with runtime pruning of +-- result relations (bug #19484) +create table fdw_part_update (a int not null, b int) partition by list (a); +create table fdw_part_update_p1 partition of fdw_part_update for values in (1); +create table fdw_part_update_remote (a int not null, b int); +create foreign table fdw_part_update_p2 partition of fdw_part_update + for values in (2) + server loopback options (table_name 'fdw_part_update_remote'); +insert into fdw_part_update_p1 values (1, 10); +insert into fdw_part_update_remote values (2, 20); +set plan_cache_mode = force_generic_plan; + +-- Check DirectModify case +prepare fdw_part_upd(int) as + update fdw_part_update set b = b + 1 where a = $1 + returning tableoid::regclass, a, b; +explain (verbose, costs off) + execute fdw_part_upd(2); +execute fdw_part_upd(2); +deallocate fdw_part_upd; + +-- Check ForeignModify case +prepare fdw_part_upd2(int) as + update fdw_part_update set b = b + random()::int * 0 + 1 where a = $1 + returning tableoid::regclass, a, b; +explain (verbose, costs off) + execute fdw_part_upd2(2); +execute fdw_part_upd2(2); +deallocate fdw_part_upd2; + +reset plan_cache_mode; +drop table fdw_part_update; +drop table fdw_part_update_remote; + -- =================================================================== -- test check constraints -- =================================================================== diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 112c17b0d64..a40d03d35f3 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -4821,7 +4821,7 @@ show_modifytable_info(ModifyTableState *mtstate, List *ancestors, fdwroutine != NULL && fdwroutine->ExplainForeignModify != NULL) { - List *fdw_private = (List *) list_nth(node->fdwPrivLists, j); + List *fdw_private = (List *) list_nth(mtstate->mt_fdwPrivLists, j); fdwroutine->ExplainForeignModify(mtstate, resultRelInfo, diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 33a6735f08d..846dc516b43 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -5108,6 +5108,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) List *updateColnosLists = NIL; List *mergeActionLists = NIL; List *mergeJoinConditions = NIL; + List *fdwPrivLists = NIL; + Bitmapset *fdwDirectModifyPlans = NULL; ResultRelInfo *resultRelInfo; List *arowmarks; ListCell *l; @@ -5150,6 +5152,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) if (keep_rel) { + List *fdwPrivList = (List *) list_nth(node->fdwPrivLists, i); + resultRelations = lappend_int(resultRelations, rti); if (node->withCheckOptionLists) { @@ -5185,6 +5189,19 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) mergeJoinConditions = lappend(mergeJoinConditions, mergeJoinCondition); } + + /* + * fdwPrivLists/fdwDirectModifyPlans are re-indexed to match + * resultRelations + */ + fdwPrivLists = lappend(fdwPrivLists, fdwPrivList); + if (bms_is_member(i, node->fdwDirectModifyPlans)) + { + int new_index = list_length(resultRelations) - 1; + + fdwDirectModifyPlans = bms_add_member(fdwDirectModifyPlans, + new_index); + } } i++; } @@ -5213,6 +5230,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) mtstate->mt_updateColnosLists = updateColnosLists; mtstate->mt_mergeActionLists = mergeActionLists; mtstate->mt_mergeJoinConditions = mergeJoinConditions; + mtstate->mt_fdwPrivLists = fdwPrivLists; /*---------- * Resolve the target relation. This is the same as: @@ -5288,7 +5306,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) /* Initialize the usesFdwDirectModify flag */ resultRelInfo->ri_usesFdwDirectModify = - bms_is_member(i, node->fdwDirectModifyPlans); + bms_is_member(i, fdwDirectModifyPlans); /* * Verify result relation is a valid target for the current operation @@ -5317,7 +5335,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) resultRelInfo->ri_FdwRoutine != NULL && resultRelInfo->ri_FdwRoutine->BeginForeignModify != NULL) { - List *fdw_private = (List *) list_nth(node->fdwPrivLists, i); + List *fdw_private = (List *) list_nth(fdwPrivLists, i); resultRelInfo->ri_FdwRoutine->BeginForeignModify(mtstate, resultRelInfo, diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 53c138310db..e64fd8c7ea3 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -1502,13 +1502,15 @@ typedef struct ModifyTableState double mt_merge_deleted; /* - * Lists of valid updateColnosLists, mergeActionLists, and - * mergeJoinConditions. These contain only entries for unpruned - * relations, filtered from the corresponding lists in ModifyTable. + * Lists of valid updateColnosLists, mergeActionLists, + * mergeJoinConditions, and fdwPrivLists. These contain only entries for + * unpruned relations, filtered from the corresponding lists in + * ModifyTable. */ List *mt_updateColnosLists; List *mt_mergeActionLists; List *mt_mergeJoinConditions; + List *mt_fdwPrivLists; } ModifyTableState; /* ---------------- From 4015abe14bb05f67d2c47549f59c5d382e57150b Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Wed, 24 Jun 2026 09:09:48 +0900 Subject: [PATCH 010/481] plperl: Fix NULL pointer dereference for forged array object In get_perl_array_ref(), for a PostgreSQL::InServer::ARRAY object, we look up its "array" key with hv_fetch_string() and then inspect the returned SV. However, hv_fetch_string() returns a NULL pointer when the key is absent, and the code dereferenced that result without first checking whether the pointer itself was NULL. As a result, a plperl function returning a forged PostgreSQL::InServer::ARRAY object that lacks the "array" key would crash the backend with a segmentation fault. Fix this by checking the pointer returned by hv_fetch_string() before dereferencing it, matching how other callers in this file already guard the result. With the check in place, such an object falls through to the existing error report instead of crashing. Author: Xing Guo Reviewed-by: Richard Guo Discussion: https://postgr.es/m/CACpMh+DYgcnqZwQLXXuxQcehJTd7T8UmKWSLsK4mFBEp9G2ajA@mail.gmail.com Backpatch-through: 14 --- src/pl/plperl/expected/plperl_array.out | 7 +++++++ src/pl/plperl/plperl.c | 2 +- src/pl/plperl/sql/plperl_array.sql | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/pl/plperl/expected/plperl_array.out b/src/pl/plperl/expected/plperl_array.out index 260a55ea7e9..f5803e10a6e 100644 --- a/src/pl/plperl/expected/plperl_array.out +++ b/src/pl/plperl/expected/plperl_array.out @@ -274,3 +274,10 @@ select perl_setof_array('{{1}, {2}, {3}}'); {3} (3 rows) +-- Test a forged PostgreSQL::InServer::ARRAY object lacking the 'array' key +CREATE OR REPLACE FUNCTION perl_forged_array() RETURNS integer[] AS $$ + return bless {}, "PostgreSQL::InServer::ARRAY"; +$$ LANGUAGE plperl; +SELECT perl_forged_array(); +ERROR: could not get array reference from PostgreSQL::InServer::ARRAY object +CONTEXT: PL/Perl function "perl_forged_array" diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index c1f9b8932a3..9ddb81d42b9 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -1154,7 +1154,7 @@ get_perl_array_ref(SV *sv) HV *hv = (HV *) SvRV(sv); SV **sav = hv_fetch_string(hv, "array"); - if (*sav && SvOK(*sav) && SvROK(*sav) && + if (sav && *sav && SvOK(*sav) && SvROK(*sav) && SvTYPE(SvRV(*sav)) == SVt_PVAV) return *sav; diff --git a/src/pl/plperl/sql/plperl_array.sql b/src/pl/plperl/sql/plperl_array.sql index ca63b5db625..cd1d7e34c50 100644 --- a/src/pl/plperl/sql/plperl_array.sql +++ b/src/pl/plperl/sql/plperl_array.sql @@ -206,3 +206,10 @@ create or replace function perl_setof_array(integer[]) returns setof integer[] l $$; select perl_setof_array('{{1}, {2}, {3}}'); + +-- Test a forged PostgreSQL::InServer::ARRAY object lacking the 'array' key +CREATE OR REPLACE FUNCTION perl_forged_array() RETURNS integer[] AS $$ + return bless {}, "PostgreSQL::InServer::ARRAY"; +$$ LANGUAGE plperl; + +SELECT perl_forged_array(); From 419ce13b7019f906ebc010af3be09a9deffc2a47 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 24 Jun 2026 11:42:36 +0900 Subject: [PATCH 011/481] Refine error reporting for null treatment on non-window functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 4e5920e6de8 disallowed RESPECT NULLS/IGNORE NULLS on non-window functions, but it also caused the parser to check for that clause too early in some cases. As a result, calls such as a nonexistent function with IGNORE NULLS no longer reported the more helpful "function ... does not exist" error, and aggregate functions used as window functions reported "only window functions accept ..." instead of the more accurate aggregate-specific error. This commit moves the RESPECT NULLS/IGNORE NULLS checks so that helpful existing errors are preserved where appropriate. This restores "function ... does not exist" for nonexistent functions, while still reporting that plain functions are not window functions and that aggregates do not accept null treatment. Author: Fujii Masao Reviewed-by: Tatsuo Ishii Reviewed-by: Chao Li Reviewed-by: Álvaro Herrera Discussion: https://postgr.es/m/CAHGQGwH7VY_0GkhycyYZ4czkPGL0uGzDyOxk3uuFOSRR7wFY3g@mail.gmail.com --- src/backend/parser/parse_func.c | 23 ++++++++++++++--------- src/test/regress/expected/window.out | 17 +++++++++++++++-- src/test/regress/sql/window.sql | 3 +++ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 860767a52ee..fb306c05112 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -351,17 +351,15 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, errmsg("OVER specified, but %s is not a window function nor an aggregate function", NameListToString(funcname)), parser_errposition(pstate, location))); + if (ignore_nulls != NO_NULLTREATMENT) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + /*- translator: first %s is a null treatment option, eg IGNORE NULLS */ + errmsg("%s specified, but %s is not a window function", + "RESPECT/IGNORE NULLS", NameListToString(funcname)), + parser_errposition(pstate, location))); } - /* - * NULL TREATEMENT is only allowed for window functions per spec. - */ - if (fdresult != FUNCDETAIL_WINDOWFUNC && ignore_nulls != NO_NULLTREATMENT) - ereport(ERROR, - errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("only window functions accept RESPECT/IGNORE NULLS"), - parser_errposition(pstate, location)); - /* * So far so good, so do some fdresult-type-specific processing. */ @@ -528,7 +526,14 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, errmsg("%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP", NameListToString(funcname)), parser_errposition(pstate, location))); + } + + if (ignore_nulls != NO_NULLTREATMENT) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("aggregate functions do not accept RESPECT/IGNORE NULLS"), + parser_errposition(pstate, location))); } else if (fdresult == FUNCDETAIL_WINDOWFUNC) { diff --git a/src/test/regress/expected/window.out b/src/test/regress/expected/window.out index 59c3df8cf0a..90d9f953b81 100644 --- a/src/test/regress/expected/window.out +++ b/src/test/regress/expected/window.out @@ -5748,6 +5748,19 @@ WINDOW w AS (ORDER BY name ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING EXCLUDE CURR (10 rows) -- valid and invalid functions +SELECT abs(1) IGNORE NULLS; -- fails +ERROR: RESPECT/IGNORE NULLS specified, but abs is not a window function +LINE 1: SELECT abs(1) IGNORE NULLS; + ^ +SELECT no_such_window_func() IGNORE NULLS; -- fails, but not because of null treatment +ERROR: function no_such_window_func() does not exist +LINE 1: SELECT no_such_window_func() IGNORE NULLS; + ^ +DETAIL: There is no function of that name. +SELECT sum(orbit) IGNORE NULLS FROM planets; -- fails +ERROR: aggregate functions do not accept RESPECT/IGNORE NULLS +LINE 1: SELECT sum(orbit) IGNORE NULLS FROM planets; + ^ SELECT sum(orbit) OVER () FROM planets; -- succeeds sum -------- @@ -5764,11 +5777,11 @@ SELECT sum(orbit) OVER () FROM planets; -- succeeds (10 rows) SELECT sum(orbit) RESPECT NULLS OVER () FROM planets; -- fails -ERROR: only window functions accept RESPECT/IGNORE NULLS +ERROR: aggregate functions do not accept RESPECT/IGNORE NULLS LINE 1: SELECT sum(orbit) RESPECT NULLS OVER () FROM planets; ^ SELECT sum(orbit) IGNORE NULLS OVER () FROM planets; -- fails -ERROR: only window functions accept RESPECT/IGNORE NULLS +ERROR: aggregate functions do not accept RESPECT/IGNORE NULLS LINE 1: SELECT sum(orbit) IGNORE NULLS OVER () FROM planets; ^ SELECT row_number() OVER () FROM planets; -- succeeds diff --git a/src/test/regress/sql/window.sql b/src/test/regress/sql/window.sql index 17261135dc3..5ac3a486e16 100644 --- a/src/test/regress/sql/window.sql +++ b/src/test/regress/sql/window.sql @@ -2099,6 +2099,9 @@ WINDOW w AS (ORDER BY name ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING EXCLUDE CURR ; -- valid and invalid functions +SELECT abs(1) IGNORE NULLS; -- fails +SELECT no_such_window_func() IGNORE NULLS; -- fails, but not because of null treatment +SELECT sum(orbit) IGNORE NULLS FROM planets; -- fails SELECT sum(orbit) OVER () FROM planets; -- succeeds SELECT sum(orbit) RESPECT NULLS OVER () FROM planets; -- fails SELECT sum(orbit) IGNORE NULLS OVER () FROM planets; -- fails From b3a95566fc2505d4586680c09d4966dba836cb20 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 24 Jun 2026 16:00:28 +0900 Subject: [PATCH 012/481] Fix set of typos and grammar mistakes This is similar to d3bba0415435, batching all the reports of this type received since the last batch. This covers typos and inconsistencies for the most part. The user-visible documentation change impacts only HEAD. --- contrib/pg_stash_advice/stashfuncs.c | 6 +++--- doc/src/sgml/oauth-validators.sgml | 2 +- doc/src/sgml/stylesheet-html-common.xsl | 2 +- src/backend/access/transam/xact.c | 16 ++++++++-------- src/backend/access/transam/xlogprefetcher.c | 15 ++++++++------- src/backend/access/transam/xlogrecovery.c | 2 +- src/backend/postmaster/startup.c | 4 ++-- src/backend/utils/activity/pgstat_relation.c | 2 +- src/backend/utils/activity/pgstat_slru.c | 3 --- src/backend/utils/adt/float.c | 2 +- src/backend/utils/adt/pg_dependencies.c | 3 +-- src/include/tsearch/ts_type.h | 2 +- src/port/pqsignal.c | 4 ++-- 13 files changed, 30 insertions(+), 33 deletions(-) diff --git a/contrib/pg_stash_advice/stashfuncs.c b/contrib/pg_stash_advice/stashfuncs.c index d7aa9f2223f..a70df60579b 100644 --- a/contrib/pg_stash_advice/stashfuncs.c +++ b/contrib/pg_stash_advice/stashfuncs.c @@ -266,9 +266,9 @@ pg_get_advice_stash_contents(PG_FUNCTION_ARGS) * SQL-callable function to update an advice stash entry for a particular * query ID * - * If the second argument is NULL, we delete any existing advice stash - * entry; otherwise, we either create an entry or update it with the new - * advice string. + * If the advice string (the third argument) is NULL, we delete any existing + * advice stash entry; otherwise, we either create an entry or update it with + * the new advice string. */ Datum pg_set_stashed_advice(PG_FUNCTION_ARGS) diff --git a/doc/src/sgml/oauth-validators.sgml b/doc/src/sgml/oauth-validators.sgml index d69b6cf98ad..6c4a4f94769 100644 --- a/doc/src/sgml/oauth-validators.sgml +++ b/doc/src/sgml/oauth-validators.sgml @@ -396,7 +396,7 @@ typedef struct ValidatorModuleResult field. Alternatively, result->authn_id may be set to NULL if the token is valid but the associated user identity cannot be determined. If the validator returns true and - set result->authn_id then the identity appears + sets result->authn_id then the identity appears in the server log when includes authentication. This happens before authorization and will log authentication even if the connection is later rejected due to diff --git a/doc/src/sgml/stylesheet-html-common.xsl b/doc/src/sgml/stylesheet-html-common.xsl index 9dcf96c02e5..f94fb9e1ccc 100644 --- a/doc/src/sgml/stylesheet-html-common.xsl +++ b/doc/src/sgml/stylesheet-html-common.xsl @@ -137,7 +137,7 @@ set toc,title
  • -This is controled with the EXCEPT clause, and is useful when specifying ALL TABLES. +This is controlled with the EXCEPT clause, and is useful when specifying ALL TABLES. @@ -2484,7 +2484,7 @@ Author: Tom Lane -Allow psql to more accurately determine if the pagerl is needed (Erik Wienhold) +Allow psql to more accurately determine if the pager is needed (Erik Wienhold) § From cae90d747969612b6e3778416246840790421527 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 25 Jun 2026 10:51:22 +0200 Subject: [PATCH 022/481] Message and comment wording fixes Some parts of pg_upgrade referred to "on the old cluster" etc. Change that to "in the old cluster", matching existing style. --- doc/src/sgml/logical-replication.sgml | 6 +++--- src/bin/pg_upgrade/check.c | 6 +++--- src/bin/pg_upgrade/t/003_logical_slots.pl | 6 +++--- src/bin/pg_upgrade/t/004_subscription.pl | 4 ++-- src/bin/pg_upgrade/t/006_transfer_modes.pl | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index 9e7868487de..5befefd9c5a 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -2773,7 +2773,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - The output plugins referenced by the slots on the old cluster must be + The output plugins referenced by the slots in the old cluster must be installed in the new PostgreSQL executable directory. @@ -2785,7 +2785,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - All slots on the old cluster must be usable, i.e., their + All slots in the old cluster must be usable, i.e., their pg_replication_slots.conflicting is false. @@ -2868,7 +2868,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER If there are subscriptions with retain_dead_tuples enabled, the reserved replication slot pg_conflict_detection - must not exist on the new cluster. Additionally, the + must not exist in the new cluster. Additionally, the wal_level on the new cluster must be set to replica or logical. diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index f5c93e611d2..7556fb3f22a 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -2287,13 +2287,13 @@ check_new_cluster_replication_slots(void) if (old_cluster.sub_retain_dead_tuples && nslots_on_old + 1 > max_replication_slots) pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of " - "logical replication slots on the old cluster plus one additional slot required " + "logical replication slots in the old cluster plus one additional slot required " "for retaining conflict detection information (%d)", max_replication_slots, nslots_on_old + 1); if (nslots_on_old > max_replication_slots) pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of " - "logical replication slots (%d) on the old cluster", + "logical replication slots (%d) in the old cluster", max_replication_slots, nslots_on_old); PQclear(res); @@ -2337,7 +2337,7 @@ check_new_cluster_subscription_configuration(void) max_active_replication_origins = atoi(PQgetvalue(res, 0, 0)); if (old_cluster.nsubs > max_active_replication_origins) pg_fatal("\"max_active_replication_origins\" (%d) must be greater than or equal to the number of " - "subscriptions (%d) on the old cluster", + "subscriptions (%d) in the old cluster", max_active_replication_origins, old_cluster.nsubs); PQclear(res); diff --git a/src/bin/pg_upgrade/t/003_logical_slots.pl b/src/bin/pg_upgrade/t/003_logical_slots.pl index de53c6f3eff..05918aad935 100644 --- a/src/bin/pg_upgrade/t/003_logical_slots.pl +++ b/src/bin/pg_upgrade/t/003_logical_slots.pl @@ -58,7 +58,7 @@ # TEST: Confirm pg_upgrade fails when the new cluster has wrong GUC values # Preparations for the subsequent test: -# 1. Create two slots on the old cluster +# 1. Create two slots in the old cluster $oldpub->start; $oldpub->safe_psql( 'postgres', qq[ @@ -69,7 +69,7 @@ $oldpub->stop(); # 2. Set 'max_replication_slots' to be less than the number of slots (2) -# present on the old cluster. +# present in the old cluster. $newpub->append_conf('postgresql.conf', "max_replication_slots = 1"); # pg_upgrade will fail because the new cluster has insufficient @@ -78,7 +78,7 @@ [@pg_upgrade_cmd], 1, [ - qr/"max_replication_slots" \(1\) must be greater than or equal to the number of logical replication slots \(3\) on the old cluster/ + qr/"max_replication_slots" \(1\) must be greater than or equal to the number of logical replication slots \(3\) in the old cluster/ ], [qr//], 'run of pg_upgrade where the new cluster has insufficient "max_replication_slots"' diff --git a/src/bin/pg_upgrade/t/004_subscription.pl b/src/bin/pg_upgrade/t/004_subscription.pl index c94a82deae0..36f059faa2e 100644 --- a/src/bin/pg_upgrade/t/004_subscription.pl +++ b/src/bin/pg_upgrade/t/004_subscription.pl @@ -74,7 +74,7 @@ ], 1, [ - qr/"max_active_replication_origins" \(0\) must be greater than or equal to the number of subscriptions \(1\) on the old cluster/ + qr/"max_active_replication_origins" \(0\) must be greater than or equal to the number of subscriptions \(1\) in the old cluster/ ], [qr//], 'run of pg_upgrade where the new cluster has insufficient max_active_replication_origins' @@ -123,7 +123,7 @@ ], 1, [ - qr/"max_replication_slots" \(0\) must be greater than or equal to the number of logical replication slots on the old cluster plus one additional slot required for retaining conflict detection information \(1\)/ + qr/"max_replication_slots" \(0\) must be greater than or equal to the number of logical replication slots in the old cluster plus one additional slot required for retaining conflict detection information \(1\)/ ], [qr//], 'run of pg_upgrade where the new cluster has insufficient max_replication_slots' diff --git a/src/bin/pg_upgrade/t/006_transfer_modes.pl b/src/bin/pg_upgrade/t/006_transfer_modes.pl index ca2d422bf28..6b7ab9f29a2 100644 --- a/src/bin/pg_upgrade/t/006_transfer_modes.pl +++ b/src/bin/pg_upgrade/t/006_transfer_modes.pl @@ -63,7 +63,7 @@ sub test_mode } $new->stop; - # Create a small variety of simple test objects on the old cluster. We'll + # Create a small variety of simple test objects in the old cluster. We'll # check that these reach the new version after upgrading. $old->start; $old->safe_psql('postgres', From 7f5e0b22e5eabf7b794b5059efa9454ba3616afe Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 25 Jun 2026 16:58:29 -0400 Subject: [PATCH 023/481] Fix null-pointer crash in ECPG compiler. When compiling a DECLARE section containing a union nested inside a struct, ecpg passes a null value for struct_sizeof to ECPGmake_struct_type. I (tgl) didn't foresee that case in commit 0e6060790, and wrote an unprotected mm_strdup() call. Reported-by: iMSA (via Jehan-Guillaume de Rorthais ) Author: Jehan-Guillaume de Rorthais Reviewed-by: Tom Lane Discussion: https://postgr.es/m/20260625114849.34b2148e@karst Backpatch-through: 18 --- src/interfaces/ecpg/preproc/type.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c index eec87c9cae1..7b40c61f782 100644 --- a/src/interfaces/ecpg/preproc/type.c +++ b/src/interfaces/ecpg/preproc/type.c @@ -101,7 +101,7 @@ ECPGmake_struct_type(struct ECPGstruct_member *rm, enum ECPGttype type, ne->type_name = mm_strdup(type_name); ne->u.members = ECPGstruct_member_dup(rm); - ne->struct_sizeof = mm_strdup(struct_sizeof); + ne->struct_sizeof = struct_sizeof ? mm_strdup(struct_sizeof) : NULL; return ne; } From 6468f7a853c3c75066410cfb54ecdb3050ec7132 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 25 Jun 2026 14:25:57 -0700 Subject: [PATCH 024/481] Mark uuid-to-bytea cast as leakproof. The uuid-to-bytea cast just serializes a valid uuid datum into its fixed 16-byte representation. It does not have an input-dependent error path so mark its pg_proc entry as leakproof. Oversight in commit ba21f5bf8a. Bump catalog version. Author: Chao Li Discussion: https://postgr.es/m/1FAAF426-9205-4F53-8D3B-F2003D96EC37@gmail.com --- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 4 ++-- src/test/regress/expected/opr_sanity.out | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 04eb2af2ac8..2fe3be9ada5 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202606232 +#define CATALOG_VERSION_NO 202606251 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index fa76c7923f0..384ba908d35 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -1209,8 +1209,8 @@ prosrc => 'bytea_int8' }, { oid => '6510', descr => 'convert uuid to bytea', - proname => 'bytea', prorettype => 'bytea', proargtypes => 'uuid', - prosrc => 'uuid_bytea' }, + proname => 'bytea', proleakproof => 't', prorettype => 'bytea', + proargtypes => 'uuid', prosrc => 'uuid_bytea' }, { oid => '6511', descr => 'convert bytea to uuid', proname => 'uuid', prorettype => 'uuid', proargtypes => 'bytea', prosrc => 'bytea_uuid' }, diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index 80400a33734..9f5a954da92 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -887,6 +887,7 @@ oid8le(oid8,oid8) oid8gt(oid8,oid8) oid8ge(oid8,oid8) btoid8cmp(oid8,oid8) +bytea(uuid) tid_block(tid) tid_offset(tid) -- Check that functions without argument are not marked as leakproof. From 30937c60cd9d9069a0377214d9675a7128a2e5a1 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 26 Jun 2026 10:47:32 +0900 Subject: [PATCH 025/481] doc: Improve description of pg_get_multixact_stats() This addresses two gaps in the documentation: - The function uses an xid, and was not mentioned as an exception in a section of the docs related to xid8. - The function returns NULL if a role does not have the privileges of pg_read_all_stats. The execution is not denied. Author: Chao Li Author: Yingying Chen Discussion: https://postgr.es/m/CAGGTb65Qmtor2nJP-ATgfWpMpD2qhKrdyO7fmRbbS++nQ=vtMw@mail.gmail.com --- doc/src/sgml/func/func-info.sgml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml index 34f4019690f..211bc8b238b 100644 --- a/doc/src/sgml/func/func-info.sgml +++ b/doc/src/sgml/func/func-info.sgml @@ -3020,8 +3020,9 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} vary between calls, even within a single transaction. - To use this function, you must have privileges of the - pg_read_all_stats role. + By default, all columns are shown as NULL unless + the user has privileges of the pg_read_all_stats + role. @@ -3032,8 +3033,9 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} The internal transaction ID type xid is 32 bits wide and wraps around every 4 billion transactions. However, the functions shown in , except - age, mxid_age, and - pg_get_multixact_members, use a + age, mxid_age, + pg_get_multixact_members, and + pg_get_multixact_stats, use a 64-bit type xid8 that does not wrap around during the life of an installation and can be converted to xid by casting if required; see for details. From cdae794af31b3e9cfc323fc654292d86fa746f77 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Fri, 26 Jun 2026 15:25:13 +0300 Subject: [PATCH 026/481] Take into account default_tablespace during MERGE/SPLIT PARTITION(S) createPartitionTable() passed the partitioned parent's reltablespace straight to heap_create_with_catalog(), bypassing the default_tablespace GUC fallback that DefineRelation() applies for CREATE TABLE ... PARTITION OF. When the parent had no explicit tablespace (reltablespace = 0), the new partition unconditionally landed in the database default, even if default_tablespace was set to something else; merging or splitting a set of partitions that all lived in a non-default tablespace produced a new partition in the database default. Mirror DefineRelation()'s logic: take parent's reltablespace if set, otherwise check GetDefaultTablespace() (which reads default_tablespace and normalises pg_default / MyDatabaseTableSpace to InvalidOid). Also add the CREATE ACL check on the resolved tablespace and the pg_global rejection, matching DefineRelation()'s behavior. Update the documentation for MERGE/SPLIT PARTITION to spell out the tablespace-selection rule explicitly. Reported-by: Justin Pryzby Reviewed-by: Pavel Borisov Discussion: https://postgr.es/m/ajQTklv8QArzTp3h%40pryzbyj2023 --- doc/src/sgml/ref/alter_table.sgml | 18 +++-- src/backend/commands/tablecmds.c | 31 ++++++++- src/test/regress/expected/partition_merge.out | 53 +++++++++++++++ src/test/regress/expected/partition_split.out | 68 +++++++++++++++++++ src/test/regress/sql/partition_merge.sql | 40 +++++++++++ src/test/regress/sql/partition_split.sql | 52 ++++++++++++++ 6 files changed, 257 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index 4ca91f81d34..67a05593140 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -1234,8 +1234,13 @@ WITH ( MODULUS numeric_literal, REM ALTER TABLE MERGE PARTITION uses the partitioned table itself as the template to construct the new partition. - The new partition will inherit the same table access method, persistence - type, and tablespace as the partitioned table. + The new partition inherits the table access method and persistence type + of the partitioned table. Its tablespace is selected as for a + CREATE TABLE ... PARTITION OF command issued + without a TABLESPACE clause: if the partitioned + table has an explicit tablespace, the new partition uses it; + otherwise the value of is + taken into account, falling back to the database's default tablespace. Constraints, column defaults, column generation expressions, identity columns, indexes, and triggers are copied from the partitioned table to @@ -1332,8 +1337,13 @@ WITH ( MODULUS numeric_literal, REM ALTER TABLE SPLIT PARTITION uses the partitioned table itself as the template to construct new partitions. - New partitions will inherit the same table access method, persistence - type, and tablespace as the partitioned table. + New partitions inherit the table access method and persistence type of + the partitioned table. Their tablespace is selected as for a + CREATE TABLE ... PARTITION OF command issued + without a TABLESPACE clause: if the partitioned + table has an explicit tablespace, the new partitions use it; + otherwise the value of is + taken into account, falling back to the database's default tablespace. diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 265dcfe7fda..33e065d61ce 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -22735,6 +22735,7 @@ createPartitionTable(List **wqueue, RangeVar *newPartName, Relation newRel; Oid newRelId; Oid existingRelid; + Oid tablespaceId; TupleDesc descriptor; List *colList = NIL; Oid relamId; @@ -22786,10 +22787,38 @@ createPartitionTable(List **wqueue, RangeVar *newPartName, errmsg("cannot create a permanent relation as partition of temporary relation \"%s\"", RelationGetRelationName(parent_rel))); + /* + * Select the tablespace for the new partition. Mirror the logic that + * CREATE TABLE foo PARTITION OF ... uses in DefineRelation: take the + * partitioned parent's explicit tablespace if it has one, otherwise take + * default_tablespace into account, and finally use the database default. + */ + tablespaceId = parent_relform->reltablespace; + if (!OidIsValid(tablespaceId)) + tablespaceId = GetDefaultTablespace(newPartName->relpersistence, false); + + /* Check permissions except when using database's default */ + if (OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace) + { + AclResult aclresult; + + aclresult = object_aclcheck(TableSpaceRelationId, tablespaceId, + GetUserId(), ACL_CREATE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, OBJECT_TABLESPACE, + get_tablespace_name(tablespaceId)); + } + + /* In all cases disallow placing user relations in pg_global */ + if (tablespaceId == GLOBALTABLESPACE_OID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("only shared relations can be placed in pg_global tablespace"))); + /* Create the relation. */ newRelId = heap_create_with_catalog(newPartName->relname, namespaceId, - parent_relform->reltablespace, + tablespaceId, InvalidOid, InvalidOid, InvalidOid, diff --git a/src/test/regress/expected/partition_merge.out b/src/test/regress/expected/partition_merge.out index 4f42afc3dc7..ccda2b5843b 100644 --- a/src/test/regress/expected/partition_merge.out +++ b/src/test/regress/expected/partition_merge.out @@ -1114,6 +1114,59 @@ SELECT length(a) FROM t; 10000 (1 row) +DROP TABLE t; +-- Tablespace selection for the new merged partition mirrors +-- CREATE TABLE ... PARTITION OF: the partitioned root's explicit +-- tablespace wins; otherwise default_tablespace applies; otherwise the +-- database default is used. +CREATE TABLE t (i int) PARTITION BY RANGE(i) TABLESPACE regress_tblspace; +CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); +CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; +SELECT spcname FROM pg_class c LEFT JOIN pg_tablespace s + ON c.reltablespace = s.oid WHERE c.relname = 'tp_merged'; + spcname +------------------ + regress_tblspace +(1 row) + +DROP TABLE t; +-- Parent has no explicit tablespace, but default_tablespace is set: the +-- new partition lands on default_tablespace. +CREATE TABLE t (i int) PARTITION BY RANGE(i); +CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); +CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +SET default_tablespace TO regress_tblspace; +ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; +RESET default_tablespace; +SELECT spcname FROM pg_class c LEFT JOIN pg_tablespace s + ON c.reltablespace = s.oid WHERE c.relname = 'tp_merged'; + spcname +------------------ + regress_tblspace +(1 row) + +DROP TABLE t; +CREATE TABLE t (i int) PARTITION BY RANGE(i); +CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); +CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +-- pg_global is rejected when picked up from default_tablespace. +SET default_tablespace TO pg_global; +ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; -- fails +ERROR: only shared relations can be placed in pg_global tablespace +RESET default_tablespace; +-- Parent has no explicit tablespace and default_tablespace is empty: the +-- new partition uses the database default (reltablespace = 0). +ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; +SELECT reltablespace FROM pg_class WHERE relname = 'tp_merged'; + reltablespace +--------------- + 0 +(1 row) + DROP TABLE t; RESET search_path; -- diff --git a/src/test/regress/expected/partition_split.out b/src/test/regress/expected/partition_split.out index faaf32ed20a..8e245563801 100644 --- a/src/test/regress/expected/partition_split.out +++ b/src/test/regress/expected/partition_split.out @@ -1683,6 +1683,74 @@ SELECT length(a) FROM t; 10000 (1 row) +DROP TABLE t; +-- Tablespace selection for the new partitions mirrors +-- CREATE TABLE ... PARTITION OF: the partitioned root's explicit +-- tablespace wins; otherwise default_tablespace applies; otherwise the +-- database default is used. +CREATE TABLE t (i int) PARTITION BY RANGE(i) TABLESPACE regress_tblspace; +CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +ALTER TABLE t SPLIT PARTITION tp_all INTO ( + PARTITION tp_lo FOR VALUES FROM (0) TO (5), + PARTITION tp_hi FOR VALUES FROM (5) TO (10) +); +SELECT c.relname, s.spcname FROM pg_class c LEFT JOIN pg_tablespace s + ON c.reltablespace = s.oid WHERE c.relname IN ('tp_lo', 'tp_hi') + ORDER BY c.relname; + relname | spcname +---------+------------------ + tp_hi | regress_tblspace + tp_lo | regress_tblspace +(2 rows) + +DROP TABLE t; +-- Parent has no explicit tablespace, but default_tablespace is set: the +-- new partitions land on default_tablespace. +CREATE TABLE t (i int) PARTITION BY RANGE(i); +CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +SET default_tablespace TO regress_tblspace; +ALTER TABLE t SPLIT PARTITION tp_all INTO ( + PARTITION tp_lo FOR VALUES FROM (0) TO (5), + PARTITION tp_hi FOR VALUES FROM (5) TO (10) +); +RESET default_tablespace; +SELECT c.relname, s.spcname FROM pg_class c LEFT JOIN pg_tablespace s + ON c.reltablespace = s.oid WHERE c.relname IN ('tp_lo', 'tp_hi') + ORDER BY c.relname; + relname | spcname +---------+------------------ + tp_hi | regress_tblspace + tp_lo | regress_tblspace +(2 rows) + +DROP TABLE t; +CREATE TABLE t (i int) PARTITION BY RANGE(i); +CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +-- pg_global is rejected when picked up from default_tablespace. +SET default_tablespace TO pg_global; +ALTER TABLE t SPLIT PARTITION tp_all INTO ( + PARTITION tp_lo FOR VALUES FROM (0) TO (5), + PARTITION tp_hi FOR VALUES FROM (5) TO (10) +); -- fails +ERROR: only shared relations can be placed in pg_global tablespace +RESET default_tablespace; +-- Parent has no explicit tablespace and default_tablespace is empty: new +-- partitions use the database default (reltablespace = 0). +ALTER TABLE t SPLIT PARTITION tp_all INTO ( + PARTITION tp_lo FOR VALUES FROM (0) TO (5), + PARTITION tp_hi FOR VALUES FROM (5) TO (10) +); +SELECT relname, reltablespace FROM pg_class + WHERE relname IN ('tp_lo', 'tp_hi') ORDER BY relname; + relname | reltablespace +---------+--------------- + tp_hi | 0 + tp_lo | 0 +(2 rows) + DROP TABLE t; RESET search_path; -- diff --git a/src/test/regress/sql/partition_merge.sql b/src/test/regress/sql/partition_merge.sql index 4c8c625f97b..80dc365b0ce 100644 --- a/src/test/regress/sql/partition_merge.sql +++ b/src/test/regress/sql/partition_merge.sql @@ -798,6 +798,46 @@ SELECT reltoastrelid <> 0 AS has_toast, SELECT length(a) FROM t; DROP TABLE t; +-- Tablespace selection for the new merged partition mirrors +-- CREATE TABLE ... PARTITION OF: the partitioned root's explicit +-- tablespace wins; otherwise default_tablespace applies; otherwise the +-- database default is used. +CREATE TABLE t (i int) PARTITION BY RANGE(i) TABLESPACE regress_tblspace; +CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); +CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; +SELECT spcname FROM pg_class c LEFT JOIN pg_tablespace s + ON c.reltablespace = s.oid WHERE c.relname = 'tp_merged'; +DROP TABLE t; + +-- Parent has no explicit tablespace, but default_tablespace is set: the +-- new partition lands on default_tablespace. +CREATE TABLE t (i int) PARTITION BY RANGE(i); +CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); +CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +SET default_tablespace TO regress_tblspace; +ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; +RESET default_tablespace; +SELECT spcname FROM pg_class c LEFT JOIN pg_tablespace s + ON c.reltablespace = s.oid WHERE c.relname = 'tp_merged'; +DROP TABLE t; + +CREATE TABLE t (i int) PARTITION BY RANGE(i); +CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); +CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +-- pg_global is rejected when picked up from default_tablespace. +SET default_tablespace TO pg_global; +ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; -- fails +RESET default_tablespace; +-- Parent has no explicit tablespace and default_tablespace is empty: the +-- new partition uses the database default (reltablespace = 0). +ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; +SELECT reltablespace FROM pg_class WHERE relname = 'tp_merged'; +DROP TABLE t; + RESET search_path; diff --git a/src/test/regress/sql/partition_split.sql b/src/test/regress/sql/partition_split.sql index 9e44aa9caf0..ffd15e7f969 100644 --- a/src/test/regress/sql/partition_split.sql +++ b/src/test/regress/sql/partition_split.sql @@ -1204,6 +1204,58 @@ SELECT relname, SELECT length(a) FROM t; DROP TABLE t; +-- Tablespace selection for the new partitions mirrors +-- CREATE TABLE ... PARTITION OF: the partitioned root's explicit +-- tablespace wins; otherwise default_tablespace applies; otherwise the +-- database default is used. +CREATE TABLE t (i int) PARTITION BY RANGE(i) TABLESPACE regress_tblspace; +CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +ALTER TABLE t SPLIT PARTITION tp_all INTO ( + PARTITION tp_lo FOR VALUES FROM (0) TO (5), + PARTITION tp_hi FOR VALUES FROM (5) TO (10) +); +SELECT c.relname, s.spcname FROM pg_class c LEFT JOIN pg_tablespace s + ON c.reltablespace = s.oid WHERE c.relname IN ('tp_lo', 'tp_hi') + ORDER BY c.relname; +DROP TABLE t; + +-- Parent has no explicit tablespace, but default_tablespace is set: the +-- new partitions land on default_tablespace. +CREATE TABLE t (i int) PARTITION BY RANGE(i); +CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +SET default_tablespace TO regress_tblspace; +ALTER TABLE t SPLIT PARTITION tp_all INTO ( + PARTITION tp_lo FOR VALUES FROM (0) TO (5), + PARTITION tp_hi FOR VALUES FROM (5) TO (10) +); +RESET default_tablespace; +SELECT c.relname, s.spcname FROM pg_class c LEFT JOIN pg_tablespace s + ON c.reltablespace = s.oid WHERE c.relname IN ('tp_lo', 'tp_hi') + ORDER BY c.relname; +DROP TABLE t; + +CREATE TABLE t (i int) PARTITION BY RANGE(i); +CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); +INSERT INTO t SELECT generate_series(0, 9); +-- pg_global is rejected when picked up from default_tablespace. +SET default_tablespace TO pg_global; +ALTER TABLE t SPLIT PARTITION tp_all INTO ( + PARTITION tp_lo FOR VALUES FROM (0) TO (5), + PARTITION tp_hi FOR VALUES FROM (5) TO (10) +); -- fails +RESET default_tablespace; +-- Parent has no explicit tablespace and default_tablespace is empty: new +-- partitions use the database default (reltablespace = 0). +ALTER TABLE t SPLIT PARTITION tp_all INTO ( + PARTITION tp_lo FOR VALUES FROM (0) TO (5), + PARTITION tp_hi FOR VALUES FROM (5) TO (10) +); +SELECT relname, reltablespace FROM pg_class + WHERE relname IN ('tp_lo', 'tp_hi') ORDER BY relname; +DROP TABLE t; + RESET search_path; -- From ed9ec3abb601bbe6a22363ca5ac80959de8c14ef Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Fri, 26 Jun 2026 17:57:26 +0200 Subject: [PATCH 027/481] Improve docs for EXPLAIN (IO) Commit 681daed931 introduced a new EXPLAIN option "IO", but the docs did not explain what information was added to the output. Expand the description a little bit, similarly to the other EXPLAIN options. While at it, fix a typo in the first sentence. Author: Tomas Vondra --- doc/src/sgml/ref/explain.sgml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/ref/explain.sgml b/doc/src/sgml/ref/explain.sgml index e95e19081e1..f38d31e106a 100644 --- a/doc/src/sgml/ref/explain.sgml +++ b/doc/src/sgml/ref/explain.sgml @@ -303,7 +303,14 @@ ROLLBACK; IO - Include information on I/O performed by scan nodes proving such information. + Include information on I/O performed by scan nodes providing such + information. + Specifically, include information about the prefetch queue (the average + and the maximum distance, and the queue capacity), and information about + issued I/O requests (the total number of requests, the average request + size, the number of I/O waits, and the average number of concurrent I/O + requests). The request size is reported in blocks. + In text format, only non-zero values are printed. This parameter may only be used when ANALYZE is also enabled. It defaults to FALSE. From dac36601fd774a00b3b7390a656a689e2881bcf4 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Fri, 26 Jun 2026 19:34:14 +0200 Subject: [PATCH 028/481] Fix out-of-bounds access in autoprewarm worker The read stream callback apw_read_stream_next_block() advances p->pos through the block_info array. When processing the last block, it increments p->pos to prewarm_stop_idx before returning. The callback itself is safe because it checks bounds before accessing the array. However, the caller assigned blk from block_info[i] at the end of the loop body, before the loop condition was re-evaluated. When i equaled prewarm_stop_idx, this accessed memory beyond the allocated DSM segment, causing a segfault. Restructure the loop to check bounds at the top and assign blk at the beginning of the loop body, where it is always safe. This avoids the need for an explicit bounds check at the end. Backpatch to 18, where the bug was introduced by commit 6acab8bdbcda. Author: Matheus Alcantara Reported-by: Glauber Batista Reviewed-by: Melanie Plageman Reviewed-by: Tomas Vondra Backpatch-through: 18 Discussion: https://www.postgresql.org/message-id/CAO%2B_mTQgQyTYwDh%3DU8iTnsDmOGyWsZJjUV31SmEYwmw6_xY6Bw%40mail.gmail.com --- contrib/pg_prewarm/autoprewarm.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c index ba0bc8e6d4a..deb4c2671b5 100644 --- a/contrib/pg_prewarm/autoprewarm.c +++ b/contrib/pg_prewarm/autoprewarm.c @@ -572,16 +572,23 @@ autoprewarm_database_main(Datum main_arg) * valid forks or run out of options, we'll close the relation and * move on. */ - while (i < apw_state->prewarm_stop_idx && - blk.tablespace == tablespace && - blk.filenumber == filenumber) + while (i < apw_state->prewarm_stop_idx) { - ForkNumber forknum = blk.forknum; + ForkNumber forknum; BlockNumber nblocks; struct AutoPrewarmReadStreamData p; ReadStream *stream; Buffer buf; + blk = block_info[i]; + + /* Stop when we reach a different relation. */ + if (blk.tablespace != tablespace || + blk.filenumber != filenumber) + break; + + forknum = blk.forknum; + /* * smgrexists is not safe for illegal forknum, hence check whether * the passed forknum is valid before using it in smgrexists. @@ -643,9 +650,12 @@ autoprewarm_database_main(Datum main_arg) read_stream_end(stream); - /* Advance i past all the blocks just prewarmed. */ + /* + * Advance i past all the blocks just prewarmed. Note that the + * callback might have advanced the index beyond the last valid + * block, so don't access block_info[i] yet. + */ i = p.pos; - blk = block_info[i]; } relation_close(rel, AccessShareLock); From 4df5fe3833a87f6629eb888ca5a385bcb0b179d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Fri, 26 Jun 2026 20:03:42 +0200 Subject: [PATCH 029/481] Make crosstabview honor boolean/null display settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit psql's \pset display_true/false settings, added by commit 645cb44c5490, affect normal query output, but not \crosstabview. As a result, boolean values used anywhere in crosstab output were always shown as "t" or "f", which is inconsistent. Change \crosstabview so that the configured values are displayed instead. While at it, make \crosstabview print the \pset null string, if any, in cells for which the query produces a NULL value. Cells for which the query produces no value continue to have the empty string. This is an oversight in the aboriginal \crosstabview commit, c09b18f21c52. Add a regression test covering all of this. Author: Chao Li Reported-by: Chao Li Reviewed-by: David G. Johnston Reviewed-by: Álvaro Herrera Backpatch: none needed Discussion: https://postgr.es/m/B5E6F0A5-4B48-46D0-B5EB-CF8F8CC7D07D@gmail.com --- src/bin/psql/crosstabview.c | 59 +++++++++++++++------ src/test/regress/expected/psql_crosstab.out | 29 ++++++++++ src/test/regress/sql/psql_crosstab.sql | 24 +++++++++ 3 files changed, 96 insertions(+), 16 deletions(-) diff --git a/src/bin/psql/crosstabview.c b/src/bin/psql/crosstabview.c index 111e8823bdb..b59437e41eb 100644 --- a/src/bin/psql/crosstabview.c +++ b/src/bin/psql/crosstabview.c @@ -7,6 +7,7 @@ */ #include "postgres_fe.h" +#include "catalog/pg_type_d.h" #include "common.h" #include "common/int.h" #include "common/logging.h" @@ -82,6 +83,8 @@ static bool printCrosstab(const PGresult *result, int num_columns, pivot_field *piv_columns, int field_for_columns, int num_rows, pivot_field *piv_rows, int field_for_rows, int field_for_data); +static char *displayValue(char *value, Oid ftype, char *default_null); + static void avlInit(avl_tree *tree); static void avlMergeValue(avl_tree *tree, char *name, char *sort_value); static int avlCollectFields(avl_tree *tree, avl_node *node, @@ -292,6 +295,9 @@ printCrosstab(const PGresult *result, rn; char col_align; int *horiz_map; + Oid col_ftype = PQftype(result, field_for_columns); + Oid row_ftype = PQftype(result, field_for_rows); + Oid data_ftype = PQftype(result, field_for_data); bool retval = false; printTableInit(&cont, &popt.topt, popt.title, num_columns + 1, num_rows); @@ -302,8 +308,7 @@ printCrosstab(const PGresult *result, printTableAddHeader(&cont, PQfname(result, field_for_rows), false, - column_type_alignment(PQftype(result, - field_for_rows))); + column_type_alignment(row_ftype)); /* * To iterate over piv_columns[] by piv_columns[].rank, create a reverse @@ -317,15 +322,13 @@ printCrosstab(const PGresult *result, /* * The display alignment depends on its PQftype(). */ - col_align = column_type_alignment(PQftype(result, field_for_data)); + col_align = column_type_alignment(data_ftype); for (i = 0; i < num_columns; i++) { char *colname; - colname = piv_columns[horiz_map[i]].name ? - piv_columns[horiz_map[i]].name : - (popt.nullPrint ? popt.nullPrint : ""); + colname = displayValue(piv_columns[horiz_map[i]].name, col_ftype, ""); printTableAddHeader(&cont, colname, false, col_align); } @@ -335,10 +338,9 @@ printCrosstab(const PGresult *result, for (i = 0; i < num_rows; i++) { int k = piv_rows[i].rank; + int idx = k * (num_columns + 1); - cont.cells[k * (num_columns + 1)] = piv_rows[i].name ? - piv_rows[i].name : - (popt.nullPrint ? popt.nullPrint : ""); + cont.cells[idx] = displayValue(piv_rows[i].name, row_ftype, ""); } cont.cellsadded = num_rows * (num_columns + 1); @@ -384,6 +386,7 @@ printCrosstab(const PGresult *result, if (col_number >= 0 && row_number >= 0) { int idx; + char *value; /* index into the cont.cells array */ idx = 1 + col_number + row_number * (num_columns + 1); @@ -394,16 +397,16 @@ printCrosstab(const PGresult *result, if (cont.cells[idx] != NULL) { pg_log_error("\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"", - rp->name ? rp->name : - (popt.nullPrint ? popt.nullPrint : "(null)"), - cp->name ? cp->name : - (popt.nullPrint ? popt.nullPrint : "(null)")); + displayValue(rp->name, row_ftype, "(null)"), + displayValue(cp->name, col_ftype, "(null)")); goto error; } - cont.cells[idx] = !PQgetisnull(result, rn, field_for_data) ? - PQgetvalue(result, rn, field_for_data) : - (popt.nullPrint ? popt.nullPrint : ""); + if (PQgetisnull(result, rn, field_for_data)) + value = NULL; + else + value = PQgetvalue(result, rn, field_for_data); + cont.cells[idx] = displayValue(value, data_ftype, ""); } } @@ -426,6 +429,30 @@ printCrosstab(const PGresult *result, return retval; } +/* + * Return the display representation of one cell value in \crosstabview, + * following pset substitutions. + * + * The returned pointer is not to be freed. + */ +static char * +displayValue(char *value, Oid ftype, char *default_null) +{ + printQueryOpt popt = pset.popt; + + if (value == NULL) + value = popt.nullPrint ? popt.nullPrint : default_null; + else if (ftype == BOOLOID) + { + if (value[0] == 't' && popt.truePrint) + value = popt.truePrint; + else if (value[0] == 'f' && popt.falsePrint) + value = popt.falsePrint; + } + + return value; +} + /* * The avl* functions below provide a minimalistic implementation of AVL binary * trees, to efficiently collect the distinct values that will form the horizontal diff --git a/src/test/regress/expected/psql_crosstab.out b/src/test/regress/expected/psql_crosstab.out index e09e3310165..e32d79d38b0 100644 --- a/src/test/regress/expected/psql_crosstab.out +++ b/src/test/regress/expected/psql_crosstab.out @@ -136,6 +136,35 @@ GROUP BY v, h ORDER BY h,v | | | | -3 | (3 rows) +\pset null '' +-- boolean display +\pset display_true 'Aye' +\pset display_false 'Nay' +\pset null 'Wut' +with rows (display_bools, col_key, val) as (values + (false, false, false), + (true, true, true), + (null, null, null), + (null, true, false), + (null, false, true), + (true, null, false), + (false, null, true) +) select * from rows + \crosstabview display_bools col_key val + display_bools | Nay | Aye | Wut +---------------+-----+-----+----- + Nay | Nay | | Aye + Aye | | Aye | Nay + Wut | Aye | Nay | Wut +(3 rows) + +with rows (tst, col, val) as (values + (true, null, 42), (true, null, 142857) +) select * from rows + \crosstabview tst col +\crosstabview: query result contains multiple data values for row "Aye", column "Wut" +\pset display_true 't' +\pset display_false 'f' \pset null '' -- refer to columns by position SELECT v,h,string_agg(i::text, E'\n'), string_agg(c, E'\n') diff --git a/src/test/regress/sql/psql_crosstab.sql b/src/test/regress/sql/psql_crosstab.sql index 5a4511389de..82a73981d5d 100644 --- a/src/test/regress/sql/psql_crosstab.sql +++ b/src/test/regress/sql/psql_crosstab.sql @@ -69,6 +69,30 @@ GROUP BY v, h ORDER BY h,v \crosstabview v h i \pset null '' +-- boolean display +\pset display_true 'Aye' +\pset display_false 'Nay' +\pset null 'Wut' +with rows (display_bools, col_key, val) as (values + (false, false, false), + (true, true, true), + (null, null, null), + (null, true, false), + (null, false, true), + (true, null, false), + (false, null, true) +) select * from rows + \crosstabview display_bools col_key val + +with rows (tst, col, val) as (values + (true, null, 42), (true, null, 142857) +) select * from rows + \crosstabview tst col + +\pset display_true 't' +\pset display_false 'f' +\pset null '' + -- refer to columns by position SELECT v,h,string_agg(i::text, E'\n'), string_agg(c, E'\n') FROM ctv_data GROUP BY v, h ORDER BY h,v From dbaa4dc3c8dd77a0e1c977024d4ae150e00456b3 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Sat, 27 Jun 2026 11:45:56 +0900 Subject: [PATCH 030/481] Switch maximum of GUC huge_page_size to MAX_KILOBYTES As documented in guc.h, MAX_KILOBYTES is used to cap GUC parameters that are measured in kilobytes of memory. This way, size_t values can fit in builds where sizeof(size_t) is 4 bytes. Unfortunately, huge_page_size has missed this aspect, causing calculation failures when setting this GUC to a value higher than MAX_KILOBYTES, up to INT_MAX. Oversight in d2bddc2500fb. No backpatch is done, based on the lack of complaints. Reported-by: Daria Shanina Reviewed-by: Kyotaro Horiguchi Discussion: https://postgr.es/m/20260626.132415.904994526137946499.horikyota.ntt@gmail.com --- src/backend/utils/misc/guc_parameters.dat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat index 7b1eb6e61bc..3c1e6b31bf8 100644 --- a/src/backend/utils/misc/guc_parameters.dat +++ b/src/backend/utils/misc/guc_parameters.dat @@ -1252,7 +1252,7 @@ variable => 'huge_page_size', boot_val => '0', min => '0', - max => 'INT_MAX', + max => 'MAX_KILOBYTES', check_hook => 'check_huge_page_size', }, From a272a58b94249879c3f7e170a5ebfaeec940d411 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Sat, 27 Jun 2026 09:07:07 +0200 Subject: [PATCH 031/481] Move FOR PORTION OF volatile check into planner This needs to be wary of the function volatility changing after we check it. We cannot enforce this when checking at parse time, so move it later, into the planner. Author: Paul A. Jungwirth Reported-by: Tom Lane Reviewed-by: jian he Discussion: https://www.postgresql.org/message-id/flat/CA%2BrenyUte0_UJsJiDJQi82oaBsMJn%3Dcct0Wn%3DvOqXtuDn%3DYYJA%40mail.gmail.com --- src/backend/optimizer/plan/planner.c | 12 ++++++++++++ src/backend/parser/analyze.c | 3 --- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index f4689e7c9f8..846bd7c1fbe 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -1081,6 +1081,18 @@ subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, /* exclRelTlist contains only Vars, so no preprocessing needed */ } + if (parse->forPortionOf) + { + parse->forPortionOf->targetRange = + preprocess_expression(root, + parse->forPortionOf->targetRange, + EXPRKIND_TARGET); + if (contain_volatile_functions(parse->forPortionOf->targetRange)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("FOR PORTION OF bounds cannot contain volatile functions"))); + } + foreach(l, parse->mergeActionList) { MergeAction *action = (MergeAction *) lfirst(l); diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 93fa66ae57c..76758adefb6 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -1489,9 +1489,6 @@ transformForPortionOfClause(ParseState *pstate, args, InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL); } - if (contain_volatile_functions_after_planning((Expr *) result->targetRange)) - ereport(ERROR, - (errmsg("FOR PORTION OF bounds cannot contain volatile functions"))); /* * Build overlapsExpr to use as an extra qual. This means we only hit rows From a40fdf658862b3221a35268f8c74abfd46b9e93c Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Sat, 27 Jun 2026 19:34:40 +0200 Subject: [PATCH 032/481] Reject child partition FDWs in FOR PORTION OF We should defer validating FDW usage until after analysis. We have to guard against not just the topmost table, but also individual child partitions. Added the check to CheckValidResultRel, because it is called after looking up child partitions (accounting for pruning), but before the FDW can run a DirectModify update, which would bypass per-tuple executor work. Author: jian he Reported-by: Tom Lane Reviewed-by: Paul A. Jungwirth Discussion: https://www.postgresql.org/message-id/flat/CA%2BrenyUte0_UJsJiDJQi82oaBsMJn%3Dcct0Wn%3DvOqXtuDn%3DYYJA%40mail.gmail.com --- .../postgres_fdw/expected/postgres_fdw.out | 42 +++++++++++++++++-- contrib/postgres_fdw/sql/postgres_fdw.sql | 30 +++++++++++-- src/backend/commands/copyfrom.c | 2 +- src/backend/executor/execMain.c | 11 ++++- src/backend/executor/execPartition.c | 4 +- src/backend/executor/nodeModifyTable.c | 2 +- src/backend/parser/analyze.c | 6 --- src/include/executor/executor.h | 2 +- 8 files changed, 81 insertions(+), 18 deletions(-) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 13853b8b720..0805c56cb1b 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -6335,9 +6335,10 @@ DELETE FROM ft2 WHERE c1 = 1200 RETURNING tableoid::regclass; -- Test UPDATE FOR PORTION OF UPDATE ft8 FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01' -SET c2 = c2 + 1 -WHERE c1 = '[1,2)'; + SET c2 = c2 + 1 + WHERE c1 = '[1,2)'; -- error ERROR: foreign tables don't support FOR PORTION OF +DETAIL: "ft8" is a foreign table. SELECT * FROM ft8 WHERE c1 = '[1,2)' ORDER BY c1, c4; c1 | c2 | c3 | c4 -------+----+--------+------------------------- @@ -6346,14 +6347,49 @@ SELECT * FROM ft8 WHERE c1 = '[1,2)' ORDER BY c1, c4; -- Test DELETE FOR PORTION OF DELETE FROM ft8 FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01' -WHERE c1 = '[2,3)'; + WHERE c1 = '[2,3)'; -- error ERROR: foreign tables don't support FOR PORTION OF +DETAIL: "ft8" is a foreign table. SELECT * FROM ft8 WHERE c1 = '[2,3)' ORDER BY c1, c4; c1 | c2 | c3 | c4 -------+----+--------+------------------------- [2,3) | 3 | AAA002 | [01-01-2000,01-01-2020) (1 row) +-- FOR PORTION OF fails if a child partition is a foreign table, even if the +-- root is not. But a child partition that is pruned doesn't cause an error. +CREATE TABLE fpo_part_parent ( + c1 int4range NOT NULL, + c2 int NOT NULL, + c3 text, + c4 daterange NOT NULL +) PARTITION BY LIST (c2); +CREATE TABLE fpo_part_local PARTITION OF fpo_part_parent FOR VALUES IN (1); +INSERT INTO fpo_part_local VALUES ('[1,2)', 1, 'one', '[2024-01-01,2024-12-31)'); +CREATE FOREIGN TABLE fpo_part_foreign + PARTITION OF fpo_part_parent FOR VALUES IN (6) + SERVER loopback OPTIONS (schema_name 'S 1', table_name 'T 5'); +DELETE FROM fpo_part_parent + FOR PORTION OF c4 FROM '2001-01-01' TO '2001-02-01' WHERE c2 = 6; -- error +ERROR: foreign tables don't support FOR PORTION OF +DETAIL: "fpo_part_foreign" is a foreign table. +UPDATE fpo_part_parent + FOR PORTION OF c4 FROM '2001-01-01' TO '2001-02-01' SET c3 = 'x' WHERE c2 = 6; -- error +ERROR: foreign tables don't support FOR PORTION OF +DETAIL: "fpo_part_foreign" is a foreign table. +UPDATE fpo_part_parent + FOR PORTION OF c4 FROM '2024-06-01' TO '2024-07-01' SET c3 = 'edited' WHERE c2 = 1; -- okay +DELETE FROM fpo_part_parent + FOR PORTION OF c4 FROM '2024-06-01' TO '2024-06-15' WHERE c2 = 1; -- okay +SELECT c1, c2, c3, c4 FROM fpo_part_local ORDER BY c4; + c1 | c2 | c3 | c4 +-------+----+--------+------------------------- + [1,2) | 1 | one | [01-01-2024,06-01-2024) + [1,2) | 1 | edited | [06-15-2024,07-01-2024) + [1,2) | 1 | one | [07-01-2024,12-31-2024) +(3 rows) + +DROP TABLE fpo_part_parent; -- Test UPDATE/DELETE with RETURNING on a three-table join INSERT INTO ft2 (c1,c2,c3) SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id; diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index 697c4a92e2d..8162c5496bf 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -1578,15 +1578,39 @@ DELETE FROM ft2 WHERE c1 = 1200 RETURNING tableoid::regclass; -- Test UPDATE FOR PORTION OF UPDATE ft8 FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01' -SET c2 = c2 + 1 -WHERE c1 = '[1,2)'; + SET c2 = c2 + 1 + WHERE c1 = '[1,2)'; -- error SELECT * FROM ft8 WHERE c1 = '[1,2)' ORDER BY c1, c4; -- Test DELETE FOR PORTION OF DELETE FROM ft8 FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01' -WHERE c1 = '[2,3)'; + WHERE c1 = '[2,3)'; -- error SELECT * FROM ft8 WHERE c1 = '[2,3)' ORDER BY c1, c4; +-- FOR PORTION OF fails if a child partition is a foreign table, even if the +-- root is not. But a child partition that is pruned doesn't cause an error. +CREATE TABLE fpo_part_parent ( + c1 int4range NOT NULL, + c2 int NOT NULL, + c3 text, + c4 daterange NOT NULL +) PARTITION BY LIST (c2); +CREATE TABLE fpo_part_local PARTITION OF fpo_part_parent FOR VALUES IN (1); +INSERT INTO fpo_part_local VALUES ('[1,2)', 1, 'one', '[2024-01-01,2024-12-31)'); +CREATE FOREIGN TABLE fpo_part_foreign + PARTITION OF fpo_part_parent FOR VALUES IN (6) + SERVER loopback OPTIONS (schema_name 'S 1', table_name 'T 5'); +DELETE FROM fpo_part_parent + FOR PORTION OF c4 FROM '2001-01-01' TO '2001-02-01' WHERE c2 = 6; -- error +UPDATE fpo_part_parent + FOR PORTION OF c4 FROM '2001-01-01' TO '2001-02-01' SET c3 = 'x' WHERE c2 = 6; -- error +UPDATE fpo_part_parent + FOR PORTION OF c4 FROM '2024-06-01' TO '2024-07-01' SET c3 = 'edited' WHERE c2 = 1; -- okay +DELETE FROM fpo_part_parent + FOR PORTION OF c4 FROM '2024-06-01' TO '2024-06-15' WHERE c2 = 1; -- okay +SELECT c1, c2, c3, c4 FROM fpo_part_local ORDER BY c4; +DROP TABLE fpo_part_parent; + -- Test UPDATE/DELETE with RETURNING on a three-table join INSERT INTO ft2 (c1,c2,c3) SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id; diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c index 0087585b2c4..80a527ed4c6 100644 --- a/src/backend/commands/copyfrom.c +++ b/src/backend/commands/copyfrom.c @@ -921,7 +921,7 @@ CopyFrom(CopyFromState cstate) ExecInitResultRelation(estate, resultRelInfo, 1); /* Verify the named relation is a valid target for INSERT */ - CheckValidResultRel(resultRelInfo, CMD_INSERT, ONCONFLICT_NONE, NIL); + CheckValidResultRel(resultRelInfo, CMD_INSERT, ONCONFLICT_NONE, NIL, NULL); ExecOpenIndices(resultRelInfo, false); diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 4b30f768680..c3af96989ba 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -1063,7 +1063,8 @@ InitPlan(QueryDesc *queryDesc, int eflags) */ void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation, - OnConflictAction onConflictAction, List *mergeActions) + OnConflictAction onConflictAction, List *mergeActions, + ModifyTable *mtnode) { Relation resultRel = resultRelInfo->ri_RelationDesc; FdwRoutine *fdwroutine; @@ -1126,6 +1127,14 @@ CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation, RelationGetRelationName(resultRel)))); break; case RELKIND_FOREIGN_TABLE: + /* We don't support FOR PORTION OF FDW queries. */ + if (mtnode && mtnode->forPortionOf) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("foreign tables don't support FOR PORTION OF"), + errdetail("\"%s\" is a foreign table.", + RelationGetRelationName(resultRel))); + /* Okay only if the FDW supports it */ fdwroutine = resultRelInfo->ri_FdwRoutine; switch (operation) diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index d96d4f9947b..33ec5bfde4c 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -368,7 +368,7 @@ ExecFindPartition(ModifyTableState *mtstate, /* Verify this ResultRelInfo allows INSERTs */ CheckValidResultRel(rri, CMD_INSERT, node ? node->onConflictAction : ONCONFLICT_NONE, - NIL); + NIL, node); /* * Initialize information needed to insert this and @@ -594,7 +594,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, * required when the operation is CMD_UPDATE. */ CheckValidResultRel(leaf_part_rri, CMD_INSERT, - node ? node->onConflictAction : ONCONFLICT_NONE, NIL); + node ? node->onConflictAction : ONCONFLICT_NONE, NIL, node); /* * Open partition indices. The user may have asked to check for conflicts diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 846dc516b43..c333d7139fa 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -5312,7 +5312,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) * Verify result relation is a valid target for the current operation */ CheckValidResultRel(resultRelInfo, operation, node->onConflictAction, - mergeActions); + mergeActions, node); resultRelInfo++; i++; diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 76758adefb6..dc65a505c16 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -1335,12 +1335,6 @@ transformForPortionOfClause(ParseState *pstate, ForPortionOfExpr *result; Var *rangeVar; - /* We don't support FOR PORTION OF FDW queries. */ - if (targetrel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("foreign tables don't support FOR PORTION OF"))); - result = makeNode(ForPortionOfExpr); /* Look up the FOR PORTION OF name requested. */ diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 650baab3efc..1798e6027d4 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -249,7 +249,7 @@ extern bool ExecCheckPermissions(List *rangeTable, extern bool ExecCheckOneRelPerms(RTEPermissionInfo *perminfo); extern void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation, OnConflictAction onConflictAction, - List *mergeActions); + List *mergeActions, ModifyTable *mtnode); extern void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, From effb923d9dec8fd4a5102fee80e52d65d86747c8 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sat, 27 Jun 2026 16:48:35 -0400 Subject: [PATCH 033/481] COPY TO FORMAT JSON: respect column list order When COPY TO with FORMAT json is given an explicit column list that names all columns in a different order, the JSON output incorrectly used the table's physical column order instead of the requested order. This happened because BeginCopyTo() only built a restricted TupleDesc when list_length(attnumlist) < tupDesc->natts. When all columns are listed (just reordered), this condition was false and no projected TupleDesc was built, causing CopyToJsonOneRow() to emit columns in physical order. Fix by also building the projected TupleDesc when an explicit column list was provided (attnamelist != NIL), even if it names all columns. Author: Baji Shaik Reviewed-by: Andrew Dunstan Discussion: https://postgr.es/m/CA+fm-ROd4cNKM524n6EdgtZ9xOzOHJDNv8J_9Mvr2+2t1qWSDw@mail.gmail.com --- src/backend/commands/copyto.c | 14 +++++++++----- src/test/regress/expected/copy.out | 9 +++++++++ src/test/regress/sql/copy.sql | 9 +++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c index 6755bb698de..d30cad019c7 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -1051,15 +1051,19 @@ BeginCopyTo(ParseState *pstate, { cstate->json_buf = makeStringInfo(); - if (rel && list_length(cstate->attnumlist) < tupDesc->natts) + /* + * Build a projected TupleDesc describing only the selected columns + * so that composite_to_json() emits the right column names and + * types; needed when an explicit column list was given (possibly + * with a different column order) or when generated columns are + * excluded from the output. + */ + if (rel && (attnamelist != NIL || + list_length(cstate->attnumlist) < tupDesc->natts)) { int natts = list_length(cstate->attnumlist); TupleDesc resultDesc; - /* - * Build a TupleDesc describing only the selected columns so that - * composite_to_json() emits the right column names and types. - */ resultDesc = CreateTemplateTupleDesc(natts); foreach_int(attnum, cstate->attnumlist) diff --git a/src/test/regress/expected/copy.out b/src/test/regress/expected/copy.out index 37498cdd6e7..ace38225623 100644 --- a/src/test/regress/expected/copy.out +++ b/src/test/regress/expected/copy.out @@ -73,6 +73,15 @@ copy copytest3 to stdout csv header; c1,"col with , comma","col with "" quote" 1,a,1 2,b,2 +-- testing explicit column order +create temp table copytest_order (a int, b int, c int); +copy copytest_order from stdin; +copy copytest_order (c, b, a) to stdout; +3 2 1 +copy copytest_order (c, b, a) to stdout (format csv); +3,2,1 +copy copytest_order (c, b, a) to stdout (format json); +{"c":3,"b":2,"a":1} --- test copying in JSON mode with various styles copy (select 1 union all select 2) to stdout with (format json); {"?column?":1} diff --git a/src/test/regress/sql/copy.sql b/src/test/regress/sql/copy.sql index 094fd76c12b..507b822946f 100644 --- a/src/test/regress/sql/copy.sql +++ b/src/test/regress/sql/copy.sql @@ -82,6 +82,15 @@ this is just a line full of junk that would error out if parsed copy copytest3 to stdout csv header; +-- testing explicit column order +create temp table copytest_order (a int, b int, c int); +copy copytest_order from stdin; +1 2 3 +\. +copy copytest_order (c, b, a) to stdout; +copy copytest_order (c, b, a) to stdout (format csv); +copy copytest_order (c, b, a) to stdout (format json); + --- test copying in JSON mode with various styles copy (select 1 union all select 2) to stdout with (format json); copy (select 1 as foo union all select 2) to stdout with (format json); From 0cd17fdd3c000f6e64e79da0fea5e65dc9f562df Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sat, 27 Jun 2026 17:42:51 -0400 Subject: [PATCH 034/481] Prevent inherited CHECK constraints from being weakened MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disallow marking an inherited CHECK constraint as NOT ENFORCED when an equivalent parent constraint remains ENFORCED. This prevents ALTER CONSTRAINT from producing a child constraint that is weaker than one of its inherited parent definitions. When recursively altering a CHECK constraint to NOT ENFORCED, collect the corresponding constraints in the affected inheritance subtree and ignore those parent constraints while checking descendants. If a descendant also inherits an equivalent ENFORCED constraint from a parent outside the current ALTER, keep the descendant ENFORCED by merging to the stricter state. This was missed in commit 342051d73b3, which introduced the ability to alter CHECK constraint enforceability. Add regression coverage for direct child ALTER, ONLY ALTER, mixed-parent inheritance, and a common-ancestor diamond where all equivalent inherited constraints can be changed together. Author: Chao Li Reviewed-by: Jian He Reviewed-by: Zsolt Parragi Reviewed-by: Álvaro Herrera Discussion: https://postgr.es/m/E74C57FA-1DD0-4C8E-8FB1-538034752592@gmail.com --- src/backend/commands/tablecmds.c | 256 ++++++++++++++++++++-- src/test/regress/expected/constraints.out | 15 +- src/test/regress/expected/inherit.out | 92 ++++++++ src/test/regress/sql/constraints.sql | 5 +- src/test/regress/sql/inherit.sql | 52 +++++ 5 files changed, 395 insertions(+), 25 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 33e065d61ce..472db112fa7 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -437,6 +437,7 @@ static bool ATExecAlterFKConstrEnforceability(List **wqueue, ATAlterConstraint * static bool ATExecAlterCheckConstrEnforceability(List **wqueue, ATAlterConstraint *cmdcon, Relation conrel, HeapTuple contuple, bool recurse, bool recursing, + List *changing_conids, LOCKMODE lockmode); static bool ATExecAlterConstrDeferrability(List **wqueue, ATAlterConstraint *cmdcon, Relation conrel, Relation tgrel, Relation rel, @@ -459,6 +460,7 @@ static void AlterFKConstrEnforceabilityRecurse(List **wqueue, ATAlterConstraint static void AlterCheckConstrEnforceabilityRecurse(List **wqueue, ATAlterConstraint *cmdcon, Relation conrel, Oid conrelid, bool recurse, bool recursing, + List *changing_conids, LOCKMODE lockmode); static void AlterConstrDeferrabilityRecurse(List **wqueue, ATAlterConstraint *cmdcon, Relation conrel, Relation tgrel, Relation rel, @@ -466,6 +468,10 @@ static void AlterConstrDeferrabilityRecurse(List **wqueue, ATAlterConstraint *cm List **otherrelids, LOCKMODE lockmode); static void AlterConstrUpdateConstraintEntry(ATAlterConstraint *cmdcon, Relation conrel, HeapTuple contuple); +static bool ATCheckCheckConstrHasEnforcedParent(Relation conrel, Relation rel, + HeapTuple contuple, + List *changing_conids, + Oid *enforced_parentoid); static ObjectAddress ATExecValidateConstraint(List **wqueue, Relation rel, char *constrName, bool recurse, bool recursing, LOCKMODE lockmode); @@ -477,6 +483,7 @@ static void QueueCheckConstraintValidation(List **wqueue, Relation conrel, Relat static void QueueNNConstraintValidation(List **wqueue, Relation conrel, Relation rel, HeapTuple contuple, bool recurse, bool recursing, LOCKMODE lockmode); +static bool constraints_equivalent(HeapTuple a, HeapTuple b, TupleDesc tupleDesc); static int transformColumnNameList(Oid relId, List *colList, int16 *attnums, Oid *atttypids, Oid *attcollids); static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid, @@ -12459,7 +12466,7 @@ ATExecAlterConstraintInternal(List **wqueue, ATAlterConstraint *cmdcon, else if (currcon->contype == CONSTRAINT_CHECK) changed = ATExecAlterCheckConstrEnforceability(wqueue, cmdcon, conrel, contuple, recurse, false, - lockmode); + NIL, lockmode); } else if (cmdcon->alterDeferrability && ATExecAlterConstrDeferrability(wqueue, cmdcon, conrel, tgrel, rel, @@ -12646,12 +12653,16 @@ ATExecAlterFKConstrEnforceability(List **wqueue, ATAlterConstraint *cmdcon, static bool ATExecAlterCheckConstrEnforceability(List **wqueue, ATAlterConstraint *cmdcon, Relation conrel, HeapTuple contuple, - bool recurse, bool recursing, LOCKMODE lockmode) + bool recurse, bool recursing, + List *changing_conids, + LOCKMODE lockmode) { Form_pg_constraint currcon; Relation rel; bool changed = false; List *children = NIL; + bool target_enforced = cmdcon->is_enforced; + Oid enforced_parentoid = InvalidOid; /* Since this function recurses, it could be driven to stack overflow */ check_stack_depth(); @@ -12668,16 +12679,57 @@ ATExecAlterCheckConstrEnforceability(List **wqueue, ATAlterConstraint *cmdcon, */ rel = table_open(currcon->conrelid, NoLock); - if (currcon->conenforced != cmdcon->is_enforced) + /* + * When setting a constraint to NOT ENFORCED, check whether any matching + * parent constraint remains ENFORCED and is not part of this ALTER. + * + * For a direct ALTER of an inherited constraint, reject the command, + * because the child cannot be weakened while its parent remains enforced. + * + * During recursion, another parent outside this ALTER may still enforce + * the same constraint in a regular inheritance hierarchy. In that case, + * keep the child constraint ENFORCED so that its merged enforceability + * still reflects the remaining enforced parent. Partitions do not need + * this recursive parent check because a partition can have only one + * direct parent. + */ + if (!cmdcon->is_enforced && + (!recursing || !rel->rd_rel->relispartition) && + ATCheckCheckConstrHasEnforcedParent(conrel, rel, contuple, + changing_conids, + &enforced_parentoid)) { - AlterConstrUpdateConstraintEntry(cmdcon, conrel, contuple); + if (!recursing) + ereport(ERROR, + errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("cannot mark inherited constraint \"%s\" as %s", + NameStr(currcon->conname), + "NOT ENFORCED"), + errdetail("The matching constraint on parent table \"%s\" is %s.", + get_rel_name(enforced_parentoid), "ENFORCED")); + + target_enforced = true; + } + + /* + * Update to the merged enforceability if needed. This may differ from the + * requested enforceability when another matching parent constraint + * remains enforced. + */ + if (currcon->conenforced != target_enforced) + { + ATAlterConstraint updatecon = *cmdcon; + + updatecon.is_enforced = target_enforced; + AlterConstrUpdateConstraintEntry(&updatecon, conrel, contuple); changed = true; } /* * Note that we must recurse even when trying to change a check constraint * to not enforced if it is already not enforced, in case descendant - * constraints might be enforced and need to be changed to not enforced. + * constraints might be enforced and need to be changed to not enforced, + * unless they still inherit an enforced constraint from another parent. * Conversely, we should do nothing if a constraint is being set to * enforced and is already enforced, as descendant constraints cannot be * different in that case. @@ -12690,28 +12742,66 @@ ATExecAlterCheckConstrEnforceability(List **wqueue, ATAlterConstraint *cmdcon, * try to look for it in the children. */ if (!recursing && !currcon->connoinherit) + { + Assert(changing_conids == NIL); + children = find_all_inheritors(RelationGetRelid(rel), lockmode, NULL); + /* + * When setting NOT ENFORCED, build the set of equivalent CHECK + * constraints that this command will attempt to change before + * visiting descendants. The root itself has already been checked + * above. + */ + if (!cmdcon->is_enforced) + changing_conids = list_make1_oid(currcon->oid); + + foreach_oid(childoid, children) + { + if (childoid == RelationGetRelid(rel)) + continue; + + /* + * If we are told not to recurse, there had better not be any + * child tables, because we can't change constraint + * enforceability on the parent unless we have changed + * enforceability for all child. + */ + if (!recurse) + ereport(ERROR, + errcode(ERRCODE_INVALID_TABLE_DEFINITION), + errmsg("constraint must be altered on child tables too"), + errhint("Do not specify the ONLY keyword.")); + + /* + * It is sufficient to look up the constraint by name here. + * Supported DDL ensures that inheritable CHECK constraints + * with the same name have equivalent definitions when they + * are propagated to children or when inheritance is + * established. All descendants returned by + * find_all_inheritors must have this constraint: inherited + * CHECK constraints propagate to all children at + * inheritance-link creation time and cannot be dropped + * independently on child tables. + */ + if (!cmdcon->is_enforced) + changing_conids = + list_append_unique_oid(changing_conids, + get_relation_constraint_oid(childoid, + cmdcon->conname, + false)); + } + } + foreach_oid(childoid, children) { if (childoid == RelationGetRelid(rel)) continue; - /* - * If we are told not to recurse, there had better not be any - * child tables, because we can't change constraint enforceability - * on the parent unless we have changed enforceability for all - * child. - */ - if (!recurse) - ereport(ERROR, - errcode(ERRCODE_INVALID_TABLE_DEFINITION), - errmsg("constraint must be altered on child tables too"), - errhint("Do not specify the ONLY keyword.")); - AlterCheckConstrEnforceabilityRecurse(wqueue, cmdcon, conrel, childoid, false, true, + changing_conids, lockmode); } } @@ -12723,7 +12813,7 @@ ATExecAlterCheckConstrEnforceability(List **wqueue, ATAlterConstraint *cmdcon, */ if (rel->rd_rel->relkind == RELKIND_RELATION && !currcon->conenforced && - cmdcon->is_enforced) + target_enforced) { AlteredTableInfo *tab; NewConstraint *newcon; @@ -12763,6 +12853,7 @@ static void AlterCheckConstrEnforceabilityRecurse(List **wqueue, ATAlterConstraint *cmdcon, Relation conrel, Oid conrelid, bool recurse, bool recursing, + List *changing_conids, LOCKMODE lockmode) { SysScanDesc pscan; @@ -12792,11 +12883,138 @@ AlterCheckConstrEnforceabilityRecurse(List **wqueue, ATAlterConstraint *cmdcon, cmdcon->conname, get_rel_name(conrelid))); ATExecAlterCheckConstrEnforceability(wqueue, cmdcon, conrel, childtup, - recurse, recursing, lockmode); + recurse, recursing, changing_conids, + lockmode); systable_endscan(pscan); } +/* + * When setting an inherited CHECK constraint to NOT ENFORCED, look for a + * matching parent constraint that remains ENFORCED and is not part of the same + * ALTER. + */ +static bool +ATCheckCheckConstrHasEnforcedParent(Relation conrel, Relation rel, + HeapTuple contuple, + List *changing_conids, + Oid *enforced_parentoid) +{ + Form_pg_constraint currcon; + Relation inhrel; + SysScanDesc scan; + ScanKeyData skey; + HeapTuple inheritsTuple; + + /* Since this function recurses, it could be driven to stack overflow */ + check_stack_depth(); + + currcon = (Form_pg_constraint) GETSTRUCT(contuple); + Assert(currcon->contype == CONSTRAINT_CHECK); + + if (currcon->coninhcount <= 0) + return false; + + inhrel = table_open(InheritsRelationId, AccessShareLock); + + ScanKeyInit(&skey, + Anum_pg_inherits_inhrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(rel))); + scan = systable_beginscan(inhrel, InheritsRelidSeqnoIndexId, + true, NULL, 1, &skey); + + while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan))) + { + Oid parentoid; + Relation parentrel = NULL; + SysScanDesc pscan; + ScanKeyData pkey[3]; + HeapTuple parenttup; + + parentoid = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhparent; + + ScanKeyInit(&pkey[0], + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(parentoid)); + ScanKeyInit(&pkey[1], + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + ScanKeyInit(&pkey[2], + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(&currcon->conname)); + + pscan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, + true, NULL, 3, pkey); + + /* + * ConstraintRelidTypidNameIndexId is unique on (conrelid, contypid, + * conname), so this loop body executes at most once per parent. + */ + while (HeapTupleIsValid(parenttup = systable_getnext(pscan))) + { + Form_pg_constraint parentcon; + + parentcon = (Form_pg_constraint) GETSTRUCT(parenttup); + + if (parentcon->contype != CONSTRAINT_CHECK || + parentcon->connoinherit || + !parentcon->conenforced) + continue; + + if (!constraints_equivalent(parenttup, contuple, + RelationGetDescr(conrel))) + elog(ERROR, "child table \"%s\" has different definition for check constraint \"%s\"", + RelationGetRelationName(rel), + NameStr(parentcon->conname)); + + /* + * A parent listed in changing_conids is being changed by the same + * ALTER, but it may not have been updated yet. For regular + * inheritance, recurse upward to check whether an equivalent + * enforced parent outside the ALTER will make it remain enforced. + * Partitions cannot have multiple parents, so they do not need + * this check. + */ + if (!rel->rd_rel->relispartition && + list_member_oid(changing_conids, parentcon->oid)) + { + Oid parent_enforced_parentoid = InvalidOid; + + if (parentrel == NULL) + parentrel = table_open(parentoid, NoLock); + + if (!ATCheckCheckConstrHasEnforcedParent(conrel, + parentrel, + parenttup, + changing_conids, + &parent_enforced_parentoid)) + continue; + } + + *enforced_parentoid = parentoid; + if (parentrel != NULL) + table_close(parentrel, NoLock); + systable_endscan(pscan); + systable_endscan(scan); + table_close(inhrel, AccessShareLock); + return true; + } + + if (parentrel != NULL) + table_close(parentrel, NoLock); + systable_endscan(pscan); + } + + systable_endscan(scan); + table_close(inhrel, AccessShareLock); + + return false; +} + /* * Returns true if the constraint's deferrability is altered. * diff --git a/src/test/regress/expected/constraints.out b/src/test/regress/expected/constraints.out index e54fec7fb57..83f97f684d5 100644 --- a/src/test/regress/expected/constraints.out +++ b/src/test/regress/expected/constraints.out @@ -446,8 +446,15 @@ alter table parted_ch_2 alter constraint cc_2 enforced; --error ERROR: check constraint "cc_2" of relation "parted_ch_2" is violated by some row delete from parted_ch where a = 16; alter table parted_ch_2 alter constraint cc_2 enforced; -alter table parted_ch_2 alter constraint cc not enforced; -alter table parted_ch_2 alter constraint cc_1 not enforced; +alter table parted_ch_2 alter constraint cc not enforced; --error +ERROR: cannot mark inherited constraint "cc" as NOT ENFORCED +DETAIL: The matching constraint on parent table "parted_ch" is ENFORCED. +alter table only parted_ch_2 alter constraint cc not enforced; --error +ERROR: cannot mark inherited constraint "cc" as NOT ENFORCED +DETAIL: The matching constraint on parent table "parted_ch" is ENFORCED. +alter table parted_ch_2 alter constraint cc_1 not enforced; --error +ERROR: cannot mark inherited constraint "cc_1" as NOT ENFORCED +DETAIL: The matching constraint on parent table "parted_ch" is ENFORCED. alter table parted_ch_2 alter constraint cc_2 not enforced; --check these CHECK constraint status again select * from check_constraint_status; @@ -457,12 +464,12 @@ select * from check_constraint_status; cc | parted_ch_1 | t | t cc | parted_ch_11 | t | t cc | parted_ch_12 | t | t - cc | parted_ch_2 | f | f + cc | parted_ch_2 | t | t cc_1 | parted_ch | t | t cc_1 | parted_ch_1 | t | t cc_1 | parted_ch_11 | t | t cc_1 | parted_ch_12 | t | t - cc_1 | parted_ch_2 | f | f + cc_1 | parted_ch_2 | t | t cc_2 | parted_ch_2 | f | f (11 rows) diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out index 3d8e8d8afd2..3c2ff55d3ba 100644 --- a/src/test/regress/expected/inherit.out +++ b/src/test/regress/expected/inherit.out @@ -1479,6 +1479,98 @@ NOTICE: drop cascades to 3 other objects DETAIL: drop cascades to table p1_c1 drop cascades to table p1_c2 drop cascades to table p1_c3 +-- an inherited CHECK constraint cannot be NOT ENFORCED under an ENFORCED parent +create table p1(f1 int constraint p1_a_check check (f1 > 0) enforced); +create table p1_c1() inherits(p1); +alter table p1_c1 alter constraint p1_a_check not enforced; --error +ERROR: cannot mark inherited constraint "p1_a_check" as NOT ENFORCED +DETAIL: The matching constraint on parent table "p1" is ENFORCED. +alter table p1 alter constraint p1_a_check not enforced; --ok +alter table p1_c1 alter constraint p1_a_check not enforced; --ok +drop table p1 cascade; +NOTICE: drop cascades to table p1_c1 +-- recursive NOT ENFORCED merges with ENFORCED constraints from other parents +create table p1(a int constraint p1_a_check check (a > 0) enforced); +create table p2(a int constraint p1_a_check check (a > 0) enforced); +create table p1_c1() inherits (p1, p2); +NOTICE: merging multiple inherited definitions of column "a" +-- make p1_c1_g2's oid smaller than p1_c1_g1's, to ensure ordering of +-- pg_constraint rows to not impact the test results. +create table p1_c1_g2() inherits (p1_c1); +create table p1_c1_g1() inherits (p1_c1); +alter table p1_c1_g2 inherit p1_c1_g1; +create table p1_c2() inherits (p1); +alter table p1 alter constraint p1_a_check not enforced; --ok +select conname, conenforced, convalidated, conrelid::regclass +from pg_constraint +where conname = 'p1_a_check' and contype = 'c' +order by conrelid::regclass::text collate "C"; + conname | conenforced | convalidated | conrelid +------------+-------------+--------------+---------- + p1_a_check | f | f | p1 + p1_a_check | t | t | p1_c1 + p1_a_check | t | t | p1_c1_g1 + p1_a_check | t | t | p1_c1_g2 + p1_a_check | f | f | p1_c2 + p1_a_check | t | t | p2 +(6 rows) + +alter table p1_c1 alter constraint p1_a_check not enforced; --error +ERROR: cannot mark inherited constraint "p1_a_check" as NOT ENFORCED +DETAIL: The matching constraint on parent table "p2" is ENFORCED. +alter table p2 alter constraint p1_a_check not enforced; --ok +alter table p1_c1 alter constraint p1_a_check not enforced; --ok +drop table p1, p2 cascade; +NOTICE: drop cascades to 4 other objects +DETAIL: drop cascades to table p1_c1 +drop cascades to table p1_c1_g1 +drop cascades to table p1_c1_g2 +drop cascades to table p1_c2 +-- recursive NOT ENFORCED can change all matching enforced parents together +create table gp(a int constraint gp_a_check check (a > 0) enforced); +create table p1() inherits (gp); +create table p2() inherits (gp); +create table p1_c1() inherits (p1, p2); +NOTICE: merging multiple inherited definitions of column "a" +alter table gp alter constraint gp_a_check not enforced; --ok +select conname, conenforced, convalidated, conrelid::regclass +from pg_constraint +where conname = 'gp_a_check' and contype = 'c' +order by conrelid::regclass::text collate "C"; + conname | conenforced | convalidated | conrelid +------------+-------------+--------------+---------- + gp_a_check | f | f | gp + gp_a_check | f | f | p1 + gp_a_check | f | f | p1_c1 + gp_a_check | f | f | p2 +(4 rows) + +drop table gp cascade; +NOTICE: drop cascades to 3 other objects +DETAIL: drop cascades to table p1 +drop cascades to table p2 +drop cascades to table p1_c1 +-- recursive NOT ENFORCED can change a direct-plus-indirect diamond together +create table gp(a int constraint gp_a_check check (a > 0) enforced); +create table p1_c1() inherits (gp); +create table p1() inherits (gp); +alter table p1_c1 inherit p1; +alter table gp alter constraint gp_a_check not enforced; --ok +select conname, conenforced, convalidated, conrelid::regclass +from pg_constraint +where conname = 'gp_a_check' and contype = 'c' +order by conrelid::regclass::text collate "C"; + conname | conenforced | convalidated | conrelid +------------+-------------+--------------+---------- + gp_a_check | f | f | gp + gp_a_check | f | f | p1 + gp_a_check | f | f | p1_c1 +(3 rows) + +drop table gp cascade; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to table p1 +drop cascades to table p1_c1 --for "no inherit" check constraint, it will not recurse to child table create table p1(f1 int constraint p1_a_check check (f1 > 0) no inherit not enforced); create table p1_c1(f1 int constraint p1_a_check check (f1 > 0) not enforced); diff --git a/src/test/regress/sql/constraints.sql b/src/test/regress/sql/constraints.sql index dc133b124bb..9705962eb9f 100644 --- a/src/test/regress/sql/constraints.sql +++ b/src/test/regress/sql/constraints.sql @@ -309,8 +309,9 @@ select * from check_constraint_status; alter table parted_ch_2 alter constraint cc_2 enforced; --error delete from parted_ch where a = 16; alter table parted_ch_2 alter constraint cc_2 enforced; -alter table parted_ch_2 alter constraint cc not enforced; -alter table parted_ch_2 alter constraint cc_1 not enforced; +alter table parted_ch_2 alter constraint cc not enforced; --error +alter table only parted_ch_2 alter constraint cc not enforced; --error +alter table parted_ch_2 alter constraint cc_1 not enforced; --error alter table parted_ch_2 alter constraint cc_2 not enforced; --check these CHECK constraint status again diff --git a/src/test/regress/sql/inherit.sql b/src/test/regress/sql/inherit.sql index 8f986904389..072fca13c13 100644 --- a/src/test/regress/sql/inherit.sql +++ b/src/test/regress/sql/inherit.sql @@ -535,6 +535,58 @@ where conname = 'inh_check_constraint3' and contype = 'c' order by conrelid::regclass::text collate "C"; drop table p1 cascade; +-- an inherited CHECK constraint cannot be NOT ENFORCED under an ENFORCED parent +create table p1(f1 int constraint p1_a_check check (f1 > 0) enforced); +create table p1_c1() inherits(p1); +alter table p1_c1 alter constraint p1_a_check not enforced; --error +alter table p1 alter constraint p1_a_check not enforced; --ok +alter table p1_c1 alter constraint p1_a_check not enforced; --ok +drop table p1 cascade; + +-- recursive NOT ENFORCED merges with ENFORCED constraints from other parents +create table p1(a int constraint p1_a_check check (a > 0) enforced); +create table p2(a int constraint p1_a_check check (a > 0) enforced); +create table p1_c1() inherits (p1, p2); +-- make p1_c1_g2's oid smaller than p1_c1_g1's, to ensure ordering of +-- pg_constraint rows to not impact the test results. +create table p1_c1_g2() inherits (p1_c1); +create table p1_c1_g1() inherits (p1_c1); +alter table p1_c1_g2 inherit p1_c1_g1; +create table p1_c2() inherits (p1); +alter table p1 alter constraint p1_a_check not enforced; --ok +select conname, conenforced, convalidated, conrelid::regclass +from pg_constraint +where conname = 'p1_a_check' and contype = 'c' +order by conrelid::regclass::text collate "C"; +alter table p1_c1 alter constraint p1_a_check not enforced; --error +alter table p2 alter constraint p1_a_check not enforced; --ok +alter table p1_c1 alter constraint p1_a_check not enforced; --ok +drop table p1, p2 cascade; + +-- recursive NOT ENFORCED can change all matching enforced parents together +create table gp(a int constraint gp_a_check check (a > 0) enforced); +create table p1() inherits (gp); +create table p2() inherits (gp); +create table p1_c1() inherits (p1, p2); +alter table gp alter constraint gp_a_check not enforced; --ok +select conname, conenforced, convalidated, conrelid::regclass +from pg_constraint +where conname = 'gp_a_check' and contype = 'c' +order by conrelid::regclass::text collate "C"; +drop table gp cascade; + +-- recursive NOT ENFORCED can change a direct-plus-indirect diamond together +create table gp(a int constraint gp_a_check check (a > 0) enforced); +create table p1_c1() inherits (gp); +create table p1() inherits (gp); +alter table p1_c1 inherit p1; +alter table gp alter constraint gp_a_check not enforced; --ok +select conname, conenforced, convalidated, conrelid::regclass +from pg_constraint +where conname = 'gp_a_check' and contype = 'c' +order by conrelid::regclass::text collate "C"; +drop table gp cascade; + --for "no inherit" check constraint, it will not recurse to child table create table p1(f1 int constraint p1_a_check check (f1 > 0) no inherit not enforced); create table p1_c1(f1 int constraint p1_a_check check (f1 > 0) not enforced); From d16be8605f5f699020fe4e6eaef008a41407a9bb Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sat, 27 Jun 2026 17:43:02 -0400 Subject: [PATCH 035/481] doc: Clarify inherited constraint behavior Update the table inheritance documentation to mention not-null constraints alongside check constraints where inherited constraints are discussed. Also clarify that some properties of inherited constraints can now be altered directly on child tables, while the resulting constraint must remain compatible with its inherited parent constraints. For multiple inheritance, say explicitly that when a column or constraint is inherited from more than one parent, the stricter definition applies. Author: Chao Li Reviewed-by: Zsolt Parragi Discussion: https://postgr.es/m/E74C57FA-1DD0-4C8E-8FB1-538034752592@gmail.com --- doc/src/sgml/ddl.sgml | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index 45db20d47d8..fbd0ebbf10f 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -4090,7 +4090,9 @@ VALUES ('Albany', NULL, NULL, 'NY'); similar fashion. Thus, for example, a merged column will be marked not-null if any one of the column definitions it came from is marked not-null. Check constraints are merged if they have the same name, - and the merge will fail if their conditions are different. + and the merge will fail if their conditions are different. For merged + check constraints, stricter enforceability is preserved: if any inherited + copy is enforced, the merged constraint is enforced. @@ -4104,8 +4106,9 @@ VALUES ('Albany', NULL, NULL, 'NY'); To do this the new child table must already include columns with the same names and types as the columns of the parent. It must also include check constraints with the same names and check expressions as those of the - parent. Similarly an inheritance link can be removed from a child using the - NO INHERIT variant of ALTER TABLE. + parent, as well as matching not-null constraints. Similarly an inheritance + link can be removed from a child using the NO INHERIT + variant of ALTER TABLE. Dynamically adding and removing inheritance links like this can be useful when the inheritance relationship is being used for table partitioning (see ). @@ -4124,21 +4127,23 @@ VALUES ('Albany', NULL, NULL, 'NY'); A parent table cannot be dropped while any of its children remain. Neither - can columns or check constraints of child tables be dropped or altered - if they are inherited - from any parent tables. If you wish to remove a table and all of its - descendants, one easy way is to drop the parent table with the - CASCADE option (see ). + can inherited columns or inherited check and not-null constraints of child + tables be dropped directly. Some properties of inherited constraints can + be altered, but each resulting constraint must remain compatible with all + parent constraints from which it is inherited. If you wish to remove a + table and all of its descendants, one easy way is to drop the parent table + with the CASCADE option (see ). ALTER TABLE will - propagate any changes in column data definitions and check - constraints down the inheritance hierarchy. Again, dropping - columns that are depended on by other tables is only possible when using - the CASCADE option. ALTER - TABLE follows the same rules for duplicate column merging - and rejection that apply during CREATE TABLE. + propagate changes in column definitions and in inheritable constraints + (check and not-null constraints) down the inheritance hierarchy. Again, + dropping columns that are depended on by other tables is only possible + when using the CASCADE option. ALTER + TABLE follows the same rules for merging or rejecting duplicate + inherited column and constraint definitions that apply during + CREATE TABLE. From f03ecd26396423cc38898b2479586c7c89ac9a1c Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sat, 27 Jun 2026 17:43:02 -0400 Subject: [PATCH 036/481] doc: Clarify ALTER CONSTRAINT enforceability behavior The ALTER TABLE documentation said that FOREIGN KEY and CHECK constraints may be altered, but did not distinguish between deferrability and enforceability attributes. Clarify that deferrability attributes can currently be altered only for FOREIGN KEY constraints, while enforceability can be altered for both FOREIGN KEY and CHECK constraints. Also document that setting a constraint to ENFORCED verifies existing rows and resumes checking new or updated rows. Author: Chao Li Reviewed-by: Zsolt Parragi Discussion: https://postgr.es/m/E74C57FA-1DD0-4C8E-8FB1-538034752592@gmail.com Discussion: https://postgr.es/m/711B1ED3-1781-4B6C-A573-B58AF20770E5@gmail.com --- doc/src/sgml/ref/alter_table.sgml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index 67a05593140..6dd518752c0 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -586,8 +586,18 @@ WITH ( MODULUS numeric_literal, REM This form alters the attributes of a constraint that was previously - created. Currently FOREIGN KEY and CHECK - constraints may be altered in this fashion, but see below. + created. Currently, the deferrability attributes can be altered only + for FOREIGN KEY constraints. The enforceability + attribute can be altered for FOREIGN KEY and + CHECK constraints. + + + + Setting a constraint to NOT ENFORCED causes the + database system to stop checking it for new or updated rows. Setting + a constraint to ENFORCED causes the database system + to verify that existing rows satisfy the constraint and to check it + for new or updated rows. From 02f699c1416380c0411fbc0f53061f86b2f52ed3 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sat, 27 Jun 2026 19:57:41 -0400 Subject: [PATCH 037/481] pgindent fix for commit effb923d9de --- src/backend/commands/copyto.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c index d30cad019c7..d3adc752ae3 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -1052,11 +1052,11 @@ BeginCopyTo(ParseState *pstate, cstate->json_buf = makeStringInfo(); /* - * Build a projected TupleDesc describing only the selected columns - * so that composite_to_json() emits the right column names and - * types; needed when an explicit column list was given (possibly - * with a different column order) or when generated columns are - * excluded from the output. + * Build a projected TupleDesc describing only the selected columns so + * that composite_to_json() emits the right column names and types; + * needed when an explicit column list was given (possibly with a + * different column order) or when generated columns are excluded from + * the output. */ if (rel && (attnamelist != NIL || list_length(cstate->attnumlist) < tupDesc->natts)) From d6ed87d19890b1cfa93d1f6e8957fa525834c0e2 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Fri, 26 Jun 2026 08:00:39 -0400 Subject: [PATCH 038/481] Use named boolean parameters for pg_get_*_ddl option arguments Replace the VARIADIC text[] alternating key/value option interface with typed named boolean parameters for pg_get_role_ddl(), pg_get_tablespace_ddl(), and pg_get_database_ddl(), as added by commit 4881981f920 and friends. The new signatures are: pg_get_role_ddl(role regrole, pretty boolean DEFAULT false, memberships boolean DEFAULT true) pg_get_tablespace_ddl(tablespace oid/name, pretty boolean DEFAULT false, owner boolean DEFAULT true) pg_get_database_ddl(db regdatabase, pretty boolean DEFAULT false, owner boolean DEFAULT true, tablespace boolean DEFAULT true) This provides type safety at the SQL level, allows named-argument calling syntax (pretty => true), removes the runtime string-parsing machinery (DdlOption, parse_ddl_options) in favour of direct PG_GETARG_BOOL() calls, and allows the functions to be marked STRICT. While we're here, I added an extra TAP test for pg_get_database(owner => false, ...) Catalog version bumped. Author: Jelte Fennema-Nio Discussion: https://postgr.es/m/DHM6C7SLS4BN.1WW9Z4PRPN0VJ@jeltef.nl (and on Discord) --- doc/src/sgml/func/func-info.sgml | 54 ++-- src/backend/utils/adt/ddlutils.c | 260 ++----------------- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 41 ++- src/test/modules/test_misc/t/012_ddlutils.pl | 28 +- 5 files changed, 95 insertions(+), 290 deletions(-) diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml index 211bc8b238b..bc80bcbd0b3 100644 --- a/doc/src/sgml/func/func-info.sgml +++ b/doc/src/sgml/func/func-info.sgml @@ -3856,9 +3856,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} reconstruct DDL statements for various global database objects. Each function returns a set of text rows, one SQL statement per row. (This is a decompiled reconstruction, not the original text of the - command.) Functions that accept VARIADIC options - take alternating name/value text pairs; values are parsed as boolean, - integer or text. + command.) @@ -3883,8 +3881,10 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} pg_get_role_ddl ( roleregrole - , VARIADIC options - text[] ) + , pretty boolean + DEFAULT false + , memberships boolean + DEFAULT true ) setof text @@ -3892,10 +3892,10 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} ALTER ROLE ... SET statements for the given role. Each statement is returned as a separate row. Password information is never included in the output. - The following options are supported: pretty (boolean) - for pretty-printed output and memberships (boolean, - default true) to include GRANT statements for - role memberships and their options. + When pretty is true, the output is + pretty-printed. When memberships is false, + GRANT statements for role memberships are + omitted. @@ -3905,15 +3905,19 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} pg_get_tablespace_ddl ( tablespace oid - , VARIADIC options - text[] ) + , pretty boolean + DEFAULT false + , owner boolean + DEFAULT true ) setof text pg_get_tablespace_ddl ( tablespace name - , VARIADIC options - text[] ) + , pretty boolean + DEFAULT false + , owner boolean + DEFAULT true ) setof text @@ -3921,9 +3925,9 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} the specified tablespace (by OID or name). If the tablespace has options set, an ALTER TABLESPACE ... SET statement is also returned. Each statement is returned as a separate row. - The following options are supported: pretty (boolean) - for formatted output and owner (boolean) to include - OWNER. + When pretty is true, the output is + pretty-printed. When owner is false, the + OWNER clause is omitted. @@ -3933,8 +3937,12 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} pg_get_database_ddl ( database regdatabase - , VARIADIC options - text[] ) + , pretty boolean + DEFAULT false + , owner boolean + DEFAULT true + , tablespace boolean + DEFAULT true ) setof text @@ -3942,11 +3950,11 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} specified database, followed by ALTER DATABASE statements for connection limit, template status, and configuration settings. Each statement is returned as a separate row. - The following options are supported: - pretty (boolean) for formatted output, - owner (boolean) to include OWNER, - and tablespace (boolean) to include - TABLESPACE. + When pretty is true, the output is + pretty-printed. When owner is false, the + OWNER clause is omitted. When + tablespace is false, the + TABLESPACE clause is omitted. diff --git a/src/backend/utils/adt/ddlutils.c b/src/backend/utils/adt/ddlutils.c index f32fcd453ef..a70f1c28655 100644 --- a/src/backend/utils/adt/ddlutils.c +++ b/src/backend/utils/adt/ddlutils.c @@ -33,7 +33,6 @@ #include "mb/pg_wchar.h" #include "miscadmin.h" #include "utils/acl.h" -#include "utils/array.h" #include "utils/builtins.h" #include "utils/datetime.h" #include "utils/fmgroids.h" @@ -46,35 +45,6 @@ #include "utils/timestamp.h" #include "utils/varlena.h" -/* Option value types for DDL option parsing */ -typedef enum -{ - DDL_OPT_BOOL, - DDL_OPT_TEXT, - DDL_OPT_INT, -} DdlOptType; - -/* - * A single DDL option descriptor: caller fills in name and type, - * parse_ddl_options fills in isset + the appropriate value field. - */ -typedef struct DdlOption -{ - const char *name; /* option name (case-insensitive match) */ - DdlOptType type; /* expected value type */ - bool isset; /* true if caller supplied this option */ - /* fields for specific option types */ - union - { - bool boolval; /* filled in for DDL_OPT_BOOL */ - char *textval; /* filled in for DDL_OPT_TEXT (palloc'd) */ - int intval; /* filled in for DDL_OPT_INT */ - }; -} DdlOption; - - -static void parse_ddl_options(FunctionCallInfo fcinfo, int variadic_start, - DdlOption *opts, int nopts); static void append_ddl_option(StringInfo buf, bool pretty, int indent, const char *fmt, ...) pg_attribute_printf(4, 5); @@ -83,150 +53,11 @@ static void append_guc_value(StringInfo buf, const char *name, static List *pg_get_role_ddl_internal(Oid roleid, bool pretty, bool memberships); static List *pg_get_tablespace_ddl_internal(Oid tsid, bool pretty, bool no_owner); -static Datum pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid, bool isnull); +static Datum pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid); static List *pg_get_database_ddl_internal(Oid dbid, bool pretty, bool no_owner, bool no_tablespace); -/* - * parse_ddl_options - * Parse variadic name/value option pairs - * - * Options are passed as alternating key/value text pairs. The caller - * provides an array of DdlOption descriptors specifying the accepted - * option names and their types; this function matches each supplied - * pair against the array, validates the value, and fills in the - * result fields. - */ -static void -parse_ddl_options(FunctionCallInfo fcinfo, int variadic_start, - DdlOption *opts, int nopts) -{ - Datum *args; - bool *nulls; - Oid *types; - int nargs; - - /* Clear all output fields */ - for (int i = 0; i < nopts; i++) - { - opts[i].isset = false; - switch (opts[i].type) - { - case DDL_OPT_BOOL: - opts[i].boolval = false; - break; - case DDL_OPT_TEXT: - opts[i].textval = NULL; - break; - case DDL_OPT_INT: - opts[i].intval = 0; - break; - } - } - - nargs = extract_variadic_args(fcinfo, variadic_start, true, - &args, &types, &nulls); - - if (nargs <= 0) - return; - - /* Handle DEFAULT NULL case */ - if (nargs == 1 && nulls[0]) - return; - - if (nargs % 2 != 0) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("variadic arguments must be name/value pairs"), - errhint("Provide an even number of variadic arguments that can be divided into pairs."))); - - /* - * For each option name/value pair, find corresponding positional option - * for the option name, and assign the option value. - */ - for (int i = 0; i < nargs; i += 2) - { - char *name; - char *valstr; - DdlOption *opt = NULL; - - if (nulls[i]) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("option name at variadic position %d is null", i + 1))); - - name = TextDatumGetCString(args[i]); - - if (nulls[i + 1]) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("value for option \"%s\" must not be null", name))); - - /* Find matching option descriptor */ - for (int j = 0; j < nopts; j++) - { - if (pg_strcasecmp(name, opts[j].name) == 0) - { - opt = &opts[j]; - break; - } - } - - if (opt == NULL) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("unrecognized option: \"%s\"", name))); - - if (opt->isset) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("option \"%s\" is specified more than once", - name))); - - valstr = TextDatumGetCString(args[i + 1]); - - switch (opt->type) - { - case DDL_OPT_BOOL: - if (!parse_bool(valstr, &opt->boolval)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid value for boolean option \"%s\": %s", - name, valstr))); - break; - - case DDL_OPT_TEXT: - opt->textval = valstr; - valstr = NULL; /* don't pfree below */ - break; - - case DDL_OPT_INT: - { - char *endp; - long val; - - errno = 0; - val = strtol(valstr, &endp, 10); - if (*endp != '\0' || errno == ERANGE || - val < PG_INT32_MIN || val > PG_INT32_MAX) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid value for integer option \"%s\": %s", - name, valstr))); - opt->intval = (int) val; - } - break; - } - - opt->isset = true; - - if (valstr) - pfree(valstr); - pfree(name); - } -} - /* * Helper to append a formatted string with optional pretty-printing. */ @@ -590,7 +421,6 @@ pg_get_role_ddl_internal(Oid roleid, bool pretty, bool memberships) * Each row is a complete SQL statement. The first row is always the * CREATE ROLE statement; subsequent rows are ALTER ROLE SET statements * and optionally GRANT statements for role memberships. - * Returns no rows if the role argument is NULL. */ Datum pg_get_role_ddl(PG_FUNCTION_ARGS) @@ -602,26 +432,17 @@ pg_get_role_ddl(PG_FUNCTION_ARGS) { MemoryContext oldcontext; Oid roleid; - DdlOption opts[] = { - {"pretty", DDL_OPT_BOOL}, - {"memberships", DDL_OPT_BOOL}, - }; + bool pretty; + bool memberships; funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - if (PG_ARGISNULL(0)) - { - MemoryContextSwitchTo(oldcontext); - SRF_RETURN_DONE(funcctx); - } - roleid = PG_GETARG_OID(0); - parse_ddl_options(fcinfo, 1, opts, lengthof(opts)); + pretty = PG_GETARG_BOOL(1); + memberships = PG_GETARG_BOOL(2); - statements = pg_get_role_ddl_internal(roleid, - opts[0].isset && opts[0].boolval, - !opts[1].isset || opts[1].boolval); + statements = pg_get_role_ddl_internal(roleid, pretty, memberships); funcctx->user_fctx = statements; funcctx->max_calls = list_length(statements); @@ -755,7 +576,7 @@ pg_get_tablespace_ddl_internal(Oid tsid, bool pretty, bool no_owner) * pg_get_tablespace_ddl_srf - common SRF logic for tablespace DDL */ static Datum -pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid, bool isnull) +pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid) { FuncCallContext *funcctx; List *statements; @@ -763,25 +584,16 @@ pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid, bool isnull) if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; - DdlOption opts[] = { - {"pretty", DDL_OPT_BOOL}, - {"owner", DDL_OPT_BOOL}, - }; + bool pretty; + bool no_owner; funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - if (isnull) - { - MemoryContextSwitchTo(oldcontext); - SRF_RETURN_DONE(funcctx); - } - - parse_ddl_options(fcinfo, 1, opts, lengthof(opts)); + pretty = PG_GETARG_BOOL(1); + no_owner = !PG_GETARG_BOOL(2); - statements = pg_get_tablespace_ddl_internal(tsid, - opts[0].isset && opts[0].boolval, - opts[1].isset && !opts[1].boolval); + statements = pg_get_tablespace_ddl_internal(tsid, pretty, no_owner); funcctx->user_fctx = statements; funcctx->max_calls = list_length(statements); @@ -813,14 +625,9 @@ pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid, bool isnull) Datum pg_get_tablespace_ddl_oid(PG_FUNCTION_ARGS) { - Oid tsid = InvalidOid; - bool isnull; - - isnull = PG_ARGISNULL(0); - if (!isnull) - tsid = PG_GETARG_OID(0); + Oid tsid = PG_GETARG_OID(0); - return pg_get_tablespace_ddl_srf(fcinfo, tsid, isnull); + return pg_get_tablespace_ddl_srf(fcinfo, tsid); } /* @@ -830,19 +637,10 @@ pg_get_tablespace_ddl_oid(PG_FUNCTION_ARGS) Datum pg_get_tablespace_ddl_name(PG_FUNCTION_ARGS) { - Oid tsid = InvalidOid; - Name tspname; - bool isnull; + Name tspname = PG_GETARG_NAME(0); + Oid tsid = get_tablespace_oid(NameStr(*tspname), false); - isnull = PG_ARGISNULL(0); - - if (!isnull) - { - tspname = PG_GETARG_NAME(0); - tsid = get_tablespace_oid(NameStr(*tspname), false); - } - - return pg_get_tablespace_ddl_srf(fcinfo, tsid, isnull); + return pg_get_tablespace_ddl_srf(fcinfo, tsid); } /* @@ -1140,28 +938,20 @@ pg_get_database_ddl(PG_FUNCTION_ARGS) { MemoryContext oldcontext; Oid dbid; - DdlOption opts[] = { - {"pretty", DDL_OPT_BOOL}, - {"owner", DDL_OPT_BOOL}, - {"tablespace", DDL_OPT_BOOL}, - }; + bool pretty; + bool no_owner; + bool no_tablespace; funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - if (PG_ARGISNULL(0)) - { - MemoryContextSwitchTo(oldcontext); - SRF_RETURN_DONE(funcctx); - } - dbid = PG_GETARG_OID(0); - parse_ddl_options(fcinfo, 1, opts, lengthof(opts)); + pretty = PG_GETARG_BOOL(1); + no_owner = !PG_GETARG_BOOL(2); + no_tablespace = !PG_GETARG_BOOL(3); - statements = pg_get_database_ddl_internal(dbid, - opts[0].isset && opts[0].boolval, - opts[1].isset && !opts[1].boolval, - opts[2].isset && !opts[2].boolval); + statements = pg_get_database_ddl_internal(dbid, pretty, no_owner, + no_tablespace); funcctx->user_fctx = statements; funcctx->max_calls = list_length(statements); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 2fe3be9ada5..635c0d9cb13 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202606251 +#define CATALOG_VERSION_NO 202606281 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 384ba908d35..402d869710b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -8591,30 +8591,29 @@ proname => 'pg_get_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid bool', prosrc => 'pg_get_constraintdef_ext' }, { oid => '6501', descr => 'get DDL to recreate a role', - proname => 'pg_get_role_ddl', prorows => '10', provariadic => 'text', - proisstrict => 'f', proretset => 't', provolatile => 's', - pronargdefaults => '1', prorettype => 'text', proargtypes => 'regrole _text', - proallargtypes => '{regrole,_text}', proargmodes => '{i,v}', - proargdefaults => '{NULL}', prosrc => 'pg_get_role_ddl' }, + proname => 'pg_get_role_ddl', prorows => '10', proisstrict => 't', + proretset => 't', provolatile => 's', pronargdefaults => '2', + prorettype => 'text', proargtypes => 'regrole bool bool', + proargnames => '{role,pretty,memberships}', + proargdefaults => '{false,true}', prosrc => 'pg_get_role_ddl' }, { oid => '6499', descr => 'get DDL to recreate a tablespace', - proname => 'pg_get_tablespace_ddl', prorows => '10', provariadic => 'text', - proisstrict => 'f', proretset => 't', provolatile => 's', - pronargdefaults => '1', prorettype => 'text', proargtypes => 'oid _text', - proallargtypes => '{oid,_text}', proargmodes => '{i,v}', - proargdefaults => '{NULL}', prosrc => 'pg_get_tablespace_ddl_oid' }, + proname => 'pg_get_tablespace_ddl', prorows => '10', proisstrict => 't', + proretset => 't', provolatile => 's', pronargdefaults => '2', + prorettype => 'text', proargtypes => 'oid bool bool', + proargnames => '{tablespace,pretty,owner}', + proargdefaults => '{false,true}', prosrc => 'pg_get_tablespace_ddl_oid' }, { oid => '6500', descr => 'get DDL to recreate a tablespace', - proname => 'pg_get_tablespace_ddl', prorows => '10', provariadic => 'text', - proisstrict => 'f', proretset => 't', provolatile => 's', - pronargdefaults => '1', prorettype => 'text', proargtypes => 'name _text', - proallargtypes => '{name,_text}', proargmodes => '{i,v}', - proargdefaults => '{NULL}', prosrc => 'pg_get_tablespace_ddl_name' }, + proname => 'pg_get_tablespace_ddl', prorows => '10', proisstrict => 't', + proretset => 't', provolatile => 's', pronargdefaults => '2', + prorettype => 'text', proargtypes => 'name bool bool', + proargnames => '{tablespace,pretty,owner}', + proargdefaults => '{false,true}', prosrc => 'pg_get_tablespace_ddl_name' }, { oid => '6502', descr => 'get DDL to recreate a database', - proname => 'pg_get_database_ddl', prorows => '10', provariadic => 'text', - proisstrict => 'f', proretset => 't', provolatile => 's', - pronargdefaults => '1', prorettype => 'text', - proargtypes => 'regdatabase _text', proallargtypes => '{regdatabase,_text}', - proargmodes => '{i,v}', proargdefaults => '{NULL}', - prosrc => 'pg_get_database_ddl' }, + proname => 'pg_get_database_ddl', prorows => '10', proisstrict => 't', + proretset => 't', provolatile => 's', pronargdefaults => '3', + prorettype => 'text', proargtypes => 'regdatabase bool bool bool', + proargnames => '{database,pretty,owner,tablespace}', + proargdefaults => '{false,true,true}', prosrc => 'pg_get_database_ddl' }, { oid => '2509', descr => 'deparse an encoded expression with pretty-print option', proname => 'pg_get_expr', provolatile => 's', prorettype => 'text', diff --git a/src/test/modules/test_misc/t/012_ddlutils.pl b/src/test/modules/test_misc/t/012_ddlutils.pl index bcdb831a676..e541dfa38d1 100644 --- a/src/test/modules/test_misc/t/012_ddlutils.pl +++ b/src/test/modules/test_misc/t/012_ddlutils.pl @@ -93,7 +93,7 @@ sub ddl_filter # Pretty-printed output $result = $node->safe_psql('postgres', - q{SELECT * FROM pg_get_role_ddl('regress_role_ddl_test2', 'pretty', 'true')} + q{SELECT * FROM pg_get_role_ddl('regress_role_ddl_test2', pretty => true)} ); like($result, qr/\n\s+SUPERUSER/, 'role pretty-print indents attributes'); @@ -123,7 +123,7 @@ sub ddl_filter # Memberships suppressed $result = $node->safe_psql('postgres', - q{SELECT * FROM pg_get_role_ddl('regress_role_ddl_member', 'memberships', 'false')} + q{SELECT * FROM pg_get_role_ddl('regress_role_ddl_member', memberships => false)} ); unlike($result, qr/GRANT/, 'memberships suppressed'); @@ -176,18 +176,18 @@ sub ddl_filter q{SELECT count(*) FROM pg_get_database_ddl(NULL)}); is($result, '0', 'NULL database returns no rows'); -# Invalid option +# Invalid option (bad boolean cast) ($ret, $stdout, $stderr) = $node->psql('postgres', - q{SELECT * FROM pg_get_database_ddl('regression_ddlutils_test', 'owner', 'invalid')} + q{SELECT * FROM pg_get_database_ddl('regression_ddlutils_test', owner => 'invalid')} ); isnt($ret, 0, 'invalid boolean option errors'); -like($stderr, qr/invalid value/, 'invalid option error message'); +like($stderr, qr/invalid input syntax for type boolean/, 'invalid option error message'); -# Duplicate option +# Duplicate named argument ($ret, $stdout, $stderr) = $node->psql( 'postgres', q{SELECT * FROM pg_get_database_ddl('regression_ddlutils_test', - 'owner', 'false', 'owner', 'true')}); + owner => false, owner => true)}); isnt($ret, 0, 'duplicate option errors'); # Basic output (without locale details) @@ -218,9 +218,17 @@ sub ddl_filter 'postgres', q{SELECT pg_get_database_ddl FROM pg_get_database_ddl('regression_ddlutils_test', - 'pretty', 'true', 'tablespace', 'false')})); + pretty => true, tablespace => false)})); like($result, qr/\n\s+WITH TEMPLATE/, 'database DDL pretty-prints WITH'); +# Owner suppressed +$result = ddl_filter( + $node->safe_psql( + 'postgres', + q{SELECT pg_get_database_ddl + FROM pg_get_database_ddl('regression_ddlutils_test', owner => false)})); +unlike($result, qr/OWNER/, 'database DDL owner suppressed'); + # Permission check $node->safe_psql( 'postgres', q{ @@ -292,14 +300,14 @@ sub ddl_filter $result = $node->safe_psql( 'postgres', q{SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp', - 'pretty', 'true')}); + pretty => true)}); like($result, qr/\n\s+OWNER/, 'tablespace DDL pretty-prints OWNER'); # Owner suppressed $result = $node->safe_psql( 'postgres', q{SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp', - 'owner', 'false')}); + owner => false)}); unlike($result, qr/OWNER/, 'tablespace DDL owner suppressed'); # Lookup by OID From b574fec00f275e50ffe2c9780ec1f6398796c905 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 28 Jun 2026 12:31:29 -0400 Subject: [PATCH 039/481] Avoid collation lookup failure when considering a "char" column. If a "char" column has a statistics histogram, scalarineqsel() would fail with "cache lookup failed for collation 0". Avoid the failing lookup by acting as though the collation is "C". Prior to commit 06421b084, this code didn't fail because lc_collate_is_c() intentionally didn't spit up on InvalidOid. It did act differently though: it would take the non-C-collation code path and hence apply strxfrm using libc's prevailing locale. But that seems like the wrong thing for a non-collatable comparison, so let's not resurrect that aspect. Author: Feng Wu Reviewed-by: Tom Lane Discussion: https://postgr.es/m/CACK3muq6s-O1Wc3w4dRL1Fe8YQ-Fz1zJbezeQwhuLgNxGNEFiA@mail.gmail.com Backpatch-through: 18 --- src/backend/utils/adt/selfuncs.c | 8 ++++++++ src/test/regress/expected/planner_est.out | 11 +++++++++++ src/test/regress/sql/planner_est.sql | 6 ++++++ 3 files changed, 25 insertions(+) diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index d6efd07073a..cbc70fde716 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -5295,6 +5295,14 @@ convert_string_datum(Datum value, Oid typid, Oid collid, bool *failure) return NULL; } + /* + * If we don't have a collation, act as though it's "C". This would + * normally happen only for the "char" type, but perhaps there are other + * cases. + */ + if (!OidIsValid(collid)) + return val; + mylocale = pg_newlocale_from_collation(collid); if (!mylocale->collate_is_c) diff --git a/src/test/regress/expected/planner_est.out b/src/test/regress/expected/planner_est.out index b62a47552fa..236cb274a78 100644 --- a/src/test/regress/expected/planner_est.out +++ b/src/test/regress/expected/planner_est.out @@ -210,4 +210,15 @@ false, true, false, true); -> Result (cost=N..N rows=1 width=N) (4 rows) +-- Verify that scalarineqsel() works on "char" columns +CREATE TEMP TABLE char_table_1 AS + SELECT i::"char" AS c FROM generate_series(64,96) i; +ANALYZE char_table_1; +EXPLAIN (COSTS OFF) SELECT * FROM char_table_1 WHERE c < 'Q'; + QUERY PLAN +----------------------------- + Seq Scan on char_table_1 + Filter: (c < 'Q'::"char") +(2 rows) + DROP FUNCTION explain_mask_costs(text, bool, bool, bool, bool); diff --git a/src/test/regress/sql/planner_est.sql b/src/test/regress/sql/planner_est.sql index 53210d5baad..2b696a4e4e5 100644 --- a/src/test/regress/sql/planner_est.sql +++ b/src/test/regress/sql/planner_est.sql @@ -147,4 +147,10 @@ SELECT explain_mask_costs($$ SELECT * FROM tenk1 WHERE unique1 <> ALL (ARRAY[1, 2, 98, (SELECT 99), NULL]);$$, false, true, false, true); +-- Verify that scalarineqsel() works on "char" columns +CREATE TEMP TABLE char_table_1 AS + SELECT i::"char" AS c FROM generate_series(64,96) i; +ANALYZE char_table_1; +EXPLAIN (COSTS OFF) SELECT * FROM char_table_1 WHERE c < 'Q'; + DROP FUNCTION explain_mask_costs(text, bool, bool, bool, bool); From e42d4a1f3dc59420be796883404020cb41ddd05e Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Sun, 28 Jun 2026 23:43:19 +0200 Subject: [PATCH 040/481] doc: Improve consistency in varlistentry attributes Use underscores consistent across the varlistentry attributes in config.sgml. Inconsistencies found using Claude, verified by the reporter. Reported-by: Bill Kim Reviewed-by: Peter Smith Discussion: https://postgr.es/m/CAMQXxchB0ZfMHyk+Ji-=s3hkqh0_XyuKiaNLRgvatvndSt3KNw@mail.gmail.com --- doc/src/sgml/config.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index fa566c9e553..569fc0e7dba 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -5842,7 +5842,7 @@ ANY num_sync ( + enable_group_by_reordering (boolean) enable_group_by_reordering configuration parameter @@ -11894,7 +11894,7 @@ dynamic_library_path = '/usr/local/lib/postgresql:$libdir' - + quote_all_identifiers (boolean) quote_all_identifiers configuration parameter From 6f4bac854fb784f83b86f05c7e9921e038135442 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Mon, 29 Jun 2026 10:24:28 +0900 Subject: [PATCH 041/481] Hardwire RI fast-path end-of-xact cleanup into xact.c Commit b7b27eb41a5, which added foreign-key fast-path batching to ri_triggers.c, registered ri_FastPathXactCallback() via RegisterXactCallback() to clear the fast-path batching state at end of transaction. RegisterXactCallback() is documented as intended for dynamically loaded modules; built-in code is supposed to hardwire its end-of-xact hooks into xact.c, mainly so callback ordering can be controlled where it matters (see the header comment on RegisterXactCallback()). Convert the callback into a plain AtEOXact_RI() function and call it directly from CommitTransaction(), PrepareTransaction() and AbortTransaction(), alongside the other AtEOXact_* cleanup steps, and drop the RegisterXactCallback() registration. Like the other AtEOXact_* routines, AtEOXact_RI() takes an isCommit argument and treats the two paths differently. On commit or prepare the fast-path cache must already have been flushed and torn down by the after-trigger batch callback, so a surviving cache indicates a trigger batch was never flushed -- which would have silently skipped FK checks -- and draws an Assert plus a WARNING. On abort a surviving cache is expected (a flush may have errored out partway) and is simply reset. There is no ordering dependency here: AtEOXact_RI() only resets backend-local static state (the cache pointer, the callback-registered flag, and the in-flush guard). It touches no relations, locks, buffers or catalogs, so its position relative to ResourceOwnerRelease() and the surrounding AtEOXact_* calls does not matter. On a normal commit the fast-path cache has already been flushed and torn down by ri_FastPathEndBatch() (an AfterTriggerBatchCallback fired from AfterTriggerFireDeferred(), well before any end-of-xact callback), so the reset is a no-op; its real job is the abort path, where teardown may not have run and the static pointers would otherwise dangle into the next transaction. The cache memory itself lives in TopTransactionContext and is freed by the end-of-transaction memory-context reset on both paths. The companion RegisterSubXactCallback() use from b7b27eb41a5 was already removed by commit 4113873a, which confined fast-path batching to the top transaction level, so only the RegisterXactCallback() use remained. Reported-by: Bertrand Drouvot Reviewed-by: Bertrand Drouvot Discussion: https://postgr.es/m/ajypPeEWceXRGAEW@bdtpg --- src/backend/access/transam/xact.c | 3 ++ src/backend/utils/adt/ri_triggers.c | 58 +++++++++++++++++++++-------- src/include/commands/trigger.h | 2 + 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index de4cf96eaa2..3a89149016f 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -2514,6 +2514,7 @@ CommitTransaction(void) AtEOXact_Files(true); AtEOXact_ComboCid(); AtEOXact_HashTables(true); + AtEOXact_RI(true); AtEOXact_PgStat(true, is_parallel_worker); AtEOXact_Snapshot(true, false); AtEOXact_ApplyLauncher(true); @@ -2809,6 +2810,7 @@ PrepareTransaction(void) AtEOXact_Files(true); AtEOXact_ComboCid(); AtEOXact_HashTables(true); + AtEOXact_RI(true); /* don't call AtEOXact_PgStat here; we fixed pgstat state above */ AtEOXact_Snapshot(true, true); /* we treat PREPARE as ROLLBACK so far as waking workers goes */ @@ -3039,6 +3041,7 @@ AbortTransaction(void) AtEOXact_Files(false); AtEOXact_ComboCid(); AtEOXact_HashTables(false); + AtEOXact_RI(false); AtEOXact_PgStat(false, is_parallel_worker); AtEOXact_ApplyLauncher(false); AtEOXact_LogicalRepWorkers(false); diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 44129a35c08..bf54f9b4592 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -228,7 +228,7 @@ typedef struct RI_CompareHashEntry * relations are held open with locks for the transaction duration, preventing * relcache invalidation. The entry itself is torn down at batch end by * ri_FastPathEndBatch(); on abort, ResourceOwner releases the cached - * relations and the XactCallback NULLs the static cache pointer to prevent + * relations and AtEOXact_RI() NULLs the static cache pointer to prevent * any subsequent access. */ typedef struct RI_FastPathEntry @@ -4187,8 +4187,8 @@ RI_FKey_trigger_type(Oid tgfoid) * Registered as an AfterTriggerBatchCallback. Note: the flush can * do real work (CCI, security context switch, index probes) and can * throw ERROR on a constraint violation. If that happens, - * ri_FastPathTeardown never runs; ResourceOwner + XactCallback - * handle resource cleanup on the abort path. + * ri_FastPathTeardown never runs; ResourceOwner releases the cached + * relations and AtEOXact_RI() resets the static state on the abort path. */ static void ri_FastPathEndBatch(void *arg) @@ -4273,15 +4273,47 @@ ri_FastPathTeardown(void) ri_fastpath_callback_registered = false; } -static bool ri_fastpath_xact_callback_registered = false; - -static void -ri_FastPathXactCallback(XactEvent event, void *arg) +/* + * AtEOXact_RI + * Reset fast-path batching state at end of transaction. + * + * Called from CommitTransaction() and PrepareTransaction() with isCommit + * true, and from AbortTransaction() with isCommit false. + * + * By the time we get here on a clean commit or prepare, the fast-path cache + * has already been flushed and torn down by ri_FastPathEndBatch() (an + * AfterTriggerBatchCallback fired from AfterTriggerFireDeferred(), well before + * this point), so the static pointers are already clear and the reset below is + * a no-op. A surviving cache at commit means a trigger batch was never + * flushed, which would have silently skipped FK checks, so we complain. + * + * On abort, ri_FastPathEndBatch()/ri_FastPathTeardown() may not have run (a + * flush can error out partway): the ResourceOwner releases the cached + * relations and the TopTransactionContext reset frees the cache memory, but + * the process-local static pointers below would dangle into the next + * transaction. This resets them so they don't. + * + * The reset touches only backend-local static state (no relations, locks, + * buffers or catalog access), so it has no ordering dependency on the + * surrounding ResourceOwnerRelease() / AtEOXact_* steps. + */ +void +AtEOXact_RI(bool isCommit) { /* - * On abort, ResourceOwner already released relations; on commit, - * ri_FastPathTeardown already ran. Either way, just NULL the static - * pointers so they don't dangle into the next transaction. + * The cache must be empty on a clean commit or prepare; a survivor means + * a trigger batch went unflushed. Assert for assert-enabled builds and, + * since the transaction is already committed by now and FK checks may + * have been skipped, also warn in production builds. + */ + Assert(ri_fastpath_cache == NULL || !isCommit); + if (isCommit && ri_fastpath_cache != NULL) + elog(WARNING, "RI fast-path cache not flushed at end of transaction"); + + /* + * Clear the static pointers/flags. The cache memory lives in + * TopTransactionContext and is freed by the end-of-transaction + * memory-context reset; here we only drop the references to it. */ ri_fastpath_cache = NULL; ri_fastpath_callback_registered = false; @@ -4316,12 +4348,6 @@ ri_FastPathGetEntry(const RI_ConstraintInfo *riinfo, Relation fk_rel) { HASHCTL ctl; - if (!ri_fastpath_xact_callback_registered) - { - RegisterXactCallback(ri_FastPathXactCallback, NULL); - ri_fastpath_xact_callback_registered = true; - } - ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(RI_FastPathEntry); ctl.hcxt = TopTransactionContext; diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h index 1d9869973c0..0c3d485abf4 100644 --- a/src/include/commands/trigger.h +++ b/src/include/commands/trigger.h @@ -310,4 +310,6 @@ extern void RegisterAfterTriggerBatchCallback(AfterTriggerBatchCallback callback void *arg); extern bool AfterTriggerIsActive(void); +extern void AtEOXact_RI(bool isCommit); + #endif /* TRIGGER_H */ From 8612f0b7ce09212b0b80af925b0966bdbd46a60f Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Mon, 29 Jun 2026 11:38:39 +0900 Subject: [PATCH 042/481] plpython: Fix NULL pointer dereferences for broken sequence and mapping objects PL/Python and its hstore and jsonb transforms build SQL values from Python containers by calling Python C API functions that can return NULL, and in several places the result was used without first checking it. On the sequence side, PySequence_GetItem() is used when converting a returned sequence into a SQL array or composite value, when reading the argument list passed to plpy.execute() or plpy.cursor(), and when reading the list of type names given to plpy.prepare(). On the mapping side, the hstore and jsonb transforms call PyMapping_Size() and PyMapping_Items() and then index the result with PyList_GetItem() and PyTuple_GetItem(). All of these return NULL (or -1), with a Python exception set, for a broken object: for example one whose __getitem__() or items() raises, or which reports a length that disagrees with what it actually yields. The unchecked result was then dereferenced, crashing the backend. Fix this by checking the result of each call and reporting a regular error if it failed, so that the underlying Python exception is surfaced instead of taking down the session. Author: Richard Guo Reviewed-by: Ayush Tiwari Discussion: https://postgr.es/m/CAMbWs49BKM9wP6m8bCXEpHwQKp7usvOGV6Jf=J7FYr_BCpxLqg@mail.gmail.com Backpatch-through: 14 --- .../expected/hstore_plpython.out | 65 ++++++++++++++ contrib/hstore_plpython/hstore_plpython.c | 16 ++++ .../hstore_plpython/sql/hstore_plpython.sql | 65 ++++++++++++++ .../expected/jsonb_plpython.out | 89 +++++++++++++++++++ contrib/jsonb_plpython/jsonb_plpython.c | 21 ++++- contrib/jsonb_plpython/sql/jsonb_plpython.sql | 77 ++++++++++++++++ .../plpython/expected/plpython_composite.out | 16 ++++ src/pl/plpython/expected/plpython_spi.out | 51 +++++++++++ src/pl/plpython/expected/plpython_types.out | 16 ++++ src/pl/plpython/plpy_cursorobject.c | 5 ++ src/pl/plpython/plpy_spi.c | 10 +++ src/pl/plpython/plpy_typeio.c | 9 +- src/pl/plpython/sql/plpython_composite.sql | 12 +++ src/pl/plpython/sql/plpython_spi.sql | 39 ++++++++ src/pl/plpython/sql/plpython_types.sql | 13 +++ 15 files changed, 500 insertions(+), 4 deletions(-) diff --git a/contrib/hstore_plpython/expected/hstore_plpython.out b/contrib/hstore_plpython/expected/hstore_plpython.out index 5fb56a2f65d..5f8315e84dd 100644 --- a/contrib/hstore_plpython/expected/hstore_plpython.out +++ b/contrib/hstore_plpython/expected/hstore_plpython.out @@ -43,6 +43,71 @@ SELECT test1bad(); ERROR: not a Python mapping CONTEXT: while creating return value PL/Python function "test1bad" +-- A mapping whose items() raises should be reported as an error, not crash +-- the backend +CREATE FUNCTION test1broken() RETURNS hstore +LANGUAGE plpython3u +TRANSFORM FOR TYPE hstore +AS $$ +class C(dict): + def items(self): + raise ValueError('items failed') +d = C() +d['x'] = 1 +return d +$$; +SELECT test1broken(); +ERROR: could not get items from Python mapping +CONTEXT: while creating return value +PL/Python function "test1broken" +-- Likewise for a mapping whose items() does not return key/value pairs +CREATE FUNCTION test1malformed() RETURNS hstore +LANGUAGE plpython3u +TRANSFORM FOR TYPE hstore +AS $$ +class C(dict): + def items(self): + return [42] +d = C() +d['x'] = 1 +return d +$$; +SELECT test1malformed(); +ERROR: items() of a Python mapping must return key/value pairs +CONTEXT: while creating return value +PL/Python function "test1malformed" +-- Likewise for a mapping whose items() yields fewer pairs than its length +CREATE FUNCTION test1short() RETURNS hstore +LANGUAGE plpython3u +TRANSFORM FOR TYPE hstore +AS $$ +class C(dict): + def items(self): + return [] +d = C() +d['x'] = 1 +return d +$$; +SELECT test1short(); +ERROR: items() of a Python mapping must return key/value pairs +CONTEXT: while creating return value +PL/Python function "test1short" +-- Likewise for a mapping whose __len__() raises +CREATE FUNCTION test1brokenlen() RETURNS hstore +LANGUAGE plpython3u +TRANSFORM FOR TYPE hstore +AS $$ +class C(dict): + def __len__(self): + raise ValueError('len failed') +d = C() +d['x'] = 1 +return d +$$; +SELECT test1brokenlen(); +ERROR: could not get size of Python mapping +CONTEXT: while creating return value +PL/Python function "test1brokenlen" -- test hstore[] -> python CREATE FUNCTION test1arr(val hstore[]) RETURNS int LANGUAGE plpython3u diff --git a/contrib/hstore_plpython/hstore_plpython.c b/contrib/hstore_plpython/hstore_plpython.c index f1e483980f4..b9d8b4537f7 100644 --- a/contrib/hstore_plpython/hstore_plpython.c +++ b/contrib/hstore_plpython/hstore_plpython.c @@ -143,7 +143,16 @@ plpython_to_hstore(PG_FUNCTION_ARGS) errmsg("not a Python mapping"))); pcount = PyMapping_Size(dict); + if (pcount < 0) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("could not get size of Python mapping"))); + items = PyMapping_Items(dict); + if (items == NULL) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("could not get items from Python mapping"))); PG_TRY(); { @@ -160,6 +169,13 @@ plpython_to_hstore(PG_FUNCTION_ARGS) PyObject *value; tuple = PyList_GetItem(items, i); + + /* The mapping's items() must yield key/value pairs */ + if (tuple == NULL || !PyTuple_Check(tuple) || PyTuple_Size(tuple) < 2) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("items() of a Python mapping must return key/value pairs"))); + key = PyTuple_GetItem(tuple, 0); value = PyTuple_GetItem(tuple, 1); diff --git a/contrib/hstore_plpython/sql/hstore_plpython.sql b/contrib/hstore_plpython/sql/hstore_plpython.sql index ebd61e6c467..a2b2046380f 100644 --- a/contrib/hstore_plpython/sql/hstore_plpython.sql +++ b/contrib/hstore_plpython/sql/hstore_plpython.sql @@ -38,6 +38,71 @@ $$; SELECT test1bad(); +-- A mapping whose items() raises should be reported as an error, not crash +-- the backend +CREATE FUNCTION test1broken() RETURNS hstore +LANGUAGE plpython3u +TRANSFORM FOR TYPE hstore +AS $$ +class C(dict): + def items(self): + raise ValueError('items failed') +d = C() +d['x'] = 1 +return d +$$; + +SELECT test1broken(); + + +-- Likewise for a mapping whose items() does not return key/value pairs +CREATE FUNCTION test1malformed() RETURNS hstore +LANGUAGE plpython3u +TRANSFORM FOR TYPE hstore +AS $$ +class C(dict): + def items(self): + return [42] +d = C() +d['x'] = 1 +return d +$$; + +SELECT test1malformed(); + + +-- Likewise for a mapping whose items() yields fewer pairs than its length +CREATE FUNCTION test1short() RETURNS hstore +LANGUAGE plpython3u +TRANSFORM FOR TYPE hstore +AS $$ +class C(dict): + def items(self): + return [] +d = C() +d['x'] = 1 +return d +$$; + +SELECT test1short(); + + +-- Likewise for a mapping whose __len__() raises +CREATE FUNCTION test1brokenlen() RETURNS hstore +LANGUAGE plpython3u +TRANSFORM FOR TYPE hstore +AS $$ +class C(dict): + def __len__(self): + raise ValueError('len failed') +d = C() +d['x'] = 1 +return d +$$; + +SELECT test1brokenlen(); + + -- test hstore[] -> python CREATE FUNCTION test1arr(val hstore[]) RETURNS int LANGUAGE plpython3u diff --git a/contrib/jsonb_plpython/expected/jsonb_plpython.out b/contrib/jsonb_plpython/expected/jsonb_plpython.out index cac963de69c..8d3f5328809 100644 --- a/contrib/jsonb_plpython/expected/jsonb_plpython.out +++ b/contrib/jsonb_plpython/expected/jsonb_plpython.out @@ -304,3 +304,92 @@ SELECT test_dict1(); {"": 2, "a": 1, "33": 3} (1 row) +-- A custom sequence whose __getitem__ raises should be reported as an error, +-- not crash the backend +CREATE FUNCTION test_broken_sequence() RETURNS jsonb +LANGUAGE plpython3u +TRANSFORM FOR TYPE jsonb +AS $$ +class C: + def __len__(self): + return 2 + def __getitem__(self, i): + raise ValueError('getitem failed') +return C() +$$; +SELECT test_broken_sequence(); +ERROR: could not get element 0 from sequence +DETAIL: ValueError: getitem failed +CONTEXT: Traceback (most recent call last): +while creating return value +PL/Python function "test_broken_sequence" +-- A mapping whose items() raises should be reported as an error, not crash +-- the backend +CREATE FUNCTION test_broken_mapping() RETURNS jsonb +LANGUAGE plpython3u +TRANSFORM FOR TYPE jsonb +AS $$ +class C(dict): + def items(self): + raise ValueError('items failed') +d = C() +d['x'] = 1 +return d +$$; +SELECT test_broken_mapping(); +ERROR: could not get items from Python mapping +DETAIL: ValueError: items failed +CONTEXT: Traceback (most recent call last): +while creating return value +PL/Python function "test_broken_mapping" +-- Likewise for a mapping whose items() does not return key/value pairs +CREATE FUNCTION test_malformed_mapping() RETURNS jsonb +LANGUAGE plpython3u +TRANSFORM FOR TYPE jsonb +AS $$ +class C(dict): + def items(self): + return [42] +d = C() +d['x'] = 1 +return d +$$; +SELECT test_malformed_mapping(); +ERROR: items() of a Python mapping must return key/value pairs +CONTEXT: while creating return value +PL/Python function "test_malformed_mapping" +-- Likewise for a mapping whose items() yields fewer pairs than its length +CREATE FUNCTION test_short_mapping() RETURNS jsonb +LANGUAGE plpython3u +TRANSFORM FOR TYPE jsonb +AS $$ +class C(dict): + def items(self): + return [] +d = C() +d['x'] = 1 +return d +$$; +SELECT test_short_mapping(); +ERROR: items() of a Python mapping must return key/value pairs +DETAIL: IndexError: list index out of range +CONTEXT: while creating return value +PL/Python function "test_short_mapping" +-- Likewise for a mapping whose __len__() raises +CREATE FUNCTION test_broken_len_mapping() RETURNS jsonb +LANGUAGE plpython3u +TRANSFORM FOR TYPE jsonb +AS $$ +class C(dict): + def __len__(self): + raise ValueError('len failed') +d = C() +d['x'] = 1 +return d +$$; +SELECT test_broken_len_mapping(); +ERROR: could not get size of Python mapping +DETAIL: ValueError: len failed +CONTEXT: Traceback (most recent call last): +while creating return value +PL/Python function "test_broken_len_mapping" diff --git a/contrib/jsonb_plpython/jsonb_plpython.c b/contrib/jsonb_plpython/jsonb_plpython.c index 909612a6039..dc17c9ee570 100644 --- a/contrib/jsonb_plpython/jsonb_plpython.c +++ b/contrib/jsonb_plpython/jsonb_plpython.c @@ -274,7 +274,12 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbInState *jsonb_state) PyObject *volatile items; pcount = PyMapping_Size(obj); + if (pcount < 0) + PLy_elog(ERROR, "could not get size of Python mapping"); + items = PyMapping_Items(obj); + if (items == NULL) + PLy_elog(ERROR, "could not get items from Python mapping"); PG_TRY(); { @@ -286,8 +291,15 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbInState *jsonb_state) { JsonbValue jbvKey; PyObject *item = PyList_GetItem(items, i); - PyObject *key = PyTuple_GetItem(item, 0); - PyObject *value = PyTuple_GetItem(item, 1); + PyObject *key; + PyObject *value; + + /* The mapping's items() must yield key/value pairs */ + if (item == NULL || !PyTuple_Check(item) || PyTuple_Size(item) < 2) + PLy_elog(ERROR, "items() of a Python mapping must return key/value pairs"); + + key = PyTuple_GetItem(item, 0); + value = PyTuple_GetItem(item, 1); /* Python dictionary can have None as key */ if (key == Py_None) @@ -337,7 +349,10 @@ PLySequence_ToJsonbValue(PyObject *obj, JsonbInState *jsonb_state) for (i = 0; i < pcount; i++) { value = PySequence_GetItem(obj, i); - Assert(value); + + /* PySequence_GetItem() can return NULL, with an exception set */ + if (value == NULL) + PLy_elog(ERROR, "could not get element %d from sequence", (int) i); PLyObject_ToJsonbValue(value, jsonb_state, true); Py_XDECREF(value); diff --git a/contrib/jsonb_plpython/sql/jsonb_plpython.sql b/contrib/jsonb_plpython/sql/jsonb_plpython.sql index 29dc33279a0..fd8485c89c1 100644 --- a/contrib/jsonb_plpython/sql/jsonb_plpython.sql +++ b/contrib/jsonb_plpython/sql/jsonb_plpython.sql @@ -181,3 +181,80 @@ return x $$; SELECT test_dict1(); + +-- A custom sequence whose __getitem__ raises should be reported as an error, +-- not crash the backend +CREATE FUNCTION test_broken_sequence() RETURNS jsonb +LANGUAGE plpython3u +TRANSFORM FOR TYPE jsonb +AS $$ +class C: + def __len__(self): + return 2 + def __getitem__(self, i): + raise ValueError('getitem failed') +return C() +$$; + +SELECT test_broken_sequence(); + +-- A mapping whose items() raises should be reported as an error, not crash +-- the backend +CREATE FUNCTION test_broken_mapping() RETURNS jsonb +LANGUAGE plpython3u +TRANSFORM FOR TYPE jsonb +AS $$ +class C(dict): + def items(self): + raise ValueError('items failed') +d = C() +d['x'] = 1 +return d +$$; + +SELECT test_broken_mapping(); + +-- Likewise for a mapping whose items() does not return key/value pairs +CREATE FUNCTION test_malformed_mapping() RETURNS jsonb +LANGUAGE plpython3u +TRANSFORM FOR TYPE jsonb +AS $$ +class C(dict): + def items(self): + return [42] +d = C() +d['x'] = 1 +return d +$$; + +SELECT test_malformed_mapping(); + +-- Likewise for a mapping whose items() yields fewer pairs than its length +CREATE FUNCTION test_short_mapping() RETURNS jsonb +LANGUAGE plpython3u +TRANSFORM FOR TYPE jsonb +AS $$ +class C(dict): + def items(self): + return [] +d = C() +d['x'] = 1 +return d +$$; + +SELECT test_short_mapping(); + +-- Likewise for a mapping whose __len__() raises +CREATE FUNCTION test_broken_len_mapping() RETURNS jsonb +LANGUAGE plpython3u +TRANSFORM FOR TYPE jsonb +AS $$ +class C(dict): + def __len__(self): + raise ValueError('len failed') +d = C() +d['x'] = 1 +return d +$$; + +SELECT test_broken_len_mapping(); diff --git a/src/pl/plpython/expected/plpython_composite.out b/src/pl/plpython/expected/plpython_composite.out index 674af93ddcf..ffce7fc1be7 100644 --- a/src/pl/plpython/expected/plpython_composite.out +++ b/src/pl/plpython/expected/plpython_composite.out @@ -606,3 +606,19 @@ DETAIL: Missing left parenthesis. HINT: To return a composite type in an array, return the composite type as a Python tuple, e.g., "[('foo',)]". CONTEXT: while creating return value PL/Python function "composite_type_as_list_broken" +-- A custom sequence whose length matches the tuple but whose __getitem__ +-- raises should be reported as an error, not crash the backend. +CREATE FUNCTION composite_type_as_broken_sequence() RETURNS type_record AS $$ +class C: + def __len__(self): + return 2 + def __getitem__(self, i): + raise ValueError('getitem failed') +return C() +$$ LANGUAGE plpython3u; +SELECT * FROM composite_type_as_broken_sequence(); +ERROR: could not get element 0 from sequence +DETAIL: ValueError: getitem failed +CONTEXT: Traceback (most recent call last): +while creating return value +PL/Python function "composite_type_as_broken_sequence" diff --git a/src/pl/plpython/expected/plpython_spi.out b/src/pl/plpython/expected/plpython_spi.out index b572f9bf73b..0320ff01f6b 100644 --- a/src/pl/plpython/expected/plpython_spi.out +++ b/src/pl/plpython/expected/plpython_spi.out @@ -451,3 +451,54 @@ SELECT plan_composite_args(); (3,label) (1 row) +-- A custom argument sequence whose length matches the plan but whose +-- __getitem__ raises should be reported as an error, not crash the backend. +CREATE FUNCTION plan_broken_arg_sequence() RETURNS void AS $$ +plan = plpy.prepare("select $1", ["int4"]) +class C: + def __len__(self): + return 1 + def __getitem__(self, i): + raise ValueError('getitem failed') +plpy.execute(plan, C()) +$$ LANGUAGE plpython3u; +SELECT plan_broken_arg_sequence(); +ERROR: spiexceptions.ExternalRoutineException: could not get element 0 from sequence +DETAIL: ValueError: getitem failed +CONTEXT: Traceback (most recent call last): + PL/Python function "plan_broken_arg_sequence", line 8, in + plpy.execute(plan, C()) +PL/Python function "plan_broken_arg_sequence" +-- Likewise for the type-name list passed to plpy.prepare(). +CREATE FUNCTION prepare_broken_type_sequence() RETURNS void AS $$ +class C: + def __len__(self): + return 1 + def __getitem__(self, i): + raise ValueError('getitem failed') +plpy.prepare("select $1", C()) +$$ LANGUAGE plpython3u; +SELECT prepare_broken_type_sequence(); +ERROR: spiexceptions.ExternalRoutineException: could not get element 0 from sequence +DETAIL: ValueError: getitem failed +CONTEXT: Traceback (most recent call last): + PL/Python function "prepare_broken_type_sequence", line 7, in + plpy.prepare("select $1", C()) +PL/Python function "prepare_broken_type_sequence" +-- Likewise for the argument sequence passed to plpy.cursor(). +CREATE FUNCTION cursor_broken_arg_sequence() RETURNS void AS $$ +plan = plpy.prepare("select $1", ["int4"]) +class C: + def __len__(self): + return 1 + def __getitem__(self, i): + raise ValueError('getitem failed') +plpy.cursor(plan, C()) +$$ LANGUAGE plpython3u; +SELECT cursor_broken_arg_sequence(); +ERROR: spiexceptions.ExternalRoutineException: could not get element 0 from sequence +DETAIL: ValueError: getitem failed +CONTEXT: Traceback (most recent call last): + PL/Python function "cursor_broken_arg_sequence", line 8, in + plpy.cursor(plan, C()) +PL/Python function "cursor_broken_arg_sequence" diff --git a/src/pl/plpython/expected/plpython_types.out b/src/pl/plpython/expected/plpython_types.out index 8a680e15c14..0cb3d6ea8c6 100644 --- a/src/pl/plpython/expected/plpython_types.out +++ b/src/pl/plpython/expected/plpython_types.out @@ -796,6 +796,22 @@ SELECT * FROM test_type_conversion_array_error(); ERROR: return value of function with array return type is not a Python sequence CONTEXT: while creating return value PL/Python function "test_type_conversion_array_error" +-- A custom sequence whose __getitem__ raises should be reported as an error, +-- not crash the backend. +CREATE FUNCTION test_type_conversion_array_getitem_fail() RETURNS int[] AS $$ +class C: + def __len__(self): + return 2 + def __getitem__(self, i): + raise ValueError('getitem failed') +return C() +$$ LANGUAGE plpython3u; +SELECT * FROM test_type_conversion_array_getitem_fail(); +ERROR: could not get element 0 from sequence +DETAIL: ValueError: getitem failed +CONTEXT: Traceback (most recent call last): +while creating return value +PL/Python function "test_type_conversion_array_getitem_fail" -- -- Domains over arrays -- diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index cc74c4df6ba..0725fbc19f2 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -258,6 +258,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PyObject *elem; elem = PySequence_GetItem(args, j); + + /* PySequence_GetItem() can return NULL, with an exception set */ + if (elem == NULL) + PLy_elog(ERROR, "could not get element %d from sequence", j); + PG_TRY(2); { bool isnull; diff --git a/src/pl/plpython/plpy_spi.c b/src/pl/plpython/plpy_spi.c index 4ad40bf78f3..4980873efcf 100644 --- a/src/pl/plpython/plpy_spi.c +++ b/src/pl/plpython/plpy_spi.c @@ -87,6 +87,11 @@ PLy_spi_prepare(PyObject *self, PyObject *args) int32 typmod; optr = PySequence_GetItem(list, i); + + /* PySequence_GetItem() can return NULL, with an exception set */ + if (optr == NULL) + PLy_elog(ERROR, "could not get element %d from sequence", i); + if (PyUnicode_Check(optr)) sptr = PLyUnicode_AsString(optr); else @@ -250,6 +255,11 @@ PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit) PyObject *elem; elem = PySequence_GetItem(list, j); + + /* PySequence_GetItem() can return NULL, with an exception set */ + if (elem == NULL) + PLy_elog(ERROR, "could not get element %d from sequence", j); + PG_TRY(2); { bool isnull; diff --git a/src/pl/plpython/plpy_typeio.c b/src/pl/plpython/plpy_typeio.c index 92d55bf9f42..e499ed8cbfd 100644 --- a/src/pl/plpython/plpy_typeio.c +++ b/src/pl/plpython/plpy_typeio.c @@ -1210,6 +1210,10 @@ PLySequence_ToArray_recurse(PyObject *obj, ArrayBuildState **astatep, /* fetch the array element */ PyObject *subobj = PySequence_GetItem(obj, i); + /* PySequence_GetItem() can return NULL, with an exception set */ + if (subobj == NULL) + PLy_elog(ERROR, "could not get element %d from sequence", i); + /* need PG_TRY to ensure we release the subobj's refcount */ PG_TRY(); { @@ -1456,7 +1460,10 @@ PLySequence_ToComposite(PLyObToDatum *arg, TupleDesc desc, PyObject *sequence) PG_TRY(); { value = PySequence_GetItem(sequence, idx); - Assert(value); + + /* PySequence_GetItem() can return NULL, with an exception set */ + if (value == NULL) + PLy_elog(ERROR, "could not get element %d from sequence", idx); values[i] = att->func(att, value, &nulls[i], false); diff --git a/src/pl/plpython/sql/plpython_composite.sql b/src/pl/plpython/sql/plpython_composite.sql index 1bb9b83b719..b401b3f2f6b 100644 --- a/src/pl/plpython/sql/plpython_composite.sql +++ b/src/pl/plpython/sql/plpython_composite.sql @@ -233,3 +233,15 @@ CREATE FUNCTION composite_type_as_list_broken() RETURNS type_record[] AS $$ return [['first', 1]]; $$ LANGUAGE plpython3u; SELECT * FROM composite_type_as_list_broken(); + +-- A custom sequence whose length matches the tuple but whose __getitem__ +-- raises should be reported as an error, not crash the backend. +CREATE FUNCTION composite_type_as_broken_sequence() RETURNS type_record AS $$ +class C: + def __len__(self): + return 2 + def __getitem__(self, i): + raise ValueError('getitem failed') +return C() +$$ LANGUAGE plpython3u; +SELECT * FROM composite_type_as_broken_sequence(); diff --git a/src/pl/plpython/sql/plpython_spi.sql b/src/pl/plpython/sql/plpython_spi.sql index 00dcc8bb669..276d130431e 100644 --- a/src/pl/plpython/sql/plpython_spi.sql +++ b/src/pl/plpython/sql/plpython_spi.sql @@ -307,3 +307,42 @@ SELECT cursor_fetch_next_empty(); SELECT cursor_plan(); SELECT cursor_plan_wrong_args(); SELECT plan_composite_args(); + +-- A custom argument sequence whose length matches the plan but whose +-- __getitem__ raises should be reported as an error, not crash the backend. +CREATE FUNCTION plan_broken_arg_sequence() RETURNS void AS $$ +plan = plpy.prepare("select $1", ["int4"]) +class C: + def __len__(self): + return 1 + def __getitem__(self, i): + raise ValueError('getitem failed') +plpy.execute(plan, C()) +$$ LANGUAGE plpython3u; + +SELECT plan_broken_arg_sequence(); + +-- Likewise for the type-name list passed to plpy.prepare(). +CREATE FUNCTION prepare_broken_type_sequence() RETURNS void AS $$ +class C: + def __len__(self): + return 1 + def __getitem__(self, i): + raise ValueError('getitem failed') +plpy.prepare("select $1", C()) +$$ LANGUAGE plpython3u; + +SELECT prepare_broken_type_sequence(); + +-- Likewise for the argument sequence passed to plpy.cursor(). +CREATE FUNCTION cursor_broken_arg_sequence() RETURNS void AS $$ +plan = plpy.prepare("select $1", ["int4"]) +class C: + def __len__(self): + return 1 + def __getitem__(self, i): + raise ValueError('getitem failed') +plpy.cursor(plan, C()) +$$ LANGUAGE plpython3u; + +SELECT cursor_broken_arg_sequence(); diff --git a/src/pl/plpython/sql/plpython_types.sql b/src/pl/plpython/sql/plpython_types.sql index 0985a9cca2f..31549c7f4f1 100644 --- a/src/pl/plpython/sql/plpython_types.sql +++ b/src/pl/plpython/sql/plpython_types.sql @@ -417,6 +417,19 @@ $$ LANGUAGE plpython3u; SELECT * FROM test_type_conversion_array_error(); +-- A custom sequence whose __getitem__ raises should be reported as an error, +-- not crash the backend. +CREATE FUNCTION test_type_conversion_array_getitem_fail() RETURNS int[] AS $$ +class C: + def __len__(self): + return 2 + def __getitem__(self, i): + raise ValueError('getitem failed') +return C() +$$ LANGUAGE plpython3u; + +SELECT * FROM test_type_conversion_array_getitem_fail(); + -- -- Domains over arrays From b7e4e3e7fa73458ecca5cd10f341743fd12a4faa Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 29 Jun 2026 13:15:07 +0900 Subject: [PATCH 043/481] doc: Reorder table for Object DDL Functions While on it, let's add links pointing to the set of SQL commands generated by these functions. The descriptions of the functions are exactly the same, just moved around. Author: Peter Smith Reviewed-by: Ian Lawrence Barwick Discussion: https://postgr.es/m/CAHut+Pun9Z8qZFJTa9fLgdhM=Cip9d-cnx2YXDW6eFrSwbQj1g@mail.gmail.com --- doc/src/sgml/func/func-info.sgml | 81 +++++++++++++++++--------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml index bc80bcbd0b3..69ef3857cfa 100644 --- a/doc/src/sgml/func/func-info.sgml +++ b/doc/src/sgml/func/func-info.sgml @@ -3874,6 +3874,34 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} + + + + pg_get_database_ddl + + pg_get_database_ddl + ( database regdatabase + , pretty boolean + DEFAULT false + , owner boolean + DEFAULT true + , tablespace boolean + DEFAULT true ) + setof text + + + Reconstructs the CREATE + DATABASE statement for the specified database, + followed by ALTER DATABASE + statements for connection limit, template status, + and configuration settings. Each statement is returned as a separate + row. When pretty is true, the output is + pretty-printed. When owner is false, the + OWNER clause is omitted. When + tablespace is false, the + TABLESPACE clause is omitted. + + @@ -3888,14 +3916,15 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} setof text - Reconstructs the CREATE ROLE statement and any - ALTER ROLE ... SET statements for the given role. - Each statement is returned as a separate row. + Reconstructs the CREATE ROLE + statement and any + ALTER ROLE ... SET statements for the given + role. Each statement is returned as a separate row. Password information is never included in the output. When pretty is true, the output is pretty-printed. When memberships is false, - GRANT statements for role memberships are - omitted. + GRANT statements + for role memberships are omitted. @@ -3921,40 +3950,14 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} setof text - Reconstructs the CREATE TABLESPACE statement for - the specified tablespace (by OID or name). If the tablespace has - options set, an ALTER TABLESPACE ... SET statement - is also returned. Each statement is returned as a separate row. - When pretty is true, the output is - pretty-printed. When owner is false, the - OWNER clause is omitted. - - - - - - pg_get_database_ddl - - pg_get_database_ddl - ( database regdatabase - , pretty boolean - DEFAULT false - , owner boolean - DEFAULT true - , tablespace boolean - DEFAULT true ) - setof text - - - Reconstructs the CREATE DATABASE statement for the - specified database, followed by ALTER DATABASE - statements for connection limit, template status, and configuration - settings. Each statement is returned as a separate row. - When pretty is true, the output is - pretty-printed. When owner is false, the - OWNER clause is omitted. When - tablespace is false, the - TABLESPACE clause is omitted. + Reconstructs the CREATE + TABLESPACE statement for the specified tablespace (by + OID or name). If the tablespace has options set, an + ALTER TABLESPACE ... SET + statement is also returned. Each statement is + returned as a separate row. When pretty is + true, the output is pretty-printed. When owner + is false, the OWNER clause is omitted. From 994f770a0fd55dfdeb96d1d60d35545ba2d51480 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 29 Jun 2026 11:49:11 +0200 Subject: [PATCH 044/481] Fix handling of copy_file_range() return value Treat copy_file_range() return value of zero as an error: it indicates that no bytes could be copied (perhaps the source file is shorter than expected), and the existing retry loop would otherwise spin forever since nwritten would never reach BLCKSZ. The other uses of copy_file_range() in the tree don't have this problem. Reviewed-by: Nazir Bilal Yavuz Reviewed-by: Kyotaro Horiguchi Reviewed-by: Yingying Chen Discussion: https://www.postgresql.org/message-id/flat/3208cf7a-c7f3-41eb-92f6-33cbeff4df40%40eisentraut.org --- src/bin/pg_combinebackup/reconstruct.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bin/pg_combinebackup/reconstruct.c b/src/bin/pg_combinebackup/reconstruct.c index 3349aa2441d..38e756be7ef 100644 --- a/src/bin/pg_combinebackup/reconstruct.c +++ b/src/bin/pg_combinebackup/reconstruct.c @@ -705,6 +705,9 @@ write_reconstructed_file(char *input_filename, if (wb < 0) pg_fatal("error while copying file range from \"%s\" to \"%s\": %m", input_filename, output_filename); + else if (wb == 0) + pg_fatal("unexpected end of file while copying file range from \"%s\" to \"%s\"", + input_filename, output_filename); nwritten += wb; From bc3ae886a759f2d3fd5f1b92f5fbeeccfee9e7a9 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 29 Jun 2026 15:13:45 +0200 Subject: [PATCH 045/481] Forbid FOR PORTION OF with WHERE CURRENT OF It is not clear how the implicit condition of FOR PORTION OF should interact with the use of a cursor. Normally, we forbid combining WHERE CURRENT OF with other WHERE conditions. The SQL standard only includes FOR PORTION OF with and , not or , so it is easy for us to exclude the functionality, at least for now. Author: Paul A. Jungwirth Discussion: https://www.postgresql.org/message-id/flat/CA%2BrenyUEKPexUYsH4qeU8_o1jqKsUkEWca1keS6n21shgG1g%2BA%40mail.gmail.com --- doc/src/sgml/ref/delete.sgml | 7 ++-- doc/src/sgml/ref/update.sgml | 7 ++-- src/backend/parser/analyze.c | 10 +++++ src/test/regress/expected/for_portion_of.out | 42 ++++++++++++++++++++ src/test/regress/sql/for_portion_of.sql | 28 +++++++++++++ 5 files changed, 86 insertions(+), 8 deletions(-) diff --git a/doc/src/sgml/ref/delete.sgml b/doc/src/sgml/ref/delete.sgml index 9066d7ea83d..ffdcd7fc4fa 100644 --- a/doc/src/sgml/ref/delete.sgml +++ b/doc/src/sgml/ref/delete.sgml @@ -231,10 +231,9 @@ DELETE FROM [ ONLY ] table_name [ * from this cursor. The cursor must be a non-grouping query on the DELETE's target table. Note that WHERE CURRENT OF cannot be - specified together with a Boolean condition. See - - for more information about using cursors with - WHERE CURRENT OF. + specified together with a Boolean condition or FOR PORTION + OF. See for more information + about using cursors with WHERE CURRENT OF. diff --git a/doc/src/sgml/ref/update.sgml b/doc/src/sgml/ref/update.sgml index dd57bead90c..21a8fd8b037 100644 --- a/doc/src/sgml/ref/update.sgml +++ b/doc/src/sgml/ref/update.sgml @@ -287,10 +287,9 @@ UPDATE [ ONLY ] table_name [ * ] from this cursor. The cursor must be a non-grouping query on the UPDATE's target table. Note that WHERE CURRENT OF cannot be - specified together with a Boolean condition. See - - for more information about using cursors with - WHERE CURRENT OF. + specified together with a Boolean condition or FOR PORTION + OF. See for more information + about using cursors with WHERE CURRENT OF. diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index dc65a505c16..2932d17a107 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -81,6 +81,7 @@ static OnConflictExpr *transformOnConflictClause(ParseState *pstate, static ForPortionOfExpr *transformForPortionOfClause(ParseState *pstate, int rtindex, const ForPortionOfClause *forPortionOf, + const Node *whereClause, bool isUpdate); static int count_rowexpr_columns(ParseState *pstate, Node *expr); static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt, @@ -626,6 +627,7 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt) qry->forPortionOf = transformForPortionOfClause(pstate, qry->resultRelation, stmt->forPortionOf, + stmt->whereClause, false); qual = transformWhereClause(pstate, stmt->whereClause, @@ -1319,6 +1321,7 @@ static ForPortionOfExpr * transformForPortionOfClause(ParseState *pstate, int rtindex, const ForPortionOfClause *forPortionOf, + const Node *whereClause, bool isUpdate) { Relation targetrel = pstate->p_target_relation; @@ -1335,6 +1338,12 @@ transformForPortionOfClause(ParseState *pstate, ForPortionOfExpr *result; Var *rangeVar; + /* disallow FOR PORTION OF ... WHERE CURRENT OF */ + if (whereClause && IsA(whereClause, CurrentOfExpr)) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("WHERE CURRENT OF with FOR PORTION OF is not implemented")); + result = makeNode(ForPortionOfExpr); /* Look up the FOR PORTION OF name requested. */ @@ -2875,6 +2884,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) qry->forPortionOf = transformForPortionOfClause(pstate, qry->resultRelation, stmt->forPortionOf, + stmt->whereClause, true); nsitem = pstate->p_target_nsitem; diff --git a/src/test/regress/expected/for_portion_of.out b/src/test/regress/expected/for_portion_of.out index 43408972117..207e370627e 100644 --- a/src/test/regress/expected/for_portion_of.out +++ b/src/test/regress/expected/for_portion_of.out @@ -2446,4 +2446,46 @@ NOTICE: fpo_before_row1: BEFORE UPDATE ROW: NOTICE: old: [10,100) NOTICE: new: [30,70) DROP TABLE fpo_update_of_trigger; +-- CURSORs +CREATE TABLE fpo_cursed ( + id int, + valid_at int4range +); +INSERT INTO fpo_cursed (id, valid_at) VALUES (1, '[10,100)'); +-- UPDATE FOR PORTION OF is not permitted with a CURSOR: +BEGIN; +DECLARE fpo_cur CURSOR FOR SELECT * FROM fpo_cursed; +FETCH NEXT FROM fpo_cur; + id | valid_at +----+---------- + 1 | [10,100) +(1 row) + +UPDATE fpo_cursed + FOR PORTION OF valid_at FROM 5 TO 6 + SET id = 2 + WHERE CURRENT OF fpo_cur; +ERROR: WHERE CURRENT OF with FOR PORTION OF is not implemented +ROLLBACK; +-- DELETE FOR PORTION OF is not permitted with a CURSOR: +BEGIN; +DECLARE fpo_cur CURSOR FOR SELECT * FROM fpo_cursed; +FETCH NEXT FROM fpo_cur; + id | valid_at +----+---------- + 1 | [10,100) +(1 row) + +DELETE FROM fpo_cursed + FOR PORTION OF valid_at FROM 8 TO 9 + WHERE CURRENT OF fpo_cur; +ERROR: WHERE CURRENT OF with FOR PORTION OF is not implemented +ROLLBACK; +SELECT * FROM fpo_cursed; + id | valid_at +----+---------- + 1 | [10,100) +(1 row) + +DROP TABLE fpo_cursed; RESET datestyle; diff --git a/src/test/regress/sql/for_portion_of.sql b/src/test/regress/sql/for_portion_of.sql index 7b08f8cf45e..a3c41abf7b7 100644 --- a/src/test/regress/sql/for_portion_of.sql +++ b/src/test/regress/sql/for_portion_of.sql @@ -1591,4 +1591,32 @@ UPDATE fpo_update_of_trigger SET id = 2; DROP TABLE fpo_update_of_trigger; +-- CURSORs +CREATE TABLE fpo_cursed ( + id int, + valid_at int4range +); +INSERT INTO fpo_cursed (id, valid_at) VALUES (1, '[10,100)'); + +-- UPDATE FOR PORTION OF is not permitted with a CURSOR: +BEGIN; +DECLARE fpo_cur CURSOR FOR SELECT * FROM fpo_cursed; +FETCH NEXT FROM fpo_cur; +UPDATE fpo_cursed + FOR PORTION OF valid_at FROM 5 TO 6 + SET id = 2 + WHERE CURRENT OF fpo_cur; +ROLLBACK; + +-- DELETE FOR PORTION OF is not permitted with a CURSOR: +BEGIN; +DECLARE fpo_cur CURSOR FOR SELECT * FROM fpo_cursed; +FETCH NEXT FROM fpo_cur; +DELETE FROM fpo_cursed + FOR PORTION OF valid_at FROM 8 TO 9 + WHERE CURRENT OF fpo_cur; +ROLLBACK; +SELECT * FROM fpo_cursed; +DROP TABLE fpo_cursed; + RESET datestyle; From 52e118fe2f7e3381bdaa479816a7f72eda2ae517 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 29 Jun 2026 16:15:13 +0200 Subject: [PATCH 046/481] Fix typo from commit c1fe2d1a383 --- src/bin/pg_upgrade/check.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 7556fb3f22a..f8f31382835 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -2635,7 +2635,7 @@ check_old_cluster_global_names(ClusterInfo *cluster) { fclose(script); pg_log(PG_REPORT, "fatal"); - pg_fatal("Your installation contains databases, roles, or tablespace with names\n" + pg_fatal("Your installation contains databases, roles, or tablespaces with names\n" "with invalid characters (newline or carriage return). To fix this,\n" "rename these objects.\n" "A list of all objects with invalid names is in the file:\n" From 3f815dd11374b54deb29228dc0040179864af828 Mon Sep 17 00:00:00 2001 From: Joe Conway Date: Mon, 29 Jun 2026 15:16:25 -0400 Subject: [PATCH 047/481] Sync typedefs.list with the buildfarm. Replace typedefs.list with the authoritative list from our buildfarm, and run pgindent using that. --- src/tools/pgindent/typedefs.list | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index c5db6ca6705..3a2720fb5f9 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -525,6 +525,7 @@ ConnType ConnectionStateEnum ConnectionTiming ConnectionWarning +ConnectionWarningFilter ConsiderSplitContext Const ConstrCheck @@ -723,7 +724,6 @@ ENGINE EOM_flatten_into_method EOM_get_flat_size_method EPQState -EPlan EState EStatus EVP_CIPHER @@ -3110,7 +3110,6 @@ TParserStateActionItem TQueueDestReceiver TRGM TSAnyCacheEntry -TscClockSourceInfo TSConfigCacheEntry TSConfigInfo TSDictInfo @@ -3261,6 +3260,7 @@ TriggerInfo TriggerInstrumentation TriggerTransition TruncateStmt +TscClockSourceInfo TsmRoutine TupOutputState TupSortStatus From 99e44c3181c779ae0f3539ba7f408661983fbf8e Mon Sep 17 00:00:00 2001 From: Joe Conway Date: Mon, 29 Jun 2026 15:27:44 -0400 Subject: [PATCH 048/481] Run pgperltidy This is required before the creation of a new branch. pgindent is clean, as well as is reformat-dat-files. perltidy version is v20230309, as documented in pgindent's README. --- contrib/dblink/t/001_auth_scram.pl | 13 ++++---- contrib/postgres_fdw/t/001_auth_scram.pl | 20 +++++++------ src/include/catalog/pg_proc.dat | 30 +++++++++---------- src/test/modules/test_misc/t/012_ddlutils.pl | 5 +++- .../recovery/t/051_effective_wal_level.pl | 3 +- src/test/ssl/t/001_ssltests.pl | 9 ++++-- src/test/subscription/t/100_bugs.pl | 6 ++-- 7 files changed, 46 insertions(+), 40 deletions(-) diff --git a/contrib/dblink/t/001_auth_scram.pl b/contrib/dblink/t/001_auth_scram.pl index b087b38e5a5..8d6280656d5 100644 --- a/contrib/dblink/t/001_auth_scram.pl +++ b/contrib/dblink/t/001_auth_scram.pl @@ -103,10 +103,10 @@ { my $connstr = $node1->connstr($db0) . qq' user=$user'; - $node1->safe_psql($db0, + $node1->safe_psql( + $db0, qq'ALTER USER MAPPING FOR $user SERVER $fdw_server3 OPTIONS(add use_scram_passthrough \'false\')', - connstr => $connstr - ); + connstr => $connstr); my ($ret, $stdout, $stderr) = $node1->psql( $db0, @@ -114,10 +114,9 @@ connstr => $connstr); is($ret, 3, 'SCRAM passthrough disabled on user mapping should fail'); - like( - $stderr, - qr/password/i, - 'expected password-related error when scram passthrough disabled on user mapping'); + like($stderr, qr/password/i, + 'expected password-related error when scram passthrough disabled on user mapping' + ); } # Ensure that trust connections fail without superuser opt-in. diff --git a/contrib/postgres_fdw/t/001_auth_scram.pl b/contrib/postgres_fdw/t/001_auth_scram.pl index c4b57cd81b3..972faf1f552 100644 --- a/contrib/postgres_fdw/t/001_auth_scram.pl +++ b/contrib/postgres_fdw/t/001_auth_scram.pl @@ -75,16 +75,19 @@ { my $connstr = $node1->connstr($db0) . qq' user=$user'; - $node1->safe_psql($db0, + $node1->safe_psql( + $db0, qq'ALTER USER MAPPING FOR $user SERVER $fdw_server3 OPTIONS(add use_scram_passthrough \'false\')', - connstr => $connstr - ); + connstr => $connstr); $node1->safe_psql( $db0, qq'CREATE FOREIGN TABLE override_t (g int, col2 int) SERVER $fdw_server3 OPTIONS (table_name \'t\');', - connstr => $connstr ); - $node1->safe_psql($db0, qq'GRANT SELECT ON override_t TO $user;', connstr => $connstr); + connstr => $connstr); + $node1->safe_psql( + $db0, + qq'GRANT SELECT ON override_t TO $user;', + connstr => $connstr); my ($ret, $stdout, $stderr) = $node1->psql( $db0, @@ -92,10 +95,9 @@ connstr => $connstr); is($ret, 3, 'SCRAM passthrough disabled on user mapping should fail'); - like( - $stderr, - qr/password/i, - 'expected password-related error when scram passthrough disabled on user mapping'); + like($stderr, qr/password/i, + 'expected password-related error when scram passthrough disabled on user mapping' + ); } SKIP: diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 402d869710b..1a985becde3 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -8591,27 +8591,25 @@ proname => 'pg_get_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid bool', prosrc => 'pg_get_constraintdef_ext' }, { oid => '6501', descr => 'get DDL to recreate a role', - proname => 'pg_get_role_ddl', prorows => '10', proisstrict => 't', - proretset => 't', provolatile => 's', pronargdefaults => '2', - prorettype => 'text', proargtypes => 'regrole bool bool', - proargnames => '{role,pretty,memberships}', - proargdefaults => '{false,true}', prosrc => 'pg_get_role_ddl' }, + proname => 'pg_get_role_ddl', prorows => '10', proretset => 't', + provolatile => 's', pronargdefaults => '2', prorettype => 'text', + proargtypes => 'regrole bool bool', + proargnames => '{role,pretty,memberships}', proargdefaults => '{false,true}', + prosrc => 'pg_get_role_ddl' }, { oid => '6499', descr => 'get DDL to recreate a tablespace', - proname => 'pg_get_tablespace_ddl', prorows => '10', proisstrict => 't', - proretset => 't', provolatile => 's', pronargdefaults => '2', - prorettype => 'text', proargtypes => 'oid bool bool', - proargnames => '{tablespace,pretty,owner}', + proname => 'pg_get_tablespace_ddl', prorows => '10', proretset => 't', + provolatile => 's', pronargdefaults => '2', prorettype => 'text', + proargtypes => 'oid bool bool', proargnames => '{tablespace,pretty,owner}', proargdefaults => '{false,true}', prosrc => 'pg_get_tablespace_ddl_oid' }, { oid => '6500', descr => 'get DDL to recreate a tablespace', - proname => 'pg_get_tablespace_ddl', prorows => '10', proisstrict => 't', - proretset => 't', provolatile => 's', pronargdefaults => '2', - prorettype => 'text', proargtypes => 'name bool bool', - proargnames => '{tablespace,pretty,owner}', + proname => 'pg_get_tablespace_ddl', prorows => '10', proretset => 't', + provolatile => 's', pronargdefaults => '2', prorettype => 'text', + proargtypes => 'name bool bool', proargnames => '{tablespace,pretty,owner}', proargdefaults => '{false,true}', prosrc => 'pg_get_tablespace_ddl_name' }, { oid => '6502', descr => 'get DDL to recreate a database', - proname => 'pg_get_database_ddl', prorows => '10', proisstrict => 't', - proretset => 't', provolatile => 's', pronargdefaults => '3', - prorettype => 'text', proargtypes => 'regdatabase bool bool bool', + proname => 'pg_get_database_ddl', prorows => '10', proretset => 't', + provolatile => 's', pronargdefaults => '3', prorettype => 'text', + proargtypes => 'regdatabase bool bool bool', proargnames => '{database,pretty,owner,tablespace}', proargdefaults => '{false,true,true}', prosrc => 'pg_get_database_ddl' }, { oid => '2509', diff --git a/src/test/modules/test_misc/t/012_ddlutils.pl b/src/test/modules/test_misc/t/012_ddlutils.pl index e541dfa38d1..c4096879922 100644 --- a/src/test/modules/test_misc/t/012_ddlutils.pl +++ b/src/test/modules/test_misc/t/012_ddlutils.pl @@ -181,7 +181,10 @@ sub ddl_filter q{SELECT * FROM pg_get_database_ddl('regression_ddlutils_test', owner => 'invalid')} ); isnt($ret, 0, 'invalid boolean option errors'); -like($stderr, qr/invalid input syntax for type boolean/, 'invalid option error message'); +like( + $stderr, + qr/invalid input syntax for type boolean/, + 'invalid option error message'); # Duplicate named argument ($ret, $stdout, $stderr) = $node->psql( diff --git a/src/test/recovery/t/051_effective_wal_level.pl b/src/test/recovery/t/051_effective_wal_level.pl index c45eddc7383..d4bc7f0aa40 100644 --- a/src/test/recovery/t/051_effective_wal_level.pl +++ b/src/test/recovery/t/051_effective_wal_level.pl @@ -76,8 +76,7 @@ sub wait_for_logical_decoding_disabled # Wait for the checkpointer to disable logical decoding. wait_for_logical_decoding_disabled($primary); test_wal_level($primary, "replica|replica", - "logical decoding disabled after repack" -); + "logical decoding disabled after repack"); # Create a new logical slot and check that effective_wal_level must be increased # to 'logical'. diff --git a/src/test/ssl/t/001_ssltests.pl b/src/test/ssl/t/001_ssltests.pl index 01f3573e1fd..cb7c2a06193 100644 --- a/src/test/ssl/t/001_ssltests.pl +++ b/src/test/ssl/t/001_ssltests.pl @@ -885,7 +885,8 @@ sub switch_server_cert "$common_connstr user=ssltestuser sslcert=ssl/client-revoked.crt " . sslkey('client-revoked.key'), "certificate authorization fails with revoked client cert", - expected_stderr => qr!SSL error: (ssl[a-z0-9/]*|tls) alert certificate revoked!, + expected_stderr => + qr!SSL error: (ssl[a-z0-9/]*|tls) alert certificate revoked!, log_like => [ qr{Client certificate verification failed at depth 0: certificate revoked}, qr{Failed certificate data \(unverified\): subject "/CN=ssltestuser", serial number \d+, issuer "/CN=Test CA for PostgreSQL SSL regression test client certs"}, @@ -987,7 +988,8 @@ sub switch_server_cert "$common_connstr user=ssltestuser sslcert=ssl/client-revoked.crt " . sslkey('client-revoked.key'), "certificate authorization fails with revoked client cert with server-side CRL directory", - expected_stderr => qr!SSL error: (ssl[a-z0-9/]*|tls) alert certificate revoked!, + expected_stderr => + qr!SSL error: (ssl[a-z0-9/]*|tls) alert certificate revoked!, log_like => [ qr{Client certificate verification failed at depth 0: certificate revoked}, qr{Failed certificate data \(unverified\): subject "/CN=ssltestuser", serial number \d+, issuer "/CN=Test CA for PostgreSQL SSL regression test client certs"}, @@ -998,7 +1000,8 @@ sub switch_server_cert "$common_connstr user=ssltestuser sslcert=ssl/client-revoked-utf8.crt " . sslkey('client-revoked-utf8.key'), "certificate authorization fails with revoked UTF-8 client cert with server-side CRL directory", - expected_stderr => qr!SSL error: (ssl[a-z0-9/]*|tls) alert certificate revoked!, + expected_stderr => + qr!SSL error: (ssl[a-z0-9/]*|tls) alert certificate revoked!, log_like => [ qr{Client certificate verification failed at depth 0: certificate revoked}, qr{Failed certificate data \(unverified\): subject "/CN=\\xce\\x9f\\xce\\xb4\\xcf\\x85\\xcf\\x83\\xcf\\x83\\xce\\xad\\xce\\xb1\\xcf\\x82", serial number \d+, issuer "/CN=Test CA for PostgreSQL SSL regression test client certs"}, diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl index 31dc63ae8c4..075c52f98fd 100644 --- a/src/test/subscription/t/100_bugs.pl +++ b/src/test/subscription/t/100_bugs.pl @@ -644,8 +644,10 @@ BEGIN ); # Clean up -$node_publisher->safe_psql('postgres', "SELECT pg_drop_replication_slot('upsert_slot')"); -$node_publisher->safe_psql('postgres', "DROP PUBLICATION pub_rowfilter_error"); +$node_publisher->safe_psql('postgres', + "SELECT pg_drop_replication_slot('upsert_slot')"); +$node_publisher->safe_psql('postgres', + "DROP PUBLICATION pub_rowfilter_error"); $node_publisher->safe_psql('postgres', "DROP TABLE tab_upsert"); $node_publisher->stop('fast'); From 9cfd19bc10ac07139ca6c6d051d4492764441edb Mon Sep 17 00:00:00 2001 From: Joe Conway Date: Mon, 29 Jun 2026 15:33:52 -0400 Subject: [PATCH 049/481] Add previous 2 commits to .git-blame-ignore-revs. --- .git-blame-ignore-revs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index f9a955af12d..4d8f98d953b 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -14,6 +14,12 @@ # # $ git log --pretty=format:"%H # %cd%n# %s" $PGINDENTGITHASH -1 --date=iso +99e44c3181c779ae0f3539ba7f408661983fbf8e # 2026-06-29 15:27:44 -0400 +# Run pgperltidy + +3f815dd11374b54deb29228dc0040179864af828 # 2026-06-29 15:16:25 -0400 +# Sync typedefs.list with the buildfarm. + bd57abbb1910e51e45761b59985745d094ae9e03 # 2026-06-04 10:15:37 -0500 # Re-pgindent nodeModifyTable.c after commit 993a7aa0e4. From 3cd530e84b05080492dcf0f4c596ef9d58ced012 Mon Sep 17 00:00:00 2001 From: Joe Conway Date: Mon, 29 Jun 2026 16:39:23 -0400 Subject: [PATCH 050/481] Adapt REL_19_STABLE to its new status as a stable branch Per the checklist in RELEASE_CHANGES for the creation of a new stable branch, this commit does the following things: - Update URLs of top-level README and Makefile to point to the new stable version. --- Makefile | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9bc1a4ec17b..e76169f9a34 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ all: all check install installdirs installcheck installcheck-parallel uninstall clean distclean maintainer-clean dist distcheck world check-world install-world installcheck-world: @if [ ! -f GNUmakefile ] ; then \ echo "You need to run the 'configure' program first. Please see"; \ - echo "" ; \ + echo "" ; \ false ; \ fi @IFS=':' ; \ diff --git a/README.md b/README.md index f6104c038b3..d97057b2e64 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ and functions. This distribution also contains C language bindings. Copyright and license information can be found in the file COPYRIGHT. General documentation about this version of PostgreSQL can be found at -. In particular, information +. In particular, information about building PostgreSQL from the source code can be found at -. +. The latest version of this software, and related software, may be obtained at . For more information From 1a7fa06dbcd186f4e13332157f3ffb6da955fe1a Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 29 Jun 2026 17:37:58 -0400 Subject: [PATCH 051/481] doc PG 19 relnotes: fix autovacuum_vacuum_score_weight prefix Was missing "autovacuum_" prefix. Reported-by: Chao Li Author: Chao Li Discussion: https://postgr.es/m/6D50BAF9-0586-420C-AFAC-CCDB61EF694A@gmail.com Backpatch-through: 19 only --- doc/src/sgml/release-19.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/release-19.sgml b/doc/src/sgml/release-19.sgml index b0925d5f24b..d8d3758d5ba 100644 --- a/doc/src/sgml/release-19.sgml +++ b/doc/src/sgml/release-19.sgml @@ -1318,7 +1318,7 @@ Add scoring system to control the order that tables are processed by -The new server variables are autovacuum_freeze_score_weight, autovacuum_multixact_freeze_score_weight, autovacuum_vacuum_score_weight, vacuum_insert_score_weight, and +The new server variables are autovacuum_freeze_score_weight, autovacuum_multixact_freeze_score_weight, autovacuum_vacuum_score_weight, autovacuum_vacuum_insert_score_weight, and autovacuum_analyze_score_weight. From ac536a4061bcf22db46ba23d077cd36e65e14e1a Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 30 Jun 2026 08:30:52 +0900 Subject: [PATCH 052/481] Simplify some stats restore code with InputFunctionCallSafe() statatt_build_stavalues() and array_in_safe() have been relying on InitFunctionCallInfoData() with a locally-filled state to call a data type input function. InputFunctionCallSafe() can be used to achieve the same job, simplifying some code. This fixes an over-allocation of FunctionCallInfoBaseData done in statatt_build_stavalues(), where there was space for 8 elements but only 3 were needed. The over-allocation exists since REL_18_STABLE, and was harmless in practice. While on it, fix some comments for both routines, where elemtypid was mentioned. Backpatch down to v19. This code has been reworked during the last development cycle while working on the restore of extended statistics, so this keeps the code consistent across all branches. Author: Jian He Author: Michael Paquier Discussion: https://postgr.es/m/CACJufxEGah9PaiTQ=cG14GMMBsUQ3ohGct9tdSwbMQPQ0-nbbQ@mail.gmail.com Backpatch-through: 19 --- src/backend/statistics/extended_stats_funcs.c | 17 +++----------- src/backend/statistics/stat_utils.c | 23 +++++-------------- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/src/backend/statistics/extended_stats_funcs.c b/src/backend/statistics/extended_stats_funcs.c index 2cb3942056f..a5dce8a2206 100644 --- a/src/backend/statistics/extended_stats_funcs.c +++ b/src/backend/statistics/extended_stats_funcs.c @@ -1033,7 +1033,7 @@ jbv_to_infunc_datum(JsonbValue *jval, PGFunction func, AttrNumber exprnum, } /* - * Build an array datum with element type elemtypid from a text datum, used as + * Build an array datum with element type typid from a text datum, used as * value of an attribute in a pg_statistic tuple. * * If an error is encountered, capture it, and reduce the elevel to WARNING. @@ -1044,7 +1044,6 @@ static Datum array_in_safe(FmgrInfo *array_in, const char *s, Oid typid, int32 typmod, AttrNumber exprnum, const char *element_name, bool *ok) { - LOCAL_FCINFO(fcinfo, 3); Datum result; ErrorSaveContext escontext = { @@ -1053,17 +1052,6 @@ array_in_safe(FmgrInfo *array_in, const char *s, Oid typid, int32 typmod, }; *ok = false; - InitFunctionCallInfoData(*fcinfo, array_in, 3, InvalidOid, - (Node *) &escontext, NULL); - - fcinfo->args[0].value = CStringGetDatum(s); - fcinfo->args[0].isnull = false; - fcinfo->args[1].value = ObjectIdGetDatum(typid); - fcinfo->args[1].isnull = false; - fcinfo->args[2].value = Int32GetDatum(typmod); - fcinfo->args[2].isnull = false; - - result = FunctionCallInvoke(fcinfo); /* * If the array_in function returned an error, we will want to report that @@ -1071,7 +1059,8 @@ array_in_safe(FmgrInfo *array_in, const char *s, Oid typid, int32 typmod, * Overwriting the existing hint (if any) is not ideal, and an error * context would only work for level >= ERROR. */ - if (escontext.error_occurred) + if (!InputFunctionCallSafe(array_in, (char *) s, typid, typmod, + (Node *) &escontext, &result)) { StringInfoData hint_str; diff --git a/src/backend/statistics/stat_utils.c b/src/backend/statistics/stat_utils.c index a673e3c704b..0b190e88237 100644 --- a/src/backend/statistics/stat_utils.c +++ b/src/backend/statistics/stat_utils.c @@ -555,7 +555,7 @@ statatt_get_elem_type(Oid atttypid, char atttyptype, } /* - * Build an array with element type elemtypid from a text datum, used as + * Build an array with element type typid from a text datum, used as * value of an attribute in a tuple to-be-inserted into pg_statistic. * * The typid and typmod should be derived from a previous call to @@ -569,7 +569,6 @@ Datum statatt_build_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid, int32 typmod, bool *ok) { - LOCAL_FCINFO(fcinfo, 8); char *s; Datum result; ErrorSaveContext escontext = {T_ErrorSaveContext}; @@ -578,28 +577,18 @@ statatt_build_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid ty s = TextDatumGetCString(d); - InitFunctionCallInfoData(*fcinfo, array_in, 3, InvalidOid, - (Node *) &escontext, NULL); - - fcinfo->args[0].value = CStringGetDatum(s); - fcinfo->args[0].isnull = false; - fcinfo->args[1].value = ObjectIdGetDatum(typid); - fcinfo->args[1].isnull = false; - fcinfo->args[2].value = Int32GetDatum(typmod); - fcinfo->args[2].isnull = false; - - result = FunctionCallInvoke(fcinfo); - - pfree(s); - - if (escontext.error_occurred) + if (!InputFunctionCallSafe(array_in, s, typid, typmod, + (Node *) &escontext, &result)) { + pfree(s); escontext.error_data->elevel = WARNING; ThrowErrorData(escontext.error_data); *ok = false; return (Datum) 0; } + pfree(s); + if (ARR_NDIM(DatumGetArrayTypeP(result)) != 1) { ereport(WARNING, From 22af34b983620a840e38c5f4ddae34b53647ba5c Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Tue, 30 Jun 2026 08:48:47 +0900 Subject: [PATCH 053/481] Fix unlogged sequence corruption after standby promotion Previously, if an unlogged sequence was created on the primary and replicated to a standby, reading the sequence after promoting the standby (for example, with nextval()) could trigger the following assertion failure: TRAP: failed Assert("((const PageHeaderData *) page)->pd_special >= SizeOfPageHeaderData") In non-assert builds, the same operation could instead fail with an error such as: ERROR: bad magic number in sequence The problem was that seq_redo() updated the init fork page in shared buffers but did not flush it to disk. During promotion, ResetUnloggedRelations() recreates the main fork of unlogged relations by copying the init fork from disk, bypassing shared buffers. As a result, the main fork could be recreated from a stale init fork instead of the WAL-replayed page. Fix this by introducing a helper to flush init fork buffers immediately, and make seq_redo() use it. As a result, the main fork of an unlogged sequence is recreated from the up-to-date init fork on disk, allowing the unlogged sequence to be read successfully after standby promotion. Backpatch to v15, where unlogged sequences were introduced. Author: Fujii Masao Reviewed-by: vignesh C Discussion: https://postgr.es/m/CAHGQGwH1Ssze3XM6wjoTjSLVOR041c6xP+vsdLP951=w8oG8bA@mail.gmail.com Backpatch-through: 15 --- src/backend/access/hash/hash_xlog.c | 29 ++-------------- src/backend/access/transam/xlogutils.c | 26 +++++++++++++- src/backend/commands/sequence_xlog.c | 1 + src/include/access/xlogutils.h | 2 ++ src/test/recovery/meson.build | 1 + .../t/054_unlogged_sequence_promotion.pl | 34 +++++++++++++++++++ 6 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 src/test/recovery/t/054_unlogged_sequence_promotion.pl diff --git a/src/backend/access/hash/hash_xlog.c b/src/backend/access/hash/hash_xlog.c index 2060620c7de..e9a2b9aa9a7 100644 --- a/src/backend/access/hash/hash_xlog.c +++ b/src/backend/access/hash/hash_xlog.c @@ -29,7 +29,6 @@ hash_xlog_init_meta_page(XLogReaderState *record) XLogRecPtr lsn = record->EndRecPtr; Page page; Buffer metabuf; - ForkNumber forknum; xl_hash_init_meta_page *xlrec = (xl_hash_init_meta_page *) XLogRecGetData(record); @@ -41,16 +40,7 @@ hash_xlog_init_meta_page(XLogReaderState *record) page = BufferGetPage(metabuf); PageSetLSN(page, lsn); MarkBufferDirty(metabuf); - - /* - * Force the on-disk state of init forks to always be in sync with the - * state in shared buffers. See XLogReadBufferForRedoExtended. We need - * special handling for init forks as create index operations don't log a - * full page image of the metapage. - */ - XLogRecGetBlockTag(record, 0, NULL, &forknum, NULL); - if (forknum == INIT_FORKNUM) - FlushOneBuffer(metabuf); + XLogFlushBufferForRedoIfInit(record, 0, metabuf); /* all done */ UnlockReleaseBuffer(metabuf); @@ -68,7 +58,6 @@ hash_xlog_init_bitmap_page(XLogReaderState *record) Page page; HashMetaPage metap; uint32 num_buckets; - ForkNumber forknum; xl_hash_init_bitmap_page *xlrec = (xl_hash_init_bitmap_page *) XLogRecGetData(record); @@ -79,16 +68,7 @@ hash_xlog_init_bitmap_page(XLogReaderState *record) _hash_initbitmapbuffer(bitmapbuf, xlrec->bmsize, true); PageSetLSN(BufferGetPage(bitmapbuf), lsn); MarkBufferDirty(bitmapbuf); - - /* - * Force the on-disk state of init forks to always be in sync with the - * state in shared buffers. See XLogReadBufferForRedoExtended. We need - * special handling for init forks as create index operations don't log a - * full page image of the metapage. - */ - XLogRecGetBlockTag(record, 0, NULL, &forknum, NULL); - if (forknum == INIT_FORKNUM) - FlushOneBuffer(bitmapbuf); + XLogFlushBufferForRedoIfInit(record, 0, bitmapbuf); UnlockReleaseBuffer(bitmapbuf); /* add the new bitmap page to the metapage's list of bitmaps */ @@ -109,10 +89,7 @@ hash_xlog_init_bitmap_page(XLogReaderState *record) PageSetLSN(page, lsn); MarkBufferDirty(metabuf); - - XLogRecGetBlockTag(record, 1, NULL, &forknum, NULL); - if (forknum == INIT_FORKNUM) - FlushOneBuffer(metabuf); + XLogFlushBufferForRedoIfInit(record, 1, metabuf); } if (BufferIsValid(metabuf)) UnlockReleaseBuffer(metabuf); diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c index fdc341d8fa4..d8c179c5dcc 100644 --- a/src/backend/access/transam/xlogutils.c +++ b/src/backend/access/transam/xlogutils.c @@ -321,6 +321,28 @@ XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id) return buf; } +/* + * If a redo routine modified an init fork, flush the buffer immediately. + * + * At the end of crash recovery the init forks of unlogged relations are + * copied to the main fork directly from disk, without going through shared + * buffers. Therefore, redo routines that update init forks without + * restoring a full-page image must call this after setting the page LSN and + * marking the buffer dirty. + */ +void +XLogFlushBufferForRedoIfInit(XLogReaderState *record, uint8 block_id, + Buffer buffer) +{ + ForkNumber forknum; + + Assert(BufferIsValid(buffer)); + + XLogRecGetBlockTag(record, block_id, NULL, &forknum, NULL); + if (forknum == INIT_FORKNUM) + FlushOneBuffer(buffer); +} + /* * XLogReadBufferForRedoExtended * Like XLogReadBufferForRedo, but with extra options. @@ -398,7 +420,9 @@ XLogReadBufferForRedoExtended(XLogReaderState *record, * At the end of crash recovery the init forks of unlogged relations * are copied, without going through shared buffers. So we need to * force the on-disk state of init forks to always be in sync with the - * state in shared buffers. + * state in shared buffers. Use XLogFlushBufferForRedoIfInit() for + * redo routines that dirty init-fork buffers without restoring a + * full-page image. */ if (forknum == INIT_FORKNUM) FlushOneBuffer(*buf); diff --git a/src/backend/commands/sequence_xlog.c b/src/backend/commands/sequence_xlog.c index d0aed48e268..fcb3230cf3b 100644 --- a/src/backend/commands/sequence_xlog.c +++ b/src/backend/commands/sequence_xlog.c @@ -63,6 +63,7 @@ seq_redo(XLogReaderState *record) memcpy(page, localpage, BufferGetPageSize(buffer)); MarkBufferDirty(buffer); + XLogFlushBufferForRedoIfInit(record, 0, buffer); UnlockReleaseBuffer(buffer); pfree(localpage); diff --git a/src/include/access/xlogutils.h b/src/include/access/xlogutils.h index b97387c6d4c..0c6c7410069 100644 --- a/src/include/access/xlogutils.h +++ b/src/include/access/xlogutils.h @@ -87,6 +87,8 @@ typedef struct ReadLocalXLogPageNoWaitPrivate extern XLogRedoAction XLogReadBufferForRedo(XLogReaderState *record, uint8 block_id, Buffer *buf); extern Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id); +extern void XLogFlushBufferForRedoIfInit(XLogReaderState *record, + uint8 block_id, Buffer buffer); extern XLogRedoAction XLogReadBufferForRedoExtended(XLogReaderState *record, uint8 block_id, ReadBufferMode mode, bool get_cleanup_lock, diff --git a/src/test/recovery/meson.build b/src/test/recovery/meson.build index 9eb8ed11425..ad0d85f4189 100644 --- a/src/test/recovery/meson.build +++ b/src/test/recovery/meson.build @@ -62,6 +62,7 @@ tests += { 't/051_effective_wal_level.pl', 't/052_checkpoint_segment_missing.pl', 't/053_standby_login_event_trigger.pl', + 't/054_unlogged_sequence_promotion.pl', ], }, } diff --git a/src/test/recovery/t/054_unlogged_sequence_promotion.pl b/src/test/recovery/t/054_unlogged_sequence_promotion.pl new file mode 100644 index 00000000000..96d1e4bf18b --- /dev/null +++ b/src/test/recovery/t/054_unlogged_sequence_promotion.pl @@ -0,0 +1,34 @@ +# Copyright (c) 2026, PostgreSQL Global Development Group + +# Test that unlogged sequences created on a primary can be read after +# promotion of a standby that replayed their init fork. + +use strict; +use warnings FATAL => 'all'; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +my $node_primary = PostgreSQL::Test::Cluster->new('primary'); +$node_primary->init(allows_streaming => 1); +$node_primary->start; + +my $backup_name = 'my_backup'; +$node_primary->backup($backup_name); + +my $node_standby = PostgreSQL::Test::Cluster->new('standby'); +$node_standby->init_from_backup($node_primary, $backup_name, + has_streaming => 1); +$node_standby->start; + +# Create the unlogged sequence after the standby has started, so its init fork +# is generated by WAL replay on the standby. +$node_primary->safe_psql('postgres', "CREATE UNLOGGED SEQUENCE ulseq"); +$node_primary->wait_for_replay_catchup($node_standby); + +$node_standby->promote; + +is($node_standby->safe_psql('postgres', "SELECT nextval('ulseq')"), + 1, 'unlogged sequence can be read after standby promotion'); + +done_testing(); From b07664a179bd038aec89813b336306678a84bb1c Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Tue, 30 Jun 2026 10:28:52 +0900 Subject: [PATCH 054/481] Remove stray blank line in ParseFuncOrColumn() Commit 419ce13b701 accidentally left a stray blank line in ParseFuncOrColumn(). Remove it. No functional change. Author: Henson Choi Discussion: https://postgr.es/m/CAAAe_zDLBkZFXXCgR_-NuaeW+aUXUtuDoSgg-2QRz+b2g7G4BA@mail.gmail.com Backpatch-through: 19 --- src/backend/parser/parse_func.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index fb306c05112..9cdbaa542fe 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -526,7 +526,6 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, errmsg("%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP", NameListToString(funcname)), parser_errposition(pstate, location))); - } if (ignore_nulls != NO_NULLTREATMENT) From 74e93d0f0000f197f27d311ab5fd70b3adfbac26 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Tue, 30 Jun 2026 10:30:47 +0900 Subject: [PATCH 055/481] bufmgr: Fix race in LockBufferForCleanup() LockBufferForCleanup() acquires the exclusive content lock, checks the buffer's shared pin count, and, if other pins remain, registers itself as the BM_PIN_COUNT_WAITER before waiting for an unpin notification. Since commits 5310fac6e0f and c75ebc657ffc, however, a shared buffer pin can be released while BM_LOCKED is set, introducing the following race: - LockBufferForCleanup() observes a refcount greater than one. - Before it sets BM_PIN_COUNT_WAITER, another backend releases the last conflicting pin. - Since BM_PIN_COUNT_WAITER is not yet set, no wakeup is sent. - LockBufferForCleanup() then sets BM_PIN_COUNT_WAITER and goes to sleep, even though only its own pin remains. As a result, LockBufferForCleanup() can sleep indefinitely because the wakeup corresponding to the last conflicting unpin has already been missed. Fix this by setting BM_PIN_COUNT_WAITER while holding the buffer header lock, then rechecking the refcount before releasing the content lock. If only our pin remains, clear the waiter state and proceed without sleeping. Otherwise, wait as before. This issue was reported by buildfarm member skink, where it manifested as intermittent timeouts in 048_vacuum_horizon_floor.pl. Backpatch to v19, where commits 5310fac6e0f and c75ebc657ffc introduced the race. Reported-by: Alexander Lakhin Author: Xuneng Zhou Reviewed-by: Andres Freund Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/7685519a-0bf9-4e17-93ca-7e3aa10fa29c@gmail.com Backpatch-through: 19 --- src/backend/storage/buffer/bufmgr.c | 68 ++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index d6c0cc1f6d4..f79a8fa5da2 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -6715,24 +6715,7 @@ LockBufferForCleanup(Buffer buffer) { /* Successfully acquired exclusive lock with pincount 1 */ UnlockBufHdr(bufHdr); - - /* - * Emit the log message if recovery conflict on buffer pin was - * resolved but the startup process waited longer than - * deadlock_timeout for it. - */ - if (logged_recovery_conflict) - LogRecoveryConflict(RECOVERY_CONFLICT_BUFFERPIN, - waitStart, GetCurrentTimestamp(), - NULL, false); - - if (waiting) - { - /* reset ps display to remove the suffix if we added one */ - set_ps_display_remove_suffix(); - waiting = false; - } - return; + goto cleanup_lock_acquired; } /* Failed, so mark myself as waiting for pincount 1 */ if (buf_state & BM_PIN_COUNT_WAITER) @@ -6743,9 +6726,32 @@ LockBufferForCleanup(Buffer buffer) } bufHdr->wait_backend_pgprocno = MyProcNumber; PinCountWaitBuf = bufHdr; - UnlockBufHdrExt(bufHdr, buf_state, - BM_PIN_COUNT_WAITER, 0, - 0); + + /* + * Publish BM_PIN_COUNT_WAITER while retaining the buffer header lock. + * The shared refcount can be decremented while BM_LOCKED is set, so + * use an atomic operation that preserves concurrent refcount changes. + */ + pg_atomic_fetch_or_u64(&bufHdr->state, BM_PIN_COUNT_WAITER); + + /* + * Recheck the refcount after publishing the waiter flag, while shared + * refcount increments are still prevented by BM_LOCKED. If only our + * pin remains, the cleanup-lock condition has already been satisfied, + * so remove the waiter state and return without sleeping. + */ + buf_state = pg_atomic_read_u64(&bufHdr->state); + + if (BUF_STATE_GET_REFCOUNT(buf_state) == 1) + { + UnlockBufHdrExt(bufHdr, buf_state, + 0, BM_PIN_COUNT_WAITER, + 0); + PinCountWaitBuf = NULL; + goto cleanup_lock_acquired; + } + + UnlockBufHdr(bufHdr); LockBuffer(buffer, BUFFER_LOCK_UNLOCK); /* Wait to be signaled by UnpinBuffer() */ @@ -6816,6 +6822,26 @@ LockBufferForCleanup(Buffer buffer) PinCountWaitBuf = NULL; /* Loop back and try again */ } + +cleanup_lock_acquired: + + /* + * Emit the log message if recovery conflict on buffer pin was resolved + * but the startup process waited longer than deadlock_timeout for it. + */ + if (logged_recovery_conflict) + LogRecoveryConflict(RECOVERY_CONFLICT_BUFFERPIN, + waitStart, GetCurrentTimestamp(), + NULL, false); + + if (waiting) + { + /* reset ps display to remove the suffix if we added one */ + set_ps_display_remove_suffix(); + waiting = false; + } + + return; } /* From 7e5a19a16c55290471c6503a2b3e50d1e14d393c Mon Sep 17 00:00:00 2001 From: Noah Misch Date: Mon, 29 Jun 2026 19:41:09 -0700 Subject: [PATCH 056/481] Restore comment at appendShellString(). Commit b380a56a3f9556588a89013b765d67947d54f7d0 removed a paragraph, but two of the paragraph's three sentences remained relevant. Backpatch-through: 19 --- src/fe_utils/string_utils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fe_utils/string_utils.c b/src/fe_utils/string_utils.c index 38fffbd036b..7a762251f32 100644 --- a/src/fe_utils/string_utils.c +++ b/src/fe_utils/string_utils.c @@ -568,6 +568,10 @@ appendByteaLiteral(PQExpBuffer buf, const unsigned char *str, size_t length, * Append the given string to the shell command being built in the buffer, * with shell-style quoting as needed to create exactly one argument. * + * Forbid LF or CR characters, which have scant practical use beyond designing + * security breaches. The Windows command shell is unusable as a conduit for + * arguments containing LF or CR characters. + * * appendShellString() simply prints an error and dies if LF or CR appears. * appendShellStringNoError() omits those characters from the result, and * returns false if there were any. From ff6f6e0470ecb362a389bb20aac46a843e496c2f Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 30 Jun 2026 12:47:57 +0900 Subject: [PATCH 057/481] Change stat_lock.wait_time to double precision Other statistics views (pg_stat_io, pg_stat_database, etc.) use float8 for all measured-time columns, the new pg_stat_lock standing out as an outlier by using bigint. This commit aligns pg_stat_lock with the other stats views for consistency. Like pg_stat_io, the time is stored in microseconds, and is displayed in milliseconds with a conversion done when the view is queried. While on it, replace a use of "long" by PgStat_Counter, the former could overflow for large wait times where sizeof(long) is 4 bytes (aka WIN32). Bump catalog version. Author: Tatsuya Kawata Reviewed-by: Bertrand Drouvot Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/CAHza6qerEiQehrbW5xaXyxvR0qJe3KBX1R4kocDz1+7Ygu8x-g@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/monitoring.sgml | 2 +- src/backend/storage/lmgr/proc.c | 9 +++++---- src/backend/utils/activity/pgstat_lock.c | 4 ++-- src/backend/utils/adt/pgstatfuncs.c | 2 +- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 2 +- src/include/pgstat.h | 5 +++-- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 08d5b824552..6dcf05eb702 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -3359,7 +3359,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - wait_time bigint + wait_time double precision Total time spent waiting for locks of this type, in milliseconds. diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 6fa9de33e1c..7d01c981a1f 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -1608,12 +1608,13 @@ ProcSleep(LOCALLOCK *locallock) TimestampDifference(get_timeout_start_time(DEADLOCK_TIMEOUT), GetCurrentTimestamp(), &secs, &usecs); - msecs = secs * 1000 + usecs / 1000; - usecs = usecs % 1000; - /* Increment the lock statistics counters if done waiting. */ if (myWaitStatus == PROC_WAIT_STATUS_OK) - pgstat_count_lock_waits(locallock->tag.lock.locktag_type, msecs); + pgstat_count_lock_waits(locallock->tag.lock.locktag_type, + (PgStat_Counter) secs * 1000000 + usecs); + + msecs = secs * 1000 + usecs / 1000; + usecs = usecs % 1000; if (log_lock_waits) { diff --git a/src/backend/utils/activity/pgstat_lock.c b/src/backend/utils/activity/pgstat_lock.c index aec64f8fb4b..8910a15634d 100644 --- a/src/backend/utils/activity/pgstat_lock.c +++ b/src/backend/utils/activity/pgstat_lock.c @@ -140,11 +140,11 @@ pgstat_count_lock_fastpath_exceeded(uint8 locktag_type) * like lock acquisitions. */ void -pgstat_count_lock_waits(uint8 locktag_type, long msecs) +pgstat_count_lock_waits(uint8 locktag_type, PgStat_Counter usecs) { Assert(locktag_type <= LOCKTAG_LAST_TYPE); PendingLockStats.stats[locktag_type].waits++; - PendingLockStats.stats[locktag_type].wait_time += (PgStat_Counter) msecs; + PendingLockStats.stats[locktag_type].wait_time += usecs; have_lockstats = true; pgstat_report_fixed = true; } diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 6f9c9c72de5..0c59df17901 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -1761,7 +1761,7 @@ pg_stat_get_lock(PG_FUNCTION_ARGS) values[i++] = CStringGetTextDatum(locktypename); values[i++] = Int64GetDatum(lck_stats->waits); - values[i++] = Int64GetDatum(lck_stats->wait_time); + values[i++] = Float8GetDatum(pg_stat_us_to_ms(lck_stats->wait_time)); values[i++] = Int64GetDatum(lck_stats->fastpath_exceeded); values[i] = TimestampTzGetDatum(lock_stats->stat_reset_timestamp); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 635c0d9cb13..875a147f753 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202606281 +#define CATALOG_VERSION_NO 202606301 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 1a985becde3..efe13b7866a 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6064,7 +6064,7 @@ { oid => '6509', descr => 'statistics: per lock type statistics', proname => 'pg_stat_get_lock', prorows => '10', proretset => 't', provolatile => 'v', proparallel => 'r', prorettype => 'record', - proargtypes => '', proallargtypes => '{text,int8,int8,int8,timestamptz}', + proargtypes => '', proallargtypes => '{text,int8,float8,int8,timestamptz}', proargmodes => '{o,o,o,o,o}', proargnames => '{locktype,waits,wait_time,fastpath_exceeded,stats_reset}', prosrc => 'pg_stat_get_lock' }, diff --git a/src/include/pgstat.h b/src/include/pgstat.h index dfa2e837638..72496695999 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -349,7 +349,7 @@ typedef struct PgStat_IO typedef struct PgStat_LockEntry { PgStat_Counter waits; - PgStat_Counter wait_time; /* time in milliseconds */ + PgStat_Counter wait_time; /* time in microseconds */ PgStat_Counter fastpath_exceeded; } PgStat_LockEntry; @@ -638,7 +638,8 @@ extern bool pgstat_tracks_io_op(BackendType bktype, IOObject io_object, extern void pgstat_lock_flush(bool nowait); extern void pgstat_count_lock_fastpath_exceeded(uint8 locktag_type); -extern void pgstat_count_lock_waits(uint8 locktag_type, long msecs); +extern void pgstat_count_lock_waits(uint8 locktag_type, + PgStat_Counter usecs); extern PgStat_Lock *pgstat_fetch_stat_lock(void); /* From 2fb6015f78749c3a235354acded31562414775be Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 30 Jun 2026 14:03:10 +0200 Subject: [PATCH 058/481] Fixes for SPI "const Datum *" use Fixup for commit 8a27d418f8f, which converted many functions to use "const Datum *" instead of "Datum *", including some SPI functions. For SPI_cursor_open(), the code was updated but not the documentation. For SPI_cursor_open_with_args(), the documentation was updated but not the code. (Possibly, these two were confused with each other.) Also, SPI_execp() and SPI_modifytuple() were not updated, even though they are closely related to the functions touched by the previous commit and now look inconsistent. Fix all these. Reviewed-by: Tom Lane Discussion: https://www.postgresql.org/message-id/flat/86b5162f-c472-40fa-997b-0450dece1dec%40eisentraut.org --- doc/src/sgml/spi.sgml | 6 +++--- src/backend/executor/spi.c | 6 +++--- src/include/executor/spi.h | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index e30d0962ae7..179cceb8da9 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -2086,7 +2086,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, -int SPI_execp(SPIPlanPtr plan, Datum * values, const char * nulls, long count) +int SPI_execp(SPIPlanPtr plan, const Datum * values, const char * nulls, long count) @@ -2191,7 +2191,7 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< Portal SPI_cursor_open(const char * name, SPIPlanPtr plan, - Datum * values, const char * nulls, + const Datum * values, const char * nulls, bool read_only) @@ -4694,7 +4694,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc HeapTuple SPI_modifytuple(Relation rel, HeapTuple row, int ncols, - int * colnum, Datum * values, const char * nulls) + int * colnum, const Datum * values, const char * nulls) diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 52f3b11301c..4e52542a3d1 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -702,7 +702,7 @@ SPI_execute_plan(SPIPlanPtr plan, const Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, const Datum *Values, const char *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -1105,7 +1105,7 @@ SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc) HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum, - Datum *Values, const char *Nulls) + const Datum *Values, const char *Nulls) { MemoryContext oldcxt; HeapTuple mtuple; @@ -1473,7 +1473,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + const Datum *Values, const char *Nulls, bool read_only, int cursorOptions) { Portal result; diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index f4985cb715d..fd79f86a98c 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -119,7 +119,7 @@ extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, bool read_only, long tcount); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, const Datum *Values, const char *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, const Datum *Values, const char *Nulls, @@ -155,7 +155,7 @@ extern CachedPlan *SPI_plan_get_cached_plan(SPIPlanPtr plan); extern HeapTuple SPI_copytuple(HeapTuple tuple); extern HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc); extern HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, - int *attnum, Datum *Values, const char *Nulls); + int *attnum, const Datum *Values, const char *Nulls); extern int SPI_fnumber(TupleDesc tupdesc, const char *fname); extern char *SPI_fname(TupleDesc tupdesc, int fnumber); extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber); @@ -176,7 +176,7 @@ extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + const Datum *Values, const char *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); From 78860fab26f1440ec4a8e31d039a88c66329196f Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Tue, 30 Jun 2026 22:29:43 +0300 Subject: [PATCH 059/481] doc: clarify MERGE PARTITIONS adjacency requirement The existing description says the ranges of merged range-partitions "must be adjacent" only under the heading "If the DEFAULT partition is not in the list of merged partitions". That could be misread as a restriction tied to the presence of a default partition. In fact, merging non-adjacent ranges is rejected regardless of whether the partitioned table has a default partition; spell that out explicitly. Also, this commit removes a small redundancy in the documentation sentence stating that "merged range-partitions" are "to be merged". Reported-by: Justin Pryzby Discussion: https://postgr.es/m/aj6BPoziSb-F8aJz%40pryzbyj2023 Reported-by: Pavel Borisov Backpatch-through: 19 --- doc/src/sgml/ref/alter_table.sgml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index 6dd518752c0..ff7071bef5b 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -1206,7 +1206,8 @@ WITH ( MODULUS numeric_literal, REM For range-partitioned tables, the ranges of merged partitions - must be adjacent in order to be merged. + must be adjacent; this applies even if the partitioned table + has no default partition. The partition bounds of merged partitions are combined to form the new partition bound for partition_name. From 0c15b715c6517af7b1046b45f868425930eaee6f Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 30 Jun 2026 17:21:23 -0400 Subject: [PATCH 060/481] Disallow set-returning functions within window OVER clauses. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We previously allowed this, but it leads to odd behaviors, basically because putting a SRF there is inconsistent with the principle that a window function doesn't change the number of rows in the query result. There doesn't seem to be a strong reason to try to make such cases behave consistently. Users should put their SRFs in lateral FROM clauses instead. This issue has been sitting on the back burner for multiple years now, partially because it didn't seem wise to back-patch such a change. Let's squeeze it into v19 before it's too late. Bug: #17502 Bug: #19535 Reported-by: Daniel Farkaš Reported-by: Qifan Liu Author: Tom Lane Reviewed-by: David Rowley Discussion: https://postgr.es/m/17502-281a7aaacfaa872a@postgresql.org Discussion: https://postgr.es/m/19535-376081d7cc07c86d@postgresql.org Backpatch-through: 19 --- src/backend/parser/parse_func.c | 3 --- src/test/regress/expected/tsrf.out | 25 +++++++++++++++---------- src/test/regress/sql/tsrf.sql | 10 +++++++--- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 9cdbaa542fe..a9b6be7203b 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -2700,9 +2700,6 @@ check_srf_call_placement(ParseState *pstate, Node *last_srf, int location) break; case EXPR_KIND_WINDOW_PARTITION: case EXPR_KIND_WINDOW_ORDER: - /* okay, these are effectively GROUP BY/ORDER BY */ - pstate->p_hasTargetSRFs = true; - break; case EXPR_KIND_WINDOW_FRAME_RANGE: case EXPR_KIND_WINDOW_FRAME_ROWS: case EXPR_KIND_WINDOW_FRAME_GROUPS: diff --git a/src/test/regress/expected/tsrf.out b/src/test/regress/expected/tsrf.out index c4f7b187f5b..005f1268f4b 100644 --- a/src/test/regress/expected/tsrf.out +++ b/src/test/regress/expected/tsrf.out @@ -267,7 +267,21 @@ ERROR: window function calls cannot contain set-returning function calls LINE 1: SELECT min(generate_series(1, 3)) OVER() FROM few; ^ HINT: You might be able to move the set-returning function into a LATERAL FROM item. --- SRFs are normally computed after window functions +--- ... nor in window definitions +SELECT sum(id) OVER (PARTITION BY generate_series(1, 3)) FROM few; +ERROR: set-returning functions are not allowed in window definitions +LINE 1: SELECT sum(id) OVER (PARTITION BY generate_series(1, 3)) FRO... + ^ +SELECT sum(id) OVER (ORDER BY generate_series(1, 3)) FROM few; +ERROR: set-returning functions are not allowed in window definitions +LINE 1: SELECT sum(id) OVER (ORDER BY generate_series(1, 3)) FROM fe... + ^ +SELECT sum(id) OVER (ROWS BETWEEN UNBOUNDED PRECEDING + AND generate_series(1, 3) FOLLOWING) FROM few; +ERROR: set-returning functions are not allowed in window definitions +LINE 2: AND generate_series(1, 3) FOLLOWING) FR... + ^ +-- SRFs are computed after window functions SELECT id,lag(id) OVER(), count(*) OVER(), generate_series(1,3) FROM few; id | lag | count | generate_series ----+-----+-------+----------------- @@ -282,15 +296,6 @@ SELECT id,lag(id) OVER(), count(*) OVER(), generate_series(1,3) FROM few; 3 | 2 | 3 | 3 (9 rows) --- unless referencing SRFs -SELECT SUM(count(*)) OVER(PARTITION BY generate_series(1,3) ORDER BY generate_series(1,3)), generate_series(1,3) g FROM few GROUP BY g; - sum | g ------+--- - 3 | 1 - 3 | 2 - 3 | 3 -(3 rows) - -- sorting + grouping SELECT few.dataa, count(*), min(id), max(id), generate_series(1,3) FROM few GROUP BY few.dataa ORDER BY 5, 1; dataa | count | min | max | generate_series diff --git a/src/test/regress/sql/tsrf.sql b/src/test/regress/sql/tsrf.sql index 7c22529a0db..8442ba9e743 100644 --- a/src/test/regress/sql/tsrf.sql +++ b/src/test/regress/sql/tsrf.sql @@ -82,10 +82,14 @@ SELECT sum((3 = ANY(SELECT lag(x) over(order by x) -- SRFs are not allowed in window function arguments, either SELECT min(generate_series(1, 3)) OVER() FROM few; --- SRFs are normally computed after window functions +--- ... nor in window definitions +SELECT sum(id) OVER (PARTITION BY generate_series(1, 3)) FROM few; +SELECT sum(id) OVER (ORDER BY generate_series(1, 3)) FROM few; +SELECT sum(id) OVER (ROWS BETWEEN UNBOUNDED PRECEDING + AND generate_series(1, 3) FOLLOWING) FROM few; + +-- SRFs are computed after window functions SELECT id,lag(id) OVER(), count(*) OVER(), generate_series(1,3) FROM few; --- unless referencing SRFs -SELECT SUM(count(*)) OVER(PARTITION BY generate_series(1,3) ORDER BY generate_series(1,3)), generate_series(1,3) g FROM few GROUP BY g; -- sorting + grouping SELECT few.dataa, count(*), min(id), max(id), generate_series(1,3) FROM few GROUP BY few.dataa ORDER BY 5, 1; From 1f34f12f0c312ae7f31d76fa8dc2d934c43f9b6c Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Wed, 1 Jul 2026 11:25:37 +1200 Subject: [PATCH 061/481] Remove radius from initdb authentication methods. Commit a1643d40b removed RADIUS authentication, but apparently overlooked initdb's list of accepted authentication methods. As a result, initdb still accepted radius for --auth, --auth-host, and --auth-local, allowing it to create a pg_hba.conf that the server could not load. Remove radius from initdb's local and host authentication method lists. Backpatch-through: 19 Author: Chao Li Discussion: https://postgr.es/m/983F946B-A7CE-4C93-B5F0-665616F72254%40gmail.com --- src/bin/initdb/initdb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 14cb79c26be..8fba896561b 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -94,7 +94,7 @@ typedef struct _stringlist } _stringlist; static const char *const auth_methods_host[] = { - "trust", "reject", "scram-sha-256", "md5", "password", "ident", "radius", + "trust", "reject", "scram-sha-256", "md5", "password", "ident", #ifdef ENABLE_GSS "gss", #endif @@ -116,7 +116,7 @@ static const char *const auth_methods_host[] = { NULL }; static const char *const auth_methods_local[] = { - "trust", "reject", "scram-sha-256", "md5", "password", "peer", "radius", + "trust", "reject", "scram-sha-256", "md5", "password", "peer", #ifdef USE_PAM "pam", #endif From b26e0f61451dfa0756d398129c79bbd46365b51e Mon Sep 17 00:00:00 2001 From: John Naylor Date: Wed, 1 Jul 2026 08:50:08 +0700 Subject: [PATCH 062/481] Document wal_compression=on Commit 4035cd5d4 added LZ4 compression for full-page writes in WAL, and retained "on" as a backward-compatible way to specify the builtin PGLZ method. Document this meaning of "on" and update postgresql.conf.sample to make the equivalence clear. Author: Christoph Berg Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/akJDHRtXwGLTppsQ@msg.df7cb.de Backpatch-through: 15 --- doc/src/sgml/config.sgml | 1 + src/backend/utils/misc/postgresql.conf.sample | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 569fc0e7dba..24f6a72f758 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -3671,6 +3671,7 @@ include_dir 'conf.d' was compiled with ) and zstd (if PostgreSQL was compiled with ). + The value on is a historical spelling of pglz. The default value is off. Only superusers and users with the appropriate SET privilege can change this setting. diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index ac38cddaaf9..86f2e16eba0 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -262,7 +262,7 @@ #wal_log_hints = off # also do full page writes of non-critical updates # (change requires restart) #wal_compression = off # enables compression of full-page writes; - # off, pglz, lz4, zstd, or on + # off, pglz (or "on"), lz4, or zstd #wal_init_zero = on # zero-fill new WAL files #wal_recycle = on # recycle WAL files #wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers From 9a2c07cbde9796049e4b37e3dde0b6f5253cb97b Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 1 Jul 2026 12:17:24 +0900 Subject: [PATCH 063/481] Avoid useless calls in pg_get_multixact_stats() MultiXactOffsetStorageSize() and GetMultiXactInfo() are called to gather the information reported by the function, but were wasteful for the case where a role does not have the privileges of pg_read_all_stats, where we return a set of NULLs. These calls are moved to the code path where their results are used. Author: Ranier Vilela Discussion: https://postgr.es/m/CAEudQAonQh7be=wOR-CJFW=bgMBz5wW_bv4t0OFxbgn-794JCQ@mail.gmail.com Backpatch-through: 19 --- src/backend/utils/adt/multixactfuncs.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/multixactfuncs.c b/src/backend/utils/adt/multixactfuncs.c index 9fe2ebafa73..d9aa58e821d 100644 --- a/src/backend/utils/adt/multixactfuncs.c +++ b/src/backend/utils/adt/multixactfuncs.c @@ -102,23 +102,12 @@ pg_get_multixact_stats(PG_FUNCTION_ARGS) TupleDesc tupdesc; Datum values[4]; bool nulls[4]; - uint64 members; - MultiXactId oldestMultiXactId; - uint32 multixacts; - MultiXactOffset oldestOffset; - MultiXactOffset nextOffset; - uint64 membersBytes; if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("return type must be a row type"))); - GetMultiXactInfo(&multixacts, &nextOffset, &oldestMultiXactId, &oldestOffset); - members = nextOffset - oldestOffset; - - membersBytes = MultiXactOffsetStorageSize(nextOffset, oldestOffset); - if (!has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS)) { /* @@ -129,6 +118,17 @@ pg_get_multixact_stats(PG_FUNCTION_ARGS) } else { + uint64 members; + MultiXactId oldestMultiXactId; + uint32 multixacts; + MultiXactOffset oldestOffset; + MultiXactOffset nextOffset; + uint64 membersBytes; + + GetMultiXactInfo(&multixacts, &nextOffset, &oldestMultiXactId, &oldestOffset); + members = nextOffset - oldestOffset; + membersBytes = MultiXactOffsetStorageSize(nextOffset, oldestOffset); + values[0] = UInt32GetDatum(multixacts); values[1] = Int64GetDatum(members); values[2] = Int64GetDatum(membersBytes); From 182f6944d3d0eeccf60e5885757f1677d4b988cc Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 29 Jun 2026 10:46:51 +0200 Subject: [PATCH 064/481] Use C11 alignas instead of pg_attribute_aligned Replace pg_attribute_aligned with C11 alignas, for consistency with current conventions. (These new uses were added by commit fbc57f2bc2e, which was developed concurrently with the switch from pg_attribute_aligned to C11 standard alignas, and it ended up being committed with the "old" style.) Reviewed-by: John Naylor Discussion: https://postgr.es/m/CANWCAZaKhE+RD5KKouUFoxx1EbUNrNhcduM1VQ=DkSDadNEFng@mail.gmail.com --- src/port/pg_crc32c_armv8.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/port/pg_crc32c_armv8.c b/src/port/pg_crc32c_armv8.c index 8cf838a510a..8fad2f83c24 100644 --- a/src/port/pg_crc32c_armv8.c +++ b/src/port/pg_crc32c_armv8.c @@ -166,7 +166,7 @@ pg_comp_crc32c_pmull(pg_crc32c crc, const void *data, size_t len) uint64x2_t k; { - static const uint64_t pg_attribute_aligned(16) k_[] = {0x740eef02, 0x9e4addf8}; + static const alignas(16) uint64_t k_[] = {0x740eef02, 0x9e4addf8}; k = vld1q_u64(k_); } @@ -192,14 +192,14 @@ pg_comp_crc32c_pmull(pg_crc32c crc, const void *data, size_t len) /* Reduce x0 ... x3 to just x0. */ { - static const uint64_t pg_attribute_aligned(16) k_[] = {0xf20c0dfe, 0x493c7d27}; + static const alignas(16) uint64_t k_[] = {0xf20c0dfe, 0x493c7d27}; k = vld1q_u64(k_); } y0 = clmul_lo_e(x0, k, x1), x0 = clmul_hi_e(x0, k, y0); y2 = clmul_lo_e(x2, k, x3), x2 = clmul_hi_e(x2, k, y2); { - static const uint64_t pg_attribute_aligned(16) k_[] = {0x3da6d0cb, 0xba4fc28e}; + static const alignas(16) uint64_t k_[] = {0x3da6d0cb, 0xba4fc28e}; k = vld1q_u64(k_); } From d4e2280b7e4872b603592ae521320b9d1c4e6b24 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 1 Jul 2026 09:40:16 +0200 Subject: [PATCH 065/481] Don't cast off_t to 32-bit type for output, bug fix off_t is most likely a 64-bit integer, so casting it to a 32-bit type for output could lose data. There are more issues like this in the tree, but this is an instance where this could actually happen in practice, since base backups are routinely larger than 4 GB. So this is separated out as a bug fix. Reviewed-by: Heikki Linnakangas Discussion: https://www.postgresql.org/message-id/flat/20ce62fa-47fc-457b-b504-12f3c1651726%40eisentraut.org --- src/backend/backup/basebackup_server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/backup/basebackup_server.c b/src/backend/backup/basebackup_server.c index 0d44a148f01..3d44bf71d19 100644 --- a/src/backend/backup/basebackup_server.c +++ b/src/backend/backup/basebackup_server.c @@ -176,9 +176,9 @@ bbsink_server_archive_contents(bbsink *sink, size_t len) /* short write: complain appropriately */ ereport(ERROR, (errcode(ERRCODE_DISK_FULL), - errmsg("could not write file \"%s\": wrote only %d of %zu bytes at offset %u", + errmsg("could not write file \"%s\": wrote only %d of %zu bytes at offset %lld", FilePathName(mysink->file), - nbytes, len, (unsigned) mysink->filepos), + nbytes, len, (long long) mysink->filepos), errhint("Check free disk space."))); } @@ -269,9 +269,9 @@ bbsink_server_manifest_contents(bbsink *sink, size_t len) /* short write: complain appropriately */ ereport(ERROR, (errcode(ERRCODE_DISK_FULL), - errmsg("could not write file \"%s\": wrote only %d of %zu bytes at offset %u", + errmsg("could not write file \"%s\": wrote only %d of %zu bytes at offset %lld", FilePathName(mysink->file), - nbytes, len, (unsigned) mysink->filepos), + nbytes, len, (long long) mysink->filepos), errhint("Check free disk space."))); } From 36b1a1e826eaa144d5661f1f047cc43d8921cbae Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 1 Jul 2026 10:12:33 +0200 Subject: [PATCH 066/481] Split dry-run messages into primary and detail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixup for commit c05dee19112. It fits better with the style and APIs to print separate primary and a detail messages instead of one multiline message. Reviewed-by: Euler Taveira Reviewed-by: Peter Smith Reviewed-by: Álvaro Herrera Discussion: https://postgr.es/m/CAHut+PsvQJQnQO0KT0S2oegenkvJ8FUuY-QS5syyqmT24R2xFQ@mail.gmail.com --- src/bin/pg_archivecleanup/pg_archivecleanup.c | 6 ++++-- src/bin/pg_basebackup/pg_createsubscriber.c | 6 ++++-- src/bin/pg_combinebackup/pg_combinebackup.c | 6 ++++-- src/bin/pg_rewind/pg_rewind.c | 6 ++++-- src/bin/scripts/vacuumdb.c | 6 ++++-- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/bin/pg_archivecleanup/pg_archivecleanup.c b/src/bin/pg_archivecleanup/pg_archivecleanup.c index ab686b4748c..3492dab64d7 100644 --- a/src/bin/pg_archivecleanup/pg_archivecleanup.c +++ b/src/bin/pg_archivecleanup/pg_archivecleanup.c @@ -376,8 +376,10 @@ main(int argc, char **argv) } if (dryrun) - pg_log_info("Executing in dry-run mode.\n" - "No files will be removed."); + { + pg_log_info("executing in dry-run mode"); + pg_log_info_detail("No files will be removed."); + } /* * Check archive exists and other initialization if required. diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c index 4d705778454..0a9b11184f5 100644 --- a/src/bin/pg_basebackup/pg_createsubscriber.c +++ b/src/bin/pg_basebackup/pg_createsubscriber.c @@ -2514,8 +2514,10 @@ main(int argc, char **argv) } if (dry_run) - pg_log_info("Executing in dry-run mode.\n" - "The target directory will not be modified."); + { + pg_log_info("executing in dry-run mode"); + pg_log_info_detail("The target directory will not be modified."); + } pg_log_info("validating publisher connection string"); pub_base_conninfo = get_base_conninfo(opt.pub_conninfo_str, diff --git a/src/bin/pg_combinebackup/pg_combinebackup.c b/src/bin/pg_combinebackup/pg_combinebackup.c index d13bf63eb1e..767b8b9e499 100644 --- a/src/bin/pg_combinebackup/pg_combinebackup.c +++ b/src/bin/pg_combinebackup/pg_combinebackup.c @@ -243,8 +243,10 @@ main(int argc, char *argv[]) opt.manifest_checksums = CHECKSUM_TYPE_NONE; if (opt.dry_run) - pg_log_info("Executing in dry-run mode.\n" - "The target directory will not be modified."); + { + pg_log_info("executing in dry-run mode"); + pg_log_info_detail("The target directory will not be modified."); + } /* Check that the platform supports the requested copy method. */ if (opt.copy_method == COPY_METHOD_CLONE) diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c index 9d745d4b25b..2e86fd158d0 100644 --- a/src/bin/pg_rewind/pg_rewind.c +++ b/src/bin/pg_rewind/pg_rewind.c @@ -302,8 +302,10 @@ main(int argc, char **argv) /* Ok, we have all the options and we're ready to start. */ if (dry_run) - pg_log_info("Executing in dry-run mode.\n" - "The target directory will not be modified."); + { + pg_log_info("executing in dry-run mode"); + pg_log_info_detail("The target directory will not be modified."); + } /* First, connect to remote server. */ if (connstr_source) diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c index ccc7f88a291..f8158ca6a78 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -308,8 +308,10 @@ main(int argc, char *argv[]) "missing-stats-only", "analyze-only", "analyze-in-stages"); if (vacopts.dry_run && !vacopts.quiet) - pg_log_info("Executing in dry-run mode.\n" - "No commands will be sent to the server."); + { + pg_log_info("executing in dry-run mode"); + pg_log_info_detail("No commands will be sent to the server."); + } ret = vacuuming_main(&cparams, dbname, maintenance_db, &vacopts, &objects, tbl_count, From e57a865dc7003f75d3a2d080603c95dd469b89a5 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 1 Jul 2026 20:57:28 +0900 Subject: [PATCH 067/481] Warn on password auth with MD5-encrypted passwords Commit bc60ee860 added a connection warning after successful MD5 authentication, but only for the md5 authentication method. A role with an MD5-encrypted password can also authenticate via the password method, which left that path without the same deprecation warning. Emit the MD5 deprecation connection warning after successful password authentication as well, when the stored password is MD5-encrypted. Backpatch to v19, where the MD5 connection warning was introduced. Author: Fujii Masao Reviewed-by: Chao Li Reviewed-by: Japin Li Discussion: https://postgr.es/m/CAHGQGwGkWfn5rtHzvdRbVk+PCefQU3gun3hc7QnaMXHFa5Bu3w@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/config.sgml | 3 ++- src/backend/libpq/auth.c | 33 +++++++++++++++++++++++ src/backend/libpq/crypt.c | 22 --------------- src/test/authentication/t/001_password.pl | 10 +++++++ 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 24f6a72f758..45827687b9c 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1206,7 +1206,8 @@ include_dir 'conf.d' Controls whether a WARNING about MD5 password - deprecation is produced upon successful MD5 password authentication or + deprecation is produced upon successful authentication using an + MD5-encrypted password or when a CREATE ROLE or ALTER ROLE statement sets an MD5-encrypted password. The default value is on. diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 2af5615e54a..12bf153d66f 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -48,6 +48,8 @@ static void auth_failed(Port *port, int elevel, int status, const char *logdetail); static char *recv_password_packet(Port *port); +static bool md5_password_warning_enabled(void); +static void queue_md5_password_warning(void); /*---------------------------------------------------------------- @@ -795,6 +797,7 @@ CheckPasswordAuth(Port *port, const char **logdetail) char *passwd; int result; char *shadow_pass; + bool md5_password = false; sendAuthRequest(port, AUTH_REQ_PASSWORD, NULL, 0); @@ -807,6 +810,7 @@ CheckPasswordAuth(Port *port, const char **logdetail) { result = plain_crypt_verify(port->user_name, shadow_pass, passwd, logdetail); + md5_password = (get_password_type(shadow_pass) == PASSWORD_TYPE_MD5); } else result = STATUS_ERROR; @@ -816,7 +820,11 @@ CheckPasswordAuth(Port *port, const char **logdetail) pfree(passwd); if (result == STATUS_OK) + { + if (md5_password) + queue_md5_password_warning(); set_authn_id(port, port->user_name); + } return result; } @@ -913,9 +921,34 @@ CheckMD5Auth(Port *port, char *shadow_pass, const char **logdetail) pfree(passwd); + if (result == STATUS_OK) + queue_md5_password_warning(); + return result; } +static bool +md5_password_warning_enabled(void) +{ + return md5_password_warnings; +} + +static void +queue_md5_password_warning(void) +{ + MemoryContext oldcontext; + char *warning; + char *detail; + + oldcontext = MemoryContextSwitchTo(TopMemoryContext); + + warning = pstrdup(_("authenticated with an MD5-encrypted password")); + detail = pstrdup(_("MD5 password support is deprecated and will be removed in a future release of PostgreSQL.")); + StoreConnectionWarning(warning, detail, md5_password_warning_enabled); + + MemoryContextSwitchTo(oldcontext); +} + /*---------------------------------------------------------------- * GSSAPI authentication system diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index 28857773d9c..e8e840db6b9 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -32,8 +32,6 @@ int password_expiration_warning_threshold = 604800; /* Enables deprecation warnings for MD5 passwords. */ bool md5_password_warnings = true; -static bool md5_password_warning_enabled(void); - /* * Fetch stored password for a user, for authentication. * @@ -297,21 +295,7 @@ md5_crypt_verify(const char *role, const char *shadow_pass, if (strlen(client_pass) == strlen(crypt_pwd) && timingsafe_bcmp(client_pass, crypt_pwd, strlen(crypt_pwd)) == 0) - { - MemoryContext oldcontext; - char *warning; - char *detail; - retval = STATUS_OK; - - oldcontext = MemoryContextSwitchTo(TopMemoryContext); - - warning = pstrdup(_("authenticated with an MD5-encrypted password")); - detail = pstrdup(_("MD5 password support is deprecated and will be removed in a future release of PostgreSQL.")); - StoreConnectionWarning(warning, detail, md5_password_warning_enabled); - - MemoryContextSwitchTo(oldcontext); - } else { *logdetail = psprintf(_("Password does not match for user \"%s\"."), @@ -322,12 +306,6 @@ md5_crypt_verify(const char *role, const char *shadow_pass, return retval; } -static bool -md5_password_warning_enabled(void) -{ - return md5_password_warnings; -} - /* * Check given password for given user, and return STATUS_OK or STATUS_ERROR. * diff --git a/src/test/authentication/t/001_password.pl b/src/test/authentication/t/001_password.pl index fca78fc4d6a..ac67935c258 100644 --- a/src/test/authentication/t/001_password.pl +++ b/src/test/authentication/t/001_password.pl @@ -385,9 +385,19 @@ sub test_conn { skip "MD5 not supported" unless $md5_works; test_conn($node, 'user=md5_role', 'password', 0, + expected_stderr => qr/authenticated with an MD5-encrypted password/, log_like => [qr/connection authenticated: identity="md5_role" method=password/] ); + + $node->connect_ok( + 'user=md5_role_no_warnings', + 'password with warnings disabled', + sql => 'SHOW md5_password_warnings', + expected_stdout => qr/^off$/, + log_like => [ + qr/connection authenticated: identity="md5_role_no_warnings" method=password/ + ]); } # require_auth succeeds here with a plaintext password. From b70000837888917690782197c098942ddb529753 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 1 Jul 2026 23:03:08 +0900 Subject: [PATCH 068/481] Clear base backup progress on backup failure Previously, if a base backup failed after it had started streaming files, pg_stat_progress_basebackup could continue to show a stale progress entry even though the backup was no longer running. This could be observed when the client kept the replication connection open after the error. It is normally not observable when using pg_basebackup, because the client disconnects after the error. The problem was that progress reporting was cleared only after successful completion. This commit moves the progress reporting cleanup into the progress sink's cleanup callback so that it is cleared after both successful and failed backups. Backpatch to v15. v14 has the same issue, but the fix does not apply cleanly because it lacks the base backup sink infrastructure. Since the bug does not affect the backup itself and is normally not observable when using pg_basebackup, skip the v14 backpatch. Author: Chao Li Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/EA1A6CD2-EFA6-462B-9A02-03003555AB4A@gmail.com Backpatch-through: 15 --- src/backend/backup/basebackup.c | 2 -- src/backend/backup/basebackup_progress.c | 22 ++++++++++++---------- src/include/backup/basebackup_sink.h | 1 - 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c index 9c79dadaacc..5214e7b99c7 100644 --- a/src/backend/backup/basebackup.c +++ b/src/backend/backup/basebackup.c @@ -676,8 +676,6 @@ perform_base_backup(basebackup_options *opt, bbsink *sink, /* clean up the resource owner we created */ ReleaseAuxProcessResources(true); - - basebackup_progress_done(); } /* diff --git a/src/backend/backup/basebackup_progress.c b/src/backend/backup/basebackup_progress.c index fb9e57f04df..f74459181d0 100644 --- a/src/backend/backup/basebackup_progress.c +++ b/src/backend/backup/basebackup_progress.c @@ -38,6 +38,7 @@ static void bbsink_progress_begin_backup(bbsink *sink); static void bbsink_progress_archive_contents(bbsink *sink, size_t len); static void bbsink_progress_end_archive(bbsink *sink); +static void bbsink_progress_cleanup(bbsink *sink); static const bbsink_ops bbsink_progress_ops = { .begin_backup = bbsink_progress_begin_backup, @@ -48,7 +49,7 @@ static const bbsink_ops bbsink_progress_ops = { .manifest_contents = bbsink_forward_manifest_contents, .end_manifest = bbsink_forward_end_manifest, .end_backup = bbsink_forward_end_backup, - .cleanup = bbsink_forward_cleanup + .cleanup = bbsink_progress_cleanup }; /* @@ -184,6 +185,16 @@ bbsink_progress_archive_contents(bbsink *sink, size_t len) pgstat_progress_update_multi_param(nparam, index, val); } +/* + * Clean up progress reporting. + */ +static void +bbsink_progress_cleanup(bbsink *sink) +{ + pgstat_progress_end_command(); + bbsink_forward_cleanup(sink); +} + /* * Advertise that we are waiting for the start-of-backup checkpoint. */ @@ -236,12 +247,3 @@ basebackup_progress_transfer_wal(void) pgstat_progress_update_param(PROGRESS_BASEBACKUP_PHASE, PROGRESS_BASEBACKUP_PHASE_TRANSFER_WAL); } - -/* - * Advertise that we are no longer performing a backup. - */ -void -basebackup_progress_done(void) -{ - pgstat_progress_end_command(); -} diff --git a/src/include/backup/basebackup_sink.h b/src/include/backup/basebackup_sink.h index bbf4de0cbdc..96fa2c4eaba 100644 --- a/src/include/backup/basebackup_sink.h +++ b/src/include/backup/basebackup_sink.h @@ -297,6 +297,5 @@ extern void basebackup_progress_wait_checkpoint(void); extern void basebackup_progress_estimate_backup_size(void); extern void basebackup_progress_wait_wal_archive(bbsink_state *); extern void basebackup_progress_transfer_wal(void); -extern void basebackup_progress_done(void); #endif From ba7a65c5c5aaa71df23def8280fa70db7f11fd3b Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 1 Jul 2026 10:47:53 -0500 Subject: [PATCH 069/481] doc: Fix pg_stat_autovacuum_scores descriptions. The descriptions of the component scores state that values greater than or equal to the corresponding weight parameter mean autovacuum will process the table. However, since the code that determines whether to vacuum or analyze a table actually checks whether the threshold is exceeded, it's more accurate to say "greater than" there. Author: Chao Li Reviewed-by: Sami Imseih Discussion: https://postgr.es/m/E3ABDC6B-80CA-4C37-BA0B-A519D49F4C66%40gmail.com Backpatch-through: 19 --- doc/src/sgml/monitoring.sgml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 6dcf05eb702..38836f2c90f 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -4594,7 +4594,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage xid_score double precision - Transaction ID age component score. Scores greater than or equal to + Transaction ID age component score. Scores greater than indicate that autovacuum would vacuum the table for transaction ID wraparound prevention. @@ -4606,7 +4606,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage mxid_score double precision - Multixact ID age component score. Scores greater than or equal to + Multixact ID age component score. Scores greater than indicate that autovacuum would vacuum the table for multixact ID wraparound prevention. @@ -4618,7 +4618,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage vacuum_score double precision - Vacuum component score. Scores greater than or equal to + Vacuum component score. Scores greater than indicate that autovacuum would vacuum the table (unless autovacuum is disabled). @@ -4629,7 +4629,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage vacuum_insert_score double precision - Vacuum insert component score. Scores greater than or equal to + Vacuum insert component score. Scores greater than indicate that autovacuum would vacuum the table (unless autovacuum is disabled). @@ -4640,7 +4640,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage analyze_score double precision - Analyze component score. Scores greater than or equal to + Analyze component score. Scores greater than indicate that autovacuum would analyze the table (unless autovacuum is disabled). From a47005f0b11df3e456c755c73b6f41fd26b27cad Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 1 Jul 2026 13:27:22 -0400 Subject: [PATCH 070/481] btree_gist: fix NaN handling in float4/float8 opclasses. The float4 and float8 btree_gist opclasses compared keys with raw C operators (==, <, >). IEEE 754 makes every comparison involving NaN false, so GiST disagreed with the regular float comparison operators and with the btree opclass, which uses float[4|8]_cmp_internal() (so that all NaNs are equal and NaN sorts after every non-NaN value). In addition, the penalty and distance functions were not careful about NaNs, and the penalty functions could also misbehave for IEEE infinities. Wrong answers from the penalty functions would probably do no more than make the index non-optimal, but the distance mistakes were visible from SQL. To fix, make the comparison functions rely on the same NaN-aware comparison functions the core code uses, and rewrite the penalty and distance functions to follow the rules that NaNs are equal but maximally far away from non-NaNs. The penalty_num() code was formerly shared between integral and float cases, but I chose to make two copies so that the integral cases are not saddled with the extra logic for NaNs and infinities/overflows. I also rewrote it as static inline functions instead of an unreadable and uncommented macro. The float penalty functions were previously unreached by the regression tests, so add new test cases to exercise them. There's no on-disk format change, but users who have NaN entries in a btree_gist index would be well advised to reindex it. Bug: #19501 Bug: #19524 Reported-by: Man Zeng Reported-by: Yuelin Wang <3020001251@tju.edu.cn> Author: Bill Kim Co-authored-by: Tom Lane Discussion: https://postgr.es/m/19501-3bff3bbc97f1e7c9@postgresql.org Discussion: https://postgr.es/m/19524-9559d302c8455664@postgresql.org Discussion: https://postgr.es/m/CAMQXxcgbtD2LXfX0tpgvOizxP-XxrCHV2ZDy4By_TZnJMsxXWQ@mail.gmail.com Backpatch-through: 14 --- contrib/btree_gist/btree_float4.c | 59 ++++++++--- contrib/btree_gist/btree_float8.c | 51 ++++++--- contrib/btree_gist/btree_utils_num.h | 131 +++++++++++++++++++++--- contrib/btree_gist/data/float4.data | 3 + contrib/btree_gist/data/float8.data | 3 + contrib/btree_gist/expected/float4.out | 51 +++++++-- contrib/btree_gist/expected/float8.out | 51 +++++++-- contrib/btree_gist/expected/numeric.out | 48 ++++----- contrib/btree_gist/sql/float4.sql | 17 +++ contrib/btree_gist/sql/float8.sql | 17 +++ 10 files changed, 345 insertions(+), 86 deletions(-) diff --git a/contrib/btree_gist/btree_float4.c b/contrib/btree_gist/btree_float4.c index c076918fd48..04868e81a0e 100644 --- a/contrib/btree_gist/btree_float4.c +++ b/contrib/btree_gist/btree_float4.c @@ -26,30 +26,36 @@ PG_FUNCTION_INFO_V1(gbt_float4_penalty); PG_FUNCTION_INFO_V1(gbt_float4_same); PG_FUNCTION_INFO_V1(gbt_float4_sortsupport); +/* + * Use the NaN-aware comparators from utils/float.h, so that our results + * will agree with standard btree indexes. Note that penalty and distance + * functions below must also cope with NaNs, in particular with the policy + * that all NaNs are equal. + */ static bool gbt_float4gt(const void *a, const void *b, FmgrInfo *flinfo) { - return (*((const float4 *) a) > *((const float4 *) b)); + return float4_gt(*((const float4 *) a), *((const float4 *) b)); } static bool gbt_float4ge(const void *a, const void *b, FmgrInfo *flinfo) { - return (*((const float4 *) a) >= *((const float4 *) b)); + return float4_ge(*((const float4 *) a), *((const float4 *) b)); } static bool gbt_float4eq(const void *a, const void *b, FmgrInfo *flinfo) { - return (*((const float4 *) a) == *((const float4 *) b)); + return float4_eq(*((const float4 *) a), *((const float4 *) b)); } static bool gbt_float4le(const void *a, const void *b, FmgrInfo *flinfo) { - return (*((const float4 *) a) <= *((const float4 *) b)); + return float4_le(*((const float4 *) a), *((const float4 *) b)); } static bool gbt_float4lt(const void *a, const void *b, FmgrInfo *flinfo) { - return (*((const float4 *) a) < *((const float4 *) b)); + return float4_lt(*((const float4 *) a), *((const float4 *) b)); } static int @@ -57,22 +63,33 @@ gbt_float4key_cmp(const void *a, const void *b, FmgrInfo *flinfo) { float4KEY *ia = (float4KEY *) (((const Nsrt *) a)->t); float4KEY *ib = (float4KEY *) (((const Nsrt *) b)->t); + int res; - if (ia->lower == ib->lower) - { - if (ia->upper == ib->upper) - return 0; - - return (ia->upper > ib->upper) ? 1 : -1; - } - - return (ia->lower > ib->lower) ? 1 : -1; + res = float4_cmp_internal(ia->lower, ib->lower); + if (res != 0) + return res; + return float4_cmp_internal(ia->upper, ib->upper); } static float8 gbt_float4_dist(const void *a, const void *b, FmgrInfo *flinfo) { - return GET_FLOAT_DISTANCE(float4, a, b); + float8 arg1 = *(const float4 *) a; + float8 arg2 = *(const float4 *) b; + float8 r; + + r = arg1 - arg2; + /* needn't consider isinf case here, must be due to input infinity */ + if (unlikely(isnan(r))) + { + if (isnan(arg1) && isnan(arg2)) + r = 0.0; /* treat NaNs as equal */ + else if (isnan(arg1) || isnan(arg2)) + r = get_float8_infinity(); /* max dist for NaN vs non-NaN */ + else + r = 0.0; /* must be Inf - Inf case */ + } + return fabs(r); } @@ -102,7 +119,15 @@ float4_dist(PG_FUNCTION_ARGS) r = a - b; if (unlikely(isinf(r)) && !isinf(a) && !isinf(b)) float_overflow_error(); - + if (unlikely(isnan(r))) + { + if (isnan(a) && isnan(b)) + r = 0.0; /* treat NaNs as equal */ + else if (isnan(a) || isnan(b)) + r = get_float4_infinity(); /* max dist for NaN vs non-NaN */ + else + r = 0.0; /* must be Inf - Inf case */ + } PG_RETURN_FLOAT4(fabsf(r)); } @@ -186,7 +211,7 @@ gbt_float4_penalty(PG_FUNCTION_ARGS) float4KEY *newentry = (float4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key); float *result = (float *) PG_GETARG_POINTER(2); - penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper); + float_penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper); PG_RETURN_POINTER(result); } diff --git a/contrib/btree_gist/btree_float8.c b/contrib/btree_gist/btree_float8.c index d7386e885a2..2771e8e0f7e 100644 --- a/contrib/btree_gist/btree_float8.c +++ b/contrib/btree_gist/btree_float8.c @@ -27,30 +27,36 @@ PG_FUNCTION_INFO_V1(gbt_float8_same); PG_FUNCTION_INFO_V1(gbt_float8_sortsupport); +/* + * Use the NaN-aware comparators from utils/float.h, so that our results + * will agree with standard btree indexes. Note that penalty and distance + * functions below must also cope with NaNs, in particular with the policy + * that all NaNs are equal. + */ static bool gbt_float8gt(const void *a, const void *b, FmgrInfo *flinfo) { - return (*((const float8 *) a) > *((const float8 *) b)); + return float8_gt(*((const float8 *) a), *((const float8 *) b)); } static bool gbt_float8ge(const void *a, const void *b, FmgrInfo *flinfo) { - return (*((const float8 *) a) >= *((const float8 *) b)); + return float8_ge(*((const float8 *) a), *((const float8 *) b)); } static bool gbt_float8eq(const void *a, const void *b, FmgrInfo *flinfo) { - return (*((const float8 *) a) == *((const float8 *) b)); + return float8_eq(*((const float8 *) a), *((const float8 *) b)); } static bool gbt_float8le(const void *a, const void *b, FmgrInfo *flinfo) { - return (*((const float8 *) a) <= *((const float8 *) b)); + return float8_le(*((const float8 *) a), *((const float8 *) b)); } static bool gbt_float8lt(const void *a, const void *b, FmgrInfo *flinfo) { - return (*((const float8 *) a) < *((const float8 *) b)); + return float8_lt(*((const float8 *) a), *((const float8 *) b)); } static int @@ -58,16 +64,12 @@ gbt_float8key_cmp(const void *a, const void *b, FmgrInfo *flinfo) { float8KEY *ia = (float8KEY *) (((const Nsrt *) a)->t); float8KEY *ib = (float8KEY *) (((const Nsrt *) b)->t); + int res; - if (ia->lower == ib->lower) - { - if (ia->upper == ib->upper) - return 0; - - return (ia->upper > ib->upper) ? 1 : -1; - } - - return (ia->lower > ib->lower) ? 1 : -1; + res = float8_cmp_internal(ia->lower, ib->lower); + if (res != 0) + return res; + return float8_cmp_internal(ia->upper, ib->upper); } static float8 @@ -80,6 +82,15 @@ gbt_float8_dist(const void *a, const void *b, FmgrInfo *flinfo) r = arg1 - arg2; if (unlikely(isinf(r)) && !isinf(arg1) && !isinf(arg2)) float_overflow_error(); + if (unlikely(isnan(r))) + { + if (isnan(arg1) && isnan(arg2)) + r = 0.0; /* treat NaNs as equal */ + else if (isnan(arg1) || isnan(arg2)) + r = get_float8_infinity(); /* max dist for NaN vs non-NaN */ + else + r = 0.0; /* must be Inf - Inf case */ + } return fabs(r); } @@ -110,7 +121,15 @@ float8_dist(PG_FUNCTION_ARGS) r = a - b; if (unlikely(isinf(r)) && !isinf(a) && !isinf(b)) float_overflow_error(); - + if (unlikely(isnan(r))) + { + if (isnan(a) && isnan(b)) + r = 0.0; /* treat NaNs as equal */ + else if (isnan(a) || isnan(b)) + r = get_float8_infinity(); /* max dist for NaN vs non-NaN */ + else + r = 0.0; /* must be Inf - Inf case */ + } PG_RETURN_FLOAT8(fabs(r)); } @@ -194,7 +213,7 @@ gbt_float8_penalty(PG_FUNCTION_ARGS) float8KEY *newentry = (float8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key); float *result = (float *) PG_GETARG_POINTER(2); - penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper); + float_penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper); PG_RETURN_POINTER(result); } diff --git a/contrib/btree_gist/btree_utils_num.h b/contrib/btree_gist/btree_utils_num.h index 53e477d8b1e..d42d1e61585 100644 --- a/contrib/btree_gist/btree_utils_num.h +++ b/contrib/btree_gist/btree_utils_num.h @@ -9,6 +9,7 @@ #include "access/gist.h" #include "btree_gist.h" +#include "utils/float.h" typedef char GBT_NUMKEY; @@ -58,21 +59,124 @@ typedef struct /* - * Note: The factor 0.49 in following macro avoids floating point overflows + * Compute penalty for expanding a range olower..oupper to nlower..nupper. + * + * Although the arguments are declared double, they must not be NaN nor + * large enough to risk overflows in the calculations herein. We only + * actually use this for integral data types, so there's no hazard. + */ +static inline float +penalty_num_impl(double olower, double oupper, + double nlower, double nupper, + int natts) +{ + float result = 0.0F; + double tmp = 0.0; + + /* Add penalty for expanding upper bound */ + if (nupper > oupper) + tmp += nupper - oupper; + /* Add penalty for expanding lower bound */ + if (olower > nlower) + tmp += olower - nlower; + if (tmp > 0.0) + { + /* Ensure result is non-zero, even if next step underflows to zero */ + result += FLT_MIN; + /* Scale penalty to 0 .. 1 */ + result += (float) (tmp / (tmp + (oupper - olower))); + /* Scale to 0 .. FLT_MAX / (natts + 1) */ + result *= FLT_MAX / (natts + 1); + } + return result; +} + +/* + * As above, but the input values are float4 or float8, so we must cope + * with NaNs, infinities, and overflows. + */ +static inline float +float_penalty_num_impl(double olower, double oupper, + double nlower, double nupper, + int natts) +{ + float result = 0.0F; + double tmp = 0.0; + + /* Add penalty for expanding upper bound */ + if (float8_gt(nupper, oupper)) + { + double delta = nupper - oupper; + + if (unlikely(isnan(delta))) + { + /* oupper couldn't be NaN here, see float8_gt */ + if (isnan(nupper)) + delta = FLT_MAX; /* max penalty for NaN vs non-NaN */ + else + delta = 0.0; /* must be Inf - Inf case */ + } + else if (delta > FLT_MAX) + delta = FLT_MAX; /* clamp to FLT_MAX, esp for infinity */ + tmp += delta; + } + /* Add penalty for expanding lower bound */ + if (float8_gt(olower, nlower)) + { + double delta = olower - nlower; + + if (unlikely(isnan(delta))) + { + /* nlower couldn't be NaN here, see float8_gt */ + if (isnan(olower)) + delta = FLT_MAX; /* max penalty for NaN vs non-NaN */ + else + delta = 0.0; /* must be Inf - Inf case */ + } + else if (delta > FLT_MAX) + delta = FLT_MAX; /* clamp to FLT_MAX, esp for infinity */ + tmp += delta; + } + if (tmp > 0.0) + { + double delta = oupper - olower; + + /* Clamp delta (the original range size) to 0 .. FLT_MAX */ + if (unlikely(isnan(delta))) + { + /* here, we must deal with olower possibly being NaN */ + if (isnan(oupper) && isnan(olower)) + delta = 0.0; /* treat NaNs as equal */ + else if (isnan(oupper) || isnan(olower)) + delta = FLT_MAX; /* max penalty for NaN vs non-NaN */ + else + delta = 0.0; /* must be Inf - Inf case */ + } + else if (delta > FLT_MAX) + delta = FLT_MAX; /* clamp to FLT_MAX, esp for infinity */ + /* Ensure result is non-zero, even if next step underflows to zero */ + result += FLT_MIN; + /* Scale penalty to 0 .. 1 */ + result += (float) (tmp / (tmp + delta)); + /* Scale to 0 .. FLT_MAX / (natts + 1) */ + result *= FLT_MAX / (natts + 1); + } + return result; +} + +/* + * These macros provide backwards-compatible notation for callers. */ #define penalty_num(result,olower,oupper,nlower,nupper) do { \ - double tmp = 0.0F; \ - (*(result)) = 0.0F; \ - if ( (nupper) > (oupper) ) \ - tmp += ( ((double)nupper)*0.49F - ((double)oupper)*0.49F ); \ - if ( (olower) > (nlower) ) \ - tmp += ( ((double)olower)*0.49F - ((double)nlower)*0.49F ); \ - if (tmp > 0.0F) \ - { \ - (*(result)) += FLT_MIN; \ - (*(result)) += (float) ( ((double)(tmp)) / ( (double)(tmp) + ( ((double)(oupper))*0.49F - ((double)(olower))*0.49F ) ) ); \ - (*(result)) *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1)); \ - } \ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); \ + *(result) = penalty_num_impl(olower, oupper, nlower, nupper, \ + entry->rel->rd_att->natts); \ +} while (0) + +#define float_penalty_num(result,olower,oupper,nlower,nupper) do { \ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); \ + *(result) = float_penalty_num_impl(olower, oupper, nlower, nupper, \ + entry->rel->rd_att->natts); \ } while (0) @@ -86,6 +190,7 @@ typedef struct (ivp)->day * (24.0 * SECS_PER_HOUR) + \ (ivp)->month * (30.0 * SECS_PER_DAY)) +/* This macro is not safe to use with actual float inputs, only integers */ #define GET_FLOAT_DISTANCE(t, arg1, arg2) fabs( ((float8) *((const t *) (arg1))) - ((float8) *((const t *) (arg2))) ) diff --git a/contrib/btree_gist/data/float4.data b/contrib/btree_gist/data/float4.data index 947955e4680..af7d09f00d6 100644 --- a/contrib/btree_gist/data/float4.data +++ b/contrib/btree_gist/data/float4.data @@ -298,6 +298,9 @@ \N 2972.381398 220.199877 +Infinity +-Infinity +NaN 3542.561032 -2168.024176 -3305.714558 diff --git a/contrib/btree_gist/data/float8.data b/contrib/btree_gist/data/float8.data index ff21226e066..b60e22f957f 100644 --- a/contrib/btree_gist/data/float8.data +++ b/contrib/btree_gist/data/float8.data @@ -298,6 +298,9 @@ 27770.539968 13275.355549 -4267.695804 +Infinity +-Infinity +NaN \N \N 38915.525185 diff --git a/contrib/btree_gist/expected/float4.out b/contrib/btree_gist/expected/float4.out index dfe732049e6..a917b79a63b 100644 --- a/contrib/btree_gist/expected/float4.out +++ b/contrib/btree_gist/expected/float4.out @@ -5,13 +5,13 @@ SET enable_seqscan=on; SELECT count(*) FROM float4tmp WHERE a < -179.0; count ------- - 244 + 245 (1 row) SELECT count(*) FROM float4tmp WHERE a <= -179.0; count ------- - 245 + 246 (1 row) SELECT count(*) FROM float4tmp WHERE a = -179.0; @@ -23,13 +23,13 @@ SELECT count(*) FROM float4tmp WHERE a = -179.0; SELECT count(*) FROM float4tmp WHERE a >= -179.0; count ------- - 303 + 305 (1 row) SELECT count(*) FROM float4tmp WHERE a > -179.0; count ------- - 302 + 304 (1 row) SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3; @@ -45,13 +45,13 @@ SET enable_seqscan=off; SELECT count(*) FROM float4tmp WHERE a < -179.0::float4; count ------- - 244 + 245 (1 row) SELECT count(*) FROM float4tmp WHERE a <= -179.0::float4; count ------- - 245 + 246 (1 row) SELECT count(*) FROM float4tmp WHERE a = -179.0::float4; @@ -63,13 +63,13 @@ SELECT count(*) FROM float4tmp WHERE a = -179.0::float4; SELECT count(*) FROM float4tmp WHERE a >= -179.0::float4; count ------- - 303 + 305 (1 row) SELECT count(*) FROM float4tmp WHERE a > -179.0::float4; count ------- - 302 + 304 (1 row) EXPLAIN (COSTS OFF) @@ -89,3 +89,38 @@ SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3; -158.17741 | 20.822586 (3 rows) +-- EXCLUDE constraint must block a duplicate NaN, same as it does for finite +-- values. +CREATE TABLE float4excl (a float4, EXCLUDE USING gist (a WITH =)); +INSERT INTO float4excl VALUES ('NaN'::float4); +INSERT INTO float4excl VALUES ('NaN'::float4); -- expect: violates EXCLUDE +ERROR: conflicting key value violates exclusion constraint "float4excl_a_excl" +DETAIL: Key (a)=(NaN) conflicts with existing key (a)=(NaN). +SELECT count(*) FROM float4excl; + count +------- + 1 +(1 row) + +-- Test double-column index +CREATE INDEX float4idx2 ON float4tmp USING gist ( a, abs(a) ); +EXPLAIN (COSTS OFF) +SELECT count(*) FROM float4tmp WHERE abs(a) = 179.0::float4; + QUERY PLAN +-------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on float4tmp + Recheck Cond: (abs(a) = '179'::real) + -> Bitmap Index Scan on float4idx2 + Index Cond: (abs(a) = '179'::real) +(5 rows) + +SELECT count(*) FROM float4tmp WHERE abs(a) = 179.0::float4; + count +------- + 1 +(1 row) + +RESET enable_seqscan; +RESET enable_indexscan; +RESET enable_bitmapscan; diff --git a/contrib/btree_gist/expected/float8.out b/contrib/btree_gist/expected/float8.out index ebd0ef3d689..194bd210ac6 100644 --- a/contrib/btree_gist/expected/float8.out +++ b/contrib/btree_gist/expected/float8.out @@ -5,13 +5,13 @@ SET enable_seqscan=on; SELECT count(*) FROM float8tmp WHERE a < -1890.0; count ------- - 237 + 238 (1 row) SELECT count(*) FROM float8tmp WHERE a <= -1890.0; count ------- - 238 + 239 (1 row) SELECT count(*) FROM float8tmp WHERE a = -1890.0; @@ -23,13 +23,13 @@ SELECT count(*) FROM float8tmp WHERE a = -1890.0; SELECT count(*) FROM float8tmp WHERE a >= -1890.0; count ------- - 307 + 309 (1 row) SELECT count(*) FROM float8tmp WHERE a > -1890.0; count ------- - 306 + 308 (1 row) SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3; @@ -45,13 +45,13 @@ SET enable_seqscan=off; SELECT count(*) FROM float8tmp WHERE a < -1890.0::float8; count ------- - 237 + 238 (1 row) SELECT count(*) FROM float8tmp WHERE a <= -1890.0::float8; count ------- - 238 + 239 (1 row) SELECT count(*) FROM float8tmp WHERE a = -1890.0::float8; @@ -63,13 +63,13 @@ SELECT count(*) FROM float8tmp WHERE a = -1890.0::float8; SELECT count(*) FROM float8tmp WHERE a >= -1890.0::float8; count ------- - 307 + 309 (1 row) SELECT count(*) FROM float8tmp WHERE a > -1890.0::float8; count ------- - 306 + 308 (1 row) EXPLAIN (COSTS OFF) @@ -89,3 +89,38 @@ SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3; -1769.73634 | 120.26366000000007 (3 rows) +-- EXCLUDE constraint must block a duplicate NaN, same as it does for finite +-- values. +CREATE TABLE float8excl (a float8, EXCLUDE USING gist (a WITH =)); +INSERT INTO float8excl VALUES ('NaN'::float8); +INSERT INTO float8excl VALUES ('NaN'::float8); -- expect: violates EXCLUDE +ERROR: conflicting key value violates exclusion constraint "float8excl_a_excl" +DETAIL: Key (a)=(NaN) conflicts with existing key (a)=(NaN). +SELECT count(*) FROM float8excl; + count +------- + 1 +(1 row) + +-- Test double-column index +CREATE INDEX float8idx2 ON float8tmp USING gist ( a, abs(a) ); +EXPLAIN (COSTS OFF) +SELECT count(*) FROM float8tmp WHERE abs(a) = 1890.0::float8; + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on float8tmp + Recheck Cond: (abs(a) = '1890'::double precision) + -> Bitmap Index Scan on float8idx2 + Index Cond: (abs(a) = '1890'::double precision) +(5 rows) + +SELECT count(*) FROM float8tmp WHERE abs(a) = 1890.0::float8; + count +------- + 1 +(1 row) + +RESET enable_seqscan; +RESET enable_indexscan; +RESET enable_bitmapscan; diff --git a/contrib/btree_gist/expected/numeric.out b/contrib/btree_gist/expected/numeric.out index ae839b8ec83..34c1e568063 100644 --- a/contrib/btree_gist/expected/numeric.out +++ b/contrib/btree_gist/expected/numeric.out @@ -7,13 +7,13 @@ SET enable_seqscan=on; SELECT count(*) FROM numerictmp WHERE a < -1890.0; count ------- - 505 + 506 (1 row) SELECT count(*) FROM numerictmp WHERE a <= -1890.0; count ------- - 506 + 507 (1 row) SELECT count(*) FROM numerictmp WHERE a = -1890.0; @@ -25,37 +25,37 @@ SELECT count(*) FROM numerictmp WHERE a = -1890.0; SELECT count(*) FROM numerictmp WHERE a >= -1890.0; count ------- - 597 + 599 (1 row) SELECT count(*) FROM numerictmp WHERE a > -1890.0; count ------- - 596 + 598 (1 row) SELECT count(*) FROM numerictmp WHERE a < 'NaN' ; count ------- - 1100 + 1102 (1 row) SELECT count(*) FROM numerictmp WHERE a <= 'NaN' ; count ------- - 1102 + 1105 (1 row) SELECT count(*) FROM numerictmp WHERE a = 'NaN' ; count ------- - 2 + 3 (1 row) SELECT count(*) FROM numerictmp WHERE a >= 'NaN' ; count ------- - 2 + 3 (1 row) SELECT count(*) FROM numerictmp WHERE a > 'NaN' ; @@ -67,13 +67,13 @@ SELECT count(*) FROM numerictmp WHERE a > 'NaN' ; SELECT count(*) FROM numerictmp WHERE a < 0 ; count ------- - 523 + 524 (1 row) SELECT count(*) FROM numerictmp WHERE a <= 0 ; count ------- - 526 + 527 (1 row) SELECT count(*) FROM numerictmp WHERE a = 0 ; @@ -85,13 +85,13 @@ SELECT count(*) FROM numerictmp WHERE a = 0 ; SELECT count(*) FROM numerictmp WHERE a >= 0 ; count ------- - 579 + 581 (1 row) SELECT count(*) FROM numerictmp WHERE a > 0 ; count ------- - 576 + 578 (1 row) CREATE INDEX numericidx ON numerictmp USING gist ( a ); @@ -99,13 +99,13 @@ SET enable_seqscan=off; SELECT count(*) FROM numerictmp WHERE a < -1890.0; count ------- - 505 + 506 (1 row) SELECT count(*) FROM numerictmp WHERE a <= -1890.0; count ------- - 506 + 507 (1 row) SELECT count(*) FROM numerictmp WHERE a = -1890.0; @@ -117,37 +117,37 @@ SELECT count(*) FROM numerictmp WHERE a = -1890.0; SELECT count(*) FROM numerictmp WHERE a >= -1890.0; count ------- - 597 + 599 (1 row) SELECT count(*) FROM numerictmp WHERE a > -1890.0; count ------- - 596 + 598 (1 row) SELECT count(*) FROM numerictmp WHERE a < 'NaN' ; count ------- - 1100 + 1102 (1 row) SELECT count(*) FROM numerictmp WHERE a <= 'NaN' ; count ------- - 1102 + 1105 (1 row) SELECT count(*) FROM numerictmp WHERE a = 'NaN' ; count ------- - 2 + 3 (1 row) SELECT count(*) FROM numerictmp WHERE a >= 'NaN' ; count ------- - 2 + 3 (1 row) SELECT count(*) FROM numerictmp WHERE a > 'NaN' ; @@ -159,13 +159,13 @@ SELECT count(*) FROM numerictmp WHERE a > 'NaN' ; SELECT count(*) FROM numerictmp WHERE a < 0 ; count ------- - 523 + 524 (1 row) SELECT count(*) FROM numerictmp WHERE a <= 0 ; count ------- - 526 + 527 (1 row) SELECT count(*) FROM numerictmp WHERE a = 0 ; @@ -177,13 +177,13 @@ SELECT count(*) FROM numerictmp WHERE a = 0 ; SELECT count(*) FROM numerictmp WHERE a >= 0 ; count ------- - 579 + 581 (1 row) SELECT count(*) FROM numerictmp WHERE a > 0 ; count ------- - 576 + 578 (1 row) -- Test index-only scans diff --git a/contrib/btree_gist/sql/float4.sql b/contrib/btree_gist/sql/float4.sql index 3da1ce953c8..71de5d5cf49 100644 --- a/contrib/btree_gist/sql/float4.sql +++ b/contrib/btree_gist/sql/float4.sql @@ -35,3 +35,20 @@ SELECT count(*) FROM float4tmp WHERE a > -179.0::float4; EXPLAIN (COSTS OFF) SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3; SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3; + +-- EXCLUDE constraint must block a duplicate NaN, same as it does for finite +-- values. +CREATE TABLE float4excl (a float4, EXCLUDE USING gist (a WITH =)); +INSERT INTO float4excl VALUES ('NaN'::float4); +INSERT INTO float4excl VALUES ('NaN'::float4); -- expect: violates EXCLUDE +SELECT count(*) FROM float4excl; + +-- Test double-column index +CREATE INDEX float4idx2 ON float4tmp USING gist ( a, abs(a) ); +EXPLAIN (COSTS OFF) +SELECT count(*) FROM float4tmp WHERE abs(a) = 179.0::float4; +SELECT count(*) FROM float4tmp WHERE abs(a) = 179.0::float4; + +RESET enable_seqscan; +RESET enable_indexscan; +RESET enable_bitmapscan; diff --git a/contrib/btree_gist/sql/float8.sql b/contrib/btree_gist/sql/float8.sql index e1e819b37f9..a0fc84f94bb 100644 --- a/contrib/btree_gist/sql/float8.sql +++ b/contrib/btree_gist/sql/float8.sql @@ -35,3 +35,20 @@ SELECT count(*) FROM float8tmp WHERE a > -1890.0::float8; EXPLAIN (COSTS OFF) SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3; SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3; + +-- EXCLUDE constraint must block a duplicate NaN, same as it does for finite +-- values. +CREATE TABLE float8excl (a float8, EXCLUDE USING gist (a WITH =)); +INSERT INTO float8excl VALUES ('NaN'::float8); +INSERT INTO float8excl VALUES ('NaN'::float8); -- expect: violates EXCLUDE +SELECT count(*) FROM float8excl; + +-- Test double-column index +CREATE INDEX float8idx2 ON float8tmp USING gist ( a, abs(a) ); +EXPLAIN (COSTS OFF) +SELECT count(*) FROM float8tmp WHERE abs(a) = 1890.0::float8; +SELECT count(*) FROM float8tmp WHERE abs(a) = 1890.0::float8; + +RESET enable_seqscan; +RESET enable_indexscan; +RESET enable_bitmapscan; From 5bbc9b3000a50b4278ddd449ecea0fd7c3d91686 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Thu, 2 Jul 2026 12:44:31 +0900 Subject: [PATCH 071/481] Fix jsonpath .decimal() to honor silent mode The jsonpath .decimal(precision[, scale]) method built its numeric typmod by calling numerictypmodin() through DirectFunctionCall1(), which can throw a hard error for an incorrect set of precision and/or scale vaulues. This breaks the silent mode supported by this function, that should not fail. Most of the jsonpath code uses the soft error reporting to bypass errors, which is what this fix does by avoiding a direct use of numerictypmodin(). Its code is refactored to use a new routine called make_numeric_typmod_safe(), able to take an error context in input. numerictypmodin() sets no context, mapping to its previous behavior. The jsonpath code sets or not a context depending on the use of the silent mode. This result leads to some nice simplifications: numerictypmodin() feeds on an array, we can now pass directly values for the scale and precision. Oversight in 66ea94e8e606. Author: Ewan Young Discussion: https://postgr.es/m/CAON2xHMaigKABiyPBBq3Sjd3gp7uWMJXnnMHt=s85V1ij3KP1w@mail.gmail.com Backpatch-through: 17 --- src/backend/utils/adt/jsonpath_exec.c | 26 ++++-------- src/backend/utils/adt/numeric.c | 44 +++++++++++--------- src/include/utils/numeric.h | 2 + src/test/regress/expected/jsonb_jsonpath.out | 32 ++++++++++++++ src/test/regress/sql/jsonb_jsonpath.sql | 7 ++++ 5 files changed, 73 insertions(+), 38 deletions(-) diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c index 6cc2acb4254..9bf8ecdcd0c 100644 --- a/src/backend/utils/adt/jsonpath_exec.c +++ b/src/backend/utils/adt/jsonpath_exec.c @@ -1489,14 +1489,10 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, if (jsp->type == jpiDecimal && jsp->content.args.left) { Datum numdatum; - Datum dtypmod; + int32 dtypmod; int32 precision; int32 scale = 0; bool noerr; - ArrayType *arrtypmod; - Datum datums[2]; - char pstr[12]; /* sign, 10 digits and '\0' */ - char sstr[12]; /* sign, 10 digits and '\0' */ ErrorSaveContext escontext = {T_ErrorSaveContext}; jspGetLeftArg(jsp, &elem); @@ -1526,23 +1522,16 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, jspOperationName(jsp->type))))); } - /* - * numerictypmodin() takes the precision and scale in the - * form of CString arrays. - */ - pg_ltoa(precision, pstr); - datums[0] = CStringGetDatum(pstr); - pg_ltoa(scale, sstr); - datums[1] = CStringGetDatum(sstr); - arrtypmod = construct_array_builtin(datums, 2, CSTRINGOID); - - dtypmod = DirectFunctionCall1(numerictypmodin, - PointerGetDatum(arrtypmod)); + /* Pack the precision and scale into a numeric typmod */ + dtypmod = make_numeric_typmod_safe(precision, scale, + jspThrowErrors(cxt) ? NULL : (Node *) &escontext); + if (escontext.error_occurred) + return jperError; /* Convert numstr to Numeric with typmod */ Assert(numstr != NULL); noerr = DirectInputFunctionCallSafe(numeric_in, numstr, - InvalidOid, DatumGetInt32(dtypmod), + InvalidOid, dtypmod, (Node *) &escontext, &numdatum); @@ -1553,7 +1542,6 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, numstr, jspOperationName(jsp->type), "numeric")))); num = DatumGetNumeric(numdatum); - pfree(arrtypmod); } jbv.type = jbvNumeric; diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index cb23dfe9b95..c9717faea26 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -1305,6 +1305,29 @@ numeric (PG_FUNCTION_ARGS) PG_RETURN_NUMERIC(new); } +/* + * make_numeric_typmod_safe() - + * + * Validate a numeric precision/scale and pack them into a typmod value, + * with soft error handling. + */ +int32 +make_numeric_typmod_safe(int32 precision, int32 scale, Node *escontext) +{ + if (precision < 1 || precision > NUMERIC_MAX_PRECISION) + ereturn(escontext, -1, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("NUMERIC precision %d must be between 1 and %d", + precision, NUMERIC_MAX_PRECISION))); + if (scale < NUMERIC_MIN_SCALE || scale > NUMERIC_MAX_SCALE) + ereturn(escontext, -1, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("NUMERIC scale %d must be between %d and %d", + scale, NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE))); + + return make_numeric_typmod(precision, scale); +} + Datum numerictypmodin(PG_FUNCTION_ARGS) { @@ -1316,28 +1339,11 @@ numerictypmodin(PG_FUNCTION_ARGS) tl = ArrayGetIntegerTypmods(ta, &n); if (n == 2) - { - if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("NUMERIC precision %d must be between 1 and %d", - tl[0], NUMERIC_MAX_PRECISION))); - if (tl[1] < NUMERIC_MIN_SCALE || tl[1] > NUMERIC_MAX_SCALE) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("NUMERIC scale %d must be between %d and %d", - tl[1], NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE))); - typmod = make_numeric_typmod(tl[0], tl[1]); - } + typmod = make_numeric_typmod_safe(tl[0], tl[1], NULL); else if (n == 1) { - if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("NUMERIC precision %d must be between 1 and %d", - tl[0], NUMERIC_MAX_PRECISION))); /* scale defaults to zero */ - typmod = make_numeric_typmod(tl[0], 0); + typmod = make_numeric_typmod_safe(tl[0], 0, NULL); } else { diff --git a/src/include/utils/numeric.h b/src/include/utils/numeric.h index b1cf40ed9fd..ea289dabfeb 100644 --- a/src/include/utils/numeric.h +++ b/src/include/utils/numeric.h @@ -101,6 +101,8 @@ extern Numeric numeric_div_safe(Numeric num1, Numeric num2, Node *escontext); extern Numeric numeric_mod_safe(Numeric num1, Numeric num2, Node *escontext); extern int32 numeric_int4_safe(Numeric num, Node *escontext); extern int64 numeric_int8_safe(Numeric num, Node *escontext); +extern int32 make_numeric_typmod_safe(int32 precision, int32 scale, + Node *escontext); extern Numeric random_numeric(pg_prng_state *state, Numeric rmin, Numeric rmax); diff --git a/src/test/regress/expected/jsonb_jsonpath.out b/src/test/regress/expected/jsonb_jsonpath.out index 81efebc3d0f..c7b8c36c842 100644 --- a/src/test/regress/expected/jsonb_jsonpath.out +++ b/src/test/regress/expected/jsonb_jsonpath.out @@ -2336,6 +2336,38 @@ select jsonb_path_query('12.3', '$.decimal(12345678901,1)'); ERROR: precision of jsonpath item method .decimal() is out of range for type integer select jsonb_path_query('12.3', '$.decimal(1,12345678901)'); ERROR: scale of jsonpath item method .decimal() is out of range for type integer +-- An out-of-range precision or scale does not fail in silent mode. +select jsonb_path_query('12345.678', '$.decimal(0, 6)', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('12345.678', '$.decimal(1001, 6)', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('1234.5678', '$.decimal(-6, +2)', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('1234.5678', '$.decimal(6, -1001)', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('1234.5678', '$.decimal(6, 1001)', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select '1234.5678'::jsonb @? '$.decimal(0)'; + ?column? +---------- + +(1 row) + -- Test .integer() select jsonb_path_query('null', '$.integer()'); ERROR: jsonpath item method .integer() can only be applied to a string or numeric value diff --git a/src/test/regress/sql/jsonb_jsonpath.sql b/src/test/regress/sql/jsonb_jsonpath.sql index c1f4ab5422e..c37dc3817ff 100644 --- a/src/test/regress/sql/jsonb_jsonpath.sql +++ b/src/test/regress/sql/jsonb_jsonpath.sql @@ -523,6 +523,13 @@ select jsonb_path_query('0.0012345', '$.decimal(2,4)'); select jsonb_path_query('-0.00123456', '$.decimal(2,-4)'); select jsonb_path_query('12.3', '$.decimal(12345678901,1)'); select jsonb_path_query('12.3', '$.decimal(1,12345678901)'); +-- An out-of-range precision or scale does not fail in silent mode. +select jsonb_path_query('12345.678', '$.decimal(0, 6)', silent => true); +select jsonb_path_query('12345.678', '$.decimal(1001, 6)', silent => true); +select jsonb_path_query('1234.5678', '$.decimal(-6, +2)', silent => true); +select jsonb_path_query('1234.5678', '$.decimal(6, -1001)', silent => true); +select jsonb_path_query('1234.5678', '$.decimal(6, 1001)', silent => true); +select '1234.5678'::jsonb @? '$.decimal(0)'; -- Test .integer() select jsonb_path_query('null', '$.integer()'); From 7838efe9a2d165cc3cf3a4538ecc5f10d49b1a49 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Thu, 2 Jul 2026 15:52:50 +0900 Subject: [PATCH 072/481] test_custom_stats: Fail if loading module outside shared_preload_libraries Previously, test_custom_var_stats and test_custom_fixed_stats silently skipped pgstat_register_kind() when not loaded via shared_preload_libraries, behavior inherited from injection_points. This left the SQL functions callable without the kind registered, leading to various issues on the backend side. This code is not designed to work without the pgstats kinds registered. pgstat_register_kind() gets now called when these libraries are loaded, with or without shared_preload_libraries, letting the registration fail if loading the modules at a later step than startup. test_custom_rmgrs does the same thing. Author: Bertrand Drouvot Reviewed-by: Ewan Young Discussion: https://postgr.es/m/akS/ldidWeqG1FWk@bdtpg Backpatch-through: 19 --- src/test/modules/test_custom_stats/test_custom_fixed_stats.c | 4 ---- src/test/modules/test_custom_stats/test_custom_var_stats.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/test/modules/test_custom_stats/test_custom_fixed_stats.c b/src/test/modules/test_custom_stats/test_custom_fixed_stats.c index a066ce117a6..32be1d587a1 100644 --- a/src/test/modules/test_custom_stats/test_custom_fixed_stats.c +++ b/src/test/modules/test_custom_stats/test_custom_fixed_stats.c @@ -72,10 +72,6 @@ static const PgStat_KindInfo custom_stats = { void _PG_init(void) { - /* Must be loaded via shared_preload_libraries */ - if (!process_shared_preload_libraries_in_progress) - return; - /* Register custom statistics kind */ pgstat_register_kind(PGSTAT_KIND_TEST_CUSTOM_FIXED_STATS, &custom_stats); } diff --git a/src/test/modules/test_custom_stats/test_custom_var_stats.c b/src/test/modules/test_custom_stats/test_custom_var_stats.c index 863d6a52492..024dae85a45 100644 --- a/src/test/modules/test_custom_stats/test_custom_var_stats.c +++ b/src/test/modules/test_custom_stats/test_custom_var_stats.c @@ -129,10 +129,6 @@ static const PgStat_KindInfo custom_stats = { void _PG_init(void) { - /* Must be loaded via shared_preload_libraries */ - if (!process_shared_preload_libraries_in_progress) - return; - /* Register custom statistics kind */ pgstat_register_kind(PGSTAT_KIND_TEST_CUSTOM_VAR_STATS, &custom_stats); } From 89f5f860cc584cf4c531dbc38b614e4db5c61e24 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Thu, 2 Jul 2026 15:45:22 -0400 Subject: [PATCH 073/481] pg_plan_advice: Don't generate FOREIGN_JOIN advice for a single relation. A foreign scan can target a single relation while still reaching the fs_relids branch of pgpa_build_scan() -- for example, when postgres_fdw pushes an aggregate down over one foreign table. In that case, no advice should be emitted. Author: Mahendra Singh Thalor Co-authored-by: Robert Haas Discussion: http://postgr.es/m/CAKYtNAofuAJBz6++SeikpCb=Y=MO1QgEuZNJ+KZOP2johF1r4Q@mail.gmail.com --- contrib/pg_plan_advice/Makefile | 4 +- contrib/pg_plan_advice/meson.build | 5 ++ contrib/pg_plan_advice/pgpa_scan.c | 8 +- contrib/pg_plan_advice/t/001_foreign_scan.pl | 83 ++++++++++++++++++++ 4 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 contrib/pg_plan_advice/t/001_foreign_scan.pl diff --git a/contrib/pg_plan_advice/Makefile b/contrib/pg_plan_advice/Makefile index d016723794d..c844846dd54 100644 --- a/contrib/pg_plan_advice/Makefile +++ b/contrib/pg_plan_advice/Makefile @@ -22,7 +22,9 @@ PGFILEDESC = "pg_plan_advice - help the planner get the right plan" REGRESS = alternatives gather join_order join_strategy partitionwise \ prepared scan semijoin syntax -EXTRA_INSTALL = contrib/tsm_system_time +TAP_TESTS = 1 + +EXTRA_INSTALL = contrib/tsm_system_time contrib/postgres_fdw EXTRA_CLEAN = pgpa_parser.h pgpa_parser.c pgpa_scanner.c diff --git a/contrib/pg_plan_advice/meson.build b/contrib/pg_plan_advice/meson.build index f2098947b64..bbab676be31 100644 --- a/contrib/pg_plan_advice/meson.build +++ b/contrib/pg_plan_advice/meson.build @@ -64,4 +64,9 @@ tests += { 'syntax', ], }, + 'tap': { + 'tests': [ + 't/001_foreign_scan.pl', + ], + }, } diff --git a/contrib/pg_plan_advice/pgpa_scan.c b/contrib/pg_plan_advice/pgpa_scan.c index 21b58a0ac42..a7ee09335fd 100644 --- a/contrib/pg_plan_advice/pgpa_scan.c +++ b/contrib/pg_plan_advice/pgpa_scan.c @@ -141,9 +141,13 @@ pgpa_build_scan(pgpa_plan_walker_context *walker, Plan *plan, * If multiple relations are being targeted by a single * foreign scan, then the foreign join has been pushed to the * remote side, and we want that to be reflected in the - * generated advice. + * generated advice. We can't emit FOREIGN_JOIN() advice for + * a single relation, so treat that case as an ordinary scan. */ - strategy = PGPA_SCAN_FOREIGN; + if (bms_membership(relids) == BMS_MULTIPLE) + strategy = PGPA_SCAN_FOREIGN; + else + strategy = PGPA_SCAN_ORDINARY; break; case T_Append: diff --git a/contrib/pg_plan_advice/t/001_foreign_scan.pl b/contrib/pg_plan_advice/t/001_foreign_scan.pl new file mode 100644 index 00000000000..96c7385219d --- /dev/null +++ b/contrib/pg_plan_advice/t/001_foreign_scan.pl @@ -0,0 +1,83 @@ +# Copyright (c) 2021-2026, PostgreSQL Global Development Group + +# Verify plan advice for foreign scans. + +use strict; +use warnings FATAL => 'all'; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +my $node = PostgreSQL::Test::Cluster->new('node'); +$node->init; +$node->append_conf('postgresql.conf', + "session_preload_libraries = 'pg_plan_advice'"); +$node->start; + +my $host = $node->host; +my $port = $node->port; + +$node->safe_psql( + 'postgres', qq{ + CREATE EXTENSION postgres_fdw; + CREATE SERVER loopback FOREIGN DATA WRAPPER postgres_fdw + OPTIONS (host '$host', port '$port', dbname 'postgres'); + CREATE USER MAPPING FOR CURRENT_USER SERVER loopback; + CREATE TABLE base_tab (a int); + CREATE TABLE base_tab2 (a int); + CREATE FOREIGN TABLE ftab (a int) + SERVER loopback OPTIONS (table_name 'base_tab'); + CREATE FOREIGN TABLE ftab2 (a int) + SERVER loopback OPTIONS (table_name 'base_tab2'); +}); + +# Get the generated advice from EXPLAIN output. +sub extract_generated_advice +{ + my ($explain) = @_; + my $generated_advice = ''; + my $collecting = 0; + foreach my $line (split /\n/, $explain) + { + if ($line =~ /Generated Plan Advice:/) + { + $collecting = 1; + next; + } + if ($collecting) + { + $line =~ s/^\s+//; + $line =~ s/\s+$//; + $generated_advice .= ' ' if $generated_advice ne ''; + $generated_advice .= $line; + } + } + return $generated_advice; +} + +# A pushed-down aggregate over a single foreign table yields a ForeignScan +# that names exactly one relation. No FOREIGN_JOIN advice should be generated. +my $agg_explain = $node->safe_psql('postgres', + "EXPLAIN (COSTS OFF, PLAN_ADVICE) SELECT count(*) FROM ftab;"); +my $agg_pat = qr/\QRelations: Aggregate on (ftab)\E/; +like($agg_explain, $agg_pat, 'single-table aggregate is pushed down'); +my $agg_advice = extract_generated_advice($agg_explain); +is($agg_advice, 'NO_GATHER(ftab)', 'advice for single-table aggregate'); + +# A foreign join should generate FOREIGN_JOIN advice. Here we force this by +# disabling local join methods. +my $join_explain = $node->safe_psql( + 'postgres', q{ + SET enable_mergejoin = off; + SET enable_hashjoin = off; + SET enable_nestloop = off; + EXPLAIN (COSTS OFF, PLAN_ADVICE) SELECT * FROM ftab JOIN ftab2 USING (a); +}); +my $ja_expected = 'FOREIGN_JOIN((ftab ftab2)) NO_GATHER(ftab ftab2)'; +my $ja_actual = extract_generated_advice($join_explain); +is($ja_actual, $ja_expected, 'advice for foreign join'); + +$node->stop; + +done_testing(); From 4ebbf001882f46fae10d7a564ceded4d9bbd92b5 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 3 Jul 2026 11:16:34 +0900 Subject: [PATCH 074/481] Remove replication slot advice from MultiXact wraparound hints Previously, MultiXactId wraparound hints suggested dropping stale replication slots. While that advice is appropriate for transaction ID wraparound, where replication slots can hold back XID horizons, it was misleading for MultiXactId wraparound. Following it could lead users to drop replication slots unnecessarily without helping resolve the MultiXactId wraparound condition. MultiXact cleanup is not directly delayed by replication slots. Instead, it depends on whether old MultiXactIds can still be seen as live by running transactions. This commit removes the replication slot advice from MultiXactId wraparound hints, and documents that stale replication slots are normally not relevant to resolving MultiXactId wraparound problems. Backpatch to all supported branches. BUG #18876 Reported-by: Haruka Takatsuka Author: Fujii Masao Discussion: https://postgr.es/m/18876-0d0b53bad5a1f4c1@postgresql.org Backpatch-through: 14 --- doc/src/sgml/maintenance.sgml | 6 ++++++ src/backend/access/transam/multixact.c | 12 ++++++------ src/backend/commands/vacuum.c | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index e341f165efd..0eec6e2e888 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -869,6 +869,12 @@ HINT: Execute a database-wide VACUUM in that database. Running transactions and prepared transactions can be ignored if there is no chance that they might appear in a multixact. + + Unlike transaction ID wraparound, replication slots do not + directly hold back multixact cleanup. Dropping stale replication + slots is therefore not usually relevant to resolving multixact ID + wraparound problems. + MXID information is not directly visible in system views such as pg_stat_activity; however, looking for old XIDs is still a good diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 10cbc0d76bd..8c694658132 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,14 +1040,14 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) errmsg("database is not accepting commands that assign new MultiXactIds to avoid wraparound data loss in database \"%s\"", oldest_datname), errhint("Execute a database-wide VACUUM in that database.\n" - "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); + "You might also need to commit or roll back old prepared transactions."))); else ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("database is not accepting commands that assign new MultiXactIds to avoid wraparound data loss in database with OID %u", oldest_datoid), errhint("Execute a database-wide VACUUM in that database.\n" - "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); + "You might also need to commit or roll back old prepared transactions."))); } /* @@ -1073,7 +1073,7 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) errdetail("Approximately %.2f%% of MultiXactIds are available for use.", (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" - "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); + "You might also need to commit or roll back old prepared transactions."))); else ereport(WARNING, (errmsg_plural("database with OID %u must be vacuumed before %u more MultiXactId is used", @@ -1084,7 +1084,7 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) errdetail("Approximately %.2f%% of MultiXactIds are available for use.", (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" - "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); + "You might also need to commit or roll back old prepared transactions."))); } /* Re-acquire lock and start over */ @@ -2211,7 +2211,7 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) errdetail("Approximately %.2f%% of MultiXactIds are available for use.", (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" - "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); + "You might also need to commit or roll back old prepared transactions."))); else ereport(WARNING, (errmsg_plural("database with OID %u must be vacuumed before %u more MultiXactId is used", @@ -2222,7 +2222,7 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) errdetail("Approximately %.2f%% of MultiXactIds are available for use.", (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" - "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); + "You might also need to commit or roll back old prepared transactions."))); } } diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..38539a6fd3d 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -1177,7 +1177,7 @@ vacuum_get_cutoffs(Relation rel, const VacuumParams *params, ereport(WARNING, (errmsg("cutoff for freezing multixacts is far in the past"), errhint("Close open transactions soon to avoid wraparound problems.\n" - "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); + "You might also need to commit or roll back old prepared transactions."))); /* * Determine the minimum freeze age to use: as specified by the caller, or From ea203d371de0a411cc4a27f3d707c0b6dce1fb4f Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Fri, 3 Jul 2026 12:31:15 +0900 Subject: [PATCH 075/481] pgindent fix for commit 53e6f51ee --- contrib/pg_plan_advice/pgpa_scan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/pg_plan_advice/pgpa_scan.c b/contrib/pg_plan_advice/pgpa_scan.c index a7ee09335fd..4da77936216 100644 --- a/contrib/pg_plan_advice/pgpa_scan.c +++ b/contrib/pg_plan_advice/pgpa_scan.c @@ -141,8 +141,8 @@ pgpa_build_scan(pgpa_plan_walker_context *walker, Plan *plan, * If multiple relations are being targeted by a single * foreign scan, then the foreign join has been pushed to the * remote side, and we want that to be reflected in the - * generated advice. We can't emit FOREIGN_JOIN() advice for - * a single relation, so treat that case as an ordinary scan. + * generated advice. We can't emit FOREIGN_JOIN() advice for a + * single relation, so treat that case as an ordinary scan. */ if (bms_membership(relids) == BMS_MULTIPLE) strategy = PGPA_SCAN_FOREIGN; From 558e0de6d3bba428a2aa9f233e0483d52672097c Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 3 Jul 2026 13:46:35 +0900 Subject: [PATCH 076/481] psql: Fix \df tab completion for procedures Commit fb421231daa extended \df to include procedures, but its tab completion continued not to show procedures. Update \df tab completion to include procedures as well. Backpatch to all supported versions. Author: Erik Wienhold Reviewed-by: Surya Poondla Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/10fbfdfe-80f6-4ef9-b8b3-f7be0eb53a50@ewie.name Backpatch-through: 14 --- src/bin/psql/tab-complete.in.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index 46b9add0604..b783f123643 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -5669,7 +5669,7 @@ match_previous_words(int pattern_id, else if (TailMatchesCS("\\dew*")) COMPLETE_WITH_QUERY(Query_for_list_of_fdws); else if (TailMatchesCS("\\df*")) - COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions); + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines); else if (HeadMatchesCS("\\df*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes); From ac0ad6a7c9d1f7c0d82696260fdcb2d09a8962c1 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 3 Jul 2026 11:52:42 +0200 Subject: [PATCH 077/481] Prevent dropping the last label from a property graph element Per SQL/PGQ standard, every graph element must have at least one label. When dropping a label from a graph element, ensure that there exists at least one other label on the element. If the label being dropped is the only label on the element, raise an error. We hold a ShareRowExclusiveLock when modifying a property graph. Hence the label will not be dropped even when multiple labels are being dropped concurrently. Author: Ashutosh Bapat Author: Satyanarayana Narlapuram Reported-by: Satyanarayana Narlapuram Discussion: https://www.postgresql.org/message-id/CAHg+QDeP=mTHTV48R23zKMy1SBmCKZ_L7-z5zKnYyw+K0x-gCg@mail.gmail.com --- doc/src/sgml/ref/alter_property_graph.sgml | 4 +- src/backend/commands/propgraphcmds.c | 55 +++++++++++++++++-- .../expected/create_property_graph.out | 7 +++ .../regress/sql/create_property_graph.sql | 5 ++ 4 files changed, 65 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/ref/alter_property_graph.sgml b/doc/src/sgml/ref/alter_property_graph.sgml index f517f2b2d7a..d2768a4644a 100644 --- a/doc/src/sgml/ref/alter_property_graph.sgml +++ b/doc/src/sgml/ref/alter_property_graph.sgml @@ -99,7 +99,9 @@ ALTER PROPERTY GRAPH [ IF EXISTS ] nameALTER {VERTEX|NODE|EDGE|RELATIONSHIP} TABLE ... DROP LABEL - This form removes a label from an existing vertex or edge table. + This form removes a label from an existing vertex or edge table. The + last label on an element table cannot be dropped; every vertex or edge + table must have at least one label. diff --git a/src/backend/commands/propgraphcmds.c b/src/backend/commands/propgraphcmds.c index cc516e27020..aa974ca6a4f 100644 --- a/src/backend/commands/propgraphcmds.c +++ b/src/backend/commands/propgraphcmds.c @@ -1294,6 +1294,11 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) ListCell *lc; ObjectAddress pgaddress; + /* + * ShareRowExclusiveLock is required because this command runs some + * graph-wide consistency checks that wouldn't work if more than one ALTER + * PROPERTY GRAPH could operate on the same graph at once. + */ pgrelid = RangeVarGetRelidExtended(stmt->pgname, ShareRowExclusiveLock, stmt->missing_ok ? RVR_MISSING_OK : 0, @@ -1491,8 +1496,13 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) { Oid peoid; Oid labeloid; - Oid ellabeloid; + Oid ellabeloid = InvalidOid; ObjectAddress obj; + Relation ellabelrel; + SysScanDesc ellabelscan; + ScanKeyData ellabelkey[1]; + int nlabels; + HeapTuple tuple; if (stmt->element_kind == PROPGRAPH_ELEMENT_KIND_VERTEX) peoid = get_vertex_oid(pstate, pgrelid, stmt->element_alias, -1); @@ -1510,10 +1520,34 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) get_rel_name(pgrelid), stmt->element_alias, stmt->drop_label), parser_errposition(pstate, -1)); - ellabeloid = GetSysCacheOid2(PROPGRAPHELEMENTLABELELEMENTLABEL, - Anum_pg_propgraph_element_label_oid, - ObjectIdGetDatum(peoid), - ObjectIdGetDatum(labeloid)); + /* + * Is the given label associated with the element? Is this the only + * label associated with the element? Scan the + * pg_propgraph_element_label table to find answers to these + * questions. Stop scanning when we know both answers. + */ + ellabelrel = table_open(PropgraphElementLabelRelationId, AccessShareLock); + ScanKeyInit(&ellabelkey[0], + Anum_pg_propgraph_element_label_pgelelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(peoid)); + ellabelscan = systable_beginscan(ellabelrel, PropgraphElementLabelElementLabelIndexId, + true, NULL, 1, ellabelkey); + nlabels = 0; + while (HeapTupleIsValid(tuple = systable_getnext(ellabelscan))) + { + Form_pg_propgraph_element_label ellabelform = (Form_pg_propgraph_element_label) GETSTRUCT(tuple); + + nlabels++; + + if (ellabelform->pgellabelid == labeloid) + ellabeloid = ellabelform->oid; + + if (nlabels > 1 && ellabeloid) + break; + } + systable_endscan(ellabelscan); + table_close(ellabelrel, AccessShareLock); if (!ellabeloid) ereport(ERROR, @@ -1522,6 +1556,17 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) get_rel_name(pgrelid), stmt->element_alias, stmt->drop_label), parser_errposition(pstate, -1)); + /* + * Prevent dropping the last label from an element. Every element must + * have at least one label associated with it. + */ + if (nlabels == 1) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot drop the last label from element \"%s\"", + stmt->element_alias), + errhint("Every element must have at least one label."))); + ObjectAddressSet(obj, PropgraphElementLabelRelationId, ellabeloid); performDeletion(&obj, stmt->drop_behavior, 0); diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out index 2f06c7ce5a8..f9960e5e0ae 100644 --- a/src/test/regress/expected/create_property_graph.out +++ b/src/test/regress/expected/create_property_graph.out @@ -57,6 +57,13 @@ ALTER PROPERTY GRAPH g3 ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l3x; -- error ERROR: property graph "g3" element "t3" has no label "t3l3x" ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l3; +-- Test that the last label on an element cannot be dropped +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l2; +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l1; -- error: last label +ERROR: cannot drop the last label from element "t3" +HINT: Every element must have at least one label. +-- Restore the dropped label for further tests +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 ADD LABEL t3l2 PROPERTIES ALL COLUMNS; ALTER PROPERTY GRAPH g3 DROP VERTEX TABLES (t2); -- fail ERROR: cannot drop vertex t2 of property graph g3 because other objects depend on it DETAIL: edge e1 of property graph g3 depends on vertex t2 of property graph g3 diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql index 85088ae632c..b10d7191506 100644 --- a/src/test/regress/sql/create_property_graph.sql +++ b/src/test/regress/sql/create_property_graph.sql @@ -52,6 +52,11 @@ ALTER PROPERTY GRAPH g3 ADD LABEL t3l3 PROPERTIES ALL COLUMNS; ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l3x; -- error ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l3; +-- Test that the last label on an element cannot be dropped +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l2; +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l1; -- error: last label +-- Restore the dropped label for further tests +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 ADD LABEL t3l2 PROPERTIES ALL COLUMNS; ALTER PROPERTY GRAPH g3 DROP VERTEX TABLES (t2); -- fail ALTER PROPERTY GRAPH g3 DROP VERTEX TABLES (t2) CASCADE; ALTER PROPERTY GRAPH g3 DROP EDGE TABLES (e2); From fb284f2f9bdb9dd5e866132f7d0b8eeaa972e521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Fri, 3 Jul 2026 12:22:37 +0200 Subject: [PATCH 078/481] Fix REPACK CONCURRENTLY for stored generated columns In order to replay concurrent changes, REPACK CONCURRENTLY needs the pg_attrdef tuples for the transient table to be there, in case a tuple is modified concurrently with REPACK and requires to store the value from the generated column (which, with the current arrangements, means all tuples concurrently updated or inserted). Fix by creating a copy of them from the original table. Add a test that tickles the bug. Author: Antonin Houska Reported-by: Ewan Young Diagnosed-by: Ewan Young Reviewed-by: Ewan Young Backpatch-through: 19 Discussion: https://postgr.es/m/CAON2xHMrELwx9vKg6niSf8fMBA=-MGXmG=MPQU6+vMVhGjF8kQ@mail.gmail.com --- src/backend/commands/repack.c | 103 +++++++++++++++++- .../injection_points/specs/repack.spec | 3 +- 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 4d177c868bb..83a49afe7e1 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -48,6 +48,7 @@ #include "catalog/namespace.h" #include "catalog/objectaccess.h" #include "catalog/pg_am.h" +#include "catalog/pg_attrdef.h" #include "catalog/pg_constraint.h" #include "catalog/pg_inherits.h" #include "catalog/toasting.h" @@ -204,6 +205,7 @@ static void rebuild_relation_finish_concurrent(Relation NewHeap, Relation OldHea static List *build_new_indexes(Relation NewHeap, Relation OldHeap, List *OldIndexes); static void copy_index_constraints(Relation old_index, Oid new_index_id, Oid new_heap_id); +static void copy_attribute_defaults(Oid old_heap_oid, Oid new_heap_oid); static Relation process_single_relation(RepackStmt *stmt, LOCKMODE lockmode, bool isTopLevel, @@ -1083,6 +1085,13 @@ rebuild_relation(Relation OldHeap, Relation index, bool verbose, Assert(CheckRelationOidLockedByMe(OIDNewHeap, AccessExclusiveLock, false)); NewHeap = table_open(OIDNewHeap, NoLock); + /* + * In concurrent mode, create a copy of the attribute defaults on the temp + * table, which the executor needs when replaying concurrent data changes. + */ + if (concurrent) + copy_attribute_defaults(tableOid, OIDNewHeap); + /* Copy the heap data into the new table in the desired order */ copy_table_data(NewHeap, OldHeap, index, snapshot, verbose, &swap_toast_by_content, &frozenXid, &cutoffMulti); @@ -3370,7 +3379,7 @@ build_new_indexes(Relation NewHeap, Relation OldHeap, List *OldIndexes) * * We don't need the constraints for anything else (the original constraints * will be there once repack completes), so we add pg_depend entries so that - * the are dropped when the transient table is dropped. + * they are dropped when the transient table is dropped. */ static void copy_index_constraints(Relation old_index, Oid new_index_id, Oid new_heap_id) @@ -3434,6 +3443,98 @@ copy_index_constraints(Relation old_index, Oid new_index_id, Oid new_heap_id) CommandCounterIncrement(); } +/* + * Create a transient copy of attribute defaults. + * + * When repacking a table that has stored generated columns, the executor + * relies on these entries to generate the values for them during apply of + * concurrent operations. These copies are there to support that. + * + * We don't need the defaults for anything else, so we add pg_depend entries + * so that they are dropped when the transient table is dropped. + */ +static void +copy_attribute_defaults(Oid old_heap_oid, Oid new_heap_oid) +{ + ScanKeyData skey; + Relation rel; + Relation att_rel; + SysScanDesc scan; + HeapTuple def_tup; + ObjectAddress objrel; + + rel = table_open(AttrDefaultRelationId, RowExclusiveLock); + att_rel = table_open(AttributeRelationId, RowExclusiveLock); + + ObjectAddressSet(objrel, RelationRelationId, new_heap_oid); + + ScanKeyInit(&skey, + Anum_pg_attrdef_adrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(old_heap_oid)); + scan = systable_beginscan(rel, AttrDefaultIndexId, true, + NULL, 1, &skey); + while (HeapTupleIsValid(def_tup = systable_getnext(scan))) + { + Form_pg_attrdef adform; + Oid oid; + Datum def_values[Natts_pg_attrdef]; + bool def_nulls[Natts_pg_attrdef]; + bool def_replaces[Natts_pg_attrdef] = {0}; + Datum att_values[Natts_pg_attribute]; + bool att_nulls[Natts_pg_attribute]; + bool att_replaces[Natts_pg_attribute] = {0}; + HeapTuple new_def_tup, + att_tup, + new_att_tup; + ObjectAddress objad; + + adform = (Form_pg_attrdef) GETSTRUCT(def_tup); + Assert(adform->adrelid == old_heap_oid); + + /* + * Insert a new tuple that's identical to the existing one, other than + * its OID and the relation it refers to. + */ + oid = GetNewOidWithIndex(rel, AttrDefaultOidIndexId, + Anum_pg_attrdef_oid); + def_values[Anum_pg_attrdef_oid - 1] = ObjectIdGetDatum(oid); + def_nulls[Anum_pg_attrdef_oid - 1] = false; + def_replaces[Anum_pg_attrdef_oid - 1] = true; + def_values[Anum_pg_attrdef_adrelid - 1] = ObjectIdGetDatum(new_heap_oid); + def_nulls[Anum_pg_attrdef_adrelid - 1] = false; + def_replaces[Anum_pg_attrdef_adrelid - 1] = true; + new_def_tup = heap_modify_tuple(def_tup, RelationGetDescr(rel), + def_values, def_nulls, def_replaces); + CatalogTupleInsert(rel, new_def_tup); + + /* Set atthasdef for this attribute in the transient table */ + att_tup = SearchSysCache2(ATTNUM, + ObjectIdGetDatum(new_heap_oid), + ObjectIdGetDatum(adform->adnum)); + if (!HeapTupleIsValid(att_tup)) + elog(ERROR, "cache lookup failed for attribute %d of relation %u", + adform->adnum, new_heap_oid); + att_values[Anum_pg_attribute_atthasdef - 1] = BoolGetDatum(true); + att_nulls[Anum_pg_attribute_atthasdef - 1] = false; + att_replaces[Anum_pg_attribute_atthasdef - 1] = true; + new_att_tup = heap_modify_tuple(att_tup, RelationGetDescr(att_rel), + att_values, att_nulls, att_replaces); + CatalogTupleUpdate(att_rel, &new_att_tup->t_self, new_att_tup); + ReleaseSysCache(att_tup); + + /* Add a pg_depend record so it's removed with the transient table */ + ObjectAddressSet(objad, AttrDefaultRelationId, oid); + recordDependencyOn(&objad, &objrel, DEPENDENCY_AUTO); + } + systable_endscan(scan); + + table_close(rel, RowExclusiveLock); + table_close(att_rel, RowExclusiveLock); + + CommandCounterIncrement(); +} + /* * Try to start a background worker to perform logical decoding of data * changes applied to relation while REPACK CONCURRENTLY is copying its diff --git a/src/test/modules/injection_points/specs/repack.spec b/src/test/modules/injection_points/specs/repack.spec index d727a9b056b..7896d1456ad 100644 --- a/src/test/modules/injection_points/specs/repack.spec +++ b/src/test/modules/injection_points/specs/repack.spec @@ -3,7 +3,8 @@ setup { CREATE EXTENSION injection_points; - CREATE TABLE repack_test(i int PRIMARY KEY, j int); + CREATE TABLE repack_test(i int PRIMARY KEY, j int, + k int GENERATED ALWAYS AS (j * 2) STORED); INSERT INTO repack_test(i, j) VALUES (1, 1), (2, 2), (3, 3), (4, 4); CREATE TABLE relfilenodes(node oid); From 0766bc57e9f94e5321e6ea4cb49db430224b2e60 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 3 Jul 2026 14:57:35 +0300 Subject: [PATCH 079/481] Fix tracing of BackendKeyData and CancelRequest BackendKeyData length was increased from 4 bytes to a variable-length length (up to 256 bytes) in a460251f0a. However, pqTrace still traces it as a 4 bytes key, leading to a "mismatched message length" warning message. The same issue impacts the tracing of CancelRequest. This patch fixes the issue by using pqTraceOutputNchar instead of pqTraceOutputInt32 in both cases. Author: Anthonin Bonnefoy Discussion: https://www.postgresql.org/message-id/CAO6_Xqo6gTv9=76H=k2qDRFU+KHuBiY2S=bQynEr6J8gS7L6xA@mail.gmail.com Backpatch-through: 18 --- src/interfaces/libpq/fe-trace.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/interfaces/libpq/fe-trace.c b/src/interfaces/libpq/fe-trace.c index c348b08c39b..2901fa5b451 100644 --- a/src/interfaces/libpq/fe-trace.c +++ b/src/interfaces/libpq/fe-trace.c @@ -452,11 +452,12 @@ pqTraceOutput_CopyOutResponse(FILE *f, const char *message, int *cursor) } static void -pqTraceOutput_BackendKeyData(FILE *f, const char *message, int *cursor, bool regress) +pqTraceOutput_BackendKeyData(FILE *f, const char *message, int *cursor, int length, + bool regress) { fprintf(f, "BackendKeyData\t"); pqTraceOutputInt32(f, message, cursor, regress); - pqTraceOutputInt32(f, message, cursor, regress); + pqTraceOutputNchar(f, length - *cursor + 1, message, cursor, regress); } static void @@ -762,7 +763,8 @@ pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer) /* No message content */ break; case PqMsg_BackendKeyData: - pqTraceOutput_BackendKeyData(conn->Pfdebug, message, &logCursor, regress); + pqTraceOutput_BackendKeyData(conn->Pfdebug, message, &logCursor, + length, regress); break; case PqMsg_NoData: fprintf(conn->Pfdebug, "NoData"); @@ -876,7 +878,8 @@ pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message) pqTraceOutputInt16(conn->Pfdebug, message, &logCursor); pqTraceOutputInt16(conn->Pfdebug, message, &logCursor); pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, regress); - pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, regress); + pqTraceOutputNchar(conn->Pfdebug, length - logCursor, message, + &logCursor, regress); } else if (version == NEGOTIATE_SSL_CODE) { From 36aae3d0297d35602dec40ca3edbaf82320a4cc7 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 3 Jul 2026 16:06:29 +0200 Subject: [PATCH 080/481] Fix handling of dropping a property not associated with the given label When dropping a property by name from a label, the code checked only whether the property existed in the graph's property catalog. It did not verify that the property was actually associated with the given label, resulting in passing InvalidOid to performDeletion(). Fix it by explicilty checking the label property association. While at it also rearrange the code so as to avoid multiple ereport calls for the same error in the same block. Author: Chao Li Reviewed-by: Ashutosh Bapat Discussion: https://www.postgresql.org/message-id/flat/1DA5D52A-4AFA-426E-83F7-42ED974D682B%40gmail.com --- src/backend/commands/propgraphcmds.c | 47 ++++++++----------- .../expected/create_property_graph.out | 2 + .../regress/sql/create_property_graph.sql | 1 + 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/backend/commands/propgraphcmds.c b/src/backend/commands/propgraphcmds.c index aa974ca6a4f..78cbf7d08d0 100644 --- a/src/backend/commands/propgraphcmds.c +++ b/src/backend/commands/propgraphcmds.c @@ -1583,7 +1583,7 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) Oid peoid; Oid pgerelid; Oid labeloid; - Oid ellabeloid; + Oid ellabeloid = InvalidOid; if (stmt->element_kind == PROPGRAPH_ELEMENT_KIND_VERTEX) peoid = get_vertex_oid(pstate, pgrelid, stmt->element_alias, -1); @@ -1594,17 +1594,11 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) Anum_pg_propgraph_label_oid, ObjectIdGetDatum(pgrelid), CStringGetDatum(stmt->alter_label)); - if (!labeloid) - ereport(ERROR, - errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("property graph \"%s\" element \"%s\" has no label \"%s\"", - get_rel_name(pgrelid), stmt->element_alias, stmt->alter_label), - parser_errposition(pstate, -1)); - - ellabeloid = GetSysCacheOid2(PROPGRAPHELEMENTLABELELEMENTLABEL, - Anum_pg_propgraph_element_label_oid, - ObjectIdGetDatum(peoid), - ObjectIdGetDatum(labeloid)); + if (labeloid) + ellabeloid = GetSysCacheOid2(PROPGRAPHELEMENTLABELELEMENTLABEL, + Anum_pg_propgraph_element_label_oid, + ObjectIdGetDatum(peoid), + ObjectIdGetDatum(labeloid)); if (!ellabeloid) ereport(ERROR, errcode(ERRCODE_UNDEFINED_OBJECT), @@ -1625,7 +1619,7 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) { Oid peoid; Oid labeloid; - Oid ellabeloid; + Oid ellabeloid = InvalidOid; ObjectAddress obj; if (stmt->element_kind == PROPGRAPH_ELEMENT_KIND_VERTEX) @@ -1637,17 +1631,11 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) Anum_pg_propgraph_label_oid, ObjectIdGetDatum(pgrelid), CStringGetDatum(stmt->alter_label)); - if (!labeloid) - ereport(ERROR, - errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("property graph \"%s\" element \"%s\" has no label \"%s\"", - get_rel_name(pgrelid), stmt->element_alias, stmt->alter_label), - parser_errposition(pstate, -1)); - - ellabeloid = GetSysCacheOid2(PROPGRAPHELEMENTLABELELEMENTLABEL, - Anum_pg_propgraph_element_label_oid, - ObjectIdGetDatum(peoid), - ObjectIdGetDatum(labeloid)); + if (labeloid) + ellabeloid = GetSysCacheOid2(PROPGRAPHELEMENTLABELELEMENTLABEL, + Anum_pg_propgraph_element_label_oid, + ObjectIdGetDatum(peoid), + ObjectIdGetDatum(labeloid)); if (!ellabeloid) ereport(ERROR, @@ -1660,21 +1648,24 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) { char *propname = strVal(lfirst(lc)); Oid propoid; - Oid plpoid; + Oid plpoid = InvalidOid; propoid = GetSysCacheOid2(PROPGRAPHPROPNAME, Anum_pg_propgraph_property_oid, ObjectIdGetDatum(pgrelid), CStringGetDatum(propname)); - if (!propoid) + if (propoid) + plpoid = GetSysCacheOid2(PROPGRAPHLABELPROP, + Anum_pg_propgraph_label_property_oid, + ObjectIdGetDatum(ellabeloid), + ObjectIdGetDatum(propoid)); + if (!plpoid) ereport(ERROR, errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("property graph \"%s\" element \"%s\" label \"%s\" has no property \"%s\"", get_rel_name(pgrelid), stmt->element_alias, stmt->alter_label, propname), parser_errposition(pstate, -1)); - plpoid = GetSysCacheOid2(PROPGRAPHLABELPROP, Anum_pg_propgraph_label_property_oid, ObjectIdGetDatum(ellabeloid), ObjectIdGetDatum(propoid)); - ObjectAddressSet(obj, PropgraphLabelPropertyRelationId, plpoid); performDeletion(&obj, stmt->drop_behavior, 0); } diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out index f9960e5e0ae..2a52a396fb4 100644 --- a/src/test/regress/expected/create_property_graph.out +++ b/src/test/regress/expected/create_property_graph.out @@ -89,6 +89,8 @@ CREATE PROPERTY GRAPH g4 ); ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 ADD PROPERTIES (k * 2 AS kk); ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (k); +ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (yy); -- error +ERROR: property graph "g4" element "t2" label "t2" has no property "yy" CREATE TABLE t11 (a int PRIMARY KEY); CREATE TABLE t12 (b int PRIMARY KEY); CREATE TABLE t13 ( diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql index b10d7191506..3b27d4170bb 100644 --- a/src/test/regress/sql/create_property_graph.sql +++ b/src/test/regress/sql/create_property_graph.sql @@ -80,6 +80,7 @@ CREATE PROPERTY GRAPH g4 ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 ADD PROPERTIES (k * 2 AS kk); ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (k); +ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (yy); -- error CREATE TABLE t11 (a int PRIMARY KEY); CREATE TABLE t12 (b int PRIMARY KEY); From 8021cdceb0186d3e0fb2c56ffef9ece46840a7e3 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Fri, 3 Jul 2026 15:53:03 +0300 Subject: [PATCH 081/481] Prevent access to other sessions' empty temp tables Commit ce146621 ensures that ERROR is raised if a session tries to read pages of another session's temp table. But there is a corner case where the other session's temp table is empty -- in this case the INSERT command bypasses our checks and executes without any errors. Such behavior is inconsistent and erroneous: it leaves an invalid buffer in the temp buffers pool. Since the buffer was created for another session's temp table, we get an error "no such file or directory" when trying to flush it. This commit fixes it by adding a RELATION_IS_OTHER_TEMP check in the relation-extension path. Backpatch to 16, because it is the first release after 31966b151e6, which introduced a separate local relation extension function ExtendBufferedRelLocal(), which lacks of RELATION_IS_OTHER_TEMP() check. As this fix introduces more checks to 013_temp_obj_multisession.pl, backpatch the whole test script to 16. Discussion: https://postgr.es/m/CAJDiXgiX2XZBHDNo%2BzBbvku%2BtchrUurvPRaN1_40mEQ1_sG90g%40mail.gmail.com Author: Daniil Davydov <3danissimo@gmail.com> Reviewed-by: Jim Jones Reviewed-by: Imran Zaheer Reviewed-by: ZizhuanLiu X-MAN <44973863@qq.com> Backpatch-through: 16 --- src/backend/storage/buffer/bufmgr.c | 14 ++++++++++++++ src/include/utils/rel.h | 8 ++++---- .../test_misc/t/013_temp_obj_multisession.pl | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index f79a8fa5da2..9ab282a76d1 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -2767,9 +2767,23 @@ ExtendBufferedRelCommon(BufferManagerRelation bmr, extend_by); if (bmr.relpersistence == RELPERSISTENCE_TEMP) + { + /* + * Reject attempts to extend non-local temporary relations; we have no + * ability to transfer about-to-be-created local buffers into the + * owning session's local buffers. This is the canonical place for + * the check, covering any attempt to extend a non-local temporary + * relation. + */ + if (bmr.rel && RELATION_IS_OTHER_TEMP(bmr.rel)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot access temporary tables of other sessions"))); + first_block = ExtendBufferedRelLocal(bmr, fork, flags, extend_by, extend_upto, buffers, &extend_by); + } else first_block = ExtendBufferedRelShared(bmr, fork, strategy, flags, extend_by, extend_upto, diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index fa07ebf8ff7..89c159b133f 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -668,10 +668,10 @@ RelationCloseSmgr(Relation relation) * the owning session keeps the data in its private local buffer pool, * which we cannot access. Existing buffer-manager entry points * (ReadBuffer_common(), StartReadBuffersImpl(), read_stream_begin_impl(), - * and PrefetchBuffer()) already enforce this; any new buffer-access entry - * points must do the same. Command-level code (TRUNCATE, ALTER TABLE, - * VACUUM, CLUSTER, REINDEX, ...) additionally uses this macro for - * command-specific error messages. + * PrefetchBuffer() and ExtendBufferedRelCommon()) already enforce this; any + * new buffer-access entry points must do the same. Command-level code + * (TRUNCATE, ALTER TABLE, VACUUM, CLUSTER, REINDEX, ...) additionally uses + * this macro for command-specific error messages. * * Beware of multiple eval of argument */ diff --git a/src/test/modules/test_misc/t/013_temp_obj_multisession.pl b/src/test/modules/test_misc/t/013_temp_obj_multisession.pl index 5f3cc7d2fc5..ff6f23ef3b1 100644 --- a/src/test/modules/test_misc/t/013_temp_obj_multisession.pl +++ b/src/test/modules/test_misc/t/013_temp_obj_multisession.pl @@ -36,6 +36,10 @@ # masked by an index scan that would hit ReadBuffer_common from nbtree. $psql1->query_safe(q(CREATE TEMP TABLE foo AS SELECT 42 AS val;)); +# Also create an empty table, so read path go straight through the +# extend-relation entry point. +$psql1->query_safe(q(CREATE TEMP TABLE empty_foo (val INT);)); + # Resolve the owner's temp schema so the probing session can refer to # the table by a fully-qualified name. my $tempschema = $node->safe_psql( @@ -66,6 +70,18 @@ qr/cannot access temporary tables of other sessions/, 'SELECT (seqscan via read_stream)'); +# INSERT into empty table goes through hio.c which calls RelationAddBlocks() to +# extend the table; that hits the check before new pages are created for the +# table. +$node->psql( + 'postgres', + "INSERT INTO $tempschema.empty_foo VALUES (42);", + stderr => \$stderr); +like( + $stderr, + qr/cannot access temporary tables of other sessions/, + 'INSERT (caught via hio.c)'); + # INSERT goes through hio.c which calls ReadBufferExtended() to find a # page with free space; that hits the existing check before any data # is written. From cc9aa7f3a9839878d6bb376bec6ea2e005c64d76 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 3 Jul 2026 16:58:31 +0200 Subject: [PATCH 082/481] Resolve unknown-type literals in GRAPH_TABLE COLUMNS The unknown-type literals in the COLUMNS clause of a GRAPH_TABLE are now resolved to the appropriate types. Without that, this could cause various failures. Author: Satya Narlapuram Author: Ashutosh Bapat Reviewed-by: Junwang Zhao Discussion: https://www.postgresql.org/message-id/flat/CAHg%2BQDcyKNWyzDoKMxiZNjv7C-wAxs8y0ZoNkOV137Y%2Bnk3UXg%40mail.gmail.com --- src/backend/parser/parse_clause.c | 4 ++++ src/test/regress/expected/graph_table.out | 9 +++++++++ src/test/regress/sql/graph_table.sql | 2 ++ 3 files changed, 15 insertions(+) diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 5fe5257b019..881fba2e7b5 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -1005,6 +1005,10 @@ transformRangeGraphTable(ParseState *pstate, RangeGraphTable *rgt) columns = lappend(columns, te); } + /* resolve any still-unresolved output columns as being type text */ + if (pstate->p_resolve_unknowns) + resolveTargetListUnknowns(pstate, columns); + /* * Assign collations to column expressions now since * assign_query_collations() does not process rangetable entries. diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out index 70d986e8ab0..bd603ea0d77 100644 --- a/src/test/regress/expected/graph_table.out +++ b/src/test/regress/expected/graph_table.out @@ -160,6 +160,15 @@ SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers) COLUMNS (c.name)); customer3 (3 rows) +-- unknown type resolution +SELECT *, pg_typeof(unknown_col) AS unknown_col_type, pg_typeof(null_col) AS null_col_type FROM GRAPH_TABLE (myshop MATCH (c IS customers) COLUMNS (c.name, 'unknown-literal' AS unknown_col, NULL AS null_col)); + name | unknown_col | null_col | unknown_col_type | null_col_type +-----------+-----------------+----------+------------------+--------------- + customer1 | unknown-literal | | text | text + customer2 | unknown-literal | | text | text + customer3 | unknown-literal | | text | text +(3 rows) + SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.address = 'US')-[IS customer_orders]->(o IS orders) COLUMNS (c.name)); name ----------- diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql index 0b44f70d7e7..5c8049ed242 100644 --- a/src/test/regress/sql/graph_table.sql +++ b/src/test/regress/sql/graph_table.sql @@ -134,6 +134,8 @@ INSERT INTO wishlist_items (wishlist_items_id, wishlist_id, product_no) VALUES -- single element path pattern SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers) COLUMNS (c.name)); +-- unknown type resolution +SELECT *, pg_typeof(unknown_col) AS unknown_col_type, pg_typeof(null_col) AS null_col_type FROM GRAPH_TABLE (myshop MATCH (c IS customers) COLUMNS (c.name, 'unknown-literal' AS unknown_col, NULL AS null_col)); SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.address = 'US')-[IS customer_orders]->(o IS orders) COLUMNS (c.name)); -- graph element specification without label or variable SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.address = 'US')-[]->(o IS orders) COLUMNS (c.name AS customer_name)); From 11cb9c431127ad0f331b1bf884f5c646f70b3c4f Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 3 Jul 2026 13:11:14 -0400 Subject: [PATCH 083/481] Use the proper comparator in gbt_bit_ssup_cmp. If we're dealing with leaf entries, the function to call is bitcmp not byteacmp. Using byteacmp didn't lead to any obvious failure, but it did result in sorting the entries in a way not matching the datatype's actual sort order. Hence the constructed index would be less efficient than one would expect, and in particular worse than what you got before this code was added in v18 (by commit e4309f73f). We might want to recommend that users reindex btree_gist indexes on bit/varbit columns. Author: Tom Lane Reviewed-by: Ayush Tiwari Discussion: https://postgr.es/m/AH*AvQCYKhQGVvPWi1GiU4oY.8.1781609375063.Hmail.3020001251@tju.edu.cn Backpatch-through: 18 --- contrib/btree_gist/btree_bit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/btree_gist/btree_bit.c b/contrib/btree_gist/btree_bit.c index 2b9c18a586f..ad1d2013116 100644 --- a/contrib/btree_gist/btree_bit.c +++ b/contrib/btree_gist/btree_bit.c @@ -217,7 +217,7 @@ gbt_bit_ssup_cmp(Datum x, Datum y, SortSupport ssup) Datum result; /* for leaf items we expect lower == upper, so only compare lower */ - result = DirectFunctionCall2(byteacmp, + result = DirectFunctionCall2(bitcmp, PointerGetDatum(arg1.lower), PointerGetDatum(arg2.lower)); From fc6649abefd44bd0edc4318e3e82caf34b0e885f Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 3 Jul 2026 13:50:14 -0400 Subject: [PATCH 084/481] Fix btree_gist's NotEqual strategy on internal index pages. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gbt_var_consistent() handled the <> (BtreeGistNotEqual) strategy without distinguishing leaf from internal pages, unlike every other strategy. In particular, it tried to apply the datatype-specific f_eq method, which is completely wrong since internal keys might not have the same representation as leaf keys. This led to OOB reads and potentially crashes, and most likely to wrong query results as well. On leaf pages we can apply the inverse of what the Equal strategy does. On internal pages, use a correct implementation of what the previous code intended: we can descend if the query value equals both bounds, *so long as the bounds aren't truncated*. With truncated bounds we don't quite know the range of what's below, so we must always descend. Adjust the code in gbt_num_consistent() to look similar, too. This fixes a performance buglet in that there's no need to do two comparisons on a leaf entry, but the main point is just to keep code consistency. Reported-by: 王跃林 Author: Ayush Tiwari Reviewed-by: Tom Lane Discussion: https://postgr.es/m/AH*AvQCYKhQGVvPWi1GiU4oY.8.1781609375063.Hmail.3020001251@tju.edu.cn Backpatch-through: 14 --- contrib/btree_gist/btree_utils_num.c | 15 +++++++++++++-- contrib/btree_gist/btree_utils_var.c | 23 +++++++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c index 3affe4c2c46..b0e41de00e1 100644 --- a/contrib/btree_gist/btree_utils_num.c +++ b/contrib/btree_gist/btree_utils_num.c @@ -297,8 +297,19 @@ gbt_num_consistent(const GBT_NUMKEY_R *key, retval = tinfo->f_le(query, key->upper, flinfo); break; case BtreeGistNotEqualStrategyNumber: - retval = (!(tinfo->f_eq(query, key->lower, flinfo) && - tinfo->f_eq(query, key->upper, flinfo))); + if (is_leaf) + retval = !(tinfo->f_eq(query, key->lower, flinfo)); + else + { + /* + * If the upper/lower bounds are equal, then all entries below + * this node must have exactly that value. So we can avoid + * descending if the query equals both bounds. In all other + * cases, we must descend. + */ + retval = !(tinfo->f_eq(query, key->lower, flinfo) && + tinfo->f_eq(query, key->upper, flinfo)); + } break; default: retval = false; diff --git a/contrib/btree_gist/btree_utils_var.c b/contrib/btree_gist/btree_utils_var.c index 25c3bbe8eac..0b766217529 100644 --- a/contrib/btree_gist/btree_utils_var.c +++ b/contrib/btree_gist/btree_utils_var.c @@ -571,6 +571,13 @@ gbt_var_consistent(GBT_VARKEY_R *key, { bool retval = false; + /* + * Remember that f_cmp is for internal pages, f_eq etc for leaf pages, and + * on internal pages we need to check gbt_var_node_pf_match too. + * + * The leaf-page tests use swapped operands (e.g., f_gt(query, lower) + * means "lower < query"), which is why they look reversed. + */ switch (strategy) { case BTLessEqualStrategyNumber: @@ -611,8 +618,20 @@ gbt_var_consistent(GBT_VARKEY_R *key, || gbt_var_node_pf_match(key, query, tinfo); break; case BtreeGistNotEqualStrategyNumber: - retval = !(tinfo->f_eq(query, key->lower, collation, flinfo) && - tinfo->f_eq(query, key->upper, collation, flinfo)); + if (is_leaf) + retval = !(tinfo->f_eq(query, key->lower, collation, flinfo)); + else + { + /* + * If the upper/lower bounds are equal and not truncated, then + * all entries below this node must have exactly that value. + * So we can avoid descending if the query equals both bounds. + * In all other cases, we must descend. + */ + retval = tinfo->trnc || + !(tinfo->f_cmp(query, key->lower, collation, flinfo) == 0 && + tinfo->f_cmp(query, key->upper, collation, flinfo) == 0); + } break; default: retval = false; From 5e450df50dc8e688abbad229f174f006cc550388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Fri, 3 Jul 2026 20:04:48 +0200 Subject: [PATCH 085/481] REPACK CONCURRENTLY: Initialize the range table more honestly We were skipping a bunch of things that are mostly unnecessary for REPACK. However, one thing that seems would be better to pass closer to truth, is the updatedCols bitmapset in the range table entry for the repacked table. Cons up an RTE and install it into the EState. This only has an effect on btree indexes, because certain operations are optimized in the case of unchanged columns; and even then, correctnesss is not being compromised. The values we pass after this commit are not fully trustworthy either, because we simply say "all columns were updated" for all insert/updates, regardless of whether their values were actually modified or not. However, this way we err to the side of caution rather than to the opposite direction as we were originally doing. This could be refined in the future, but there's a trade-off: determining whether the column was in fact updated could be expensive. Author: Antonin Houska Reviewed-by: Ewan Young Backpatch-through: 19 Discussion: https://postgr.es/m/18222.1782126731@localhost --- src/backend/commands/repack.c | 57 +++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 83a49afe7e1..faa07d1a118 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -63,6 +63,7 @@ #include "libpq/pqmq.h" #include "miscadmin.h" #include "optimizer/optimizer.h" +#include "parser/parse_relation.h" #include "pgstat.h" #include "replication/logicalrelation.h" #include "storage/bufmgr.h" @@ -3019,8 +3020,60 @@ initialize_change_context(ChangeContext *chgcxt, /* Only initialize fields needed by ExecInsertIndexTuples(). */ chgcxt->cc_estate = CreateExecutorState(); - chgcxt->cc_rri = (ResultRelInfo *) palloc(sizeof(ResultRelInfo)); - InitResultRelInfo(chgcxt->cc_rri, relation, 0, 0, 0); + /* + * Set up a range table for the executor, containing our repacked table as + * its only member. + */ + { + RangeTblEntry *rte; + TupleDesc desc = RelationGetDescr(relation); + List *perminfos = NIL; + Bitmapset *updatedCols = NULL; + RTEPermissionInfo *perminfo; + + /* + * For our use, the RTE only needs to have perminfoindex initialized, + * but there's no reason to not set the fields whose values we have at + * hand. + */ + rte = makeNode(RangeTblEntry); + rte->rtekind = RTE_RELATION; + rte->relid = RelationGetRelid(relation); + rte->relkind = RelationGetForm(relation)->relkind; + /* Create the RTEPermissionInfo instance (and set ->perminfoindex). */ + addRTEPermissionInfo(&perminfos, rte); + + /* + * Initialize updatedCols to show that all columns are updated. This + * is of course not necessarily true, and we cannot know this early; + * but this is only used by ExecInsertIndexTuples to flag index + * updates with no logical value changes, so if it's wrong, nothing + * terribly bad happens. We may want to improve this someday though. + * + * Don't claim that dropped columns are changed though. + */ + for (int i = 0; i < desc->natts; i++) + { + CompactAttribute *attr = TupleDescCompactAttr(desc, i); + + if (attr->attisdropped) + continue; + updatedCols = bms_add_member(updatedCols, + i + 1 - FirstLowInvalidHeapAttributeNumber); + } + + /* install updatedCols in the right place */ + perminfo = getRTEPermissionInfo(perminfos, rte); + perminfo->updatedCols = updatedCols; + + /* finally we can initialize the range table proper */ + ExecInitRangeTable(chgcxt->cc_estate, list_make1(rte), perminfos, + bms_make_singleton(1)); + } + + /* Set up our ResultRelInfo to use for index updates */ + chgcxt->cc_rri = makeNode(ResultRelInfo); + InitResultRelInfo(chgcxt->cc_rri, relation, 1, NULL, 0); ExecOpenIndices(chgcxt->cc_rri, false); /* From d86873683001a57b32e894a5ea06fd8f3cee254f Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 3 Jul 2026 23:32:20 +0200 Subject: [PATCH 086/481] Make property graph object descriptions better translatable getObjectDescription() currently constructs property graph-related object descriptions incrementally with appendStringInfo(). This effectively fixes the word order in English, which makes the messages difficult to translate naturally into languages such as Japanese. Author: Kyotaro Horiguchi Reviewed-by: Ashutosh Bapat Discussion: https://www.postgresql.org/message-id/flat/20260528.121622.1662808269492494574.horikyota.ntt%40gmail.com --- src/backend/catalog/objectaddress.c | 45 +++++++++++++++++++---------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index af0e4703616..0c305ed6de3 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -4083,6 +4083,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) { HeapTuple tup; Form_pg_propgraph_element pgeform; + StringInfoData rel; tup = SearchSysCache1(PROPGRAPHELOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) @@ -4095,16 +4096,17 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) pgeform = (Form_pg_propgraph_element) GETSTRUCT(tup); + initStringInfo(&rel); + getRelationDescription(&rel, pgeform->pgepgid, false); + if (pgeform->pgekind == PGEKIND_VERTEX) - /* translator: followed by, e.g., "property graph %s" */ - appendStringInfo(&buffer, _("vertex %s of "), NameStr(pgeform->pgealias)); + appendStringInfo(&buffer, _("vertex %s of %s"), NameStr(pgeform->pgealias), rel.data); else if (pgeform->pgekind == PGEKIND_EDGE) - /* translator: followed by, e.g., "property graph %s" */ - appendStringInfo(&buffer, _("edge %s of "), NameStr(pgeform->pgealias)); + appendStringInfo(&buffer, _("edge %s of %s"), NameStr(pgeform->pgealias), rel.data); else - appendStringInfo(&buffer, "??? element %s of ", NameStr(pgeform->pgealias)); - getRelationDescription(&buffer, pgeform->pgepgid, false); + appendStringInfo(&buffer, "??? element %s of %s", NameStr(pgeform->pgealias), rel.data); + pfree(rel.data); ReleaseSysCache(tup); break; } @@ -4131,9 +4133,10 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) pgelform = (Form_pg_propgraph_element_label) GETSTRUCT(tuple); - appendStringInfo(&buffer, _("label %s of "), get_propgraph_label_name(pgelform->pgellabelid)); ObjectAddressSet(oa, PropgraphElementRelationId, pgelform->pgelelid); - appendStringInfoString(&buffer, getObjectDescription(&oa, false)); + appendStringInfo(&buffer, _("label %s of %s"), + get_propgraph_label_name(pgelform->pgellabelid), + getObjectDescription(&oa, false)); table_close(rel, AccessShareLock); break; @@ -4143,6 +4146,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) { HeapTuple tuple; Form_pg_propgraph_label pglform; + StringInfoData rel; tuple = SearchSysCache1(PROPGRAPHLABELOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tuple)) @@ -4154,9 +4158,12 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) pglform = (Form_pg_propgraph_label) GETSTRUCT(tuple); - /* translator: followed by, e.g., "property graph %s" */ - appendStringInfo(&buffer, _("label %s of "), NameStr(pglform->pgllabel)); - getRelationDescription(&buffer, pglform->pglpgid, false); + initStringInfo(&rel); + getRelationDescription(&rel, pglform->pglpgid, false); + + appendStringInfo(&buffer, _("label %s of %s"), NameStr(pglform->pgllabel), rel.data); + + pfree(rel.data); ReleaseSysCache(tuple); break; } @@ -4183,9 +4190,11 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) plpform = (Form_pg_propgraph_label_property) GETSTRUCT(tuple); - appendStringInfo(&buffer, _("property %s of "), get_propgraph_property_name(plpform->plppropid)); ObjectAddressSet(oa, PropgraphElementLabelRelationId, plpform->plpellabelid); - appendStringInfoString(&buffer, getObjectDescription(&oa, false)); + + appendStringInfo(&buffer, _("property %s of %s"), + get_propgraph_property_name(plpform->plppropid), + getObjectDescription(&oa, false)); table_close(rel, AccessShareLock); break; @@ -4195,6 +4204,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) { HeapTuple tuple; Form_pg_propgraph_property pgpform; + StringInfoData rel; tuple = SearchSysCache1(PROPGRAPHPROPOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tuple)) @@ -4206,9 +4216,12 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) pgpform = (Form_pg_propgraph_property) GETSTRUCT(tuple); - /* translator: followed by, e.g., "property graph %s" */ - appendStringInfo(&buffer, _("property %s of "), NameStr(pgpform->pgpname)); - getRelationDescription(&buffer, pgpform->pgppgid, false); + initStringInfo(&rel); + getRelationDescription(&rel, pgpform->pgppgid, false); + + appendStringInfo(&buffer, _("property %s of %s"), NameStr(pgpform->pgpname), rel.data); + + pfree(rel.data); ReleaseSysCache(tuple); break; } From 80c7f5467d9e14595688ceceba62b8b784595d1e Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 4 Jul 2026 11:34:26 -0400 Subject: [PATCH 087/481] Disallow renaming a rule to "_RETURN". ON SELECT rules must be named "_RETURN", while other kinds of rules must not be; this ancient restriction is depended on by various client code. We successfully enforced this convention in most places, but ALTER RULE allowed renaming a non-SELECT rule to "_RETURN". Notably, that would break dump/restore, since the eventual CREATE RULE command would reject the name. While at it, remove DefineQueryRewrite's hack to substitute "_RETURN" for the convention that was used before 7.3. We dropped other server-side code that supported restoring pre-7.3 dumps some time ago (notably in e58a59975 and nearby commits), but this bit was missed. Bug: #19543 Reported-by: Adam Pickering Author: Tom Lane Discussion: https://postgr.es/m/19543-461228e77f3b32fc@postgresql.org Backpatch-through: 14 --- src/backend/rewrite/rewriteDefine.c | 36 +++++++++++++---------------- src/test/regress/expected/rules.out | 2 ++ src/test/regress/sql/rules.sql | 1 + 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 6a223fbeaa4..6361eeea20f 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -390,26 +390,11 @@ DefineQueryRewrite(const char *rulename, * ... and finally the rule must be named _RETURN. */ if (strcmp(rulename, ViewSelectRuleName) != 0) - { - /* - * In versions before 7.3, the expected name was _RETviewname. For - * backwards compatibility with old pg_dump output, accept that - * and silently change it to _RETURN. Since this is just a quick - * backwards-compatibility hack, limit the number of characters - * checked to a few less than NAMEDATALEN; this saves having to - * worry about where a multibyte character might have gotten - * truncated. - */ - if (strncmp(rulename, "_RET", 4) != 0 || - strncmp(rulename + 4, RelationGetRelationName(event_relation), - NAMEDATALEN - 4 - 4) != 0) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("view rule for \"%s\" must be named \"%s\"", - RelationGetRelationName(event_relation), - ViewSelectRuleName))); - rulename = pstrdup(ViewSelectRuleName); - } + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("view rule for \"%s\" must be named \"%s\"", + RelationGetRelationName(event_relation), + ViewSelectRuleName))); } else { @@ -843,6 +828,17 @@ RenameRewriteRule(RangeVar *relation, const char *oldName, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("renaming an ON SELECT rule is not allowed"))); + /* + * Conversely, if it's not an ON SELECT rule then it must *not* be named + * _RETURN. + */ + if (strcmp(newName, ViewSelectRuleName) == 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("non-view rule for \"%s\" must not be named \"%s\"", + RelationGetRelationName(targetrel), + ViewSelectRuleName))); + /* OK, do the update */ namestrcpy(&(ruleform->rulename), newName); diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index a65a5bf0c4f..475f5683e1c 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -3428,6 +3428,8 @@ ALTER RULE NewInsertRule ON rule_v1 RENAME TO "_RETURN"; -- already exists ERROR: rule "_RETURN" for relation "rule_v1" already exists ALTER RULE "_RETURN" ON rule_v1 RENAME TO abc; -- ON SELECT rule cannot be renamed ERROR: renaming an ON SELECT rule is not allowed +ALTER RULE rtest_t4_ins1 ON rtest_t4 RENAME TO "_RETURN"; -- also disallowed +ERROR: non-view rule for "rtest_t4" must not be named "_RETURN" DROP VIEW rule_v1; DROP TABLE rule_t1; -- diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql index 40f5c16e540..abe89d097c9 100644 --- a/src/test/regress/sql/rules.sql +++ b/src/test/regress/sql/rules.sql @@ -1087,6 +1087,7 @@ SELECT * FROM rule_v1; ALTER RULE InsertRule ON rule_v1 RENAME TO NewInsertRule; -- doesn't exist ALTER RULE NewInsertRule ON rule_v1 RENAME TO "_RETURN"; -- already exists ALTER RULE "_RETURN" ON rule_v1 RENAME TO abc; -- ON SELECT rule cannot be renamed +ALTER RULE rtest_t4_ins1 ON rtest_t4 RENAME TO "_RETURN"; -- also disallowed DROP VIEW rule_v1; DROP TABLE rule_t1; From 45d4c917ff4f4fe206ad18d0279a47c9f2a08123 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Sun, 5 Jul 2026 13:47:18 +0200 Subject: [PATCH 088/481] Fix properties orphaned by dropping a label AlterPropGraph() cleans up pg_propgraph_property entries that are orphaned by dropping an element or by dropping properties associated with an element. But it did not clean up pg_propgraph_property entries that are orphaned by dropping labels associated with an element. Fix this missing case. Author: Ashutosh Bapat Author: zengman Discussion: https://www.postgresql.org/message-id/flat/tencent_76F6ACA2364EAA1E5DBD7A47%40qq.com --- src/backend/commands/propgraphcmds.c | 2 +- .../expected/create_property_graph.out | 23 +++++++++---------- .../regress/sql/create_property_graph.sql | 5 ++++ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/backend/commands/propgraphcmds.c b/src/backend/commands/propgraphcmds.c index 78cbf7d08d0..6939a448895 100644 --- a/src/backend/commands/propgraphcmds.c +++ b/src/backend/commands/propgraphcmds.c @@ -1674,7 +1674,7 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) } /* Remove any orphaned pg_propgraph_property entries */ - if (stmt->drop_properties || stmt->drop_vertex_tables || stmt->drop_edge_tables) + if (stmt->drop_properties || stmt->drop_vertex_tables || stmt->drop_edge_tables || stmt->drop_label) { foreach_oid(propoid, get_graph_property_ids(pgrelid)) { diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out index 2a52a396fb4..3638f7f9f68 100644 --- a/src/test/regress/expected/create_property_graph.out +++ b/src/test/regress/expected/create_property_graph.out @@ -91,6 +91,11 @@ ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 ADD PROPERTIES (k * ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (k); ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (yy); -- error ERROR: property graph "g4" element "t2" label "t2" has no property "yy" +-- Dropping a label should drop only orphaned properties. zz is orphaned because +-- it is only associated with the dropped label t3l2, while x is not orphaned +-- because it remains associated with t3l1. We will verify this in the +-- information schema queries outputs below. +ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t3 DROP LABEL t3l2; CREATE TABLE t11 (a int PRIMARY KEY); CREATE TABLE t12 (b int PRIMARY KEY); CREATE TABLE t13 ( @@ -448,7 +453,6 @@ SELECT * FROM information_schema.pg_element_table_labels ORDER BY property_graph regression | create_property_graph_tests | g4 | t1 | t1 regression | create_property_graph_tests | g4 | t2 | t2 regression | create_property_graph_tests | g4 | t3 | t3l1 - regression | create_property_graph_tests | g4 | t3 | t3l2 regression | create_property_graph_tests | g5 | t11 | t11 regression | create_property_graph_tests | g5 | t12 | t12 regression | create_property_graph_tests | g5 | t13 | t13 @@ -460,7 +464,7 @@ SELECT * FROM information_schema.pg_element_table_labels ORDER BY property_graph regression | create_property_graph_tests | gt | e | e regression | create_property_graph_tests | gt | v1 | v1 regression | create_property_graph_tests | gt | v2 | v2 -(26 rows) +(25 rows) SELECT * FROM information_schema.pg_element_table_properties ORDER BY property_graph_name, element_table_alias, property_name; property_graph_catalog | property_graph_schema | property_graph_name | element_table_alias | property_name | property_expression @@ -494,7 +498,6 @@ SELECT * FROM information_schema.pg_element_table_properties ORDER BY property_g regression | create_property_graph_tests | g4 | t2 | kk | (k * 2) regression | create_property_graph_tests | g4 | t3 | x | x regression | create_property_graph_tests | g4 | t3 | yy | y - regression | create_property_graph_tests | g4 | t3 | zz | z regression | create_property_graph_tests | g5 | t11 | a | a regression | create_property_graph_tests | g5 | t12 | b | b regression | create_property_graph_tests | g5 | t13 | c | c @@ -519,7 +522,7 @@ SELECT * FROM information_schema.pg_element_table_properties ORDER BY property_g regression | create_property_graph_tests | gt | v1 | b | b regression | create_property_graph_tests | gt | v2 | m | m regression | create_property_graph_tests | gt | v2 | n | n -(54 rows) +(53 rows) SELECT * FROM information_schema.pg_label_properties ORDER BY property_graph_name, label_name, property_name; property_graph_catalog | property_graph_schema | property_graph_name | label_name | property_name @@ -559,8 +562,6 @@ SELECT * FROM information_schema.pg_label_properties ORDER BY property_graph_nam regression | create_property_graph_tests | g4 | t2 | kk regression | create_property_graph_tests | g4 | t3l1 | x regression | create_property_graph_tests | g4 | t3l1 | yy - regression | create_property_graph_tests | g4 | t3l2 | x - regression | create_property_graph_tests | g4 | t3l2 | zz regression | create_property_graph_tests | g5 | t11 | a regression | create_property_graph_tests | g5 | t12 | b regression | create_property_graph_tests | g5 | t13 | c @@ -585,7 +586,7 @@ SELECT * FROM information_schema.pg_label_properties ORDER BY property_graph_nam regression | create_property_graph_tests | gt | v1 | b regression | create_property_graph_tests | gt | v2 | m regression | create_property_graph_tests | gt | v2 | n -(61 rows) +(59 rows) SELECT * FROM information_schema.pg_labels ORDER BY property_graph_name, label_name; property_graph_catalog | property_graph_schema | property_graph_name | label_name @@ -604,7 +605,6 @@ SELECT * FROM information_schema.pg_labels ORDER BY property_graph_name, label_n regression | create_property_graph_tests | g4 | t1 regression | create_property_graph_tests | g4 | t2 regression | create_property_graph_tests | g4 | t3l1 - regression | create_property_graph_tests | g4 | t3l2 regression | create_property_graph_tests | g5 | t11 regression | create_property_graph_tests | g5 | t12 regression | create_property_graph_tests | g5 | t13 @@ -616,7 +616,7 @@ SELECT * FROM information_schema.pg_labels ORDER BY property_graph_name, label_n regression | create_property_graph_tests | gt | e regression | create_property_graph_tests | gt | v1 regression | create_property_graph_tests | gt | v2 -(26 rows) +(25 rows) SELECT * FROM information_schema.pg_property_data_types ORDER BY property_graph_name, property_name; property_graph_catalog | property_graph_schema | property_graph_name | property_name | data_type | character_maximum_length | character_octet_length | character_set_catalog | character_set_schema | character_set_name | collation_catalog | collation_schema | collation_name | numeric_precision | numeric_precision_radix | numeric_scale | datetime_precision | interval_type | interval_precision | user_defined_type_catalog | user_defined_type_schema | user_defined_type_name | scope_catalog | scope_schema | scope_name | maximum_cardinality | dtd_identifier @@ -642,7 +642,6 @@ SELECT * FROM information_schema.pg_property_data_types ORDER BY property_graph_ regression | create_property_graph_tests | g4 | t | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | t regression | create_property_graph_tests | g4 | x | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | x regression | create_property_graph_tests | g4 | yy | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | yy - regression | create_property_graph_tests | g4 | zz | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | zz regression | create_property_graph_tests | g5 | a | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | a regression | create_property_graph_tests | g5 | b | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | b regression | create_property_graph_tests | g5 | c | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | c @@ -660,7 +659,7 @@ SELECT * FROM information_schema.pg_property_data_types ORDER BY property_graph_ regression | create_property_graph_tests | gt | k2 | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | k2 regression | create_property_graph_tests | gt | m | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | m regression | create_property_graph_tests | gt | n | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | n -(39 rows) +(38 rows) SELECT * FROM information_schema.pg_property_graph_privileges WHERE grantee LIKE 'regress%' ORDER BY property_graph_name, grantor, grantee, privilege_type; grantor | grantee | property_graph_catalog | property_graph_schema | property_graph_name | privilege_type | is_grantable @@ -810,7 +809,7 @@ CREATE PROPERTY GRAPH create_property_graph_tests.g4 VERTEX TABLES ( t1 KEY (a) NO PROPERTIES, t2 KEY (i) PROPERTIES ((i + j) AS i_j, (k * 2) AS kk), - t3 KEY (x) LABEL t3l1 PROPERTIES (x, y AS yy) LABEL t3l2 PROPERTIES (x, z AS zz) + t3 KEY (x) LABEL t3l1 PROPERTIES (x, y AS yy) ) EDGE TABLES ( e1 KEY (a, i) SOURCE KEY (a) REFERENCES t1 (a) DESTINATION KEY (i) REFERENCES t2 (i) PROPERTIES (a, i, t), diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql index 3b27d4170bb..5262971342c 100644 --- a/src/test/regress/sql/create_property_graph.sql +++ b/src/test/regress/sql/create_property_graph.sql @@ -81,6 +81,11 @@ CREATE PROPERTY GRAPH g4 ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 ADD PROPERTIES (k * 2 AS kk); ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (k); ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (yy); -- error +-- Dropping a label should drop only orphaned properties. zz is orphaned because +-- it is only associated with the dropped label t3l2, while x is not orphaned +-- because it remains associated with t3l1. We will verify this in the +-- information schema queries outputs below. +ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t3 DROP LABEL t3l2; CREATE TABLE t11 (a int PRIMARY KEY); CREATE TABLE t12 (b int PRIMARY KEY); From 56e892a49439ad361d8610bd859f4c7a29ec336e Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 5 Jul 2026 18:11:40 -0400 Subject: [PATCH 089/481] Fix psql's pager selection for wrapped expanded output. psql decided whether to use the pager in expanded output without accounting for possible wrapping of column values. This could allow it to not use the pager in cases where it should do so. To fix, move the IsPagerNeeded decision in print_aligned_vertical() down until after the wrapped data width is known. Then, if we're in wrapped mode, prepare a width_wrap array specifying that width (which, in vertical mode, is the same for all columns). This is fixing an omission in 27da1a796, so back-patch to v19 where that came in. Author: Chao Li Reviewed-by: Erik Wienhold Reviewed-by: Tom Lane Discussion: https://postgr.es/m/A44110E7-6A03-4C67-95AD-527192A6C768@gmail.com Backpatch-through: 19 --- src/bin/psql/t/030_pager.pl | 5 ++++ src/fe_utils/print.c | 53 ++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/bin/psql/t/030_pager.pl b/src/bin/psql/t/030_pager.pl index d3f964639d3..7b8b32b3caf 100644 --- a/src/bin/psql/t/030_pager.pl +++ b/src/bin/psql/t/030_pager.pl @@ -130,6 +130,11 @@ sub do_command qr/55\r?$/m, "execute command with footer that needs pagination"); +do_command( + "\\pset expanded on\n\\pset format wrapped\nSELECT repeat('x',80) AS payload FROM generate_series(1,11);\n", + qr/34\r?$/m, + "execute SELECT query that needs pagination in expanded wrapped mode"); + # send psql an explicit \q to shut it down, else pty won't close properly $h->quit or die "psql returned $?"; diff --git a/src/fe_utils/print.c b/src/fe_utils/print.c index bfbaf094d7e..7a16827d4e1 100644 --- a/src/fe_utils/print.c +++ b/src/fe_utils/print.c @@ -1354,17 +1354,6 @@ print_aligned_vertical(const printTableContent *cont, return; } - /* - * Deal with the pager here instead of in printTable(), because we could - * get here via print_aligned_text() in expanded auto mode, and so we have - * to recalculate the pager requirement based on vertical output. - */ - if (!is_pager) - { - IsPagerNeeded(cont, NULL, true, &fout, &is_pager); - is_local_pager = is_pager; - } - /* Find the maximum dimensions for the headers */ for (i = 0; i < cont->ncolumns; i++) { @@ -1415,13 +1404,6 @@ print_aligned_vertical(const printTableContent *cont, dlineptr->ptr = pg_malloc(dformatsize); hlineptr->ptr = pg_malloc(hformatsize); - if (cont->opt->start_table) - { - /* print title */ - if (!opt_tuples_only && cont->title) - fprintf(fout, "%s\n", cont->title); - } - /* * Choose target output width: \pset columns, or $COLUMNS, or ioctl */ @@ -1569,6 +1551,41 @@ print_aligned_vertical(const printTableContent *cont, dwidth = newdwidth; } + /* + * Deal with the pager here instead of in printTable(), because we could + * get here via print_aligned_text() in expanded auto mode, and so we have + * to recalculate the pager requirement based on vertical output. + */ + if (!is_pager) + { + unsigned int *width_wrap = NULL; + + /* + * Wrapping can add extra output lines, which count_table_lines() can + * only account for if it has wrap widths. But vertical output uses + * the same data width for every field, so that's easy: use dwidth for + * every column. + */ + if (cont->opt->format == PRINT_WRAPPED && cont->ncolumns > 0) + { + width_wrap = pg_malloc_array(unsigned int, cont->ncolumns); + for (i = 0; i < cont->ncolumns; i++) + width_wrap[i] = dwidth; + } + + IsPagerNeeded(cont, width_wrap, true, &fout, &is_pager); + is_local_pager = is_pager; + + free(width_wrap); + } + + if (cont->opt->start_table) + { + /* print title */ + if (!opt_tuples_only && cont->title) + fprintf(fout, "%s\n", cont->title); + } + /* print records */ for (i = 0, ptr = cont->cells; *ptr; i++, ptr++) { From 80cfd8aef645295aceafd2aa98912c64edd06394 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 6 Jul 2026 09:32:28 +0900 Subject: [PATCH 090/481] amcheck: Fix memory leak with gin_index_check() "prev_tuple" was overwritten with a new tuple coming from CopyIndexTuple() on each loop, leaking memory for every tuple processed on entry tree pages. The function uses a dedicated memory context, but this could leave unused large areas of memory while processing a large GIN index, the larger the worse. Oversight in 14ffaece0fb5. Author: Kirill Reshke Reviewed-by: Ewan Young Discussion: https://postgr.es/m/CALdSSPjTS6TYe5=5NfMUBYZyQu5cn=ABL6K5_OZjzGWqnwXeBw@mail.gmail.com Backpatch-through: 18 --- contrib/amcheck/verify_gin.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/amcheck/verify_gin.c b/contrib/amcheck/verify_gin.c index abfad07d5e4..fa06689ed5b 100644 --- a/contrib/amcheck/verify_gin.c +++ b/contrib/amcheck/verify_gin.c @@ -637,6 +637,9 @@ gin_check_parent_keys_consistency(Relation rel, pfree(ipd); } + if (prev_tuple) + pfree(prev_tuple); + prev_tuple = CopyIndexTuple(idxtuple); prev_attnum = current_attnum; } From 98d5d7ee6419dc4b3894d7b4610a2e128f675052 Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Mon, 6 Jul 2026 16:13:14 +0900 Subject: [PATCH 091/481] Fix qual pushdown past grouping with mismatched equivalence The planner has two optimizations that move a qual clause across a grouping boundary: subquery_planner transfers HAVING clauses to WHERE so they can be evaluated before aggregation, and qual_is_pushdown_safe pushes outer restriction clauses into a subquery past its DISTINCT, DISTINCT ON, window PARTITION BY, or set-operation grouping layer. Both produce wrong results when the moved clause's equivalence relation disagrees with the grouping's, since the clause then filters rows the grouping would have merged. The disagreement has two forms. A type may belong to multiple btree opfamilies whose equality operators disagree (e.g. record_ops vs record_image_ops); or the grouping may use a nondeterministic collation, where comparing the column under a different collation, or wrapping it in a function or operator, can distinguish values the collation considers equal. Because we cannot prove an arbitrary expression preserves that equality, a grouping column with a nondeterministic collation is safe to push only as a direct operand of a comparison under its own collation. Fix both call sites through a shared walker parameterized by a callback that maps each Var to the grouping equality operator for its column (or InvalidOid for non-grouping Vars). For HAVING, the callback recovers the SortGroupClause's eqop via the GROUP Var's varattno, which requires running before flatten_group_exprs while havingQual still contains GROUP Vars. For subquery pushdown, the callback recovers the eqop from subquery->distinctClause, a window's partitionClause, or any grouping node in the SetOperationStmt tree. The walker fires only when there is an equivalence boundary to cross, gated by either the existing UNSAFE_NOTIN_DISTINCTON_CLAUSE and UNSAFE_NOTIN_PARTITIONBY_CLAUSE flags or by a recursive check for any grouping node in the set-op tree. Back-patch to v18 only. The HAVING half relies on the RTE_GROUP mechanism introduced in v18 (commit 247dea89f), which is what lets us identify grouping expressions via GROUP Vars on pre-flatten havingQual. Pre-v18 branches lack that machinery, so a back-patch there would need a different approach. Given the absence of field reports of these bugs on back branches, the risk of carrying a different fix on stable branches is not justified. Author: Richard Guo Reviewed-by: Thom Brown Reviewed-by: Florin Irion Reviewed-by: Zsolt Parragi Reviewed-by: Tender Wang Reviewed-by: Chengpeng Yan Discussion: https://postgr.es/m/CAMbWs4-QLZpn3UVOpeG2fOxxhdnkDNMZ_3Zcm3dqJwRAphz68g@mail.gmail.com Backpatch-through: 18 --- src/backend/optimizer/path/allpaths.c | 179 +++++++++++ src/backend/optimizer/plan/planner.c | 263 +++++----------- src/backend/optimizer/util/clauses.c | 268 ++++++++++++++++ src/backend/utils/cache/lsyscache.c | 24 +- src/include/optimizer/clauses.h | 14 + src/test/regress/expected/aggregates.out | 80 ++++- .../regress/expected/collate.icu.utf8.out | 286 ++++++++++++++++-- src/test/regress/expected/subselect.out | 214 +++++++++++++ src/test/regress/sql/aggregates.sql | 46 ++- src/test/regress/sql/collate.icu.utf8.sql | 129 +++++++- src/test/regress/sql/subselect.sql | 105 +++++++ src/tools/pgindent/typedefs.list | 4 +- 12 files changed, 1370 insertions(+), 242 deletions(-) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index c134594a21a..9c040ecefc8 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -162,6 +162,10 @@ static bool targetIsInAllPartitionLists(TargetEntry *tle, Query *query); static pushdown_safe_type qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo, pushdown_safety_info *safetyInfo); +static Oid pushdown_var_grouping_eqop(Var *var, void *context); +static Oid subquery_column_grouping_eqop(Query *subquery, AttrNumber attno); +static Oid setop_column_grouping_eqop(Node *setop, AttrNumber attno); +static bool setop_has_grouping(Node *setop); static void subquery_push_qual(Query *subquery, RangeTblEntry *rte, Index rti, Node *qual); static void recurse_push_qual(Node *setOp, Query *topquery, @@ -4440,6 +4444,16 @@ targetIsInAllPartitionLists(TargetEntry *tle, Query *query) * * 5. rinfo's clause must not refer to any subquery output columns that were * found to be unsafe to reference by subquery_is_pushdown_safe(). + * + * 6. If the subquery has a grouping layer (DISTINCT, DISTINCT ON, window + * PARTITION BY, or a set operation that groups rows by equality), rinfo's + * clause must not apply a different equivalence relation to a grouping column + * than the grouping uses; otherwise it would distinguish rows the grouping + * considers equal, and pushing such a clause past the grouping would drop + * members of a group and change which row becomes the group's representative + * (or, for window functions, change per-partition values such as ranks and + * counts). See expression_has_grouping_conflict for the kinds of conflict + * detected. */ static pushdown_safe_type qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo, @@ -4536,9 +4550,174 @@ qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo, list_free(vars); + /* Check point 6 */ + if (safe == PUSHDOWN_SAFE && + (subquery->hasWindowFuncs || + subquery->distinctClause != NIL || + (subquery->setOperations != NULL && + setop_has_grouping(subquery->setOperations)))) + { + if (expression_has_grouping_conflict(qual, pushdown_var_grouping_eqop, + subquery)) + safe = PUSHDOWN_UNSAFE; + } + return safe; } +/* + * pushdown_var_grouping_eqop + * grouping_eqop_callback for qual_is_pushdown_safe. + * + * Returns the grouping equality operator for 'var' if it references a subquery + * output column that participates in the subquery's grouping layer; InvalidOid + * otherwise. + * + * 'context' is the subquery Query whose pushdown safety we're checking. + */ +static Oid +pushdown_var_grouping_eqop(Var *var, void *context) +{ + Query *subquery = (Query *) context; + Oid eqop; + + if (var->varlevelsup != 0) + return InvalidOid; + + eqop = subquery_column_grouping_eqop(subquery, var->varattno); + + /* + * qual_is_pushdown_safe ensures any level-0 subquery Var that reaches us + * references a grouping column. + */ + Assert(OidIsValid(eqop)); + + return eqop; +} + +/* + * subquery_column_grouping_eqop + * Return the equality operator that the subquery uses to group rows on + * the given output column, or InvalidOid if the column doesn't + * participate in any grouping mechanism. + * + * A subquery output column is grouping-relevant if it appears in + * subquery->distinctClause (covering both DISTINCT and DISTINCT ON), in every + * window's PARTITION BY clause, or is grouped by some node in a set-operation + * tree. In all of these cases the parser builds the SortGroupClause with the + * column's type-default equality operator via get_sort_group_operators, so any + * matching SortGroupClause carries the correct eqop. + */ +static Oid +subquery_column_grouping_eqop(Query *subquery, AttrNumber attno) +{ + TargetEntry *tle; + ListCell *lc; + + if (attno <= 0 || attno > list_length(subquery->targetList)) + return InvalidOid; + + tle = list_nth_node(TargetEntry, subquery->targetList, attno - 1); + + /* DISTINCT or DISTINCT ON */ + foreach(lc, subquery->distinctClause) + { + SortGroupClause *sgc = lfirst_node(SortGroupClause, lc); + + if (sgc->tleSortGroupRef == tle->ressortgroupref) + return sgc->eqop; + } + + /* Window function PARTITION BY: must appear in every window's list. */ + if (subquery->hasWindowFuncs && subquery->windowClause != NIL) + { + Oid eqop = InvalidOid; + + foreach(lc, subquery->windowClause) + { + WindowClause *wc = (WindowClause *) lfirst(lc); + ListCell *lc2; + + foreach(lc2, wc->partitionClause) + { + SortGroupClause *sgc = lfirst_node(SortGroupClause, lc2); + + if (sgc->tleSortGroupRef == tle->ressortgroupref) + break; + } + if (lc2 == NULL) + break; /* not present in this window's list */ + eqop = lfirst_node(SortGroupClause, lc2)->eqop; + } + if (lc == NULL) + return eqop; /* matched in every window */ + } + + /* Set operation */ + if (subquery->setOperations != NULL) + return setop_column_grouping_eqop(subquery->setOperations, attno); + + return InvalidOid; +} + +/* + * setop_column_grouping_eqop + * Recursively search a SetOperationStmt tree for any node that groups + * rows by equality, and return the equality operator used for the given + * output column. Returns InvalidOid if no node in the tree groups (i.e., + * an entirely-UNION-ALL tree). + * + * For any set operation other than UNION ALL, groupClauses is a positional + * list of SortGroupClauses, with element N-1 corresponding to output column N + * (see makeSortGroupClauseForSetOp). + */ +static Oid +setop_column_grouping_eqop(Node *setop, AttrNumber attno) +{ + SetOperationStmt *op; + Oid eqop; + + if (setop == NULL || !IsA(setop, SetOperationStmt)) + return InvalidOid; + + op = (SetOperationStmt *) setop; + + if (op->groupClauses != NIL && + attno >= 1 && attno <= list_length(op->groupClauses)) + { + SortGroupClause *sgc = list_nth_node(SortGroupClause, + op->groupClauses, attno - 1); + + return sgc->eqop; + } + + /* Recurse into children to find any inner grouping */ + eqop = setop_column_grouping_eqop(op->larg, attno); + if (OidIsValid(eqop)) + return eqop; + return setop_column_grouping_eqop(op->rarg, attno); +} + +/* + * setop_has_grouping + * Return true if any node in the SetOperationStmt tree groups rows by + * equality (i.e., has non-NIL groupClauses). + */ +static bool +setop_has_grouping(Node *setop) +{ + SetOperationStmt *op; + + if (setop == NULL || !IsA(setop, SetOperationStmt)) + return false; + + op = (SetOperationStmt *) setop; + if (op->groupClauses != NIL) + return true; + + return setop_has_grouping(op->larg) || setop_has_grouping(op->rarg); +} + /* * subquery_push_qual - push down a qual that we have determined is safe */ diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 846bd7c1fbe..cac2ebb86c6 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -135,26 +135,21 @@ typedef struct } standard_qp_extra; /* - * Context for the find_having_collation_conflicts walker. - * - * ancestor_collids is a stack of inputcollids contributed by collation-aware - * ancestors of the current node. Entries are pushed before recursing into a - * node's children and popped afterwards, so the stack reflects exactly the - * inputcollids on the current root-to-node path. + * Context for find_having_conflicts. This is the callback context passed to + * expression_has_grouping_conflict in clauses.c. */ typedef struct { + Query *parse; Index group_rtindex; - List *ancestor_collids; -} having_collation_ctx; +} having_grouping_ctx; /* Local functions */ static Node *preprocess_expression(PlannerInfo *root, Node *expr, int kind); static void preprocess_qual_conditions(PlannerInfo *root, Node *jtnode); -static Bitmapset *find_having_collation_conflicts(Query *parse, - Index group_rtindex); -static bool having_collation_conflict_walker(Node *node, - having_collation_ctx *ctx); +static Bitmapset *find_having_conflicts(Query *parse, Index group_rtindex); +static Oid having_var_grouping_eqop(Var *var, void *context); +static Oid group_var_eqop(Query *parse, Var *var); static void grouping_planner(PlannerInfo *root, double tuple_fraction, SetOperationStmt *setops); static grouping_sets_data *preprocess_grouping_sets(PlannerInfo *root); @@ -780,7 +775,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, PlannerInfo *root; List *newWithCheckOptions; List *newHaving; - Bitmapset *havingCollationConflicts; + Bitmapset *havingPushdownConflicts; int havingIdx; bool hasOuterJoins; bool hasResultRTEs; @@ -1208,25 +1203,14 @@ subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, } /* - * Before we flatten GROUP Vars, check which HAVING clauses have collation - * conflicts. When GROUP BY uses a nondeterministic collation, values - * that are "equal" for grouping may be distinguishable under a different - * collation. If such a HAVING clause were moved to WHERE, it would - * filter individual rows before grouping, potentially eliminating some - * members of a group and thereby changing aggregate results. - * - * We do this check before flatten_group_exprs because we can easily - * identify grouping expressions by checking whether a Var references - * RTE_GROUP, and such Vars directly carry the GROUP BY collation as their - * varcollid. After flattening, these Vars are replaced by the underlying - * expressions, and we would have to match expressions in the HAVING - * clause back to grouping expressions, which is much more complex. + * Before we flatten GROUP Vars, identify HAVING clauses whose equality + * semantics disagree with the GROUP BY's. See find_having_conflicts. */ if (parse->hasGroupRTE) - havingCollationConflicts = - find_having_collation_conflicts(parse, root->group_rtindex); + havingPushdownConflicts = find_having_conflicts(parse, + root->group_rtindex); else - havingCollationConflicts = NULL; + havingPushdownConflicts = NULL; /* * Replace any Vars in the subquery's targetlist and havingQual that @@ -1272,13 +1256,13 @@ subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, * but it's okay: it's just an optimization to avoid running pull_varnos * when there cannot be any Vars in the HAVING clause.) * - * We also cannot do this if the HAVING clause uses a different collation - * than the GROUP BY for any grouping expression whose GROUP BY collation - * is nondeterministic. This is detected before flatten_group_exprs (see - * find_having_collation_conflicts above) and recorded in the - * havingCollationConflicts bitmapset. The bitmapset indexes remain valid - * here because flatten_group_exprs uses expression_tree_mutator, which - * preserves the list length and ordering of havingQual. + * We also cannot do this for HAVING clauses that conflict with GROUP BY + * on collation or operator family. Both kinds of conflict are detected + * before flatten_group_exprs (see find_having_conflicts above) and + * recorded in the havingPushdownConflicts bitmapset. The bitmapset + * indexes remain valid here because flatten_group_exprs uses + * expression_tree_mutator, which preserves the list length and ordering + * of havingQual. * * Also, it may be that the clause is so expensive to execute that we're * better off doing it only once per group, despite the loss of @@ -1320,7 +1304,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, if (contain_agg_clause(havingclause) || contain_volatile_functions(havingclause) || contain_subplans(havingclause) || - bms_is_member(havingIdx, havingCollationConflicts) || + bms_is_member(havingIdx, havingPushdownConflicts) || (parse->groupClause && parse->groupingSets && bms_is_member(root->group_rtindex, pull_varnos(root, havingclause)))) { @@ -1551,192 +1535,99 @@ preprocess_qual_conditions(PlannerInfo *root, Node *jtnode) } /* - * find_having_collation_conflicts - * Identify HAVING clauses that must not be moved to WHERE due to collation - * mismatches with GROUP BY. + * find_having_conflicts + * Identify HAVING clauses that must not be moved to WHERE because they + * apply a different equivalence relation than GROUP BY. Pushing such a + * clause to WHERE would filter individual rows before grouping happens, + * eliminating rows that GROUP BY would have merged into a single group + * and thereby changing aggregate results. + * + * The actual walking is done by expression_has_grouping_conflict; see that + * function for the kinds of conflict it looks for. We just iterate over + * havingQual and supply a HAVING-specific callback that identifies GROUP + * Vars. * * This must be called before flatten_group_exprs, while the HAVING clause * still contains GROUP Vars (Vars referencing RTE_GROUP). These GROUP Vars - * carry the GROUP BY collation as their varcollid. A GROUP Var with a - * nondeterministic varcollid conflicts whenever some collation-aware ancestor - * on its path applies a different inputcollid: that operator would distinguish - * values which the GROUP BY considers equal, so the clause is unsafe to push - * to WHERE. + * carry the GROUP BY collation as their varcollid and let us recover the + * grouping eqop via varattno. After flattening, those Vars are replaced by + * the underlying expressions, and matching back to grouping expressions is + * much harder. * * Returns a Bitmapset of zero-based indexes into the havingQual list for - * clauses that have collation conflicts and must stay in HAVING. + * clauses that conflict and must stay in HAVING. */ static Bitmapset * -find_having_collation_conflicts(Query *parse, Index group_rtindex) +find_having_conflicts(Query *parse, Index group_rtindex) { Bitmapset *result = NULL; - having_collation_ctx ctx; + having_grouping_ctx ctx; int idx; if (parse->havingQual == NULL) return NULL; + ctx.parse = parse; ctx.group_rtindex = group_rtindex; - ctx.ancestor_collids = NIL; idx = 0; foreach_ptr(Node, clause, (List *) parse->havingQual) { - if (having_collation_conflict_walker(clause, &ctx)) + if (expression_has_grouping_conflict(clause, having_var_grouping_eqop, + &ctx)) result = bms_add_member(result, idx); idx++; - Assert(ctx.ancestor_collids == NIL); } return result; } /* - * Walker function for find_having_collation_conflicts. - * - * Walk the clause top-down, maintaining a stack of inputcollids contributed - * by collation-aware ancestors. At each GROUP Var with a nondeterministic - * varcollid, the clause has a conflict if any ancestor's inputcollid differs - * from the GROUP Var's varcollid. Most collation-aware nodes expose their - * inputcollid through exprInputCollation(). Two structural exceptions need - * special handling: - * - * - RowCompareExpr carries one inputcollid per column in inputcollids[], so we - * descend into its (largs[i], rargs[i]) pairs explicitly with the matching - * collation pushed onto the stack. - * - * - A simple CASE (CaseExpr with a non-NULL arg) holds the arg outside the - * WHEN's OpExpr, even though the WHEN's OpExpr is the place where the - * comparison's inputcollid lives. Parse analysis builds each WHEN as - * "OpExpr(CaseTestExpr op val)" -- the CaseTestExpr is a placeholder for - * the arg. Before walking cexpr->arg we therefore push every WHEN's - * inputcollid onto the ancestor stack, so a GROUP Var at the arg is - * checked against the same collations the WHEN comparisons would apply. - * The WHEN bodies and defresult are then walked under the unchanged stack - * so their own collation contexts are picked up by the default path. + * having_var_grouping_eqop + * grouping_eqop_callback for find_having_conflicts. + * + * Returns the GROUP BY equality operator for 'var' if it references the + * query's RTE_GROUP, or InvalidOid otherwise. */ -static bool -having_collation_conflict_walker(Node *node, having_collation_ctx *ctx) +static Oid +having_var_grouping_eqop(Var *var, void *context) { - Oid this_collid; - bool result; - - if (node == NULL) - return false; - - if (IsA(node, Var)) - { - Var *var = (Var *) node; - - /* We should not see any upper-level Vars here */ - Assert(var->varlevelsup == 0); - - if (var->varno == ctx->group_rtindex && - OidIsValid(var->varcollid) && - !get_collation_isdeterministic(var->varcollid)) - { - foreach_oid(collid, ctx->ancestor_collids) - { - if (collid != var->varcollid) - return true; - } - } - return false; - } + having_grouping_ctx *ctx = (having_grouping_ctx *) context; - if (IsA(node, RowCompareExpr)) - { - RowCompareExpr *rcexpr = (RowCompareExpr *) node; - ListCell *lc_l; - ListCell *lc_r; - ListCell *lc_c; + if (var->varno != ctx->group_rtindex || var->varlevelsup != 0) + return InvalidOid; - /* - * Each column of a row comparison is compared under its own - * inputcollids[i]. Walk each (largs[i], rargs[i]) pair with that - * collation pushed, so a Var in column i is checked against the - * collation that actually applies to it. - */ - forthree(lc_l, rcexpr->largs, - lc_r, rcexpr->rargs, - lc_c, rcexpr->inputcollids) - { - Oid collid = lfirst_oid(lc_c); - bool found; - - if (OidIsValid(collid)) - ctx->ancestor_collids = lappend_oid(ctx->ancestor_collids, - collid); - - found = having_collation_conflict_walker((Node *) lfirst(lc_l), - ctx) || - having_collation_conflict_walker((Node *) lfirst(lc_r), - ctx); + return group_var_eqop(ctx->parse, var); +} - if (OidIsValid(collid)) - ctx->ancestor_collids = - list_delete_last(ctx->ancestor_collids); +/* + * group_var_eqop + * Return the equality operator that GROUP BY uses for the given GROUP Var. + * + * A GROUP Var's varattno is its 1-based position in the RTE_GROUP's groupexprs + * list, which addRangeTableEntryForGroup built by iterating parse->groupClause + * and including every SortGroupClause whose TLE was present in the targetlist. + * Replay that traversal here to recover the SortGroupClause for the given + * varattno. + */ +static Oid +group_var_eqop(Query *parse, Var *var) +{ + int counter = 0; - if (found) - return true; - } - return false; - } + Assert(var->varlevelsup == 0); - if (IsA(node, CaseExpr) && ((CaseExpr *) node)->arg != NULL) + foreach_node(SortGroupClause, sgc, parse->groupClause) { - CaseExpr *cexpr = (CaseExpr *) node; - int saved_len = list_length(ctx->ancestor_collids); - bool found; - - /* - * Push every WHEN's inputcollid before walking cexpr->arg, since each - * WHEN implicitly compares the arg under that inputcollid. - */ - foreach_node(CaseWhen, cw, cexpr->args) - { - Oid collid = exprInputCollation((Node *) cw->expr); - - if (OidIsValid(collid)) - ctx->ancestor_collids = lappend_oid(ctx->ancestor_collids, - collid); - } - - found = having_collation_conflict_walker((Node *) cexpr->arg, ctx); - - ctx->ancestor_collids = list_truncate(ctx->ancestor_collids, - saved_len); - - if (found) - return true; - - /* - * Walk the WHEN bodies and defresult under the unchanged ancestor - * stack; any inputcollids inside them are picked up by the default - * path. - */ - foreach_node(CaseWhen, cw, cexpr->args) - { - if (having_collation_conflict_walker((Node *) cw->expr, ctx) || - having_collation_conflict_walker((Node *) cw->result, ctx)) - return true; - } - return having_collation_conflict_walker((Node *) cexpr->defresult, - ctx); + if (get_sortgroupclause_tle(sgc, parse->targetList) == NULL) + continue; + if (++counter == var->varattno) + return sgc->eqop; } - this_collid = exprInputCollation(node); - if (OidIsValid(this_collid)) - ctx->ancestor_collids = lappend_oid(ctx->ancestor_collids, - this_collid); - - result = expression_tree_walker(node, having_collation_conflict_walker, - ctx); - - if (OidIsValid(this_collid)) - ctx->ancestor_collids = list_delete_last(ctx->ancestor_collids); - - return result; + elog(ERROR, "could not find GROUP clause for GROUP Var attno %d", + var->varattno); + return InvalidOid; /* keep compiler quiet */ } /* diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 01997e22266..aa8886ec210 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -100,6 +100,17 @@ typedef struct List *safe_param_ids; /* PARAM_EXEC Param IDs to treat as safe */ } max_parallel_hazard_context; +/* + * Walker context for expression_has_grouping_conflict. get_eqop is a callback + * that returns the equality operator used for grouping. cb_context is opaque + * to the walker and is forwarded to get_eqop unchanged. + */ +typedef struct +{ + grouping_eqop_callback get_eqop; + void *cb_context; +} grouping_walker_ctx; + static bool contain_agg_clause_walker(Node *node, void *context); static bool find_window_functions_walker(Node *node, WindowFuncLists *lists); static bool contain_subplans_walker(Node *node, void *context); @@ -118,6 +129,11 @@ static List *find_nonnullable_vars_walker(Node *node, bool top_level); static void find_subquery_safe_quals(Node *jtnode, List **safe_quals); static bool is_strict_saop(ScalarArrayOpExpr *expr, bool falseOK); static bool convert_saop_to_hashed_saop_walker(Node *node, void *context); +static bool grouping_conflict_walker(Node *node, grouping_walker_ctx *ctx); +static bool grouping_check_operands(Oid opno, Oid inputcollid, + List *args, grouping_walker_ctx *ctx); +static bool grouping_check_operand(Node *arg, Oid opno, Oid inputcollid, + grouping_walker_ctx *ctx); static Node *eval_const_expressions_mutator(Node *node, eval_const_expressions_context *context); static bool contain_non_const_walker(Node *node, void *context); @@ -6264,6 +6280,258 @@ pull_paramids_walker(Node *node, Bitmapset **context) return expression_tree_walker(node, pull_paramids_walker, context); } +/* + * expression_has_grouping_conflict + * Detect whether 'expr' would distinguish rows that a grouping mechanism + * (GROUP BY, DISTINCT, DISTINCT ON, window PARTITION BY, or set operation) + * considers equal. + * + * The caller supplies a get_eqop callback (see clauses.h) so the same walker + * serves every grouping context. The callback identifies a grouping column by + * returning a valid eqop for its Var. A grouping column is safe to reference + * only if the reference yields the same result for every value the grouping + * treats as equal. Otherwise, pushing the clause past the grouping could + * discard rows that the grouping would have combined into a single group. + * + * The reference is provably safe only when the grouping column is a direct + * operand of a comparison that tests the grouping's own equality. Such an + * operand is rejected when the comparison's operator does not have equality + * semantics compatible with the grouping eqop, or, for a nondeterministic + * collation, when the comparison applies a collation other than the column's. + * + * For a nondeterministic collation, every other reference is rejected: a + * comparison under a different collation, and any function or operator over + * the column, because we cannot tell whether the function yields the same + * result for values the grouping treats as equal, and many do not. A column + * with a deterministic collation is not restricted this way. + * + * This leaves one case uncaught: with a deterministic collation, a function + * over the column can still feed a finer comparison than the direct-operand + * check sees, for example record_image_ops over a rebuilt record, or scale() + * over numeric where two equal values differ in scale. Catching it would + * require knowing that a type's equality is bitwise, which we do not test + * here. + * + * Returns true if any such conflict exists. + */ +bool +expression_has_grouping_conflict(Node *expr, + grouping_eqop_callback get_eqop, + void *context) +{ + grouping_walker_ctx ctx; + + if (expr == NULL) + return false; + + ctx.get_eqop = get_eqop; + ctx.cb_context = context; + + return grouping_conflict_walker(expr, &ctx); +} + +/* + * Walker function for expression_has_grouping_conflict. + * + * A comparison node checks its direct operands with grouping_check_operand, + * which does not recurse into a grouping-column operand. A grouping column + * therefore reaches the Var branch only when it is referenced in some other + * way: wrapped in a function or other expression, used as the whole qual (a + * bare boolean column), or used as an operand of an operator that is not a + * btree/hash member and so is not treated as a comparison here. + * + * Comparison nodes are OpExpr/ScalarArrayOpExpr whose operator is a btree/hash + * member, and RowCompareExpr (one operator and collation per column). A + * simple CASE (CaseExpr with a non-NULL arg) is a comparison in disguise: + * parse analysis builds each WHEN as "OpExpr(CaseTestExpr op val)", with the + * CaseTestExpr standing in for the arg, so the arg is effectively an operand + * of each WHEN's comparison. Those WHEN operators are always the type-default + * "=", matching the grouping eqop, so only a collation conflict is possible + * there. + */ +static bool +grouping_conflict_walker(Node *node, grouping_walker_ctx *ctx) +{ + if (node == NULL) + return false; + + if (IsA(node, Var)) + { + Var *var = (Var *) node; + + /* + * A grouping column reaches here when it was not handled as a direct + * operand by a comparison node above (see the function header). That + * is safe for a deterministic collation, but not for a + * nondeterministic one, where the reference may distinguish values + * the grouping considers equal. A bare boolean qual is safe too: + * boolean is not collatable, so it takes the deterministic path here. + */ + if (OidIsValid(ctx->get_eqop(var, ctx->cb_context)) && + OidIsValid(var->varcollid) && + !get_collation_isdeterministic(var->varcollid)) + return true; + return false; + } + else if (IsA(node, OpExpr)) + { + OpExpr *opexpr = (OpExpr *) node; + + if (op_is_safe_index_member(opexpr->opno)) + return grouping_check_operands(opexpr->opno, opexpr->inputcollid, + opexpr->args, ctx); + /* fall through */ + } + else if (IsA(node, ScalarArrayOpExpr)) + { + ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) node; + + if (op_is_safe_index_member(saop->opno)) + return grouping_check_operands(saop->opno, saop->inputcollid, + saop->args, ctx); + /* fall through */ + } + else if (IsA(node, RowCompareExpr)) + { + RowCompareExpr *rcexpr = (RowCompareExpr *) node; + ListCell *lc_l; + ListCell *lc_r; + ListCell *lc_o; + ListCell *lc_c; + + /* Each column is compared under its own operator and inputcollid. */ + forfour(lc_l, rcexpr->largs, + lc_r, rcexpr->rargs, + lc_o, rcexpr->opnos, + lc_c, rcexpr->inputcollids) + { + Oid opno = lfirst_oid(lc_o); + Oid collid = lfirst_oid(lc_c); + + if (grouping_check_operand((Node *) lfirst(lc_l), opno, collid, ctx) || + grouping_check_operand((Node *) lfirst(lc_r), opno, collid, ctx)) + return true; + } + return false; + } + else if (IsA(node, CaseExpr) && ((CaseExpr *) node)->arg != NULL) + { + CaseExpr *cexpr = (CaseExpr *) node; + Node *arg = (Node *) cexpr->arg; + + /* Look through RelabelType to find a direct Var arg. */ + while (arg && IsA(arg, RelabelType)) + arg = (Node *) ((RelabelType *) arg)->arg; + + if (arg && IsA(arg, Var)) + { + Var *var = (Var *) arg; + + /* + * The arg is a grouping column compared by every WHEN. For a + * nondeterministic collation, reject if any WHEN applies a + * different collation. + */ + if (OidIsValid(ctx->get_eqop(var, ctx->cb_context)) && + OidIsValid(var->varcollid) && + !get_collation_isdeterministic(var->varcollid)) + { + foreach_node(CaseWhen, cw, cexpr->args) + { + Oid collid = exprInputCollation((Node *) cw->expr); + + if (OidIsValid(collid) && collid != var->varcollid) + return true; + } + } + } + else if (grouping_conflict_walker((Node *) cexpr->arg, ctx)) + { + /* arg is a complex expression; walked as a non-operand */ + return true; + } + + /* + * Walk the WHEN conditions, their results, and the default result as + * non-operands. The WHEN conditions hold a CaseTestExpr in place of + * the arg, so they contribute no grouping operand of their own, but + * the condition expression or the substitution result may reference + * another grouping column. + */ + foreach_node(CaseWhen, cw, cexpr->args) + { + if (grouping_conflict_walker((Node *) cw->expr, ctx) || + grouping_conflict_walker((Node *) cw->result, ctx)) + return true; + } + return grouping_conflict_walker((Node *) cexpr->defresult, ctx); + } + + return expression_tree_walker(node, grouping_conflict_walker, ctx); +} + +/* + * grouping_check_operands + * Check every argument of a comparison node as a direct operand of the + * comparison's operator 'opno' and collation 'inputcollid'. + */ +static bool +grouping_check_operands(Oid opno, Oid inputcollid, List *args, + grouping_walker_ctx *ctx) +{ + ListCell *lc; + + foreach(lc, args) + { + if (grouping_check_operand((Node *) lfirst(lc), opno, inputcollid, ctx)) + return true; + } + return false; +} + +/* + * grouping_check_operand + * Handle one operand 'arg' of a comparison with operator 'opno' and + * collation 'inputcollid'. + * + * If 'arg' is a grouping column (after looking through RelabelType), verify + * that comparison's operator has equality semantics compatible with the + * grouping eqop and, for a nondeterministic collation, that it uses the same + * collation; such a direct operand is then fully handled and is not recursed + * into. Any other operand is walked normally, so a grouping column buried + * inside it is seen as a non-operand reference. + */ +static bool +grouping_check_operand(Node *arg, Oid opno, Oid inputcollid, + grouping_walker_ctx *ctx) +{ + Node *node = arg; + + while (node && IsA(node, RelabelType)) + node = (Node *) ((RelabelType *) node)->arg; + + if (node && IsA(node, Var)) + { + Var *var = (Var *) node; + Oid grouping_eqop = ctx->get_eqop(var, ctx->cb_context); + + if (OidIsValid(grouping_eqop)) + { + /* incompatible equality semantics */ + if (!equality_ops_are_compatible(opno, grouping_eqop)) + return true; + /* nondeterministic collation compared under a different collation */ + if (OidIsValid(var->varcollid) && + !get_collation_isdeterministic(var->varcollid) && + inputcollid != var->varcollid) + return true; + } + return false; /* direct operand handled; do not recurse */ + } + + return grouping_conflict_walker(arg, ctx); +} + /* * Build ScalarArrayOpExpr on top of 'exprs.' 'haveNonConst' indicates * whether at least one of the expressions is not Const. When it's false, diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 036de5f79ef..cc6f05a0aa7 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -820,15 +820,22 @@ get_op_index_interpretation(Oid opno) /* * equality_ops_are_compatible - * Return true if the two given equality operators have compatible + * Return true if the two given operators have compatible equality * semantics. * * This is trivially true if they are the same operator. Otherwise, * we look to see if they both belong to an opfamily that guarantees * compatible semantics for equality. Either finding allows us to assume - * that they have compatible notions of equality. (The reason we need - * to do these pushups is that one might be a cross-type operator; for - * instance int24eq vs int4eq.) + * that they have compatible notions of equality. + * + * The typical use is to compare two equality operators (for instance the + * cross-type operators int24eq vs int4eq), but the test is meaningful for + * any pair of operators in a btree/hash opfamily. Btree marks its + * opfamilies as amconsistentequality, which guarantees that every member + * of the family (=, <, <=, >, >=) agrees on the equivalence relation + * defined by the family's "=". So a non-equality operator and an + * equality operator from the same opfamily are also "compatible" in this + * sense. */ bool equality_ops_are_compatible(Oid opno1, Oid opno2) @@ -963,10 +970,11 @@ collations_agree_on_equality(Oid coll1, Oid coll2) * op_is_safe_index_member * Check if the operator is a member of a B-tree or Hash operator family. * - * We use this check as a proxy for "null-safety": if an operator is trusted by - * the btree or hash opfamily, it implies that the operator adheres to standard - * boolean behavior, and would not return NULL when given valid non-null - * inputs, as doing so would break index integrity. + * Membership in such an opfamily has several useful implications: the operator + * returns non-null for non-null inputs (i.e. "null-safety", required so that + * the operator doesn't break index integrity), and it agrees with other + * members of the same opfamily on equality semantics. Callers use this check + * as a proxy for any of those properties. */ bool op_is_safe_index_member(Oid opno) diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h index 853a28c0007..0e5a7b07404 100644 --- a/src/include/optimizer/clauses.h +++ b/src/include/optimizer/clauses.h @@ -23,6 +23,16 @@ typedef struct List **windowFuncs; /* lists of WindowFuncs for each winref */ } WindowFuncLists; +/* + * Callback used by expression_has_grouping_conflict below. Given a Var, the + * callback returns the equality operator that the relevant grouping mechanism + * (GROUP BY, DISTINCT, DISTINCT ON, window PARTITION BY, or set operation) + * uses for the column the Var references, or InvalidOid if the Var does not + * participate in that grouping. Returning InvalidOid signals "not a grouping + * column" to both the opfamily and collation checks. + */ +typedef Oid (*grouping_eqop_callback) (Var *var, void *context); + extern bool contain_agg_clause(Node *clause); extern bool contain_window_function(Node *clause); @@ -56,4 +66,8 @@ extern Query *inline_function_in_from(PlannerInfo *root, extern Bitmapset *pull_paramids(Expr *expr); +extern bool expression_has_grouping_conflict(Node *expr, + grouping_eqop_callback get_eqop, + void *context); + #endif /* CLAUSES_H */ diff --git a/src/test/regress/expected/aggregates.out b/src/test/regress/expected/aggregates.out index 89e051ee824..728a3ecd03f 100644 --- a/src/test/regress/expected/aggregates.out +++ b/src/test/regress/expected/aggregates.out @@ -1675,17 +1675,26 @@ explain (costs off) select y,z from t2 group by y,z; -> Seq Scan on t2 (3 rows) +drop table t1 cascade; +NOTICE: drop cascades to table t1c +drop table t2; +drop table t3; +drop table p_t1; +-- A composite type used by the tests below to exercise the asymmetry +-- between record_ops (per-field equality, the default) and record_image_ops +-- (bytewise equality): values like row(1.0) and row(1.00) are field-equal +-- but byte-distinct. +create type avg_rec as (x numeric); -- A unique index proves uniqueness only under its own opfamily. When the -- GROUP BY's eqop comes from a different opfamily with looser equality, -- rows the index regards as distinct can collapse into one GROUP BY group, -- so the index is not usable for removing redundant columns. -create type t_rec as (x numeric); -create temp table t_opf (a t_rec not null, b text); +create temp table t_opf (a avg_rec not null, b text); create unique index on t_opf (a record_image_ops); -- (1.0) and (1.00) are bytewise distinct but logically equal as records; -- the index admits both, but GROUP BY a (default record_ops) would merge -- them, so b must be retained as a grouping key. -insert into t_opf values (row(1.0)::t_rec, 'X'), (row(1.00)::t_rec, 'Y'); +insert into t_opf values (row(1.0)::avg_rec, 'X'), (row(1.00)::avg_rec, 'Y'); explain (costs off) select a, b from t_opf group by a, b order by b; QUERY PLAN @@ -1705,12 +1714,65 @@ select a, b from t_opf group by a, b order by b; (2 rows) drop table t_opf; -drop type t_rec; -drop table t1 cascade; -NOTICE: drop cascades to table t1c -drop table t2; -drop table t3; -drop table p_t1; +-- A HAVING clause that uses an equality operator from a different opfamily +-- than the GROUP BY's eqop must NOT be pushed down to WHERE. +create temp table t_having (id int, a avg_rec); +insert into t_having values + (1, row(1.0)::avg_rec), + (2, row(1.00)::avg_rec), + (3, row(2)::avg_rec); +-- the clause must stay in HAVING +explain (costs off) +select a, count(*) from t_having group by a having a *= row(1.0)::avg_rec; + QUERY PLAN +----------------------------------- + HashAggregate + Group Key: a + Filter: (a *= '(1.0)'::avg_rec) + -> Seq Scan on t_having +(4 rows) + +select a, count(*) from t_having group by a having a *= row(1.0)::avg_rec; + a | count +-------+------- + (1.0) | 2 +(1 row) + +-- the clause must stay in HAVING +explain (costs off) +select a, count(*) from t_having group by a having a *= any (array[row(1.0)::avg_rec]); + QUERY PLAN +--------------------------------------------- + HashAggregate + Group Key: a + Filter: (a *= ANY ('{(1.0)}'::avg_rec[])) + -> Seq Scan on t_having +(4 rows) + +select a, count(*) from t_having group by a having a *= any (array[row(1.0)::avg_rec]); + a | count +-------+------- + (1.0) | 2 +(1 row) + +-- the clause can be pushed down to WHERE +explain (costs off) +select a, count(*) from t_having group by a having a = row(1.0)::avg_rec; + QUERY PLAN +---------------------------------------- + GroupAggregate + -> Seq Scan on t_having + Filter: (a = '(1.0)'::avg_rec) +(3 rows) + +select a, count(*) from t_having group by a having a = row(1.0)::avg_rec; + a | count +-------+------- + (1.0) | 2 +(1 row) + +drop table t_having; +drop type avg_rec; -- -- Test GROUP BY ALL -- diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out index 04e2f6df037..cf2c55ba92e 100644 --- a/src/test/regress/expected/collate.icu.utf8.out +++ b/src/test/regress/expected/collate.icu.utf8.out @@ -2122,7 +2122,7 @@ SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensi abc | 2 (1 row) --- Negative: function applied to grouped column with conflicting collation +-- Negative: function over the grouping column, conflicting collation EXPLAIN (COSTS OFF) SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_sensitive; QUERY PLAN @@ -2139,18 +2139,36 @@ SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_ abc | 2 (1 row) --- Positive: function with same collation as GROUP BY +-- Negative: function over the grouping column whose result is compared as an +-- integer, under no collation +EXPLAIN (COSTS OFF) +SELECT x, count(*) FROM test3ci GROUP BY x HAVING ascii(x) = 97; + QUERY PLAN +--------------------------- + HashAggregate + Group Key: x + Filter: (ascii(x) = 97) + -> Seq Scan on test3ci +(4 rows) + +SELECT x, count(*) FROM test3ci GROUP BY x HAVING ascii(x) = 97; + x | count +-----+------- + abc | 2 +(1 row) + +-- Negative: a function wrapping the grouping column is not provably safe even +-- when compared under the matching collation, since the function need not +-- preserve the collation's equality EXPLAIN (COSTS OFF) SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_insensitive; - QUERY PLAN -------------------------------------------------------------------------- - GroupAggregate + QUERY PLAN +------------------------------------------------------------- + HashAggregate Group Key: x - -> Sort - Sort Key: x COLLATE case_insensitive - -> Seq Scan on test3ci - Filter: (upper(x) = 'ABC'::text COLLATE case_insensitive) -(6 rows) + Filter: (upper(x) = 'ABC'::text COLLATE case_insensitive) + -> Seq Scan on test3ci +(4 rows) SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_insensitive; x | count @@ -2158,8 +2176,8 @@ SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_ abc | 2 (1 row) --- Negative: inner function has conflicting collation, even though outer --- operator's collation matches GROUP BY due to a COLLATE override +-- Negative: same, with the grouping column wrapped in a function whose input +-- collation is overridden; still not a direct operand, so it stays in HAVING EXPLAIN (COSTS OFF) SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x COLLATE case_sensitive) COLLATE case_insensitive = 'ABC'; QUERY PLAN @@ -2178,17 +2196,17 @@ SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x COLLATE case_sensitive -- Mixed AND: conflicting clause stays in HAVING, safe clause pushed to WHERE EXPLAIN (COSTS OFF) -SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive AND length(x) > 1; - QUERY PLAN ----------------------------------------------------- +SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive AND x >= 'a' COLLATE case_insensitive; + QUERY PLAN +----------------------------------------------------------- HashAggregate Group Key: x Filter: (x = 'abc'::text COLLATE case_sensitive) -> Seq Scan on test3ci - Filter: (length(x) > 1) + Filter: (x >= 'a'::text COLLATE case_insensitive) (5 rows) -SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive AND length(x) > 1; +SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive AND x >= 'a' COLLATE case_insensitive; x | count -----+------- abc | 2 @@ -2196,15 +2214,15 @@ SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensiti -- Positive: AND of two safe clauses, both can be pushed EXPLAIN (COSTS OFF) -SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive AND length(x) > 1; - QUERY PLAN ----------------------------------------------------------------------------------- +SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive AND x >= 'a' COLLATE case_insensitive; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ GroupAggregate -> Seq Scan on test3ci - Filter: ((x = 'abc'::text COLLATE case_insensitive) AND (length(x) > 1)) + Filter: ((x >= 'a'::text COLLATE case_insensitive) AND (x = 'abc'::text COLLATE case_insensitive)) (3 rows) -SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive AND length(x) > 1; +SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive AND x >= 'a' COLLATE case_insensitive; x | count -----+------- abc | 2 @@ -2348,6 +2366,230 @@ SELECT x, count(*) FROM test3cs GROUP BY x HAVING x = 'abc' COLLATE case_insensi ABC | 1 (2 rows) +-- Test WHERE-pushdown past a grouping layer (DISTINCT, DISTINCT ON, window +-- PARTITION BY) when the qual applies a different collation than the +-- grouping column's nondeterministic collation. The qual would distinguish +-- rows the grouping considers equal, so it must NOT be pushed inside the +-- subquery. +CREATE TABLE pushdown_ci (id int, x text COLLATE case_insensitive); +INSERT INTO pushdown_ci VALUES (1, 'ABC'), (2, 'abc'), (3, 'def'); +-- DISTINCT ON: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT ON (x) id, x FROM pushdown_ci ORDER BY x, id) s +WHERE x = 'abc' COLLATE case_sensitive; + QUERY PLAN +-------------------------------------------------------------------------------- + Subquery Scan on s + Filter: (s.x = 'abc'::text COLLATE case_sensitive) + -> Unique + -> Sort + Sort Key: pushdown_ci.x COLLATE case_insensitive, pushdown_ci.id + -> Seq Scan on pushdown_ci +(6 rows) + +SELECT * FROM (SELECT DISTINCT ON (x) id, x FROM pushdown_ci ORDER BY x, id) s +WHERE x = 'abc' COLLATE case_sensitive; + id | x +----+--- +(0 rows) + +-- Window function PARTITION BY: conflict, qual stays outside the WindowAgg +EXPLAIN (COSTS OFF) +SELECT * FROM ( + SELECT id, x, count(*) OVER (PARTITION BY x) AS cnt FROM pushdown_ci +) s +WHERE x = 'abc' COLLATE case_sensitive; + QUERY PLAN +---------------------------------------------------------------- + Subquery Scan on s + Filter: (s.x = 'abc'::text COLLATE case_sensitive) + -> WindowAgg + Window: w1 AS (PARTITION BY pushdown_ci.x) + -> Sort + Sort Key: pushdown_ci.x COLLATE case_insensitive + -> Seq Scan on pushdown_ci +(7 rows) + +SELECT * FROM ( + SELECT id, x, count(*) OVER (PARTITION BY x) AS cnt FROM pushdown_ci +) s +WHERE x = 'abc' COLLATE case_sensitive; + id | x | cnt +----+-----+----- + 2 | abc | 2 +(1 row) + +-- Plain DISTINCT: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT x FROM pushdown_ci) s +WHERE x = 'abc' COLLATE case_sensitive; + QUERY PLAN +------------------------------------------------------ + Subquery Scan on s + Filter: (s.x = 'abc'::text COLLATE case_sensitive) + -> HashAggregate + Group Key: pushdown_ci.x + -> Seq Scan on pushdown_ci +(5 rows) + +SELECT * FROM (SELECT DISTINCT x FROM pushdown_ci) s +WHERE x = 'abc' COLLATE case_sensitive; + x +--- +(0 rows) + +-- Positive: matching collation, safe to push past the grouping +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT ON (x) id, x FROM pushdown_ci ORDER BY x, id) s +WHERE x = 'abc' COLLATE case_insensitive; + QUERY PLAN +------------------------------------------------------------------ + Limit + -> Sort + Sort Key: pushdown_ci.id + -> Seq Scan on pushdown_ci + Filter: (x = 'abc'::text COLLATE case_insensitive) +(5 rows) + +SELECT * FROM (SELECT DISTINCT ON (x) id, x FROM pushdown_ci ORDER BY x, id) s +WHERE x = 'abc' COLLATE case_insensitive; + id | x +----+----- + 1 | ABC +(1 row) + +-- Set operations: any operation other than UNION ALL groups rows by equality, +-- so the same collation-mismatch rules apply. +CREATE TABLE pushdown_ci2 (x text COLLATE case_insensitive); +INSERT INTO pushdown_ci2 VALUES ('abc'); +-- UNION: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT x FROM pushdown_ci UNION SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + QUERY PLAN +------------------------------------------------------ + Subquery Scan on s + Filter: (s.x = 'abc'::text COLLATE case_sensitive) + -> HashAggregate + Group Key: pushdown_ci.x + -> Append + -> Seq Scan on pushdown_ci + -> Seq Scan on pushdown_ci2 +(7 rows) + +SELECT * FROM (SELECT x FROM pushdown_ci UNION SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + x +--- +(0 rows) + +-- INTERSECT: same +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT x FROM pushdown_ci INTERSECT SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + QUERY PLAN +------------------------------------------------------ + Subquery Scan on s + Filter: (s.x = 'abc'::text COLLATE case_sensitive) + -> HashSetOp Intersect + -> Seq Scan on pushdown_ci + -> Seq Scan on pushdown_ci2 +(5 rows) + +SELECT * FROM (SELECT x FROM pushdown_ci INTERSECT SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + x +--- +(0 rows) + +-- INTERSECT ALL: still groups +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT x FROM pushdown_ci INTERSECT ALL SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + QUERY PLAN +------------------------------------------------------ + Subquery Scan on s + Filter: (s.x = 'abc'::text COLLATE case_sensitive) + -> HashSetOp Intersect All + -> Seq Scan on pushdown_ci + -> Seq Scan on pushdown_ci2 +(5 rows) + +SELECT * FROM (SELECT x FROM pushdown_ci INTERSECT ALL SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + x +--- +(0 rows) + +-- Negative: a function over a grouping column with a nondeterministic +-- collation, whose result is compared under no collation (an integer +-- comparison), can distinguish values the grouping considers equal. +-- PARTITION BY +EXPLAIN (COSTS OFF) +SELECT * FROM ( + SELECT id, x, count(*) OVER (PARTITION BY x) AS cnt FROM pushdown_ci +) s +WHERE ascii(x) = 97; + QUERY PLAN +---------------------------------------------------------------- + Subquery Scan on s + Filter: (ascii(s.x) = 97) + -> WindowAgg + Window: w1 AS (PARTITION BY pushdown_ci.x) + -> Sort + Sort Key: pushdown_ci.x COLLATE case_insensitive + -> Seq Scan on pushdown_ci +(7 rows) + +SELECT * FROM ( + SELECT id, x, count(*) OVER (PARTITION BY x) AS cnt FROM pushdown_ci +) s +WHERE ascii(x) = 97; + id | x | cnt +----+-----+----- + 2 | abc | 2 +(1 row) + +-- Same with DISTINCT +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT x FROM pushdown_ci) s WHERE ascii(x) = 97; + QUERY PLAN +------------------------------------- + Subquery Scan on s + Filter: (ascii(s.x) = 97) + -> HashAggregate + Group Key: pushdown_ci.x + -> Seq Scan on pushdown_ci +(5 rows) + +SELECT * FROM (SELECT DISTINCT x FROM pushdown_ci) s WHERE ascii(x) = 97; + x +--- +(0 rows) + +-- Same with Set operations +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT x FROM pushdown_ci UNION SELECT x FROM pushdown_ci2) s +WHERE ascii(x) = 97; + QUERY PLAN +-------------------------------------------- + Subquery Scan on s + Filter: (ascii(s.x) = 97) + -> HashAggregate + Group Key: pushdown_ci.x + -> Append + -> Seq Scan on pushdown_ci + -> Seq Scan on pushdown_ci2 +(7 rows) + +SELECT * FROM (SELECT x FROM pushdown_ci UNION SELECT x FROM pushdown_ci2) s +WHERE ascii(x) = 97; + x +--- +(0 rows) + +DROP TABLE pushdown_ci2; +DROP TABLE pushdown_ci; -- bpchar CREATE TABLE test1bpci (x char(3) COLLATE case_insensitive); CREATE TABLE test2bpci (x char(3) COLLATE case_insensitive); diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index a3778c23c34..20140f171af 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -2031,6 +2031,220 @@ NOTICE: x = 3, y = 0 drop function tattle(x int, y int); -- +-- check that an upper-level qual is not pushed down if its operator is from a +-- different btree opfamily than the subquery's grouping eqop +-- +BEGIN; +CREATE TYPE t_rec AS (x numeric); +CREATE TEMP TABLE pdt (id int, a t_rec); +INSERT INTO pdt VALUES + (1, ROW(1.00)::t_rec), + (2, ROW(1.0)::t_rec), + (3, ROW(2)::t_rec); +-- DISTINCT ON: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT ON (a) id, a FROM pdt ORDER BY a, id) s +WHERE a *= ROW(1.0)::t_rec; + QUERY PLAN +--------------------------------------- + Subquery Scan on s + Filter: (s.a *= '(1.0)'::t_rec) + -> Unique + -> Sort + Sort Key: pdt.a, pdt.id + -> Seq Scan on pdt +(6 rows) + +SELECT * FROM (SELECT DISTINCT ON (a) id, a FROM pdt ORDER BY a, id) s +WHERE a *= ROW(1.0)::t_rec; + id | a +----+--- +(0 rows) + +-- Window function PARTITION BY: conflict, qual stays outside the WindowAgg +EXPLAIN (COSTS OFF) +SELECT * FROM ( + SELECT id, a, count(*) OVER (PARTITION BY a) AS cnt FROM pdt +) s +WHERE a *= ROW(1.0)::t_rec; + QUERY PLAN +-------------------------------------------- + Subquery Scan on s + Filter: (s.a *= '(1.0)'::t_rec) + -> WindowAgg + Window: w1 AS (PARTITION BY pdt.a) + -> Sort + Sort Key: pdt.a + -> Seq Scan on pdt +(7 rows) + +SELECT * FROM ( + SELECT id, a, count(*) OVER (PARTITION BY a) AS cnt FROM pdt +) s +WHERE a *= ROW(1.0)::t_rec; + id | a | cnt +----+-------+----- + 2 | (1.0) | 2 +(1 row) + +-- Plain DISTINCT: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT a FROM pdt) s WHERE a *= ROW(1.0)::t_rec; + QUERY PLAN +----------------------------------- + Subquery Scan on s + Filter: (s.a *= '(1.0)'::t_rec) + -> HashAggregate + Group Key: pdt.a + -> Seq Scan on pdt +(5 rows) + +SELECT * FROM (SELECT DISTINCT a FROM pdt) s WHERE a *= ROW(1.0)::t_rec; + a +--- +(0 rows) + +-- Positive: compatible opfamily, safe to push past the grouping +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT ON (a) id, a FROM pdt ORDER BY a, id) s +WHERE a = ROW(1.0)::t_rec; + QUERY PLAN +-------------------------------------------- + Limit + -> Sort + Sort Key: pdt.id + -> Seq Scan on pdt + Filter: (a = '(1.0)'::t_rec) +(5 rows) + +SELECT * FROM (SELECT DISTINCT ON (a) id, a FROM pdt ORDER BY a, id) s +WHERE a = ROW(1.0)::t_rec; + id | a +----+-------- + 1 | (1.00) +(1 row) + +-- Set operations: any operation other than UNION ALL groups rows by equality, +-- so the same opfamily-mismatch rules apply. +CREATE TEMP TABLE u1 (a t_rec); +CREATE TEMP TABLE u2 (a t_rec); +INSERT INTO u1 VALUES (ROW(1.00)::t_rec), (ROW(1.0)::t_rec); +INSERT INTO u2 VALUES (ROW(1.0)::t_rec); +-- UNION: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT a FROM u1 UNION SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + QUERY PLAN +----------------------------------- + Subquery Scan on s + Filter: (s.a *= '(1.0)'::t_rec) + -> HashAggregate + Group Key: u1.a + -> Append + -> Seq Scan on u1 + -> Seq Scan on u2 +(7 rows) + +SELECT * FROM (SELECT a FROM u1 UNION SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + a +--- +(0 rows) + +-- INTERSECT: same +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT a FROM u1 INTERSECT SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + QUERY PLAN +----------------------------------- + Subquery Scan on s + Filter: (s.a *= '(1.0)'::t_rec) + -> HashSetOp Intersect + -> Seq Scan on u1 + -> Seq Scan on u2 +(5 rows) + +SELECT * FROM (SELECT a FROM u1 INTERSECT SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + a +--- +(0 rows) + +-- INTERSECT ALL: still groups +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT a FROM u1 INTERSECT ALL SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + QUERY PLAN +----------------------------------- + Subquery Scan on s + Filter: (s.a *= '(1.0)'::t_rec) + -> HashSetOp Intersect All + -> Seq Scan on u1 + -> Seq Scan on u2 +(5 rows) + +SELECT * FROM (SELECT a FROM u1 INTERSECT ALL SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + a +--- +(0 rows) + +-- UNION ALL of (UNION ...): an inner grouping node still exposes the +-- conflict to a qual pushed down through the outer UNION ALL. +EXPLAIN (COSTS OFF) +SELECT * FROM ( + (SELECT a FROM u1 UNION SELECT a FROM u2) + UNION ALL + SELECT a FROM u2 +) s +WHERE a *= ROW(1.0)::t_rec; + QUERY PLAN +---------------------------------------- + Subquery Scan on s + Filter: (s.a *= '(1.0)'::t_rec) + -> Append + -> HashAggregate + Group Key: u1.a + -> Append + -> Seq Scan on u1 + -> Seq Scan on u2 + -> Seq Scan on u2 u2_1 +(9 rows) + +SELECT * FROM ( + (SELECT a FROM u1 UNION SELECT a FROM u2) + UNION ALL + SELECT a FROM u2 +) s +WHERE a *= ROW(1.0)::t_rec; + a +------- + (1.0) +(1 row) + +-- UNION ALL only: no grouping anywhere, pushdown remains allowed. +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT a FROM u1 UNION ALL SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + QUERY PLAN +--------------------------------------- + Append + -> Seq Scan on u1 + Filter: (a *= '(1.0)'::t_rec) + -> Seq Scan on u2 + Filter: (a *= '(1.0)'::t_rec) +(5 rows) + +SELECT * FROM (SELECT a FROM u1 UNION ALL SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + a +------- + (1.0) + (1.0) +(2 rows) + +ROLLBACK; +-- -- Test that LIMIT can be pushed to SORT through a subquery that just projects -- columns. We check for that having happened by looking to see if EXPLAIN -- ANALYZE shows that a top-N sort was used. We must suppress or filter away diff --git a/src/test/regress/sql/aggregates.sql b/src/test/regress/sql/aggregates.sql index 916383db927..342605d5497 100644 --- a/src/test/regress/sql/aggregates.sql +++ b/src/test/regress/sql/aggregates.sql @@ -588,27 +588,57 @@ alter table t2 alter column z drop not null; create unique index t2_z_uidx on t2(z) nulls not distinct; explain (costs off) select y,z from t2 group by y,z; +drop table t1 cascade; +drop table t2; +drop table t3; +drop table p_t1; + +-- A composite type used by the tests below to exercise the asymmetry +-- between record_ops (per-field equality, the default) and record_image_ops +-- (bytewise equality): values like row(1.0) and row(1.00) are field-equal +-- but byte-distinct. +create type avg_rec as (x numeric); + -- A unique index proves uniqueness only under its own opfamily. When the -- GROUP BY's eqop comes from a different opfamily with looser equality, -- rows the index regards as distinct can collapse into one GROUP BY group, -- so the index is not usable for removing redundant columns. -create type t_rec as (x numeric); -create temp table t_opf (a t_rec not null, b text); +create temp table t_opf (a avg_rec not null, b text); create unique index on t_opf (a record_image_ops); -- (1.0) and (1.00) are bytewise distinct but logically equal as records; -- the index admits both, but GROUP BY a (default record_ops) would merge -- them, so b must be retained as a grouping key. -insert into t_opf values (row(1.0)::t_rec, 'X'), (row(1.00)::t_rec, 'Y'); +insert into t_opf values (row(1.0)::avg_rec, 'X'), (row(1.00)::avg_rec, 'Y'); explain (costs off) select a, b from t_opf group by a, b order by b; select a, b from t_opf group by a, b order by b; drop table t_opf; -drop type t_rec; -drop table t1 cascade; -drop table t2; -drop table t3; -drop table p_t1; +-- A HAVING clause that uses an equality operator from a different opfamily +-- than the GROUP BY's eqop must NOT be pushed down to WHERE. +create temp table t_having (id int, a avg_rec); +insert into t_having values + (1, row(1.0)::avg_rec), + (2, row(1.00)::avg_rec), + (3, row(2)::avg_rec); + +-- the clause must stay in HAVING +explain (costs off) +select a, count(*) from t_having group by a having a *= row(1.0)::avg_rec; +select a, count(*) from t_having group by a having a *= row(1.0)::avg_rec; + +-- the clause must stay in HAVING +explain (costs off) +select a, count(*) from t_having group by a having a *= any (array[row(1.0)::avg_rec]); +select a, count(*) from t_having group by a having a *= any (array[row(1.0)::avg_rec]); + +-- the clause can be pushed down to WHERE +explain (costs off) +select a, count(*) from t_having group by a having a = row(1.0)::avg_rec; +select a, count(*) from t_having group by a having a = row(1.0)::avg_rec; + +drop table t_having; +drop type avg_rec; -- -- Test GROUP BY ALL diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql index 18c47e6e05a..a1f10708c96 100644 --- a/src/test/regress/sql/collate.icu.utf8.sql +++ b/src/test/regress/sql/collate.icu.utf8.sql @@ -761,31 +761,39 @@ EXPLAIN (COSTS OFF) SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive; SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive; --- Negative: function applied to grouped column with conflicting collation +-- Negative: function over the grouping column, conflicting collation EXPLAIN (COSTS OFF) SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_sensitive; SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_sensitive; --- Positive: function with same collation as GROUP BY +-- Negative: function over the grouping column whose result is compared as an +-- integer, under no collation +EXPLAIN (COSTS OFF) +SELECT x, count(*) FROM test3ci GROUP BY x HAVING ascii(x) = 97; +SELECT x, count(*) FROM test3ci GROUP BY x HAVING ascii(x) = 97; + +-- Negative: a function wrapping the grouping column is not provably safe even +-- when compared under the matching collation, since the function need not +-- preserve the collation's equality EXPLAIN (COSTS OFF) SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_insensitive; SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_insensitive; --- Negative: inner function has conflicting collation, even though outer --- operator's collation matches GROUP BY due to a COLLATE override +-- Negative: same, with the grouping column wrapped in a function whose input +-- collation is overridden; still not a direct operand, so it stays in HAVING EXPLAIN (COSTS OFF) SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x COLLATE case_sensitive) COLLATE case_insensitive = 'ABC'; SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x COLLATE case_sensitive) COLLATE case_insensitive = 'ABC'; -- Mixed AND: conflicting clause stays in HAVING, safe clause pushed to WHERE EXPLAIN (COSTS OFF) -SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive AND length(x) > 1; -SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive AND length(x) > 1; +SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive AND x >= 'a' COLLATE case_insensitive; +SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive AND x >= 'a' COLLATE case_insensitive; -- Positive: AND of two safe clauses, both can be pushed EXPLAIN (COSTS OFF) -SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive AND length(x) > 1; -SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive AND length(x) > 1; +SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive AND x >= 'a' COLLATE case_insensitive; +SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive AND x >= 'a' COLLATE case_insensitive; -- Negative: OR with a conflicting clause: must stay in HAVING EXPLAIN (COSTS OFF) @@ -826,6 +834,111 @@ EXPLAIN (COSTS OFF) SELECT x, count(*) FROM test3cs GROUP BY x HAVING x = 'abc' COLLATE case_insensitive ORDER BY 1; SELECT x, count(*) FROM test3cs GROUP BY x HAVING x = 'abc' COLLATE case_insensitive ORDER BY 1; +-- Test WHERE-pushdown past a grouping layer (DISTINCT, DISTINCT ON, window +-- PARTITION BY) when the qual applies a different collation than the +-- grouping column's nondeterministic collation. The qual would distinguish +-- rows the grouping considers equal, so it must NOT be pushed inside the +-- subquery. +CREATE TABLE pushdown_ci (id int, x text COLLATE case_insensitive); +INSERT INTO pushdown_ci VALUES (1, 'ABC'), (2, 'abc'), (3, 'def'); + +-- DISTINCT ON: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT ON (x) id, x FROM pushdown_ci ORDER BY x, id) s +WHERE x = 'abc' COLLATE case_sensitive; + +SELECT * FROM (SELECT DISTINCT ON (x) id, x FROM pushdown_ci ORDER BY x, id) s +WHERE x = 'abc' COLLATE case_sensitive; + +-- Window function PARTITION BY: conflict, qual stays outside the WindowAgg +EXPLAIN (COSTS OFF) +SELECT * FROM ( + SELECT id, x, count(*) OVER (PARTITION BY x) AS cnt FROM pushdown_ci +) s +WHERE x = 'abc' COLLATE case_sensitive; + +SELECT * FROM ( + SELECT id, x, count(*) OVER (PARTITION BY x) AS cnt FROM pushdown_ci +) s +WHERE x = 'abc' COLLATE case_sensitive; + +-- Plain DISTINCT: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT x FROM pushdown_ci) s +WHERE x = 'abc' COLLATE case_sensitive; + +SELECT * FROM (SELECT DISTINCT x FROM pushdown_ci) s +WHERE x = 'abc' COLLATE case_sensitive; + +-- Positive: matching collation, safe to push past the grouping +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT ON (x) id, x FROM pushdown_ci ORDER BY x, id) s +WHERE x = 'abc' COLLATE case_insensitive; + +SELECT * FROM (SELECT DISTINCT ON (x) id, x FROM pushdown_ci ORDER BY x, id) s +WHERE x = 'abc' COLLATE case_insensitive; + +-- Set operations: any operation other than UNION ALL groups rows by equality, +-- so the same collation-mismatch rules apply. +CREATE TABLE pushdown_ci2 (x text COLLATE case_insensitive); +INSERT INTO pushdown_ci2 VALUES ('abc'); + +-- UNION: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT x FROM pushdown_ci UNION SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + +SELECT * FROM (SELECT x FROM pushdown_ci UNION SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + +-- INTERSECT: same +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT x FROM pushdown_ci INTERSECT SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + +SELECT * FROM (SELECT x FROM pushdown_ci INTERSECT SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + +-- INTERSECT ALL: still groups +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT x FROM pushdown_ci INTERSECT ALL SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + +SELECT * FROM (SELECT x FROM pushdown_ci INTERSECT ALL SELECT x FROM pushdown_ci2) s +WHERE x = 'abc' COLLATE case_sensitive; + +-- Negative: a function over a grouping column with a nondeterministic +-- collation, whose result is compared under no collation (an integer +-- comparison), can distinguish values the grouping considers equal. +-- PARTITION BY +EXPLAIN (COSTS OFF) +SELECT * FROM ( + SELECT id, x, count(*) OVER (PARTITION BY x) AS cnt FROM pushdown_ci +) s +WHERE ascii(x) = 97; + +SELECT * FROM ( + SELECT id, x, count(*) OVER (PARTITION BY x) AS cnt FROM pushdown_ci +) s +WHERE ascii(x) = 97; + +-- Same with DISTINCT +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT x FROM pushdown_ci) s WHERE ascii(x) = 97; + +SELECT * FROM (SELECT DISTINCT x FROM pushdown_ci) s WHERE ascii(x) = 97; + +-- Same with Set operations +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT x FROM pushdown_ci UNION SELECT x FROM pushdown_ci2) s +WHERE ascii(x) = 97; + +SELECT * FROM (SELECT x FROM pushdown_ci UNION SELECT x FROM pushdown_ci2) s +WHERE ascii(x) = 97; + +DROP TABLE pushdown_ci2; +DROP TABLE pushdown_ci; + -- bpchar CREATE TABLE test1bpci (x char(3) COLLATE case_insensitive); CREATE TABLE test2bpci (x char(3) COLLATE case_insensitive); diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql index 1a02c3f86c0..3defbc29177 100644 --- a/src/test/regress/sql/subselect.sql +++ b/src/test/regress/sql/subselect.sql @@ -994,6 +994,111 @@ select * from drop function tattle(x int, y int); +-- +-- check that an upper-level qual is not pushed down if its operator is from a +-- different btree opfamily than the subquery's grouping eqop +-- +BEGIN; + +CREATE TYPE t_rec AS (x numeric); +CREATE TEMP TABLE pdt (id int, a t_rec); +INSERT INTO pdt VALUES + (1, ROW(1.00)::t_rec), + (2, ROW(1.0)::t_rec), + (3, ROW(2)::t_rec); + +-- DISTINCT ON: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT ON (a) id, a FROM pdt ORDER BY a, id) s +WHERE a *= ROW(1.0)::t_rec; + +SELECT * FROM (SELECT DISTINCT ON (a) id, a FROM pdt ORDER BY a, id) s +WHERE a *= ROW(1.0)::t_rec; + +-- Window function PARTITION BY: conflict, qual stays outside the WindowAgg +EXPLAIN (COSTS OFF) +SELECT * FROM ( + SELECT id, a, count(*) OVER (PARTITION BY a) AS cnt FROM pdt +) s +WHERE a *= ROW(1.0)::t_rec; + +SELECT * FROM ( + SELECT id, a, count(*) OVER (PARTITION BY a) AS cnt FROM pdt +) s +WHERE a *= ROW(1.0)::t_rec; + +-- Plain DISTINCT: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT a FROM pdt) s WHERE a *= ROW(1.0)::t_rec; + +SELECT * FROM (SELECT DISTINCT a FROM pdt) s WHERE a *= ROW(1.0)::t_rec; + +-- Positive: compatible opfamily, safe to push past the grouping +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT DISTINCT ON (a) id, a FROM pdt ORDER BY a, id) s +WHERE a = ROW(1.0)::t_rec; + +SELECT * FROM (SELECT DISTINCT ON (a) id, a FROM pdt ORDER BY a, id) s +WHERE a = ROW(1.0)::t_rec; + +-- Set operations: any operation other than UNION ALL groups rows by equality, +-- so the same opfamily-mismatch rules apply. +CREATE TEMP TABLE u1 (a t_rec); +CREATE TEMP TABLE u2 (a t_rec); +INSERT INTO u1 VALUES (ROW(1.00)::t_rec), (ROW(1.0)::t_rec); +INSERT INTO u2 VALUES (ROW(1.0)::t_rec); + +-- UNION: conflict, qual stays in outer query +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT a FROM u1 UNION SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + +SELECT * FROM (SELECT a FROM u1 UNION SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + +-- INTERSECT: same +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT a FROM u1 INTERSECT SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + +SELECT * FROM (SELECT a FROM u1 INTERSECT SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + +-- INTERSECT ALL: still groups +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT a FROM u1 INTERSECT ALL SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + +SELECT * FROM (SELECT a FROM u1 INTERSECT ALL SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + +-- UNION ALL of (UNION ...): an inner grouping node still exposes the +-- conflict to a qual pushed down through the outer UNION ALL. +EXPLAIN (COSTS OFF) +SELECT * FROM ( + (SELECT a FROM u1 UNION SELECT a FROM u2) + UNION ALL + SELECT a FROM u2 +) s +WHERE a *= ROW(1.0)::t_rec; + +SELECT * FROM ( + (SELECT a FROM u1 UNION SELECT a FROM u2) + UNION ALL + SELECT a FROM u2 +) s +WHERE a *= ROW(1.0)::t_rec; + +-- UNION ALL only: no grouping anywhere, pushdown remains allowed. +EXPLAIN (COSTS OFF) +SELECT * FROM (SELECT a FROM u1 UNION ALL SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + +SELECT * FROM (SELECT a FROM u1 UNION ALL SELECT a FROM u2) s +WHERE a *= ROW(1.0)::t_rec; + +ROLLBACK; + -- -- Test that LIMIT can be pushed to SORT through a subquery that just projects -- columns. We check for that having happened by looking to see if EXPLAIN diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 3a2720fb5f9..3442c4b9ec9 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -3841,7 +3841,9 @@ gistxlogPageDelete gistxlogPageReuse gistxlogPageSplit gistxlogPageUpdate +grouping_eqop_callback grouping_sets_data +grouping_walker_ctx growable_trgm_array gseg_picksplit_item gss_OID_set @@ -3854,7 +3856,7 @@ gss_key_value_set_desc gss_name_t gtrgm_consistent_cache gzFile -having_collation_ctx +having_grouping_ctx heap_page_items_state help_handler hlCheck From c8d49ffb007b2f5aff61cff2ff68786f2d53ac5d Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 6 Jul 2026 09:19:02 +0200 Subject: [PATCH 092/481] Forbid generated columns in FOR PORTION OF With virtual generated columns there is no column to assign to, and we shouldn't assign directly to stored generated columns either. (Once we have PERIODs, we will allow a stored generated column here, but we will assign to its start/end inputs.) We can't do this in parse analysis, because views haven't yet been rewritten, so they mask generated columns. Author: Paul A. Jungwirth Discussion: https://www.postgresql.org/message-id/agOOykf2HV26yVfU%40nathan --- doc/src/sgml/ddl.sgml | 4 +- src/backend/optimizer/plan/planner.c | 26 +++++++ src/test/regress/expected/for_portion_of.out | 73 ++++++++++++++++++++ src/test/regress/sql/for_portion_of.sql | 57 +++++++++++++++ 4 files changed, 159 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index fbd0ebbf10f..f9b0a43ad59 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -382,7 +382,9 @@ CREATE TABLE people ( A generated column cannot be written to directly. In INSERT or UPDATE commands, a value cannot be specified for a generated column, but the keyword - DEFAULT may be specified. + DEFAULT may be specified. Also, a generated column + cannot be used in the FOR PORTION OF clause of an + UPDATE or DELETE command. diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index cac2ebb86c6..3225185d16f 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -848,6 +848,32 @@ subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, */ transform_MERGE_to_join(parse); + /* + * Reject FOR PORTION OF on a generated column. We can't write to a + * virtual generated column, and a stored generated column should be + * written by its own expression. + * + * We do this in the planner rather than parse analysis so that updatable + * views have been rewritten; otherwise they would mask which columns are + * generated. We need to check before preprocess_relation_rtes(), so that + * for virtual generated columns we still have the rangeVar. After that + * it is replaced by the column's expression. + * + * XXX: We plan to implement PERIODs as stored generated columns, so later + * we will loosen this restriction if the column belongs to a PERIOD. + */ + if (parse->forPortionOf) + { + ForPortionOfExpr *forPortionOf = parse->forPortionOf; + RangeTblEntry *rte = rt_fetch(parse->resultRelation, parse->rtable); + + if (get_attgenerated(rte->relid, forPortionOf->rangeVar->varattno)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot use generated column \"%s\" in FOR PORTION OF", + forPortionOf->range_name))); + } + /* * Scan the rangetable for relation RTEs and retrieve the necessary * catalog information for each relation. Using this information, clear diff --git a/src/test/regress/expected/for_portion_of.out b/src/test/regress/expected/for_portion_of.out index 207e370627e..a050fc2dadf 100644 --- a/src/test/regress/expected/for_portion_of.out +++ b/src/test/regress/expected/for_portion_of.out @@ -2208,6 +2208,79 @@ SELECT * FROM fpo_rule ORDER BY f1; (2 rows) DROP TABLE fpo_rule; +-- UPDATE/DELETE FOR PORTION OF on a GENERATED VIRTUAL range column: +CREATE TABLE fpo_gen_virtual ( + a int, + b int4range GENERATED ALWAYS AS (int4range(a, a + 1)) VIRTUAL +); +INSERT INTO fpo_gen_virtual VALUES (1); +DELETE FROM fpo_gen_virtual FOR PORTION OF b FROM 1 TO 2; -- fails +ERROR: cannot use generated column "b" in FOR PORTION OF +UPDATE fpo_gen_virtual FOR PORTION OF b FROM 1 TO 2 SET a = 5; -- fails +ERROR: column "b" can only be updated to DEFAULT +DETAIL: Column "b" is a generated column. +DROP TABLE fpo_gen_virtual; +-- UPDATE/DELETE FOR PORTION OF on a GENERATED STORED range column: +CREATE TABLE fpo_gen_stored ( + a int, + b int4range GENERATED ALWAYS AS (int4range(a, a + 1)) STORED +); +INSERT INTO fpo_gen_stored VALUES (1); +DELETE FROM fpo_gen_stored FOR PORTION OF b FROM 1 TO 2; -- fails +ERROR: cannot use generated column "b" in FOR PORTION OF +UPDATE fpo_gen_stored FOR PORTION OF b FROM 1 TO 2 SET a = 5; -- fails +ERROR: column "b" can only be updated to DEFAULT +DETAIL: Column "b" is a generated column. +DROP TABLE fpo_gen_stored; +-- FOR PORTION OF a generated column reached through an updatable view. +-- The view hides that b is generated during parse analysis, so the check +-- must happen later (in the planner), after the view is rewritten to its +-- underlying table. +CREATE TABLE fpo_gen_view ( + a int, + b int4range GENERATED ALWAYS AS (int4range(a, a + 1)) STORED +); +INSERT INTO fpo_gen_view VALUES (1); +CREATE VIEW fpo_gen_view_v AS SELECT * FROM fpo_gen_view; +DELETE FROM fpo_gen_view_v FOR PORTION OF b FROM 1 TO 2; -- fails +ERROR: cannot use generated column "b" in FOR PORTION OF +UPDATE fpo_gen_view_v FOR PORTION OF b FROM 1 TO 2 SET a = 5; -- fails +ERROR: column "b" can only be updated to DEFAULT +DETAIL: Column "b" is a generated column. +DROP VIEW fpo_gen_view_v; +DROP TABLE fpo_gen_view; +-- A new-style SQL function is parsed at CREATE FUNCTION time, but our +-- generated-column check is in the planner, so it sees the column's +-- current attgenerated when the function's plan is built at run time. +CREATE TABLE fpo_func_test ( + a int, + b int4range GENERATED ALWAYS AS (int4range(a, a + 1)) STORED +); +INSERT INTO fpo_func_test VALUES (1); +-- Definition succeeds even though b is a generated column today. +CREATE FUNCTION fpo_delete() RETURNS void + LANGUAGE SQL + BEGIN ATOMIC + DELETE FROM fpo_func_test FOR PORTION OF b FROM 1 TO 2; + END; +SELECT fpo_delete(); -- fails: b is generated +ERROR: cannot use generated column "b" in FOR PORTION OF +CONTEXT: SQL function "fpo_delete" statement 1 +-- Drop the generation expression and the same function now succeeds. +ALTER TABLE fpo_func_test ALTER COLUMN b DROP EXPRESSION; +SELECT fpo_delete(); + fpo_delete +------------ + +(1 row) + +TABLE fpo_func_test ORDER BY a, b; + a | b +---+--- +(0 rows) + +DROP FUNCTION fpo_delete(); +DROP TABLE fpo_func_test; -- UPDATE/DELETE FOR PORTION OF with table inheritance -- Leftover rows must stay in the child table, preserving child-specific columns. CREATE TABLE fpo_inh_parent ( diff --git a/src/test/regress/sql/for_portion_of.sql b/src/test/regress/sql/for_portion_of.sql index a3c41abf7b7..a1ee1d5e501 100644 --- a/src/test/regress/sql/for_portion_of.sql +++ b/src/test/regress/sql/for_portion_of.sql @@ -1448,6 +1448,63 @@ SELECT * FROM fpo_rule ORDER BY f1; DROP TABLE fpo_rule; +-- UPDATE/DELETE FOR PORTION OF on a GENERATED VIRTUAL range column: +CREATE TABLE fpo_gen_virtual ( + a int, + b int4range GENERATED ALWAYS AS (int4range(a, a + 1)) VIRTUAL +); +INSERT INTO fpo_gen_virtual VALUES (1); +DELETE FROM fpo_gen_virtual FOR PORTION OF b FROM 1 TO 2; -- fails +UPDATE fpo_gen_virtual FOR PORTION OF b FROM 1 TO 2 SET a = 5; -- fails +DROP TABLE fpo_gen_virtual; + +-- UPDATE/DELETE FOR PORTION OF on a GENERATED STORED range column: +CREATE TABLE fpo_gen_stored ( + a int, + b int4range GENERATED ALWAYS AS (int4range(a, a + 1)) STORED +); +INSERT INTO fpo_gen_stored VALUES (1); +DELETE FROM fpo_gen_stored FOR PORTION OF b FROM 1 TO 2; -- fails +UPDATE fpo_gen_stored FOR PORTION OF b FROM 1 TO 2 SET a = 5; -- fails +DROP TABLE fpo_gen_stored; + +-- FOR PORTION OF a generated column reached through an updatable view. +-- The view hides that b is generated during parse analysis, so the check +-- must happen later (in the planner), after the view is rewritten to its +-- underlying table. +CREATE TABLE fpo_gen_view ( + a int, + b int4range GENERATED ALWAYS AS (int4range(a, a + 1)) STORED +); +INSERT INTO fpo_gen_view VALUES (1); +CREATE VIEW fpo_gen_view_v AS SELECT * FROM fpo_gen_view; +DELETE FROM fpo_gen_view_v FOR PORTION OF b FROM 1 TO 2; -- fails +UPDATE fpo_gen_view_v FOR PORTION OF b FROM 1 TO 2 SET a = 5; -- fails +DROP VIEW fpo_gen_view_v; +DROP TABLE fpo_gen_view; + +-- A new-style SQL function is parsed at CREATE FUNCTION time, but our +-- generated-column check is in the planner, so it sees the column's +-- current attgenerated when the function's plan is built at run time. +CREATE TABLE fpo_func_test ( + a int, + b int4range GENERATED ALWAYS AS (int4range(a, a + 1)) STORED +); +INSERT INTO fpo_func_test VALUES (1); +-- Definition succeeds even though b is a generated column today. +CREATE FUNCTION fpo_delete() RETURNS void + LANGUAGE SQL + BEGIN ATOMIC + DELETE FROM fpo_func_test FOR PORTION OF b FROM 1 TO 2; + END; +SELECT fpo_delete(); -- fails: b is generated +-- Drop the generation expression and the same function now succeeds. +ALTER TABLE fpo_func_test ALTER COLUMN b DROP EXPRESSION; +SELECT fpo_delete(); +TABLE fpo_func_test ORDER BY a, b; +DROP FUNCTION fpo_delete(); +DROP TABLE fpo_func_test; + -- UPDATE/DELETE FOR PORTION OF with table inheritance -- Leftover rows must stay in the child table, preserving child-specific columns. CREATE TABLE fpo_inh_parent ( From 33bfad0f3cad222e4a2593cc774234e3117f1bc0 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 6 Jul 2026 11:44:55 +0200 Subject: [PATCH 093/481] Remove apparent support for SECURITY LABEL ON PROPERTY GRAPH Commit 2f094e7ac69 added a mention of SECURITY LABEL ON PROPERTY GRAPH to the SECURITY LABEL reference page, and it added support to psql tab completion. However, security labels on property graphs are not actually supported (per SecLabelSupportsObjectType()). The syntax does work, but that is just a result of how gram.y is factored. We don't document or tab-complete the syntax of SECURITY LABEL for other object types that are not actually supported, so it was inconsistent to do this for property graphs. Thus, remove this. Reported-by: Noah Misch Discussion: https://www.postgresql.org/message-id/flat/20260704221210.08.noahmisch%40microsoft.com --- doc/src/sgml/ref/security_label.sgml | 1 - src/bin/psql/tab-complete.in.c | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/src/sgml/ref/security_label.sgml b/doc/src/sgml/ref/security_label.sgml index c112f7a08a7..aa45c0af248 100644 --- a/doc/src/sgml/ref/security_label.sgml +++ b/doc/src/sgml/ref/security_label.sgml @@ -35,7 +35,6 @@ SECURITY LABEL [ FOR provider ] ON MATERIALIZED VIEW object_name | [ PROCEDURAL ] LANGUAGE object_name | PROCEDURE procedure_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] | - PROPERTY GRAPH object_name PUBLICATION object_name | ROLE object_name | ROUTINE routine_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] | diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index b783f123643..6207c91d482 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -5270,10 +5270,8 @@ match_previous_words(int pattern_id, COMPLETE_WITH("TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN", "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION", "LARGE OBJECT", "MATERIALIZED VIEW", "LANGUAGE", - "PROPERTY GRAPH", "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA", + "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA", "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW"); - else if (Matches("SECURITY", "LABEL", "ON", "PROPERTY", "GRAPH")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_propgraphs); else if (Matches("SECURITY", "LABEL", "ON", MatchAny, MatchAny)) COMPLETE_WITH("IS"); From 2ddc4566214d8eff3c4013a9e241b5e9b47abbaf Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 6 Jul 2026 12:12:41 -0400 Subject: [PATCH 094/481] Prevent satisfies_hash_partition from crashing with VARIADIC NULL. Commit f3b0897a1213f46b4d3a99a7f8ef3a4b32e03572 fixed some related problems, but overlooked this one. That commit first appeared in PostgreSQL 11, so back-patch to all supported branches. Backpatch-through: 14 Discussion: http://postgr.es/m/CA+TgmobsvQw3F+KRYT83=N3teh8D2t-oPR=U06QDZJE3viCJRg@mail.gmail.com Reviewed-by: Tender Wang Reviewed-by: Ewan Young --- src/backend/partitioning/partbounds.c | 14 +++++++++++++- src/test/regress/expected/hash_part.out | 7 +++++++ src/test/regress/sql/hash_part.sql | 3 +++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index 6fb150a8763..a7822a4192b 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -4861,6 +4861,12 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) fcinfo->flinfo->fn_mcxt); } } + else if (PG_ARGISNULL(3)) + { + /* Special case for VARIADIC NULL::sometype[] */ + relation_close(parent, NoLock); + PG_RETURN_BOOL(false); + } else { ArrayType *variadic_array = PG_GETARG_ARRAYTYPE_P(3); @@ -4931,12 +4937,18 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) } else { - ArrayType *variadic_array = PG_GETARG_ARRAYTYPE_P(3); + ArrayType *variadic_array; int i; int nelems; Datum *datum; bool *isnull; + /* Special case for VARIADIC NULL::sometype[] */ + if (PG_ARGISNULL(3)) + PG_RETURN_BOOL(false); + + variadic_array = PG_GETARG_ARRAYTYPE_P(3); + deconstruct_array(variadic_array, my_extra->variadic_type, my_extra->variadic_typlen, diff --git a/src/test/regress/expected/hash_part.out b/src/test/regress/expected/hash_part.out index cb39161f867..44b6e461ffe 100644 --- a/src/test/regress/expected/hash_part.out +++ b/src/test/regress/expected/hash_part.out @@ -40,6 +40,13 @@ SELECT satisfies_hash_partition('mchash'::regclass, 4, NULL, NULL); f (1 row) +-- variadic null +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, VARIADIC NULL::int[]); + satisfies_hash_partition +-------------------------- + f +(1 row) + -- too many arguments SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, NULL::int, NULL::text, NULL::json); ERROR: number of partitioning columns (2) does not match number of partition keys provided (3) diff --git a/src/test/regress/sql/hash_part.sql b/src/test/regress/sql/hash_part.sql index 6e2c1f21bfc..7243299d962 100644 --- a/src/test/regress/sql/hash_part.sql +++ b/src/test/regress/sql/hash_part.sql @@ -35,6 +35,9 @@ SELECT satisfies_hash_partition('mchash'::regclass, NULL, 0, NULL); -- remainder is null SELECT satisfies_hash_partition('mchash'::regclass, 4, NULL, NULL); +-- variadic null +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, VARIADIC NULL::int[]); + -- too many arguments SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, NULL::int, NULL::text, NULL::json); From 67cf73ddbe3334ee1fecc29ffb6d4cd2e10ab9ac Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 6 Jul 2026 13:06:21 -0400 Subject: [PATCH 095/481] Fix LIKE/regex optimization for indexscan with exact-match pattern. Commit 85b7efa1c introduced support for LIKE with non-deterministic collations. By moving some conditionals around, it accidentally broke the optimization for converting a LIKE or regex exact-match pattern to an equality indexqual when the index collation doesn't match the expression collation. That should be allowed if the expression collation is deterministic. This patch re-introduces the optimization for that common case. One important beneficiary of this optimization is the "\d tablename" command in psql. Without this fix that will do a seqscan on pg_class instead of an index point lookup. Reported-by: Andres Freund Author: Jelte Fennema-Nio Reviewed-by: Tom Lane Discussion: https://postgr.es/m/DHBQIZX8SZVI.ZX614ZMFL645@jeltef.nl Backpatch-through: 18 --- src/backend/utils/adt/like_support.c | 20 ++++++++++++---- .../regress/expected/collate.icu.utf8.out | 23 +++++++++++++++++++ src/test/regress/expected/collate.out | 23 +++++++++++++++++++ src/test/regress/sql/collate.icu.utf8.sql | 10 ++++++++ src/test/regress/sql/collate.sql | 10 ++++++++ 5 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/adt/like_support.c b/src/backend/utils/adt/like_support.c index 01cd6b10730..4c8db9147ee 100644 --- a/src/backend/utils/adt/like_support.c +++ b/src/backend/utils/adt/like_support.c @@ -69,6 +69,10 @@ typedef enum Pattern_Prefix_None, Pattern_Prefix_Partial, Pattern_Prefix_Exact, } Pattern_Prefix_Status; +/* non-collatable comparisons, eg for bytea, are always deterministic */ +#define NONDETERMINISTIC(coll) \ + (OidIsValid(coll) && !get_collation_isdeterministic(coll)) + static Node *like_regex_support(Node *rawreq, Pattern_Type ptype); static List *match_pattern_prefix(Node *leftop, Node *rightop, @@ -381,12 +385,22 @@ match_pattern_prefix(Node *leftop, * us to not be concerned with specific opclasses (except for the legacy * "pattern" cases); any index that correctly implements the operators * will work. + * + * This case will work for LIKE/regex expressions with nondeterministic + * collation, so long as the index's collation is the same. If the + * expression's collation is deterministic, we can even use an index whose + * collation differs from the expression's. All deterministic collations + * agree on equality (it's bitwise), while we assume that an index with + * nondeterministic collation will return a superset of the bitwise-equal + * entries. Since the "=" indexqual is marked as lossy by default, we'll + * apply the LIKE/regex operator as a recheck, and that will filter out + * any non-matching entries. */ if (pstatus == Pattern_Prefix_Exact) { if (!op_in_opfamily(eqopr, opfamily)) return NIL; - if (indexcollation != expr_coll) + if (indexcollation != expr_coll && NONDETERMINISTIC(expr_coll)) return NIL; expr = make_opclause(eqopr, BOOLOID, false, (Expr *) leftop, (Expr *) prefix, @@ -400,10 +414,8 @@ match_pattern_prefix(Node *leftop, * expression collation is nondeterministic. The optimized equality or * prefix tests use bytewise comparisons, which is not consistent with * nondeterministic collations. - * - * expr_coll is not set for a non-collation-aware data type such as bytea. */ - if (expr_coll && !get_collation_isdeterministic(expr_coll)) + if (NONDETERMINISTIC(expr_coll)) return NIL; /* diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out index cf2c55ba92e..fb95eee9b7c 100644 --- a/src/test/regress/expected/collate.icu.utf8.out +++ b/src/test/regress/expected/collate.icu.utf8.out @@ -2084,6 +2084,29 @@ SELECT string_to_array('ABCDEFGHI' COLLATE case_insensitive, NULL, 'b'); {A,NULL,C,D,E,F,G,H,I} (1 row) +-- These queries should be able to use the index on test1ci.x: +SET enable_seqscan = off; +SET enable_indexonlyscan = off; +EXPLAIN (COSTS OFF) +SELECT * FROM test1ci WHERE x ~ '^abc$' COLLATE "C"; + QUERY PLAN +------------------------------------------- + Index Scan using test1ci_x_idx on test1ci + Index Cond: (x = 'abc'::text) + Filter: (x ~ '^abc$'::text COLLATE "C") +(3 rows) + +EXPLAIN (COSTS OFF) +SELECT * FROM test1ci WHERE x LIKE 'abc' COLLATE case_insensitive; + QUERY PLAN +------------------------------------------------------- + Index Scan using test1ci_x_idx on test1ci + Index Cond: (x = 'abc'::text) + Filter: (x ~~ 'abc'::text COLLATE case_insensitive) +(3 rows) + +RESET enable_seqscan; +RESET enable_indexonlyscan; -- Test HAVING-to-WHERE pushdown with nondeterministic collations. -- When a HAVING clause uses a different collation than the GROUP BY's -- nondeterministic collation, it must not be pushed to WHERE, otherwise diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out index 25818f09ad2..b17c5abaddc 100644 --- a/src/test/regress/expected/collate.out +++ b/src/test/regress/expected/collate.out @@ -768,6 +768,29 @@ DETAIL: LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE. CREATE COLLATION coll_dup_chk (FROM = "C", VERSION = "1"); ERROR: conflicting or redundant options DETAIL: FROM cannot be specified together with any other options. +-- Regex exact-match optimization should use an index even when the expression +-- and index have different collations, so long as the expression's collation +-- is deterministic. This example tests what we want because the optimizer +-- does not perceive "C" collation (used by the system catalogs) as identical +-- to "POSIX" collation. +EXPLAIN (COSTS OFF) +SELECT * FROM pg_class WHERE relname ~ '^pg_class$' COLLATE "POSIX"; + QUERY PLAN +---------------------------------------------------------- + Index Scan using pg_class_relname_nsp_index on pg_class + Index Cond: (relname = 'pg_class'::text) + Filter: (relname ~ '^pg_class$'::text COLLATE "POSIX") +(3 rows) + +EXPLAIN (COSTS OFF) +SELECT * FROM pg_class WHERE relname LIKE 'pg\_class' COLLATE "POSIX"; + QUERY PLAN +---------------------------------------------------------- + Index Scan using pg_class_relname_nsp_index on pg_class + Index Cond: (relname = 'pg_class'::text) + Filter: (relname ~~ 'pg\_class'::text COLLATE "POSIX") +(3 rows) + -- -- Clean up. Many of these table names will be re-used if the user is -- trying to run any platform-specific collation tests later, so we diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql index a1f10708c96..954d8ea6cb4 100644 --- a/src/test/regress/sql/collate.icu.utf8.sql +++ b/src/test/regress/sql/collate.icu.utf8.sql @@ -745,6 +745,16 @@ CREATE UNIQUE INDEX ON test3ci (x); -- error SELECT string_to_array('ABC,DEF,GHI' COLLATE case_insensitive, ',', 'abc'); SELECT string_to_array('ABCDEFGHI' COLLATE case_insensitive, NULL, 'b'); +-- These queries should be able to use the index on test1ci.x: +SET enable_seqscan = off; +SET enable_indexonlyscan = off; +EXPLAIN (COSTS OFF) +SELECT * FROM test1ci WHERE x ~ '^abc$' COLLATE "C"; +EXPLAIN (COSTS OFF) +SELECT * FROM test1ci WHERE x LIKE 'abc' COLLATE case_insensitive; +RESET enable_seqscan; +RESET enable_indexonlyscan; + -- Test HAVING-to-WHERE pushdown with nondeterministic collations. -- When a HAVING clause uses a different collation than the GROUP BY's -- nondeterministic collation, it must not be pushed to WHERE, otherwise diff --git a/src/test/regress/sql/collate.sql b/src/test/regress/sql/collate.sql index 4b0e4472c3f..b018da13f24 100644 --- a/src/test/regress/sql/collate.sql +++ b/src/test/regress/sql/collate.sql @@ -302,6 +302,16 @@ CREATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LOCALE = ''); -- FROM conflicts with any other option CREATE COLLATION coll_dup_chk (FROM = "C", VERSION = "1"); +-- Regex exact-match optimization should use an index even when the expression +-- and index have different collations, so long as the expression's collation +-- is deterministic. This example tests what we want because the optimizer +-- does not perceive "C" collation (used by the system catalogs) as identical +-- to "POSIX" collation. +EXPLAIN (COSTS OFF) +SELECT * FROM pg_class WHERE relname ~ '^pg_class$' COLLATE "POSIX"; +EXPLAIN (COSTS OFF) +SELECT * FROM pg_class WHERE relname LIKE 'pg\_class' COLLATE "POSIX"; + -- -- Clean up. Many of these table names will be re-used if the user is -- trying to run any platform-specific collation tests later, so we From 017499a50f371c5a801f4e3b9b6a6ec2f59da859 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 6 Jul 2026 13:48:42 -0400 Subject: [PATCH 096/481] Make PLy_elog() use pg_integer_constant_p(). This macro is supposed to work like ereport(). But when 59c2f03d1 adjusted ereport() to be more MSVC-friendly, it missed updating this copy of the logic. Discussion: https://postgr.es/m/754534.1783264708@sss.pgh.pa.us Backpatch-through: 19 --- src/pl/plpython/plpy_elog.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pl/plpython/plpy_elog.h b/src/pl/plpython/plpy_elog.h index 3150f9e72ca..887535d5860 100644 --- a/src/pl/plpython/plpy_elog.h +++ b/src/pl/plpython/plpy_elog.h @@ -17,14 +17,14 @@ extern PyObject *PLy_exc_spi_error; * * See comments at elog() about the compiler hinting. */ -#ifdef HAVE__BUILTIN_CONSTANT_P +#ifdef HAVE_PG_INTEGER_CONSTANT_P #define PLy_elog(elevel, ...) \ do { \ PLy_elog_impl(elevel, __VA_ARGS__); \ - if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ + if (pg_integer_constant_p(elevel) && (elevel) >= ERROR) \ pg_unreachable(); \ } while(0) -#else /* !HAVE__BUILTIN_CONSTANT_P */ +#else /* !HAVE_PG_INTEGER_CONSTANT_P */ #define PLy_elog(elevel, ...) \ do { \ const int elevel_ = (elevel); \ @@ -32,7 +32,7 @@ extern PyObject *PLy_exc_spi_error; if (elevel_ >= ERROR) \ pg_unreachable(); \ } while(0) -#endif /* HAVE__BUILTIN_CONSTANT_P */ +#endif /* HAVE_PG_INTEGER_CONSTANT_P */ extern PGDLLEXPORT void PLy_elog_impl(int elevel, const char *fmt, ...) pg_attribute_printf(2, 3); From 99775b3885b600277dea577db69e7469e59bcdbe Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 6 Jul 2026 14:35:21 -0400 Subject: [PATCH 097/481] Fix LIKE matching with nondeterministic collations and backslashes. Commit 85b7efa1c added support for LIKE with nondeterministic collations, but it included a bug in the de-escaping logic for literal pattern substrings. That unconditionally skipped all backslashes, but when it encounters '\\' it should emit the second backslash as a de-escaped character. That led to acting as though the escaped backslash was not there. Bug: #19474 Reported-by: Bowen Shi Author: Nitin Motiani Reviewed-by: Zsolt Parragi Reviewed-by: Ewan Young Reviewed-by: Tom Lane Discussion: https://postgr.es/m/19474-5b86a95f3d9a7ecb@postgresql.org Discussion: https://postgr.es/m/CAH5HC94yU+K8Gcdy12M5BS8gwD_SXLSHzc9k5tNk7JDnpBiFMA@mail.gmail.com Backpatch-through: 18 --- src/backend/utils/adt/like_match.c | 5 ++- .../regress/expected/collate.icu.utf8.out | 31 +++++++++++++++++++ src/test/regress/sql/collate.icu.utf8.sql | 7 +++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/adt/like_match.c b/src/backend/utils/adt/like_match.c index f5f72b82e21..ddaf6b1806a 100644 --- a/src/backend/utils/adt/like_match.c +++ b/src/backend/utils/adt/like_match.c @@ -257,9 +257,8 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale) for (const char *c = p; c < p1; c++) { if (*c == '\\') - ; - else - *(b++) = *c; + c++; /* we already checked this isn't the end */ + *(b++) = *c; } subpat = buf; diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out index fb95eee9b7c..3209964cc44 100644 --- a/src/test/regress/expected/collate.icu.utf8.out +++ b/src/test/regress/expected/collate.icu.utf8.out @@ -3006,6 +3006,37 @@ SELECT U&'\0061\0308bc' LIKE U&'_\00e4bc' COLLATE ignore_accents; -- escape character at end of pattern SELECT 'foox' LIKE 'foo\' COLLATE ignore_accents; ERROR: LIKE pattern must not end with escape character +-- literal backslash with nondeterministic collation (bug #19474) +SELECT 'back\slash' COLLATE ignore_accents LIKE 'back\slash%' ESCAPE '#'; + ?column? +---------- + t +(1 row) + +SELECT 'aäb' COLLATE ignore_accents LIKE 'a#äb' ESCAPE '#' AS multibyte_escape; + multibyte_escape +------------------ + t +(1 row) + +SELECT 'a\äb' COLLATE ignore_accents LIKE 'a\äb%' ESCAPE '#' AS backslash_multibyte; + backslash_multibyte +--------------------- + t +(1 row) + +SELECT 'a\b%c' COLLATE ignore_accents LIKE 'a#\b#%%c' ESCAPE '#' AS mixed_escapes; + mixed_escapes +--------------- + t +(1 row) + +SELECT 'backslash' COLLATE ignore_accents LIKE 'back\\slash%'; + ?column? +---------- + f +(1 row) + -- foreign keys (mixing different nondeterministic collations not allowed) CREATE TABLE test10pk (x text COLLATE case_sensitive PRIMARY KEY); CREATE TABLE test10fk (x text COLLATE case_insensitive REFERENCES test10pk (x) ON UPDATE CASCADE ON DELETE CASCADE); -- error diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql index 954d8ea6cb4..3cee7223f95 100644 --- a/src/test/regress/sql/collate.icu.utf8.sql +++ b/src/test/regress/sql/collate.icu.utf8.sql @@ -1083,6 +1083,13 @@ SELECT U&'\0061\0308bc' LIKE U&'_\00e4bc' COLLATE ignore_accents; -- escape character at end of pattern SELECT 'foox' LIKE 'foo\' COLLATE ignore_accents; +-- literal backslash with nondeterministic collation (bug #19474) +SELECT 'back\slash' COLLATE ignore_accents LIKE 'back\slash%' ESCAPE '#'; +SELECT 'aäb' COLLATE ignore_accents LIKE 'a#äb' ESCAPE '#' AS multibyte_escape; +SELECT 'a\äb' COLLATE ignore_accents LIKE 'a\äb%' ESCAPE '#' AS backslash_multibyte; +SELECT 'a\b%c' COLLATE ignore_accents LIKE 'a#\b#%%c' ESCAPE '#' AS mixed_escapes; +SELECT 'backslash' COLLATE ignore_accents LIKE 'back\\slash%'; + -- foreign keys (mixing different nondeterministic collations not allowed) CREATE TABLE test10pk (x text COLLATE case_sensitive PRIMARY KEY); CREATE TABLE test10fk (x text COLLATE case_insensitive REFERENCES test10pk (x) ON UPDATE CASCADE ON DELETE CASCADE); -- error From 54d5947efe2d03a1419d71630c3ae95b2ec14906 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 6 Jul 2026 14:47:58 -0400 Subject: [PATCH 098/481] Fix mishandling of leading '\' in nondeterministic LIKE. The loop in MatchText() processed a leading '\' without regard to nondeterministic locales, which is problematic if what the '\' precedes is an ordinary character that should be subject to nondeterministic matching. We'd insist on a literal match for it, which is not right and is not like what happens with a '\' that follows some ordinary characters. Worse, we'd then advance the text and pattern pointers by one byte, so that if the escaped character is multibyte the next loop iteration would take the nondeterministic code path starting at a point within the character. That could very possibly cause pg_strncoll() to misbehave. The fix is quite simple: move the stanza that handles '\' down past the one that handles nondeterminism. The stanzas for '%' and '_' are fine where they are, but the '\' stanza is only correct for deterministic matching. The logic for nondeterministic cases is already prepared to do the right things with a '\'. While here, I replaced tests of "locale && !locale->deterministic" with a boolean local variable, reasoning that those are in the hot loop paths so saving a branch and indirect fetch is worth the trouble. I also improved a number of related comments. Author: Tom Lane Discussion: https://postgr.es/m/391592.1783187986@sss.pgh.pa.us Backpatch-through: 18 --- src/backend/utils/adt/like_match.c | 76 +++++++++++-------- .../regress/expected/collate.icu.utf8.out | 30 ++++++++ src/test/regress/sql/collate.icu.utf8.sql | 6 ++ 3 files changed, 80 insertions(+), 32 deletions(-) diff --git a/src/backend/utils/adt/like_match.c b/src/backend/utils/adt/like_match.c index ddaf6b1806a..defcaa96fb5 100644 --- a/src/backend/utils/adt/like_match.c +++ b/src/backend/utils/adt/like_match.c @@ -83,6 +83,8 @@ static int MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale) { + bool nondeterministic = (locale && !locale->deterministic); + /* Fast path for match-everything pattern */ if (plen == 1 && *p == '%') return LIKE_TRUE; @@ -96,23 +98,16 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale) * occasions it is safe to advance by byte, as the text and pattern will * be in lockstep. This allows us to perform all comparisons between the * text and pattern on a byte by byte basis, even for multi-byte - * encodings. + * encodings. (But that doesn't work in a nondeterministic locale, so the + * nondeterministic case below has to advance the text by chars.) */ while (tlen > 0 && plen > 0) { - if (*p == '\\') - { - /* Next pattern byte must match literally, whatever it is */ - NextByte(p, plen); - /* ... and there had better be one, per SQL standard */ - if (plen <= 0) - ereport(ERROR, - (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE), - errmsg("LIKE pattern must not end with escape character"))); - if (GETCHAR(*p) != GETCHAR(*t)) - return LIKE_FALSE; - } - else if (*p == '%') + /* + * At the top of this loop, we are not positioned immediately after an + * escape, so we may take wildcards at face value. + */ + if (*p == '%') { char firstpat; @@ -161,9 +156,9 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale) * the first pattern byte to each text byte to avoid recursing * more than we have to. This fact also guarantees that we don't * have to consider a match to the zero-length substring at the - * end of the text. With a nondeterministic collation, we can't - * rely on the first bytes being equal, so we have to recurse in - * any case. + * end of the text. But with a nondeterministic locale, we can't + * rely on the first byte of a match being equal, so we have to + * recurse in any case. */ if (*p == '\\') { @@ -178,7 +173,7 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale) while (tlen > 0) { - if (GETCHAR(*t) == firstpat || (locale && !locale->deterministic)) + if (GETCHAR(*t) == firstpat || nondeterministic) { int matched = MatchText(t, tlen, p, plen, locale); @@ -202,7 +197,7 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale) NextByte(p, plen); continue; } - else if (locale && !locale->deterministic) + else if (nondeterministic) { /* * For nondeterministic locales, we find the next substring of the @@ -222,9 +217,9 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale) char *buf = NULL; /* - * Determine next substring of pattern without wildcards. p is - * the start of the subpattern, p1 is one past the last byte. Also - * track if we found an escape character. + * Determine length of substring of pattern without wildcards. p + * is the start of the subpattern, p1 will advance to one past its + * last byte. Also track if we found an escape character. */ p1 = p; p1len = plen; @@ -242,12 +237,15 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale) } else if (*p1 == '_' || *p1 == '%') break; + /* Advance over regular or escaped character */ NextByte(p1, p1len); } /* - * If we found an escape character, then make an unescaped copy of - * the subpattern. + * If we found an escape character, then make a de-escaped copy of + * the subpattern that we can use to match literally. Otherwise + * we can use the subpattern in-place. (buf holds the de-escaped + * copy; be sure to pfree it before returning.) */ if (found_escape) { @@ -289,9 +287,10 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale) } /* - * Now build a substring of the text and try to match it against - * the subpattern. t is the start of the text, t1 is one past the - * last byte. We start with a zero-length string. + * Consider each successively-longer substring of the remaining + * text and try to match it against the subpattern. t is the + * start of the substring, t1 is one past its last byte. We start + * with a zero-length substring. */ t1 = t; t1len = tlen; @@ -299,16 +298,16 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale) { int cmp; + /* This could be slow, so allow interrupts */ CHECK_FOR_INTERRUPTS(); cmp = pg_strncoll(subpat, subpatlen, t, (t1 - t), locale); /* * If we found a match, we have to test if the rest of pattern - * can match against the rest of the string. Otherwise we - * have to continue here try matching with a longer substring. - * (This is similar to the recursion for the '%' wildcard - * above.) + * can match against the rest of the text. If not, we have to + * continue and try the next longer substring. (This is + * similar to the recursion for the '%' wildcard above.) * * Note that we can't just wind forward p and t and continue * with the main loop. This would fail for example with @@ -343,7 +342,20 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale) } else NextChar(t1, t1len); - } + } /* end loop over substrings starting at t */ + } + /* the rest of this loop considers only deterministic cases */ + else if (*p == '\\') + { + /* Next pattern byte must match literally, whatever it is */ + NextByte(p, plen); + /* ... and there had better be one, per SQL standard */ + if (plen <= 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE), + errmsg("LIKE pattern must not end with escape character"))); + if (GETCHAR(*p) != GETCHAR(*t)) + return LIKE_FALSE; } else if (GETCHAR(*p) != GETCHAR(*t)) { diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out index 3209964cc44..fcfcc658bea 100644 --- a/src/test/regress/expected/collate.icu.utf8.out +++ b/src/test/regress/expected/collate.icu.utf8.out @@ -1481,6 +1481,36 @@ SELECT 'abc' <= 'ABC' COLLATE case_insensitive, 'abc' >= 'ABC' COLLATE case_inse t | t (1 row) +SELECT 'AB' LIKE 'ab' COLLATE case_insensitive AS t; + t +--- + t +(1 row) + +SELECT 'AB' LIKE 'a\b' COLLATE case_insensitive AS t; + t +--- + t +(1 row) + +SELECT 'AB' LIKE '\ab' COLLATE case_insensitive AS t; + t +--- + t +(1 row) + +SELECT 'AB' LIKE '\a%' COLLATE case_insensitive AS t; + t +--- + t +(1 row) + +SELECT 'AB' LIKE '\a\%' COLLATE case_insensitive AS f; + f +--- + f +(1 row) + -- tests with array_sort SELECT array_sort('{a,B}'::text[] COLLATE case_insensitive); array_sort diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql index 3cee7223f95..ce4e2bb3ffd 100644 --- a/src/test/regress/sql/collate.icu.utf8.sql +++ b/src/test/regress/sql/collate.icu.utf8.sql @@ -568,6 +568,12 @@ CREATE COLLATION case_insensitive (provider = icu, locale = '@colStrength=second SELECT 'abc' <= 'ABC' COLLATE case_sensitive, 'abc' >= 'ABC' COLLATE case_sensitive; SELECT 'abc' <= 'ABC' COLLATE case_insensitive, 'abc' >= 'ABC' COLLATE case_insensitive; +SELECT 'AB' LIKE 'ab' COLLATE case_insensitive AS t; +SELECT 'AB' LIKE 'a\b' COLLATE case_insensitive AS t; +SELECT 'AB' LIKE '\ab' COLLATE case_insensitive AS t; +SELECT 'AB' LIKE '\a%' COLLATE case_insensitive AS t; +SELECT 'AB' LIKE '\a\%' COLLATE case_insensitive AS f; + -- tests with array_sort SELECT array_sort('{a,B}'::text[] COLLATE case_insensitive); SELECT array_sort('{a,B}'::text[] COLLATE "C"); From da8889ccd7ea0782a22a2300abc8fb801ecfa160 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 6 Jul 2026 15:34:12 -0400 Subject: [PATCH 099/481] Use PG_MODULE_MAGIC_EXT in newly introduced modules We forgot to use the PG_MODULE_MAGIC_EXT in some newly added modules: pg_plan_advice, pg_stash_advice and the pgrepack output plugin and instead used the older PG_MODULE_MAGIC macro. Author: Andreas Karlsson Discussion: http://postgr.es/m/ad7b910c-d145-4120-994d-2e55c456aa75@proxel.se Backpatch-through: 19 --- contrib/pg_plan_advice/pg_plan_advice.c | 5 ++++- contrib/pg_stash_advice/pg_stash_advice.c | 5 ++++- src/backend/replication/pgrepack/pgrepack.c | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/contrib/pg_plan_advice/pg_plan_advice.c b/contrib/pg_plan_advice/pg_plan_advice.c index 299b0d02a86..7cd753ee171 100644 --- a/contrib/pg_plan_advice/pg_plan_advice.c +++ b/contrib/pg_plan_advice/pg_plan_advice.c @@ -28,7 +28,10 @@ #include "storage/dsm_registry.h" #include "utils/guc.h" -PG_MODULE_MAGIC; +PG_MODULE_MAGIC_EXT( + .name = "pg_plan_advice", + .version = PG_VERSION +); /* GUC variables */ char *pg_plan_advice_advice = NULL; diff --git a/contrib/pg_stash_advice/pg_stash_advice.c b/contrib/pg_stash_advice/pg_stash_advice.c index 1858c6a135a..777ff374599 100644 --- a/contrib/pg_stash_advice/pg_stash_advice.c +++ b/contrib/pg_stash_advice/pg_stash_advice.c @@ -22,7 +22,10 @@ #include "utils/guc.h" #include "utils/memutils.h" -PG_MODULE_MAGIC; +PG_MODULE_MAGIC_EXT( + .name = "pg_stash_advice", + .version = PG_VERSION +); /* Shared memory hash table parameters */ static dshash_parameters pgsa_stash_dshash_parameters = { diff --git a/src/backend/replication/pgrepack/pgrepack.c b/src/backend/replication/pgrepack/pgrepack.c index 959551f5724..5c5095bde4e 100644 --- a/src/backend/replication/pgrepack/pgrepack.c +++ b/src/backend/replication/pgrepack/pgrepack.c @@ -18,7 +18,10 @@ #include "replication/snapbuild.h" #include "utils/memutils.h" -PG_MODULE_MAGIC; +PG_MODULE_MAGIC_EXT( + .name = "pgrepack", + .version = PG_VERSION +); static void repack_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, bool is_init); From d30bfcbddca3b08f66d1207265d9ab7d8a7b95c1 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Tue, 7 Jul 2026 08:13:59 +0900 Subject: [PATCH 100/481] Enforce RETURNING typmod on SQL/JSON DEFAULT behavior expressions transformJsonBehavior() coerced an ON EMPTY / ON ERROR DEFAULT expression only when its type differed from the RETURNING type's OID. When the base type matched but the RETURNING type carried a type modifier (e.g. numeric(4,1) or varchar(3)), the coercion that enforces the typmod was skipped, so the DEFAULT value could violate the declared type: SELECT JSON_VALUE(jsonb '{}', '$.a' RETURNING numeric(4,1) DEFAULT 99999.999 ON EMPTY); returned 99999.999, which 99999.999::numeric(4,1) would reject; the value could even be stored into a numeric(4,1) column, as later coercions trust its already-correct type label. Fix by also coercing when the RETURNING type has a typmod, except for a NULL constant. coerce_to_target_type() is a no-op when the typmod already matches. The matching-OID short-circuit dates to 74c96699be3. Reported-by: Ewan Young Author: Ewan Young Discussion: https://postgr.es/m/CAON2xHPO9f4cAmyGn1mQ=VqoS7wN5rz4yOiqudxX78zninZpCw@mail.gmail.com Backpatch-through: 17 --- src/backend/parser/parse_expr.c | 11 +++++++++- .../regress/expected/sqljson_jsontable.out | 16 ++++++++++++++ .../regress/expected/sqljson_queryfuncs.out | 21 +++++++++++++++++++ src/test/regress/sql/sqljson_jsontable.sql | 9 ++++++++ src/test/regress/sql/sqljson_queryfuncs.sql | 8 +++++++ 5 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 9adc9d4c0f6..e6ea34a7809 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -4931,8 +4931,17 @@ transformJsonBehavior(ParseState *pstate, JsonExpr *jsexpr, * * For other non-NULL expressions, try to find a cast and error out if one * is not found. + * + * The DEFAULT expression's base type may already match the RETURNING type + * yet still need coercion: when the RETURNING type carries a type + * modifier (e.g. numeric(4,1)), the cast below is what enforces it, so + * skipping it here would let the DEFAULT yield a value that violates its + * declared RETURNING type. A NULL constant needs no such enforcement. */ - if (expr && exprType(expr) != returning->typid) + if (expr && + (exprType(expr) != returning->typid || + (returning->typmod >= 0 && + !(IsA(expr, Const) && ((Const *) expr)->constisnull)))) { bool isnull = (IsA(expr, Const) && ((Const *) expr)->constisnull); diff --git a/src/test/regress/expected/sqljson_jsontable.out b/src/test/regress/expected/sqljson_jsontable.out index 458c5aaa5b0..4d500e7de2d 100644 --- a/src/test/regress/expected/sqljson_jsontable.out +++ b/src/test/regress/expected/sqljson_jsontable.out @@ -250,6 +250,22 @@ SELECT * FROM JSON_TABLE(jsonb '{"d1": "foo"}', '$' {1} (1 row) +-- A DEFAULT expression whose base type matches the column type must still be +-- coerced to the column's typmod. +SELECT * FROM JSON_TABLE(jsonb '{}', '$' + COLUMNS (c numeric(4,1) PATH '$.x' DEFAULT 99999.999 ON EMPTY)); +ERROR: numeric field overflow +DETAIL: A field with precision 4, scale 1 must round to an absolute value less than 10^3. +SELECT * FROM JSON_TABLE(jsonb '{}', '$' + COLUMNS (c bit(3) PATH '$.x' DEFAULT b'10101' ON EMPTY)); +ERROR: bit string length 5 does not match type bit(3) +SELECT * FROM JSON_TABLE(jsonb '{}', '$' + COLUMNS (c numeric(4,1) PATH '$.x' DEFAULT abs(NULL::numeric) ON EMPTY)); + c +--- + +(1 row) + -- JSON_TABLE: Test backward parsing CREATE VIEW jsonb_table_view2 AS SELECT * FROM diff --git a/src/test/regress/expected/sqljson_queryfuncs.out b/src/test/regress/expected/sqljson_queryfuncs.out index 57e52e963f6..ff64dce0c59 100644 --- a/src/test/regress/expected/sqljson_queryfuncs.out +++ b/src/test/regress/expected/sqljson_queryfuncs.out @@ -433,6 +433,27 @@ SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int FORMAT JSON); -- RETURNING ERROR: cannot specify FORMAT JSON in RETURNING clause of JSON_VALUE() LINE 1: ...CT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int FORMAT JSO... ^ +-- A DEFAULT expression must be coerced to the RETURNING type's typmod even +-- when its base type already matches, but a matching NULL needs no coercion. +SELECT JSON_VALUE(jsonb '{}', '$.a' RETURNING numeric(4,1) DEFAULT 99999.999 ON EMPTY); +ERROR: numeric field overflow +DETAIL: A field with precision 4, scale 1 must round to an absolute value less than 10^3. +SELECT JSON_VALUE(jsonb '{}', '$.a' RETURNING varchar(3) DEFAULT 'toolong'::varchar(10) ON EMPTY); +ERROR: value too long for type character varying(3) +SELECT JSON_VALUE(jsonb '{}', '$.a' RETURNING numeric(4,1) DEFAULT NULL::numeric ON EMPTY); + json_value +------------ + +(1 row) + +SELECT JSON_VALUE(jsonb '{}', '$.a' RETURNING bit(3) DEFAULT b'10101' ON EMPTY); +ERROR: bit string length 5 does not match type bit(3) +SELECT JSON_VALUE(jsonb '{}', '$.a' RETURNING numeric(4,1) DEFAULT abs(NULL::numeric) ON EMPTY); + json_value +------------ + +(1 row) + -- RETUGNING pseudo-types not allowed SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING record); ERROR: returning pseudo-types is not supported in SQL/JSON functions diff --git a/src/test/regress/sql/sqljson_jsontable.sql b/src/test/regress/sql/sqljson_jsontable.sql index 154eea79c76..41824094b96 100644 --- a/src/test/regress/sql/sqljson_jsontable.sql +++ b/src/test/regress/sql/sqljson_jsontable.sql @@ -132,6 +132,15 @@ SELECT * FROM JSON_TABLE(jsonb '{"d1": "foo"}', '$' SELECT * FROM JSON_TABLE(jsonb '{"d1": "foo"}', '$' COLUMNS (js1 oid[] PATH '$.d2' DEFAULT '{1}'::int[]::oid[] ON EMPTY)); +-- A DEFAULT expression whose base type matches the column type must still be +-- coerced to the column's typmod. +SELECT * FROM JSON_TABLE(jsonb '{}', '$' + COLUMNS (c numeric(4,1) PATH '$.x' DEFAULT 99999.999 ON EMPTY)); +SELECT * FROM JSON_TABLE(jsonb '{}', '$' + COLUMNS (c bit(3) PATH '$.x' DEFAULT b'10101' ON EMPTY)); +SELECT * FROM JSON_TABLE(jsonb '{}', '$' + COLUMNS (c numeric(4,1) PATH '$.x' DEFAULT abs(NULL::numeric) ON EMPTY)); + -- JSON_TABLE: Test backward parsing CREATE VIEW jsonb_table_view2 AS diff --git a/src/test/regress/sql/sqljson_queryfuncs.sql b/src/test/regress/sql/sqljson_queryfuncs.sql index d218b44ea47..a69ef253f66 100644 --- a/src/test/regress/sql/sqljson_queryfuncs.sql +++ b/src/test/regress/sql/sqljson_queryfuncs.sql @@ -105,6 +105,14 @@ SELECT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR); SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR); SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int FORMAT JSON); -- RETURNING FORMAT not allowed +-- A DEFAULT expression must be coerced to the RETURNING type's typmod even +-- when its base type already matches, but a matching NULL needs no coercion. +SELECT JSON_VALUE(jsonb '{}', '$.a' RETURNING numeric(4,1) DEFAULT 99999.999 ON EMPTY); +SELECT JSON_VALUE(jsonb '{}', '$.a' RETURNING varchar(3) DEFAULT 'toolong'::varchar(10) ON EMPTY); +SELECT JSON_VALUE(jsonb '{}', '$.a' RETURNING numeric(4,1) DEFAULT NULL::numeric ON EMPTY); +SELECT JSON_VALUE(jsonb '{}', '$.a' RETURNING bit(3) DEFAULT b'10101' ON EMPTY); +SELECT JSON_VALUE(jsonb '{}', '$.a' RETURNING numeric(4,1) DEFAULT abs(NULL::numeric) ON EMPTY); + -- RETUGNING pseudo-types not allowed SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING record); From 7f0998f87b08e325ab65b1355464a1430042b9aa Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 7 Jul 2026 08:37:15 +0200 Subject: [PATCH 101/481] Update GROUP BY ALL comments about window functions When GROUP BY ALL was added in commit ef38a4d9756, the SQL standard working draft was silent on what to do with window functions. This has now been fixed in the SQL standard working draft. Update the documentation and code comments about that. Also make the documentation more specific that we are only talking about aggregate functions referring to the same query level, which is another thing that has been made more precise in the SQL standard working draft since. The PostgreSQL implementation was already doing the right thing for both aspects, so no functionality changes. Reviewed-by: Tom Lane Discussion: https://www.postgresql.org/message-id/flat/CAHM0NXjz0kDwtzoe-fnHAqPB1qA8_VJN0XAmCgUZ%2BiPnvP5LbA%40mail.gmail.com --- doc/src/sgml/queries.sgml | 2 +- doc/src/sgml/ref/select.sgml | 3 ++- src/backend/parser/parse_clause.c | 4 +--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/queries.sgml b/doc/src/sgml/queries.sgml index d8d4c3c53ef..b3cfbc93582 100644 --- a/doc/src/sgml/queries.sgml +++ b/doc/src/sgml/queries.sgml @@ -1162,7 +1162,7 @@ SELECT product_id, p.name, (sum(s.units) * p.price) AS sales PostgreSQL also supports the syntax GROUP BY ALL, which is equivalent to explicitly writing all select-list entries that - do not contain either an aggregate function or a window function. + do not contain either an aggregate function referring to the same query level or a window function. This can greatly simplify ad-hoc exploration of data. As an example, these queries are equivalent: diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml index 09b6ce809bb..8d5a751af7e 100644 --- a/doc/src/sgml/ref/select.sgml +++ b/doc/src/sgml/ref/select.sgml @@ -862,7 +862,8 @@ GROUP BY { ALL | [ ALL | DISTINCT ] grouping_elem grouping_elements provided is equivalent to writing GROUP BY with the numbers of all SELECT output columns that do not - contain either an aggregate function or a window function. + contain either an aggregate function referring to the same query level or + a window function. diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 881fba2e7b5..2f7333e6786 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -2817,9 +2817,7 @@ transformGroupClause(ParseState *pstate, List *grouplist, bool groupByAll, /* * Likewise, TLEs containing window functions are not okay to add - * to GROUP BY. At this writing, the SQL standard is silent on - * what to do with them, but by analogy to aggregates we'll just - * skip them. + * to GROUP BY, and the SQL standard directs us to skip them. */ if (pstate->p_hasWindowFuncs && contain_windowfuncs((Node *) tle->expr)) From 0021794f4c5778348418fc2f5658f3b3cb2f2e86 Mon Sep 17 00:00:00 2001 From: Etsuro Fujita Date: Tue, 7 Jul 2026 18:40:00 +0900 Subject: [PATCH 102/481] postgres_fdw: Report ANALYZE to pgstats after importing statistics. Commit 28972b6fc should have done this, but didn't. While at it, remove an extra blank line in fetch_remote_statistics() introduced by that commit. Reported-by: Chao Li Co-authored-by: Chao Li Co-authored-by: Etsuro Fujita Discussion: https://postgr.es/m/6ED81190-B398-44C9-A1E9-8EFE4ED183AF%40gmail.com Backpatch-through: 19 --- .../postgres_fdw/expected/postgres_fdw.out | 40 +++++++++++++++++++ contrib/postgres_fdw/postgres_fdw.c | 18 ++++++++- contrib/postgres_fdw/sql/postgres_fdw.sql | 10 +++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 0805c56cb1b..5ebae1cedc2 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -12973,9 +12973,29 @@ ALTER FOREIGN TABLE simport_ftable OPTIONS (ADD restore_stats 'true'); ANALYZE simport_ftable; -- should fail WARNING: could not import statistics for foreign table "public.simport_ftable" --- remote table "public.simport_table" has no relation statistics to import ANALYZE simport_table; +SELECT pg_stat_reset_single_table_counters('public.simport_ftable'::regclass); + pg_stat_reset_single_table_counters +------------------------------------- + +(1 row) + ANALYZE VERBOSE simport_ftable; -- should work INFO: importing statistics for foreign table "public.simport_ftable" INFO: finished importing statistics for foreign table "public.simport_ftable" +SELECT pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +SELECT pg_stat_get_live_tuples('public.simport_ftable'::regclass), + pg_stat_get_dead_tuples('public.simport_ftable'::regclass), + pg_stat_get_analyze_count('public.simport_ftable'::regclass); + pg_stat_get_live_tuples | pg_stat_get_dead_tuples | pg_stat_get_analyze_count +-------------------------+-------------------------+--------------------------- + 0 | 0 | 1 +(1 row) + ALTER TABLE simport_table ALTER COLUMN c1 SET STATISTICS 0; ALTER TABLE simport_table ALTER COLUMN c2 SET STATISTICS 0; INSERT INTO simport_table VALUES (1, 'foo'), (1, 'foo'), (2, 'bar'), (2, 'bar'); @@ -12988,9 +13008,29 @@ ANALYZE simport_ftable; -- should fail WARNING: could not import statistics for foreign table "public.simport_ftable" --- no attribute statistics found for column "c2" of remote table "public.simport_table" ALTER TABLE simport_table ALTER COLUMN c2 SET STATISTICS DEFAULT; ANALYZE simport_table; +SELECT pg_stat_reset_single_table_counters('public.simport_ftable'::regclass); + pg_stat_reset_single_table_counters +------------------------------------- + +(1 row) + ANALYZE VERBOSE simport_ftable; -- should work INFO: importing statistics for foreign table "public.simport_ftable" INFO: finished importing statistics for foreign table "public.simport_ftable" +SELECT pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +SELECT pg_stat_get_live_tuples('public.simport_ftable'::regclass), + pg_stat_get_dead_tuples('public.simport_ftable'::regclass), + pg_stat_get_analyze_count('public.simport_ftable'::regclass); + pg_stat_get_live_tuples | pg_stat_get_dead_tuples | pg_stat_get_analyze_count +-------------------------+-------------------------+--------------------------- + 4 | 0 | 1 +(1 row) + ANALYZE VERBOSE simport_ftable (c1); -- should work INFO: importing statistics for foreign table "public.simport_ftable" INFO: finished importing statistics for foreign table "public.simport_ftable" diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 6dbae583ecc..12059ec8544 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -41,6 +41,7 @@ #include "optimizer/restrictinfo.h" #include "optimizer/tlist.h" #include "parser/parsetree.h" +#include "pgstat.h" #include "postgres_fdw.h" #include "statistics/statistics.h" #include "storage/latch.h" @@ -52,6 +53,7 @@ #include "utils/rel.h" #include "utils/sampling.h" #include "utils/selfuncs.h" +#include "utils/timestamp.h" PG_MODULE_MAGIC_EXT( .name = "postgres_fdw", @@ -336,6 +338,8 @@ typedef struct PGresult *rel; PGresult *att; int server_version_num; + double livetuples; + double deadtuples; } RemoteStatsResults; /* Column order in relation stats query */ @@ -5597,6 +5601,7 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel) RemoteStatsResults remstats = {.rel = NULL, .att = NULL}; RemoteAttributeMapping *remattrmap = NULL; int attrcnt = 0; + TimestampTz starttime = 0; bool restore_stats = false; bool ok = false; ListCell *lc; @@ -5656,6 +5661,8 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel) (errmsg("importing statistics for foreign table \"%s.%s\"", schemaname, relname))); + starttime = GetCurrentTimestamp(); + ok = fetch_remote_statistics(relation, va_cols, table, schemaname, relname, &attrcnt, &remattrmap, &remstats); @@ -5665,9 +5672,15 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel) attrcnt, remattrmap, &remstats); if (ok) + { + pgstat_report_analyze(relation, + remstats.livetuples, remstats.deadtuples, + (va_cols == NIL), starttime); + ereport(elevel, (errmsg("finished importing statistics for foreign table \"%s.%s\"", schemaname, relname))); + } PQclear(remstats.rel); PQclear(remstats.att); @@ -5780,7 +5793,6 @@ fetch_remote_statistics(Relation relation, goto fetch_cleanup; } - if (reltuples > 0) { StringInfoData column_list; @@ -5807,6 +5819,10 @@ fetch_remote_statistics(Relation relation, } } + /* We assume that we have no dead tuple. */ + remstats->deadtuples = 0.0; + remstats->livetuples = reltuples; + ok = true; fetch_cleanup: diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index 8162c5496bf..e868da00ace 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -4587,7 +4587,12 @@ ANALYZE simport_ftable; -- should fail ANALYZE simport_table; +SELECT pg_stat_reset_single_table_counters('public.simport_ftable'::regclass); ANALYZE VERBOSE simport_ftable; -- should work +SELECT pg_stat_force_next_flush(); +SELECT pg_stat_get_live_tuples('public.simport_ftable'::regclass), + pg_stat_get_dead_tuples('public.simport_ftable'::regclass), + pg_stat_get_analyze_count('public.simport_ftable'::regclass); ALTER TABLE simport_table ALTER COLUMN c1 SET STATISTICS 0; ALTER TABLE simport_table ALTER COLUMN c2 SET STATISTICS 0; @@ -4604,7 +4609,12 @@ ANALYZE simport_ftable; -- should fail ALTER TABLE simport_table ALTER COLUMN c2 SET STATISTICS DEFAULT; ANALYZE simport_table; +SELECT pg_stat_reset_single_table_counters('public.simport_ftable'::regclass); ANALYZE VERBOSE simport_ftable; -- should work +SELECT pg_stat_force_next_flush(); +SELECT pg_stat_get_live_tuples('public.simport_ftable'::regclass), + pg_stat_get_dead_tuples('public.simport_ftable'::regclass), + pg_stat_get_analyze_count('public.simport_ftable'::regclass); ANALYZE VERBOSE simport_ftable (c1); -- should work From fcd58c6d9642487eb97e9cf7699daddb3951bc9a Mon Sep 17 00:00:00 2001 From: David Rowley Date: Tue, 7 Jul 2026 23:58:29 +1200 Subject: [PATCH 103/481] Fix COUNT's logic for window run condition support 9d9c02ccd added code to allow the executor to stop early when processing WindowAgg nodes where a monotonic window function starts producing values that result in a pushed-down qual no longer matching, and will never match again due to the window function's monotonic properties. That commit requires a SupportRequestWFuncMonotonic to exist on the window function and for it to detect when the function is monotonic. For COUNT(ANY) and COUNT(*), the support function failed to consider some cases where the WindowClause used EXCLUDE to exclude certain rows from being aggregated. Some WindowClause definitions mean we aggregate rows that come after the current row, and when processing those rows later, if we EXCLUDE certain rows, the monotonic property can be broken. Wrongly treating the COUNT(*) or COUNT(ANY) aggregate as monotonic could lead to rows being filtered that should not be filtered from the result set. Another issue was that the support function for the COUNT aggregate mistakenly thought that a WindowClause without an ORDER BY meant that the results would be both monotonically increasing and decreasing, but that's only true when in RANGE mode, where all rows are peers. It is possible to support various cases that do have an EXCLUDE clause, but getting the logic correct for the exact set of cases that are valid is quite complex and would likely better be left for a future project. Here, we mostly disable run condition pushdown when there is an EXCLUDE clause unless the clause is for EXCLUDE CURRENT ROW, uses COUNT(*) (rather than COUNT(ANY)), and the window aggregate has no FILTER clause. Bug: #19533 Reported-by: Qifan Liu Author: Chengpeng Yan Author: David Rowley Reviewed-by: Richard Guo Reviewed-by: John Naylor Discussion: https://postgr.es/m/19533-413a1014e5d0e766@postgresql.org Backpatch-through: 15 --- src/backend/utils/adt/int8.c | 34 ++++- src/test/regress/expected/window.out | 221 ++++++++++++++++++++++++++- src/test/regress/sql/window.sql | 115 +++++++++++++- 3 files changed, 361 insertions(+), 9 deletions(-) diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c index 9b429da86d9..1f59d831600 100644 --- a/src/backend/utils/adt/int8.c +++ b/src/backend/utils/adt/int8.c @@ -795,8 +795,38 @@ int8inc_support(PG_FUNCTION_ARGS) MonotonicFunction monotonic = MONOTONICFUNC_NONE; int frameOptions = req->window_clause->frameOptions; - /* No ORDER BY clause then all rows are peers */ - if (req->window_clause->orderClause == NIL) + /* + * Because an EXCLUDE clauses in the window definition can exclude + * rows that have previously been included in the aggregate result for + * prior rows, this can break the monotonic properties that might + * otherwise be guaranteed. There's a narrow set of circumstances + * that can be guaranteed, which we check for below. + */ + if (frameOptions & FRAMEOPTION_EXCLUSION) + { + WindowFunc *wfunc = req->window_func; + + /* + * To add handling for all valid monotonic cases with an EXCLUDE + * clause is complex and likely not worth troubling over. For + * now, just bail unless we see EXCLUDE CURRENT ROW with COUNT(*) + * and no FILTER. Excluding the current row is fine when using + * COUNT(*) as this always reduces the count by 1. The same isn't + * true for COUNY(ANY) as a NULL won't be counted, and a + * subsequent non-NULL could make the count decrease. + */ + if ((frameOptions & FRAMEOPTION_EXCLUDE_CURRENT_ROW) == 0 || + wfunc->winfnoid != F_COUNT_ || + wfunc->aggfilter != NULL) + { + req->monotonic = MONOTONICFUNC_NONE; + PG_RETURN_POINTER(req); + } + } + + /* No ORDER BY clause and RANGE mode means all rows are peers. */ + if (req->window_clause->orderClause == NIL && + (frameOptions & FRAMEOPTION_RANGE)) monotonic = MONOTONICFUNC_BOTH; else { diff --git a/src/test/regress/expected/window.out b/src/test/regress/expected/window.out index 90d9f953b81..c0bde1c5eec 100644 --- a/src/test/regress/expected/window.out +++ b/src/test/regress/expected/window.out @@ -4232,23 +4232,59 @@ WHERE c <= 3; (8 rows) -- Ensure we get the correct run condition when the window function is both --- monotonically increasing and decreasing. +-- monotonically increasing and decreasing in RANGE mode without an ORDER BY EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, depname, salary, - count(empno) OVER () c + count(empno) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) c FROM empsalary) emp WHERE c = 1; - QUERY PLAN -------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------- WindowAgg - Window: w1 AS () + Window: w1 AS (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) Run Condition: (count(empsalary.empno) OVER w1 = 1) -> Seq Scan on empsalary (4 rows) +-- As above, but check we detect it's monotonically increasing +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + QUERY PLAN +------------------------------------------------------------- + WindowAgg + Window: w1 AS (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) + Run Condition: (count(empsalary.empno) OVER w1 <= 3) + -> Seq Scan on empsalary +(4 rows) + +-- Ensure that ROWS mode without an ORDER BY doesn't think it's monotonically +-- decreasing, i.e. don't push down the run condition. +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER (ROWS BETWEEN CURRENT ROW AND CURRENT ROW) c + FROM empsalary) emp +WHERE c > 1; + QUERY PLAN +------------------------------------------------------------------ + Subquery Scan on emp + Filter: (emp.c > 1) + -> WindowAgg + Window: w1 AS (ROWS BETWEEN CURRENT ROW AND CURRENT ROW) + -> Seq Scan on empsalary +(5 rows) + -- Try another case with a WindowFunc with a byref return type SELECT * FROM (SELECT row_number() OVER (PARTITION BY salary) AS rn, @@ -4436,6 +4472,181 @@ WHERE c = 1; -> Seq Scan on empsalary (9 rows) +-- +-- Ensure we get the correct behavior for run condition pushdown when the +-- frame option has an EXCLUDE clause +-- +-- Ensure pushdown occurs for ROWS BETWEEN UNBOUNDED PRECEDING with EXCLUDE +-- CURRENT ROW with COUNT(*) +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------- + WindowAgg + Window: w1 AS (ORDER BY empsalary.salary ROWS BETWEEN UNBOUNDED PRECEDING AND '0'::bigint PRECEDING EXCLUDE CURRENT ROW) + Run Condition: (count(*) OVER w1 <= 3) + -> Sort + Sort Key: empsalary.salary + -> Seq Scan on empsalary +(6 rows) + +-- Ensure pushdown occurs for GROUPS BETWEEN UNBOUNDED PRECEDING with EXCLUDE +-- CURRENT ROW with COUNT(*) +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + WindowAgg + Window: w1 AS (ORDER BY empsalary.salary GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW) + Run Condition: (count(*) OVER w1 <= 3) + -> Sort + Sort Key: empsalary.salary + -> Seq Scan on empsalary +(6 rows) + +-- Ensure pushdown occurs for RANGE BETWEEN UNBOUNDED PRECEDING with EXCLUDE +-- CURRENT ROW with COUNT(*) +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + WindowAgg + Window: w1 AS (ORDER BY empsalary.salary RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW) + Run Condition: (count(*) OVER w1 <= 3) + -> Sort + Sort Key: empsalary.salary + -> Seq Scan on empsalary +(6 rows) + +-- Ensure we don't get pushdown when a FILTER clause is present +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) FILTER (WHERE salary > 4000) OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------- + Subquery Scan on emp + Filter: (emp.c <= 3) + -> WindowAgg + Window: w1 AS (ORDER BY empsalary.salary ROWS BETWEEN UNBOUNDED PRECEDING AND '0'::bigint PRECEDING EXCLUDE CURRENT ROW) + -> Sort + Sort Key: empsalary.salary + -> Seq Scan on empsalary +(7 rows) + +-- Ensure we don't get pushdown with COUNT(ANY) +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(salary) OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------- + Subquery Scan on emp + Filter: (emp.c <= 3) + -> WindowAgg + Window: w1 AS (ORDER BY empsalary.salary ROWS BETWEEN UNBOUNDED PRECEDING AND '0'::bigint PRECEDING EXCLUDE CURRENT ROW) + -> Sort + Sort Key: empsalary.salary + -> Seq Scan on empsalary +(7 rows) + +-- Ensure we don't get pushdown with EXCLUDE GROUP +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE GROUP) c + FROM empsalary) emp +WHERE c <= 3; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------- + Subquery Scan on emp + Filter: (emp.c <= 3) + -> WindowAgg + Window: w1 AS (ORDER BY empsalary.salary ROWS BETWEEN UNBOUNDED PRECEDING AND '0'::bigint PRECEDING EXCLUDE GROUP) + -> Sort + Sort Key: empsalary.salary + -> Seq Scan on empsalary +(7 rows) + +-- Ensure we don't get pushdown with EXCLUDE TIES +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE TIES) c + FROM empsalary) emp +WHERE c <= 3; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Subquery Scan on emp + Filter: (emp.c <= 3) + -> WindowAgg + Window: w1 AS (ORDER BY empsalary.salary ROWS BETWEEN UNBOUNDED PRECEDING AND '0'::bigint PRECEDING EXCLUDE TIES) + -> Sort + Sort Key: empsalary.salary + -> Seq Scan on empsalary +(7 rows) + +-- Ensure we don't get pushdown with GROUPS mode and EXCLUDE GROUP +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary GROUPS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE GROUP) c + FROM empsalary) emp +WHERE c <= 3; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------ + Subquery Scan on emp + Filter: (emp.c <= 3) + -> WindowAgg + Window: w1 AS (ORDER BY empsalary.salary GROUPS BETWEEN UNBOUNDED PRECEDING AND '0'::bigint PRECEDING EXCLUDE GROUP) + -> Sort + Sort Key: empsalary.salary + -> Seq Scan on empsalary +(7 rows) + +-- Ensure we don't get pushdown with GROUPS mode and EXCLUDE TIES +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary GROUPS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE TIES) c + FROM empsalary) emp +WHERE c <= 3; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Subquery Scan on emp + Filter: (emp.c <= 3) + -> WindowAgg + Window: w1 AS (ORDER BY empsalary.salary GROUPS BETWEEN UNBOUNDED PRECEDING AND '0'::bigint PRECEDING EXCLUDE TIES) + -> Sort + Sort Key: empsalary.salary + -> Seq Scan on empsalary +(7 rows) + -- Test Sort node collapsing EXPLAIN (COSTS OFF) SELECT * FROM diff --git a/src/test/regress/sql/window.sql b/src/test/regress/sql/window.sql index 5ac3a486e16..8e6f92d94c7 100644 --- a/src/test/regress/sql/window.sql +++ b/src/test/regress/sql/window.sql @@ -1361,16 +1361,37 @@ SELECT * FROM WHERE c <= 3; -- Ensure we get the correct run condition when the window function is both --- monotonically increasing and decreasing. +-- monotonically increasing and decreasing in RANGE mode without an ORDER BY EXPLAIN (COSTS OFF) SELECT * FROM (SELECT empno, depname, salary, - count(empno) OVER () c + count(empno) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) c FROM empsalary) emp WHERE c = 1; +-- As above, but check we detect it's monotonically increasing +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + +-- Ensure that ROWS mode without an ORDER BY doesn't think it's monotonically +-- decreasing, i.e. don't push down the run condition. +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER (ROWS BETWEEN CURRENT ROW AND CURRENT ROW) c + FROM empsalary) emp +WHERE c > 1; + -- Try another case with a WindowFunc with a byref return type SELECT * FROM (SELECT row_number() OVER (PARTITION BY salary) AS rn, @@ -1460,6 +1481,96 @@ SELECT * FROM FROM empsalary) emp WHERE c = 1; +-- +-- Ensure we get the correct behavior for run condition pushdown when the +-- frame option has an EXCLUDE clause +-- + +-- Ensure pushdown occurs for ROWS BETWEEN UNBOUNDED PRECEDING with EXCLUDE +-- CURRENT ROW with COUNT(*) +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + +-- Ensure pushdown occurs for GROUPS BETWEEN UNBOUNDED PRECEDING with EXCLUDE +-- CURRENT ROW with COUNT(*) +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + +-- Ensure pushdown occurs for RANGE BETWEEN UNBOUNDED PRECEDING with EXCLUDE +-- CURRENT ROW with COUNT(*) +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + +-- Ensure we don't get pushdown when a FILTER clause is present +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) FILTER (WHERE salary > 4000) OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + +-- Ensure we don't get pushdown with COUNT(ANY) +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(salary) OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE CURRENT ROW) c + FROM empsalary) emp +WHERE c <= 3; + +-- Ensure we don't get pushdown with EXCLUDE GROUP +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE GROUP) c + FROM empsalary) emp +WHERE c <= 3; + +-- Ensure we don't get pushdown with EXCLUDE TIES +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE TIES) c + FROM empsalary) emp +WHERE c <= 3; + +-- Ensure we don't get pushdown with GROUPS mode and EXCLUDE GROUP +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary GROUPS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE GROUP) c + FROM empsalary) emp +WHERE c <= 3; + +-- Ensure we don't get pushdown with GROUPS mode and EXCLUDE TIES +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary GROUPS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING EXCLUDE TIES) c + FROM empsalary) emp +WHERE c <= 3; + + -- Test Sort node collapsing EXPLAIN (COSTS OFF) SELECT * FROM From 4746a35e45ab360fa3408da0367c4165a5cb8837 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Tue, 7 Jul 2026 18:11:28 +0300 Subject: [PATCH 104/481] pg_dump: check for _beginthreadex() failure in parallel dump ParallelBackupStart() stored _beginthreadex()'s return value as the worker's thread handle without checking it. On failure that value is 0, which would later reach WaitForMultipleObjects() as a null handle, caught only by an Assert. The fork() path already calls pg_fatal() when it fails; do the same for _beginthreadex(), as pgbench does. Author: Bryan Green Discussion: https://www.postgresql.org/message-id/8c712d76-ecf7-4749-a6d8-dddc01f298ec@gmail.com Backpatch-through: 14 --- src/bin/pg_dump/parallel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c index 7e2e9f958ea..abcf0d55277 100644 --- a/src/bin/pg_dump/parallel.c +++ b/src/bin/pg_dump/parallel.c @@ -976,6 +976,8 @@ ParallelBackupStart(ArchiveHandle *AH) handle = _beginthreadex(NULL, 0, (void *) &init_spawned_worker_win32, wi, 0, &(slot->threadId)); + if (handle == 0) + pg_fatal("could not create worker thread: %m"); slot->hThread = handle; slot->workerStatus = WRKR_IDLE; #else /* !WIN32 */ From f74a45a5416fb18c391b3a1651e29ada78106c43 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Tue, 7 Jul 2026 17:39:28 +0200 Subject: [PATCH 105/481] Replace hardcoded mentions of pg_hosts.conf with GUC Three error messages were using the default file name pg_hosts.conf and not the variable backing the GUC, which would make logging be confusing for users who have renamed the file using the GUC. Fix by consistently using the HostsFileName variable. Backpatch down to v19 where serverside SNI was introduced. Author: Zsolt Parragi Reviewed-by: Surya Poondla Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/CAN4CZFMARYjQfgyRaCKOXDO=Q91kuKn=pSC02DAOOr23ojhEGQ@mail.gmail.com Backpatch-through: 19 --- src/backend/libpq/be-secure-openssl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 7890e6c2de2..4ce2a92b964 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -228,7 +228,7 @@ be_tls_init(bool isServerStart) { ereport(isServerStart ? FATAL : LOG, errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("could not load \"%s\": %s", "pg_hosts.conf", + errmsg("could not load \"%s\": %s", HostsFileName, err_msg ? err_msg : "unknown error")); goto error; } @@ -365,7 +365,7 @@ be_tls_init(bool isServerStart) errmsg("no SSL configurations loaded"), /*- translator: The two %s contain filenames */ errhint("If ssl_sni is enabled then add configuration to \"%s\", else \"%s\"", - "pg_hosts.conf", "postgresql.conf")); + HostsFileName, "postgresql.conf")); goto error; } @@ -644,7 +644,7 @@ init_host_context(HostsLine *host, bool isServerStart) "Set \"%s\" to \"off\" to make use of the hook " "that is currently installed, or remove the hook " "and use per-host passphrase commands in \"%s\".", - "ssl_sni", "pg_hosts.conf")); + "ssl_sni", HostsFileName)); init_warned = true; } From eeb2940ae83cb6a5e48e90465bea0cede341ea59 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Tue, 7 Jul 2026 18:45:34 +0300 Subject: [PATCH 106/481] libpq: Extend "read pending" check from SSL to GSS An extra check for pending bytes in the SSL layer has been part of pqReadReady() for a very long time (79ff2e96d). But when GSS transport encryption was added, it didn't receive the same treatment. (As 79ff2e96d notes, "The bug that I fixed in this patch is exceptionally hard to reproduce reliably.") Without that check, it's possible to hit a hang in gssencmode, if the server splits a large libpq message such that the final message in a streamed response is part of the same wrapped token as the split message: DataRowDataRowDataRowDataRowDataRowData -- token boundary -- RowDataRowCommandCompleteReadyForQuery If the split message takes up enough memory to nearly fill libpq's receive buffer, libpq may return from pqReadData() before the later messages are pulled out of the PqGSSRecvBuffer. Without additional socket activity from the server, pqReadReady() (via pqSocketCheck()) will never again return true, hanging the connection. Pull the pending-bytes check into the pqsecure API layer, where both SSL and GSS now implement it. Note that this does not fix the root problem! Third party clients of libpq have no way to call pqsecure_read_is_pending() in their own polling. This just brings the GSS implementation up to par with the existing SSL workaround; a broader fix is left to a subsequent commit. In preparation for the broader fix, this patch already changes the *_read_pending() functions to return the number of bytes in the buffer rather than just a boolean. The current callers don't need that, but the subsequent fix will. Author: Jacob Champion Discussion: https://postgr.es/m/CAOYmi%2BmpymrgZ76Jre2dx_PwRniS9YZojwH0rZnTuiGHCsj0rA%40mail.gmail.com Backpatch-through: 14 --- src/interfaces/libpq/fe-misc.c | 6 ++--- src/interfaces/libpq/fe-secure-gssapi.c | 7 +++++ src/interfaces/libpq/fe-secure-openssl.c | 34 +++++++++++++++++++++--- src/interfaces/libpq/fe-secure.c | 22 +++++++++++++++ src/interfaces/libpq/libpq-int.h | 6 +++-- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index 905344d5c38..58ccca1e393 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -1099,14 +1099,12 @@ pqSocketCheck(PGconn *conn, int forRead, int forWrite, pg_usec_time_t end_time) return -1; } -#ifdef USE_SSL - /* Check for SSL library buffering read bytes */ - if (forRead && conn->ssl_in_use && pgtls_read_pending(conn)) + /* Check for SSL/GSS library buffering read bytes */ + if (forRead && pqsecure_bytes_pending(conn) != 0) { /* short-circuit the select */ return 1; } -#endif } /* We will retry as long as we get EINTR */ diff --git a/src/interfaces/libpq/fe-secure-gssapi.c b/src/interfaces/libpq/fe-secure-gssapi.c index 72f438dfa9c..cc60240582d 100644 --- a/src/interfaces/libpq/fe-secure-gssapi.c +++ b/src/interfaces/libpq/fe-secure-gssapi.c @@ -471,6 +471,13 @@ gss_read(PGconn *conn, void *recv_buffer, size_t length, ssize_t *ret) return PGRES_POLLING_OK; } +ssize_t +pg_GSS_bytes_pending(PGconn *conn) +{ + Assert(PqGSSResultLength >= PqGSSResultNext); + return (ssize_t) (PqGSSResultLength - PqGSSResultNext); +} + /* * Negotiate GSSAPI transport for a connection. When complete, returns * PGRES_POLLING_OK. Will return PGRES_POLLING_READING or diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 6b44eeb68eb..1b22ba7b7f6 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -230,10 +230,38 @@ pgtls_read(PGconn *conn, void *ptr, size_t len) return n; } -bool -pgtls_read_pending(PGconn *conn) +ssize_t +pgtls_bytes_pending(PGconn *conn) { - return SSL_pending(conn->ssl) > 0; + int pending; + + /* + * OpenSSL readahead is documented to break SSL_pending(). + */ + Assert(!SSL_get_read_ahead(conn->ssl)); + + pending = SSL_pending(conn->ssl); + if (pending < 0) + { + /* shouldn't be possible */ + Assert(false); + libpq_append_conn_error(conn, "OpenSSL reports negative bytes pending"); + return -1; + } + else if (pending == INT_MAX) + { + /* + * If we ever found a legitimate way to hit this, we'd need to loop + * around in the caller to call pgtls_bytes_pending() again. Throw an + * error rather than complicate the code in that way, because + * SSL_read() should be bounded to the size of a single TLS record, + * and conn->inBuffer can't currently go past INT_MAX in size anyway. + */ + libpq_append_conn_error(conn, "OpenSSL reports INT_MAX bytes pending"); + return -1; + } + + return (ssize_t) pending; } ssize_t diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c index 31d5b48d3f9..907cdb9ea39 100644 --- a/src/interfaces/libpq/fe-secure.c +++ b/src/interfaces/libpq/fe-secure.c @@ -243,6 +243,28 @@ pqsecure_raw_read(PGconn *conn, void *ptr, size_t len) return n; } +/* + * Return the number of bytes available in the transport buffer. + * + * If pqsecure_read() is called for this number of bytes, it's guaranteed to + * return successfully without reading from the underlying socket. + */ +ssize_t +pqsecure_bytes_pending(PGconn *conn) +{ +#ifdef USE_SSL + if (conn->ssl_in_use) + return pgtls_bytes_pending(conn); +#endif +#ifdef ENABLE_GSS + if (conn->gssenc) + return pg_GSS_bytes_pending(conn); +#endif + + /* Plaintext connections have no transport buffer. */ + return 0; +} + /* * Write data to a secure connection. * diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index 461b39620c3..3f921207a14 100644 --- a/src/interfaces/libpq/libpq-int.h +++ b/src/interfaces/libpq/libpq-int.h @@ -827,6 +827,7 @@ extern int pqWriteReady(PGconn *conn); extern PostgresPollingStatusType pqsecure_open_client(PGconn *); extern void pqsecure_close(PGconn *); extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len); +extern ssize_t pqsecure_bytes_pending(PGconn *); extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len); extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len); extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len); @@ -863,9 +864,9 @@ extern void pgtls_close(PGconn *conn); extern ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len); /* - * Is there unread data waiting in the SSL read buffer? + * Return the number of bytes available in the transport buffer. */ -extern bool pgtls_read_pending(PGconn *conn); +extern ssize_t pgtls_bytes_pending(PGconn *conn); /* * Write data to a secure connection. @@ -913,6 +914,7 @@ extern PostgresPollingStatusType pqsecure_open_gss(PGconn *conn); */ extern ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len); extern ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len); +extern ssize_t pg_GSS_bytes_pending(PGconn *conn); #endif /* === in fe-trace.c === */ From 7f8745543e79ae48cb8d80e97c17105d76511fd9 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Tue, 7 Jul 2026 18:45:37 +0300 Subject: [PATCH 107/481] libpq: Drain all pending bytes from SSL/GSS during pqReadData() The previous commit strengthened a workaround for a hang when large messages are split across TLS records/GSS tokens. Because that workaround is implemented in libpq internals, it can only help us when libpq itself is polling on the socket. In nonblocking situations, where the client above libpq is expected to poll, the same bugs can show up. As a contrived example, consider a large protocol-2.0 error coming back from a server during PQconnectPoll(), split in an odd way across two records: -- TLS record (8192-byte payload) -- EEEE[...repeated a total of 8192 times] -- TLS record (8193-byte payload) -- EEEE[...repeated a total of 8192 times]\0 The first record will fill the first half of the libpq receive buffer, which is 16k long by default. The second record completely fills the last half with its first 8192 bytes, leaving the terminating NULL in the OpenSSL buffer. Since we still haven't seen the terminator at our level, PQconnectPoll() will return PGRES_POLLING_READING, expecting to come back when the server has sent "the rest" of the data. But there is nothing left to read from the socket; OpenSSL had to pull all of the data in the 8193-byte record off of the wire to decrypt it. A real server would probably not split up the records this way, nor keep the connection open after sending a fatal connection error. But servers that regularly use larger TLS records can get the libpq receive buffer into the same state if DataRows are big enough, as reported on the list. While the PostgreSQL server doesn't use larger TLS records like that, other non-PostgreSQL servers that implement the wire protocol are known to do that, as well as proxies that sit between the server and the client This is a layering violation. libpq makes decisions based on data in the application buffer, above the transport buffer (whether SSL or GSS), but clients are polling the socket below the transport buffer. One way to fix this in a backportable way, without changing APIs too much, is to ensure data never stays in the transport buffer. Then pqReadData's postconditions will look similar for both raw sockets and SSL/GSS: any available data is either in the application buffer, or still on the socket. Building on the prior commit, make pqReadData() to drain all pending data from the transport layer into conn->inBuffer, expanding the buffer as necessary. This is not particularly efficient from an architectural perspective (the pqsecure_read() implementations take care to fit their packets into the current buffer, and that effort is now completely discarded), but it's hopefully easier to reason about than a full rewrite would be for the back branches. Author: Jacob Champion Reviewed-by: Mark Dilger Reviewed-by: solai v Reported-by: Lars Kanis Discussion: https://postgr.es/m/2039ac58-d3e0-434b-ac1a-2a987f3b4cb1%40greiz-reinsdorf.de Backpatch-through: 14 --- src/interfaces/libpq/fe-misc.c | 145 ++++++++++++++++++++++- src/interfaces/libpq/fe-secure-openssl.c | 4 +- src/interfaces/libpq/fe-secure.c | 3 +- 3 files changed, 148 insertions(+), 4 deletions(-) diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index 58ccca1e393..dd772838005 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -55,6 +55,8 @@ static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn); static int pqSendSome(PGconn *conn, int len); static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, pg_usec_time_t end_time); +static int pqReadData_internal(PGconn *conn); +static int pqDrainPending(PGconn *conn); /* * PQlibVersion: return the libpq version number @@ -593,6 +595,13 @@ pqPutMsgEnd(PGconn *conn) /* ---------- * pqReadData: read more data, if any is available + * + * Upon a successful return, callers may assume that either 1) all available + * bytes have been consumed from the socket, or 2) the socket is still marked + * readable by the OS. (In other words: after a successful pqReadData, it's + * safe to tell a client to poll for readable bytes on the socket without any + * further draining of the SSL/GSS transport buffers.) + * * Possible return values: * 1: successfully loaded at least one more byte * 0: no data is presently available, but no error detected @@ -605,8 +614,7 @@ pqPutMsgEnd(PGconn *conn) int pqReadData(PGconn *conn) { - int someread = 0; - int nread; + int available; if (conn->sock == PGINVALID_SOCKET) { @@ -614,6 +622,40 @@ pqReadData(PGconn *conn) return -1; } + available = pqReadData_internal(conn); + if (available < 0) + return -1; + else if (available > 0) + { + /* + * Make sure there are no bytes stuck in layers between conn->inBuffer + * and the socket, to make it safe for clients to poll on PQsocket(). + */ + if (pqDrainPending(conn)) + return -1; + } + else + { + /* + * If we're not returning any bytes from the underlying transport, + * that must imply there aren't any in the transport buffer... + */ + Assert(pqsecure_bytes_pending(conn) == 0); + } + + return available; +} + +/* + * Workhorse for pqReadData(). It's kept separate from the pqDrainPending() + * logic to avoid adding to this function's goto complexity. + */ +static int +pqReadData_internal(PGconn *conn) +{ + int someread = 0; + int nread; + /* Left-justify any data in the buffer to make room */ if (conn->inStart < conn->inEnd) { @@ -800,6 +842,105 @@ pqReadData(PGconn *conn) return -1; } +/*--- + * Drain any transport data that is already buffered in userspace and add it + * to conn->inBuffer, enlarging inBuffer if necessary. The drain fails if + * inBuffer cannot be made to hold all available transport data. + * + * We assume that the underlying secure transport implementation does not + * attempt to read any more data from the socket while draining the transport + * buffer. After a successful return, pqsecure_bytes_pending() must be zero. + * + * This operation is necessary to prevent deadlock, due to a layering + * violation designed into our asynchronous client API: pqReadData() and all + * the parsing routines above it receive data from the SSL/GSS transport + * buffer, but clients poll on the raw PQsocket() handle. So data can be + * "lost" in the intermediate layer if we don't take it out here. + * + * To illustrate what we're trying to prevent, say that the server is sending + * two messages at once in response to a query (Aaaa and Bb), the libpq buffer + * is five characters in size, and TLS records max out at three-character + * payloads. Here's what would happen if pqReadData() didn't call + * pqDrainPending(): + * + * Client libpq SSL Socket + * | | | | + * | [ ] [ ] [ ] [1] Buffers are empty, client is + * x --------------------------> | polling on socket + * | | | | + * | [ ] [ ] [xxx] [2] First record is received; poll + * | <-------------------------- | signals read-ready + * | | | | + * x ---> [ ] [ ] [xxx] [3] Client calls PQconsumeInput() + * | | | | + * | [ ] -> [ ] [xxx] [4] libpq calls pqReadData() to fill + * | | | | the receive buffer + * | [ ] [Aaa] <-- [ ] [5] SSL pulls payload off the wire + * | | | | and decrypts it + * | [Aaa ] <- [ ] [ ] [6] pqsecure_read() takes all data + * | | | | + * | <--- [Aaa ] [ ] [ ] [7] PQconsumeInput() returns with a + * x --------------------------> | partial message, PQisBusy() is + * | | | | still true, client polls again + * | [Aaa ] [ ] [xxx] [8] Second record is received; poll + * | <-------------------------- | signals read-ready + * | | | | + * x ---> [Aaa ] [ ] [xxx] [9] Client calls PQconsumeInput() + * | | | | + * | [Aaa ] -> [ ] [xxx] [10] libpq calls pqReadData() to fill + * | | | | the receive buffer + * | [Aaa ] [aBb] <-- [ ] [11] SSL decrypts + * | | | | + * | [AaaaB] <- [b ] [ ] [12] pqsecure_read() fills its + * | | | | buffer, taking only two bytes + * | <--- [AaaaB] [b ] [ ] [13] PQconsumeInput() returns with a + * | | | | complete message buffered; + * | | | | PQisBusy() is false + * x ---> [AaaaB] [b ] [ ] [14] Client calls PQgetResult() + * | | | | + * | <--- [B ] [b ] [ ] [15] Aaaa is returned; PQisBusy() is + * x --------------------------> | true and client polls again + * . | | . + * . [B ] [b ] . [16] No packets, and client hangs. + * . | | . + * + * The pqDrainPending() call fixes the above scenario at step [13]. Before + * returning to the Client, it first expands the libpq buffer and moves the + * remaining data from the SSL buffer to the libpq buffer. + * + * The function returns 0 on success and -1 on error. Success means that + * there was no data pending or it was successfully drained to conn->inBuffer. + * On error, conn->errorMessage is set. + */ +static int +pqDrainPending(PGconn *conn) +{ + ssize_t bytes_pending; + ssize_t nread; + + bytes_pending = pqsecure_bytes_pending(conn); + if (bytes_pending <= 0) + return bytes_pending; + + /* Expand the input buffer if necessary. */ + if (pqCheckInBufferSpace(conn->inEnd + (size_t) bytes_pending, conn)) + return -1; /* errorMessage already set */ + + nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd, + bytes_pending); + conn->inEnd += nread; + + /* When there are bytes pending, the read function is not supposed to fail */ + if (nread != bytes_pending) + { + libpq_append_conn_error(conn, + "drained only %zu of %zd pending bytes in transport buffer", + nread, bytes_pending); + return -1; + } + return 0; +} + /* * pqSendSome: send data waiting in the output buffer. * diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 1b22ba7b7f6..f8b2184a1ce 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -236,7 +236,9 @@ pgtls_bytes_pending(PGconn *conn) int pending; /* - * OpenSSL readahead is documented to break SSL_pending(). + * OpenSSL readahead is documented to break SSL_pending(). Plus, we can't + * afford to have OpenSSL take bytes off the socket without processing + * them; that breaks the postconditions for pqsecure_drain_pending(). */ Assert(!SSL_get_read_ahead(conn->ssl)); diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c index 907cdb9ea39..70faf8b2fe0 100644 --- a/src/interfaces/libpq/fe-secure.c +++ b/src/interfaces/libpq/fe-secure.c @@ -247,7 +247,8 @@ pqsecure_raw_read(PGconn *conn, void *ptr, size_t len) * Return the number of bytes available in the transport buffer. * * If pqsecure_read() is called for this number of bytes, it's guaranteed to - * return successfully without reading from the underlying socket. + * return successfully without reading from the underlying socket. See + * pqDrainPending() for a more complete discussion of the concepts involved. */ ssize_t pqsecure_bytes_pending(PGconn *conn) From ccca2cd81b2dab2be7d9d451a84d971a8489ca70 Mon Sep 17 00:00:00 2001 From: Noah Misch Date: Tue, 7 Jul 2026 09:51:04 -0700 Subject: [PATCH 108/481] Fix pg_dump ACL minimization for PROPERTY GRAPH. Adding a GRANT caused pg_dump to emit a useless REVOKE + GRANT of owner privileges, as seen in a dump of the regression database: REVOKE ALL ON PROPERTY GRAPH graph_rls_schema.cabinet FROM nm; GRANT ALL ON PROPERTY GRAPH graph_rls_schema.cabinet TO nm; GRANT ALL ON PROPERTY GRAPH graph_rls_schema.cabinet TO PUBLIC; For normal dumps, this has no functional consequences. For --no-owner restores, the extra statements may fail or locate unrelated users of the destination cluster. The problem was pg_dump assuming NULL relacl implies acldefault('r'), the default for TABLE. Fix by teaching acldefault() to retrieve the PROPERTY GRAPH default ACL. So pg_dump can still dump from 19beta1, use acldefault('g') for v20+ only. For v19, use a hard-coded snapshot of the v19 default. information_schema.pg_property_graph_privileges also misused acldefault('r'), but its "c.prtype IN ('SELECT')" predicate compensated for it. Switch to the new acldefault('g') for clarity. Bump catversion since a new view won't work with old binaries. Back-patch to v19, which introduced PROPERTY GRAPH. Reviewed-by: Ashutosh Bapat Reviewed-by: Robert Haas Discussion: https://postgr.es/m/20260630023308.c7.noahmisch@microsoft.com Backpatch-through: 19 --- src/backend/catalog/information_schema.sql | 2 +- src/backend/utils/adt/acl.c | 3 ++ src/bin/pg_dump/pg_dump.c | 37 ++++++++++++++++++++-- src/include/catalog/catversion.h | 2 +- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql index 4f0e2492937..624d538a5c0 100644 --- a/src/backend/catalog/information_schema.sql +++ b/src/backend/catalog/information_schema.sql @@ -3328,7 +3328,7 @@ CREATE VIEW pg_property_graph_privileges AS THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable FROM ( - SELECT oid, relname, relnamespace, relkind, relowner, (aclexplode(coalesce(relacl, acldefault('r', relowner)))).* FROM pg_class + SELECT oid, relname, relnamespace, relkind, relowner, (aclexplode(coalesce(relacl, acldefault('g', relowner)))).* FROM pg_class ) AS c (oid, relname, relnamespace, relkind, relowner, grantor, grantee, prtype, grantable), pg_namespace nc, pg_authid u_grantor, diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 01caa12eca7..e2547d719ed 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -956,6 +956,9 @@ acldefault_sql(PG_FUNCTION_ARGS) case 'c': objtype = OBJECT_COLUMN; break; + case 'g': + objtype = OBJECT_PROPGRAPH; + break; case 'r': objtype = OBJECT_TABLE; break; diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..41b9531e41a 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -7358,8 +7358,17 @@ getTables(Archive *fout, int *numTables) "c.relhastriggers, c.relpersistence, " "c.reloftype, " "c.relacl, " - "acldefault(CASE WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE) - " THEN 's'::\"char\" ELSE 'r'::\"char\" END, c.relowner) AS acldefault, " + "acldefault(CASE" + " WHEN c.relkind = " CppAsString2(RELKIND_PROPGRAPH)); + /* 19beta1 didn't support acldefault('g'), so we'll fix that below */ + appendPQExpBufferStr(query, + fout->remoteVersion >= 200000 ? + " THEN 'g'::\"char\"" : + " THEN NULL"); + appendPQExpBufferStr(query, + " WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE) + " THEN 's'::\"char\"" + " ELSE 'r'::\"char\" END, c.relowner) AS acldefault, " "CASE WHEN c.relkind = " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN " "(SELECT ftserver FROM pg_catalog.pg_foreign_table WHERE ftrelid = c.oid) " "ELSE 0 END AS foreignserver, " @@ -7579,7 +7588,7 @@ getTables(Archive *fout, int *numTables) tblinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_relnamespace))); tblinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_relacl)); - tblinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault)); + /* acldefault computed below */ tblinfo[i].dacl.privtype = 0; tblinfo[i].dacl.initprivs = NULL; tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind)); @@ -7631,6 +7640,28 @@ getTables(Archive *fout, int *numTables) tblinfo[i].is_identity_sequence = (strcmp(PQgetvalue(res, i, i_is_identity_sequence), "t") == 0); tblinfo[i].ispartition = (strcmp(PQgetvalue(res, i, i_ispartition), "t") == 0); + if (tblinfo[i].relkind == RELKIND_PROPGRAPH && + !(fout->remoteVersion >= 200000)) + { + PQExpBuffer aclarray = createPQExpBuffer(); + PQExpBuffer aclitem = createPQExpBuffer(); + + /* Standard ACL as of v19 is {owner=r/owner} */ + appendPQExpBufferChar(aclarray, '{'); + quoteAclUserName(aclitem, tblinfo[i].rolname); + appendPQExpBufferStr(aclitem, "=r/"); + quoteAclUserName(aclitem, tblinfo[i].rolname); + appendPGArray(aclarray, aclitem->data); + appendPQExpBufferChar(aclarray, '}'); + + tblinfo[i].dacl.acldefault = pstrdup(aclarray->data); + + destroyPQExpBuffer(aclarray); + destroyPQExpBuffer(aclitem); + } + else + tblinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault)); + /* other fields were zeroed above */ /* diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 875a147f753..79291aaaf5c 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202606301 +#define CATALOG_VERSION_NO 202607071 #endif From a53d6d8aea8fe703d86dd2bdc0a3d86800eca7c3 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Tue, 7 Jul 2026 22:32:36 +0300 Subject: [PATCH 109/481] Cleanup comments/docs around the new shmem request callbacks Make it explicit in the docs that the shmem initialization callbacks are called while holding ShmemIndexLock. Reviewed-by: Ashutosh Bapat Discussion: https://www.postgresql.org/message-id/CAExHW5sHs+eSiTDOd14buayc6JbBX=Hm5ssFMBK0Ki9sTGEOuA@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/xfunc.sgml | 4 ++-- src/backend/storage/ipc/shmem.c | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index bae16d7fb53..cb3cc09f16d 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -3739,8 +3739,8 @@ my_shmem_init(void *arg) startup, it will immediately call the appropriate callbacks, depending on whether the requested memory areas were already initialized by another backend. The callbacks will be called while holding an internal - lock, which prevents concurrent two backends from initializing the - memory area concurrently. + lock (ShmemIndexLock), which prevents the race condition of two backends + trying to initializing the memory area at the same time. diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index f1f7cd3a4ff..1fbba9c3a4c 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -918,7 +918,10 @@ CallShmemCallbacksAfterStartup(const ShmemCallbacks *callbacks) return; } - /* Hold ShmemIndexLock while we allocate all the shmem entries */ + /* + * Hold ShmemIndexLock while we allocate all the shmem entries and run all + * the initializers. + */ LWLockAcquire(ShmemIndexLock, LW_EXCLUSIVE); /* @@ -937,7 +940,7 @@ CallShmemCallbacksAfterStartup(const ShmemCallbacks *callbacks) notfound_any = true; } if (found_any && notfound_any) - elog(ERROR, "found some but not all"); + elog(ERROR, "some of the requested shmem areas have already been initialized"); /* * Allocate or attach all the shmem areas requested by the request_fn From 05da336dd7d32ed4a70efc5f21c355f8ace482e8 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Tue, 7 Jul 2026 13:35:07 -0700 Subject: [PATCH 110/481] unicode_case.c: defend against truncated UTF8. Reviewed-by: Chao Li Discussion: https://postgr.es/m/c355354e6c3f4a7aafb047361b73db247260fca0.camel@j-davis.com Backpatch-through: 17 --- src/backend/utils/adt/pg_locale_builtin.c | 24 ++++++++--- src/common/unicode/case_test.c | 8 ++++ src/common/unicode_case.c | 52 +++++++++++++++++++---- 3 files changed, 70 insertions(+), 14 deletions(-) diff --git a/src/backend/utils/adt/pg_locale_builtin.c b/src/backend/utils/adt/pg_locale_builtin.c index 01d4f55b07e..7c36fd5091b 100644 --- a/src/backend/utils/adt/pg_locale_builtin.c +++ b/src/backend/utils/adt/pg_locale_builtin.c @@ -62,21 +62,33 @@ initcap_wbnext(void *state) while (wbstate->offset < wbstate->len) { - char32_t u = utf8_to_unicode((const unsigned char *) wbstate->str + + int ulen = pg_utf_mblen((const unsigned char *) wbstate->str + wbstate->offset); - bool curr_alnum = pg_u_isalnum(u, wbstate->posix); + char32_t u; + bool curr_alnum; + size_t prev_offset = wbstate->offset; - if (!wbstate->init || curr_alnum != wbstate->prev_alnum) + /* invalid UTF8 */ + if (wbstate->offset + ulen > wbstate->len) { - size_t prev_offset = wbstate->offset; + wbstate->init = true; + wbstate->offset = wbstate->len; + return prev_offset; + } + u = utf8_to_unicode((const unsigned char *) wbstate->str + + wbstate->offset); + curr_alnum = pg_u_isalnum(u, wbstate->posix); + + if (!wbstate->init || curr_alnum != wbstate->prev_alnum) + { wbstate->init = true; - wbstate->offset += unicode_utf8len(u); + wbstate->offset += ulen; wbstate->prev_alnum = curr_alnum; return prev_offset; } - wbstate->offset += unicode_utf8len(u); + wbstate->offset += ulen; } return wbstate->len; diff --git a/src/common/unicode/case_test.c b/src/common/unicode/case_test.c index a0dbf00b671..31ea94513bf 100644 --- a/src/common/unicode/case_test.c +++ b/src/common/unicode/case_test.c @@ -296,6 +296,8 @@ tfunc_fold(char *dst, size_t dstsize, const char *src, static void test_convert_case(void) { + size_t needed; + /* test string with no case changes */ test_convert(tfunc_lower, "√∞", "√∞"); /* test adjust-to-cased behavior */ @@ -320,6 +322,12 @@ test_convert_case(void) /* U+FF11 FULLWIDTH ONE is alphanumeric for full case mapping */ test_convert(tfunc_title, "\uFF11a", "\uFF11a"); + /* invalid UTF8: truncated multibyte sequence */ + needed = unicode_strfold(NULL, 0, "abc\xCE", 4, false); + Assert(needed == 3); + /* invalid UTF8: invalid byte */ + needed = unicode_strfold(NULL, 0, "abc\xF8xyz", 7, false); + Assert(needed == 3); #ifdef USE_ICU icu_test_full(""); diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c index d6ee00b7d9c..42eb7d22211 100644 --- a/src/common/unicode_case.c +++ b/src/common/unicode_case.c @@ -189,6 +189,22 @@ unicode_strfold(char *dst, size_t dstsize, const char *src, size_t srclen, NULL); } +/* local version of pg_utf_mblen() to be inlinable */ +static int +utf8_mblen(const unsigned char *s) +{ + if ((*s & 0x80) == 0) + return 1; + else if ((*s & 0xe0) == 0xc0) + return 2; + else if ((*s & 0xf0) == 0xe0) + return 3; + else if ((*s & 0xf8) == 0xf0) + return 4; + else + return -1; +} + /* * Implement Unicode Default Case Conversion algorithm. * @@ -227,12 +243,18 @@ convert_case(char *dst, size_t dstsize, const char *src, size_t srclen, while (srcoff < srclen) { - char32_t u1 = utf8_to_unicode((const unsigned char *) src + srcoff); - int u1len = unicode_utf8len(u1); + int u1len = utf8_mblen((const unsigned char *) src + srcoff); + char32_t u1; char32_t simple = 0; const char32_t *special = NULL; enum CaseMapResult casemap_result; + /* invalid UTF8 */ + if (u1len < 0 || srcoff + u1len > srclen) + break; + + u1 = utf8_to_unicode((const unsigned char *) src + srcoff); + if (str_casekind == CaseTitle) { if (srcoff == boundary) @@ -316,7 +338,14 @@ check_final_sigma(const unsigned char *str, size_t len, size_t offset) { if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0) { - char32_t curr = utf8_to_unicode(str + i); + int u1len = utf8_mblen((const unsigned char *) str + i); + char32_t curr; + + /* invalid UTF8 */ + if (u1len < 0 || i + u1len > len) + return false; + + curr = utf8_to_unicode(str + i); if (pg_u_prop_case_ignorable(curr)) continue; @@ -327,8 +356,8 @@ check_final_sigma(const unsigned char *str, size_t len, size_t offset) } else if ((str[i] & 0xC0) == 0x80) continue; - - Assert(false); /* invalid UTF-8 */ + else + return false; /* invalid UTF8 */ } /* end of string is not followed by a Cased character */ @@ -340,7 +369,14 @@ check_final_sigma(const unsigned char *str, size_t len, size_t offset) { if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0) { - char32_t curr = utf8_to_unicode(str + i); + int u1len = utf8_mblen((const unsigned char *) str + i); + char32_t curr; + + /* invalid UTF8 */ + if (u1len < 0 || i + u1len > len) + return false; + + curr = utf8_to_unicode(str + i); if (pg_u_prop_case_ignorable(curr)) continue; @@ -351,8 +387,8 @@ check_final_sigma(const unsigned char *str, size_t len, size_t offset) } else if ((str[i] & 0xC0) == 0x80) continue; - - Assert(false); /* invalid UTF-8 */ + else + return false; /* invalid UTF8 */ } return true; From 28d498e28031f026b8416a4c8439ddda62dfb00f Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Tue, 7 Jul 2026 14:29:21 -0700 Subject: [PATCH 111/481] pg_unicode_fast: fix final sigma logic. If the string is preceded only by Case Ignorable characters, don't consider it to be a final sigma. In the process, refactor so that the preceding and following characters are found first, and then the rule is applied, to improve clarity. Discussion: https://postgr.es/m/c355354e6c3f4a7aafb047361b73db247260fca0.camel@j-davis.com Backpatch-through: 18 --- src/common/unicode_case.c | 88 ++++++++++------------ src/test/regress/expected/collate.utf8.out | 6 ++ src/test/regress/sql/collate.utf8.sql | 1 + 3 files changed, 47 insertions(+), 48 deletions(-) diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c index 42eb7d22211..dd5b3ba86d0 100644 --- a/src/common/unicode_case.c +++ b/src/common/unicode_case.c @@ -323,75 +323,67 @@ convert_case(char *dst, size_t dstsize, const char *src, size_t srclen, * 3-17. The character at the given offset must be directly preceded by a * Cased character, and must not be directly followed by a Cased character. * - * Case_Ignorable characters are ignored. NB: some characters may be both + * Case_Ignorable characters are ignored. Neither beginning of string nor end + * of string are considered Cased characters. NB: some characters may be both * Cased and Case_Ignorable, in which case they are ignored. */ static bool check_final_sigma(const unsigned char *str, size_t len, size_t offset) { - /* the start of the string is not preceded by a Cased character */ - if (offset == 0) - return false; + bool preceded_by_cased = false; + bool followed_by_cased = false; + char32_t curr; + int ulen; - /* iterate backwards, looking for Cased character */ - for (int i = offset - 1; i >= 0; i--) + /* iterate backwards looking for preceding character */ + for (int i = offset; i > 0;) { - if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0) - { - int u1len = utf8_mblen((const unsigned char *) str + i); - char32_t curr; + /* skip backwards through continuation bytes */ + i--; + if ((str[i] & 0xC0) == 0x80) + continue; - /* invalid UTF8 */ - if (u1len < 0 || i + u1len > len) - return false; + /* now at leading byte of previous sequence */ + Assert((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0); - curr = utf8_to_unicode(str + i); + ulen = utf8_mblen((const unsigned char *) str + i); - if (pg_u_prop_case_ignorable(curr)) - continue; - else if (pg_u_prop_cased(curr)) - break; - else - return false; + /* invalid UTF8 */ + if (ulen < 0 || i + ulen > len) + return false; + + curr = utf8_to_unicode((const unsigned char *) str + i); + + if (!pg_u_prop_case_ignorable(curr)) + { + preceded_by_cased = pg_u_prop_cased(curr); + break; } - else if ((str[i] & 0xC0) == 0x80) - continue; - else - return false; /* invalid UTF8 */ } - /* end of string is not followed by a Cased character */ - if (offset == len) - return true; + ulen = utf8_mblen((const unsigned char *) str + offset); - /* iterate forwards, looking for Cased character */ - for (int i = offset + 1; i < len && str[i] != '\0'; i++) + /* iterate forward looking for following character */ + for (int i = offset + ulen; i < len;) { - if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0) - { - int u1len = utf8_mblen((const unsigned char *) str + i); - char32_t curr; + ulen = utf8_mblen((const unsigned char *) str + i); - /* invalid UTF8 */ - if (u1len < 0 || i + u1len > len) - return false; + /* invalid UTF8 */ + if (ulen < 0 || i + ulen > len) + return false; - curr = utf8_to_unicode(str + i); + curr = utf8_to_unicode((const unsigned char *) str + i); - if (pg_u_prop_case_ignorable(curr)) - continue; - else if (pg_u_prop_cased(curr)) - return false; - else - break; + if (!pg_u_prop_case_ignorable(curr)) + { + followed_by_cased = pg_u_prop_cased(curr); + break; } - else if ((str[i] & 0xC0) == 0x80) - continue; - else - return false; /* invalid UTF8 */ + + i += ulen; } - return true; + return (preceded_by_cased && !followed_by_cased); } /* diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out index 0c3ab5c89b2..99fdc111fa4 100644 --- a/src/test/regress/expected/collate.utf8.out +++ b/src/test/regress/expected/collate.utf8.out @@ -263,6 +263,12 @@ SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391 ᾳσͅα (1 row) +SELECT lower(U&'\0300\03A3' COLLATE PG_UNICODE_FAST); + lower +------- + ̀σ +(1 row) + -- properties SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST; ?column? diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql index d6d14220ab3..22aecee3a60 100644 --- a/src/test/regress/sql/collate.utf8.sql +++ b/src/test/regress/sql/collate.utf8.sql @@ -128,6 +128,7 @@ SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3 SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391 SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391 SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391 +SELECT lower(U&'\0300\03A3' COLLATE PG_UNICODE_FAST); -- properties From eaa561fb6e278ed7ce293ed7d1e7ddaa7354180b Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Wed, 8 Jul 2026 08:46:43 +0900 Subject: [PATCH 112/481] Fix EXPLAIN failure when deparsing SQL/JSON aggregates If an expression containing an aggregate is evaluated above the plan node that computes the aggregate, as happens with window functions or with expressions postponed to above the final sort, setrefs.c replaces the Aggref or WindowFunc with a Var referencing the lower node's output. For SQL/JSON aggregates such as JSON_ARRAYAGG and JSON_OBJECTAGG, deparsing the containing JsonConstructorExpr then failed with "invalid JsonConstructorExpr underlying node type", since get_json_agg_constructor() did not expect a Var there. Fix by resolving the Var back to the underlying Aggref or WindowFunc and deparsing the constructor as if the aggregate were computed at the current node. The JsonConstructorExpr retains the RETURNING clause and the ABSENT/NULL ON NULL and WITH UNIQUE options, and the arguments come from the resolved aggregate, so the original JSON aggregate syntax is reproduced in full. This mirrors how get_agg_expr() already looks through such a Var when deparsing a combining aggregate. Reported-by: Thom Brown Author: Richard Guo Discussion: https://postgr.es/m/CAA-aLv5QYTaMOk=Qhv6cgwceeHETZV8YJvWZ_rH+yVZCuchATA@mail.gmail.com Backpatch-through: 16 --- src/backend/utils/adt/ruleutils.c | 32 ++++++++ src/test/regress/expected/sqljson.out | 101 ++++++++++++++++++++++++++ src/test/regress/sql/sqljson.sql | 41 +++++++++++ 3 files changed, 174 insertions(+) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 88de5c0481c..819631781c0 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -512,6 +512,8 @@ static void get_json_agg_constructor(JsonConstructorExpr *ctor, deparse_context *context, const char *funcname, bool is_json_objectagg); +static void get_json_agg_constructor_expr(Node *node, deparse_context *context, + void *callback_arg); static void simple_quote_literal(StringInfo buf, const char *val); static void get_sublink_expr(SubLink *sublink, deparse_context *context); static void get_tablefunc(TableFunc *tf, deparse_context *context, @@ -12389,11 +12391,41 @@ get_json_agg_constructor(JsonConstructorExpr *ctor, deparse_context *context, get_windowfunc_expr_helper((WindowFunc *) ctor->func, context, funcname, options.data, is_json_objectagg); + else if (IsA(ctor->func, Var)) + { + /* + * If the aggregate is computed by a lower plan node, setrefs.c will + * have replaced the Aggref or WindowFunc with a Var referencing that + * node's output. Chase the Var back to it so we can still print the + * original JSON aggregate syntax. This only happens in EXPLAIN. + */ + resolve_special_varno((Node *) ctor->func, context, + get_json_agg_constructor_expr, ctor); + } else elog(ERROR, "invalid JsonConstructorExpr underlying node type: %d", nodeTag(ctor->func)); } +/* + * Deparse a JsonConstructorExpr whose aggregate is computed by a lower plan + * node; resolve_special_varno has located the underlying Aggref/WindowFunc. + */ +static void +get_json_agg_constructor_expr(Node *node, deparse_context *context, + void *callback_arg) +{ + JsonConstructorExpr ctor; + + if (!IsA(node, Aggref) && !IsA(node, WindowFunc)) + elog(ERROR, "JSON aggregate constructor does not point to an Aggref or WindowFunc"); + + /* Flat copy suffices; we only replace func. */ + ctor = *(JsonConstructorExpr *) callback_arg; + ctor.func = (Expr *) node; + get_json_constructor(&ctor, context, false); +} + /* * simple_quote_literal - Format a string as a SQL literal, append to buf */ diff --git a/src/test/regress/expected/sqljson.out b/src/test/regress/expected/sqljson.out index 0f337bda325..091a0b98574 100644 --- a/src/test/regress/expected/sqljson.out +++ b/src/test/regress/expected/sqljson.out @@ -1757,3 +1757,104 @@ SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': 1 RETURNING text) FORMAT JSON); (1 row) DROP FUNCTION volatile_one, stable_one; +-- Test deparsing of JSON aggregates that are computed below a WindowAgg +-- node. +EXPLAIN (VERBOSE, COSTS OFF) +SELECT i % 2 AS g, + JSON_ARRAYAGG(i ORDER BY i RETURNING jsonb) AS ja, + JSON_ARRAYAGG(i ORDER BY i RETURNING text) AS ja_text, + JSON_ARRAYAGG(i ORDER BY i NULL ON NULL RETURNING jsonb) AS ja_null, + JSON_OBJECTAGG(i: i ABSENT ON NULL RETURNING jsonb) AS jo_absent, + JSON_OBJECTAGG(i: i WITH UNIQUE RETURNING jsonb) AS jo_unique, + row_number() OVER (ORDER BY i % 2) AS rn +FROM generate_series(1, 3) i +GROUP BY i % 2; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + WindowAgg + Output: ((i % 2)), JSON_ARRAYAGG(i ORDER BY i RETURNING jsonb), JSON_ARRAYAGG(i ORDER BY i RETURNING text), JSON_ARRAYAGG(i ORDER BY i NULL ON NULL RETURNING jsonb), JSON_OBJECTAGG(i : i ABSENT ON NULL RETURNING jsonb), JSON_OBJECTAGG(i : i WITH UNIQUE KEYS RETURNING jsonb), row_number() OVER w1 + Window: w1 AS (ORDER BY ((i.i % 2)) ROWS UNBOUNDED PRECEDING) + -> GroupAggregate + Output: ((i % 2)), jsonb_agg_strict(i ORDER BY i), json_agg_strict(i ORDER BY i), jsonb_agg(i ORDER BY i), jsonb_object_agg_strict(i, i), jsonb_object_agg_unique(i, i) + Group Key: ((i.i % 2)) + -> Sort + Output: ((i % 2)), i + Sort Key: ((i.i % 2)), i.i + -> Function Scan on pg_catalog.generate_series i + Output: (i % 2), i + Function Call: generate_series(1, 3) +(12 rows) + +SELECT i % 2 AS g, + JSON_ARRAYAGG(i ORDER BY i RETURNING jsonb) AS ja, + JSON_ARRAYAGG(i ORDER BY i RETURNING text) AS ja_text, + JSON_ARRAYAGG(i ORDER BY i NULL ON NULL RETURNING jsonb) AS ja_null, + JSON_OBJECTAGG(i: i ABSENT ON NULL RETURNING jsonb) AS jo_absent, + JSON_OBJECTAGG(i: i WITH UNIQUE RETURNING jsonb) AS jo_unique, + row_number() OVER (ORDER BY i % 2) AS rn +FROM generate_series(1, 3) i +GROUP BY i % 2; + g | ja | ja_text | ja_null | jo_absent | jo_unique | rn +---+--------+---------+---------+------------------+------------------+---- + 0 | [2] | [2] | [2] | {"2": 2} | {"2": 2} | 1 + 1 | [1, 3] | [1, 3] | [1, 3] | {"1": 1, "3": 3} | {"1": 1, "3": 3} | 2 +(2 rows) + +-- The same, but with the JSON aggregate used as a window function that is +-- computed below another WindowAgg node. +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_ARRAYAGG(i NULL ON NULL RETURNING jsonb) OVER (ORDER BY i DESC) AS ja, + row_number() OVER (ORDER BY i) AS rn +FROM generate_series(1, 3) i; + QUERY PLAN +------------------------------------------------------------------------------------------ + WindowAgg + Output: JSON_ARRAYAGG(i NULL ON NULL RETURNING jsonb) OVER w1, row_number() OVER w2, i + Window: w2 AS (ORDER BY i.i ROWS UNBOUNDED PRECEDING) + -> Sort + Output: i, (jsonb_agg(i) OVER w1) + Sort Key: i.i + -> WindowAgg + Output: i, jsonb_agg(i) OVER w1 + Window: w1 AS (ORDER BY i.i) + -> Sort + Output: i + Sort Key: i.i DESC + -> Function Scan on pg_catalog.generate_series i + Output: i + Function Call: generate_series(1, 3) +(15 rows) + +SELECT JSON_ARRAYAGG(i NULL ON NULL RETURNING jsonb) OVER (ORDER BY i DESC) AS ja, + row_number() OVER (ORDER BY i) AS rn +FROM generate_series(1, 3) i; + ja | rn +-----------+---- + [3, 2, 1] | 1 + [3, 2] | 2 + [3] | 3 +(3 rows) + +-- The same, but with the expression containing the JSON aggregate postponed +-- to above the final sort due to being volatile. +EXPLAIN (VERBOSE, COSTS OFF) +SELECT i % 2 AS g, + JSON_ARRAYAGG(i RETURNING text) || random()::text AS ja +FROM generate_series(1, 3) i +GROUP BY i % 2 +ORDER BY count(*); + QUERY PLAN +---------------------------------------------------------------------------------------- + Result + Output: ((i % 2)), (JSON_ARRAYAGG(i RETURNING text) || (random())::text), (count(*)) + -> Sort + Output: ((i % 2)), (count(*)), (json_agg_strict(i)) + Sort Key: (count(*)) + -> HashAggregate + Output: ((i % 2)), count(*), json_agg_strict(i) + Group Key: (i.i % 2) + -> Function Scan on pg_catalog.generate_series i + Output: (i % 2), i + Function Call: generate_series(1, 3) +(11 rows) + diff --git a/src/test/regress/sql/sqljson.sql b/src/test/regress/sql/sqljson.sql index a68747733a1..2550da15c45 100644 --- a/src/test/regress/sql/sqljson.sql +++ b/src/test/regress/sql/sqljson.sql @@ -706,3 +706,44 @@ SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': stable_one() RETURNING text) FORMAT EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': 1 RETURNING text) FORMAT JSON); SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': 1 RETURNING text) FORMAT JSON); DROP FUNCTION volatile_one, stable_one; + +-- Test deparsing of JSON aggregates that are computed below a WindowAgg +-- node. +EXPLAIN (VERBOSE, COSTS OFF) +SELECT i % 2 AS g, + JSON_ARRAYAGG(i ORDER BY i RETURNING jsonb) AS ja, + JSON_ARRAYAGG(i ORDER BY i RETURNING text) AS ja_text, + JSON_ARRAYAGG(i ORDER BY i NULL ON NULL RETURNING jsonb) AS ja_null, + JSON_OBJECTAGG(i: i ABSENT ON NULL RETURNING jsonb) AS jo_absent, + JSON_OBJECTAGG(i: i WITH UNIQUE RETURNING jsonb) AS jo_unique, + row_number() OVER (ORDER BY i % 2) AS rn +FROM generate_series(1, 3) i +GROUP BY i % 2; +SELECT i % 2 AS g, + JSON_ARRAYAGG(i ORDER BY i RETURNING jsonb) AS ja, + JSON_ARRAYAGG(i ORDER BY i RETURNING text) AS ja_text, + JSON_ARRAYAGG(i ORDER BY i NULL ON NULL RETURNING jsonb) AS ja_null, + JSON_OBJECTAGG(i: i ABSENT ON NULL RETURNING jsonb) AS jo_absent, + JSON_OBJECTAGG(i: i WITH UNIQUE RETURNING jsonb) AS jo_unique, + row_number() OVER (ORDER BY i % 2) AS rn +FROM generate_series(1, 3) i +GROUP BY i % 2; + +-- The same, but with the JSON aggregate used as a window function that is +-- computed below another WindowAgg node. +EXPLAIN (VERBOSE, COSTS OFF) +SELECT JSON_ARRAYAGG(i NULL ON NULL RETURNING jsonb) OVER (ORDER BY i DESC) AS ja, + row_number() OVER (ORDER BY i) AS rn +FROM generate_series(1, 3) i; +SELECT JSON_ARRAYAGG(i NULL ON NULL RETURNING jsonb) OVER (ORDER BY i DESC) AS ja, + row_number() OVER (ORDER BY i) AS rn +FROM generate_series(1, 3) i; + +-- The same, but with the expression containing the JSON aggregate postponed +-- to above the final sort due to being volatile. +EXPLAIN (VERBOSE, COSTS OFF) +SELECT i % 2 AS g, + JSON_ARRAYAGG(i RETURNING text) || random()::text AS ja +FROM generate_series(1, 3) i +GROUP BY i % 2 +ORDER BY count(*); From 93338a0fd3b83bb9eeca1f80b8160510aca0272a Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 8 Jul 2026 09:04:31 +0900 Subject: [PATCH 113/481] doc: Fix typo in rule-system view example Commit dcb00495236 accidentally changed the final expanded query's condition to > 2 while rewriting the example into SQL operator notation. The original query and the preceding rewritten forms all use >= 2, and view expansion should preserve that qualification. This commit changes the final condition from > 2 to >= 2. Backpatch to all supported versions. Reported-by: Yaroslav Saburov Author: Fujii Masao Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/178248467618.108999.9966122434342474006@wrigleys.postgresql.org Backpatch-through: 14 --- doc/src/sgml/rules.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/rules.sgml b/doc/src/sgml/rules.sgml index 7f23962f524..9f9fa978f2d 100644 --- a/doc/src/sgml/rules.sgml +++ b/doc/src/sgml/rules.sgml @@ -631,7 +631,7 @@ SELECT shoe_ready.shoename, shoe_ready.sh_avail, WHERE rsl.sl_color = rsh.slcolor AND rsl.sl_len_cm >= rsh.slminlen_cm AND rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready - WHERE shoe_ready.total_avail > 2; + WHERE shoe_ready.total_avail >= 2; From ef5d080b452cb63ce798e9a77705eead062cd73f Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Tue, 7 Jul 2026 18:04:33 -0700 Subject: [PATCH 114/481] Fix unintentional behavior change from 5a38104b36. Reported-by: Noah Misch Discussion: https://postgr.es/m/20260630012919.78@rfd.leadboat.com Backpatch-through: 19 --- src/backend/utils/adt/like.c | 6 ++++-- src/test/regress/expected/collate.utf8.out | 7 +++++++ src/test/regress/sql/collate.utf8.sql | 3 +++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/like.c b/src/backend/utils/adt/like.c index 350bc07f210..64147bc5b5c 100644 --- a/src/backend/utils/adt/like.c +++ b/src/backend/utils/adt/like.c @@ -191,12 +191,14 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation) /* * For efficiency reasons, in the C locale we don't call lower() on the - * pattern and text, but instead lowercase each character lazily. + * pattern and text, but instead lowercase each character lazily. This + * only works for single-byte encodings, otherwise "_" may incorrectly + * match an incomplete byte sequence. * * XXX: use casefolding instead? */ - if (locale->ctype_is_c) + if (locale->ctype_is_c && pg_database_encoding_max_length() == 1) { p = VARDATA_ANY(pat); plen = VARSIZE_ANY_EXHDR(pat); diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out index 99fdc111fa4..cdd1a37ba18 100644 --- a/src/test/regress/expected/collate.utf8.out +++ b/src/test/regress/expected/collate.utf8.out @@ -34,6 +34,13 @@ SELECT U&'\00C1\00E1' !~ '[[:alpha:]]' COLLATE regress_builtin_c; (1 row) DROP COLLATION regress_builtin_c; +-- a '_' matches a multibyte character +SELECT 'café' ILIKE 'caf_' COLLATE "C"; + ?column? +---------- + t +(1 row) + -- -- Test PG_C_UTF8 -- diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql index 22aecee3a60..52cf068dd0c 100644 --- a/src/test/regress/sql/collate.utf8.sql +++ b/src/test/regress/sql/collate.utf8.sql @@ -26,6 +26,9 @@ SELECT U&'\00C1\00E1' !~ '[[:alpha:]]' COLLATE regress_builtin_c; DROP COLLATION regress_builtin_c; +-- a '_' matches a multibyte character +SELECT 'café' ILIKE 'caf_' COLLATE "C"; + -- -- Test PG_C_UTF8 -- From dffd7fb0a07b9d0265b447b728ac7a9c6ff60391 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Tue, 7 Jul 2026 18:19:59 -0700 Subject: [PATCH 115/481] Fix obsolete comment. Reported-by: Noah Misch Discussion: https://postgr.es/m/20260630012919.78@rfd.leadboat.com Backpatch-through: 19 --- src/backend/utils/adt/pg_locale_libc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c index 006039534a9..37e26b7e7a8 100644 --- a/src/backend/utils/adt/pg_locale_libc.c +++ b/src/backend/utils/adt/pg_locale_libc.c @@ -64,11 +64,6 @@ * where this matters is treatment of I/i in Turkish, and the behavior is * meant to match the upper()/lower() SQL functions. * - * We store the active collation setting in static variables. In principle - * it could be passed down to here via the regex library's "struct vars" data - * structure; but that would require somewhat invasive changes in the regex - * library, and right now there's no real benefit to be gained from that. - * * NB: the coding here assumes pg_wchar is an unsigned type. */ From 404fe01e0c5d402c257cfe809e5a15f64a2c6586 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Tue, 7 Jul 2026 18:20:06 -0700 Subject: [PATCH 116/481] pg_locale_libc.c: add guards to ctype methods. Necessary for 16-bit wchar_t platforms (Windows). Other guards are just defensive. Also correct style issue with branches. Reported-by: Noah Misch Discussion: https://postgr.es/m/20260630012919.78@rfd.leadboat.com Backpatch-through: 19 --- src/backend/utils/adt/pg_locale_libc.c | 52 ++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c index 37e26b7e7a8..0043371586d 100644 --- a/src/backend/utils/adt/pg_locale_libc.c +++ b/src/backend/utils/adt/pg_locale_libc.c @@ -124,60 +124,80 @@ static size_t strupper_libc_mb(char *dest, size_t destsize, static bool wc_isdigit_libc_sb(pg_wchar wc, pg_locale_t locale) { + if (wc > UCHAR_MAX) + return false; return isdigit_l((unsigned char) wc, locale->lt); } static bool wc_isalpha_libc_sb(pg_wchar wc, pg_locale_t locale) { + if (wc > UCHAR_MAX) + return false; return isalpha_l((unsigned char) wc, locale->lt); } static bool wc_isalnum_libc_sb(pg_wchar wc, pg_locale_t locale) { + if (wc > UCHAR_MAX) + return false; return isalnum_l((unsigned char) wc, locale->lt); } static bool wc_isupper_libc_sb(pg_wchar wc, pg_locale_t locale) { + if (wc > UCHAR_MAX) + return false; return isupper_l((unsigned char) wc, locale->lt); } static bool wc_islower_libc_sb(pg_wchar wc, pg_locale_t locale) { + if (wc > UCHAR_MAX) + return false; return islower_l((unsigned char) wc, locale->lt); } static bool wc_isgraph_libc_sb(pg_wchar wc, pg_locale_t locale) { + if (wc > UCHAR_MAX) + return false; return isgraph_l((unsigned char) wc, locale->lt); } static bool wc_isprint_libc_sb(pg_wchar wc, pg_locale_t locale) { + if (wc > UCHAR_MAX) + return false; return isprint_l((unsigned char) wc, locale->lt); } static bool wc_ispunct_libc_sb(pg_wchar wc, pg_locale_t locale) { + if (wc > UCHAR_MAX) + return false; return ispunct_l((unsigned char) wc, locale->lt); } static bool wc_isspace_libc_sb(pg_wchar wc, pg_locale_t locale) { + if (wc > UCHAR_MAX) + return false; return isspace_l((unsigned char) wc, locale->lt); } static bool wc_isxdigit_libc_sb(pg_wchar wc, pg_locale_t locale) { + if (wc > UCHAR_MAX) + return false; #ifndef WIN32 return isxdigit_l((unsigned char) wc, locale->lt); #else @@ -188,6 +208,8 @@ wc_isxdigit_libc_sb(pg_wchar wc, pg_locale_t locale) static bool wc_iscased_libc_sb(pg_wchar wc, pg_locale_t locale) { + if (wc > UCHAR_MAX) + return false; return isupper_l((unsigned char) wc, locale->lt) || islower_l((unsigned char) wc, locale->lt); } @@ -195,60 +217,80 @@ wc_iscased_libc_sb(pg_wchar wc, pg_locale_t locale) static bool wc_isdigit_libc_mb(pg_wchar wc, pg_locale_t locale) { + if (sizeof(wchar_t) < 4 && wc > (pg_wchar) 0xFFFF) + return false; return iswdigit_l((wint_t) wc, locale->lt); } static bool wc_isalpha_libc_mb(pg_wchar wc, pg_locale_t locale) { + if (sizeof(wchar_t) < 4 && wc > (pg_wchar) 0xFFFF) + return false; return iswalpha_l((wint_t) wc, locale->lt); } static bool wc_isalnum_libc_mb(pg_wchar wc, pg_locale_t locale) { + if (sizeof(wchar_t) < 4 && wc > (pg_wchar) 0xFFFF) + return false; return iswalnum_l((wint_t) wc, locale->lt); } static bool wc_isupper_libc_mb(pg_wchar wc, pg_locale_t locale) { + if (sizeof(wchar_t) < 4 && wc > (pg_wchar) 0xFFFF) + return false; return iswupper_l((wint_t) wc, locale->lt); } static bool wc_islower_libc_mb(pg_wchar wc, pg_locale_t locale) { + if (sizeof(wchar_t) < 4 && wc > (pg_wchar) 0xFFFF) + return false; return iswlower_l((wint_t) wc, locale->lt); } static bool wc_isgraph_libc_mb(pg_wchar wc, pg_locale_t locale) { + if (sizeof(wchar_t) < 4 && wc > (pg_wchar) 0xFFFF) + return false; return iswgraph_l((wint_t) wc, locale->lt); } static bool wc_isprint_libc_mb(pg_wchar wc, pg_locale_t locale) { + if (sizeof(wchar_t) < 4 && wc > (pg_wchar) 0xFFFF) + return false; return iswprint_l((wint_t) wc, locale->lt); } static bool wc_ispunct_libc_mb(pg_wchar wc, pg_locale_t locale) { + if (sizeof(wchar_t) < 4 && wc > (pg_wchar) 0xFFFF) + return false; return iswpunct_l((wint_t) wc, locale->lt); } static bool wc_isspace_libc_mb(pg_wchar wc, pg_locale_t locale) { + if (sizeof(wchar_t) < 4 && wc > (pg_wchar) 0xFFFF) + return false; return iswspace_l((wint_t) wc, locale->lt); } static bool wc_isxdigit_libc_mb(pg_wchar wc, pg_locale_t locale) { + if (sizeof(wchar_t) < 4 && wc > (pg_wchar) 0xFFFF) + return false; #ifndef WIN32 return iswxdigit_l((wint_t) wc, locale->lt); #else @@ -259,6 +301,8 @@ wc_isxdigit_libc_mb(pg_wchar wc, pg_locale_t locale) static bool wc_iscased_libc_mb(pg_wchar wc, pg_locale_t locale) { + if (sizeof(wchar_t) < 4 && wc > (pg_wchar) 0xFFFF) + return false; return iswupper_l((wint_t) wc, locale->lt) || iswlower_l((wint_t) wc, locale->lt); } @@ -271,7 +315,7 @@ toupper_libc_sb(pg_wchar wc, pg_locale_t locale) /* force C behavior for ASCII characters, per comments above */ if (locale->is_default && wc <= (pg_wchar) 127) return pg_ascii_toupper((unsigned char) wc); - if (wc <= (pg_wchar) UCHAR_MAX) + else if (wc <= (pg_wchar) UCHAR_MAX) return toupper_l((unsigned char) wc, locale->lt); else return wc; @@ -285,7 +329,7 @@ toupper_libc_mb(pg_wchar wc, pg_locale_t locale) /* force C behavior for ASCII characters, per comments above */ if (locale->is_default && wc <= (pg_wchar) 127) return pg_ascii_toupper((unsigned char) wc); - if (sizeof(wchar_t) >= 4 || wc <= (pg_wchar) 0xFFFF) + else if (sizeof(wchar_t) >= 4 || wc <= (pg_wchar) 0xFFFF) return towupper_l((wint_t) wc, locale->lt); else return wc; @@ -299,7 +343,7 @@ tolower_libc_sb(pg_wchar wc, pg_locale_t locale) /* force C behavior for ASCII characters, per comments above */ if (locale->is_default && wc <= (pg_wchar) 127) return pg_ascii_tolower((unsigned char) wc); - if (wc <= (pg_wchar) UCHAR_MAX) + else if (wc <= (pg_wchar) UCHAR_MAX) return tolower_l((unsigned char) wc, locale->lt); else return wc; @@ -313,7 +357,7 @@ tolower_libc_mb(pg_wchar wc, pg_locale_t locale) /* force C behavior for ASCII characters, per comments above */ if (locale->is_default && wc <= (pg_wchar) 127) return pg_ascii_tolower((unsigned char) wc); - if (sizeof(wchar_t) >= 4 || wc <= (pg_wchar) 0xFFFF) + else if (sizeof(wchar_t) >= 4 || wc <= (pg_wchar) 0xFFFF) return towlower_l((wint_t) wc, locale->lt); else return wc; From e4b24d2f56533b9d5a46a54b4f670e5129c4bac8 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Tue, 7 Jul 2026 18:20:15 -0700 Subject: [PATCH 117/481] pg_locale_libc.c: add missing casts to unsigned char. Discussion: https://postgr.es/m/20260630012919.78@rfd.leadboat.com Backpatch-through: 19 --- src/backend/utils/adt/pg_locale_libc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c index 0043371586d..b50b3f24efd 100644 --- a/src/backend/utils/adt/pg_locale_libc.c +++ b/src/backend/utils/adt/pg_locale_libc.c @@ -527,7 +527,7 @@ strlower_libc_sb(char *dest, size_t destsize, const char *src, size_t srclen, { if (*p >= 'A' && *p <= 'Z') *p += 'a' - 'A'; - else if (IS_HIGHBIT_SET(*p) && isupper_l(*p, loc)) + else if (IS_HIGHBIT_SET(*p) && isupper_l((unsigned char) *p, loc)) *p = tolower_l((unsigned char) *p, loc); } else @@ -611,14 +611,14 @@ strtitle_libc_sb(char *dest, size_t destsize, const char *src, size_t srclen, { if (*p >= 'A' && *p <= 'Z') *p += 'a' - 'A'; - else if (IS_HIGHBIT_SET(*p) && isupper_l(*p, loc)) + else if (IS_HIGHBIT_SET(*p) && isupper_l((unsigned char) *p, loc)) *p = tolower_l((unsigned char) *p, loc); } else { if (*p >= 'a' && *p <= 'z') *p -= 'a' - 'A'; - else if (IS_HIGHBIT_SET(*p) && islower_l(*p, loc)) + else if (IS_HIGHBIT_SET(*p) && islower_l((unsigned char) *p, loc)) *p = toupper_l((unsigned char) *p, loc); } } @@ -713,7 +713,7 @@ strupper_libc_sb(char *dest, size_t destsize, const char *src, size_t srclen, { if (*p >= 'a' && *p <= 'z') *p -= 'a' - 'A'; - else if (IS_HIGHBIT_SET(*p) && islower_l(*p, loc)) + else if (IS_HIGHBIT_SET(*p) && islower_l((unsigned char) *p, loc)) *p = toupper_l((unsigned char) *p, loc); } else From 64ed30fda8d77782bd69297e3892895ca9f84816 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 8 Jul 2026 12:44:06 +0900 Subject: [PATCH 118/481] doc: Clarify COPY FROM WHERE expression restrictions Commit aa606b9316a disallowed generated columns in COPY FROM WHERE expressions, and commit 21c69dc73f9 disallowed system columns. However, the COPY reference page still mentions only the restriction on subqueries. Update the documentation to also list generated columns and system columns as unsupported in COPY FROM WHERE expressions. Backpatch the generated-column documentation change to all supported versions. Backpatch the system-column documentation change to v19, where that restriction was introduced. Author: Fujii Masao Reviewed-by: Ayush Tiwari Discussion: https://postgr.es/m/CAHGQGwEgxErc54yVOAVWCsr1O=8pgw4oKRPuEQ9mfhkoYGR_XA@mail.gmail.com Backpatch-through: 14 --- doc/src/sgml/ref/copy.sgml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml index 4706c9a4410..b23433b2c41 100644 --- a/doc/src/sgml/ref/copy.sgml +++ b/doc/src/sgml/ref/copy.sgml @@ -545,10 +545,11 @@ WHERE condition - Currently, subqueries are not allowed in WHERE - expressions, and the evaluation does not see any changes made by the - COPY itself (this matters when the expression - contains calls to VOLATILE functions). + Currently, subqueries, system columns, and generated columns are not + allowed in WHERE expressions, and the evaluation + does not see any changes made by the COPY itself + (this matters when the expression contains calls to + VOLATILE functions). From 9120b7958b7b0f44589c635e41af9b33819615ff Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Wed, 8 Jul 2026 10:20:34 +0300 Subject: [PATCH 119/481] Fix misspelling in docs Reported-by: Erik Rijkers Discussion: https://www.postgresql.org/message-id/6223b7dc-bfee-fcff-88d9-13f99b8d4897@xs4all.nl Backpatch-through: 19 --- doc/src/sgml/xfunc.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index cb3cc09f16d..2b8a11e7ad0 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -3740,7 +3740,7 @@ my_shmem_init(void *arg) on whether the requested memory areas were already initialized by another backend. The callbacks will be called while holding an internal lock (ShmemIndexLock), which prevents the race condition of two backends - trying to initializing the memory area at the same time. + trying to initialize the memory area at the same time. From 7883ea13ffdc6c657923031d80b2505d08f51e33 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 8 Jul 2026 09:40:46 +0200 Subject: [PATCH 120/481] Fix replace_property_refs() ignoring the root of expression tree replace_property_refs() called expression_tree_mutator() with the root of the expression tree as the input node. But expression_tree_mutator() does not call the mutator function on the root node, so the root node remains unchanged. If the root node is a property reference or a lateral reference -- the two node kinds that replace_property_refs_mutator() rewrites -- it is returned unchanged. Modules after the rewriter do not know about property reference nodes, resulting in "ERROR: unrecognized node type: 63". Since varlevelsup of lateral references is not incremented, they are not resolved correctly in the planner, leading to many different symptoms. Fix this by calling replace_property_refs_mutator() directly from replace_property_refs(), similar to how other mutator functions do. The only case when a property reference or a lateral reference can be the root of a GRAPH_TABLE expression tree is when it is a bare property reference or a bare lateral reference in the WHERE clause. The COLUMNS clause is passed to replace_property_refs() as a targetlist. Every other expression has at least one expression node covering the property reference or a lateral reference in the expression tree. That explains why this bug was not seen so far. Author: Ashutosh Bapat Reported-by: Noah Misch Discussion: https://www.postgresql.org/message-id/flat/20260630173053.51.noahmisch%40microsoft.com --- src/backend/rewrite/rewriteGraphTable.c | 2 +- src/test/regress/expected/graph_table.out | 38 +++++++++++++++++------ src/test/regress/sql/graph_table.sql | 17 ++++++---- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/backend/rewrite/rewriteGraphTable.c b/src/backend/rewrite/rewriteGraphTable.c index 7db17bec312..cdb1f4c0dca 100644 --- a/src/backend/rewrite/rewriteGraphTable.c +++ b/src/backend/rewrite/rewriteGraphTable.c @@ -1159,7 +1159,7 @@ replace_property_refs(Oid propgraphid, Node *node, const List *mappings) context.mappings = mappings; context.propgraphid = propgraphid; - return expression_tree_mutator(node, replace_property_refs_mutator, &context); + return replace_property_refs_mutator(node, &context); } /* diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out index bd603ea0d77..a3d78a7ac43 100644 --- a/src/test/regress/expected/graph_table.out +++ b/src/test/regress/expected/graph_table.out @@ -248,12 +248,12 @@ SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers)->(o IS orders) COLUMNS -- Use table with a column name same as a property in the property graph so as -- to test resolution preferences. Property references are preferred over -- lateral table references. -CREATE TABLE x1 (a int, address text); -INSERT INTO x1 VALUES (1, 'one'), (2, 'two'); +CREATE TABLE x1 (a int, address text, flag boolean); +INSERT INTO x1 VALUES (1, 'one', true), (2, 'two', false); SELECT * FROM x1, GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.address = 'US' AND c.customer_id = x1.a)-[IS customer_orders]->(o IS orders) COLUMNS (c.name AS customer_name, c.customer_id AS cid)); - a | address | customer_name | cid ----+---------+---------------+----- - 1 | one | customer1 | 1 + a | address | flag | customer_name | cid +---+---------+------+---------------+----- + 1 | one | t | customer1 | 1 (1 row) SELECT x1.a, g.* FROM x1, GRAPH_TABLE (myshop MATCH (x1 IS customers WHERE x1.address = 'US')-[IS customer_orders]->(o IS orders) COLUMNS (x1.name AS customer_name, x1.customer_id AS cid, o.order_id)) g; @@ -263,6 +263,13 @@ SELECT x1.a, g.* FROM x1, GRAPH_TABLE (myshop MATCH (x1 IS customers WHERE x1.ad 2 | customer1 | 1 | 1 (2 rows) +-- bare lateral reference in WHERE clause +SELECT * FROM x1, GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.customer_id = x1.a) WHERE x1.flag COLUMNS (c.name AS customer_name)); + a | address | flag | customer_name +---+---------+------+--------------- + 1 | one | t | customer1 +(1 row) + -- lateral reference with multi-label pattern, which is rewritten as UNION of -- path queries SELECT x1.a, g.* FROM x1, @@ -864,12 +871,12 @@ CREATE TABLE cv2 () INHERITS (pv); INSERT INTO pv VALUES (1, 10); INSERT INTO cv1 VALUES (2, 20); INSERT INTO cv2 VALUES (3, 30); -CREATE TABLE pe (id int, src int, dest int, val int); +CREATE TABLE pe (id int, src int, dest int, val int, flag boolean); CREATE TABLE ce1 () INHERITS (pe); CREATE TABLE ce2 () INHERITS (pe); -INSERT INTO pe VALUES (1, 1, 2, 100); -INSERT INTO ce1 VALUES (2, 2, 3, 200); -INSERT INTO ce2 VALUES (3, 3, 1, 300); +INSERT INTO pe VALUES (1, 1, 2, 100, false); +INSERT INTO ce1 VALUES (2, 2, 3, 200, false); +INSERT INTO ce2 VALUES (3, 3, 1, 300, true); CREATE PROPERTY GRAPH g3 NODE TABLES ( pv KEY (id) @@ -887,6 +894,19 @@ SELECT * FROM GRAPH_TABLE (g3 MATCH (s IS pv)-[e IS pe]->(d IS pv) COLUMNS (s.va 30 | 300 | 10 (3 rows) +-- bare property reference in WHERE clause +SELECT * FROM GRAPH_TABLE (g3 MATCH (s IS pv)-[e IS pe WHERE e.flag]->(d IS pv) COLUMNS (s.val, e.val, d.val)) ORDER BY 1, 2, 3; + val | val | val +-----+-----+----- + 30 | 300 | 10 +(1 row) + +SELECT * FROM GRAPH_TABLE (g3 MATCH (s IS pv)-[e IS pe]->(d IS pv) WHERE e.flag COLUMNS (s.val, e.val, d.val)) ORDER BY 1, 2, 3; + val | val | val +-----+-----+----- + 30 | 300 | 10 +(1 row) + -- temporary property graph CREATE TEMPORARY PROPERTY GRAPH gtmp VERTEX TABLES ( diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql index 5c8049ed242..6aacc2d4aa5 100644 --- a/src/test/regress/sql/graph_table.sql +++ b/src/test/regress/sql/graph_table.sql @@ -156,10 +156,12 @@ SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers)->(o IS orders) COLUMNS -- Use table with a column name same as a property in the property graph so as -- to test resolution preferences. Property references are preferred over -- lateral table references. -CREATE TABLE x1 (a int, address text); -INSERT INTO x1 VALUES (1, 'one'), (2, 'two'); +CREATE TABLE x1 (a int, address text, flag boolean); +INSERT INTO x1 VALUES (1, 'one', true), (2, 'two', false); SELECT * FROM x1, GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.address = 'US' AND c.customer_id = x1.a)-[IS customer_orders]->(o IS orders) COLUMNS (c.name AS customer_name, c.customer_id AS cid)); SELECT x1.a, g.* FROM x1, GRAPH_TABLE (myshop MATCH (x1 IS customers WHERE x1.address = 'US')-[IS customer_orders]->(o IS orders) COLUMNS (x1.name AS customer_name, x1.customer_id AS cid, o.order_id)) g; +-- bare lateral reference in WHERE clause +SELECT * FROM x1, GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.customer_id = x1.a) WHERE x1.flag COLUMNS (c.name AS customer_name)); -- lateral reference with multi-label pattern, which is rewritten as UNION of -- path queries SELECT x1.a, g.* FROM x1, @@ -483,12 +485,12 @@ CREATE TABLE cv2 () INHERITS (pv); INSERT INTO pv VALUES (1, 10); INSERT INTO cv1 VALUES (2, 20); INSERT INTO cv2 VALUES (3, 30); -CREATE TABLE pe (id int, src int, dest int, val int); +CREATE TABLE pe (id int, src int, dest int, val int, flag boolean); CREATE TABLE ce1 () INHERITS (pe); CREATE TABLE ce2 () INHERITS (pe); -INSERT INTO pe VALUES (1, 1, 2, 100); -INSERT INTO ce1 VALUES (2, 2, 3, 200); -INSERT INTO ce2 VALUES (3, 3, 1, 300); +INSERT INTO pe VALUES (1, 1, 2, 100, false); +INSERT INTO ce1 VALUES (2, 2, 3, 200, false); +INSERT INTO ce2 VALUES (3, 3, 1, 300, true); CREATE PROPERTY GRAPH g3 NODE TABLES ( pv KEY (id) @@ -499,6 +501,9 @@ CREATE PROPERTY GRAPH g3 DESTINATION KEY(dest) REFERENCES pv(id) ); SELECT * FROM GRAPH_TABLE (g3 MATCH (s IS pv)-[e IS pe]->(d IS pv) COLUMNS (s.val, e.val, d.val)) ORDER BY 1, 2, 3; +-- bare property reference in WHERE clause +SELECT * FROM GRAPH_TABLE (g3 MATCH (s IS pv)-[e IS pe WHERE e.flag]->(d IS pv) COLUMNS (s.val, e.val, d.val)) ORDER BY 1, 2, 3; +SELECT * FROM GRAPH_TABLE (g3 MATCH (s IS pv)-[e IS pe]->(d IS pv) WHERE e.flag COLUMNS (s.val, e.val, d.val)) ORDER BY 1, 2, 3; -- temporary property graph CREATE TEMPORARY PROPERTY GRAPH gtmp VERTEX TABLES ( From b820c623dd5090ef69b8b8151a0b152f5d976fed Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 8 Jul 2026 10:11:11 +0200 Subject: [PATCH 121/481] Resolve unknown-type literals in property expressions When a string literal is provided as a property expression, the data type of the property was set to "unknown", which may lead to various failures when the property is used in GRAPH_TABLE or when its data type is compared against other properties with the same name. To fix this, call resolveTargetListUnknowns() on the targetlist of new properties being added to resolve unknown type literals. Reported-by: Noah Misch Author: Ashutosh Bapat Discussion: https://www.postgresql.org/message-id/flat/20260630173053.51.noahmisch%40microsoft.com --- src/backend/commands/propgraphcmds.c | 2 + .../expected/create_property_graph.out | 37 +++++++++++++++---- .../regress/sql/create_property_graph.sql | 5 +++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/backend/commands/propgraphcmds.c b/src/backend/commands/propgraphcmds.c index 6939a448895..c87c519b032 100644 --- a/src/backend/commands/propgraphcmds.c +++ b/src/backend/commands/propgraphcmds.c @@ -897,6 +897,8 @@ insert_property_records(Oid graphid, Oid ellabeloid, Oid pgerelid, const PropGra table_close(rel, NoLock); tp = transformTargetList(pstate, proplist, EXPR_KIND_PROPGRAPH_PROPERTY); + if (pstate->p_resolve_unknowns) + resolveTargetListUnknowns(pstate, tp); assign_expr_collations(pstate, (Node *) tp); foreach(lc, tp) diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out index 3638f7f9f68..7387751eac2 100644 --- a/src/test/regress/expected/create_property_graph.out +++ b/src/test/regress/expected/create_property_graph.out @@ -337,6 +337,10 @@ CREATE PROPERTY GRAPH gt SOURCE KEY (k1) REFERENCES v1(a) DESTINATION KEY (k2) REFERENCES v2(m) ); +-- data types of constant property values +CREATE PROPERTY GRAPH glc VERTEX TABLES ( + v1 KEY (a) LABEL l1 PROPERTIES ('foo' AS p1, 123 AS p2, 3.14 AS p3, true AS p4) +); -- information schema SELECT * FROM information_schema.property_graphs ORDER BY property_graph_name; property_graph_catalog | property_graph_schema | property_graph_name @@ -347,8 +351,9 @@ SELECT * FROM information_schema.property_graphs ORDER BY property_graph_name; regression | create_property_graph_tests | g4 regression | create_property_graph_tests | g5 regression | create_property_graph_tests | gc1 + regression | create_property_graph_tests | glc regression | create_property_graph_tests | gt -(7 rows) +(8 rows) SELECT * FROM information_schema.pg_element_tables ORDER BY property_graph_name, element_table_alias; property_graph_catalog | property_graph_schema | property_graph_name | element_table_alias | element_table_kind | table_catalog | table_schema | table_name | element_table_definition @@ -373,10 +378,11 @@ SELECT * FROM information_schema.pg_element_tables ORDER BY property_graph_name, regression | create_property_graph_tests | gc1 | tc1 | VERTEX | regression | create_property_graph_tests | tc1 | regression | create_property_graph_tests | gc1 | tc2 | VERTEX | regression | create_property_graph_tests | tc2 | regression | create_property_graph_tests | gc1 | tc3 | VERTEX | regression | create_property_graph_tests | tc3 | + regression | create_property_graph_tests | glc | v1 | VERTEX | regression | create_property_graph_tests | v1 | regression | create_property_graph_tests | gt | e | EDGE | regression | create_property_graph_tests | e | regression | create_property_graph_tests | gt | v1 | VERTEX | regression | create_property_graph_tests | v1 | regression | create_property_graph_tests | gt | v2 | VERTEX | regression | create_property_graph_tests | v2 | -(23 rows) +(24 rows) SELECT * FROM information_schema.pg_element_table_key_columns ORDER BY property_graph_name, element_table_alias, ordinal_position; property_graph_catalog | property_graph_schema | property_graph_name | element_table_alias | column_name | ordinal_position @@ -407,11 +413,12 @@ SELECT * FROM information_schema.pg_element_table_key_columns ORDER BY property_ regression | create_property_graph_tests | gc1 | tc1 | a | 1 regression | create_property_graph_tests | gc1 | tc2 | a | 1 regression | create_property_graph_tests | gc1 | tc3 | a | 1 + regression | create_property_graph_tests | glc | v1 | a | 1 regression | create_property_graph_tests | gt | e | k1 | 1 regression | create_property_graph_tests | gt | e | k2 | 2 regression | create_property_graph_tests | gt | v1 | a | 1 regression | create_property_graph_tests | gt | v2 | m | 1 -(30 rows) +(31 rows) SELECT * FROM information_schema.pg_edge_table_components ORDER BY property_graph_name, edge_table_alias, edge_end DESC, ordinal_position; property_graph_catalog | property_graph_schema | property_graph_name | edge_table_alias | vertex_table_alias | edge_end | edge_table_column_name | vertex_table_column_name | ordinal_position @@ -461,10 +468,11 @@ SELECT * FROM information_schema.pg_element_table_labels ORDER BY property_graph regression | create_property_graph_tests | gc1 | tc1 | tc1 regression | create_property_graph_tests | gc1 | tc2 | tc2 regression | create_property_graph_tests | gc1 | tc3 | tc3 + regression | create_property_graph_tests | glc | v1 | l1 regression | create_property_graph_tests | gt | e | e regression | create_property_graph_tests | gt | v1 | v1 regression | create_property_graph_tests | gt | v2 | v2 -(25 rows) +(26 rows) SELECT * FROM information_schema.pg_element_table_properties ORDER BY property_graph_name, element_table_alias, property_name; property_graph_catalog | property_graph_schema | property_graph_name | element_table_alias | property_name | property_expression @@ -515,6 +523,10 @@ SELECT * FROM information_schema.pg_element_table_properties ORDER BY property_g regression | create_property_graph_tests | gc1 | tc2 | b | ((b)::character varying COLLATE "C") regression | create_property_graph_tests | gc1 | tc3 | a | a regression | create_property_graph_tests | gc1 | tc3 | b | (b)::character varying + regression | create_property_graph_tests | glc | v1 | p1 | 'foo'::text + regression | create_property_graph_tests | glc | v1 | p2 | 123 + regression | create_property_graph_tests | glc | v1 | p3 | 3.14 + regression | create_property_graph_tests | glc | v1 | p4 | true regression | create_property_graph_tests | gt | e | c | c regression | create_property_graph_tests | gt | e | k1 | k1 regression | create_property_graph_tests | gt | e | k2 | k2 @@ -522,7 +534,7 @@ SELECT * FROM information_schema.pg_element_table_properties ORDER BY property_g regression | create_property_graph_tests | gt | v1 | b | b regression | create_property_graph_tests | gt | v2 | m | m regression | create_property_graph_tests | gt | v2 | n | n -(53 rows) +(57 rows) SELECT * FROM information_schema.pg_label_properties ORDER BY property_graph_name, label_name, property_name; property_graph_catalog | property_graph_schema | property_graph_name | label_name | property_name @@ -579,6 +591,10 @@ SELECT * FROM information_schema.pg_label_properties ORDER BY property_graph_nam regression | create_property_graph_tests | gc1 | tc2 | b regression | create_property_graph_tests | gc1 | tc3 | a regression | create_property_graph_tests | gc1 | tc3 | b + regression | create_property_graph_tests | glc | l1 | p1 + regression | create_property_graph_tests | glc | l1 | p2 + regression | create_property_graph_tests | glc | l1 | p3 + regression | create_property_graph_tests | glc | l1 | p4 regression | create_property_graph_tests | gt | e | c regression | create_property_graph_tests | gt | e | k1 regression | create_property_graph_tests | gt | e | k2 @@ -586,7 +602,7 @@ SELECT * FROM information_schema.pg_label_properties ORDER BY property_graph_nam regression | create_property_graph_tests | gt | v1 | b regression | create_property_graph_tests | gt | v2 | m regression | create_property_graph_tests | gt | v2 | n -(59 rows) +(63 rows) SELECT * FROM information_schema.pg_labels ORDER BY property_graph_name, label_name; property_graph_catalog | property_graph_schema | property_graph_name | label_name @@ -613,10 +629,11 @@ SELECT * FROM information_schema.pg_labels ORDER BY property_graph_name, label_n regression | create_property_graph_tests | gc1 | tc1 regression | create_property_graph_tests | gc1 | tc2 regression | create_property_graph_tests | gc1 | tc3 + regression | create_property_graph_tests | glc | l1 regression | create_property_graph_tests | gt | e regression | create_property_graph_tests | gt | v1 regression | create_property_graph_tests | gt | v2 -(25 rows) +(26 rows) SELECT * FROM information_schema.pg_property_data_types ORDER BY property_graph_name, property_name; property_graph_catalog | property_graph_schema | property_graph_name | property_name | data_type | character_maximum_length | character_octet_length | character_set_catalog | character_set_schema | character_set_name | collation_catalog | collation_schema | collation_name | numeric_precision | numeric_precision_radix | numeric_scale | datetime_precision | interval_type | interval_precision | user_defined_type_catalog | user_defined_type_schema | user_defined_type_name | scope_catalog | scope_schema | scope_name | maximum_cardinality | dtd_identifier @@ -652,6 +669,10 @@ SELECT * FROM information_schema.pg_property_data_types ORDER BY property_graph_ regression | create_property_graph_tests | gc1 | eb | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | eb regression | create_property_graph_tests | gc1 | ek1 | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | ek1 regression | create_property_graph_tests | gc1 | ek2 | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | ek2 + regression | create_property_graph_tests | glc | p1 | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | p1 + regression | create_property_graph_tests | glc | p2 | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | p2 + regression | create_property_graph_tests | glc | p3 | numeric | | | | | | regression | | | | | | | | | regression | pg_catalog | numeric | | | | | p3 + regression | create_property_graph_tests | glc | p4 | boolean | | | | | | regression | | | | | | | | | regression | pg_catalog | bool | | | | | p4 regression | create_property_graph_tests | gt | a | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | a regression | create_property_graph_tests | gt | b | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | b regression | create_property_graph_tests | gt | c | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | c @@ -659,7 +680,7 @@ SELECT * FROM information_schema.pg_property_data_types ORDER BY property_graph_ regression | create_property_graph_tests | gt | k2 | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | k2 regression | create_property_graph_tests | gt | m | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | m regression | create_property_graph_tests | gt | n | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | n -(38 rows) +(42 rows) SELECT * FROM information_schema.pg_property_graph_privileges WHERE grantee LIKE 'regress%' ORDER BY property_graph_name, grantor, grantee, privilege_type; grantor | grantee | property_graph_catalog | property_graph_schema | property_graph_name | privilege_type | is_grantable diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql index 5262971342c..3494390b923 100644 --- a/src/test/regress/sql/create_property_graph.sql +++ b/src/test/regress/sql/create_property_graph.sql @@ -278,6 +278,11 @@ CREATE PROPERTY GRAPH gt DESTINATION KEY (k2) REFERENCES v2(m) ); +-- data types of constant property values +CREATE PROPERTY GRAPH glc VERTEX TABLES ( + v1 KEY (a) LABEL l1 PROPERTIES ('foo' AS p1, 123 AS p2, 3.14 AS p3, true AS p4) +); + -- information schema SELECT * FROM information_schema.property_graphs ORDER BY property_graph_name; From 67490b55f38d98bd08a6fa2764dd44a2a7c5a2db Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 8 Jul 2026 18:15:33 +0900 Subject: [PATCH 122/481] doc: Clarify pg_get_sequence_data() NULL-return cases The documentation previously said that pg_get_sequence_data() returns a row of NULL values if the sequence does not exist or if the current user lacks privileges on it. This was incomplete and could be misleading. A nonexistent relation name is rejected during regclass input conversion, while the function returns NULLs for a nonexistent relation OID and several other cases. This commit clarifies that the function returns NULLs when the specified relation OID does not exist, the relation is not a sequence, the current user lacks SELECT privilege on the sequence, the sequence belongs to another session's temporary schema, or it is an unlogged sequence on a standby server. Author: Amit Kapila Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CAA4eK1JOo0aJRhFHNWpj3hMwaTtNOopY34f1Lh_QD=z=+DrzWQ@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/func/func-sequence.sgml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/func/func-sequence.sgml b/doc/src/sgml/func/func-sequence.sgml index de266c36296..9301faa67d2 100644 --- a/doc/src/sgml/func/func-sequence.sgml +++ b/doc/src/sgml/func/func-sequence.sgml @@ -163,13 +163,15 @@ SELECT setval('myseq', 42, false); Next nextvalis_called indicates whether the sequence has been used. page_lsn is the LSN corresponding to the most recent WAL record that modified this sequence relation. - This function returns a row of NULL values if the sequence does not - exist or if the current user lacks privileges on it. + This function returns a row of NULL values if the specified relation + OID does not exist, if it is not a sequence, if the current user lacks + SELECT privilege on the sequence, if the sequence + is another session's temporary sequence, or if it is an unlogged + sequence on a standby server. This function is primarily intended for internal use by pg_dump and by - logical replication to synchronize sequences. It requires - SELECT privilege on the sequence. + logical replication to synchronize sequences. From 165dc09b28619510d9ab0034fdfccfb7af5422ae Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 8 Jul 2026 18:16:38 +0900 Subject: [PATCH 123/481] Add hints for sequence synchronization permission warnings Sequence synchronization reports insufficient privileges on publisher and subscriber sequences, but the warnings do not indicate which role needs which privilege. This makes common configuration mistakes harder to diagnose. Add HINT messages for these warnings. Publisher-side warnings suggest granting SELECT to the role used for the replication connection. Subscriber-side warnings suggest granting UPDATE to the subscription owner when run_as_owner is enabled. Otherwise, the worker runs as the sequence owner, so no useful GRANT hint can be provided. Suggested-by : Amit Kapila Author: Fujii Masao Reviewed-by: Amit Kapila Reviewed-by: Bharath Rupireddy Discussion: https://postgr.es/m/CAA4eK1JOo0aJRhFHNWpj3hMwaTtNOopY34f1Lh_QD=z=+DrzWQ@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/logical-replication.sgml | 14 ++++++++--- .../replication/logical/sequencesync.c | 23 +++++++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index 5befefd9c5a..d7d75b7c9a5 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -2542,9 +2542,10 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - In order to be able to copy the initial table or sequence data, the role - used for the replication connection must have the SELECT - privilege on a published table or sequence (or be a superuser). + In order to be able to copy the initial table data or synchronize + sequences, the role used for the replication connection must have the + SELECT privilege on a published table or sequence (or be + a superuser). @@ -2611,6 +2612,13 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER security within the database is of no concern. + + When synchronizing sequences with + run_as_owner = true, the subscription owner similarly + needs UPDATE privilege on the target sequence and does + not need privileges to SET ROLE to the sequence owner. + + On the publisher, privileges are only checked once at the start of a replication connection and are not re-checked as each change record is read. diff --git a/src/backend/replication/logical/sequencesync.c b/src/backend/replication/logical/sequencesync.c index f47f962c7db..770fa5de10b 100644 --- a/src/backend/replication/logical/sequencesync.c +++ b/src/backend/replication/logical/sequencesync.c @@ -201,12 +201,26 @@ report_sequence_errors(List *mismatched_seqs_idx, if (sub_insuffperm_seqs_idx) { get_sequences_string(sub_insuffperm_seqs_idx, &seqstr); + + /* + * With run_as_owner enabled, sequence synchronization runs as the + * subscription owner, so a missing UPDATE privilege should be granted + * to that role. Otherwise, the worker switches to the sequence owner + * before checking privileges, so no useful GRANT hint can be + * provided. + */ ereport(WARNING, errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg_plural("insufficient privileges on subscriber sequence (%s)", "insufficient privileges on subscriber sequences (%s)", list_length(sub_insuffperm_seqs_idx), - seqstr.data)); + seqstr.data), + MySubscription->runasowner ? + errhint_plural("Grant UPDATE on the sequence to the subscription " + "owner on the subscriber.", + "Grant UPDATE on the sequences to the subscription " + "owner on the subscriber.", + list_length(sub_insuffperm_seqs_idx)) : 0); } if (pub_insuffperm_seqs_idx) @@ -217,7 +231,12 @@ report_sequence_errors(List *mismatched_seqs_idx, errmsg_plural("insufficient privileges on publisher sequence (%s)", "insufficient privileges on publisher sequences (%s)", list_length(pub_insuffperm_seqs_idx), - seqstr.data)); + seqstr.data), + errhint_plural("Grant SELECT on the sequence to the role used for " + "the replication connection on the publisher.", + "Grant SELECT on the sequences to the role used for " + "the replication connection on the publisher.", + list_length(pub_insuffperm_seqs_idx))); } if (missing_seqs_idx) From 9530898940302d6f501fb54a3fbc61cbfb7768bf Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 8 Jul 2026 18:44:54 +0200 Subject: [PATCH 124/481] Whole-row fixes for ALTER COLUMN SET EXPRESSION When changing the expression of a generated column via ALTER TABLE ALTER COLUMN SET EXPRESSION, objects that depend on the column via indirect whole-row references (such as CHECK constraints, indexes) must be handled specially, because technically pg_depend does not contain such dependencies, see recordDependencyOnSingleRelExpr->find_expr_references_walker. This is a fix for commit f80bedd52, "Allow ALTER COLUMN SET EXPRESSION on virtual columns with CHECK constraints". Author: jian he Co-authored-by: Peter Eisentraut Reported-by: Ayush Tiwari Reviewed-by: Ayush Tiwari Reviewed-by: solai v Reviewed-by: Zsolt Parragi Discussion: https://www.postgresql.org/message-id/flat/CAJTYsWXOkyeDVbzymWc9sKrq7Y_MUv6XJXN4H9GfsBOPd3NJ+w@mail.gmail.com --- src/backend/commands/tablecmds.c | 176 ++++++++++++++++++ .../regress/expected/generated_stored.out | 9 + .../regress/expected/generated_virtual.out | 9 + src/test/regress/sql/generated_stored.sql | 10 + src/test/regress/sql/generated_virtual.sql | 10 + 5 files changed, 214 insertions(+) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 472db112fa7..44bb18d34a0 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -693,6 +693,7 @@ static ObjectAddress ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd, LOCKMODE lockmode); static void RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype, Relation rel, AttrNumber attnum, const char *colName); +static void RememberWholeRowDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype, Relation rel); static void RememberConstraintForRebuilding(Oid conoid, AlteredTableInfo *tab); static void RememberIndexForRebuilding(Oid indoid, AlteredTableInfo *tab); static void RememberStatisticsForRebuilding(Oid stxoid, AlteredTableInfo *tab); @@ -8773,6 +8774,13 @@ ATExecSetExpression(AlteredTableInfo *tab, Relation rel, const char *colName, */ RememberAllDependentForRebuilding(tab, AT_SetExpression, rel, attnum, colName); + /* + * Find whole-row referenced objects that depend on the column + * (constraints, indexes, etc.), and record enough information to let us + * recreate the objects. + */ + RememberWholeRowDependentForRebuilding(tab, AT_SetExpression, rel); + /* * Drop the dependency records of the GENERATED expression, in particular * its INTERNAL dependency on the column, which would otherwise cause @@ -15735,6 +15743,174 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype, table_close(depRel, NoLock); } +/* + * Record information about dependencies between objects with whole-row Var + * references (indexes, check constraints, etc.) and the relation. + * + * See also RememberAllDependentForRebuilding, which handles non-whole-row Var + * references. + * + * This function currently applies only to ALTER COLUMN SET EXPRESSION. + */ +static void +RememberWholeRowDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype, Relation rel) +{ + ScanKeyData skey; + Relation pg_constraint; + Relation pg_index; + SysScanDesc conscan; + SysScanDesc indscan; + HeapTuple constrTuple; + HeapTuple indexTuple; + bool isnull; + + Assert(subtype == AT_SetExpression); + + /* + * Check CHECK constraints with whole-row references first. + */ + if (RelationGetDescr(rel)->constr && + RelationGetDescr(rel)->constr->num_check > 0) + { + pg_constraint = table_open(ConstraintRelationId, AccessShareLock); + + ScanKeyInit(&skey, + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(rel))); + + conscan = systable_beginscan(pg_constraint, + ConstraintRelidTypidNameIndexId, + true, + NULL, + 1, + &skey); + + while (HeapTupleIsValid(constrTuple = systable_getnext(conscan))) + { + Form_pg_constraint conform = (Form_pg_constraint) GETSTRUCT(constrTuple); + Datum exprDatum; + + if (conform->contype != CONSTRAINT_CHECK) + continue; + + exprDatum = heap_getattr(constrTuple, + Anum_pg_constraint_conbin, + RelationGetDescr(pg_constraint), + &isnull); + if (isnull) + elog(ERROR, "null conbin for relation \"%s\"", + RelationGetRelationName(rel)); + else + { + char *exprString; + Node *expr; + Bitmapset *expr_attrs = NULL; + + exprString = TextDatumGetCString(exprDatum); + expr = stringToNode(exprString); + pfree(exprString); + + /* Find all attributes referenced */ + pull_varattnos(expr, 1, &expr_attrs); + + /* + * If the CHECK constraint contains whole-row reference then + * remember it. + */ + if (bms_is_member(InvalidAttrNumber - FirstLowInvalidHeapAttributeNumber, expr_attrs)) + { + RememberConstraintForRebuilding(conform->oid, tab); + } + } + } + systable_endscan(conscan); + table_close(pg_constraint, AccessShareLock); + } + + /* + * Now check indexes with whole-row references. Prepare to scan pg_index + * for entries having indrelid matching this relation. + */ + ScanKeyInit(&skey, + Anum_pg_index_indrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(rel))); + + pg_index = table_open(IndexRelationId, AccessShareLock); + + indscan = systable_beginscan(pg_index, + IndexIndrelidIndexId, + true, + NULL, + 1, + &skey); + + while (HeapTupleIsValid(indexTuple = systable_getnext(indscan))) + { + Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple); + Datum exprDatum; + + exprDatum = heap_getattr(indexTuple, + Anum_pg_index_indexprs, + RelationGetDescr(pg_index), + &isnull); + if (!isnull) + { + char *exprString; + Node *expr; + Bitmapset *expr_attrs = NULL; + + exprString = TextDatumGetCString(exprDatum); + expr = stringToNode(exprString); + pfree(exprString); + + /* Find all attributes referenced */ + pull_varattnos(expr, 1, &expr_attrs); + + /* + * If the index expression contains a whole-row reference then + * remember it. + */ + if (bms_is_member(InvalidAttrNumber - FirstLowInvalidHeapAttributeNumber, expr_attrs)) + { + RememberIndexForRebuilding(index->indexrelid, tab); + continue; + } + } + + exprDatum = heap_getattr(indexTuple, + Anum_pg_index_indpred, + RelationGetDescr(pg_index), + &isnull); + if (!isnull) + { + char *exprString; + Node *expr; + Bitmapset *expr_attrs = NULL; + + exprString = TextDatumGetCString(exprDatum); + expr = stringToNode(exprString); + pfree(exprString); + + /* Find all attributes referenced */ + pull_varattnos(expr, 1, &expr_attrs); + + /* + * If the index predicate expression contains a whole-row + * reference then remember it. + */ + if (bms_is_member(InvalidAttrNumber - FirstLowInvalidHeapAttributeNumber, expr_attrs)) + { + RememberIndexForRebuilding(index->indexrelid, tab); + } + } + } + + systable_endscan(indscan); + table_close(pg_index, AccessShareLock); +} + /* * Subroutine for ATExecAlterColumnType: remember that a replica identity * needs to be reset. diff --git a/src/test/regress/expected/generated_stored.out b/src/test/regress/expected/generated_stored.out index e17ba2f4881..6a8b5113e73 100644 --- a/src/test/regress/expected/generated_stored.out +++ b/src/test/regress/expected/generated_stored.out @@ -688,6 +688,15 @@ INSERT INTO gtest20c VALUES (1); -- ok INSERT INTO gtest20c VALUES (NULL); -- fails ERROR: new row for relation "gtest20c" violates check constraint "whole_row_check" DETAIL: Failing row contains (null, null). +ALTER TABLE gtest20c ALTER COLUMN b SET EXPRESSION AS (NULL::int); -- violates constraint +ERROR: check constraint "whole_row_check" of relation "gtest20c" is violated by some row +-- index with whole-row reference needs rebuild +CREATE TABLE gtest20d (a int, b int GENERATED ALWAYS AS (a * 2) STORED); +INSERT INTO gtest20d VALUES (1), (1); +CREATE INDEX gtest20d_idx1 ON gtest20d (a) WHERE gtest20d = ROW (1, 2); +ALTER TABLE gtest20d ALTER COLUMN b SET EXPRESSION AS (a * 2::bigint); -- index rebuild +CREATE INDEX gtest20d_idx2 ON gtest20d ((gtest20d = ROW (1, 2))); +ALTER TABLE gtest20d ALTER COLUMN b SET EXPRESSION AS (a * 3); -- index rebuild -- not-null constraints CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL); INSERT INTO gtest21a (a) VALUES (1); -- ok diff --git a/src/test/regress/expected/generated_virtual.out b/src/test/regress/expected/generated_virtual.out index 01ee29fee10..6ee029796f1 100644 --- a/src/test/regress/expected/generated_virtual.out +++ b/src/test/regress/expected/generated_virtual.out @@ -694,6 +694,15 @@ INSERT INTO gtest20c VALUES (1); -- ok INSERT INTO gtest20c VALUES (NULL); -- fails ERROR: new row for relation "gtest20c" violates check constraint "whole_row_check" DETAIL: Failing row contains (null, virtual). +ALTER TABLE gtest20c ALTER COLUMN b SET EXPRESSION AS (NULL::int); -- violates constraint +ERROR: check constraint "whole_row_check" of relation "gtest20c" is violated by some row +-- index with whole-row reference needs rebuild +CREATE TABLE gtest20d (a int, b int GENERATED ALWAYS AS (a * 2) VIRTUAL); +INSERT INTO gtest20d VALUES (1), (1); +CREATE INDEX gtest20d_idx1 ON gtest20d (a) WHERE gtest20d = ROW (1, 2); +ALTER TABLE gtest20d ALTER COLUMN b SET EXPRESSION AS (a * 2::bigint); -- index rebuild +CREATE INDEX gtest20d_idx2 ON gtest20d ((gtest20d = ROW (1, 2))); +ALTER TABLE gtest20d ALTER COLUMN b SET EXPRESSION AS (a * 3); -- index rebuild -- not-null constraints CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) VIRTUAL NOT NULL); INSERT INTO gtest21a (a) VALUES (1); -- ok diff --git a/src/test/regress/sql/generated_stored.sql b/src/test/regress/sql/generated_stored.sql index 85b6212023d..b349a16ddf3 100644 --- a/src/test/regress/sql/generated_stored.sql +++ b/src/test/regress/sql/generated_stored.sql @@ -341,6 +341,16 @@ CREATE TABLE gtest20c (a int, b int GENERATED ALWAYS AS (a * 2) STORED); ALTER TABLE gtest20c ADD CONSTRAINT whole_row_check CHECK (gtest20c IS NOT NULL); INSERT INTO gtest20c VALUES (1); -- ok INSERT INTO gtest20c VALUES (NULL); -- fails +ALTER TABLE gtest20c ALTER COLUMN b SET EXPRESSION AS (NULL::int); -- violates constraint + +-- index with whole-row reference needs rebuild +CREATE TABLE gtest20d (a int, b int GENERATED ALWAYS AS (a * 2) STORED); +INSERT INTO gtest20d VALUES (1), (1); +CREATE INDEX gtest20d_idx1 ON gtest20d (a) WHERE gtest20d = ROW (1, 2); + +ALTER TABLE gtest20d ALTER COLUMN b SET EXPRESSION AS (a * 2::bigint); -- index rebuild +CREATE INDEX gtest20d_idx2 ON gtest20d ((gtest20d = ROW (1, 2))); +ALTER TABLE gtest20d ALTER COLUMN b SET EXPRESSION AS (a * 3); -- index rebuild -- not-null constraints CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL); diff --git a/src/test/regress/sql/generated_virtual.sql b/src/test/regress/sql/generated_virtual.sql index 0cb14eb0e36..ed9d50fe784 100644 --- a/src/test/regress/sql/generated_virtual.sql +++ b/src/test/regress/sql/generated_virtual.sql @@ -347,6 +347,16 @@ CREATE TABLE gtest20c (a int, b int GENERATED ALWAYS AS (a * 2) VIRTUAL); ALTER TABLE gtest20c ADD CONSTRAINT whole_row_check CHECK (gtest20c IS NOT NULL); INSERT INTO gtest20c VALUES (1); -- ok INSERT INTO gtest20c VALUES (NULL); -- fails +ALTER TABLE gtest20c ALTER COLUMN b SET EXPRESSION AS (NULL::int); -- violates constraint + +-- index with whole-row reference needs rebuild +CREATE TABLE gtest20d (a int, b int GENERATED ALWAYS AS (a * 2) VIRTUAL); +INSERT INTO gtest20d VALUES (1), (1); +CREATE INDEX gtest20d_idx1 ON gtest20d (a) WHERE gtest20d = ROW (1, 2); + +ALTER TABLE gtest20d ALTER COLUMN b SET EXPRESSION AS (a * 2::bigint); -- index rebuild +CREATE INDEX gtest20d_idx2 ON gtest20d ((gtest20d = ROW (1, 2))); +ALTER TABLE gtest20d ALTER COLUMN b SET EXPRESSION AS (a * 3); -- index rebuild -- not-null constraints CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) VIRTUAL NOT NULL); From 56fa044d15e8b06d84889f06f5def21a62fb86a3 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Wed, 8 Jul 2026 20:44:22 +0300 Subject: [PATCH 125/481] Move WAIT_FOR_WAL_* wait events from Client to IPC class WAIT_FOR_WAL_FLUSH, WAIT_FOR_WAL_REPLAY, and WAIT_FOR_WAL_WRITE were placed in the WaitEventClient class. But WaitEventClient is about waiting for a socket to become readable or writable, while these events have other delay sources as well: local fsync and local replay, which may be disk- or CPU-bound. WaitEventIPC is a better fit, so move them there. Reported-by: Noah Misch Discussion: https://postgr.es/m/20260706012642.f9.noahmisch@microsoft.com Backpatch-through: 19 --- src/backend/utils/activity/wait_event_names.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt index 560659f9568..1016502d042 100644 --- a/src/backend/utils/activity/wait_event_names.txt +++ b/src/backend/utils/activity/wait_event_names.txt @@ -89,9 +89,6 @@ LIBPQWALRECEIVER_CONNECT "Waiting in WAL receiver to establish connection to rem LIBPQWALRECEIVER_RECEIVE "Waiting in WAL receiver to receive data from remote server." SSL_OPEN_SERVER "Waiting for SSL while attempting connection." WAIT_FOR_STANDBY_CONFIRMATION "Waiting for WAL to be received and flushed by the physical standby." -WAIT_FOR_WAL_FLUSH "Waiting for WAL flush to reach a target LSN on a primary or standby." -WAIT_FOR_WAL_REPLAY "Waiting for WAL replay to reach a target LSN on a standby." -WAIT_FOR_WAL_WRITE "Waiting for WAL write to reach a target LSN on a standby." WAL_SENDER_WAIT_FOR_WAL "Waiting for WAL to be flushed in WAL sender process." WAL_SENDER_WRITE_DATA "Waiting for any activity when processing replies from WAL receiver in WAL sender process." @@ -162,6 +159,9 @@ REPLICATION_SLOT_DROP "Waiting for a replication slot to become inactive so it c RESTORE_COMMAND "Waiting for to complete." SAFE_SNAPSHOT "Waiting to obtain a valid snapshot for a READ ONLY DEFERRABLE transaction." SYNC_REP "Waiting for confirmation from a remote server during synchronous replication." +WAIT_FOR_WAL_FLUSH "Waiting for WAL flush to reach a target LSN on a primary or standby." +WAIT_FOR_WAL_REPLAY "Waiting for WAL replay to reach a target LSN on a standby." +WAIT_FOR_WAL_WRITE "Waiting for WAL write to reach a target LSN on a standby." WAL_RECEIVER_EXIT "Waiting for the WAL receiver to exit." WAL_RECEIVER_WAIT_START "Waiting for startup process to send initial data for streaming replication." WAL_SUMMARY_READY "Waiting for a new WAL summary to be generated." From 7048e50f8f93057128db7e8a0a2925248f71a266 Mon Sep 17 00:00:00 2001 From: Dean Rasheed Date: Wed, 8 Jul 2026 20:46:25 +0100 Subject: [PATCH 126/481] Fix RETURNING OLD with BEFORE UPDATE trigger and concurrent update. When executing an UPDATE with a RETURNING clause on a table with a BEFORE UPDATE row trigger, the computation of the OLD values in the RETURNING list was incorrect if the target tuple was concurrently updated by another session, at isolation level READ COMMITTED. The problem was that the trigger code would lock the target tuple, waiting for the other session to commit, and then fetch the updated target tuple, but ExecUpdate() would not realise that the target tuple had changed, and use the outdated target tuple for computing OLD values. Fix by having ExecUpdate() check the TM_FailureData from trigger execution and re-fetch the target tuple if necessary. Re-fetching the target tuple like this is a little inefficient, but probably negligible compared to the trigger execution and update. A better long-term fix might be to move the EPQ code out of trigger.c, and let ExecUpdate() handle it, like ExecMergeMatched() does, but that would likely mean changing the trigger API, which seems a bit much for back-patching. Backpatch to v18, where support for RETURNING OLD/NEW was added. Bug: #19536 Reported-by: Jonas Boberg Diagnosed-by: Bharath Rupireddy Author: Dean Rasheed Reviewed-by: Bharath Rupireddy Discussion: https://postgr.es/m/19536-73ce5847e6c0e7b1@postgresql.org Backpatch-through: 18 --- src/backend/executor/nodeModifyTable.c | 19 ++ .../expected/eval-plan-qual-trigger.out | 258 +++++++++--------- .../expected/merge-match-recheck.out | 179 +++++++++++- .../specs/eval-plan-qual-trigger.spec | 8 +- .../isolation/specs/merge-match-recheck.spec | 21 +- 5 files changed, 333 insertions(+), 152 deletions(-) diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index c333d7139fa..b9781eb3b95 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -2765,9 +2765,28 @@ ExecUpdate(ModifyTableContext *context, ResultRelInfo *resultRelInfo, * Prepare for the update. This includes BEFORE ROW triggers, so we're * done if it says we are. */ + context->tmfd.traversed = false; if (!ExecUpdatePrologue(context, resultRelInfo, tupleid, oldtuple, slot, NULL)) return NULL; + /* + * If the target tuple was concurrently updated, the trigger code will + * have done EPQ and updated tupleid, following the update chain. In this + * case, we must fetch the most recent version of old tuple for the + * benefit of RETURNING. Technically, we could get away with not doing + * this, if there is no RETURNING clause, or it doesn't refer to OLD, but + * it seems preferable to always ensure that the contents of oldSlot are + * correct. + */ + if (context->tmfd.traversed) + { + if (!table_tuple_fetch_row_version(resultRelInfo->ri_RelationDesc, + tupleid, + SnapshotAny, + oldSlot)) + elog(ERROR, "failed to re-fetch tuple updated during trigger execution"); + } + /* INSTEAD OF ROW UPDATE Triggers */ if (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->trig_update_instead_row) diff --git a/src/test/isolation/expected/eval-plan-qual-trigger.out b/src/test/isolation/expected/eval-plan-qual-trigger.out index f6714c2e599..eca8606f60f 100644 --- a/src/test/isolation/expected/eval-plan-qual-trigger.out +++ b/src/test/isolation/expected/eval-plan-qual-trigger.out @@ -61,11 +61,11 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; -key |data ------+------------------ -key-a|val-a-s1-ups1-ups2 +key |data |check_old_and_new +-----+------------------+----------------- +key-a|val-a-s1-ups1-ups2|t (1 row) step s2_c: COMMIT; @@ -132,11 +132,11 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; -key |data ------+------------- -key-a|val-a-s1-ups2 +key |data |check_old_and_new +-----+-------------+----------------- +key-a|val-a-s1-ups2|t (1 row) step s2_c: COMMIT; @@ -205,11 +205,11 @@ step s2_del_a: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING * + RETURNING *, data = old.data AS check_old; -key |data ------+------------- -key-a|val-a-s1-ups1 +key |data |check_old +-----+-------------+--------- +key-a|val-a-s1-ups1|t (1 row) step s2_c: COMMIT; @@ -277,11 +277,11 @@ step s2_del_a: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING * + RETURNING *, data = old.data AS check_old; -key |data ------+-------- -key-a|val-a-s1 +key |data |check_old +-----+--------+--------- +key-a|val-a-s1|t (1 row) step s2_c: COMMIT; @@ -343,7 +343,7 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-a = text key-a: t @@ -352,9 +352,9 @@ s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (k s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1-ups1) new: (key-a,val-a-s1-ups1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------------ -key-a|val-a-s1-ups1-ups2 +key |data |check_old_and_new +-----+------------------+----------------- +key-a|val-a-s1-ups1-ups2|t (1 row) step s2_c: COMMIT; @@ -417,16 +417,16 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_r: ROLLBACK; s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------- -key-a|val-a-s1-ups2 +key |data |check_old_and_new +-----+-------------+----------------- +key-a|val-a-s1-ups2|t (1 row) step s2_c: COMMIT; @@ -491,7 +491,7 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-a = text key-a: t @@ -500,9 +500,9 @@ s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (k s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1-ups1) new: (key-a,val-a-s1-ups1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------------ -key-a|val-a-s1-ups1-ups2 +key |data |check_old_and_new +-----+------------------+----------------- +key-a|val-a-s1-ups1-ups2|t (1 row) step s2_c: COMMIT; @@ -567,16 +567,16 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_r: ROLLBACK; s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------- -key-a|val-a-s1-ups2 +key |data |check_old_and_new +-----+-------------+----------------- +key-a|val-a-s1-ups2|t (1 row) step s2_c: COMMIT; @@ -641,13 +641,13 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-b = text key-a: f step s2_upd_a_data: <... completed> -key|data ----+---- +key|data|check_old_and_new +---+----+----------------- (0 rows) step s2_c: COMMIT; @@ -711,16 +711,16 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_r: ROLLBACK; s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------- -key-a|val-a-s1-ups2 +key |data |check_old_and_new +-----+-------------+----------------- +key-a|val-a-s1-ups2|t (1 row) step s2_c: COMMIT; @@ -873,7 +873,7 @@ step s2_upsert_a_data: WHERE noisy_oper('upd', trigtest.key, '=', 'key-a') AND noisy_oper('upk', trigtest.data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-upserts2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-a = text key-a: t @@ -881,9 +881,9 @@ s2: NOTICE: upk: text val-a-s1-ups1 <> text mismatch: t s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1-ups1) new: (key-a,val-a-s1-ups1-upserts2) s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1-ups1) new: (key-a,val-a-s1-ups1-upserts2) step s2_upsert_a_data: <... completed> -key |data ------+---------------------- -key-a|val-a-s1-ups1-upserts2 +key |data |check_old_and_new +-----+----------------------+----------------- +key-a|val-a-s1-ups1-upserts2|t (1 row) step s2_c: COMMIT; @@ -955,7 +955,7 @@ step s2_upsert_a_data: WHERE noisy_oper('upd', trigtest.key, '=', 'key-a') AND noisy_oper('upk', trigtest.data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-upserts2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-a = text key-a: t @@ -963,9 +963,9 @@ s2: NOTICE: upk: text val-a-s1-ups1 <> text mismatch: t s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1-ups1) new: (key-a,val-a-s1-ups1-upserts2) s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1-ups1) new: (key-a,val-a-s1-ups1-upserts2) step s2_upsert_a_data: <... completed> -key |data ------+---------------------- -key-a|val-a-s1-ups1-upserts2 +key |data |check_old_and_new +-----+----------------------+----------------- +key-a|val-a-s1-ups1-upserts2|t (1 row) step s2_c: COMMIT; @@ -1012,7 +1012,7 @@ step s2_upsert_a_data: WHERE noisy_oper('upd', trigtest.key, '=', 'key-a') AND noisy_oper('upk', trigtest.data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-upserts2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-a = text key-a: t @@ -1020,9 +1020,9 @@ s2: NOTICE: upk: text val-a-s1 <> text mismatch: t s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-upserts2) s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-upserts2) step s2_upsert_a_data: <... completed> -key |data ------+----------------- -key-a|val-a-s1-upserts2 +key |data |check_old_and_new +-----+-----------------+----------------- +key-a|val-a-s1-upserts2|t (1 row) step s2_c: COMMIT; @@ -1068,14 +1068,14 @@ step s2_upsert_a_data: WHERE noisy_oper('upd', trigtest.key, '=', 'key-a') AND noisy_oper('upk', trigtest.data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-upserts2' AS check_old_and_new; step s1_r: ROLLBACK; s2: NOTICE: trigger: name rep_a_i; when: AFTER; lev: ROWs; op: INSERT; old: new: (key-a,val-a-upss2) step s2_upsert_a_data: <... completed> -key |data ------+----------- -key-a|val-a-upss2 +key |data |check_old_and_new +-----+-----------+----------------- +key-a|val-a-upss2| (1 row) step s2_c: COMMIT; @@ -1137,7 +1137,7 @@ step s2_upsert_a_data: WHERE noisy_oper('upd', trigtest.key, '=', 'key-a') AND noisy_oper('upk', trigtest.data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-upserts2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-a = text key-a: t @@ -1145,9 +1145,9 @@ s2: NOTICE: upk: text val-a-s1-ups1 <> text mismatch: t s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1-ups1) new: (key-a,val-a-s1-ups1-upserts2) s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1-ups1) new: (key-a,val-a-s1-ups1-upserts2) step s2_upsert_a_data: <... completed> -key |data ------+---------------------- -key-a|val-a-s1-ups1-upserts2 +key |data |check_old_and_new +-----+----------------------+----------------- +key-a|val-a-s1-ups1-upserts2|t (1 row) step s2_c: COMMIT; @@ -1209,14 +1209,14 @@ step s2_upsert_a_data: WHERE noisy_oper('upd', trigtest.key, '=', 'key-a') AND noisy_oper('upk', trigtest.data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-upserts2' AS check_old_and_new; step s1_r: ROLLBACK; s2: NOTICE: trigger: name rep_a_i; when: AFTER; lev: ROWs; op: INSERT; old: new: (key-a,val-a-upss2) step s2_upsert_a_data: <... completed> -key |data ------+----------- -key-a|val-a-upss2 +key |data |check_old_and_new +-----+-----------+----------------- +key-a|val-a-upss2| (1 row) step s2_c: COMMIT; @@ -1276,7 +1276,7 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-a = text key-a: t @@ -1284,9 +1284,9 @@ s2: NOTICE: upk: text val-a-s1-ups1 <> text mismatch: t s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1-ups1) new: (key-a,val-a-s1-ups1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------------ -key-a|val-a-s1-ups1-ups2 +key |data |check_old_and_new +-----+------------------+----------------- +key-a|val-a-s1-ups1-ups2|t (1 row) step s2_c: COMMIT; @@ -1347,15 +1347,15 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_r: ROLLBACK; s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------- -key-a|val-a-s1-ups2 +key |data |check_old_and_new +-----+-------------+----------------- +key-a|val-a-s1-ups2|t (1 row) step s2_c: COMMIT; @@ -1417,7 +1417,7 @@ step s2_del_a: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING * + RETURNING *, data = old.data AS check_old; step s1_c: COMMIT; s2: NOTICE: upd: text key-a = text key-a: t @@ -1425,9 +1425,9 @@ s2: NOTICE: upk: text val-a-s1-ups1 <> text mismatch: t s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_d; when: AFTER; lev: ROWs; op: DELETE; old: (key-a,val-a-s1-ups1) new: step s2_del_a: <... completed> -key |data ------+------------- -key-a|val-a-s1-ups1 +key |data |check_old +-----+-------------+--------- +key-a|val-a-s1-ups1|t (1 row) step s2_c: COMMIT; @@ -1488,15 +1488,15 @@ step s2_del_a: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING * + RETURNING *, data = old.data AS check_old; step s1_r: ROLLBACK; s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_d; when: AFTER; lev: ROWs; op: DELETE; old: (key-a,val-a-s1) new: step s2_del_a: <... completed> -key |data ------+-------- -key-a|val-a-s1 +key |data |check_old +-----+--------+--------- +key-a|val-a-s1|t (1 row) step s2_c: COMMIT; @@ -1557,13 +1557,13 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-b = text key-a: f step s2_upd_a_data: <... completed> -key|data ----+---- +key|data|check_old_and_new +---+----+----------------- (0 rows) step s2_c: COMMIT; @@ -1624,15 +1624,15 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_r: ROLLBACK; s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------- -key-a|val-a-s1-ups2 +key |data |check_old_and_new +-----+-------------+----------------- +key-a|val-a-s1-ups2|t (1 row) step s2_c: COMMIT; @@ -1693,13 +1693,13 @@ step s2_del_a: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING * + RETURNING *, data = old.data AS check_old; step s1_c: COMMIT; s2: NOTICE: upd: text key-b = text key-a: f step s2_del_a: <... completed> -key|data ----+---- +key|data|check_old +---+----+--------- (0 rows) step s2_c: COMMIT; @@ -1759,15 +1759,15 @@ step s2_del_a: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING * + RETURNING *, data = old.data AS check_old; step s1_r: ROLLBACK; s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_d; when: AFTER; lev: ROWs; op: DELETE; old: (key-a,val-a-s1) new: step s2_del_a: <... completed> -key |data ------+-------- -key-a|val-a-s1 +key |data |check_old +-----+--------+--------- +key-a|val-a-s1|t (1 row) step s2_c: COMMIT; @@ -1829,14 +1829,14 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: upd: text key-c = text key-a: f step s2_upd_a_data: <... completed> -key|data ----+---- +key|data|check_old_and_new +---+----+----------------- (0 rows) step s2_c: COMMIT; @@ -1899,16 +1899,16 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_r: ROLLBACK; s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) s2: NOTICE: upd: text key-c = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------- -key-a|val-a-s1-ups2 +key |data |check_old_and_new +-----+-------------+----------------- +key-a|val-a-s1-ups2|t (1 row) step s2_c: COMMIT; @@ -2038,7 +2038,7 @@ step s2_upd_all_data: WHERE noisy_oper('upd', key, '<>', 'mismatch') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-b <> text mismatch: t @@ -2050,10 +2050,10 @@ s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (k s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-b,val-a-s1-tobs1) new: (key-b,val-a-s1-tobs1-ups2) s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-c,val-c-s1) new: (key-c,val-c-s1-ups2) step s2_upd_all_data: <... completed> -key |data ------+------------------- -key-b|val-a-s1-tobs1-ups2 -key-c|val-c-s1-ups2 +key |data |check_old_and_new +-----+-------------------+----------------- +key-b|val-a-s1-tobs1-ups2|t +key-c|val-c-s1-ups2 |t (2 rows) step s2_c: COMMIT; @@ -2118,13 +2118,13 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_c: COMMIT; s2: NOTICE: upd: text key-c = text key-a: f step s2_upd_a_data: <... completed> -key|data ----+---- +key|data|check_old_and_new +---+----+----------------- (0 rows) step s2_c: COMMIT; @@ -2188,16 +2188,16 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_r: ROLLBACK; s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) s2: NOTICE: upd: text key-c = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------- -key-a|val-a-s1-ups2 +key |data |check_old_and_new +-----+-------------+----------------- +key-a|val-a-s1-ups2|t (1 row) step s2_c: COMMIT; @@ -2260,13 +2260,13 @@ step s2_del_a: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING * + RETURNING *, data = old.data AS check_old; step s1_c: COMMIT; s2: NOTICE: upd: text key-c = text key-a: f step s2_del_a: <... completed> -key|data ----+---- +key|data|check_old +---+----+--------- (0 rows) step s2_c: COMMIT; @@ -2328,16 +2328,16 @@ step s2_del_a: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING * + RETURNING *, data = old.data AS check_old; step s1_r: ROLLBACK; s2: NOTICE: trigger: name rep_b_d; when: BEFORE; lev: ROWs; op: DELETE; old: (key-a,val-a-s1) new: s2: NOTICE: upd: text key-c = text key-a: f s2: NOTICE: trigger: name rep_a_d; when: AFTER; lev: ROWs; op: DELETE; old: (key-a,val-a-s1) new: step s2_del_a: <... completed> -key |data ------+-------- -key-a|val-a-s1 +key |data |check_old +-----+--------+--------- +key-a|val-a-s1|t (1 row) step s2_c: COMMIT; @@ -2507,7 +2507,7 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_c: COMMIT; step s2_upd_a_data: <... completed> @@ -2572,16 +2572,16 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_r: ROLLBACK; s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------- -key-a|val-a-s1-ups2 +key |data |check_old_and_new +-----+-------------+----------------- +key-a|val-a-s1-ups2|t (1 row) step s2_c: COMMIT; @@ -2646,7 +2646,7 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_c: COMMIT; step s2_upd_a_data: <... completed> @@ -2712,16 +2712,16 @@ step s2_upd_a_data: WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; step s1_r: ROLLBACK; s2: NOTICE: trigger: name rep_b_u; when: BEFORE; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) s2: NOTICE: upd: text key-b = text key-a: f s2: NOTICE: trigger: name rep_a_u; when: AFTER; lev: ROWs; op: UPDATE; old: (key-a,val-a-s1) new: (key-a,val-a-s1-ups2) step s2_upd_a_data: <... completed> -key |data ------+------------- -key-a|val-a-s1-ups2 +key |data |check_old_and_new +-----+-------------+----------------- +key-a|val-a-s1-ups2|t (1 row) step s2_c: COMMIT; diff --git a/src/test/isolation/expected/merge-match-recheck.out b/src/test/isolation/expected/merge-match-recheck.out index 4250b85af2d..10ef2ad2fcd 100644 --- a/src/test/isolation/expected/merge-match-recheck.out +++ b/src/test/isolation/expected/merge-match-recheck.out @@ -197,15 +197,23 @@ step merge_bal: MERGE INTO target t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN - UPDATE SET balance = balance * 8, val = t.val || ' when3'; + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val; step c2: COMMIT; step merge_bal: <... completed> +key|old_balance|new_balance|status|val +---+-----------+-----------+------+---------------------------------- + 1| 50| 100|s1 |setup updated by update_bal1 when1 +(1 row) + step select1: SELECT * FROM target; key|balance|status|val ---+-------+------+---------------------------------- @@ -220,15 +228,23 @@ step merge_bal_pa: MERGE INTO target_pa t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN - UPDATE SET balance = balance * 8, val = t.val || ' when3'; + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val; step c2: COMMIT; step merge_bal_pa: <... completed> +key|old_balance|new_balance|status|val +---+-----------+-----------+------+------------------------------------- + 1| 50| 100|s1 |setup updated by update_bal1_pa when1 +(1 row) + step select1_pa: SELECT * FROM target_pa; key|balance|status|val ---+-------+------+------------------------------------- @@ -245,22 +261,24 @@ step merge_bal_tg: MERGE INTO target_tg t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN UPDATE SET balance = balance * 8, val = t.val || ' when3' - RETURNING t.* + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val ) SELECT * FROM t; step c2: COMMIT; s1: NOTICE: Update: (1,50,s1,"setup updated by update_bal1_tg") -> (1,100,s1,"setup updated by update_bal1_tg when1") step merge_bal_tg: <... completed> -key|balance|status|val ----+-------+------+------------------------------------- - 1| 100|s1 |setup updated by update_bal1_tg when1 +key|old_balance|new_balance|status|val +---+-----------+-----------+------+------------------------------------- + 1| 50| 100|s1 |setup updated by update_bal1_tg when1 (1 row) step select1_tg: SELECT * FROM target_tg; @@ -278,15 +296,23 @@ step merge_bal: MERGE INTO target t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN - UPDATE SET balance = balance * 8, val = t.val || ' when3'; + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val; step c2: COMMIT; step merge_bal: <... completed> +key|old_balance|new_balance|status|val +---+-----------+-----------+------+------------------------------------------------- + 1| 70| 140|s1 |setup updated by update1 updated by update6 when1 +(1 row) + step select1: SELECT * FROM target; key|balance|status|val ---+-------+------+------------------------------------------------- @@ -302,15 +328,23 @@ step merge_bal_pa: MERGE INTO target_pa t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN - UPDATE SET balance = balance * 8, val = t.val || ' when3'; + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val; step c2: COMMIT; step merge_bal_pa: <... completed> +key|old_balance|new_balance|status|val +---+-----------+-----------+------+------------------------------------------------------- + 1| 70| 140|s1 |setup updated by update1_pa updated by update6_pa when1 +(1 row) + step select1_pa: SELECT * FROM target_pa; key|balance|status|val ---+-------+------+------------------------------------------------------- @@ -329,22 +363,24 @@ step merge_bal_tg: MERGE INTO target_tg t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN UPDATE SET balance = balance * 8, val = t.val || ' when3' - RETURNING t.* + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val ) SELECT * FROM t; step c2: COMMIT; s1: NOTICE: Update: (1,70,s1,"setup updated by update1_tg updated by update6_tg") -> (1,140,s1,"setup updated by update1_tg updated by update6_tg when1") step merge_bal_tg: <... completed> -key|balance|status|val ----+-------+------+------------------------------------------------------- - 1| 140|s1 |setup updated by update1_tg updated by update6_tg when1 +key|old_balance|new_balance|status|val +---+-----------+-----------+------+------------------------------------------------------- + 1| 70| 140|s1 |setup updated by update1_tg updated by update6_tg when1 (1 row) step select1_tg: SELECT * FROM target_tg; @@ -355,6 +391,105 @@ key|balance|status|val step c1: COMMIT; +starting permutation: update6 update6 merge_bal c2 select1 c1 +step update6: UPDATE target t SET balance = balance - 100, val = t.val || ' updated by update6' WHERE t.key = 1; +step update6: UPDATE target t SET balance = balance - 100, val = t.val || ' updated by update6' WHERE t.key = 1; +step merge_bal: + MERGE INTO target t + USING (SELECT 1 as key) s + ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE + WHEN MATCHED AND balance < 100 THEN + UPDATE SET balance = balance * 2, val = t.val || ' when1' + WHEN MATCHED AND balance < 200 THEN + UPDATE SET balance = balance * 4, val = t.val || ' when2' + WHEN MATCHED AND balance < 300 THEN + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val; + +step c2: COMMIT; +step merge_bal: <... completed> +key|old_balance|new_balance|status|val +---+-----------+-----------+------+------------------------------------------- + 1| -40| |s1 |setup updated by update6 updated by update6 +(1 row) + +step select1: SELECT * FROM target; +key|balance|status|val +---+-------+------+--- +(0 rows) + +step c1: COMMIT; + +starting permutation: update6_pa update6_pa merge_bal_pa c2 select1_pa c1 +step update6_pa: UPDATE target_pa t SET balance = balance - 100, val = t.val || ' updated by update6_pa' WHERE t.key = 1; +step update6_pa: UPDATE target_pa t SET balance = balance - 100, val = t.val || ' updated by update6_pa' WHERE t.key = 1; +step merge_bal_pa: + MERGE INTO target_pa t + USING (SELECT 1 as key) s + ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE + WHEN MATCHED AND balance < 100 THEN + UPDATE SET balance = balance * 2, val = t.val || ' when1' + WHEN MATCHED AND balance < 200 THEN + UPDATE SET balance = balance * 4, val = t.val || ' when2' + WHEN MATCHED AND balance < 300 THEN + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val; + +step c2: COMMIT; +step merge_bal_pa: <... completed> +key|old_balance|new_balance|status|val +---+-----------+-----------+------+------------------------------------------------- + 1| -40| |s1 |setup updated by update6_pa updated by update6_pa +(1 row) + +step select1_pa: SELECT * FROM target_pa; +key|balance|status|val +---+-------+------+--- +(0 rows) + +step c1: COMMIT; + +starting permutation: update6_tg update6_tg merge_bal_tg c2 select1_tg c1 +s2: NOTICE: Update: (1,160,s1,setup) -> (1,60,s1,"setup updated by update6_tg") +step update6_tg: UPDATE target_tg t SET balance = balance - 100, val = t.val || ' updated by update6_tg' WHERE t.key = 1; +s2: NOTICE: Update: (1,60,s1,"setup updated by update6_tg") -> (1,-40,s1,"setup updated by update6_tg updated by update6_tg") +step update6_tg: UPDATE target_tg t SET balance = balance - 100, val = t.val || ' updated by update6_tg' WHERE t.key = 1; +step merge_bal_tg: + WITH t AS ( + MERGE INTO target_tg t + USING (SELECT 1 as key) s + ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE + WHEN MATCHED AND balance < 100 THEN + UPDATE SET balance = balance * 2, val = t.val || ' when1' + WHEN MATCHED AND balance < 200 THEN + UPDATE SET balance = balance * 4, val = t.val || ' when2' + WHEN MATCHED AND balance < 300 THEN + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val + ) + SELECT * FROM t; + +step c2: COMMIT; +s1: NOTICE: Delete: (1,-40,s1,"setup updated by update6_tg updated by update6_tg") +step merge_bal_tg: <... completed> +key|old_balance|new_balance|status|val +---+-----------+-----------+------+------------------------------------------------- + 1| -40| |s1 |setup updated by update6_tg updated by update6_tg +(1 row) + +step select1_tg: SELECT * FROM target_tg; +key|balance|status|val +---+-------+------+--- +(0 rows) + +step c1: COMMIT; + starting permutation: update7 update6 merge_bal c2 select1 c1 step update7: UPDATE target t SET balance = 350, val = t.val || ' updated by update7' WHERE t.key = 1; step update6: UPDATE target t SET balance = balance - 100, val = t.val || ' updated by update6' WHERE t.key = 1; @@ -362,15 +497,23 @@ step merge_bal: MERGE INTO target t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN - UPDATE SET balance = balance * 8, val = t.val || ' when3'; + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val; step c2: COMMIT; step merge_bal: <... completed> +key|old_balance|new_balance|status|val +---+-----------+-----------+------+------------------------------------------------- + 1| 250| 2000|s1 |setup updated by update7 updated by update6 when3 +(1 row) + step select1: SELECT * FROM target; key|balance|status|val ---+-------+------+------------------------------------------------- @@ -385,12 +528,15 @@ step merge_bal_pa: MERGE INTO target_pa t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN - UPDATE SET balance = balance * 8, val = t.val || ' when3'; + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val; step c2: COMMIT; step merge_bal_pa: <... completed> @@ -404,12 +550,15 @@ step merge_bal_pa: MERGE INTO target_pa t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN - UPDATE SET balance = balance * 8, val = t.val || ' when3'; + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val; step c2: COMMIT; step merge_bal_pa: <... completed> diff --git a/src/test/isolation/specs/eval-plan-qual-trigger.spec b/src/test/isolation/specs/eval-plan-qual-trigger.spec index 232b3e27652..575fbe010e6 100644 --- a/src/test/isolation/specs/eval-plan-qual-trigger.spec +++ b/src/test/isolation/specs/eval-plan-qual-trigger.spec @@ -120,14 +120,14 @@ step s2_del_a { WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING * + RETURNING *, data = old.data AS check_old; } step s2_upd_a_data { UPDATE trigtest SET data = data || '-ups2' WHERE noisy_oper('upd', key, '=', 'key-a') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; } step s2_upd_b_data { UPDATE trigtest SET data = data || '-ups2' @@ -141,7 +141,7 @@ step s2_upd_all_data { WHERE noisy_oper('upd', key, '<>', 'mismatch') AND noisy_oper('upk', data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-ups2' AS check_old_and_new; } step s2_upsert_a_data { INSERT INTO trigtest VALUES ('key-a', 'val-a-upss2') @@ -150,7 +150,7 @@ step s2_upsert_a_data { WHERE noisy_oper('upd', trigtest.key, '=', 'key-a') AND noisy_oper('upk', trigtest.data, '<>', 'mismatch') - RETURNING *; + RETURNING *, new.data = old.data || '-upserts2' AS check_old_and_new; } session s3 diff --git a/src/test/isolation/specs/merge-match-recheck.spec b/src/test/isolation/specs/merge-match-recheck.spec index 6e7a776d17e..6054fcade26 100644 --- a/src/test/isolation/specs/merge-match-recheck.spec +++ b/src/test/isolation/specs/merge-match-recheck.spec @@ -10,7 +10,7 @@ setup INSERT INTO target VALUES (1, 160, 's1', 'setup'); CREATE TABLE target_pa (key int, balance integer, status text, val text) PARTITION BY RANGE (balance); - CREATE TABLE target_pa1 PARTITION OF target_pa FOR VALUES FROM (0) TO (200); + CREATE TABLE target_pa1 PARTITION OF target_pa FOR VALUES FROM (-100) TO (200); CREATE TABLE target_pa2 PARTITION OF target_pa FOR VALUES FROM (200) TO (1000); INSERT INTO target_pa VALUES (1, 160, 's1', 'setup'); @@ -78,24 +78,30 @@ step "merge_bal" MERGE INTO target t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN - UPDATE SET balance = balance * 8, val = t.val || ' when3'; + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val; } step "merge_bal_pa" { MERGE INTO target_pa t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN - UPDATE SET balance = balance * 8, val = t.val || ' when3'; + UPDATE SET balance = balance * 8, val = t.val || ' when3' + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val; } step "merge_bal_tg" { @@ -103,13 +109,15 @@ step "merge_bal_tg" MERGE INTO target_tg t USING (SELECT 1 as key) s ON s.key = t.key + WHEN MATCHED AND balance < 0 THEN + DELETE WHEN MATCHED AND balance < 100 THEN UPDATE SET balance = balance * 2, val = t.val || ' when1' WHEN MATCHED AND balance < 200 THEN UPDATE SET balance = balance * 4, val = t.val || ' when2' WHEN MATCHED AND balance < 300 THEN UPDATE SET balance = balance * 8, val = t.val || ' when3' - RETURNING t.* + RETURNING t.key, old.balance AS old_balance, new.balance AS new_balance, t.status, t.val ) SELECT * FROM t; } @@ -190,6 +198,11 @@ permutation "update1" "update6" "merge_bal" "c2" "select1" "c1" permutation "update1_pa" "update6_pa" "merge_bal_pa" "c2" "select1_pa" "c1" permutation "update1_tg" "update6_tg" "merge_bal_tg" "c2" "select1_tg" "c1" +# merge_bal sees row concurrently updated twice and rechecks WHEN conditions, different check passes, and row is deleted +permutation "update6" "update6" "merge_bal" "c2" "select1" "c1" +permutation "update6_pa" "update6_pa" "merge_bal_pa" "c2" "select1_pa" "c1" +permutation "update6_tg" "update6_tg" "merge_bal_tg" "c2" "select1_tg" "c1" + # merge_bal sees row concurrently updated twice, first update would cause all checks to fail, second update causes different check to pass, so final balance = 2000 permutation "update7" "update6" "merge_bal" "c2" "select1" "c1" From 6120d01c9f5c985c5154d226181295137e57c552 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Thu, 9 Jul 2026 02:17:08 +0300 Subject: [PATCH 127/481] Don't create SPLIT/MERGE partitions as internal relations The new partitions built for ALTER TABLE ... SPLIT PARTITION and ALTER TABLE ... MERGE PARTITIONS are created at the explicit request of the user, just like a plain CREATE TABLE. createPartitionTable() passes is_internal=true to heap_create_with_catalog(), while createTableConstraints() does the same to StoreAttrDefault() and AddRelationNewConstraints(). Pass is_internal=false in all these places instead, so that object-access hooks treat them as user-requested objects. The is_internal flag is intended for objects created as internal implementation details, such as a transient heap built during CLUSTER. While at it, pass 0 rather than PERFORM_DELETION_INTERNAL to the performDeletionCheck() calls that pre-check the drop eligibility of the old partitions, to match the subsequent performDeletion(). The flag has no functional effect on performDeletionCheck(), but change this for code consistency. Reported-by: Noah Misch Discussion: https://postgr.es/m/20260707185751.f9.noahmisch@microsoft.com Backpatch-through: 19 --- src/backend/commands/tablecmds.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 44bb18d34a0..de1afb60bbc 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -22978,7 +22978,7 @@ createTableConstraints(List **wqueue, AlteredTableInfo *tab, elog(ERROR, "cannot convert whole-row table reference"); /* Add a pre-cooked default expression. */ - StoreAttrDefault(newRel, num, def, true); + StoreAttrDefault(newRel, num, def, false); /* * Stored generated column expressions in parent_rel might @@ -23046,7 +23046,7 @@ createTableConstraints(List **wqueue, AlteredTableInfo *tab, /* Install all CHECK constraints. */ cookedConstraints = AddRelationNewConstraints(newRel, NIL, constraints, - false, true, true, NULL); + false, true, false, NULL); /* Make the additional catalog changes visible. */ CommandCounterIncrement(); @@ -23108,7 +23108,7 @@ createTableConstraints(List **wqueue, AlteredTableInfo *tab, * We already set pg_attribute.attnotnull in createPartitionTable. No * need call set_attnotnull again. */ - AddRelationNewConstraints(newRel, NIL, nnconstraints, false, true, true, NULL); + AddRelationNewConstraints(newRel, NIL, nnconstraints, false, true, false, NULL); } } @@ -23228,7 +23228,7 @@ createPartitionTable(List **wqueue, RangeVar *newPartName, (Datum) 0, true, allowSystemTableMods, - true, + false, /* is_internal */ InvalidOid, NULL); @@ -23800,7 +23800,7 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel, object.classId = RelationRelationId; object.objectSubId = 0; - performDeletionCheck(&object, DROP_RESTRICT, PERFORM_DELETION_INTERNAL); + performDeletionCheck(&object, DROP_RESTRICT, 0); } /* @@ -24214,7 +24214,7 @@ ATExecSplitPartition(List **wqueue, AlteredTableInfo *tab, Relation rel, object.objectId = splitRelOid; object.classId = RelationRelationId; object.objectSubId = 0; - performDeletionCheck(&object, DROP_RESTRICT, PERFORM_DELETION_INTERNAL); + performDeletionCheck(&object, DROP_RESTRICT, 0); /* * If a new partition has the same name as the split partition, then we From dff11f846c4bd044e51ca944f2f3e089be0462ac Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Thu, 9 Jul 2026 09:12:13 +0900 Subject: [PATCH 128/481] doc: Fix data checksum progress reporting documentation Add pg_stat_progress_data_checksums to the progress reporting summary and the list of commands with progress reporting. Also clarify that the view reports both enabling and disabling data checksums, and correct the documented types of its progress counters to bigint. Author: Fujii Masao Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CAHGQGwHJHJYAkYZBi3_O13np-Rou9UL637=hB3Y_-qdCgcZn-w@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/monitoring.sgml | 39 +++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 38836f2c90f..aa196754cb2 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -435,6 +435,16 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser See . + + + pg_stat_progress_data_checksumspg_stat_progress_data_checksums + One row for the data checksum launcher process while data + checksums are being enabled or disabled. When enabling data + checksums, the view also has one row for each worker process, + showing current progress. + See . + +
    @@ -6121,9 +6131,9 @@ FROM pg_stat_get_backend_idset() AS backendid; COPY, CREATE INDEX, REPACK (and its obsolete spelling CLUSTER), VACUUM, - and (i.e., replication + (i.e., replication command that issues to take - a base backup). + a base backup), and online data checksum operations. This may be expanded in the future.
    @@ -7855,13 +7865,14 @@ FROM pg_stat_get_backend_idset() AS backendid; - When data checksums are being enabled on a running cluster, the + When data checksums are being enabled or disabled on a running cluster, the pg_stat_progress_data_checksums view will contain - a row for the launcher process, and one row for each worker process which - is currently calculating and writing checksums for the data pages in a database. - The launcher provides overview of the overall progress (how many databases - have been processed, how many remain), while the workers track progress for - currently processed databases. + a row for the launcher process. When enabling data checksums, the view + will also contain one row for each worker process which is currently + calculating and writing checksums for the data pages in a database. The + launcher provides an overview of the overall progress, such as how many + databases have been processed and how many remain, while the workers track + progress for currently processed databases. @@ -7930,7 +7941,7 @@ FROM pg_stat_get_backend_idset() AS backendid; - databases_total integer + databases_total bigint The total number of databases which will be processed. Only the @@ -7943,7 +7954,7 @@ FROM pg_stat_get_backend_idset() AS backendid; - databases_done integer + databases_done bigint The number of databases which have been processed. Only the launcher @@ -7956,7 +7967,7 @@ FROM pg_stat_get_backend_idset() AS backendid; - relations_total integer + relations_total bigint The total number of relations which will be processed, or @@ -7971,7 +7982,7 @@ FROM pg_stat_get_backend_idset() AS backendid; - relations_done integer + relations_done bigint The number of relations which have been processed. The launcher @@ -7983,7 +7994,7 @@ FROM pg_stat_get_backend_idset() AS backendid; - blocks_total integer + blocks_total bigint The number of blocks in the current relation which will be processed, @@ -7997,7 +8008,7 @@ FROM pg_stat_get_backend_idset() AS backendid; - blocks_done integer + blocks_done bigint The number of blocks in the current relation which have been processed. From 19fbb47ef6854b1e3a7311ed2f4e765426e7a611 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Thu, 9 Jul 2026 08:01:38 +0530 Subject: [PATCH 129/481] Doc: Clarify sequence synchronization commands. Explain more accurately how REFRESH SEQUENCES differs from REFRESH PUBLICATION in ALTER SUBSCRIPTION, and note that CREATE SUBSCRIPTION uses copy_data = true (the default) to copy initial sequence values. Author: Peter Smith Author: Amit Kapila Backpatch-through: 19 Discussion: https://postgr.es/m/CAHut+PtFkGvZNihGRDoghWNKMfJufEpR9+thbG_8qPQ7RyVN4w@mail.gmail.com --- doc/src/sgml/logical-replication.sgml | 4 +++- doc/src/sgml/ref/alter_subscription.sgml | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index d7d75b7c9a5..2edf65af66e 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -1769,7 +1769,9 @@ Included in publications: use CREATE SUBSCRIPTION - to initially synchronize the published sequences. + with + copy_data = true (the default) to copy the + initial sequence values from the publisher. diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml index e4f0b6b16c7..51081ef369e 100644 --- a/doc/src/sgml/ref/alter_subscription.sgml +++ b/doc/src/sgml/ref/alter_subscription.sgml @@ -237,11 +237,13 @@ ALTER SUBSCRIPTION name RENAME TO < Re-synchronize sequence data with the publisher. Unlike - ALTER SUBSCRIPTION ... REFRESH PUBLICATION which - only has the ability to synchronize newly added sequences, + ALTER SUBSCRIPTION ... REFRESH PUBLICATION, + which synchronizes the subscription's set of sequences with the + publication (adding new and removing dropped sequences), REFRESH SEQUENCES will re-synchronize the sequence - data for all currently subscribed sequences. It does not add or remove - sequences from the subscription to match the publication. + data for all currently subscribed sequences without changing which + sequences are subscribed. Run REFRESH PUBLICATION + first if the publication's set of sequences has changed. See for From 0b1dbb74478051205c2befc90bac9d9f55524104 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 9 Jul 2026 09:53:18 +0200 Subject: [PATCH 130/481] Fix outdated comment In transformLockingClause(), there was a comment that listed all the RTE kinds it did not want to process, but that list was already outdated about what RTE kinds actually exist. Rather than keeping that up-to-date, just say "all other". Discussion: https://www.postgresql.org/message-id/flat/CAHg%2BQDcE9wp6nOEC3SCRQ90nrCO%3DQF%2BOZq1MG8Qc6hnusmogqw%40mail.gmail.com --- src/backend/parser/analyze.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 2932d17a107..739ea13d5db 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -3867,7 +3867,7 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, allrels, true); break; default: - /* ignore JOIN, SPECIAL, FUNCTION, VALUES, CTE RTEs */ + /* ignore all other RTE kinds */ break; } } From 01c544e1afb99bc2a76803870010b7cd2907f3b5 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 9 Jul 2026 10:10:07 +0200 Subject: [PATCH 131/481] Prohibit locking clauses on GRAPH_TABLE Specifying a locking clause (FOR UPDATE/SHARE) that names a GRAPH_TABLE alias currently results in an unhelpful "unrecognized RTE type: 8" error. This commit explicitly prohibits specifying a locking clause on a GRAPH_TABLE alias, raising a more user-friendly error instead. (Locking clause support for GRAPH_TABLE could be added as a separate feature in the future.) Author: SATYANARAYANA NARLAPURAM Author: Ayush Tiwari Reviewed-by: Ashutosh Bapat Discussion: https://www.postgresql.org/message-id/flat/CAHg%2BQDcE9wp6nOEC3SCRQ90nrCO%3DQF%2BOZq1MG8Qc6hnusmogqw%40mail.gmail.com --- src/backend/parser/analyze.c | 9 +++++++++ src/test/regress/expected/graph_table.out | 13 +++++++++++++ src/test/regress/sql/graph_table.sql | 4 ++++ 3 files changed, 26 insertions(+) diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 739ea13d5db..ea97d236ea8 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -4002,6 +4002,15 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, LCS_asString(lc->strength)), parser_errposition(pstate, thisrel->location))); break; + case RTE_GRAPH_TABLE: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + /*------ + translator: %s is a SQL row locking clause such as FOR UPDATE */ + errmsg("%s cannot be applied to GRAPH_TABLE", + LCS_asString(lc->strength)), + parser_errposition(pstate, thisrel->location))); + break; /* Shouldn't be possible to see RTE_RESULT here */ diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out index a3d78a7ac43..46566b2e32f 100644 --- a/src/test/regress/expected/graph_table.out +++ b/src/test/regress/expected/graph_table.out @@ -1106,4 +1106,17 @@ SELECT src.vname, count(*) FROM v1 AS src v13 | 1 (3 rows) +-- Locking clause on GRAPH_TABLE +SELECT * FROM GRAPH_TABLE (g1 MATCH (src IS vl1) COLUMNS (src.vname)) gt FOR UPDATE OF gt; -- not supported +ERROR: FOR UPDATE cannot be applied to GRAPH_TABLE +LINE 1: ...MATCH (src IS vl1) COLUMNS (src.vname)) gt FOR UPDATE OF gt; + ^ +SELECT * FROM GRAPH_TABLE (g1 MATCH (src IS vl1) COLUMNS (src.vname)) gt FOR UPDATE; -- ignored + vname +------- + v11 + v12 + v13 +(3 rows) + -- leave the objects behind for pg_upgrade/pg_dump tests diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql index 6aacc2d4aa5..3fb0e50ddb2 100644 --- a/src/test/regress/sql/graph_table.sql +++ b/src/test/regress/sql/graph_table.sql @@ -619,4 +619,8 @@ SELECT src.vname, count(*) FROM v1 AS src HAVING count(*) >= (SELECT count(*) FROM GRAPH_TABLE (g1 MATCH (a IS vl1 | vl2) COLUMNS (a.vname AS n)) WHERE n = src.vname) ORDER BY vname; +-- Locking clause on GRAPH_TABLE +SELECT * FROM GRAPH_TABLE (g1 MATCH (src IS vl1) COLUMNS (src.vname)) gt FOR UPDATE OF gt; -- not supported +SELECT * FROM GRAPH_TABLE (g1 MATCH (src IS vl1) COLUMNS (src.vname)) gt FOR UPDATE; -- ignored + -- leave the objects behind for pg_upgrade/pg_dump tests From 536512f34e7a6156188f6ba5c834ab01c911c5ae Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 9 Jul 2026 18:34:24 +0300 Subject: [PATCH 132/481] ssl: Include limits.h to get INT_MAX when using LibreSSL When compiling against OpenSSL, the header is indirectly included via openssl/ossl_typ.h from openssl/conf.h, but the LibreSSL version of ossl_typ.h does not include which cause compiler failure due to missing symbol (since ffd080d94fe). Fix by explicitly including . Author: Daniel Gustafsson Discussion: https://www.postgresql.org/message-id/6A9E7815-BD5A-4C31-A515-48159823406B@yesql.se Backpatch-through: 14 --- src/interfaces/libpq/fe-secure-openssl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index f8b2184a1ce..c7651c98ab5 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "libpq-fe.h" #include "fe-auth.h" From d9eb70c9c692475174289d9bdc5c76734abbfa0c Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 9 Jul 2026 18:34:27 +0300 Subject: [PATCH 133/481] libpq: Make error checks in the new buffer draining code more robust Check explicitly for pqsecure_read() returning an error. It shouldn't fail, and we would've caught it in the check for a short read, but better to be explicit so that the error message is more informative. We also shouldn't update 'inEnd' when the read fails, although that too is just pro forma as we will bail out and close the connection on error. Reported-by: Peter Eisentraut Discussion: https://www.postgresql.org/message-id/34844e8c-267c-4daf-b1e0-f26059a4a7d3@eisentraut.org Backpatch-through: 14 --- src/interfaces/libpq/fe-misc.c | 11 ++++++++--- src/interfaces/libpq/fe-secure.c | 5 +++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index dd772838005..f11b58bf9c7 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -928,13 +928,18 @@ pqDrainPending(PGconn *conn) nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd, bytes_pending); - conn->inEnd += nread; - /* When there are bytes pending, the read function is not supposed to fail */ + /* + * When there are bytes pending, pqsecure_read() is not supposed to fail + * or do a short read, but let's check anyway to be safe. + */ + if (nread < 0) + return -1; + conn->inEnd += nread; if (nread != bytes_pending) { libpq_append_conn_error(conn, - "drained only %zu of %zd pending bytes in transport buffer", + "drained only %zd of %zd pending bytes in transport buffer", nread, bytes_pending); return -1; } diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c index 70faf8b2fe0..1a8e2e6746e 100644 --- a/src/interfaces/libpq/fe-secure.c +++ b/src/interfaces/libpq/fe-secure.c @@ -247,8 +247,9 @@ pqsecure_raw_read(PGconn *conn, void *ptr, size_t len) * Return the number of bytes available in the transport buffer. * * If pqsecure_read() is called for this number of bytes, it's guaranteed to - * return successfully without reading from the underlying socket. See - * pqDrainPending() for a more complete discussion of the concepts involved. + * return successfully with the same number of bytes, without reading from the + * underlying socket. See pqDrainPending() for a more complete discussion of + * the concepts involved. */ ssize_t pqsecure_bytes_pending(PGconn *conn) From 3334b0d9f25a897b8298c849d08909bdc532874a Mon Sep 17 00:00:00 2001 From: Etsuro Fujita Date: Fri, 10 Jul 2026 13:20:00 +0900 Subject: [PATCH 134/481] postgres_fdw: Remove SPI from postgresImportForeignStatistics. Previously, this function imported remote statistics by executing SQL functions like pg_restore_relation_stats and pg_restore_attribute_stats via SPI (in read-write mode). As the SQL functions take a schema name and a relation name as two separate arguments, rather than a single OID argument, if the containing schema was concurrently renamed, the callback function would throw an error like this: ERROR: schema "foo" does not exist To fix, 1) provide new interface functions to import remote statistics that are directly callable from FDWs and take a single OID, and 2) modify the callback function to use the interface functions instead when importing remote statistics. For #1, this commit does a bit of refactoring to relation_statistics_update and attribute_statistics_update, which are the workhorse functions for pg_restore_relation_stats and pg_restore_attribute_stats respectively: since they also take a schema name and a relation name, separate the guts of them into new functions so that they take a single OID and are callable not only from the workhorse functions but from the interface functions introduced by #1. Oversight in commit 28972b6fc. Reported-by: Robert Haas Suggested-by: Robert Haas Author: Corey Huinker Co-authored-by: Etsuro Fujita Discussion: https://postgr.es/m/CA%2BTgmoYqMtWb4zLUkT98oFnEkJ%3DWz0Pw-ggDJrp9wnSXPzUaeQ%40mail.gmail.com Backpatch-through: 19 --- .../postgres_fdw/expected/postgres_fdw.out | 37 ++ contrib/postgres_fdw/postgres_fdw.c | 443 +++++++----------- contrib/postgres_fdw/sql/postgres_fdw.sql | 28 ++ doc/src/sgml/fdwhandler.sgml | 5 +- src/backend/statistics/attribute_stats.c | 174 +++++-- src/backend/statistics/relation_stats.c | 86 +++- src/include/statistics/statistics.h | 25 + 7 files changed, 484 insertions(+), 314 deletions(-) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 5ebae1cedc2..048f624ba0c 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -13067,6 +13067,43 @@ ANALYZE dtest_table; ANALYZE VERBOSE dtest_ftable; -- should work INFO: importing statistics for foreign table "public.dtest_ftable" INFO: finished importing statistics for foreign table "public.dtest_ftable" +-- dtest_ftable's stats should now exactly match dtest_table's +-- compare values, should match +SELECT relpages, reltuples FROM pg_class +WHERE oid = 'public.dtest_table'::regclass +EXCEPT +SELECT relpages, reltuples FROM pg_class +WHERE oid = 'public.dtest_ftable'::regclass; + relpages | reltuples +----------+----------- +(0 rows) + +-- compare the rowcounts, should get 0 rows back +SELECT COUNT(*) FROM pg_stats +WHERE schemaname = 'public' AND tablename = 'dtest_table' +EXCEPT +SELECT COUNT(*) FROM pg_stats +WHERE schemaname = 'public' AND tablename = 'dtest_ftable'; + count +------- +(0 rows) + +-- test only a few stats columns common to integer types +SELECT attname, inherited, null_frac, avg_width, n_distinct, + most_common_vals::text as mcv, most_common_freqs, + histogram_bounds::text as hb, correlation +FROM pg_stats +WHERE schemaname = 'public' AND tablename = 'dtest_table' +EXCEPT +SELECT attname, inherited, null_frac, avg_width, n_distinct, + most_common_vals::text as mcv, most_common_freqs, + histogram_bounds::text as hb, correlation +FROM pg_stats +WHERE schemaname = 'public' AND tablename = 'dtest_ftable'; + attname | inherited | null_frac | avg_width | n_distinct | mcv | most_common_freqs | hb | correlation +---------+-----------+-----------+-----------+------------+-----+-------------------+----+------------- +(0 rows) + -- cleanup DROP FOREIGN TABLE simport_ftable; DROP FOREIGN TABLE simport_fview; diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 12059ec8544..e6e0a4ab9b5 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -24,7 +24,6 @@ #include "commands/vacuum.h" #include "executor/execAsync.h" #include "executor/instrument.h" -#include "executor/spi.h" #include "foreign/fdwapi.h" #include "funcapi.h" #include "miscadmin.h" @@ -47,6 +46,7 @@ #include "storage/latch.h" #include "utils/builtins.h" #include "utils/float.h" +#include "utils/fmgroids.h" #include "utils/guc.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -337,9 +337,9 @@ typedef struct { PGresult *rel; PGresult *att; - int server_version_num; double livetuples; double deadtuples; + int version; } RemoteStatsResults; /* Column order in relation stats query */ @@ -371,136 +371,6 @@ enum AttStatsColumns ATTSTATS_NUM_FIELDS, }; -/* Relation stats import query */ -static const char *relimport_sql = -"SELECT pg_catalog.pg_restore_relation_stats(\n" -"\t'version', $1,\n" -"\t'schemaname', $2,\n" -"\t'relname', $3,\n" -"\t'relpages', $4::integer,\n" -"\t'reltuples', $5::real)"; - -/* Argument order in relation stats import query */ -enum RelImportSqlArgs -{ - RELIMPORT_SQL_VERSION = 0, - RELIMPORT_SQL_SCHEMANAME, - RELIMPORT_SQL_RELNAME, - RELIMPORT_SQL_RELPAGES, - RELIMPORT_SQL_RELTUPLES, - RELIMPORT_SQL_NUM_FIELDS -}; - -/* Argument types in relation stats import query */ -static const Oid relimport_argtypes[RELIMPORT_SQL_NUM_FIELDS] = -{ - INT4OID, TEXTOID, TEXTOID, TEXTOID, - TEXTOID, -}; - -/* Attribute stats import query */ -static const char *attimport_sql = -"SELECT pg_catalog.pg_restore_attribute_stats(\n" -"\t'version', $1,\n" -"\t'schemaname', $2,\n" -"\t'relname', $3,\n" -"\t'attnum', $4,\n" -"\t'inherited', false::boolean,\n" -"\t'null_frac', $5::real,\n" -"\t'avg_width', $6::integer,\n" -"\t'n_distinct', $7::real,\n" -"\t'most_common_vals', $8,\n" -"\t'most_common_freqs', $9::real[],\n" -"\t'histogram_bounds', $10,\n" -"\t'correlation', $11::real,\n" -"\t'most_common_elems', $12,\n" -"\t'most_common_elem_freqs', $13::real[],\n" -"\t'elem_count_histogram', $14::real[],\n" -"\t'range_length_histogram', $15,\n" -"\t'range_empty_frac', $16::real,\n" -"\t'range_bounds_histogram', $17)"; - -/* Argument order in attribute stats import query */ -enum AttImportSqlArgs -{ - ATTIMPORT_SQL_VERSION = 0, - ATTIMPORT_SQL_SCHEMANAME, - ATTIMPORT_SQL_RELNAME, - ATTIMPORT_SQL_ATTNUM, - ATTIMPORT_SQL_NULL_FRAC, - ATTIMPORT_SQL_AVG_WIDTH, - ATTIMPORT_SQL_N_DISTINCT, - ATTIMPORT_SQL_MOST_COMMON_VALS, - ATTIMPORT_SQL_MOST_COMMON_FREQS, - ATTIMPORT_SQL_HISTOGRAM_BOUNDS, - ATTIMPORT_SQL_CORRELATION, - ATTIMPORT_SQL_MOST_COMMON_ELEMS, - ATTIMPORT_SQL_MOST_COMMON_ELEM_FREQS, - ATTIMPORT_SQL_ELEM_COUNT_HISTOGRAM, - ATTIMPORT_SQL_RANGE_LENGTH_HISTOGRAM, - ATTIMPORT_SQL_RANGE_EMPTY_FRAC, - ATTIMPORT_SQL_RANGE_BOUNDS_HISTOGRAM, - ATTIMPORT_SQL_NUM_FIELDS -}; - -/* Argument types in attribute stats import query */ -static const Oid attimport_argtypes[ATTIMPORT_SQL_NUM_FIELDS] = -{ - INT4OID, TEXTOID, TEXTOID, INT2OID, - TEXTOID, TEXTOID, TEXTOID, TEXTOID, - TEXTOID, TEXTOID, TEXTOID, TEXTOID, - TEXTOID, TEXTOID, TEXTOID, TEXTOID, - TEXTOID, -}; - -/* - * The mapping of attribute stats query columns to the positional arguments in - * the prepared pg_restore_attribute_stats() statement. - */ -typedef struct -{ - enum AttStatsColumns res_field; - enum AttImportSqlArgs arg_num; -} AttrResultArgMap; - -#define NUM_MAPPED_ATTIMPORT_ARGS 13 - -static const AttrResultArgMap attr_result_arg_map[NUM_MAPPED_ATTIMPORT_ARGS] = -{ - {ATTSTATS_NULL_FRAC, ATTIMPORT_SQL_NULL_FRAC}, - {ATTSTATS_AVG_WIDTH, ATTIMPORT_SQL_AVG_WIDTH}, - {ATTSTATS_N_DISTINCT, ATTIMPORT_SQL_N_DISTINCT}, - {ATTSTATS_MOST_COMMON_VALS, ATTIMPORT_SQL_MOST_COMMON_VALS}, - {ATTSTATS_MOST_COMMON_FREQS, ATTIMPORT_SQL_MOST_COMMON_FREQS}, - {ATTSTATS_HISTOGRAM_BOUNDS, ATTIMPORT_SQL_HISTOGRAM_BOUNDS}, - {ATTSTATS_CORRELATION, ATTIMPORT_SQL_CORRELATION}, - {ATTSTATS_MOST_COMMON_ELEMS, ATTIMPORT_SQL_MOST_COMMON_ELEMS}, - {ATTSTATS_MOST_COMMON_ELEM_FREQS, ATTIMPORT_SQL_MOST_COMMON_ELEM_FREQS}, - {ATTSTATS_ELEM_COUNT_HISTOGRAM, ATTIMPORT_SQL_ELEM_COUNT_HISTOGRAM}, - {ATTSTATS_RANGE_LENGTH_HISTOGRAM, ATTIMPORT_SQL_RANGE_LENGTH_HISTOGRAM}, - {ATTSTATS_RANGE_EMPTY_FRAC, ATTIMPORT_SQL_RANGE_EMPTY_FRAC}, - {ATTSTATS_RANGE_BOUNDS_HISTOGRAM, ATTIMPORT_SQL_RANGE_BOUNDS_HISTOGRAM}, -}; - -/* Attribute stats clear query */ -static const char *attclear_sql = -"SELECT pg_catalog.pg_clear_attribute_stats($1, $2, $3, false)"; - -/* Argument order in attribute stats clear query */ -enum AttClearSqlArgs -{ - ATTCLEAR_SQL_SCHEMANAME = 0, - ATTCLEAR_SQL_RELNAME, - ATTCLEAR_SQL_ATTNAME, - ATTCLEAR_SQL_NUM_FIELDS -}; - -/* Argument types in attribute stats clear query */ -static const Oid attclear_argtypes[ATTCLEAR_SQL_NUM_FIELDS] = -{ - TEXTOID, TEXTOID, TEXTOID, -}; - /* * SQL functions */ @@ -718,14 +588,18 @@ static bool match_attrmap(PGresult *res, const char *remote_relname, int attrcnt, RemoteAttributeMapping *remattrmap); -static bool import_fetched_statistics(const char *schemaname, +static bool import_fetched_statistics(Relation relation, + const char *schemaname, const char *relname, int attrcnt, const RemoteAttributeMapping *remattrmap, RemoteStatsResults *remstats); -static void map_field_to_arg(PGresult *res, int row, int field, - int arg, Datum *values, char *nulls); -static bool import_spi_query_ok(void); +static char *get_opt_value(PGresult *res, int row, int col); +static void set_text_arg(NullableDatum *arg, const char *s); +static void set_int32_arg(NullableDatum *arg, const char *s); +static void set_uint32_arg(NullableDatum *arg, const char *s); +static void set_float_arg(NullableDatum *arg, const char *s); +static void set_floatarr_arg(NullableDatum *arg, const char *s); static void produce_tuple_asynchronously(AsyncRequest *areq, bool fetch); static void fetch_more_data_begin(AsyncRequest *areq); static void complete_pending_request(AsyncRequest *areq); @@ -5668,7 +5542,7 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel) &attrcnt, &remattrmap, &remstats); if (ok) - ok = import_fetched_statistics(schemaname, relname, + ok = import_fetched_statistics(relation, schemaname, relname, attrcnt, remattrmap, &remstats); if (ok) @@ -5738,7 +5612,7 @@ fetch_remote_statistics(Relation relation, */ user = GetUserMapping(GetUserId(), table->serverid); conn = GetConnection(user, false, NULL); - remstats->server_version_num = server_version_num = PQserverVersion(conn); + remstats->version = server_version_num = PQserverVersion(conn); /* Fetch relation stats. */ remstats->rel = relstats = fetch_relstats(conn, relation); @@ -6144,191 +6018,232 @@ match_attrmap(PGresult *res, * Import fetched statistics into the local statistics tables. */ static bool -import_fetched_statistics(const char *schemaname, +import_fetched_statistics(Relation relation, + const char *schemaname, const char *relname, int attrcnt, const RemoteAttributeMapping *remattrmap, RemoteStatsResults *remstats) { - SPIPlanPtr attimport_plan = NULL; - SPIPlanPtr attclear_plan = NULL; - Datum values[ATTIMPORT_SQL_NUM_FIELDS]; - char nulls[ATTIMPORT_SQL_NUM_FIELDS]; - int spirc; - bool ok = false; - - /* Assign all the invariant parameters common to relation/attribute stats */ - values[ATTIMPORT_SQL_VERSION] = Int32GetDatum(remstats->server_version_num); - nulls[ATTIMPORT_SQL_VERSION] = ' '; - - values[ATTIMPORT_SQL_SCHEMANAME] = CStringGetTextDatum(schemaname); - nulls[ATTIMPORT_SQL_SCHEMANAME] = ' '; - - values[ATTIMPORT_SQL_RELNAME] = CStringGetTextDatum(relname); - nulls[ATTIMPORT_SQL_RELNAME] = ' '; + PGresult *res; + NullableDatum args[ATTSTATS_NUM_FIELDS]; - SPI_connect(); + /* Set the 'version' parameter, which is common to both statistics. */ + args[0].value = UInt32GetDatum(remstats->version); + args[0].isnull = false; /* * We import attribute statistics first, if any, because those are more * prone to errors. This avoids making a modification of pg_class that * will just get rolled back by a failed attribute import. */ - if (remstats->att != NULL) + res = remstats->att; + if (res != NULL) { - Assert(PQnfields(remstats->att) == ATTSTATS_NUM_FIELDS); - Assert(PQntuples(remstats->att) >= 1); - - attimport_plan = SPI_prepare(attimport_sql, ATTIMPORT_SQL_NUM_FIELDS, - (Oid *) attimport_argtypes); - if (attimport_plan == NULL) - elog(ERROR, "failed to prepare attimport_sql query"); - - attclear_plan = SPI_prepare(attclear_sql, ATTCLEAR_SQL_NUM_FIELDS, - (Oid *) attclear_argtypes); - if (attclear_plan == NULL) - elog(ERROR, "failed to prepare attclear_sql query"); - - nulls[ATTIMPORT_SQL_ATTNUM] = ' '; + Assert(PQnfields(res) == ATTSTATS_NUM_FIELDS); + Assert(PQntuples(res) >= 1); for (int mapidx = 0; mapidx < attrcnt; mapidx++) { int row = remattrmap[mapidx].res_index; - Datum *values2 = values + 1; - char *nulls2 = nulls + 1; + AttrNumber attnum = remattrmap[mapidx].local_attnum; /* All mappings should have been assigned a result set row. */ Assert(row >= 0); - /* - * Check for user-requested abort. - */ + /* Check for user-requested abort. */ CHECK_FOR_INTERRUPTS(); - /* - * First, clear existing attribute stats. - * - * We can re-use the values/nulls because the number of parameters - * is less and the first two params are the same as the second and - * third ones in attimport_sql. - */ - values2[ATTCLEAR_SQL_ATTNAME] = - CStringGetTextDatum(remattrmap[mapidx].local_attname); - - spirc = SPI_execute_plan(attclear_plan, values2, nulls2, false, 1); - if (spirc != SPI_OK_SELECT) - elog(ERROR, "failed to execute attclear_sql query for column \"%s\" of foreign table \"%s.%s\"", - remattrmap[mapidx].local_attname, schemaname, relname); - - values[ATTIMPORT_SQL_ATTNUM] = - Int16GetDatum(remattrmap[mapidx].local_attnum); - - /* Loop through all mappable columns to set remaining arguments */ - for (int i = 0; i < NUM_MAPPED_ATTIMPORT_ARGS; i++) - map_field_to_arg(remstats->att, row, - attr_result_arg_map[i].res_field, - attr_result_arg_map[i].arg_num, - values, nulls); - - spirc = SPI_execute_plan(attimport_plan, values, nulls, false, 1); - if (spirc != SPI_OK_SELECT) - elog(ERROR, "failed to execute attimport_sql query for column \"%s\" of foreign table \"%s.%s\"", - remattrmap[mapidx].local_attname, schemaname, relname); - - if (!import_spi_query_ok()) + /* Clear existing attribute statistics. */ + delete_attribute_statistics(relation, attnum, false); + + /* Set the remaining parameters. */ + set_float_arg(&args[1], + get_opt_value(res, row, ATTSTATS_NULL_FRAC)); + set_int32_arg(&args[2], + get_opt_value(res, row, ATTSTATS_AVG_WIDTH)); + set_float_arg(&args[3], + get_opt_value(res, row, ATTSTATS_N_DISTINCT)); + set_text_arg(&args[4], + get_opt_value(res, row, ATTSTATS_MOST_COMMON_VALS)); + set_floatarr_arg(&args[5], + get_opt_value(res, row, ATTSTATS_MOST_COMMON_FREQS)); + set_text_arg(&args[6], + get_opt_value(res, row, ATTSTATS_HISTOGRAM_BOUNDS)); + set_float_arg(&args[7], + get_opt_value(res, row, ATTSTATS_CORRELATION)); + set_text_arg(&args[8], + get_opt_value(res, row, ATTSTATS_MOST_COMMON_ELEMS)); + set_floatarr_arg(&args[9], + get_opt_value(res, row, ATTSTATS_MOST_COMMON_ELEM_FREQS)); + set_floatarr_arg(&args[10], + get_opt_value(res, row, ATTSTATS_ELEM_COUNT_HISTOGRAM)); + set_text_arg(&args[11], + get_opt_value(res, row, ATTSTATS_RANGE_LENGTH_HISTOGRAM)); + set_float_arg(&args[12], + get_opt_value(res, row, ATTSTATS_RANGE_EMPTY_FRAC)); + set_text_arg(&args[13], + get_opt_value(res, row, ATTSTATS_RANGE_BOUNDS_HISTOGRAM)); + + /* Try to import the statistics. */ + if (!import_attribute_statistics(relation, attnum, false, + &args[0], &args[1], &args[2], + &args[3], &args[4], &args[5], + &args[6], &args[7], &args[8], + &args[9], &args[10], &args[11], + &args[12], &args[13])) { ereport(WARNING, errmsg("could not import statistics for foreign table \"%s.%s\" --- attribute statistics import failed for column \"%s\" of this foreign table", schemaname, relname, remattrmap[mapidx].local_attname)); - goto import_cleanup; + return false; } } } /* - * Import relation stats. We only perform this once, so there is no point - * in preparing the statement. - * - * We can re-use the values/nulls because the number of parameters is less - * and the first three params are the same as attimport_sql. - */ - Assert(remstats->rel != NULL); - Assert(PQnfields(remstats->rel) == RELSTATS_NUM_FIELDS); - Assert(PQntuples(remstats->rel) == 1); - map_field_to_arg(remstats->rel, 0, RELSTATS_RELPAGES, - RELIMPORT_SQL_RELPAGES, values, nulls); - map_field_to_arg(remstats->rel, 0, RELSTATS_RELTUPLES, - RELIMPORT_SQL_RELTUPLES, values, nulls); - - spirc = SPI_execute_with_args(relimport_sql, - RELIMPORT_SQL_NUM_FIELDS, - (Oid *) relimport_argtypes, - values, nulls, false, 1); - if (spirc != SPI_OK_SELECT) - elog(ERROR, "failed to execute relimport_sql query for foreign table \"%s.%s\"", - schemaname, relname); - - if (!import_spi_query_ok()) + * Import relation statistics. + */ + res = remstats->rel; + Assert(res != NULL); + Assert(PQnfields(res) == RELSTATS_NUM_FIELDS); + Assert(PQntuples(res) == 1); + + /* Set the remaining parameters. */ + set_uint32_arg(&args[1], get_opt_value(res, 0, RELSTATS_RELPAGES)); + Assert(!args[1].isnull); + set_float_arg(&args[2], get_opt_value(res, 0, RELSTATS_RELTUPLES)); + Assert(!args[2].isnull); + args[3].value = (Datum) 0; + args[3].isnull = true; + args[4].value = (Datum) 0; + args[4].isnull = true; + + /* Try to import the statistics. */ + if (!import_relation_statistics(relation, &args[0], &args[1], + &args[2], &args[3], &args[4])) { ereport(WARNING, errmsg("could not import statistics for foreign table \"%s.%s\" --- relation statistics import failed for this foreign table", schemaname, relname)); - goto import_cleanup; + return false; } - ok = true; + return true; +} -import_cleanup: - if (attimport_plan) - SPI_freeplan(attimport_plan); - if (attclear_plan) - SPI_freeplan(attclear_plan); - SPI_finish(); - return ok; +/* + * Conenience routine to fetch the value for the row/column of the PGresult + */ +static char * +get_opt_value(PGresult *res, int row, int col) +{ + if (PQgetisnull(res, row, col)) + return NULL; + return PQgetvalue(res, row, col); } /* - * Move a string value from a result set to a Text value of a Datum array. + * Convenience routine for setting optional text arguments */ -static void -map_field_to_arg(PGresult *res, int row, int field, - int arg, Datum *values, char *nulls) +void +set_text_arg(NullableDatum *arg, const char *s) { - if (PQgetisnull(res, row, field)) + if (s) { - values[arg] = (Datum) 0; - nulls[arg] = 'n'; + arg->value = CStringGetTextDatum(s); + arg->isnull = false; } else { - const char *s = PQgetvalue(res, row, field); + arg->value = (Datum) 0; + arg->isnull = true; + } +} - values[arg] = CStringGetTextDatum(s); - nulls[arg] = ' '; +/* + * Convenience routine for setting optional int32 arguments + */ +void +set_int32_arg(NullableDatum *arg, const char *s) +{ + if (s) + { + int32 val = pg_strtoint32(s); + + arg->value = Int32GetDatum(val); + arg->isnull = false; + } + else + { + arg->value = (Datum) 0; + arg->isnull = true; } } /* - * Check the 1x1 result set of a pg_restore_*_stats() command for success. + * Convenience routine for setting optional uint32 arguments */ -static bool -import_spi_query_ok(void) +void +set_uint32_arg(NullableDatum *arg, const char *s) { - TupleDesc tupdesc; - Datum dat; - bool isnull; + if (s) + { + uint32 val = uint32in_subr(s, NULL, "uint32", NULL); - Assert(SPI_tuptable != NULL); - Assert(SPI_processed == 1); + arg->value = UInt32GetDatum(val); + arg->isnull = false; + } + else + { + arg->value = (Datum) 0; + arg->isnull = true; + } +} + +/* + * Convenience routine for setting optional float arguments + */ +void +set_float_arg(NullableDatum *arg, const char *s) +{ + if (s) + { + float4 val = float4in_internal((char *) s, NULL, "float", s, NULL); + + arg->value = Float4GetDatum(val); + arg->isnull = false; + } + else + { + arg->value = (Datum) 0; + arg->isnull = true; + } +} + +/* + * Convenience routine for setting optional float[] arguments + */ +void +set_floatarr_arg(NullableDatum *arg, const char *s) +{ + if (s) + { + FmgrInfo flinfo; + Datum val; - tupdesc = SPI_tuptable->tupdesc; - Assert(tupdesc->natts == 1); - Assert(TupleDescAttr(tupdesc, 0)->atttypid == BOOLOID); - dat = SPI_getbinval(SPI_tuptable->vals[0], tupdesc, 1, &isnull); - Assert(!isnull); + fmgr_info(F_ARRAY_IN, &flinfo); + val = InputFunctionCall(&flinfo, (char *) s, FLOAT4OID, -1); - return DatumGetBool(dat); + arg->value = val; + arg->isnull = false; + } + else + { + arg->value = (Datum) 0; + arg->isnull = true; + } } /* diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index e868da00ace..ed2c8b58e60 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -4652,6 +4652,34 @@ ANALYZE dtest_table; ANALYZE VERBOSE dtest_ftable; -- should work +-- dtest_ftable's stats should now exactly match dtest_table's +-- compare values, should match +SELECT relpages, reltuples FROM pg_class +WHERE oid = 'public.dtest_table'::regclass +EXCEPT +SELECT relpages, reltuples FROM pg_class +WHERE oid = 'public.dtest_ftable'::regclass; + +-- compare the rowcounts, should get 0 rows back +SELECT COUNT(*) FROM pg_stats +WHERE schemaname = 'public' AND tablename = 'dtest_table' +EXCEPT +SELECT COUNT(*) FROM pg_stats +WHERE schemaname = 'public' AND tablename = 'dtest_ftable'; + +-- test only a few stats columns common to integer types +SELECT attname, inherited, null_frac, avg_width, n_distinct, + most_common_vals::text as mcv, most_common_freqs, + histogram_bounds::text as hb, correlation +FROM pg_stats +WHERE schemaname = 'public' AND tablename = 'dtest_table' +EXCEPT +SELECT attname, inherited, null_frac, avg_width, n_distinct, + most_common_vals::text as mcv, most_common_freqs, + histogram_bounds::text as hb, correlation +FROM pg_stats +WHERE schemaname = 'public' AND tablename = 'dtest_ftable'; + -- cleanup DROP FOREIGN TABLE simport_ftable; DROP FOREIGN TABLE simport_fview; diff --git a/doc/src/sgml/fdwhandler.sgml b/doc/src/sgml/fdwhandler.sgml index 8685a078c52..0103fdacfdf 100644 --- a/doc/src/sgml/fdwhandler.sgml +++ b/doc/src/sgml/fdwhandler.sgml @@ -1438,8 +1438,9 @@ ImportForeignStatistics(Relation relation, PostgreSQL is found in src/backend/command/analyze.c. It's recommended to import table-level and column-level statistics for the - foreign table using pg_restore_relation_stats and - pg_restore_attribute_stats, respectively. + foreign table using import_relation_statistics, + import_attribute_statistics, and + delete_attribute_statistics. diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c index 1cc4d657231..8e214fe60dc 100644 --- a/src/backend/statistics/attribute_stats.c +++ b/src/backend/statistics/attribute_stats.c @@ -105,6 +105,11 @@ static struct StatsArgInfo cleararginfo[] = }; static bool attribute_statistics_update(FunctionCallInfo fcinfo); +static bool attribute_statistics_update_internal(Oid reloid, + const char *attname, + AttrNumber attnum, + bool inherited, + FunctionCallInfo fcinfo); static void upsert_pg_statistic(Relation starel, HeapTuple oldtup, const Datum *values, const bool *nulls, const bool *replaces); static bool delete_pg_statistic(Oid reloid, AttrNumber attnum, bool stainherit); @@ -136,38 +141,6 @@ attribute_statistics_update(FunctionCallInfo fcinfo) bool inherited; Oid locked_table = InvalidOid; - Relation starel; - HeapTuple statup; - - Oid atttypid = InvalidOid; - int32 atttypmod; - char atttyptype; - Oid atttypcoll = InvalidOid; - Oid eq_opr = InvalidOid; - Oid lt_opr = InvalidOid; - - Oid elemtypid = InvalidOid; - Oid elem_eq_opr = InvalidOid; - - FmgrInfo array_in_fn; - - bool do_mcv = !PG_ARGISNULL(MOST_COMMON_FREQS_ARG) && - !PG_ARGISNULL(MOST_COMMON_VALS_ARG); - bool do_histogram = !PG_ARGISNULL(HISTOGRAM_BOUNDS_ARG); - bool do_correlation = !PG_ARGISNULL(CORRELATION_ARG); - bool do_mcelem = !PG_ARGISNULL(MOST_COMMON_ELEMS_ARG) && - !PG_ARGISNULL(MOST_COMMON_ELEM_FREQS_ARG); - bool do_dechist = !PG_ARGISNULL(ELEM_COUNT_HISTOGRAM_ARG); - bool do_bounds_histogram = !PG_ARGISNULL(RANGE_BOUNDS_HISTOGRAM_ARG); - bool do_range_length_histogram = !PG_ARGISNULL(RANGE_LENGTH_HISTOGRAM_ARG) && - !PG_ARGISNULL(RANGE_EMPTY_FRAC_ARG); - - Datum values[Natts_pg_statistic] = {0}; - bool nulls[Natts_pg_statistic] = {0}; - bool replaces[Natts_pg_statistic] = {0}; - - bool result = true; - stats_check_required_arg(fcinfo, attarginfo, ATTRELSCHEMA_ARG); stats_check_required_arg(fcinfo, attarginfo, ATTRELNAME_ARG); @@ -231,6 +204,50 @@ attribute_statistics_update(FunctionCallInfo fcinfo) stats_check_required_arg(fcinfo, attarginfo, INHERITED_ARG); inherited = PG_GETARG_BOOL(INHERITED_ARG); + return attribute_statistics_update_internal(reloid, attname, attnum, + inherited, fcinfo); +} + +/* + * Workhorse function for attribute_statistics_update. + */ +static bool +attribute_statistics_update_internal(Oid reloid, + const char *attname, AttrNumber attnum, + bool inherited, FunctionCallInfo fcinfo) +{ + Relation starel; + HeapTuple statup; + + Oid atttypid = InvalidOid; + int32 atttypmod; + char atttyptype; + Oid atttypcoll = InvalidOid; + Oid eq_opr = InvalidOid; + Oid lt_opr = InvalidOid; + + Oid elemtypid = InvalidOid; + Oid elem_eq_opr = InvalidOid; + + FmgrInfo array_in_fn; + + bool do_mcv = !PG_ARGISNULL(MOST_COMMON_FREQS_ARG) && + !PG_ARGISNULL(MOST_COMMON_VALS_ARG); + bool do_histogram = !PG_ARGISNULL(HISTOGRAM_BOUNDS_ARG); + bool do_correlation = !PG_ARGISNULL(CORRELATION_ARG); + bool do_mcelem = !PG_ARGISNULL(MOST_COMMON_ELEMS_ARG) && + !PG_ARGISNULL(MOST_COMMON_ELEM_FREQS_ARG); + bool do_dechist = !PG_ARGISNULL(ELEM_COUNT_HISTOGRAM_ARG); + bool do_bounds_histogram = !PG_ARGISNULL(RANGE_BOUNDS_HISTOGRAM_ARG); + bool do_range_length_histogram = !PG_ARGISNULL(RANGE_LENGTH_HISTOGRAM_ARG) && + !PG_ARGISNULL(RANGE_EMPTY_FRAC_ARG); + + Datum values[Natts_pg_statistic] = {0}; + bool nulls[Natts_pg_statistic] = {0}; + bool replaces[Natts_pg_statistic] = {0}; + + bool result = true; + /* * Check argument sanity. If some arguments are unusable, emit a WARNING * and set the corresponding argument to NULL in fcinfo. @@ -688,3 +705,96 @@ pg_restore_attribute_stats(PG_FUNCTION_ARGS) PG_RETURN_BOOL(result); } + +/* + * Import attribute statistics from NullableDatum inputs for all statitical + * values. + * + * For now, the 'version' argument is ignored. In the future it can be used + * to interpret older statistics properly. + */ +bool +import_attribute_statistics(Relation rel, AttrNumber attnum, bool inherited, + const NullableDatum *version, + const NullableDatum *null_frac, + const NullableDatum *avg_width, + const NullableDatum *n_distinct, + const NullableDatum *most_common_vals, + const NullableDatum *most_common_freqs, + const NullableDatum *histogram_bounds, + const NullableDatum *correlation, + const NullableDatum *most_common_elems, + const NullableDatum *most_common_elem_freqs, + const NullableDatum *elem_count_histogram, + const NullableDatum *range_length_histogram, + const NullableDatum *range_empty_frac, + const NullableDatum *range_bounds_histogram) +{ + LOCAL_FCINFO(newfcinfo, NUM_ATTRIBUTE_STATS_ARGS); + Oid reloid = RelationGetRelid(rel); + char *relname = RelationGetRelationName(rel); + char *attname = get_attname(reloid, attnum, true); + + Assert(null_frac); + Assert(avg_width); + Assert(n_distinct); + Assert(most_common_vals); + Assert(most_common_freqs); + Assert(histogram_bounds); + Assert(correlation); + Assert(most_common_elems); + Assert(most_common_elem_freqs); + Assert(elem_count_histogram); + Assert(range_length_histogram); + Assert(range_empty_frac); + Assert(range_bounds_histogram); + + /* annoyingly, get_attname doesn't check attisdropped */ + if (attname == NULL || + !SearchSysCacheExistsAttName(reloid, attname)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column %d of relation \"%s\" does not exist", + attnum, relname))); + + InitFunctionCallInfoData(*newfcinfo, NULL, NUM_ATTRIBUTE_STATS_ARGS, + InvalidOid, NULL, NULL); + + newfcinfo->args[ATTRELSCHEMA_ARG].value = + CStringGetTextDatum(get_namespace_name(RelationGetNamespace(rel))); + newfcinfo->args[ATTRELSCHEMA_ARG].isnull = false; + newfcinfo->args[ATTRELNAME_ARG].value = CStringGetTextDatum(relname); + newfcinfo->args[ATTRELNAME_ARG].isnull = false; + newfcinfo->args[ATTNAME_ARG].value = CStringGetTextDatum(attname); + newfcinfo->args[ATTNAME_ARG].isnull = false; + newfcinfo->args[ATTNUM_ARG].value = Int16GetDatum(attnum); + newfcinfo->args[ATTNUM_ARG].isnull = false; + newfcinfo->args[INHERITED_ARG].value = BoolGetDatum(inherited); + newfcinfo->args[INHERITED_ARG].isnull = false; + + newfcinfo->args[NULL_FRAC_ARG] = *null_frac; + newfcinfo->args[AVG_WIDTH_ARG] = *avg_width; + newfcinfo->args[N_DISTINCT_ARG] = *n_distinct; + newfcinfo->args[MOST_COMMON_VALS_ARG] = *most_common_vals; + newfcinfo->args[MOST_COMMON_FREQS_ARG] = *most_common_freqs; + newfcinfo->args[HISTOGRAM_BOUNDS_ARG] = *histogram_bounds; + newfcinfo->args[CORRELATION_ARG] = *correlation; + newfcinfo->args[MOST_COMMON_ELEMS_ARG] = *most_common_elems; + newfcinfo->args[MOST_COMMON_ELEM_FREQS_ARG] = *most_common_elem_freqs; + newfcinfo->args[ELEM_COUNT_HISTOGRAM_ARG] = *elem_count_histogram; + newfcinfo->args[RANGE_LENGTH_HISTOGRAM_ARG] = *range_length_histogram; + newfcinfo->args[RANGE_EMPTY_FRAC_ARG] = *range_empty_frac; + newfcinfo->args[RANGE_BOUNDS_HISTOGRAM_ARG] = *range_bounds_histogram; + + return attribute_statistics_update_internal(reloid, attname, attnum, + inherited, newfcinfo); +} + +/* + * Delete attribute statistics. + */ +bool +delete_attribute_statistics(Relation rel, AttrNumber attnum, bool inherited) +{ + return delete_pg_statistic(RelationGetRelid(rel), attnum, inherited); +} diff --git a/src/backend/statistics/relation_stats.c b/src/backend/statistics/relation_stats.c index d6631e9a9a4..990a7511d04 100644 --- a/src/backend/statistics/relation_stats.c +++ b/src/backend/statistics/relation_stats.c @@ -21,6 +21,7 @@ #include "catalog/indexing.h" #include "catalog/namespace.h" #include "nodes/makefuncs.h" +#include "statistics/statistics.h" #include "statistics/stat_utils.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -57,6 +58,8 @@ static struct StatsArgInfo relarginfo[] = }; static bool relation_statistics_update(FunctionCallInfo fcinfo); +static bool relation_statistics_update_internal(Oid reloid, + FunctionCallInfo fcinfo); /* * Internal function for modifying statistics for a relation. @@ -64,25 +67,9 @@ static bool relation_statistics_update(FunctionCallInfo fcinfo); static bool relation_statistics_update(FunctionCallInfo fcinfo) { - bool result = true; char *nspname; char *relname; Oid reloid; - Relation crel; - BlockNumber relpages = 0; - bool update_relpages = false; - float reltuples = 0; - bool update_reltuples = false; - BlockNumber relallvisible = 0; - bool update_relallvisible = false; - BlockNumber relallfrozen = 0; - bool update_relallfrozen = false; - HeapTuple ctup; - Form_pg_class pgcform; - int replaces[4] = {0}; - Datum values[4] = {0}; - bool nulls[4] = {0}; - int nreplaces = 0; Oid locked_table = InvalidOid; stats_check_required_arg(fcinfo, relarginfo, RELSCHEMA_ARG); @@ -101,6 +88,32 @@ relation_statistics_update(FunctionCallInfo fcinfo) ShareUpdateExclusiveLock, 0, RangeVarCallbackForStats, &locked_table); + return relation_statistics_update_internal(reloid, fcinfo); +} + +/* + * Workhorse function for relation_statistics_update. + */ +static bool +relation_statistics_update_internal(Oid reloid, FunctionCallInfo fcinfo) +{ + BlockNumber relpages = 0; + bool update_relpages = false; + float reltuples = 0; + bool update_reltuples = false; + BlockNumber relallvisible = 0; + bool update_relallvisible = false; + BlockNumber relallfrozen = 0; + bool update_relallfrozen = false; + Relation crel; + HeapTuple ctup; + Form_pg_class pgcform; + int replaces[4] = {0}; + Datum values[4] = {0}; + bool nulls[4] = {0}; + int nreplaces = 0; + bool result = true; + if (!PG_ARGISNULL(RELPAGES_ARG)) { relpages = PG_GETARG_UINT32(RELPAGES_ARG); @@ -241,3 +254,44 @@ pg_restore_relation_stats(PG_FUNCTION_ARGS) PG_RETURN_BOOL(result); } + +/* + * Import relation statistics from NullableDatum inputs for all statitical + * values. + * + * For now, the 'version' argument is ignored. In the future it can be used + * to interpret older statistics properly. + */ +bool +import_relation_statistics(Relation rel, + const NullableDatum *version, + const NullableDatum *relpages, + const NullableDatum *reltuples, + const NullableDatum *relallvisible, + const NullableDatum *relallfrozen) +{ + LOCAL_FCINFO(newfcinfo, NUM_RELATION_STATS_ARGS); + + Assert(relpages); + Assert(reltuples); + Assert(relallvisible); + Assert(relallfrozen); + + InitFunctionCallInfoData(*newfcinfo, NULL, NUM_RELATION_STATS_ARGS, + InvalidOid, NULL, NULL); + + newfcinfo->args[RELSCHEMA_ARG].value = + CStringGetTextDatum(get_namespace_name(RelationGetNamespace(rel))); + newfcinfo->args[RELSCHEMA_ARG].isnull = false; + newfcinfo->args[RELNAME_ARG].value = + CStringGetTextDatum(RelationGetRelationName(rel)); + newfcinfo->args[RELNAME_ARG].isnull = false; + + newfcinfo->args[RELPAGES_ARG] = *relpages; + newfcinfo->args[RELTUPLES_ARG] = *reltuples; + newfcinfo->args[RELALLVISIBLE_ARG] = *relallvisible; + newfcinfo->args[RELALLFROZEN_ARG] = *relallfrozen; + + return relation_statistics_update_internal(RelationGetRelid(rel), + newfcinfo); +} diff --git a/src/include/statistics/statistics.h b/src/include/statistics/statistics.h index 8f9b9d237fd..0b163103a72 100644 --- a/src/include/statistics/statistics.h +++ b/src/include/statistics/statistics.h @@ -128,4 +128,29 @@ extern StatisticExtInfo *choose_best_statistics(List *stats, char requiredkind, int nclauses); extern HeapTuple statext_expressions_load(Oid stxoid, bool inh, int idx); +extern bool import_relation_statistics(Relation rel, + const NullableDatum *version, + const NullableDatum *relpages, + const NullableDatum *reltuples, + const NullableDatum *relallvisible, + const NullableDatum *relallfrozen); +extern bool import_attribute_statistics(Relation rel, + AttrNumber attnum, bool inherited, + const NullableDatum *version, + const NullableDatum *null_frac, + const NullableDatum *avg_width, + const NullableDatum *n_distinct, + const NullableDatum *most_common_vals, + const NullableDatum *most_common_freqs, + const NullableDatum *histogram_bounds, + const NullableDatum *correlation, + const NullableDatum *most_common_elems, + const NullableDatum *most_common_elem_freqs, + const NullableDatum *elem_count_histogram, + const NullableDatum *range_length_histogram, + const NullableDatum *range_empty_frac, + const NullableDatum *range_bounds_histogram); +extern bool delete_attribute_statistics(Relation rel, + AttrNumber attnum, bool inherited); + #endif /* STATISTICS_H */ From 5b5e99047ab0df2ef3d18de81176558e49015205 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 10 Jul 2026 10:08:21 +0200 Subject: [PATCH 135/481] Forbid FOR PORTION OF on views with INSTEAD OF triggers Previously, an attempt to use these features together caused a crash. Oversight of commit 8e72d914c528. Tests are added also to show that the check for this should be in the rewriter, not the parser, as an earlier patch version suggested. Author: Aleksander Alekseev Author: Paul A. Jungwirth Discussion: https://www.postgresql.org/message-id/flat/CAJ7c6TME%2Bix6VRf-2TPnVTsj8qn_hy6sYAOmMhZEivwsu2wS6g%40mail.gmail.com --- src/backend/rewrite/rewriteHandler.c | 8 ++ src/test/regress/expected/updatable_views.out | 71 ++++++++++++++++++ src/test/regress/sql/updatable_views.sql | 73 +++++++++++++++++++ 3 files changed, 152 insertions(+) diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index e7ae9cce65f..38f54b57eec 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -4171,6 +4171,14 @@ RewriteQuery(Query *parsetree, List *rewrite_events, int orig_rt_length, */ rt_entry_relation = relation_open(rt_entry->relid, NoLock); + /* We don't support FOR PORTION OF on views with INSTEAD OF triggers. */ + if (parsetree->forPortionOf && + rt_entry_relation->rd_rel->relkind == RELKIND_VIEW && + view_has_instead_trigger(rt_entry_relation, event, NIL)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("views with INSTEAD OF triggers do not support FOR PORTION OF"))); + /* * Rewrite the targetlist as needed for the command type. */ diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out index 7b00c742776..9c6bb2219f9 100644 --- a/src/test/regress/expected/updatable_views.out +++ b/src/test/regress/expected/updatable_views.out @@ -4165,3 +4165,74 @@ select * from base_tab order by a; drop view base_tab_view; drop table base_tab; +-- FOR PORTION OF is not supported on views with INSTEAD OF triggers +create view uv_fpo_instead_view as select id, valid_at, b from uv_fpo_tab; +create function uv_fpo_instead_trig() returns trigger language plpgsql as +$$ begin return null; end $$; +create trigger uv_fpo_instead_upd_trig + instead of update on uv_fpo_instead_view + for each row execute function uv_fpo_instead_trig(); +create trigger uv_fpo_instead_del_trig + instead of delete on uv_fpo_instead_view + for each row execute function uv_fpo_instead_trig(); +update uv_fpo_instead_view + for portion of valid_at from '2015-01-01' to '2020-01-01' + set b = 99 where id = '[1,1]'; -- error +ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF +delete from uv_fpo_instead_view + for portion of valid_at from '2017-01-01' to '2022-01-01' + where id = '[1,1]'; -- error +ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF +-- The check does not depend on which rows match, so it errors even when +-- no rows do. +update uv_fpo_instead_view + for portion of valid_at from '2015-01-01' to '2020-01-01' + set b = 99 where id = '[9,9]'; -- error, even with no matching rows +ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF +delete from uv_fpo_instead_view + for portion of valid_at from '2017-01-01' to '2022-01-01' + where id = '[9,9]'; -- error, even with no matching rows +ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF +drop view uv_fpo_instead_view; +drop function uv_fpo_instead_trig(); +-- Forbid INSTEAD OF triggers with FOR PORTION OF even if the FOR PORTION OF +-- statement is parsed before the trigger exists. +-- This can happen in at least a couple ways: a rewrite rule or a BEGIN ATOMIC function. +create function uv_fpo_instead_trig() returns trigger language plpgsql as +$$ begin return new; end $$; +-- via a rewrite rule +create table uv_fpo_rule_tab (id int4range, valid_at tsrange, b float); +insert into uv_fpo_rule_tab values ('[1,1]', '[2000-01-01, 2030-01-01)', 0); +create view uv_fpo_rule_view as select id, valid_at, b from uv_fpo_rule_tab; +create rule uv_fpo_rule as on insert to uv_fpo_rule_tab do also + update uv_fpo_rule_view + for portion of valid_at from '2010-01-01' to '2020-01-01' + set b = 99 where id = '[1,1]'; +create trigger uv_fpo_rule_instead + instead of update on uv_fpo_rule_view + for each row execute function uv_fpo_instead_trig(); +-- Would crash if we checked at parse-time: +insert into uv_fpo_rule_tab values ('[2,2]', '[2000-01-01,2030-01-01)', 0); +ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF +drop table uv_fpo_rule_tab cascade; +NOTICE: drop cascades to view uv_fpo_rule_view +-- via a BEGIN ATOMIC function body +create table uv_fpo_atomic_tab (id int4range, valid_at tsrange, b float); +insert into uv_fpo_atomic_tab values ('[1,1]', '[2000-01-01, 2030-01-01)', 0); +create view uv_fpo_atomic_view as select id, valid_at, b from uv_fpo_atomic_tab; +create function uv_fpo_atomic_fn() returns void language sql begin atomic + update uv_fpo_atomic_view + for portion of valid_at from '2010-01-01' to '2020-01-01' + set b = 99 where id = '[1,1]'; +end; +create trigger uv_fpo_atomic_instead + instead of update on uv_fpo_atomic_view + for each row execute function uv_fpo_instead_trig(); +-- Would crash if we checked at parse-time: +select uv_fpo_atomic_fn(); +ERROR: views with INSTEAD OF triggers do not support FOR PORTION OF +CONTEXT: SQL function "uv_fpo_atomic_fn" statement 1 +drop function uv_fpo_atomic_fn(); +drop table uv_fpo_atomic_tab cascade; +NOTICE: drop cascades to view uv_fpo_atomic_view +drop function uv_fpo_instead_trig(); diff --git a/src/test/regress/sql/updatable_views.sql b/src/test/regress/sql/updatable_views.sql index 4a60126ec90..2ef9aa32f36 100644 --- a/src/test/regress/sql/updatable_views.sql +++ b/src/test/regress/sql/updatable_views.sql @@ -2148,3 +2148,76 @@ values (1, 2, default, 5, 4, default, 3), (10, 11, 'C value', 14, 13, 100, 12); select * from base_tab order by a; drop view base_tab_view; drop table base_tab; + +-- FOR PORTION OF is not supported on views with INSTEAD OF triggers +create view uv_fpo_instead_view as select id, valid_at, b from uv_fpo_tab; + +create function uv_fpo_instead_trig() returns trigger language plpgsql as +$$ begin return null; end $$; + +create trigger uv_fpo_instead_upd_trig + instead of update on uv_fpo_instead_view + for each row execute function uv_fpo_instead_trig(); +create trigger uv_fpo_instead_del_trig + instead of delete on uv_fpo_instead_view + for each row execute function uv_fpo_instead_trig(); + +update uv_fpo_instead_view + for portion of valid_at from '2015-01-01' to '2020-01-01' + set b = 99 where id = '[1,1]'; -- error + +delete from uv_fpo_instead_view + for portion of valid_at from '2017-01-01' to '2022-01-01' + where id = '[1,1]'; -- error + +-- The check does not depend on which rows match, so it errors even when +-- no rows do. +update uv_fpo_instead_view + for portion of valid_at from '2015-01-01' to '2020-01-01' + set b = 99 where id = '[9,9]'; -- error, even with no matching rows + +delete from uv_fpo_instead_view + for portion of valid_at from '2017-01-01' to '2022-01-01' + where id = '[9,9]'; -- error, even with no matching rows + +drop view uv_fpo_instead_view; +drop function uv_fpo_instead_trig(); + +-- Forbid INSTEAD OF triggers with FOR PORTION OF even if the FOR PORTION OF +-- statement is parsed before the trigger exists. +-- This can happen in at least a couple ways: a rewrite rule or a BEGIN ATOMIC function. +create function uv_fpo_instead_trig() returns trigger language plpgsql as +$$ begin return new; end $$; + +-- via a rewrite rule +create table uv_fpo_rule_tab (id int4range, valid_at tsrange, b float); +insert into uv_fpo_rule_tab values ('[1,1]', '[2000-01-01, 2030-01-01)', 0); +create view uv_fpo_rule_view as select id, valid_at, b from uv_fpo_rule_tab; +create rule uv_fpo_rule as on insert to uv_fpo_rule_tab do also + update uv_fpo_rule_view + for portion of valid_at from '2010-01-01' to '2020-01-01' + set b = 99 where id = '[1,1]'; +create trigger uv_fpo_rule_instead + instead of update on uv_fpo_rule_view + for each row execute function uv_fpo_instead_trig(); +-- Would crash if we checked at parse-time: +insert into uv_fpo_rule_tab values ('[2,2]', '[2000-01-01,2030-01-01)', 0); +drop table uv_fpo_rule_tab cascade; + +-- via a BEGIN ATOMIC function body +create table uv_fpo_atomic_tab (id int4range, valid_at tsrange, b float); +insert into uv_fpo_atomic_tab values ('[1,1]', '[2000-01-01, 2030-01-01)', 0); +create view uv_fpo_atomic_view as select id, valid_at, b from uv_fpo_atomic_tab; +create function uv_fpo_atomic_fn() returns void language sql begin atomic + update uv_fpo_atomic_view + for portion of valid_at from '2010-01-01' to '2020-01-01' + set b = 99 where id = '[1,1]'; +end; +create trigger uv_fpo_atomic_instead + instead of update on uv_fpo_atomic_view + for each row execute function uv_fpo_instead_trig(); +-- Would crash if we checked at parse-time: +select uv_fpo_atomic_fn(); +drop function uv_fpo_atomic_fn(); +drop table uv_fpo_atomic_tab cascade; +drop function uv_fpo_instead_trig(); From 2bbec7c49a6c872fdfdddf7ff9ea9dc9cebaef40 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 10 Jul 2026 20:36:36 +0900 Subject: [PATCH 136/481] postgres_fdw: Mark statistics import helpers as static The set_*_arg helper functions in postgres_fdw.c are declared static, but their definitions omitted the static keyword. Add it to make their file-local scope explicit and keep the declarations and definitions consistent. Also fix a couple of nearby comment typos. This is a followup to commit 54cd6fc8317. Author: Fujii Masao Reviewed-by: Etsuro Fujita Discussion: https://postgr.es/m/CAHGQGwGjcQ4SwHMUQ9P8UYQ7iLKL1QE3uLSdONToQ1MrzpUUoQ@mail.gmail.com Backpatch-through: 19 --- contrib/postgres_fdw/postgres_fdw.c | 12 ++++++------ src/backend/statistics/attribute_stats.c | 2 +- src/backend/statistics/relation_stats.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index e6e0a4ab9b5..70de942de12 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -6134,7 +6134,7 @@ import_fetched_statistics(Relation relation, } /* - * Conenience routine to fetch the value for the row/column of the PGresult + * Convenience routine to fetch the value for the row/column of the PGresult */ static char * get_opt_value(PGresult *res, int row, int col) @@ -6147,7 +6147,7 @@ get_opt_value(PGresult *res, int row, int col) /* * Convenience routine for setting optional text arguments */ -void +static void set_text_arg(NullableDatum *arg, const char *s) { if (s) @@ -6165,7 +6165,7 @@ set_text_arg(NullableDatum *arg, const char *s) /* * Convenience routine for setting optional int32 arguments */ -void +static void set_int32_arg(NullableDatum *arg, const char *s) { if (s) @@ -6185,7 +6185,7 @@ set_int32_arg(NullableDatum *arg, const char *s) /* * Convenience routine for setting optional uint32 arguments */ -void +static void set_uint32_arg(NullableDatum *arg, const char *s) { if (s) @@ -6205,7 +6205,7 @@ set_uint32_arg(NullableDatum *arg, const char *s) /* * Convenience routine for setting optional float arguments */ -void +static void set_float_arg(NullableDatum *arg, const char *s) { if (s) @@ -6225,7 +6225,7 @@ set_float_arg(NullableDatum *arg, const char *s) /* * Convenience routine for setting optional float[] arguments */ -void +static void set_floatarr_arg(NullableDatum *arg, const char *s) { if (s) diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c index 8e214fe60dc..c47df5adab3 100644 --- a/src/backend/statistics/attribute_stats.c +++ b/src/backend/statistics/attribute_stats.c @@ -707,7 +707,7 @@ pg_restore_attribute_stats(PG_FUNCTION_ARGS) } /* - * Import attribute statistics from NullableDatum inputs for all statitical + * Import attribute statistics from NullableDatum inputs for all statistical * values. * * For now, the 'version' argument is ignored. In the future it can be used diff --git a/src/backend/statistics/relation_stats.c b/src/backend/statistics/relation_stats.c index 990a7511d04..fbaab92284f 100644 --- a/src/backend/statistics/relation_stats.c +++ b/src/backend/statistics/relation_stats.c @@ -256,7 +256,7 @@ pg_restore_relation_stats(PG_FUNCTION_ARGS) } /* - * Import relation statistics from NullableDatum inputs for all statitical + * Import relation statistics from NullableDatum inputs for all statistical * values. * * For now, the 'version' argument is ignored. In the future it can be used From 9d1d91a14335392347e09a6cef2a45d8eafeebbd Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 10 Jul 2026 22:32:53 +0900 Subject: [PATCH 137/481] Fix data checksum progress counter initialization pg_stat_progress_data_checksums uses -1 as a sentinel value that is displayed as NULL for progress counters. However, after pgstat_progress_start_command() initialized all progress counters to zero, data checksum progress did not reset those counters to -1. As a result, some counters could incorrectly appear as zero instead of NULL. For example, workers could report zero database counters, and the disabling launcher could report zero relation and block counters. Also, blocks_done was not reset when a worker started processing a new relation fork. As a result, it could temporarily exceed blocks_total or report a stale value for an empty relation fork. Fix this by initializing the data checksum progress counters to -1 when progress reporting starts for both launcher and worker processes. Also reset blocks_done together with blocks_total when starting each relation fork. Author: Fujii Masao Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CAHGQGwEOQyEzW2cqrHEzvwbcsAsuH8MEe7MMidFOFxECy0E1_Q@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/monitoring.sgml | 8 ++-- src/backend/catalog/system_views.sql | 2 +- src/backend/postmaster/datachecksum_state.c | 53 ++++++++++++++++----- src/test/regress/expected/rules.out | 5 +- 4 files changed, 50 insertions(+), 18 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index aa196754cb2..9eeda36001f 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -7945,8 +7945,8 @@ FROM pg_stat_get_backend_idset() AS backendid; The total number of databases which will be processed. Only the - launcher process has this value set, the worker processes have this - set to NULL. + launcher process has this value set when enabling data checksums; + otherwise this is set to NULL. @@ -7958,8 +7958,8 @@ FROM pg_stat_get_backend_idset() AS backendid; The number of databases which have been processed. Only the launcher - process has this value set, the worker processes have this set to - NULL. + process has this value set when enabling data checksums; otherwise + this is set to NULL. diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 8f129baec90..4427b2232b0 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1482,7 +1482,7 @@ CREATE VIEW pg_stat_progress_data_checksums AS WHEN 4 THEN 'done' END AS phase, CASE S.param2 WHEN -1 THEN NULL ELSE S.param2 END AS databases_total, - S.param3 AS databases_done, + CASE S.param3 WHEN -1 THEN NULL ELSE S.param3 END AS databases_done, CASE S.param4 WHEN -1 THEN NULL ELSE S.param4 END AS relations_total, CASE S.param5 WHEN -1 THEN NULL ELSE S.param5 END AS relations_done, CASE S.param6 WHEN -1 THEN NULL ELSE S.param6 END AS blocks_total, diff --git a/src/backend/postmaster/datachecksum_state.c b/src/backend/postmaster/datachecksum_state.c index 68557c16cb9..bec110105df 100644 --- a/src/backend/postmaster/datachecksum_state.c +++ b/src/backend/postmaster/datachecksum_state.c @@ -391,6 +391,7 @@ static void FreeDatabaseList(List *dblist); static DataChecksumsWorkerResult ProcessDatabase(DataChecksumsWorkerDatabase *db); static bool ProcessAllDatabases(void); static bool ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferAccessStrategy strategy); +static void ResetDataChecksumsProgressCounters(void); static void launcher_cancel_handler(SIGNAL_ARGS); static void WaitForAllTransactionsToFinish(void); @@ -698,7 +699,19 @@ ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferAccessStrateg snprintf(activity, sizeof(activity) - 1, "processing: %s.%s (%s, %u blocks)", (relns ? relns : ""), RelationGetRelationName(reln), forkNames[forkNum], numblocks); pgstat_report_activity(STATE_RUNNING, activity); - pgstat_progress_update_param(PROGRESS_DATACHECKSUMS_BLOCKS_TOTAL, numblocks); + { + const int index[] = { + PROGRESS_DATACHECKSUMS_BLOCKS_TOTAL, + PROGRESS_DATACHECKSUMS_BLOCKS_DONE + }; + + int64 vals[2]; + + vals[0] = numblocks; + vals[1] = 0; + + pgstat_progress_update_multi_param(2, index, vals); + } if (relns) pfree(relns); @@ -764,6 +777,29 @@ ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferAccessStrateg return true; } +/* + * Initialize all data checksum progress counters to be displayed as NULL. + */ +static void +ResetDataChecksumsProgressCounters(void) +{ + const int index[] = { + PROGRESS_DATACHECKSUMS_DBS_TOTAL, + PROGRESS_DATACHECKSUMS_DBS_DONE, + PROGRESS_DATACHECKSUMS_RELS_TOTAL, + PROGRESS_DATACHECKSUMS_RELS_DONE, + PROGRESS_DATACHECKSUMS_BLOCKS_TOTAL, + PROGRESS_DATACHECKSUMS_BLOCKS_DONE, + }; + + int64 vals[lengthof(index)]; + + for (int i = 0; i < lengthof(index); i++) + vals[i] = -1; + + pgstat_progress_update_multi_param(lengthof(index), index, vals); +} + /* * ProcessSingleRelationByOid * Process a single relation based on oid. @@ -1142,6 +1178,7 @@ DataChecksumsWorkerLauncherMain(Datum arg) pgstat_progress_start_command(PROGRESS_COMMAND_DATACHECKSUMS, InvalidOid); + ResetDataChecksumsProgressCounters(); if (operation == ENABLE_DATACHECKSUMS) { @@ -1269,23 +1306,14 @@ ProcessAllDatabases(void) const int index[] = { PROGRESS_DATACHECKSUMS_DBS_TOTAL, PROGRESS_DATACHECKSUMS_DBS_DONE, - PROGRESS_DATACHECKSUMS_RELS_TOTAL, - PROGRESS_DATACHECKSUMS_RELS_DONE, - PROGRESS_DATACHECKSUMS_BLOCKS_TOTAL, - PROGRESS_DATACHECKSUMS_BLOCKS_DONE, }; - int64 vals[6]; + int64 vals[2]; vals[0] = list_length(DatabaseList); vals[1] = 0; - /* translated to NULL */ - vals[2] = -1; - vals[3] = -1; - vals[4] = -1; - vals[5] = -1; - pgstat_progress_update_multi_param(6, index, vals); + pgstat_progress_update_multi_param(2, index, vals); } foreach_ptr(DataChecksumsWorkerDatabase, db, DatabaseList) @@ -1581,6 +1609,7 @@ DataChecksumsWorkerMain(Datum arg) /* worker will have a separate entry in pg_stat_progress_data_checksums */ pgstat_progress_start_command(PROGRESS_COMMAND_DATACHECKSUMS, InvalidOid); + ResetDataChecksumsProgressCounters(); /* * Get a list of all temp tables present as we start in this database. We diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 475f5683e1c..dd4502923b1 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -2115,7 +2115,10 @@ pg_stat_progress_data_checksums| SELECT s.pid, WHEN '-1'::integer THEN NULL::bigint ELSE s.param2 END AS databases_total, - s.param3 AS databases_done, + CASE s.param3 + WHEN '-1'::integer THEN NULL::bigint + ELSE s.param3 + END AS databases_done, CASE s.param4 WHEN '-1'::integer THEN NULL::bigint ELSE s.param4 From c479ea58e7798b8cab8b8a4ca9e6ce3e292a3f17 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 10 Jul 2026 22:34:24 +0900 Subject: [PATCH 138/481] Fix data checksum processing for temp relations and dropped databases When building the list of temporary relations to wait for, the code previously included temporary relations without storage, such as temporary views, even though they are irrelevant to checksum processing. As a result, enabling data checksums could wait for a long-lived session that owned only a temporary view. This commit fixes the issue by filtering temporary relations with storage only, matching the existing behavior for non-temporary relations. Also, when enabling data checksums online, the launcher assigns the first worker to process shared catalogs and prevents later workers from doing so. Previously, if that worker's database was dropped after it had been selected for processing but before checksum processing began, the worker failed without processing the shared catalogs, yet they were still marked as processed. As a result, later workers skipped them, and checksum enabling could complete successfully even though the shared catalogs had never been processed. This commit fixes the issue by marking shared catalogs as processed only after a worker completes successfully. Author: Fujii Masao Reviewed-by: Kyotaro Horiguchi Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CAHGQGwGDHAQw=bmpRzk+EmKzVtxZiD5YDurMUffBMwr6WXugQA@mail.gmail.com Backpatch-through: 19 --- src/backend/postmaster/datachecksum_state.c | 24 ++++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/backend/postmaster/datachecksum_state.c b/src/backend/postmaster/datachecksum_state.c index bec110105df..7f29551202f 100644 --- a/src/backend/postmaster/datachecksum_state.c +++ b/src/backend/postmaster/datachecksum_state.c @@ -1352,6 +1352,14 @@ ProcessAllDatabases(void) /* Abort flag set, so exit the whole process */ return false; } + else if (result == DATACHECKSUMSWORKER_DROPDB) + { + /* + * Ignore databases that were dropped before their worker could + * process them, and continue with the remaining databases. + */ + continue; + } /* * When one database has completed, it will have done shared catalogs @@ -1497,11 +1505,11 @@ FreeDatabaseList(List *dblist) * Compile a list of relations in the database * * Returns a list of OIDs for the requested relation types. If temp_relations - * is True then only temporary relations are returned. If temp_relations is - * False then non-temporary relations which have data checksums are returned. - * If include_shared is True then shared relations are included as well in a - * non-temporary list. include_shared has no relevance when building a list of - * temporary relations. + * is True then only temporary relations with storage are returned. If + * temp_relations is False then non-temporary relations with storage are + * returned. If include_shared is True then shared relations are included as + * well in a non-temporary list. include_shared has no relevance when building + * a list of temporary relations. */ static List * BuildRelationList(bool temp_relations, bool include_shared) @@ -1522,6 +1530,9 @@ BuildRelationList(bool temp_relations, bool include_shared) { Form_pg_class pgc = (Form_pg_class) GETSTRUCT(tup); + if (!RELKIND_HAS_STORAGE(pgc->relkind)) + continue; + /* Only include temporary relations when explicitly asked to */ if (pgc->relpersistence == RELPERSISTENCE_TEMP) { @@ -1537,9 +1548,6 @@ BuildRelationList(bool temp_relations, bool include_shared) if (temp_relations) continue; - if (!RELKIND_HAS_STORAGE(pgc->relkind)) - continue; - if (pgc->relisshared && !include_shared) continue; } From 133eba078f776268d24f82a2b3d5bf9ca31dd4c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Fri, 10 Jul 2026 16:10:36 +0200 Subject: [PATCH 139/481] Don't lock tables in get_tables_to_repack() When doing a whole database repack, we build a list of tables to process taking a lock on each. But because it's a regular transaction-scoped lock, it's automatically released immediately after building the list anyway, which makes it not very useful. (Also, we have three ways to obtain a list of tables to repack, and only one of them acquired this lock.) Remove that lock acquisition, as it's useless and inconsistent. We acquire a lock properly afterwards (and recheck that the table can still be repacked as indicated), so we don't need to do anything other than drop that initial lock acquisition and harden the code in repack_is_permitted_for_relation() against possible concurrent drops. This is similar to how vacuum does it in get_all_vacuum_rels(). In order for this to work reliably, also change repack_is_permitted_for_relation() to cope with the possibility of the table going away partway through. Similarly, in ExecRepack(), be prepared for what we believed to be a table or matview to now be something else, and skip it without erroring out, by changing try_table_open() to try_relation_open() and testing the relkind separately. While at it, replace one relation_close() call in get_tables_to_repack() with table_close() to match the table_open() that opened the catalog. Author: ChangAo Chen Backpatch-through: 19 Discussion: https://postgr.es/m/tencent_9F290B256A3F52B66542F1140E32ECC64309@qq.com --- src/backend/commands/repack.c | 117 ++++++++++++++++------------------ 1 file changed, 54 insertions(+), 63 deletions(-) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index faa07d1a118..02883fe34a4 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -375,7 +375,8 @@ ExecRepack(ParseState *pstate, RepackStmt *stmt, bool isTopLevel) /* * If we don't have a relation yet, determine a relation list. If we do, * then it must be a partitioned table, and we want to process its - * partitions. + * partitions. Note that we don't acquire any locks on these tables, so + * the returned list must be treated with suspicion. */ if (rel == NULL) { @@ -452,15 +453,22 @@ ExecRepack(ParseState *pstate, RepackStmt *stmt, bool isTopLevel) StartTransactionCommand(); /* - * Open the target table, coping with the case where it has been - * dropped. + * Open the target table. It may have been dropped or replaced with + * something different, in which case silently skip it. */ - rel = try_table_open(rtc->tableOid, lockmode); + rel = try_relation_open(rtc->tableOid, lockmode); if (rel == NULL) { CommitTransactionCommand(); continue; } + if (rel->rd_rel->relkind != RELKIND_RELATION && + rel->rd_rel->relkind != RELKIND_MATVIEW) + { + relation_close(rel, lockmode); + CommitTransactionCommand(); + continue; + } /* functions in indexes may want a snapshot set */ PushActiveSnapshot(GetTransactionSnapshot()); @@ -713,6 +721,8 @@ cluster_rel_recheck(RepackCommand cmd, Relation OldHeap, Oid indexOid, { Oid tableOid = RelationGetRelid(OldHeap); + Assert(CheckRelationLockedByMe(OldHeap, lmode, false)); + /* Check that the user still has privileges for the relation */ if (!repack_is_permitted_for_relation(cmd, tableOid, userid)) { @@ -2152,6 +2162,10 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt) /* * For USING INDEX, scan pg_index to find those with indisclustered. + * + * Note we don't obtain lock of any kind on the index, which means the + * index or its owning table could be gone or change at any point. We + * have to be extra careful when examining catalog state for them. */ catalog = table_open(IndexRelationId, AccessShareLock); ScanKeyInit(&entry, @@ -2164,47 +2178,28 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt) RelToCluster *rtc; Form_pg_index index; HeapTuple classtup; - Form_pg_class classForm; + Oid relnamespace; + char relpersistence; MemoryContext oldcxt; index = (Form_pg_index) GETSTRUCT(tuple); - /* - * Try to obtain a light lock on the index's table, to ensure it - * doesn't go away while we collect the list. If we cannot, just - * disregard it. Be sure to release this if we ultimately decide - * not to process the table! - */ - if (!ConditionalLockRelationOid(index->indrelid, AccessShareLock)) - continue; - - /* Verify that the table still exists; skip if not */ classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(index->indrelid)); if (!HeapTupleIsValid(classtup)) - { - UnlockRelationOid(index->indrelid, AccessShareLock); continue; - } - classForm = (Form_pg_class) GETSTRUCT(classtup); + relnamespace = ((Form_pg_class) GETSTRUCT(classtup))->relnamespace; + relpersistence = ((Form_pg_class) GETSTRUCT(classtup))->relpersistence; + ReleaseSysCache(classtup); /* Skip temp relations belonging to other sessions */ - if (classForm->relpersistence == RELPERSISTENCE_TEMP && - !isTempOrTempToastNamespace(classForm->relnamespace)) - { - ReleaseSysCache(classtup); - UnlockRelationOid(index->indrelid, AccessShareLock); + if (relpersistence == RELPERSISTENCE_TEMP && + !isTempOrTempToastNamespace(relnamespace)) continue; - } - - ReleaseSysCache(classtup); /* noisily skip rels which the user can't process */ if (!repack_is_permitted_for_relation(cmd, index->indrelid, GetUserId())) - { - UnlockRelationOid(index->indrelid, AccessShareLock); continue; - } /* Use a permanent memory context for the result list */ oldcxt = MemoryContextSwitchTo(permcxt); @@ -2228,45 +2223,20 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt) class = (Form_pg_class) GETSTRUCT(tuple); - /* - * Try to obtain a light lock on the table, to ensure it doesn't - * go away while we collect the list. If we cannot, just - * disregard the table. Be sure to release this if we ultimately - * decide not to process the table! - */ - if (!ConditionalLockRelationOid(class->oid, AccessShareLock)) - continue; - - /* Verify that the table still exists */ - if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(class->oid))) - { - UnlockRelationOid(class->oid, AccessShareLock); - continue; - } - /* Can only process plain tables and matviews */ if (class->relkind != RELKIND_RELATION && class->relkind != RELKIND_MATVIEW) - { - UnlockRelationOid(class->oid, AccessShareLock); continue; - } /* Skip temp relations belonging to other sessions */ if (class->relpersistence == RELPERSISTENCE_TEMP && !isTempOrTempToastNamespace(class->relnamespace)) - { - UnlockRelationOid(class->oid, AccessShareLock); continue; - } /* noisily skip rels which the user can't process */ if (!repack_is_permitted_for_relation(cmd, class->oid, GetUserId())) - { - UnlockRelationOid(class->oid, AccessShareLock); continue; - } /* Use a permanent memory context for the result list */ oldcxt = MemoryContextSwitchTo(permcxt); @@ -2279,7 +2249,7 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt) } table_endscan(scan); - relation_close(catalog, AccessShareLock); + table_close(catalog, AccessShareLock); return rtcs; } @@ -2351,21 +2321,42 @@ get_tables_to_repack_partitioned(RepackCommand cmd, Oid relid, /* - * Return whether userid has privileges to REPACK relid. If not, this - * function emits a WARNING. + * Return whether userid has privileges to execute REPACK on relid. + * + * Caller may not have a lock on the relation, so it could have been + * dropped concurrently. In that case, silently return false. + * + * If the relation does exist but the user doesn't have the required + * privs, emit a WARNING and return false. Otherwise, return true. */ static bool repack_is_permitted_for_relation(RepackCommand cmd, Oid relid, Oid userid) { + bool is_missing = false; + AclResult result; + char *relname; + Assert(cmd == REPACK_COMMAND_CLUSTER || cmd == REPACK_COMMAND_REPACK); - if (pg_class_aclcheck(relid, userid, ACL_MAINTAIN) == ACLCHECK_OK) + result = pg_class_aclcheck_ext(relid, userid, ACL_MAINTAIN, &is_missing); + if (is_missing) + return false; + + if (result == ACLCHECK_OK) return true; - ereport(WARNING, - errmsg("permission denied to execute %s on \"%s\", skipping it", - RepackCommandAsString(cmd), - get_rel_name(relid))); + /* + * The relation can also be dropped after we tested its ACL and before we + * read its relname, so be careful here. + */ + relname = get_rel_name(relid); + if (relname != NULL) + { + ereport(WARNING, + errmsg("permission denied to execute %s on \"%s\", skipping it", + RepackCommandAsString(cmd), relname)); + pfree(relname); + } return false; } From a1b74b7279c24638c44f9d3d1af2da30cfb7068d Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Fri, 10 Jul 2026 13:25:13 -0400 Subject: [PATCH 140/481] bufmgr: Fix order of operations in UnlockBufHdrExt In c75ebc657ffc I (Andres) introduced UnlockBufHdrExt() which can set and clear bits in the buffer state using CAS. Unfortunately I added bits before subtracting them, which means that a bit that was both removed and set would remain unset. Fix the order of operations. The only known case where that is a problem is that BM_IO_ERROR would not actually remain set. It's unfortunately not trivial to add a decent, race-free, test to verify that BM_IO_ERROR remains set. That's therefore left for the 20 cycle. Reported-by: Yura Sokolov Discussion: https://postgr.es/m/ab0dcc9e-aba0-44e3-ac23-8d74c48888e6@postgrespro.ru Backpatch-through: 19, where c75ebc657ffc went in --- src/include/storage/buf_internals.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h index 89615a254a3..a23abf14f8f 100644 --- a/src/include/storage/buf_internals.h +++ b/src/include/storage/buf_internals.h @@ -463,12 +463,13 @@ UnlockBufHdr(BufferDesc *desc) } /* - * Unlock the buffer header, while atomically adding the flags in set_bits, - * unsetting the ones in unset_bits and changing the refcount by - * refcount_change. + * Unlock the buffer header, while atomically unsetting the ones in + * unset_bits, adding the flags in set_bits, and changing the refcount by + * refcount_change. If a flag is both cleared and added, it will end up being + * set. * - * Note that this approach would not work for usagecount, since we need to cap - * the usagecount at BM_MAX_USAGE_COUNT. + * Note that this approach would not trivially work for usagecount, since we + * need to cap the usagecount at BM_MAX_USAGE_COUNT. */ static inline uint64 UnlockBufHdrExt(BufferDesc *desc, uint64 old_buf_state, @@ -481,8 +482,12 @@ UnlockBufHdrExt(BufferDesc *desc, uint64 old_buf_state, Assert(buf_state & BM_LOCKED); - buf_state |= set_bits; + /* + * Set bits after clearing bits, so that a cleared and re-added flag + * survives. + */ buf_state &= ~unset_bits; + buf_state |= set_bits; buf_state &= ~BM_LOCKED; if (refcount_change != 0) From e9eaeb04248a8b2cc977440caa1b72174c108c14 Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Fri, 10 Jul 2026 18:10:23 -0400 Subject: [PATCH 141/481] Update FSM after updating VM on-access b46e1e54d078de allowed setting the VM while on-access pruning, but it neglected to update the freespace map. Once the page was all-visible, vacuum could skip it, leading to stale freespace map values and, effectively, bloat. Fix it by updating the FSM if we updated the VM. Author: Melanie Plageman Reviewed-by: Andres Freund Reviewed-by: Andrey Borodin Discussion: https://postgr.es/m/flat/CAAKRu_b2StZrEC%3DHmW8LePuQbczyFRnfs8qTAJwn_%3DW76-y24w%40mail.gmail.com Backpatch-through: 19 --- src/backend/access/heap/pruneheap.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index fdddd23035b..6f3ba9113b5 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -27,6 +27,7 @@ #include "miscadmin.h" #include "pgstat.h" #include "storage/bufmgr.h" +#include "storage/freespace.h" #include "utils/rel.h" #include "utils/snapmgr.h" @@ -321,6 +322,9 @@ heap_page_prune_opt(Relation relation, Buffer buffer, Buffer *vmbuffer, if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree) { + bool record_free_space = false; + Size freespace = 0; + /* OK, try to get exclusive buffer lock */ if (!ConditionalLockBufferForCleanup(buffer)) return; @@ -376,16 +380,32 @@ heap_page_prune_opt(Relation relation, Buffer buffer, Buffer *vmbuffer, if (presult.ndeleted > presult.nnewlpdead) pgstat_update_heap_dead_tuples(relation, presult.ndeleted - presult.nnewlpdead); + + /* + * If this prune newly set the page all-visible, VACUUM may later + * skip the page and not update the free space map (FSM) for it. + * Keep the FSM from going stale by recording it now. We do not + * want to update the freespace map otherwise, to reserve + * freespace on this page for HOT updates. + */ + if (presult.newly_all_visible) + { + record_free_space = true; + freespace = PageGetHeapFreeSpace(page); + } } /* And release buffer lock */ LockBuffer(buffer, BUFFER_LOCK_UNLOCK); /* - * We avoid reuse of any free space created on the page by unrelated - * UPDATEs/INSERTs by opting to not update the FSM at this point. The - * free space should be reused by UPDATEs to *this* page. + * RecordPageWithFreeSpace() only dirties the FSM when the recorded + * free-space category actually changes. Note that vacuum will still + * do FreeSpaceMapVacuum() for ranges of pages that are skipped, so we + * don't have to worry about that here. */ + if (record_free_space) + RecordPageWithFreeSpace(relation, BufferGetBlockNumber(buffer), freespace); } } From a474c01c87661f85827736dc8cfc353fd63c6ecf Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Sat, 11 Jul 2026 15:14:50 +0200 Subject: [PATCH 142/481] Shorten pg_attribute_always_inline to pg_always_inline The pg_attribute_always_inline macro name is so long it forces pgindent to format the code in strange ways. Which may incentivize patch authors to either structure the code in strange ways (e.g. reorder prototypes), use shorter names, etc. Neither is very desirable for code readability. This shortens the name by removing the _attribute_ part. It also makes it more consistent with pg_noinline, which does not have the _attribute_ part either. Backpatched to all supported branches, to prevent conflicts when backpatching other fixes. The backbranches however keep both the old and new macro name, so that existing code keeps working. Author: Andres Freund Reviewed-by: Peter Geoghegan Reviewed-by: Tomas Vondra Discussion: https://postgr.es/m/bqqdehahpoa36igpictuqyn2s2mexk3t3ehidh2ffd2slb35e5@rzgksuiszgbg Backpatch-through: 14 --- src/backend/access/heap/heapam.c | 2 +- src/backend/access/transam/xlog.c | 4 +- src/backend/commands/copyfromparse.c | 32 ++++++++-------- src/backend/commands/copyto.c | 4 +- src/backend/executor/execExprInterp.c | 54 +++++++++++++-------------- src/backend/executor/execTuples.c | 6 +-- src/backend/executor/nodeHashjoin.c | 2 +- src/backend/executor/nodeSeqscan.c | 4 +- src/backend/nodes/queryjumblefuncs.c | 6 +-- src/backend/storage/buffer/bufmgr.c | 24 ++++++------ src/backend/utils/adt/json.c | 2 +- src/backend/utils/cache/catcache.c | 2 +- src/include/c.h | 9 ++++- src/include/executor/execScan.h | 18 ++++----- src/include/portability/instr_time.h | 8 ++-- 15 files changed, 92 insertions(+), 85 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index abfd8e8970a..4f373b86028 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -519,7 +519,7 @@ heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk, BlockNumber numBlk * multiple times, with constant arguments for all_visible, * check_serializable. */ -pg_attribute_always_inline +pg_always_inline static int page_collect_tuples(HeapScanDesc scan, Snapshot snapshot, Page page, Buffer buffer, diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index a81912b7441..254bb158565 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -1143,9 +1143,9 @@ XLogInsertRecord(XLogRecData *rdata, * * NB: Testing shows that XLogInsertRecord runs faster if this code is inlined; * however, because there are two call sites, the compiler is reluctant to - * inline. We use pg_attribute_always_inline here to try to convince it. + * inline. We use pg_always_inline here to try to convince it. */ -static pg_attribute_always_inline void +static pg_always_inline void ReserveXLogInsertLocation(int size, XLogRecPtr *StartPos, XLogRecPtr *EndPos, XLogRecPtr *PrevPtr) { diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c index 65fd5a0ab4f..500810577ad 100644 --- a/src/backend/commands/copyfromparse.c +++ b/src/backend/commands/copyfromparse.c @@ -144,22 +144,22 @@ static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0"; /* non-export function prototypes */ static bool CopyReadLine(CopyFromState cstate, bool is_csv); -static pg_attribute_always_inline bool CopyReadLineText(CopyFromState cstate, - bool is_csv); +static pg_always_inline bool CopyReadLineText(CopyFromState cstate, + bool is_csv); static int CopyReadAttributesText(CopyFromState cstate); static int CopyReadAttributesCSV(CopyFromState cstate); static Datum CopyReadBinaryAttribute(CopyFromState cstate, FmgrInfo *flinfo, Oid typioparam, int32 typmod, bool *isnull); -static pg_attribute_always_inline bool CopyFromTextLikeOneRow(CopyFromState cstate, - ExprContext *econtext, - Datum *values, - bool *nulls, - bool is_csv); -static pg_attribute_always_inline bool NextCopyFromRawFieldsInternal(CopyFromState cstate, - char ***fields, - int *nfields, - bool is_csv); +static pg_always_inline bool CopyFromTextLikeOneRow(CopyFromState cstate, + ExprContext *econtext, + Datum *values, + bool *nulls, + bool is_csv); +static pg_always_inline bool NextCopyFromRawFieldsInternal(CopyFromState cstate, + char ***fields, + int *nfields, + bool is_csv); /* Low-level communications functions */ @@ -769,11 +769,11 @@ NextCopyFromRawFields(CopyFromState cstate, char ***fields, int *nfields) * * NOTE: force_not_null option are not applied to the returned fields. * - * We use pg_attribute_always_inline to reduce function call overhead + * We use pg_always_inline to reduce function call overhead * and to help compilers to optimize away the 'is_csv' condition when called * by internal functions such as CopyFromTextLikeOneRow(). */ -static pg_attribute_always_inline bool +static pg_always_inline bool NextCopyFromRawFieldsInternal(CopyFromState cstate, char ***fields, int *nfields, bool is_csv) { int fldct; @@ -946,10 +946,10 @@ CopyFromCSVOneRow(CopyFromState cstate, ExprContext *econtext, Datum *values, /* * Workhorse for CopyFromTextOneRow() and CopyFromCSVOneRow(). * - * We use pg_attribute_always_inline to reduce function call overhead + * We use pg_always_inline to reduce function call overhead * and to help compilers to optimize away the 'is_csv' condition. */ -static pg_attribute_always_inline bool +static pg_always_inline bool CopyFromTextLikeOneRow(CopyFromState cstate, ExprContext *econtext, Datum *values, bool *nulls, bool is_csv) { @@ -1463,7 +1463,7 @@ CopyReadLineTextSIMDHelper(CopyFromState cstate, bool is_csv, /* * CopyReadLineText - inner loop of CopyReadLine for text mode */ -static pg_attribute_always_inline bool +static pg_always_inline bool CopyReadLineText(CopyFromState cstate, bool is_csv) { char *copy_input_buf; diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c index d3adc752ae3..f9bc617ddb1 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -294,10 +294,10 @@ CopyToCSVOneRow(CopyToState cstate, TupleTableSlot *slot) /* * Workhorse for CopyToTextOneRow() and CopyToCSVOneRow(). * - * We use pg_attribute_always_inline to reduce function call overhead + * We use pg_always_inline to reduce function call overhead * and to help compilers to optimize away the 'is_csv' condition. */ -static pg_attribute_always_inline void +static pg_always_inline void CopyToTextLikeOneRow(CopyToState cstate, TupleTableSlot *slot, bool is_csv) diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index 0634af964a9..d45812c23aa 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -178,24 +178,24 @@ static Datum ExecJustHashInnerVarVirt(ExprState *state, ExprContext *econtext, b static Datum ExecJustHashOuterVarStrict(ExprState *state, ExprContext *econtext, bool *isnull); /* execution helper functions */ -static pg_attribute_always_inline void ExecEvalArrayCompareInternal(FunctionCallInfo fcinfo, - ArrayType *arr, - int16 typlen, - bool typbyval, - char typalign, - bool useOr, - Datum *result, - bool *resultnull); -static pg_attribute_always_inline void ExecAggPlainTransByVal(AggState *aggstate, - AggStatePerTrans pertrans, - AggStatePerGroup pergroup, - ExprContext *aggcontext, - int setno); -static pg_attribute_always_inline void ExecAggPlainTransByRef(AggState *aggstate, - AggStatePerTrans pertrans, - AggStatePerGroup pergroup, - ExprContext *aggcontext, - int setno); +static pg_always_inline void ExecEvalArrayCompareInternal(FunctionCallInfo fcinfo, + ArrayType *arr, + int16 typlen, + bool typbyval, + char typalign, + bool useOr, + Datum *result, + bool *resultnull); +static pg_always_inline void ExecAggPlainTransByVal(AggState *aggstate, + AggStatePerTrans pertrans, + AggStatePerGroup pergroup, + ExprContext *aggcontext, + int setno); +static pg_always_inline void ExecAggPlainTransByRef(AggState *aggstate, + AggStatePerTrans pertrans, + AggStatePerGroup pergroup, + ExprContext *aggcontext, + int setno); static char *ExecGetJsonValueItemString(JsonbValue *item, bool *resnull); /* @@ -2552,7 +2552,7 @@ get_cached_rowtype(Oid type_id, int32 typmod, */ /* implementation of ExecJust(Inner|Outer|Scan)Var */ -static pg_attribute_always_inline Datum +static pg_always_inline Datum ExecJustVarImpl(ExprState *state, TupleTableSlot *slot, bool *isnull) { ExprEvalStep *op = &state->steps[1]; @@ -2590,7 +2590,7 @@ ExecJustScanVar(ExprState *state, ExprContext *econtext, bool *isnull) } /* implementation of ExecJustAssign(Inner|Outer|Scan)Var */ -static pg_attribute_always_inline Datum +static pg_always_inline Datum ExecJustAssignVarImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull) { ExprEvalStep *op = &state->steps[1]; @@ -2685,7 +2685,7 @@ ExecJustConst(ExprState *state, ExprContext *econtext, bool *isnull) } /* implementation of ExecJust(Inner|Outer|Scan)VarVirt */ -static pg_attribute_always_inline Datum +static pg_always_inline Datum ExecJustVarVirtImpl(ExprState *state, TupleTableSlot *slot, bool *isnull) { ExprEvalStep *op = &state->steps[0]; @@ -2728,7 +2728,7 @@ ExecJustScanVarVirt(ExprState *state, ExprContext *econtext, bool *isnull) } /* implementation of ExecJustAssign(Inner|Outer|Scan)VarVirt */ -static pg_attribute_always_inline Datum +static pg_always_inline Datum ExecJustAssignVarVirtImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull) { ExprEvalStep *op = &state->steps[0]; @@ -2807,7 +2807,7 @@ ExecJustHashInnerVarWithIV(ExprState *state, ExprContext *econtext, } /* implementation of ExecJustHash(Inner|Outer)Var */ -static pg_attribute_always_inline Datum +static pg_always_inline Datum ExecJustHashVarImpl(ExprState *state, TupleTableSlot *slot, bool *isnull) { ExprEvalStep *fetchop = &state->steps[0]; @@ -2845,7 +2845,7 @@ ExecJustHashInnerVar(ExprState *state, ExprContext *econtext, bool *isnull) } /* implementation of ExecJustHash(Inner|Outer)VarVirt */ -static pg_attribute_always_inline Datum +static pg_always_inline Datum ExecJustHashVarVirtImpl(ExprState *state, TupleTableSlot *slot, bool *isnull) { ExprEvalStep *var = &state->steps[0]; @@ -4107,7 +4107,7 @@ ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op) * Callers must handle the strict LHS-is-NULL; return NULL fast path prior to * calling this. */ -static pg_attribute_always_inline void +static pg_always_inline void ExecEvalArrayCompareInternal(FunctionCallInfo fcinfo, ArrayType *arr, int16 typlen, bool typbyval, char typalign, bool useOr, Datum *result, bool *resultnull) @@ -5906,7 +5906,7 @@ ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op, } /* implementation of transition function invocation for byval types */ -static pg_attribute_always_inline void +static pg_always_inline void ExecAggPlainTransByVal(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup, ExprContext *aggcontext, int setno) @@ -5938,7 +5938,7 @@ ExecAggPlainTransByVal(AggState *aggstate, AggStatePerTrans pertrans, } /* implementation of transition function invocation for byref types */ -static pg_attribute_always_inline void +static pg_always_inline void ExecAggPlainTransByRef(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup, ExprContext *aggcontext, int setno) diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 7f4ebf95432..97ae019d10a 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -72,8 +72,8 @@ static TupleDesc ExecTypeFromTLInternal(List *targetList, bool skipjunk); -static pg_attribute_always_inline void slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp, - int reqnatts, bool support_cstring); +static pg_always_inline void slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp, + int reqnatts, bool support_cstring); static inline void tts_buffer_heap_store_tuple(TupleTableSlot *slot, HeapTuple tuple, Buffer buffer, @@ -1013,7 +1013,7 @@ tts_buffer_heap_store_tuple(TupleTableSlot *slot, HeapTuple tuple, * emit code during inlining for cstring deforming when it's required. * cstrings can exist in MinimalTuples, but not in HeapTuples. */ -static pg_attribute_always_inline void +static pg_always_inline void slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp, int reqnatts, bool support_cstring) { diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index 0b365d5b475..202dd866251 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -221,7 +221,7 @@ static void ExecParallelHashJoinPartitionOuter(HashJoinState *hjstate); * the other one is "outer". * ---------------------------------------------------------------- */ -static pg_attribute_always_inline TupleTableSlot * +static pg_always_inline TupleTableSlot * ExecHashJoinImpl(PlanState *pstate, bool parallel) { HashJoinState *node = castNode(HashJoinState, pstate); diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c index 5bcb0a861d7..b8c528ca089 100644 --- a/src/backend/executor/nodeSeqscan.c +++ b/src/backend/executor/nodeSeqscan.c @@ -48,7 +48,7 @@ static TupleTableSlot *SeqNext(SeqScanState *node); * This is a workhorse for ExecSeqScan * ---------------------------------------------------------------- */ -static pg_attribute_always_inline TupleTableSlot * +static pg_always_inline TupleTableSlot * SeqNext(SeqScanState *node) { TableScanDesc scandesc; @@ -95,7 +95,7 @@ SeqNext(SeqScanState *node) /* * SeqRecheck -- access method routine to recheck a tuple in EvalPlanQual */ -static pg_attribute_always_inline bool +static pg_always_inline bool SeqRecheck(SeqScanState *node, TupleTableSlot *slot) { /* diff --git a/src/backend/nodes/queryjumblefuncs.c b/src/backend/nodes/queryjumblefuncs.c index 7c63766a51c..2ce27b9e552 100644 --- a/src/backend/nodes/queryjumblefuncs.c +++ b/src/backend/nodes/queryjumblefuncs.c @@ -232,7 +232,7 @@ DoJumble(JumbleState *jstate, Node *node) * * Note: Callers must ensure that size > 0. */ -static pg_attribute_always_inline void +static pg_always_inline void AppendJumbleInternal(JumbleState *jstate, const unsigned char *item, Size size) { @@ -308,7 +308,7 @@ AppendJumble(JumbleState *jstate, const unsigned char *value, Size size) * AppendJumbleNull * For jumbling NULL pointers */ -static pg_attribute_always_inline void +static pg_always_inline void AppendJumbleNull(JumbleState *jstate) { jstate->pending_nulls++; @@ -375,7 +375,7 @@ AppendJumble64(JumbleState *jstate, const unsigned char *value) * * Note: Callers must ensure that there's at least 1 pending NULL. */ -static pg_attribute_always_inline void +static pg_always_inline void FlushPendingNulls(JumbleState *jstate) { Assert(jstate->pending_nulls > 0); diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 9ab282a76d1..3908529872a 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -649,10 +649,10 @@ static inline BufferDesc *BufferAlloc(SMgrRelation smgr, static bool AsyncReadBuffers(ReadBuffersOperation *operation, int *nblocks_progress); static void CheckReadBuffersOperation(ReadBuffersOperation *operation, bool is_complete); -static pg_attribute_always_inline void TrackBufferHit(IOObject io_object, - IOContext io_context, - Relation rel, char persistence, SMgrRelation smgr, - ForkNumber forknum, BlockNumber blocknum); +static pg_always_inline void TrackBufferHit(IOObject io_object, + IOContext io_context, + Relation rel, char persistence, SMgrRelation smgr, + ForkNumber forknum, BlockNumber blocknum); static Buffer GetVictimBuffer(BufferAccessStrategy strategy, IOContext io_context); static void FlushUnlockedBuffer(BufferDesc *buf, SMgrRelation reln, IOObject io_object, IOContext io_context); @@ -1219,7 +1219,7 @@ ZeroAndLockBuffer(Buffer buffer, ReadBufferMode mode, bool already_valid) * already present, or false if more work is required to either read it in or * zero it. */ -static pg_attribute_always_inline Buffer +static pg_always_inline Buffer PinBufferForBlock(Relation rel, SMgrRelation smgr, char persistence, @@ -1272,7 +1272,7 @@ PinBufferForBlock(Relation rel, * * smgr is required, rel is optional unless using P_NEW. */ -static pg_attribute_always_inline Buffer +static pg_always_inline Buffer ReadBuffer_common(Relation rel, SMgrRelation smgr, char smgr_persistence, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, @@ -1367,7 +1367,7 @@ ReadBuffer_common(Relation rel, SMgrRelation smgr, char smgr_persistence, return buffer; } -static pg_attribute_always_inline bool +static pg_always_inline bool StartReadBuffersImpl(ReadBuffersOperation *operation, Buffer *buffers, BlockNumber blockNum, @@ -1679,7 +1679,7 @@ CheckReadBuffersOperation(ReadBuffersOperation *operation, bool is_complete) * We track various stats related to buffer hits. Because this is done in a * few separate places, this helper exists for convenience. */ -static pg_attribute_always_inline void +static pg_always_inline void TrackBufferHit(IOObject io_object, IOContext io_context, Relation rel, char persistence, SMgrRelation smgr, ForkNumber forknum, BlockNumber blocknum) @@ -2193,7 +2193,7 @@ AsyncReadBuffers(ReadBuffersOperation *operation, int *nblocks_progress) * * No locks are held either at entry or exit. */ -static pg_attribute_always_inline BufferDesc * +static pg_always_inline BufferDesc * BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, BlockNumber blockNum, BufferAccessStrategy strategy, @@ -8326,7 +8326,7 @@ MarkDirtyAllUnpinnedBuffers(int32 *buffers_dirtied, * part of error handling, which in turn could lead to the buffer being * replaced while IO is ongoing. */ -static pg_attribute_always_inline void +static pg_always_inline void buffer_stage_common(PgAioHandle *ioh, bool is_write, bool is_temp) { uint64 *io_data; @@ -8570,7 +8570,7 @@ buffer_readv_encode_error(PgAioResult *result, * Helper for AIO readv completion callbacks, supporting both shared and temp * buffers. Gets called once for each buffer in a multi-page read. */ -static pg_attribute_always_inline void +static pg_always_inline void buffer_readv_complete_one(PgAioTargetData *td, uint8 buf_off, Buffer buffer, uint8 flags, bool failed, bool is_temp, bool *buffer_invalid, @@ -8721,7 +8721,7 @@ buffer_readv_complete_one(PgAioTargetData *td, uint8 buf_off, Buffer buffer, * * Shared between shared and local buffers, to reduce code duplication. */ -static pg_attribute_always_inline PgAioResult +static pg_always_inline PgAioResult buffer_readv_complete(PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_data, bool is_temp) { diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c index 0fee1b40d63..dccbe07cd2d 100644 --- a/src/backend/utils/adt/json.c +++ b/src/backend/utils/adt/json.c @@ -1528,7 +1528,7 @@ json_object_two_arg(PG_FUNCTION_ARGS) * escape_json_char * Inline helper function for escape_json* functions */ -static pg_attribute_always_inline void +static pg_always_inline void escape_json_char(StringInfo buf, char c) { switch (c) diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 6fb35dedf95..0c8955fc61a 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -1091,7 +1091,7 @@ RehashCatCacheLists(CatCache *cp) * * Call CatalogCacheInitializeCache() if not yet done. */ -pg_attribute_always_inline +pg_always_inline static void ConditionalCatalogCacheInitializeCache(CatCache *cache) { diff --git a/src/include/c.h b/src/include/c.h index f32989a6331..c641f004eff 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -289,19 +289,26 @@ extern "C++" #endif /* - * Use "pg_attribute_always_inline" in place of "inline" for functions that + * Use "pg_always_inline" in place of "inline" for functions that * we wish to force inlining of, even when the compiler's heuristics would * choose not to. But, if possible, don't force inlining in unoptimized * debug builds. + * + * XXX The "pg_attribute_always_inline" variant is kept for backwards + * compatibility with existing code. All new code should use the shorter + * variant "pg_always_inline." */ #if defined(__GNUC__) && defined(__OPTIMIZE__) /* GCC supports always_inline via __attribute__ */ +#define pg_always_inline __attribute__((always_inline)) inline #define pg_attribute_always_inline __attribute__((always_inline)) inline #elif defined(_MSC_VER) /* MSVC has a special keyword for this */ +#define pg_always_inline __forceinline #define pg_attribute_always_inline __forceinline #else /* Otherwise, the best we can do is to say "inline" */ +#define pg_always_inline inline #define pg_attribute_always_inline inline #endif diff --git a/src/include/executor/execScan.h b/src/include/executor/execScan.h index 18b03235c3c..25efc622f88 100644 --- a/src/include/executor/execScan.h +++ b/src/include/executor/execScan.h @@ -24,12 +24,12 @@ * This routine substitutes a test tuple if inside an EvalPlanQual recheck. * Otherwise, it simply executes the access method's next-tuple routine. * - * The pg_attribute_always_inline attribute allows the compiler to inline - * this function into its caller. When EPQState is NULL, the EvalPlanQual - * logic is completely eliminated at compile time, avoiding unnecessary - * run-time checks and code for cases where EPQ is not required. + * The pg_always_inline attribute allows the compiler to inline this function + * into its caller. When EPQState is NULL, the EvalPlanQual logic is completely + * eliminated at compile time, avoiding unnecessary run-time checks and code + * for cases where EPQ is not required. */ -static pg_attribute_always_inline TupleTableSlot * +static pg_always_inline TupleTableSlot * ExecScanFetch(ScanState *node, EPQState *epqstate, ExecScanAccessMtd accessMtd, @@ -145,9 +145,9 @@ ExecScanFetch(ScanState *node, * conditions enforced by the access method. * * This function is an alternative to ExecScan, used when callers may omit - * 'qual' or 'projInfo'. The pg_attribute_always_inline attribute allows the - * compiler to eliminate non-relevant branches at compile time, avoiding - * run-time checks in those cases. + * 'qual' or 'projInfo'. The pg_always_inline attribute allows the compiler + * to eliminate non-relevant branches at compile time, avoiding run-time + * checks in those cases. * * Conditions: * -- The AMI "cursor" is positioned at the previously returned tuple. @@ -157,7 +157,7 @@ ExecScanFetch(ScanState *node, * positioned before the first qualifying tuple. * ---------------------------------------------------------------- */ -static pg_attribute_always_inline TupleTableSlot * +static pg_always_inline TupleTableSlot * ExecScanExtended(ScanState *node, ExecScanAccessMtd accessMtd, /* function returning a tuple */ ExecScanRecheckMtd recheckMtd, diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h index 655f8737b6f..650770754d5 100644 --- a/src/include/portability/instr_time.h +++ b/src/include/portability/instr_time.h @@ -376,7 +376,7 @@ pg_rdtscp(void) * only inlining the function partially. * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124795 */ -static pg_attribute_always_inline instr_time +static pg_always_inline instr_time pg_get_ticks(void) { if (likely(timing_tsc_enabled)) @@ -390,7 +390,7 @@ pg_get_ticks(void) return pg_get_ticks_system(); } -static pg_attribute_always_inline instr_time +static pg_always_inline instr_time pg_get_ticks_fast(void) { if (likely(timing_tsc_enabled)) @@ -406,13 +406,13 @@ pg_get_ticks_fast(void) #else -static pg_attribute_always_inline instr_time +static pg_always_inline instr_time pg_get_ticks(void) { return pg_get_ticks_system(); } -static pg_attribute_always_inline instr_time +static pg_always_inline instr_time pg_get_ticks_fast(void) { return pg_get_ticks_system(); From 8055e3375aa1c2237181e06be26b05b964d18ed5 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 13 Jul 2026 12:03:36 +0200 Subject: [PATCH 143/481] Translation updates Source-Git-URL: https://git.postgresql.org/git/pgtranslation/messages.git Source-Git-Hash: 2ef2c86b2592e8a199edc86779bc44cfdb258971 --- src/backend/po/de.po | 7705 ++++++++++++++------------ src/backend/po/ja.po | 5696 ++++++++++--------- src/backend/po/ka.po | 1333 ----- src/bin/initdb/po/ka.po | 15 - src/bin/pg_archivecleanup/po/de.po | 21 +- src/bin/pg_archivecleanup/po/ja.po | 26 +- src/bin/pg_archivecleanup/po/ka.po | 31 +- src/bin/pg_basebackup/po/de.po | 212 +- src/bin/pg_basebackup/po/ja.po | 485 +- src/bin/pg_basebackup/po/ka.po | 648 +-- src/bin/pg_combinebackup/po/de.po | 170 +- src/bin/pg_combinebackup/po/ja.po | 166 +- src/bin/pg_combinebackup/po/ka.po | 222 +- src/bin/pg_config/po/ka.po | 11 - src/bin/pg_controldata/po/ka.po | 23 - src/bin/pg_ctl/po/ka.po | 19 - src/bin/pg_dump/po/de.po | 779 ++- src/bin/pg_dump/po/ja.po | 996 ++-- src/bin/pg_dump/po/ka.po | 970 ++-- src/bin/pg_resetwal/po/ka.po | 63 - src/bin/pg_rewind/po/de.po | 220 +- src/bin/pg_rewind/po/ja.po | 125 +- src/bin/pg_rewind/po/ka.po | 167 +- src/bin/pg_test_timing/po/de.po | 26 +- src/bin/pg_test_timing/po/ja.po | 208 +- src/bin/pg_test_timing/po/ka.po | 17 +- src/bin/pg_upgrade/po/de.po | 16 +- src/bin/pg_upgrade/po/ja.po | 688 ++- src/bin/pg_upgrade/po/ka.po | 164 +- src/bin/pg_verifybackup/po/ka.po | 22 - src/bin/pg_waldump/po/ka.po | 25 - src/bin/psql/po/de.po | 915 ++- src/bin/psql/po/ja.po | 1093 ++-- src/bin/psql/po/ka.po | 271 +- src/bin/scripts/po/de.po | 133 +- src/bin/scripts/po/ja.po | 133 +- src/bin/scripts/po/ka.po | 193 +- src/interfaces/ecpg/preproc/po/ka.po | 3 - src/interfaces/libpq/po/de.po | 274 +- src/interfaces/libpq/po/ja.po | 274 +- src/interfaces/libpq/po/ka.po | 393 +- src/pl/plperl/po/ka.po | 3 - src/pl/plpgsql/src/po/ka.po | 3 - src/pl/plpython/po/de.po | 122 +- src/pl/plpython/po/ja.po | 120 +- src/pl/plpython/po/ka.po | 152 +- src/pl/tcl/po/ka.po | 3 - 47 files changed, 11699 insertions(+), 13655 deletions(-) diff --git a/src/backend/po/de.po b/src/backend/po/de.po index 49ae067d375..119a4d2b9a3 100644 --- a/src/backend/po/de.po +++ b/src/backend/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-04-23 06:41+0000\n" -"PO-Revision-Date: 2026-04-23 12:31+0200\n" +"POT-Creation-Date: 2026-07-09 08:41+0000\n" +"PO-Revision-Date: 2026-07-09 12:08+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -80,7 +80,7 @@ msgid "not recorded" msgstr "nicht aufgezeichnet" #: ../common/controldata_utils.c:94 ../common/controldata_utils.c:98 -#: commands/copyfrom.c:1907 commands/extension.c:4023 utils/adt/genfile.c:123 +#: commands/copyfrom.c:1903 commands/extension.c:4025 utils/adt/genfile.c:123 #: utils/time/snapmgr.c:1450 #, c-format msgid "could not open file \"%s\" for reading: %m" @@ -88,15 +88,15 @@ msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" #: ../common/controldata_utils.c:109 ../common/controldata_utils.c:111 #: access/transam/timeline.c:144 access/transam/timeline.c:363 -#: access/transam/twophase.c:1367 access/transam/xlog.c:3537 -#: access/transam/xlog.c:4435 access/transam/xlogrecovery.c:1197 +#: access/transam/twophase.c:1367 access/transam/xlog.c:3533 +#: access/transam/xlog.c:4431 access/transam/xlogrecovery.c:1197 #: access/transam/xlogrecovery.c:1295 access/transam/xlogrecovery.c:1332 -#: access/transam/xlogrecovery.c:1399 backup/basebackup.c:2147 -#: backup/walsummary.c:283 commands/extension.c:4033 libpq/hba.c:765 +#: access/transam/xlogrecovery.c:1399 backup/basebackup.c:2145 +#: backup/walsummary.c:283 commands/extension.c:4035 libpq/hba.c:765 #: replication/logical/origin.c:786 replication/logical/origin.c:814 -#: replication/logical/reorderbuffer.c:5394 -#: replication/logical/snapbuild.c:2011 replication/slot.c:2751 -#: replication/slot.c:2792 replication/walsender.c:671 +#: replication/logical/reorderbuffer.c:5392 +#: replication/logical/snapbuild.c:1955 replication/slot.c:2747 +#: replication/slot.c:2788 replication/walsender.c:678 #: storage/file/buffile.c:471 storage/file/copydir.c:202 #: utils/adt/genfile.c:197 utils/adt/misc.c:1001 utils/cache/relmapper.c:830 #, c-format @@ -104,10 +104,10 @@ msgid "could not read file \"%s\": %m" msgstr "konnte Datei »%s« nicht lesen: %m" #: ../common/controldata_utils.c:117 ../common/controldata_utils.c:120 -#: access/transam/xlog.c:3542 access/transam/xlog.c:4440 +#: access/transam/xlog.c:3538 access/transam/xlog.c:4436 #: replication/logical/origin.c:791 replication/logical/origin.c:829 -#: replication/logical/snapbuild.c:2016 replication/slot.c:2755 -#: replication/slot.c:2796 replication/walsender.c:676 +#: replication/logical/snapbuild.c:1960 replication/slot.c:2751 +#: replication/slot.c:2792 replication/walsender.c:683 #: utils/cache/relmapper.c:834 #, c-format msgid "could not read file \"%s\": read %d of %zu" @@ -119,14 +119,14 @@ msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" #: access/transam/slru.c:1157 access/transam/timeline.c:393 #: access/transam/timeline.c:439 access/transam/timeline.c:513 #: access/transam/twophase.c:1379 access/transam/twophase.c:1805 -#: access/transam/xlog.c:3383 access/transam/xlog.c:3577 -#: access/transam/xlog.c:3582 access/transam/xlog.c:3718 -#: access/transam/xlog.c:4405 access/transam/xlog.c:5690 -#: commands/copyfrom.c:1957 commands/copyto.c:740 libpq/be-fsstubs.c:475 +#: access/transam/xlog.c:3379 access/transam/xlog.c:3573 +#: access/transam/xlog.c:3578 access/transam/xlog.c:3714 +#: access/transam/xlog.c:4401 access/transam/xlog.c:5690 +#: commands/copyfrom.c:1953 commands/copyto.c:758 libpq/be-fsstubs.c:475 #: libpq/be-fsstubs.c:545 replication/logical/origin.c:724 -#: replication/logical/origin.c:862 replication/logical/reorderbuffer.c:5446 -#: replication/logical/snapbuild.c:1756 replication/logical/snapbuild.c:1882 -#: replication/slot.c:2637 replication/slot.c:2803 replication/walsender.c:686 +#: replication/logical/origin.c:862 replication/logical/reorderbuffer.c:5444 +#: replication/logical/snapbuild.c:1700 replication/logical/snapbuild.c:1826 +#: replication/slot.c:2633 replication/slot.c:2799 replication/walsender.c:693 #: storage/file/copydir.c:225 storage/file/copydir.c:230 #: storage/file/copydir.c:285 storage/file/copydir.c:290 storage/file/fd.c:829 #: storage/file/fd.c:3803 storage/file/fd.c:3909 utils/cache/relmapper.c:842 @@ -159,18 +159,18 @@ msgstr "" #: access/heap/rewriteheap.c:1232 access/transam/slru.c:1111 #: access/transam/timeline.c:112 access/transam/timeline.c:252 #: access/transam/timeline.c:349 access/transam/twophase.c:1323 -#: access/transam/xlog.c:3273 access/transam/xlog.c:3453 -#: access/transam/xlog.c:3492 access/transam/xlog.c:3685 -#: access/transam/xlog.c:4425 access/transam/xlogrecovery.c:4271 -#: access/transam/xlogrecovery.c:4372 access/transam/xlogutils.c:825 -#: backup/basebackup.c:553 backup/basebackup.c:1602 backup/walsummary.c:220 -#: libpq/hba.c:622 postmaster/syslogger.c:1512 replication/logical/origin.c:776 -#: replication/logical/reorderbuffer.c:4051 -#: replication/logical/reorderbuffer.c:4605 -#: replication/logical/reorderbuffer.c:5374 -#: replication/logical/snapbuild.c:1711 replication/logical/snapbuild.c:1823 -#: replication/slot.c:2723 replication/walsender.c:644 -#: replication/walsender.c:3300 storage/file/copydir.c:168 +#: access/transam/xlog.c:3269 access/transam/xlog.c:3449 +#: access/transam/xlog.c:3488 access/transam/xlog.c:3681 +#: access/transam/xlog.c:4421 access/transam/xlogrecovery.c:4276 +#: access/transam/xlogrecovery.c:4377 access/transam/xlogutils.c:849 +#: backup/basebackup.c:553 backup/basebackup.c:1600 backup/walsummary.c:220 +#: libpq/hba.c:622 postmaster/syslogger.c:1531 replication/logical/origin.c:776 +#: replication/logical/reorderbuffer.c:4049 +#: replication/logical/reorderbuffer.c:4603 +#: replication/logical/reorderbuffer.c:5372 +#: replication/logical/snapbuild.c:1655 replication/logical/snapbuild.c:1767 +#: replication/slot.c:2719 replication/walsender.c:651 +#: replication/walsender.c:3329 storage/file/copydir.c:168 #: storage/file/copydir.c:256 storage/file/fd.c:804 storage/file/fd.c:3560 #: storage/file/fd.c:3790 storage/file/fd.c:3880 storage/smgr/md.c:697 #: utils/cache/relmapper.c:819 utils/cache/relmapper.c:936 @@ -183,11 +183,11 @@ msgstr "konnte Datei »%s« nicht öffnen: %m" #: ../common/controldata_utils.c:247 ../common/controldata_utils.c:250 #: access/transam/twophase.c:1778 access/transam/twophase.c:1787 -#: access/transam/xlog.c:9963 access/transam/xlogfuncs.c:718 +#: access/transam/xlog.c:9951 access/transam/xlogfuncs.c:718 #: backup/basebackup_server.c:173 backup/basebackup_server.c:266 #: backup/walsummary.c:304 postmaster/postmaster.c:4155 -#: postmaster/syslogger.c:1523 postmaster/syslogger.c:1536 -#: postmaster/syslogger.c:1549 utils/cache/relmapper.c:948 +#: postmaster/syslogger.c:1542 postmaster/syslogger.c:1555 +#: postmaster/syslogger.c:1568 utils/cache/relmapper.c:948 #, c-format msgid "could not write file \"%s\": %m" msgstr "konnte Datei »%s« nicht schreiben: %m" @@ -197,12 +197,12 @@ msgstr "konnte Datei »%s« nicht schreiben: %m" #: access/heap/rewriteheap.c:928 access/heap/rewriteheap.c:1138 #: access/heap/rewriteheap.c:1243 access/transam/slru.c:1150 #: access/transam/timeline.c:433 access/transam/timeline.c:507 -#: access/transam/twophase.c:1799 access/transam/xlog.c:3373 -#: access/transam/xlog.c:3571 access/transam/xlog.c:4398 -#: access/transam/xlog.c:9356 access/transam/xlog.c:9400 +#: access/transam/twophase.c:1799 access/transam/xlog.c:3369 +#: access/transam/xlog.c:3567 access/transam/xlog.c:4394 +#: access/transam/xlog.c:9344 access/transam/xlog.c:9388 #: backup/basebackup_server.c:207 commands/dbcommands.c:518 -#: replication/logical/snapbuild.c:1749 replication/slot.c:2621 -#: replication/slot.c:2733 storage/file/fd.c:821 storage/file/fd.c:3901 +#: replication/logical/snapbuild.c:1693 replication/slot.c:2617 +#: replication/slot.c:2729 storage/file/fd.c:821 storage/file/fd.c:3901 #: storage/smgr/md.c:1480 storage/smgr/md.c:1540 storage/sync/sync.c:447 #: utils/misc/guc.c:4428 #, c-format @@ -215,30 +215,30 @@ msgstr "konnte Datei »%s« nicht fsyncen: %m" #: ../common/hmac_openssl.c:151 ../common/hmac_openssl.c:339 #: ../common/jsonapi.c:2459 ../common/md5_common.c:156 #: ../common/parse_manifest.c:157 ../common/parse_manifest.c:852 -#: ../common/psprintf.c:140 ../common/scram-common.c:268 ../port/path.c:829 -#: ../port/path.c:866 ../port/path.c:883 access/transam/twophase.c:1432 -#: access/transam/xlogrecovery.c:509 lib/dshash.c:257 libpq/auth.c:1358 -#: libpq/auth.c:1402 libpq/auth.c:1973 libpq/be-secure-gssapi.c:539 +#: ../common/psprintf.c:140 ../common/scram-common.c:268 ../port/path.c:846 +#: ../port/path.c:883 ../port/path.c:900 access/transam/twophase.c:1432 +#: access/transam/xlogrecovery.c:509 lib/dshash.c:257 libpq/auth.c:1391 +#: libpq/auth.c:1435 libpq/auth.c:2006 libpq/be-secure-gssapi.c:539 #: libpq/be-secure-gssapi.c:719 postmaster/bgworker.c:381 #: postmaster/bgworker.c:1045 postmaster/postmaster.c:3615 #: postmaster/walsummarizer.c:935 #: replication/libpqwalreceiver/libpqwalreceiver.c:367 -#: replication/logical/logical.c:201 replication/walsender.c:853 +#: replication/logical/logical.c:201 replication/walsender.c:860 #: storage/buffer/localbuf.c:778 storage/file/fd.c:913 storage/file/fd.c:1431 #: storage/file/fd.c:1592 storage/file/fd.c:2576 storage/ipc/procarray.c:1456 -#: storage/ipc/procarray.c:2156 storage/ipc/procarray.c:2163 -#: storage/ipc/procarray.c:2668 storage/ipc/procarray.c:3408 +#: storage/ipc/procarray.c:2156 storage/ipc/procarray.c:2170 +#: storage/ipc/procarray.c:2674 storage/ipc/procarray.c:3395 #: utils/activity/pgstat_shmem.c:549 utils/adt/pg_locale.c:491 -#: utils/adt/pg_locale.c:565 utils/adt/pg_locale_icu.c:580 -#: utils/adt/pg_locale_libc.c:512 utils/adt/pg_locale_libc.c:617 -#: utils/adt/pg_locale_libc.c:710 utils/fmgr/dfmgr.c:234 +#: utils/adt/pg_locale.c:565 utils/adt/pg_locale_icu.c:595 +#: utils/adt/pg_locale_libc.c:556 utils/adt/pg_locale_libc.c:655 +#: utils/adt/pg_locale_libc.c:742 utils/fmgr/dfmgr.c:234 #: utils/hash/dynahash.c:535 utils/hash/dynahash.c:615 #: utils/hash/dynahash.c:1031 utils/mb/mbutils.c:410 utils/mb/mbutils.c:438 #: utils/mb/mbutils.c:825 utils/mb/mbutils.c:852 utils/misc/guc.c:646 #: utils/misc/guc.c:671 utils/misc/guc.c:941 utils/misc/guc.c:4406 #: utils/misc/tzparser.c:479 utils/mmgr/aset.c:451 utils/mmgr/bump.c:185 #: utils/mmgr/dsa.c:722 utils/mmgr/dsa.c:744 utils/mmgr/dsa.c:825 -#: utils/mmgr/generation.c:217 utils/mmgr/mcxt.c:1206 utils/mmgr/slab.c:370 +#: utils/mmgr/generation.c:217 utils/mmgr/mcxt.c:1209 utils/mmgr/slab.c:370 #, c-format msgid "out of memory" msgstr "Speicher aufgebraucht" @@ -279,8 +279,8 @@ msgstr "konnte kein »%s« zum Ausführen finden" msgid "could not resolve path \"%s\" to absolute form: %m" msgstr "konnte Pfad »%s« nicht in absolute Form auflösen: %m" -#: ../common/exec.c:364 commands/collationcmds.c:877 commands/copyfrom.c:1891 -#: commands/copyto.c:1148 libpq/be-secure-common.c:66 +#: ../common/exec.c:364 commands/collationcmds.c:877 commands/copyfrom.c:1887 +#: commands/copyto.c:1170 libpq/be-secure-common.c:66 #, c-format msgid "could not execute command \"%s\": %m" msgstr "konnte Befehl »%s« nicht ausführen: %m" @@ -302,20 +302,30 @@ msgstr "Befehl »%s« gab keine Daten zurück" msgid "%s() failed: %m" msgstr "%s() fehlgeschlagen: %m" -#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 -#: ../common/fe_memutils.c:98 ../common/fe_memutils.c:161 -#: ../common/psprintf.c:142 ../port/path.c:831 ../port/path.c:868 -#: ../port/path.c:885 utils/misc/ps_status.c:206 utils/misc/ps_status.c:214 +#: ../common/fe_memutils.c:41 ../common/fe_memutils.c:81 +#: ../common/fe_memutils.c:104 ../common/fe_memutils.c:167 +#: ../common/psprintf.c:142 ../port/path.c:848 ../port/path.c:885 +#: ../port/path.c:902 utils/misc/ps_status.c:206 utils/misc/ps_status.c:214 #: utils/misc/ps_status.c:247 utils/misc/ps_status.c:255 #, c-format msgid "out of memory\n" msgstr "Speicher aufgebraucht\n" -#: ../common/fe_memutils.c:92 ../common/fe_memutils.c:153 +#: ../common/fe_memutils.c:98 ../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" +#: ../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "ungültige Speicheranforderungsgröße %zu + %zu\n" + +#: ../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "ungültige Speicheranforderungsgröße %zu * %zu\n" + #: ../common/file_utils.c:75 storage/file/fd.c:3566 #, c-format msgid "could not synchronize file system for file \"%s\": %m" @@ -325,10 +335,10 @@ msgstr "konnte Dateisystem für Datei »%s« nicht synchronisieren: %m" #: ../common/file_utils.c:592 access/transam/twophase.c:1335 #: access/transam/xlogarchive.c:112 access/transam/xlogarchive.c:236 #: backup/basebackup.c:363 backup/basebackup.c:559 backup/basebackup.c:630 -#: backup/walsummary.c:247 catalog/pg_tablespace.c:67 commands/copyfrom.c:1917 -#: commands/copyto.c:1194 commands/extension.c:4012 commands/tablespace.c:812 +#: backup/walsummary.c:247 catalog/pg_tablespace.c:67 commands/copyfrom.c:1913 +#: commands/copyto.c:1216 commands/extension.c:4014 commands/tablespace.c:812 #: commands/tablespace.c:901 postmaster/pgarch.c:685 -#: replication/logical/snapbuild.c:1606 replication/logical/snapbuild.c:2133 +#: replication/logical/snapbuild.c:1550 replication/logical/snapbuild.c:2077 #: storage/file/fd.c:1956 storage/file/fd.c:2044 storage/file/fd.c:3614 #: utils/adt/dbsize.c:105 utils/adt/dbsize.c:266 utils/adt/dbsize.c:355 #: utils/adt/genfile.c:437 utils/adt/genfile.c:613 @@ -357,9 +367,9 @@ msgid "could not read directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht lesen: %m" #: ../common/file_utils.c:520 access/transam/xlogarchive.c:390 -#: postmaster/pgarch.c:839 postmaster/syslogger.c:1560 -#: replication/logical/snapbuild.c:1768 replication/slot.c:1110 -#: replication/slot.c:2504 replication/slot.c:2653 storage/file/fd.c:839 +#: postmaster/pgarch.c:839 postmaster/syslogger.c:1579 +#: replication/logical/snapbuild.c:1712 replication/slot.c:1106 +#: replication/slot.c:2500 replication/slot.c:2649 storage/file/fd.c:839 #: utils/time/snapmgr.c:1275 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" @@ -583,7 +593,7 @@ msgstr "konnte Dateinamen nicht dekodieren" msgid "file size is not an integer" msgstr "Dateigröße ist keine ganze Zahl" -#: ../common/parse_manifest.c:699 backup/basebackup.c:874 +#: ../common/parse_manifest.c:699 backup/basebackup.c:872 #, c-format msgid "unrecognized checksum algorithm: \"%s\"" msgstr "unbekannter Prüfsummenalgorithmus: »%s«" @@ -652,7 +662,7 @@ msgstr "konnte Backup-Manifest nicht parsen: %s" #: ../common/percentrepl.c:79 ../common/percentrepl.c:85 #: ../common/percentrepl.c:118 ../common/percentrepl.c:124 -#: tcop/backend_startup.c:773 utils/misc/guc.c:3061 utils/misc/guc.c:3102 +#: tcop/backend_startup.c:801 utils/misc/guc.c:3061 utils/misc/guc.c:3102 #: utils/misc/guc.c:3186 utils/misc/guc.c:4610 utils/misc/guc.c:6809 #: utils/misc/guc.c:6850 #, c-format @@ -717,10 +727,10 @@ msgstr "konnte Statuscode des Subprozesses nicht ermitteln: Fehlercode %lu" #: ../common/rmtree.c:97 access/heap/rewriteheap.c:1217 #: access/transam/twophase.c:1738 access/transam/xlogarchive.c:120 #: access/transam/xlogarchive.c:400 backup/walsummary.c:254 -#: postmaster/postmaster.c:1084 postmaster/syslogger.c:1489 -#: replication/logical/origin.c:632 replication/logical/reorderbuffer.c:4873 -#: replication/logical/snapbuild.c:1649 replication/logical/snapbuild.c:2105 -#: replication/slot.c:2707 storage/file/fd.c:879 storage/file/fd.c:3428 +#: postmaster/postmaster.c:1084 postmaster/syslogger.c:1508 +#: replication/logical/origin.c:632 replication/logical/reorderbuffer.c:4871 +#: replication/logical/snapbuild.c:1593 replication/logical/snapbuild.c:2049 +#: replication/slot.c:2703 storage/file/fd.c:879 storage/file/fd.c:3428 #: storage/file/fd.c:3490 storage/file/reinit.c:261 storage/ipc/dsm.c:353 #: storage/smgr/md.c:412 storage/smgr/md.c:471 storage/sync/sync.c:244 #: utils/time/snapmgr.c:1611 @@ -843,13 +853,13 @@ msgstr "Checkpointer" #: ../include/postmaster/proctypelist.h:41 #, fuzzy #| msgid "autovacuum launcher" -msgid "datachecksum launcher" +msgid "datachecksums launcher" msgstr "Autovacuum-Launcher" #: ../include/postmaster/proctypelist.h:42 #, fuzzy #| msgid "autovacuum worker" -msgid "datachecksum worker" +msgid "datachecksums worker" msgstr "Autovacuum-Worker" #: ../include/postmaster/proctypelist.h:43 @@ -974,15 +984,15 @@ msgstr "Setzt die Zeit, die gewartet wird, bevor ein Umschalten auf die nächste #. translator: GUC parameter "statement_timeout" long description #. translator: GUC parameter "transaction_timeout" long description #. translator: GUC parameter "wal_receiver_timeout" long description -#: ../include/utils/guc_tables.inc.c:147 ../include/utils/guc_tables.inc.c:2399 -#: ../include/utils/guc_tables.inc.c:2433 -#: ../include/utils/guc_tables.inc.c:2992 -#: ../include/utils/guc_tables.inc.c:5355 -#: ../include/utils/guc_tables.inc.c:6067 -#: ../include/utils/guc_tables.inc.c:6562 utils/guc_tables.inc.c:147 -#: utils/guc_tables.inc.c:2399 utils/guc_tables.inc.c:2433 -#: utils/guc_tables.inc.c:2992 utils/guc_tables.inc.c:5355 -#: utils/guc_tables.inc.c:6067 utils/guc_tables.inc.c:6562 +#: ../include/utils/guc_tables.inc.c:147 ../include/utils/guc_tables.inc.c:2400 +#: ../include/utils/guc_tables.inc.c:2434 +#: ../include/utils/guc_tables.inc.c:2993 +#: ../include/utils/guc_tables.inc.c:5356 +#: ../include/utils/guc_tables.inc.c:6068 +#: ../include/utils/guc_tables.inc.c:6563 utils/guc_tables.inc.c:147 +#: utils/guc_tables.inc.c:2400 utils/guc_tables.inc.c:2434 +#: utils/guc_tables.inc.c:2993 utils/guc_tables.inc.c:5356 +#: utils/guc_tables.inc.c:6068 utils/guc_tables.inc.c:6563 msgid "0 disables the timeout." msgstr "0 schaltet Zeitüberschreitungen aus." @@ -1268,9 +1278,9 @@ msgstr "Setzt die Meldungstypen, die an den Client gesendet werden." #. translator: GUC parameter "client_min_messages" long description #. translator: GUC parameter "log_min_error_statement" long description #. translator: GUC parameter "log_min_messages" long description -#: ../include/utils/guc_tables.inc.c:827 ../include/utils/guc_tables.inc.c:3304 -#: ../include/utils/guc_tables.inc.c:3320 utils/guc_tables.inc.c:827 -#: utils/guc_tables.inc.c:3304 utils/guc_tables.inc.c:3320 +#: ../include/utils/guc_tables.inc.c:827 ../include/utils/guc_tables.inc.c:3305 +#: ../include/utils/guc_tables.inc.c:3321 utils/guc_tables.inc.c:827 +#: utils/guc_tables.inc.c:3305 utils/guc_tables.inc.c:3321 msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." msgstr "Jeder Wert schließt alle ihm folgenden Werte mit ein. Je weiter hinten der Wert steht, desto weniger Meldungen werden gesendet werden." @@ -1300,9 +1310,9 @@ msgstr "Setzt die Größe des für den Commit-Timestamp-Cache bestimmten Buffer- #. translator: GUC parameter "commit_timestamp_buffers" long description #. translator: GUC parameter "subtransaction_buffers" long description #. translator: GUC parameter "transaction_buffers" long description -#: ../include/utils/guc_tables.inc.c:888 ../include/utils/guc_tables.inc.c:5388 -#: ../include/utils/guc_tables.inc.c:6002 utils/guc_tables.inc.c:888 -#: utils/guc_tables.inc.c:5388 utils/guc_tables.inc.c:6002 +#: ../include/utils/guc_tables.inc.c:888 ../include/utils/guc_tables.inc.c:5389 +#: ../include/utils/guc_tables.inc.c:6003 utils/guc_tables.inc.c:888 +#: utils/guc_tables.inc.c:5389 utils/guc_tables.inc.c:6003 msgid "0 means use a fraction of \"shared_buffers\"." msgstr "0 bedeutet, einen Bruchteil von »shared_buffers« zu verwenden." @@ -1362,156 +1372,156 @@ msgid "Shows whether data checksums are turned on for this cluster." msgstr "Zeigt, ob Datenprüfsummen in diesem Cluster angeschaltet sind." #. translator: GUC parameter "data_directory" short description -#: ../include/utils/guc_tables.inc.c:1047 utils/guc_tables.inc.c:1047 +#: ../include/utils/guc_tables.inc.c:1048 utils/guc_tables.inc.c:1048 msgid "Sets the server's data directory." msgstr "Setzt das Datenverzeichnis des Servers." #. translator: GUC parameter "data_directory_mode" short description -#: ../include/utils/guc_tables.inc.c:1061 utils/guc_tables.inc.c:1061 +#: ../include/utils/guc_tables.inc.c:1062 utils/guc_tables.inc.c:1062 msgid "Shows the mode of the data directory." msgstr "Zeigt die Zugriffsrechte des Datenverzeichnisses." #. translator: GUC parameter "data_directory_mode" long description -#: ../include/utils/guc_tables.inc.c:1063 utils/guc_tables.inc.c:1063 +#: ../include/utils/guc_tables.inc.c:1064 utils/guc_tables.inc.c:1064 msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "Der Wert dieser Option muss ein numerischer Wert in der von den Systemaufrufen chmod und umask verwendeten Form sein. (Um das gebräuchliche Oktalformat zu verwenden, muss die Zahl mit 0 (einer Null) anfangen.)" #. translator: GUC parameter "data_sync_retry" short description -#: ../include/utils/guc_tables.inc.c:1080 utils/guc_tables.inc.c:1080 +#: ../include/utils/guc_tables.inc.c:1081 utils/guc_tables.inc.c:1081 msgid "Whether to continue running after a failure to sync data files." msgstr "Ob nach fehlgeschlagenem Synchronisieren von Datendateien fortgesetzt werden soll." #. translator: GUC parameter "DateStyle" short description -#: ../include/utils/guc_tables.inc.c:1093 utils/guc_tables.inc.c:1093 +#: ../include/utils/guc_tables.inc.c:1094 utils/guc_tables.inc.c:1094 msgid "Sets the display format for date and time values." msgstr "Setzt das Ausgabeformat für Datums- und Zeitwerte." #. translator: GUC parameter "DateStyle" long description -#: ../include/utils/guc_tables.inc.c:1095 utils/guc_tables.inc.c:1095 +#: ../include/utils/guc_tables.inc.c:1096 utils/guc_tables.inc.c:1096 msgid "Also controls interpretation of ambiguous date inputs." msgstr "Kontrolliert auch die Interpretation von zweideutigen Datumseingaben." #. translator: GUC parameter "deadlock_timeout" short description -#: ../include/utils/guc_tables.inc.c:1111 utils/guc_tables.inc.c:1111 +#: ../include/utils/guc_tables.inc.c:1112 utils/guc_tables.inc.c:1112 msgid "Sets the time to wait on a lock before checking for deadlock." msgstr "Setzt die Zeit, die gewartet wird, bis auf Verklemmung geprüft wird." #. translator: GUC parameter "debug_assertions" short description -#: ../include/utils/guc_tables.inc.c:1127 utils/guc_tables.inc.c:1127 +#: ../include/utils/guc_tables.inc.c:1128 utils/guc_tables.inc.c:1128 msgid "Shows whether the running server has assertion checks enabled." msgstr "Zeigt, ob der laufende Server Assertion-Prüfungen aktiviert hat." #. translator: GUC parameter "debug_copy_parse_plan_trees" short description -#: ../include/utils/guc_tables.inc.c:1142 utils/guc_tables.inc.c:1142 +#: ../include/utils/guc_tables.inc.c:1143 utils/guc_tables.inc.c:1143 msgid "Set this to force all parse and plan trees to be passed through copyObject(), to facilitate catching errors and omissions in copyObject()." msgstr "Wenn dies gesetzt ist, werden alle Parse- und Plan-Bäume durch copyObject() geschickt, um Fehler und Versäumnisse in copyObject() finden zu können." #. translator: GUC parameter "debug_deadlocks" short description -#: ../include/utils/guc_tables.inc.c:1158 utils/guc_tables.inc.c:1158 +#: ../include/utils/guc_tables.inc.c:1159 utils/guc_tables.inc.c:1159 msgid "Dumps information about all current locks when a deadlock timeout occurs." msgstr "Gibt Informationen über alle aktuellen Sperren aus, wenn eine Verklemmung auftritt." #. translator: GUC parameter "debug_discard_caches" short description -#: ../include/utils/guc_tables.inc.c:1173 utils/guc_tables.inc.c:1173 +#: ../include/utils/guc_tables.inc.c:1174 utils/guc_tables.inc.c:1174 msgid "Aggressively flush system caches for debugging purposes." msgstr "System-Caches aggressiv flushen, zum Debuggen." #. translator: GUC parameter "debug_discard_caches" long description -#: ../include/utils/guc_tables.inc.c:1175 utils/guc_tables.inc.c:1175 +#: ../include/utils/guc_tables.inc.c:1176 utils/guc_tables.inc.c:1176 msgid "0 means use normal caching behavior." msgstr "0 bedeutet, das normale Caching-Verhalten zu verwenden." #. translator: GUC parameter "debug_exec_backend" short description -#: ../include/utils/guc_tables.inc.c:1191 utils/guc_tables.inc.c:1191 +#: ../include/utils/guc_tables.inc.c:1192 utils/guc_tables.inc.c:1192 #, fuzzy #| msgid "Shows whether the running server has assertion checks enabled." msgid "Shows whether the running server is built with EXEC_BACKEND enabled." msgstr "Zeigt, ob der laufende Server Assertion-Prüfungen aktiviert hat." #. translator: GUC parameter "debug_io_direct" short description -#: ../include/utils/guc_tables.inc.c:1205 utils/guc_tables.inc.c:1205 +#: ../include/utils/guc_tables.inc.c:1206 utils/guc_tables.inc.c:1206 msgid "Use direct I/O for file access." msgstr "Direct-I/O für Dateizugriff verwenden." #. translator: GUC parameter "debug_io_direct" long description -#: ../include/utils/guc_tables.inc.c:1207 utils/guc_tables.inc.c:1207 +#: ../include/utils/guc_tables.inc.c:1208 utils/guc_tables.inc.c:1208 msgid "An empty string disables direct I/O." msgstr "Eine leere Zeichenkette schaltet Direct-I/O aus." #. translator: GUC parameter "debug_logical_replication_streaming" short description -#: ../include/utils/guc_tables.inc.c:1223 utils/guc_tables.inc.c:1223 +#: ../include/utils/guc_tables.inc.c:1224 utils/guc_tables.inc.c:1224 msgid "Forces immediate streaming or serialization of changes in large transactions." msgstr "Erzwingt sofortiges Streaming oder sofortige Serialisierung von Änderungen in großen Transaktionen." #. translator: GUC parameter "debug_logical_replication_streaming" long description -#: ../include/utils/guc_tables.inc.c:1225 utils/guc_tables.inc.c:1225 +#: ../include/utils/guc_tables.inc.c:1226 utils/guc_tables.inc.c:1226 msgid "On the publisher, it allows streaming or serializing each change in logical decoding. On the subscriber, it allows serialization of all changes to files and notifies the parallel apply workers to read and apply them at the end of the transaction." msgstr "Auf dem Publikationsserver erlaubt es Streaming oder Serialisierung jeder Änderung aus logischer Dekodierung. Auf dem Subskriptionsserver erlaubt es die Serialisierung aller Änderungen in Dateien und benachrichtigt die Parallel-Apply-Worker, sie nach dem Ende der Transaktion zu lesen und anzuwenden." #. translator: GUC parameter "debug_parallel_query" short description -#: ../include/utils/guc_tables.inc.c:1240 utils/guc_tables.inc.c:1240 +#: ../include/utils/guc_tables.inc.c:1241 utils/guc_tables.inc.c:1241 msgid "Forces the planner's use parallel query nodes." msgstr "Erzwingt die Verwendung von Parallel-Query-Knoten im Planer." #. translator: GUC parameter "debug_parallel_query" long description -#: ../include/utils/guc_tables.inc.c:1242 utils/guc_tables.inc.c:1242 +#: ../include/utils/guc_tables.inc.c:1243 utils/guc_tables.inc.c:1243 msgid "This can be useful for testing the parallel query infrastructure by forcing the planner to generate plans that contain nodes that perform tuple communication between workers and the main process." msgstr "Das kann nützlich sein, um die Parallel-Query-Infrastruktur zu testen, indem der Planer gezwungen wird, Pläne zu erzeugen, die Knoten enthalten, die Tupelkommunikation zwischen Worker- und Hauptprozess durchführen." #. translator: GUC parameter "debug_pretty_print" short description -#: ../include/utils/guc_tables.inc.c:1257 utils/guc_tables.inc.c:1257 +#: ../include/utils/guc_tables.inc.c:1258 utils/guc_tables.inc.c:1258 msgid "Indents parse and plan tree displays." msgstr "Rückt die Anzeige von Parse- und Planbäumen ein." #. translator: GUC parameter "debug_print_parse" short description -#: ../include/utils/guc_tables.inc.c:1270 utils/guc_tables.inc.c:1270 +#: ../include/utils/guc_tables.inc.c:1271 utils/guc_tables.inc.c:1271 msgid "Logs each query's parse tree." msgstr "Scheibt den Parsebaum jeder Anfrage in den Log." #. translator: GUC parameter "debug_print_plan" short description -#: ../include/utils/guc_tables.inc.c:1283 utils/guc_tables.inc.c:1283 +#: ../include/utils/guc_tables.inc.c:1284 utils/guc_tables.inc.c:1284 msgid "Logs each query's execution plan." msgstr "Schreibt den Ausführungsplan jeder Anfrage in den Log." #. translator: GUC parameter "debug_print_raw_parse" short description -#: ../include/utils/guc_tables.inc.c:1296 utils/guc_tables.inc.c:1296 +#: ../include/utils/guc_tables.inc.c:1297 utils/guc_tables.inc.c:1297 #, fuzzy #| msgid "Logs each query's parse tree." msgid "Logs each query's raw parse tree." msgstr "Scheibt den Parsebaum jeder Anfrage in den Log." #. translator: GUC parameter "debug_print_rewritten" short description -#: ../include/utils/guc_tables.inc.c:1309 utils/guc_tables.inc.c:1309 +#: ../include/utils/guc_tables.inc.c:1310 utils/guc_tables.inc.c:1310 msgid "Logs each query's rewritten parse tree." msgstr "Schreibt den umgeschriebenen Parsebaum jeder Anfrage in den Log." #. translator: GUC parameter "debug_raw_expression_coverage_test" short description -#: ../include/utils/guc_tables.inc.c:1323 utils/guc_tables.inc.c:1323 +#: ../include/utils/guc_tables.inc.c:1324 utils/guc_tables.inc.c:1324 msgid "Set this to force all raw parse trees for DML statements to be scanned by raw_expression_tree_walker(), to facilitate catching errors and omissions in that function." msgstr "Wenn dies gesetzt ist, werden alle Raw-Parse-Bäume für DML-Anweisungen durch raw_expression_tree_walker() geprüft, um Fehler und Versäumnisse in dieser Funktion finden zu können." #. translator: GUC parameter "debug_write_read_parse_plan_trees" short description -#: ../include/utils/guc_tables.inc.c:1339 utils/guc_tables.inc.c:1339 +#: ../include/utils/guc_tables.inc.c:1340 utils/guc_tables.inc.c:1340 msgid "Set this to force all parse and plan trees to be passed through outfuncs.c/readfuncs.c, to facilitate catching errors and omissions in those modules." msgstr "Wenn dies gesetzt ist, werden alle Parse- und Plan-Bäume durch outfuncs.c/readfuncs.c geschickt, um Fehler und Versäumnisse in diesen Modulen finden zu können." #. translator: GUC parameter "default_statistics_target" short description -#: ../include/utils/guc_tables.inc.c:1354 utils/guc_tables.inc.c:1354 +#: ../include/utils/guc_tables.inc.c:1355 utils/guc_tables.inc.c:1355 msgid "Sets the default statistics target." msgstr "Setzt das voreingestellte Statistikziel." #. translator: GUC parameter "default_statistics_target" long description -#: ../include/utils/guc_tables.inc.c:1356 utils/guc_tables.inc.c:1356 +#: ../include/utils/guc_tables.inc.c:1357 utils/guc_tables.inc.c:1357 msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." msgstr "Diese Einstellung gilt für Tabellenspalten, für die kein spaltenspezifisches Ziel mit ALTER TABLE SET STATISTICS gesetzt worden ist." #. translator: GUC parameter "default_table_access_method" short description -#: ../include/utils/guc_tables.inc.c:1371 utils/guc_tables.inc.c:1371 +#: ../include/utils/guc_tables.inc.c:1372 utils/guc_tables.inc.c:1372 msgid "Sets the default table access method for new tables." msgstr "Setzt die Standard-Tabellenzugriffsmethode für neue Tabellen." #. translator: GUC parameter "default_tablespace" short description -#: ../include/utils/guc_tables.inc.c:1386 utils/guc_tables.inc.c:1386 +#: ../include/utils/guc_tables.inc.c:1387 utils/guc_tables.inc.c:1387 msgid "Sets the default tablespace to create tables and indexes in." msgstr "Setzt den Standard-Tablespace für Tabellen und Indexe." @@ -1519,69 +1529,69 @@ msgstr "Setzt den Standard-Tablespace für Tabellen und Indexe." #. translator: GUC parameter "temp_tablespaces" long description #. translator: GUC parameter "default_tablespace" long description #. translator: GUC parameter "temp_tablespaces" long description -#: ../include/utils/guc_tables.inc.c:1388 -#: ../include/utils/guc_tables.inc.c:5679 utils/guc_tables.inc.c:1388 -#: utils/guc_tables.inc.c:5679 +#: ../include/utils/guc_tables.inc.c:1389 +#: ../include/utils/guc_tables.inc.c:5680 utils/guc_tables.inc.c:1389 +#: utils/guc_tables.inc.c:5680 msgid "An empty string means use the database's default tablespace." msgstr "Eine leere Zeichenkette bedeutet, den Standard-Tablespace der Datenbank zu verwenden." #. translator: GUC parameter "default_text_search_config" short description -#: ../include/utils/guc_tables.inc.c:1403 utils/guc_tables.inc.c:1403 +#: ../include/utils/guc_tables.inc.c:1404 utils/guc_tables.inc.c:1404 msgid "Sets default text search configuration." msgstr "Setzt die vorgegebene Textsuchekonfiguration." #. translator: GUC parameter "default_toast_compression" short description -#: ../include/utils/guc_tables.inc.c:1418 utils/guc_tables.inc.c:1418 +#: ../include/utils/guc_tables.inc.c:1419 utils/guc_tables.inc.c:1419 msgid "Sets the default compression method for compressible values." msgstr "Setzt die Standard-Komprimierungsmethode für komprimierbare Werte." #. translator: GUC parameter "default_transaction_deferrable" short description -#: ../include/utils/guc_tables.inc.c:1432 utils/guc_tables.inc.c:1432 +#: ../include/utils/guc_tables.inc.c:1433 utils/guc_tables.inc.c:1433 msgid "Sets the default deferrable status of new transactions." msgstr "Setzt den Standardwert für die Deferrable-Einstellung einer neuen Transaktion." #. translator: GUC parameter "default_transaction_isolation" short description -#: ../include/utils/guc_tables.inc.c:1445 utils/guc_tables.inc.c:1445 +#: ../include/utils/guc_tables.inc.c:1446 utils/guc_tables.inc.c:1446 msgid "Sets the transaction isolation level of each new transaction." msgstr "Setzt den Transaktionsisolationsgrad neuer Transaktionen." #. translator: GUC parameter "default_transaction_read_only" short description -#: ../include/utils/guc_tables.inc.c:1459 utils/guc_tables.inc.c:1459 +#: ../include/utils/guc_tables.inc.c:1460 utils/guc_tables.inc.c:1460 msgid "Sets the default read-only status of new transactions." msgstr "Setzt den Standardwert für die Read-Only-Einstellung einer neuen Transaktion." #. translator: GUC parameter "default_with_oids" short description -#: ../include/utils/guc_tables.inc.c:1473 utils/guc_tables.inc.c:1473 +#: ../include/utils/guc_tables.inc.c:1474 utils/guc_tables.inc.c:1474 msgid "WITH OIDS is no longer supported; this can only be false." msgstr "WITH OIDS wird nicht mehr unterstützt; kann nur auf falsch gesetzt werden." #. translator: GUC parameter "dynamic_library_path" short description -#: ../include/utils/guc_tables.inc.c:1488 utils/guc_tables.inc.c:1488 +#: ../include/utils/guc_tables.inc.c:1489 utils/guc_tables.inc.c:1489 msgid "Sets the path for dynamically loadable modules." msgstr "Setzt den Pfad für ladbare dynamische Bibliotheken." #. translator: GUC parameter "dynamic_library_path" long description -#: ../include/utils/guc_tables.inc.c:1490 utils/guc_tables.inc.c:1490 +#: ../include/utils/guc_tables.inc.c:1491 utils/guc_tables.inc.c:1491 msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." msgstr "Wenn ein dynamisch ladbares Modul geöffnet werden muss und der angegebene Name keine Verzeichniskomponente hat (das heißt er enthält keinen Schrägstrich), dann sucht das System in diesem Pfad nach der angegebenen Datei." #. translator: GUC parameter "dynamic_shared_memory_type" short description -#: ../include/utils/guc_tables.inc.c:1504 utils/guc_tables.inc.c:1504 +#: ../include/utils/guc_tables.inc.c:1505 utils/guc_tables.inc.c:1505 msgid "Selects the dynamic shared memory implementation used." msgstr "Wählt die zu verwendende Implementierung von dynamischem Shared Memory." #. translator: GUC parameter "effective_cache_size" short description -#: ../include/utils/guc_tables.inc.c:1518 utils/guc_tables.inc.c:1518 +#: ../include/utils/guc_tables.inc.c:1519 utils/guc_tables.inc.c:1519 msgid "Sets the planner's assumption about the total size of the data caches." msgstr "Setzt die Annahme des Planers über die Gesamtgröße der Daten-Caches." #. translator: GUC parameter "effective_cache_size" long description -#: ../include/utils/guc_tables.inc.c:1520 utils/guc_tables.inc.c:1520 +#: ../include/utils/guc_tables.inc.c:1521 utils/guc_tables.inc.c:1521 msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." msgstr "Das heißt, die Gesamtgröße der Caches (Kernel-Cache und Shared Buffers), die für Datendateien von PostgreSQL verwendet wird. Das wird in Diskseiten gemessen, welche normalerweise 8 kB groß sind." #. translator: GUC parameter "effective_io_concurrency" short description -#: ../include/utils/guc_tables.inc.c:1536 utils/guc_tables.inc.c:1536 +#: ../include/utils/guc_tables.inc.c:1537 utils/guc_tables.inc.c:1537 msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." msgstr "Anzahl simultaner Anfragen, die das Festplattensubsystem effizient bearbeiten kann." @@ -1589,256 +1599,256 @@ msgstr "Anzahl simultaner Anfragen, die das Festplattensubsystem effizient bearb #. translator: GUC parameter "maintenance_io_concurrency" long description #. translator: GUC parameter "effective_io_concurrency" long description #. translator: GUC parameter "maintenance_io_concurrency" long description -#: ../include/utils/guc_tables.inc.c:1538 -#: ../include/utils/guc_tables.inc.c:3622 utils/guc_tables.inc.c:1538 -#: utils/guc_tables.inc.c:3622 +#: ../include/utils/guc_tables.inc.c:1539 +#: ../include/utils/guc_tables.inc.c:3623 utils/guc_tables.inc.c:1539 +#: utils/guc_tables.inc.c:3623 msgid "0 disables simultaneous requests." msgstr "0 schaltet simultane Anfragen aus." #. translator: GUC parameter "effective_wal_level" short description -#: ../include/utils/guc_tables.inc.c:1554 utils/guc_tables.inc.c:1554 +#: ../include/utils/guc_tables.inc.c:1555 utils/guc_tables.inc.c:1555 msgid "Shows effective WAL level." msgstr "" #. translator: GUC parameter "enable_async_append" short description -#: ../include/utils/guc_tables.inc.c:1570 utils/guc_tables.inc.c:1570 +#: ../include/utils/guc_tables.inc.c:1571 utils/guc_tables.inc.c:1571 msgid "Enables the planner's use of async append plans." msgstr "Ermöglicht asynchrone Append-Pläne im Planer." #. translator: GUC parameter "enable_bitmapscan" short description -#: ../include/utils/guc_tables.inc.c:1584 utils/guc_tables.inc.c:1584 +#: ../include/utils/guc_tables.inc.c:1585 utils/guc_tables.inc.c:1585 msgid "Enables the planner's use of bitmap-scan plans." msgstr "Ermöglicht Bitmap-Scans im Planer." #. translator: GUC parameter "enable_distinct_reordering" short description -#: ../include/utils/guc_tables.inc.c:1598 utils/guc_tables.inc.c:1598 +#: ../include/utils/guc_tables.inc.c:1599 utils/guc_tables.inc.c:1599 msgid "Enables reordering of DISTINCT keys." msgstr "Ermöglicht Umordnen von DISTINCT-Schlüsseln." #. translator: GUC parameter "enable_eager_aggregate" short description -#: ../include/utils/guc_tables.inc.c:1612 utils/guc_tables.inc.c:1612 +#: ../include/utils/guc_tables.inc.c:1613 utils/guc_tables.inc.c:1613 #, fuzzy #| msgid "Enables partitionwise aggregation and grouping." msgid "Enables eager aggregation." msgstr "Ermöglicht partitionsweise Aggregierung und Gruppierung." #. translator: GUC parameter "enable_gathermerge" short description -#: ../include/utils/guc_tables.inc.c:1626 utils/guc_tables.inc.c:1626 +#: ../include/utils/guc_tables.inc.c:1627 utils/guc_tables.inc.c:1627 msgid "Enables the planner's use of gather merge plans." msgstr "Ermöglicht Gather-Merge-Pläne im Planer." #. translator: GUC parameter "enable_group_by_reordering" short description -#: ../include/utils/guc_tables.inc.c:1640 utils/guc_tables.inc.c:1640 +#: ../include/utils/guc_tables.inc.c:1641 utils/guc_tables.inc.c:1641 msgid "Enables reordering of GROUP BY keys." msgstr "Ermöglicht Umordnen von GROUP-BY-Schlüsseln." #. translator: GUC parameter "enable_hashagg" short description -#: ../include/utils/guc_tables.inc.c:1654 utils/guc_tables.inc.c:1654 +#: ../include/utils/guc_tables.inc.c:1655 utils/guc_tables.inc.c:1655 msgid "Enables the planner's use of hashed aggregation plans." msgstr "Ermöglicht Hash-Aggregierung im Planer." #. translator: GUC parameter "enable_hashjoin" short description -#: ../include/utils/guc_tables.inc.c:1668 utils/guc_tables.inc.c:1668 +#: ../include/utils/guc_tables.inc.c:1669 utils/guc_tables.inc.c:1669 msgid "Enables the planner's use of hash join plans." msgstr "Ermöglicht Hash-Verbunde im Planer." #. translator: GUC parameter "enable_incremental_sort" short description -#: ../include/utils/guc_tables.inc.c:1682 utils/guc_tables.inc.c:1682 +#: ../include/utils/guc_tables.inc.c:1683 utils/guc_tables.inc.c:1683 msgid "Enables the planner's use of incremental sort steps." msgstr "Ermöglicht inkrementelle Sortierschritte im Planer." #. translator: GUC parameter "enable_indexonlyscan" short description -#: ../include/utils/guc_tables.inc.c:1696 utils/guc_tables.inc.c:1696 +#: ../include/utils/guc_tables.inc.c:1697 utils/guc_tables.inc.c:1697 msgid "Enables the planner's use of index-only-scan plans." msgstr "Ermöglicht Index-Only-Scans im Planer." #. translator: GUC parameter "enable_indexscan" short description -#: ../include/utils/guc_tables.inc.c:1710 utils/guc_tables.inc.c:1710 +#: ../include/utils/guc_tables.inc.c:1711 utils/guc_tables.inc.c:1711 msgid "Enables the planner's use of index-scan plans." msgstr "Ermöglicht Index-Scans im Planer." #. translator: GUC parameter "enable_material" short description -#: ../include/utils/guc_tables.inc.c:1724 utils/guc_tables.inc.c:1724 +#: ../include/utils/guc_tables.inc.c:1725 utils/guc_tables.inc.c:1725 msgid "Enables the planner's use of materialization." msgstr "Ermöglicht Materialisierung im Planer." #. translator: GUC parameter "enable_memoize" short description -#: ../include/utils/guc_tables.inc.c:1738 utils/guc_tables.inc.c:1738 +#: ../include/utils/guc_tables.inc.c:1739 utils/guc_tables.inc.c:1739 msgid "Enables the planner's use of memoization." msgstr "Ermöglicht Memoization im Planer." #. translator: GUC parameter "enable_mergejoin" short description -#: ../include/utils/guc_tables.inc.c:1752 utils/guc_tables.inc.c:1752 +#: ../include/utils/guc_tables.inc.c:1753 utils/guc_tables.inc.c:1753 msgid "Enables the planner's use of merge join plans." msgstr "Ermöglicht Merge-Verbunde im Planer." #. translator: GUC parameter "enable_nestloop" short description -#: ../include/utils/guc_tables.inc.c:1766 utils/guc_tables.inc.c:1766 +#: ../include/utils/guc_tables.inc.c:1767 utils/guc_tables.inc.c:1767 msgid "Enables the planner's use of nested-loop join plans." msgstr "Ermöglicht Nested-Loop-Verbunde im Planer." #. translator: GUC parameter "enable_parallel_append" short description -#: ../include/utils/guc_tables.inc.c:1780 utils/guc_tables.inc.c:1780 +#: ../include/utils/guc_tables.inc.c:1781 utils/guc_tables.inc.c:1781 msgid "Enables the planner's use of parallel append plans." msgstr "Ermöglicht parallele Append-Pläne im Planer." #. translator: GUC parameter "enable_parallel_hash" short description -#: ../include/utils/guc_tables.inc.c:1794 utils/guc_tables.inc.c:1794 +#: ../include/utils/guc_tables.inc.c:1795 utils/guc_tables.inc.c:1795 msgid "Enables the planner's use of parallel hash plans." msgstr "Ermöglicht parallele Hash-Pläne im Planer." #. translator: GUC parameter "enable_partition_pruning" short description -#: ../include/utils/guc_tables.inc.c:1808 utils/guc_tables.inc.c:1808 +#: ../include/utils/guc_tables.inc.c:1809 utils/guc_tables.inc.c:1809 msgid "Enables plan-time and execution-time partition pruning." msgstr "Ermöglicht Partition-Pruning zur Planzeit und zur Ausführungszeit." #. translator: GUC parameter "enable_partition_pruning" long description -#: ../include/utils/guc_tables.inc.c:1810 utils/guc_tables.inc.c:1810 +#: ../include/utils/guc_tables.inc.c:1811 utils/guc_tables.inc.c:1811 msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." msgstr "Erlaubt es dem Planer und dem Executor, Partitionsbegrenzungen mit Bedingungen in der Anfrage zu vergleichen, um festzustellen, welche Partitionen gelesen werden müssen." #. translator: GUC parameter "enable_partitionwise_aggregate" short description -#: ../include/utils/guc_tables.inc.c:1824 utils/guc_tables.inc.c:1824 +#: ../include/utils/guc_tables.inc.c:1825 utils/guc_tables.inc.c:1825 msgid "Enables partitionwise aggregation and grouping." msgstr "Ermöglicht partitionsweise Aggregierung und Gruppierung." #. translator: GUC parameter "enable_partitionwise_join" short description -#: ../include/utils/guc_tables.inc.c:1838 utils/guc_tables.inc.c:1838 +#: ../include/utils/guc_tables.inc.c:1839 utils/guc_tables.inc.c:1839 msgid "Enables partitionwise join." msgstr "Ermöglicht partitionsweise Verbunde." #. translator: GUC parameter "enable_presorted_aggregate" short description -#: ../include/utils/guc_tables.inc.c:1852 utils/guc_tables.inc.c:1852 +#: ../include/utils/guc_tables.inc.c:1853 utils/guc_tables.inc.c:1853 msgid "Enables the planner's ability to produce plans that provide presorted input for ORDER BY / DISTINCT aggregate functions." msgstr "Schaltet die Fähigkeit des Planers ein, Pläne zu erzeugen, die vorsortierte Eingaben für ORDER-BY-/DISTINCT-Aggregatfunktionen bereitstellen." #. translator: GUC parameter "enable_presorted_aggregate" long description -#: ../include/utils/guc_tables.inc.c:1854 utils/guc_tables.inc.c:1854 +#: ../include/utils/guc_tables.inc.c:1855 utils/guc_tables.inc.c:1855 msgid "Allows the query planner to build plans that provide presorted input for aggregate functions with an ORDER BY / DISTINCT clause. When disabled, implicit sorts are always performed during execution." msgstr "Erlaubt es dem Planer, Pläne zu bauen, die vorsortierte Eingaben für Aggregatfunktionen mit ORDER-BY-/DISTINCT-Klausel bereitstellen. Wenn ausgeschaltet, werden immer implizite Sortierschritte bei der Ausführung durchgeführt." #. translator: GUC parameter "enable_self_join_elimination" short description -#: ../include/utils/guc_tables.inc.c:1868 utils/guc_tables.inc.c:1868 +#: ../include/utils/guc_tables.inc.c:1869 utils/guc_tables.inc.c:1869 msgid "Enables removal of unique self-joins." msgstr "Ermöglicht das Entfernen von Unique Self-Joins." #. translator: GUC parameter "enable_seqscan" short description -#: ../include/utils/guc_tables.inc.c:1882 utils/guc_tables.inc.c:1882 +#: ../include/utils/guc_tables.inc.c:1883 utils/guc_tables.inc.c:1883 msgid "Enables the planner's use of sequential-scan plans." msgstr "Ermöglicht sequenzielle Scans in Planer." #. translator: GUC parameter "enable_sort" short description -#: ../include/utils/guc_tables.inc.c:1896 utils/guc_tables.inc.c:1896 +#: ../include/utils/guc_tables.inc.c:1897 utils/guc_tables.inc.c:1897 msgid "Enables the planner's use of explicit sort steps." msgstr "Ermöglicht Sortierschritte im Planer." #. translator: GUC parameter "enable_tidscan" short description -#: ../include/utils/guc_tables.inc.c:1910 utils/guc_tables.inc.c:1910 +#: ../include/utils/guc_tables.inc.c:1911 utils/guc_tables.inc.c:1911 msgid "Enables the planner's use of TID scan plans." msgstr "Ermöglicht TID-Scans im Planer." #. translator: GUC parameter "event_source" short description -#: ../include/utils/guc_tables.inc.c:1924 utils/guc_tables.inc.c:1924 +#: ../include/utils/guc_tables.inc.c:1925 utils/guc_tables.inc.c:1925 msgid "Sets the application name used to identify PostgreSQL messages in the event log." msgstr "Setzt den Programmnamen, mit dem PostgreSQL-Meldungen im Ereignisprotokoll identifiziert werden." #. translator: GUC parameter "event_triggers" short description -#: ../include/utils/guc_tables.inc.c:1937 utils/guc_tables.inc.c:1937 +#: ../include/utils/guc_tables.inc.c:1938 utils/guc_tables.inc.c:1938 msgid "Enables event triggers." msgstr "Schaltet Ereignistrigger ein." #. translator: GUC parameter "event_triggers" long description -#: ../include/utils/guc_tables.inc.c:1939 utils/guc_tables.inc.c:1939 +#: ../include/utils/guc_tables.inc.c:1940 utils/guc_tables.inc.c:1940 msgid "When enabled, event triggers will fire for all applicable statements." msgstr "Wenn eingeschaltet, werden Ereignistrigger für alle passenden Anweisungen ausgelöst." #. translator: GUC parameter "exit_on_error" short description -#: ../include/utils/guc_tables.inc.c:1952 utils/guc_tables.inc.c:1952 +#: ../include/utils/guc_tables.inc.c:1953 utils/guc_tables.inc.c:1953 msgid "Terminate session on any error." msgstr "Sitzung bei jedem Fehler abbrechen." #. translator: GUC parameter "extension_control_path" short description -#: ../include/utils/guc_tables.inc.c:1965 utils/guc_tables.inc.c:1965 +#: ../include/utils/guc_tables.inc.c:1966 utils/guc_tables.inc.c:1966 msgid "Sets the path for extension control files." msgstr "Setzt den Pfad für Kontrolldateien von Erweiterungen." #. translator: GUC parameter "extension_control_path" long description -#: ../include/utils/guc_tables.inc.c:1967 utils/guc_tables.inc.c:1967 +#: ../include/utils/guc_tables.inc.c:1968 utils/guc_tables.inc.c:1968 msgid "The remaining extension script and secondary control files are then loaded from the same directory where the primary control file was found." msgstr "Die übrigen Skriptdateien und sekundären Kontrolldateien von Erweiterungen werden aus dem selben Verzeichnis geladen, wo die primäre Kontrolldatei gefunden wurde." #. translator: GUC parameter "external_pid_file" short description -#: ../include/utils/guc_tables.inc.c:1981 utils/guc_tables.inc.c:1981 +#: ../include/utils/guc_tables.inc.c:1982 utils/guc_tables.inc.c:1982 msgid "Writes the postmaster PID to the specified file." msgstr "Schreibt die Postmaster-PID in die angegebene Datei." #. translator: GUC parameter "extra_float_digits" short description -#: ../include/utils/guc_tables.inc.c:1996 utils/guc_tables.inc.c:1996 +#: ../include/utils/guc_tables.inc.c:1997 utils/guc_tables.inc.c:1997 msgid "Sets the number of digits displayed for floating-point values." msgstr "Setzt die Anzahl ausgegebener Ziffern für Fließkommawerte." #. translator: GUC parameter "extra_float_digits" long description -#: ../include/utils/guc_tables.inc.c:1998 utils/guc_tables.inc.c:1998 +#: ../include/utils/guc_tables.inc.c:1999 utils/guc_tables.inc.c:1999 msgid "This affects real, double precision, and geometric data types. A zero or negative parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate). Any value greater than zero selects precise output mode." msgstr "Diese Einstellung betrifft real, double precision und geometrische Datentypen. Null oder ein negativer Parameterwert wird zur Standardziffernanzahl (FLT_DIG bzw. DBL_DIG) hinzuaddiert. Ein Wert größer als Null wählt präzisen Ausgabemodus." #. translator: GUC parameter "file_copy_method" short description -#: ../include/utils/guc_tables.inc.c:2013 utils/guc_tables.inc.c:2013 +#: ../include/utils/guc_tables.inc.c:2014 utils/guc_tables.inc.c:2014 msgid "Selects the file copy method." msgstr "Wählt die Methode, um Dateien zu kopieren." #. translator: GUC parameter "file_extend_method" short description -#: ../include/utils/guc_tables.inc.c:2027 utils/guc_tables.inc.c:2027 +#: ../include/utils/guc_tables.inc.c:2028 utils/guc_tables.inc.c:2028 msgid "Selects the method used for extending data files." msgstr "Wählt die Methode, um Datendateien zu erweitern." #. translator: GUC parameter "from_collapse_limit" short description -#: ../include/utils/guc_tables.inc.c:2041 utils/guc_tables.inc.c:2041 +#: ../include/utils/guc_tables.inc.c:2042 utils/guc_tables.inc.c:2042 msgid "Sets the FROM-list size beyond which subqueries are not collapsed." msgstr "Setzt die Größe der FROM-Liste, ab der Unteranfragen nicht kollabiert werden." #. translator: GUC parameter "from_collapse_limit" long description -#: ../include/utils/guc_tables.inc.c:2043 utils/guc_tables.inc.c:2043 +#: ../include/utils/guc_tables.inc.c:2044 utils/guc_tables.inc.c:2044 msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." msgstr "Der Planer bindet Unteranfragen in die übergeordneten Anfragen ein, wenn die daraus resultierende FROM-Liste nicht mehr als so viele Elemente haben würde." #. translator: GUC parameter "fsync" short description -#: ../include/utils/guc_tables.inc.c:2059 utils/guc_tables.inc.c:2059 +#: ../include/utils/guc_tables.inc.c:2060 utils/guc_tables.inc.c:2060 msgid "Forces synchronization of updates to disk." msgstr "Erzwingt die Synchronisierung von Aktualisierungen auf Festplatte." #. translator: GUC parameter "fsync" long description -#: ../include/utils/guc_tables.inc.c:2061 utils/guc_tables.inc.c:2061 +#: ../include/utils/guc_tables.inc.c:2062 utils/guc_tables.inc.c:2062 msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This ensures that a database cluster will recover to a consistent state after an operating system or hardware crash." msgstr "Der Server verwendet den Systemaufruf fsync() an mehreren Stellen, um sicherzustellen, dass Datenänderungen physikalisch auf die Festplatte geschrieben werden. Das stellt sicher, dass der Datenbankcluster nach einem Betriebssystemabsturz oder Hardwarefehler in einem korrekten Zustand wiederhergestellt werden kann." #. translator: GUC parameter "full_page_writes" short description -#: ../include/utils/guc_tables.inc.c:2074 utils/guc_tables.inc.c:2074 +#: ../include/utils/guc_tables.inc.c:2075 utils/guc_tables.inc.c:2075 msgid "Writes full pages to WAL when first modified after a checkpoint." msgstr "Schreibt volle Seiten in den WAL, sobald sie nach einem Checkpoint geändert werden." #. translator: GUC parameter "full_page_writes" long description -#: ../include/utils/guc_tables.inc.c:2076 utils/guc_tables.inc.c:2076 +#: ../include/utils/guc_tables.inc.c:2077 utils/guc_tables.inc.c:2077 msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." msgstr "Ein Seitenschreibvorgang während eines Betriebssystemabsturzes könnte eventuell nur teilweise geschrieben worden sein. Bei der Wiederherstellung sind die im WAL gespeicherten Zeilenänderungen nicht ausreichend. Diese Option schreibt Seiten, sobald sie nach einem Checkpoint geändert worden sind, damit eine volle Wiederherstellung möglich ist." #. translator: GUC parameter "geqo" short description -#: ../include/utils/guc_tables.inc.c:2089 utils/guc_tables.inc.c:2089 +#: ../include/utils/guc_tables.inc.c:2090 utils/guc_tables.inc.c:2090 msgid "Enables genetic query optimization." msgstr "Ermöglicht genetische Anfrageoptimierung." #. translator: GUC parameter "geqo" long description -#: ../include/utils/guc_tables.inc.c:2091 utils/guc_tables.inc.c:2091 +#: ../include/utils/guc_tables.inc.c:2092 utils/guc_tables.inc.c:2092 msgid "This algorithm attempts to do planning without exhaustive searching." msgstr "Dieser Algorithmus versucht das Planen ohne erschöpfende Suche durchzuführen." #. translator: GUC parameter "geqo_effort" short description -#: ../include/utils/guc_tables.inc.c:2105 utils/guc_tables.inc.c:2105 +#: ../include/utils/guc_tables.inc.c:2106 utils/guc_tables.inc.c:2106 msgid "GEQO: effort is used to set the default for other GEQO parameters." msgstr "GEQO: wird für die Berechnung der Vorgabewerte anderer GEQO-Parameter verwendet." #. translator: GUC parameter "geqo_generations" short description -#: ../include/utils/guc_tables.inc.c:2121 utils/guc_tables.inc.c:2121 +#: ../include/utils/guc_tables.inc.c:2122 utils/guc_tables.inc.c:2122 msgid "GEQO: number of iterations of the algorithm." msgstr "GEQO: Anzahl der Iterationen im Algorithmus." @@ -1846,81 +1856,81 @@ msgstr "GEQO: Anzahl der Iterationen im Algorithmus." #. translator: GUC parameter "geqo_pool_size" long description #. translator: GUC parameter "geqo_generations" long description #. translator: GUC parameter "geqo_pool_size" long description -#: ../include/utils/guc_tables.inc.c:2123 -#: ../include/utils/guc_tables.inc.c:2141 utils/guc_tables.inc.c:2123 -#: utils/guc_tables.inc.c:2141 +#: ../include/utils/guc_tables.inc.c:2124 +#: ../include/utils/guc_tables.inc.c:2142 utils/guc_tables.inc.c:2124 +#: utils/guc_tables.inc.c:2142 msgid "0 means use a suitable default value." msgstr "0 bedeutet, dass ein passender Vorgabewert verwendet wird." #. translator: GUC parameter "geqo_pool_size" short description -#: ../include/utils/guc_tables.inc.c:2139 utils/guc_tables.inc.c:2139 +#: ../include/utils/guc_tables.inc.c:2140 utils/guc_tables.inc.c:2140 msgid "GEQO: number of individuals in the population." msgstr "GEQO: Anzahl der Individien in der Bevölkerung." #. translator: GUC parameter "geqo_seed" short description -#: ../include/utils/guc_tables.inc.c:2157 utils/guc_tables.inc.c:2157 +#: ../include/utils/guc_tables.inc.c:2158 utils/guc_tables.inc.c:2158 msgid "GEQO: seed for random path selection." msgstr "GEQO: Ausgangswert für die zufällige Pfadauswahl." #. translator: GUC parameter "geqo_selection_bias" short description -#: ../include/utils/guc_tables.inc.c:2173 utils/guc_tables.inc.c:2173 +#: ../include/utils/guc_tables.inc.c:2174 utils/guc_tables.inc.c:2174 msgid "GEQO: selective pressure within the population." msgstr "GEQO: selektiver Auswahldruck in der Bevölkerung." #. translator: GUC parameter "geqo_threshold" short description -#: ../include/utils/guc_tables.inc.c:2189 utils/guc_tables.inc.c:2189 +#: ../include/utils/guc_tables.inc.c:2190 utils/guc_tables.inc.c:2190 msgid "Sets the threshold of FROM items beyond which GEQO is used." msgstr "Setzt die Anzahl der Elemente in der FROM-Liste, ab der GEQO verwendet wird." #. translator: GUC parameter "gin_fuzzy_search_limit" short description -#: ../include/utils/guc_tables.inc.c:2205 utils/guc_tables.inc.c:2205 +#: ../include/utils/guc_tables.inc.c:2206 utils/guc_tables.inc.c:2206 msgid "Sets the maximum allowed result for exact search by GIN." msgstr "Setzt die maximal erlaubte Anzahl Ergebnisse für eine genaue Suche mit GIN." #. translator: GUC parameter "gin_fuzzy_search_limit" long description -#: ../include/utils/guc_tables.inc.c:2207 utils/guc_tables.inc.c:2207 +#: ../include/utils/guc_tables.inc.c:2208 utils/guc_tables.inc.c:2208 msgid "0 means no limit." msgstr "0 bedeutet keine Grenze." #. translator: GUC parameter "gin_pending_list_limit" short description -#: ../include/utils/guc_tables.inc.c:2222 utils/guc_tables.inc.c:2222 +#: ../include/utils/guc_tables.inc.c:2223 utils/guc_tables.inc.c:2223 msgid "Sets the maximum size of the pending list for GIN index." msgstr "Setzt die maximale Größe der Pending-Liste eines GIN-Index." #. translator: GUC parameter "gss_accept_delegation" short description -#: ../include/utils/guc_tables.inc.c:2238 utils/guc_tables.inc.c:2238 +#: ../include/utils/guc_tables.inc.c:2239 utils/guc_tables.inc.c:2239 msgid "Sets whether GSSAPI delegation should be accepted from the client." msgstr "Bestimmt, ob GSSAPI-Delegation vom Client akzeptiert werden soll." #. translator: GUC parameter "hash_mem_multiplier" short description -#: ../include/utils/guc_tables.inc.c:2251 utils/guc_tables.inc.c:2251 +#: ../include/utils/guc_tables.inc.c:2252 utils/guc_tables.inc.c:2252 msgid "Multiple of \"work_mem\" to use for hash tables." msgstr "Vielfaches von »work_mem« zur Verwendung bei Hash-Tabellen." #. translator: GUC parameter "hba_file" short description -#: ../include/utils/guc_tables.inc.c:2267 utils/guc_tables.inc.c:2267 +#: ../include/utils/guc_tables.inc.c:2268 utils/guc_tables.inc.c:2268 msgid "Sets the server's \"hba\" configuration file." msgstr "Setzt die »hba«-Konfigurationsdatei des Servers." #. translator: GUC parameter "hosts_file" short description -#: ../include/utils/guc_tables.inc.c:2281 utils/guc_tables.inc.c:2281 +#: ../include/utils/guc_tables.inc.c:2282 utils/guc_tables.inc.c:2282 #, fuzzy #| msgid "Sets the server's \"hba\" configuration file." msgid "Sets the server's \"hosts\" configuration file." msgstr "Setzt die »hba«-Konfigurationsdatei des Servers." #. translator: GUC parameter "hot_standby" short description -#: ../include/utils/guc_tables.inc.c:2295 utils/guc_tables.inc.c:2295 +#: ../include/utils/guc_tables.inc.c:2296 utils/guc_tables.inc.c:2296 msgid "Allows connections and queries during recovery." msgstr "Erlaubt Verbindungen und Anfragen während der Wiederherstellung." #. translator: GUC parameter "hot_standby_feedback" short description -#: ../include/utils/guc_tables.inc.c:2308 utils/guc_tables.inc.c:2308 +#: ../include/utils/guc_tables.inc.c:2309 utils/guc_tables.inc.c:2309 msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." msgstr "Erlaubt Rückmeldungen von einem Hot Standby an den Primärserver, um Anfragekonflikte zu vermeiden." #. translator: GUC parameter "huge_page_size" short description -#: ../include/utils/guc_tables.inc.c:2321 utils/guc_tables.inc.c:2321 +#: ../include/utils/guc_tables.inc.c:2322 utils/guc_tables.inc.c:2322 msgid "The size of huge page that should be requested." msgstr "Huge-Page-Größe, die angefordert werden soll." @@ -1932,235 +1942,235 @@ msgstr "Huge-Page-Größe, die angefordert werden soll." #. translator: GUC parameter "tcp_keepalives_idle" long description #. translator: GUC parameter "tcp_keepalives_interval" long description #. translator: GUC parameter "tcp_user_timeout" long description -#: ../include/utils/guc_tables.inc.c:2323 -#: ../include/utils/guc_tables.inc.c:5584 -#: ../include/utils/guc_tables.inc.c:5604 -#: ../include/utils/guc_tables.inc.c:5624 utils/guc_tables.inc.c:2323 -#: utils/guc_tables.inc.c:5584 utils/guc_tables.inc.c:5604 -#: utils/guc_tables.inc.c:5624 +#: ../include/utils/guc_tables.inc.c:2324 +#: ../include/utils/guc_tables.inc.c:5585 +#: ../include/utils/guc_tables.inc.c:5605 +#: ../include/utils/guc_tables.inc.c:5625 utils/guc_tables.inc.c:2324 +#: utils/guc_tables.inc.c:5585 utils/guc_tables.inc.c:5605 +#: utils/guc_tables.inc.c:5625 msgid "0 means use the system default." msgstr "0 bedeutet, die Systemvoreinstellung zu verwenden." #. translator: GUC parameter "huge_pages" short description -#: ../include/utils/guc_tables.inc.c:2340 utils/guc_tables.inc.c:2340 +#: ../include/utils/guc_tables.inc.c:2341 utils/guc_tables.inc.c:2341 msgid "Use of huge pages on Linux or Windows." msgstr "Huge Pages auf Linux oder Windows verwenden." #. translator: GUC parameter "huge_pages_status" short description -#: ../include/utils/guc_tables.inc.c:2354 utils/guc_tables.inc.c:2354 +#: ../include/utils/guc_tables.inc.c:2355 utils/guc_tables.inc.c:2355 msgid "Indicates the status of huge pages." msgstr "Zeigt den Status von Huge Pages an." #. translator: GUC parameter "icu_validation_level" short description -#: ../include/utils/guc_tables.inc.c:2369 utils/guc_tables.inc.c:2369 +#: ../include/utils/guc_tables.inc.c:2370 utils/guc_tables.inc.c:2370 msgid "Log level for reporting invalid ICU locale strings." msgstr "Loglevel für Meldungen über ungültige ICU-Locale-Zeichenketten." #. translator: GUC parameter "ident_file" short description -#: ../include/utils/guc_tables.inc.c:2383 utils/guc_tables.inc.c:2383 +#: ../include/utils/guc_tables.inc.c:2384 utils/guc_tables.inc.c:2384 msgid "Sets the server's \"ident\" configuration file." msgstr "Setzt die »ident«-Konfigurationsdatei des Servers." #. translator: GUC parameter "idle_in_transaction_session_timeout" short description -#: ../include/utils/guc_tables.inc.c:2397 utils/guc_tables.inc.c:2397 +#: ../include/utils/guc_tables.inc.c:2398 utils/guc_tables.inc.c:2398 msgid "Sets the maximum allowed idle time between queries, when in a transaction." msgstr "Setzt die maximal erlaubte inaktive Zeit zwischen Anfragen, wenn in einer Transaktion." #. translator: GUC parameter "idle_replication_slot_timeout" short description -#: ../include/utils/guc_tables.inc.c:2415 utils/guc_tables.inc.c:2415 +#: ../include/utils/guc_tables.inc.c:2416 utils/guc_tables.inc.c:2416 msgid "Sets the duration a replication slot can remain idle before it is invalidated." msgstr "Setzt die Dauer, die ein Replikations-Slot inaktiv sein kann, bevor er ungültig gemacht wird." #. translator: GUC parameter "idle_session_timeout" short description -#: ../include/utils/guc_tables.inc.c:2431 utils/guc_tables.inc.c:2431 +#: ../include/utils/guc_tables.inc.c:2432 utils/guc_tables.inc.c:2432 msgid "Sets the maximum allowed idle time between queries, when not in a transaction." msgstr "Setzt die maximal erlaubte inaktive Zeit zwischen Anfragen, wenn nicht in einer Transaktion." #. translator: GUC parameter "ignore_checksum_failure" short description -#: ../include/utils/guc_tables.inc.c:2449 utils/guc_tables.inc.c:2449 +#: ../include/utils/guc_tables.inc.c:2450 utils/guc_tables.inc.c:2450 msgid "Continues processing after a checksum failure." msgstr "Setzt die Verarbeitung trotz Prüfsummenfehler fort." #. translator: GUC parameter "ignore_checksum_failure" long description -#: ../include/utils/guc_tables.inc.c:2451 utils/guc_tables.inc.c:2451 +#: ../include/utils/guc_tables.inc.c:2452 utils/guc_tables.inc.c:2452 msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." msgstr "Wenn eine fehlerhafte Prüfsumme entdeckt wird, gibt PostgreSQL normalerweise ein Fehler aus und bricht die aktuelle Transaktion ab. Wenn »ignore_checksum_failure« an ist, dann wird der Fehler ignoriert (aber trotzdem eine Warnung ausgegeben) und die Verarbeitung geht weiter. Dieses Verhalten kann Abstürze und andere ernsthafte Probleme verursachen. Es hat keine Auswirkungen, wenn Prüfsummen nicht eingeschaltet sind." #. translator: GUC parameter "ignore_invalid_pages" short description -#: ../include/utils/guc_tables.inc.c:2465 utils/guc_tables.inc.c:2465 +#: ../include/utils/guc_tables.inc.c:2466 utils/guc_tables.inc.c:2466 msgid "Continues recovery after an invalid pages failure." msgstr "Setzt die Wiederherstellung trotz Fehler durch ungültige Seiten fort." #. translator: GUC parameter "ignore_invalid_pages" long description -#: ../include/utils/guc_tables.inc.c:2467 utils/guc_tables.inc.c:2467 +#: ../include/utils/guc_tables.inc.c:2468 utils/guc_tables.inc.c:2468 msgid "Detection of WAL records having references to invalid pages during recovery causes PostgreSQL to raise a PANIC-level error, aborting the recovery. Setting \"ignore_invalid_pages\" to true causes the system to ignore invalid page references in WAL records (but still report a warning), and continue recovery. This behavior may cause crashes, data loss, propagate or hide corruption, or other serious problems. Only has an effect during recovery or in standby mode." msgstr "Wenn WAL-Einträge mit Verweisen auf ungültige Seiten bei der Wiederherstellung erkannt werden, verursacht das einen PANIC-Fehler, wodurch die Wiederherstellung abgebrochen wird. Wenn »ignore_invalid_pages« an ist, dann werden ungültige Seitenverweise in WAL-Einträgen ignoriert (aber trotzen eine Warnung ausgegeben) und die Wiederherstellung wird fortgesetzt. Dieses Verhalten kann Abstürze und Datenverlust verursachen, Datenverfälschung verbreiten oder verstecken sowie andere ernsthafte Probleme verursachen. Es hat nur Auswirkungen im Wiederherstellungs- oder Standby-Modus." #. translator: GUC parameter "ignore_system_indexes" short description -#: ../include/utils/guc_tables.inc.c:2481 utils/guc_tables.inc.c:2481 +#: ../include/utils/guc_tables.inc.c:2482 utils/guc_tables.inc.c:2482 msgid "Disables reading from system indexes." msgstr "Schaltet das Lesen aus Systemindexen ab." #. translator: GUC parameter "ignore_system_indexes" long description -#: ../include/utils/guc_tables.inc.c:2483 utils/guc_tables.inc.c:2483 +#: ../include/utils/guc_tables.inc.c:2484 utils/guc_tables.inc.c:2484 msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." msgstr "Das Aktualisieren der Indexe wird nicht verhindert, also ist die Verwendung unbedenklich. Schlimmstenfalls wird alles langsamer." #. translator: GUC parameter "in_hot_standby" short description -#: ../include/utils/guc_tables.inc.c:2497 utils/guc_tables.inc.c:2497 +#: ../include/utils/guc_tables.inc.c:2498 utils/guc_tables.inc.c:2498 msgid "Shows whether hot standby is currently active." msgstr "Zeigt, ob Hot Standby aktuell aktiv ist." #. translator: GUC parameter "integer_datetimes" short description -#: ../include/utils/guc_tables.inc.c:2512 utils/guc_tables.inc.c:2512 +#: ../include/utils/guc_tables.inc.c:2513 utils/guc_tables.inc.c:2513 msgid "Shows whether datetimes are integer based." msgstr "Zeigt ob Datum/Zeit intern ganze Zahlen verwendet." #. translator: GUC parameter "IntervalStyle" short description -#: ../include/utils/guc_tables.inc.c:2526 utils/guc_tables.inc.c:2526 +#: ../include/utils/guc_tables.inc.c:2527 utils/guc_tables.inc.c:2527 msgid "Sets the display format for interval values." msgstr "Setzt das Ausgabeformat für Intervallwerte." #. translator: GUC parameter "io_combine_limit" short description -#: ../include/utils/guc_tables.inc.c:2541 utils/guc_tables.inc.c:2541 +#: ../include/utils/guc_tables.inc.c:2542 utils/guc_tables.inc.c:2542 msgid "Limit on the size of data reads and writes." msgstr "Begrenzung der Größe von Datenlese- und -schreibvorgängen." #. translator: GUC parameter "io_max_combine_limit" short description -#: ../include/utils/guc_tables.inc.c:2558 utils/guc_tables.inc.c:2558 +#: ../include/utils/guc_tables.inc.c:2559 utils/guc_tables.inc.c:2559 msgid "Server-wide limit that clamps io_combine_limit." msgstr "Serverweites Limit, das io_combine_limit beschränkt." #. translator: GUC parameter "io_max_concurrency" short description -#: ../include/utils/guc_tables.inc.c:2575 utils/guc_tables.inc.c:2575 +#: ../include/utils/guc_tables.inc.c:2576 utils/guc_tables.inc.c:2576 msgid "Max number of IOs that one process can execute simultaneously." msgstr "Maximale Anzahl IOs, die ein Prozess gleichzeitig ausführen kann." #. translator: GUC parameter "io_max_workers" short description -#: ../include/utils/guc_tables.inc.c:2591 utils/guc_tables.inc.c:2591 +#: ../include/utils/guc_tables.inc.c:2592 utils/guc_tables.inc.c:2592 #, fuzzy #| msgid "Number of IO worker processes, for io_method=worker." msgid "Maximum number of I/O worker processes, for io_method=worker." msgstr "Anzahl IO-Worker-Prozesse, für io_method=worker." #. translator: GUC parameter "io_method" short description -#: ../include/utils/guc_tables.inc.c:2606 utils/guc_tables.inc.c:2606 +#: ../include/utils/guc_tables.inc.c:2607 utils/guc_tables.inc.c:2607 msgid "Selects the method for executing asynchronous I/O." msgstr "Wählt die Methode zum Ausführen von asynchronem I/O." #. translator: GUC parameter "io_min_workers" short description -#: ../include/utils/guc_tables.inc.c:2621 utils/guc_tables.inc.c:2621 +#: ../include/utils/guc_tables.inc.c:2622 utils/guc_tables.inc.c:2622 #, fuzzy #| msgid "Number of IO worker processes, for io_method=worker." msgid "Minimum number of I/O worker processes, for io_method=worker." msgstr "Anzahl IO-Worker-Prozesse, für io_method=worker." #. translator: GUC parameter "io_worker_idle_timeout" short description -#: ../include/utils/guc_tables.inc.c:2636 utils/guc_tables.inc.c:2636 +#: ../include/utils/guc_tables.inc.c:2637 utils/guc_tables.inc.c:2637 #, fuzzy #| msgid "Number of IO worker processes, for io_method=worker." msgid "Maximum time before idle I/O worker processes time out, for io_method=worker." msgstr "Anzahl IO-Worker-Prozesse, für io_method=worker." #. translator: GUC parameter "io_worker_launch_interval" short description -#: ../include/utils/guc_tables.inc.c:2652 utils/guc_tables.inc.c:2652 +#: ../include/utils/guc_tables.inc.c:2653 utils/guc_tables.inc.c:2653 #, fuzzy #| msgid "Number of IO worker processes, for io_method=worker." msgid "Minimum time before launching a new I/O worker process, for io_method=worker." msgstr "Anzahl IO-Worker-Prozesse, für io_method=worker." #. translator: GUC parameter "is_superuser" short description -#: ../include/utils/guc_tables.inc.c:2668 utils/guc_tables.inc.c:2668 +#: ../include/utils/guc_tables.inc.c:2669 utils/guc_tables.inc.c:2669 msgid "Shows whether the current user is a superuser." msgstr "Zeigt, ob der aktuelle Benutzer ein Superuser ist." #. translator: GUC parameter "jit" short description -#: ../include/utils/guc_tables.inc.c:2682 utils/guc_tables.inc.c:2682 +#: ../include/utils/guc_tables.inc.c:2683 utils/guc_tables.inc.c:2683 msgid "Allow JIT compilation." msgstr "Erlaubt JIT-Kompilierung." #. translator: GUC parameter "jit_above_cost" short description -#: ../include/utils/guc_tables.inc.c:2696 utils/guc_tables.inc.c:2696 +#: ../include/utils/guc_tables.inc.c:2697 utils/guc_tables.inc.c:2697 msgid "Perform JIT compilation if query is more expensive." msgstr "JIT-Kompilierung durchführen, wenn die Anfrage teurer ist." #. translator: GUC parameter "jit_above_cost" long description -#: ../include/utils/guc_tables.inc.c:2698 utils/guc_tables.inc.c:2698 +#: ../include/utils/guc_tables.inc.c:2699 utils/guc_tables.inc.c:2699 msgid "-1 disables JIT compilation." msgstr "-1 schaltet JIT-Kompilierung aus." #. translator: GUC parameter "jit_debugging_support" short description -#: ../include/utils/guc_tables.inc.c:2714 utils/guc_tables.inc.c:2714 +#: ../include/utils/guc_tables.inc.c:2715 utils/guc_tables.inc.c:2715 msgid "Register JIT-compiled functions with debugger." msgstr "JIT-kompilierte Funktionen im Debugger registrieren." #. translator: GUC parameter "jit_dump_bitcode" short description -#: ../include/utils/guc_tables.inc.c:2728 utils/guc_tables.inc.c:2728 +#: ../include/utils/guc_tables.inc.c:2729 utils/guc_tables.inc.c:2729 msgid "Write out LLVM bitcode to facilitate JIT debugging." msgstr "LLVM-Bitcode in Dateien schreiben, um Debuggen von JIT zu erleichtern." #. translator: GUC parameter "jit_expressions" short description -#: ../include/utils/guc_tables.inc.c:2742 utils/guc_tables.inc.c:2742 +#: ../include/utils/guc_tables.inc.c:2743 utils/guc_tables.inc.c:2743 msgid "Allow JIT compilation of expressions." msgstr "Erlaubt JIT-Kompilierung von Ausdrücken." #. translator: GUC parameter "jit_inline_above_cost" short description -#: ../include/utils/guc_tables.inc.c:2756 utils/guc_tables.inc.c:2756 +#: ../include/utils/guc_tables.inc.c:2757 utils/guc_tables.inc.c:2757 msgid "Perform JIT inlining if query is more expensive." msgstr "JIT-Inlining durchführen, wenn die Anfrage teurer ist." #. translator: GUC parameter "jit_inline_above_cost" long description -#: ../include/utils/guc_tables.inc.c:2758 utils/guc_tables.inc.c:2758 +#: ../include/utils/guc_tables.inc.c:2759 utils/guc_tables.inc.c:2759 msgid "-1 disables inlining." msgstr "-1 schaltet Inlining aus." #. translator: GUC parameter "jit_optimize_above_cost" short description -#: ../include/utils/guc_tables.inc.c:2774 utils/guc_tables.inc.c:2774 +#: ../include/utils/guc_tables.inc.c:2775 utils/guc_tables.inc.c:2775 msgid "Optimize JIT-compiled functions if query is more expensive." msgstr "JIT-kompilierte Funktionen optimieren, wenn die Anfrage teurer ist." #. translator: GUC parameter "jit_optimize_above_cost" long description -#: ../include/utils/guc_tables.inc.c:2776 utils/guc_tables.inc.c:2776 +#: ../include/utils/guc_tables.inc.c:2777 utils/guc_tables.inc.c:2777 msgid "-1 disables optimization." msgstr "-1 schaltet Optimierung aus." #. translator: GUC parameter "jit_profiling_support" short description -#: ../include/utils/guc_tables.inc.c:2792 utils/guc_tables.inc.c:2792 +#: ../include/utils/guc_tables.inc.c:2793 utils/guc_tables.inc.c:2793 msgid "Register JIT-compiled functions with perf profiler." msgstr "JIT-kompilierte Funktionen im Profiler perf registrieren." #. translator: GUC parameter "jit_provider" short description -#: ../include/utils/guc_tables.inc.c:2806 utils/guc_tables.inc.c:2806 +#: ../include/utils/guc_tables.inc.c:2807 utils/guc_tables.inc.c:2807 msgid "JIT provider to use." msgstr "Zu verwendender JIT-Provider." #. translator: GUC parameter "jit_tuple_deforming" short description -#: ../include/utils/guc_tables.inc.c:2820 utils/guc_tables.inc.c:2820 +#: ../include/utils/guc_tables.inc.c:2821 utils/guc_tables.inc.c:2821 msgid "Allow JIT compilation of tuple deforming." msgstr "Erlaubt JIT-Kompilierung von Tuple-Deforming." #. translator: GUC parameter "join_collapse_limit" short description -#: ../include/utils/guc_tables.inc.c:2834 utils/guc_tables.inc.c:2834 +#: ../include/utils/guc_tables.inc.c:2835 utils/guc_tables.inc.c:2835 msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." msgstr "Setzt die Größe der FROM-Liste, ab der JOIN-Konstrukte nicht aufgelöst werden." #. translator: GUC parameter "join_collapse_limit" long description -#: ../include/utils/guc_tables.inc.c:2836 utils/guc_tables.inc.c:2836 +#: ../include/utils/guc_tables.inc.c:2837 utils/guc_tables.inc.c:2837 msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." msgstr "Der Planer löst ausdrückliche JOIN-Konstrukte in FROM-Listen auf, wenn die daraus resultierende FROM-Liste nicht mehr als so viele Elemente haben würde." #. translator: GUC parameter "krb_caseins_users" short description -#: ../include/utils/guc_tables.inc.c:2852 utils/guc_tables.inc.c:2852 +#: ../include/utils/guc_tables.inc.c:2853 utils/guc_tables.inc.c:2853 msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." msgstr "Bestimmt, ob Groß-/Kleinschreibung bei Kerberos- und GSSAPI-Benutzernamen ignoriert werden soll." #. translator: GUC parameter "krb_server_keyfile" short description -#: ../include/utils/guc_tables.inc.c:2865 utils/guc_tables.inc.c:2865 +#: ../include/utils/guc_tables.inc.c:2866 utils/guc_tables.inc.c:2866 msgid "Sets the location of the Kerberos server key file." msgstr "Setzt den Ort der Kerberos-Server-Schlüsseldatei." #. translator: GUC parameter "lc_messages" short description -#: ../include/utils/guc_tables.inc.c:2879 utils/guc_tables.inc.c:2879 +#: ../include/utils/guc_tables.inc.c:2880 utils/guc_tables.inc.c:2880 msgid "Sets the language in which messages are displayed." msgstr "Setzt die Sprache, in der Mitteilungen ausgegeben werden." @@ -2172,215 +2182,215 @@ msgstr "Setzt die Sprache, in der Mitteilungen ausgegeben werden." #. translator: GUC parameter "lc_monetary" long description #. translator: GUC parameter "lc_numeric" long description #. translator: GUC parameter "lc_time" long description -#: ../include/utils/guc_tables.inc.c:2881 -#: ../include/utils/guc_tables.inc.c:2898 -#: ../include/utils/guc_tables.inc.c:2915 -#: ../include/utils/guc_tables.inc.c:2932 utils/guc_tables.inc.c:2881 -#: utils/guc_tables.inc.c:2898 utils/guc_tables.inc.c:2915 -#: utils/guc_tables.inc.c:2932 +#: ../include/utils/guc_tables.inc.c:2882 +#: ../include/utils/guc_tables.inc.c:2899 +#: ../include/utils/guc_tables.inc.c:2916 +#: ../include/utils/guc_tables.inc.c:2933 utils/guc_tables.inc.c:2882 +#: utils/guc_tables.inc.c:2899 utils/guc_tables.inc.c:2916 +#: utils/guc_tables.inc.c:2933 msgid "An empty string means use the operating system setting." msgstr "Eine leere Zeichenkette bedeutet, die Betriebssystemeinstellung zu verwenden." #. translator: GUC parameter "lc_monetary" short description -#: ../include/utils/guc_tables.inc.c:2896 utils/guc_tables.inc.c:2896 +#: ../include/utils/guc_tables.inc.c:2897 utils/guc_tables.inc.c:2897 msgid "Sets the locale for formatting monetary amounts." msgstr "Setzt die Locale für die Formatierung von Geldbeträgen." #. translator: GUC parameter "lc_numeric" short description -#: ../include/utils/guc_tables.inc.c:2913 utils/guc_tables.inc.c:2913 +#: ../include/utils/guc_tables.inc.c:2914 utils/guc_tables.inc.c:2914 msgid "Sets the locale for formatting numbers." msgstr "Setzt die Locale für die Formatierung von Zahlen." #. translator: GUC parameter "lc_time" short description -#: ../include/utils/guc_tables.inc.c:2930 utils/guc_tables.inc.c:2930 +#: ../include/utils/guc_tables.inc.c:2931 utils/guc_tables.inc.c:2931 msgid "Sets the locale for formatting date and time values." msgstr "Setzt die Locale für die Formatierung von Datums- und Zeitwerten." #. translator: GUC parameter "listen_addresses" short description -#: ../include/utils/guc_tables.inc.c:2947 utils/guc_tables.inc.c:2947 +#: ../include/utils/guc_tables.inc.c:2948 utils/guc_tables.inc.c:2948 msgid "Sets the host name or IP address(es) to listen to." msgstr "Setzt den Hostnamen oder die IP-Adresse(n), auf der auf Verbindungen gewartet wird." #. translator: GUC parameter "lo_compat_privileges" short description -#: ../include/utils/guc_tables.inc.c:2961 utils/guc_tables.inc.c:2961 +#: ../include/utils/guc_tables.inc.c:2962 utils/guc_tables.inc.c:2962 msgid "Enables backward compatibility mode for privilege checks on large objects." msgstr "Schaltet den rückwärtskompatiblen Modus für Privilegienprüfungen bei Large Objects ein." #. translator: GUC parameter "lo_compat_privileges" long description -#: ../include/utils/guc_tables.inc.c:2963 utils/guc_tables.inc.c:2963 +#: ../include/utils/guc_tables.inc.c:2964 utils/guc_tables.inc.c:2964 msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." msgstr "Überspringt Privilegienprüfungen beim Lesen oder Ändern von Large Objects, zur Kompatibilität mit PostgreSQL-Versionen vor 9.0." #. translator: GUC parameter "local_preload_libraries" short description -#: ../include/utils/guc_tables.inc.c:2976 utils/guc_tables.inc.c:2976 +#: ../include/utils/guc_tables.inc.c:2977 utils/guc_tables.inc.c:2977 msgid "Lists unprivileged shared libraries to preload into each backend." msgstr "Listet unprivilegierte dynamische Bibliotheken, die vorab in jeden Serverprozess geladen werden." #. translator: GUC parameter "lock_timeout" short description -#: ../include/utils/guc_tables.inc.c:2990 utils/guc_tables.inc.c:2990 +#: ../include/utils/guc_tables.inc.c:2991 utils/guc_tables.inc.c:2991 msgid "Sets the maximum allowed duration of any wait for a lock." msgstr "Setzt die maximal erlaubte Dauer, um auf eine Sperre zu warten." #. translator: GUC parameter "log_autoanalyze_min_duration" short description -#: ../include/utils/guc_tables.inc.c:3008 utils/guc_tables.inc.c:3008 +#: ../include/utils/guc_tables.inc.c:3009 utils/guc_tables.inc.c:3009 #, fuzzy #| msgid "Sets the minimum execution time above which autovacuum actions will be logged." msgid "Sets the minimum execution time above which analyze actions by autovacuum will be logged." msgstr "Setzt die minimale Ausführungszeit, über der Autovacuum-Aktionen geloggt werden." #. translator: GUC parameter "log_autoanalyze_min_duration" long description -#: ../include/utils/guc_tables.inc.c:3010 utils/guc_tables.inc.c:3010 +#: ../include/utils/guc_tables.inc.c:3011 utils/guc_tables.inc.c:3011 #, fuzzy #| msgid "-1 disables logging autovacuum actions. 0 means log all autovacuum actions." msgid "-1 disables logging analyze actions by autovacuum. 0 means log all analyze actions by autovacuum." msgstr "-1 schaltet das Loggen der Autovacuum-Aktionen aus. 0 bedeutet, alle Autovacuum-Aktionen zu loggen." #. translator: GUC parameter "log_autovacuum_min_duration" short description -#: ../include/utils/guc_tables.inc.c:3026 utils/guc_tables.inc.c:3026 +#: ../include/utils/guc_tables.inc.c:3027 utils/guc_tables.inc.c:3027 #, fuzzy #| msgid "Sets the minimum execution time above which autovacuum actions will be logged." msgid "Sets the minimum execution time above which vacuum actions by autovacuum will be logged." msgstr "Setzt die minimale Ausführungszeit, über der Autovacuum-Aktionen geloggt werden." #. translator: GUC parameter "log_autovacuum_min_duration" long description -#: ../include/utils/guc_tables.inc.c:3028 utils/guc_tables.inc.c:3028 +#: ../include/utils/guc_tables.inc.c:3029 utils/guc_tables.inc.c:3029 #, fuzzy #| msgid "-1 disables logging autovacuum actions. 0 means log all autovacuum actions." msgid "-1 disables logging vacuum actions by autovacuum. 0 means log all vacuum actions by autovacuum." msgstr "-1 schaltet das Loggen der Autovacuum-Aktionen aus. 0 bedeutet, alle Autovacuum-Aktionen zu loggen." #. translator: GUC parameter "log_btree_build_stats" short description -#: ../include/utils/guc_tables.inc.c:3045 utils/guc_tables.inc.c:3045 +#: ../include/utils/guc_tables.inc.c:3046 utils/guc_tables.inc.c:3046 msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." msgstr "Loggt Statistiken über Systemressourcen (Speicher und CPU) während diverser B-Baum-Operationen." #. translator: GUC parameter "log_checkpoints" short description -#: ../include/utils/guc_tables.inc.c:3060 utils/guc_tables.inc.c:3060 +#: ../include/utils/guc_tables.inc.c:3061 utils/guc_tables.inc.c:3061 msgid "Logs each checkpoint." msgstr "Schreibt jeden Checkpoint in den Log." #. translator: GUC parameter "log_connections" short description -#: ../include/utils/guc_tables.inc.c:3073 utils/guc_tables.inc.c:3073 +#: ../include/utils/guc_tables.inc.c:3074 utils/guc_tables.inc.c:3074 msgid "Logs specified aspects of connection establishment and setup." msgstr "Loggt die angegebenen Aspekte des Verbindungsaufbaus." #. translator: GUC parameter "log_destination" short description -#: ../include/utils/guc_tables.inc.c:3089 utils/guc_tables.inc.c:3089 +#: ../include/utils/guc_tables.inc.c:3090 utils/guc_tables.inc.c:3090 msgid "Sets the destination for server log output." msgstr "Setzt das Ziel für die Serverlogausgabe." #. translator: GUC parameter "log_destination" long description -#: ../include/utils/guc_tables.inc.c:3091 utils/guc_tables.inc.c:3091 +#: ../include/utils/guc_tables.inc.c:3092 utils/guc_tables.inc.c:3092 msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", \"jsonlog\", and \"eventlog\", depending on the platform." msgstr "Gültige Werte sind Kombinationen von »stderr«, »syslog«, »csvlog«, »jsonlog« und »eventlog«, je nach Plattform." #. translator: GUC parameter "log_directory" short description -#: ../include/utils/guc_tables.inc.c:3107 utils/guc_tables.inc.c:3107 +#: ../include/utils/guc_tables.inc.c:3108 utils/guc_tables.inc.c:3108 msgid "Sets the destination directory for log files." msgstr "Bestimmt das Zielverzeichnis für Logdateien." #. translator: GUC parameter "log_directory" long description -#: ../include/utils/guc_tables.inc.c:3109 utils/guc_tables.inc.c:3109 +#: ../include/utils/guc_tables.inc.c:3110 utils/guc_tables.inc.c:3110 msgid "Can be specified as relative to the data directory or as absolute path." msgstr "Kann relativ zum Datenverzeichnis oder als absoluter Pfad angegeben werden." #. translator: GUC parameter "log_disconnections" short description -#: ../include/utils/guc_tables.inc.c:3124 utils/guc_tables.inc.c:3124 +#: ../include/utils/guc_tables.inc.c:3125 utils/guc_tables.inc.c:3125 msgid "Logs end of a session, including duration." msgstr "Schreibt jedes Verbindungsende mit Sitzungszeit in den Log." #. translator: GUC parameter "log_duration" short description -#: ../include/utils/guc_tables.inc.c:3137 utils/guc_tables.inc.c:3137 +#: ../include/utils/guc_tables.inc.c:3138 utils/guc_tables.inc.c:3138 msgid "Logs the duration of each completed SQL statement." msgstr "Loggt die Dauer jeder abgeschlossenen SQL-Anweisung." #. translator: GUC parameter "log_error_verbosity" short description -#: ../include/utils/guc_tables.inc.c:3150 utils/guc_tables.inc.c:3150 +#: ../include/utils/guc_tables.inc.c:3151 utils/guc_tables.inc.c:3151 msgid "Sets the verbosity of logged messages." msgstr "Setzt den Detailgrad von geloggten Meldungen." #. translator: GUC parameter "log_executor_stats" short description -#: ../include/utils/guc_tables.inc.c:3164 utils/guc_tables.inc.c:3164 +#: ../include/utils/guc_tables.inc.c:3165 utils/guc_tables.inc.c:3165 msgid "Writes executor performance statistics to the server log." msgstr "Schreibt Executor-Leistungsstatistiken in den Serverlog." #. translator: GUC parameter "log_file_mode" short description -#: ../include/utils/guc_tables.inc.c:3178 utils/guc_tables.inc.c:3178 +#: ../include/utils/guc_tables.inc.c:3179 utils/guc_tables.inc.c:3179 msgid "Sets the file permissions for log files." msgstr "Setzt die Dateizugriffsrechte für Logdateien." #. translator: GUC parameter "log_file_mode" long description -#: ../include/utils/guc_tables.inc.c:3180 utils/guc_tables.inc.c:3180 +#: ../include/utils/guc_tables.inc.c:3181 utils/guc_tables.inc.c:3181 msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "Der Wert dieser Option muss ein numerischer Wert in der von den Systemaufrufen chmod und umask verwendeten Form sein. (Um das gebräuchliche Oktalformat zu verwenden, muss die Zahl mit 0 (einer Null) anfangen.)" #. translator: GUC parameter "log_filename" short description -#: ../include/utils/guc_tables.inc.c:3196 utils/guc_tables.inc.c:3196 +#: ../include/utils/guc_tables.inc.c:3197 utils/guc_tables.inc.c:3197 msgid "Sets the file name pattern for log files." msgstr "Bestimmt das Dateinamenmuster für Logdateien." #. translator: GUC parameter "log_hostname" short description -#: ../include/utils/guc_tables.inc.c:3210 utils/guc_tables.inc.c:3210 +#: ../include/utils/guc_tables.inc.c:3211 utils/guc_tables.inc.c:3211 msgid "Logs the host name in the connection logs." msgstr "Schreibt den Hostnamen jeder Verbindung in den Log." #. translator: GUC parameter "log_hostname" long description -#: ../include/utils/guc_tables.inc.c:3212 utils/guc_tables.inc.c:3212 +#: ../include/utils/guc_tables.inc.c:3213 utils/guc_tables.inc.c:3213 msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." msgstr "In der Standardeinstellung zeigen die Verbindungslogs nur die IP-Adresse der Clienthosts. Wenn Sie den Hostnamen auch anzeigen wollen, dann können Sie diese Option anschalten, aber je nachdem, wie Ihr DNS eingerichtet ist, kann das die Leistung nicht unerheblich beeinträchtigen." #. translator: GUC parameter "log_line_prefix" short description -#: ../include/utils/guc_tables.inc.c:3225 utils/guc_tables.inc.c:3225 +#: ../include/utils/guc_tables.inc.c:3226 utils/guc_tables.inc.c:3226 msgid "Controls information prefixed to each log line." msgstr "Bestimmt die Informationen, die vor jede Logzeile geschrieben werden." #. translator: GUC parameter "log_line_prefix" long description -#: ../include/utils/guc_tables.inc.c:3227 utils/guc_tables.inc.c:3227 +#: ../include/utils/guc_tables.inc.c:3228 utils/guc_tables.inc.c:3228 msgid "An empty string means no prefix." msgstr "Ein leerer Wert bedeutet, keinen Präfix zu schreiben." #. translator: GUC parameter "log_lock_failures" short description -#: ../include/utils/guc_tables.inc.c:3240 utils/guc_tables.inc.c:3240 +#: ../include/utils/guc_tables.inc.c:3241 utils/guc_tables.inc.c:3241 msgid "Logs lock failures." msgstr "Schreibt Meldungen über fehlgeschlagenes Sperren in den Log." #. translator: GUC parameter "log_lock_waits" short description -#: ../include/utils/guc_tables.inc.c:3253 utils/guc_tables.inc.c:3253 +#: ../include/utils/guc_tables.inc.c:3254 utils/guc_tables.inc.c:3254 msgid "Logs long lock waits." msgstr "Schreibt Meldungen über langes Warten auf Sperren in den Log." #. translator: GUC parameter "log_min_duration_sample" short description -#: ../include/utils/guc_tables.inc.c:3266 utils/guc_tables.inc.c:3266 +#: ../include/utils/guc_tables.inc.c:3267 utils/guc_tables.inc.c:3267 msgid "Sets the minimum execution time above which a sample of statements will be logged. Sampling is determined by \"log_statement_sample_rate\"." msgstr "Setzt die minimale Ausführungszeit, über der Stichproben aller Anweisungen geloggt werden. Die Stichproben werden durch »log_statement_sample_rate« bestimmt." #. translator: GUC parameter "log_min_duration_sample" long description -#: ../include/utils/guc_tables.inc.c:3268 utils/guc_tables.inc.c:3268 +#: ../include/utils/guc_tables.inc.c:3269 utils/guc_tables.inc.c:3269 msgid "-1 disables sampling. 0 means sample all statements." msgstr "-1 schaltet Stichproben aus. 0 bedeutet, alle Anweisungen zu einzubeziehen." #. translator: GUC parameter "log_min_duration_statement" short description -#: ../include/utils/guc_tables.inc.c:3284 utils/guc_tables.inc.c:3284 +#: ../include/utils/guc_tables.inc.c:3285 utils/guc_tables.inc.c:3285 msgid "Sets the minimum execution time above which all statements will be logged." msgstr "Setzt die minimale Ausführungszeit, über der alle Anweisungen geloggt werden." #. translator: GUC parameter "log_min_duration_statement" long description -#: ../include/utils/guc_tables.inc.c:3286 utils/guc_tables.inc.c:3286 +#: ../include/utils/guc_tables.inc.c:3287 utils/guc_tables.inc.c:3287 msgid "-1 disables logging statement durations. 0 means log all statement durations." msgstr "-1 schaltet das Loggen der Ausführungszeit aus. 0 bedeutet, die Ausführungszeit aller Anweisungen zu loggen." #. translator: GUC parameter "log_min_error_statement" short description -#: ../include/utils/guc_tables.inc.c:3302 utils/guc_tables.inc.c:3302 +#: ../include/utils/guc_tables.inc.c:3303 utils/guc_tables.inc.c:3303 msgid "Causes all statements generating error at or above this level to be logged." msgstr "Schreibt alle Anweisungen, die einen Fehler auf dieser Stufe oder höher verursachen, in den Log." #. translator: GUC parameter "log_min_messages" short description -#: ../include/utils/guc_tables.inc.c:3318 utils/guc_tables.inc.c:3318 +#: ../include/utils/guc_tables.inc.c:3319 utils/guc_tables.inc.c:3319 msgid "Sets the message levels that are logged." msgstr "Setzt die Meldungstypen, die geloggt werden." #. translator: GUC parameter "log_parameter_max_length" short description -#: ../include/utils/guc_tables.inc.c:3336 utils/guc_tables.inc.c:3336 +#: ../include/utils/guc_tables.inc.c:3337 utils/guc_tables.inc.c:3337 msgid "Sets the maximum length in bytes of data logged for bind parameter values when logging statements." msgstr "Setzt die maximale Länge in Bytes für geloggte Daten von Bind-Parametern, wenn Anfragen geloggt werden." @@ -2388,281 +2398,281 @@ msgstr "Setzt die maximale Länge in Bytes für geloggte Daten von Bind-Paramete #. translator: GUC parameter "log_parameter_max_length_on_error" long description #. translator: GUC parameter "log_parameter_max_length" long description #. translator: GUC parameter "log_parameter_max_length_on_error" long description -#: ../include/utils/guc_tables.inc.c:3338 -#: ../include/utils/guc_tables.inc.c:3356 utils/guc_tables.inc.c:3338 -#: utils/guc_tables.inc.c:3356 +#: ../include/utils/guc_tables.inc.c:3339 +#: ../include/utils/guc_tables.inc.c:3357 utils/guc_tables.inc.c:3339 +#: utils/guc_tables.inc.c:3357 msgid "-1 means log values in full." msgstr "-1 bedeutet, die vollen Werte zu loggen." #. translator: GUC parameter "log_parameter_max_length_on_error" short description -#: ../include/utils/guc_tables.inc.c:3354 utils/guc_tables.inc.c:3354 +#: ../include/utils/guc_tables.inc.c:3355 utils/guc_tables.inc.c:3355 msgid "Sets the maximum length in bytes of data logged for bind parameter values when logging statements, on error." msgstr "Setzt die maximale Länge in Bytes für bei Fehlern geloggte Daten von Bind-Parametern, wenn Anfragen geloggt werden." #. translator: GUC parameter "log_parser_stats" short description -#: ../include/utils/guc_tables.inc.c:3372 utils/guc_tables.inc.c:3372 +#: ../include/utils/guc_tables.inc.c:3373 utils/guc_tables.inc.c:3373 msgid "Writes parser performance statistics to the server log." msgstr "Schreibt Parser-Leistungsstatistiken in den Serverlog." #. translator: GUC parameter "log_planner_stats" short description -#: ../include/utils/guc_tables.inc.c:3386 utils/guc_tables.inc.c:3386 +#: ../include/utils/guc_tables.inc.c:3387 utils/guc_tables.inc.c:3387 msgid "Writes planner performance statistics to the server log." msgstr "Schreibt Planer-Leistungsstatistiken in den Serverlog." #. translator: GUC parameter "log_recovery_conflict_waits" short description -#: ../include/utils/guc_tables.inc.c:3400 utils/guc_tables.inc.c:3400 +#: ../include/utils/guc_tables.inc.c:3401 utils/guc_tables.inc.c:3401 msgid "Logs standby recovery conflict waits." msgstr "Schreibt Meldungen über Warten wegen Konflikten bei Wiederherstellung in den Log." #. translator: GUC parameter "log_replication_commands" short description -#: ../include/utils/guc_tables.inc.c:3413 utils/guc_tables.inc.c:3413 +#: ../include/utils/guc_tables.inc.c:3414 utils/guc_tables.inc.c:3414 msgid "Logs each replication command." msgstr "Schreibt jeden Replikationsbefehl in den Log." #. translator: GUC parameter "log_rotation_age" short description -#: ../include/utils/guc_tables.inc.c:3426 utils/guc_tables.inc.c:3426 +#: ../include/utils/guc_tables.inc.c:3427 utils/guc_tables.inc.c:3427 msgid "Sets the amount of time to wait before forcing log file rotation." msgstr "Setzt die Zeit, die gewartet wird, bevor Logdateirotation erzwungen wird." #. translator: GUC parameter "log_rotation_age" long description -#: ../include/utils/guc_tables.inc.c:3428 utils/guc_tables.inc.c:3428 +#: ../include/utils/guc_tables.inc.c:3429 utils/guc_tables.inc.c:3429 msgid "0 disables time-based creation of new log files." msgstr "0 schaltet zeitbasierende Erzeugung neuer Logdateien aus." #. translator: GUC parameter "log_rotation_size" short description -#: ../include/utils/guc_tables.inc.c:3444 utils/guc_tables.inc.c:3444 +#: ../include/utils/guc_tables.inc.c:3445 utils/guc_tables.inc.c:3445 msgid "Sets the maximum size a log file can reach before being rotated." msgstr "Setzt die maximale Größe, die eine Logdatei erreichen kann, bevor sie rotiert wird." #. translator: GUC parameter "log_rotation_size" long description -#: ../include/utils/guc_tables.inc.c:3446 utils/guc_tables.inc.c:3446 +#: ../include/utils/guc_tables.inc.c:3447 utils/guc_tables.inc.c:3447 msgid "0 disables size-based creation of new log files." msgstr "0 schaltet größenbasierende Erzeugung neuer Logdateien aus." #. translator: GUC parameter "log_startup_progress_interval" short description -#: ../include/utils/guc_tables.inc.c:3462 utils/guc_tables.inc.c:3462 +#: ../include/utils/guc_tables.inc.c:3463 utils/guc_tables.inc.c:3463 msgid "Time between progress updates for long-running startup operations." msgstr "Zeit zwischen Fortschrittsnachrichten für lange laufende Operationen beim Serverstart." #. translator: GUC parameter "log_startup_progress_interval" long description -#: ../include/utils/guc_tables.inc.c:3464 utils/guc_tables.inc.c:3464 +#: ../include/utils/guc_tables.inc.c:3465 utils/guc_tables.inc.c:3465 msgid "0 disables progress updates." msgstr "0 schaltet Fortschrittsnachrichten aus." #. translator: GUC parameter "log_statement" short description -#: ../include/utils/guc_tables.inc.c:3480 utils/guc_tables.inc.c:3480 +#: ../include/utils/guc_tables.inc.c:3481 utils/guc_tables.inc.c:3481 msgid "Sets the type of statements logged." msgstr "Setzt die Anweisungsarten, die geloggt werden." #. translator: GUC parameter "log_statement_sample_rate" short description -#: ../include/utils/guc_tables.inc.c:3494 utils/guc_tables.inc.c:3494 +#: ../include/utils/guc_tables.inc.c:3495 utils/guc_tables.inc.c:3495 msgid "Fraction of statements exceeding \"log_min_duration_sample\" to be logged." msgstr "Anteil der zu loggenden Anweisungen, die »log_min_duration_sample« überschreiten." #. translator: GUC parameter "log_statement_sample_rate" long description -#: ../include/utils/guc_tables.inc.c:3496 utils/guc_tables.inc.c:3496 +#: ../include/utils/guc_tables.inc.c:3497 utils/guc_tables.inc.c:3497 msgid "Use a value between 0.0 (never log) and 1.0 (always log)." msgstr "Verwenden Sie einen Wert zwischen 0.0 (nie loggen) und 1.0 (immer loggen)." #. translator: GUC parameter "log_statement_stats" short description -#: ../include/utils/guc_tables.inc.c:3511 utils/guc_tables.inc.c:3511 +#: ../include/utils/guc_tables.inc.c:3512 utils/guc_tables.inc.c:3512 msgid "Writes cumulative performance statistics to the server log." msgstr "Schreibt Gesamtleistungsstatistiken in den Serverlog." #. translator: GUC parameter "log_temp_files" short description -#: ../include/utils/guc_tables.inc.c:3525 utils/guc_tables.inc.c:3525 +#: ../include/utils/guc_tables.inc.c:3526 utils/guc_tables.inc.c:3526 msgid "Log the use of temporary files larger than this number of kilobytes." msgstr "Schreibt Meldungen über die Verwendung von temporären Dateien in den Log, wenn sie größer als diese Anzahl an Kilobytes sind." #. translator: GUC parameter "log_temp_files" long description -#: ../include/utils/guc_tables.inc.c:3527 utils/guc_tables.inc.c:3527 +#: ../include/utils/guc_tables.inc.c:3528 utils/guc_tables.inc.c:3528 msgid "-1 disables logging temporary files. 0 means log all temporary files." msgstr "-1 schaltet Loggen von temporären Dateien aus. 0 bedeutet, dass alle temporären Dateien geloggt werden." #. translator: GUC parameter "log_timezone" short description -#: ../include/utils/guc_tables.inc.c:3543 utils/guc_tables.inc.c:3543 +#: ../include/utils/guc_tables.inc.c:3544 utils/guc_tables.inc.c:3544 msgid "Sets the time zone to use in log messages." msgstr "Setzt die in Logmeldungen verwendete Zeitzone." #. translator: GUC parameter "log_transaction_sample_rate" short description -#: ../include/utils/guc_tables.inc.c:3559 utils/guc_tables.inc.c:3559 +#: ../include/utils/guc_tables.inc.c:3560 utils/guc_tables.inc.c:3560 msgid "Sets the fraction of transactions from which to log all statements." msgstr "Setzt den Bruchteil der Transaktionen, aus denen alle Anweisungen geloggt werden." #. translator: GUC parameter "log_transaction_sample_rate" long description -#: ../include/utils/guc_tables.inc.c:3561 utils/guc_tables.inc.c:3561 +#: ../include/utils/guc_tables.inc.c:3562 utils/guc_tables.inc.c:3562 msgid "Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." msgstr "Verwenden Sie einen Wert zwischen 0.0 (nie loggen) und 1.0 (alle Anweisungen für alle Transaktionen loggen)." #. translator: GUC parameter "log_truncate_on_rotation" short description -#: ../include/utils/guc_tables.inc.c:3576 utils/guc_tables.inc.c:3576 +#: ../include/utils/guc_tables.inc.c:3577 utils/guc_tables.inc.c:3577 msgid "Truncate existing log files of same name during log rotation." msgstr "Kürzt existierende Logdateien mit dem selben Namen beim Rotieren." #. translator: GUC parameter "logging_collector" short description -#: ../include/utils/guc_tables.inc.c:3589 utils/guc_tables.inc.c:3589 +#: ../include/utils/guc_tables.inc.c:3590 utils/guc_tables.inc.c:3590 msgid "Start a subprocess to capture stderr, csvlog and/or jsonlog into log files." msgstr "Startet einen Subprozess, um stderr, csvlog und/oder jsonlog in Logdateien auszugeben." #. translator: GUC parameter "logical_decoding_work_mem" short description -#: ../include/utils/guc_tables.inc.c:3602 utils/guc_tables.inc.c:3602 +#: ../include/utils/guc_tables.inc.c:3603 utils/guc_tables.inc.c:3603 msgid "Sets the maximum memory to be used for logical decoding." msgstr "Setzt die maximale Speichergröße für logische Dekodierung." #. translator: GUC parameter "logical_decoding_work_mem" long description -#: ../include/utils/guc_tables.inc.c:3604 utils/guc_tables.inc.c:3604 +#: ../include/utils/guc_tables.inc.c:3605 utils/guc_tables.inc.c:3605 msgid "This much memory can be used by each internal reorder buffer before spilling to disk." msgstr "Gibt die Speichermenge an, die für jeden internen Reorder-Puffer verwendet werden kann, bevor auf Festplatte ausgelagert wird." #. translator: GUC parameter "maintenance_io_concurrency" short description -#: ../include/utils/guc_tables.inc.c:3620 utils/guc_tables.inc.c:3620 +#: ../include/utils/guc_tables.inc.c:3621 utils/guc_tables.inc.c:3621 msgid "A variant of \"effective_io_concurrency\" that is used for maintenance work." msgstr "Eine Variante von »effective_io_concurrency«, die für Wartungsarbeiten verwendet wird." #. translator: GUC parameter "maintenance_work_mem" short description -#: ../include/utils/guc_tables.inc.c:3639 utils/guc_tables.inc.c:3639 +#: ../include/utils/guc_tables.inc.c:3640 utils/guc_tables.inc.c:3640 msgid "Sets the maximum memory to be used for maintenance operations." msgstr "Setzt die maximale Speichergröße für Wartungsoperationen." #. translator: GUC parameter "maintenance_work_mem" long description -#: ../include/utils/guc_tables.inc.c:3641 utils/guc_tables.inc.c:3641 +#: ../include/utils/guc_tables.inc.c:3642 utils/guc_tables.inc.c:3642 msgid "This includes operations such as VACUUM and CREATE INDEX." msgstr "Das schließt Operationen wie VACUUM und CREATE INDEX ein." #. translator: GUC parameter "max_active_replication_origins" short description -#: ../include/utils/guc_tables.inc.c:3657 utils/guc_tables.inc.c:3657 +#: ../include/utils/guc_tables.inc.c:3658 utils/guc_tables.inc.c:3658 msgid "Sets the maximum number of active replication origins." msgstr "Setzt die maximale Anzahl aktiver Replication-Origins." #. translator: GUC parameter "max_connections" short description -#: ../include/utils/guc_tables.inc.c:3672 utils/guc_tables.inc.c:3672 +#: ../include/utils/guc_tables.inc.c:3673 utils/guc_tables.inc.c:3673 msgid "Sets the maximum number of concurrent connections." msgstr "Setzt die maximale Anzahl gleichzeitiger Verbindungen." #. translator: GUC parameter "max_files_per_process" short description -#: ../include/utils/guc_tables.inc.c:3687 utils/guc_tables.inc.c:3687 +#: ../include/utils/guc_tables.inc.c:3688 utils/guc_tables.inc.c:3688 msgid "Sets the maximum number of files each server process is allowed to open simultaneously." msgstr "Setzt die maximale Zahl Dateien, die jeder Serverprozess gleichzeitig öffnen darf." #. translator: GUC parameter "max_function_args" short description -#: ../include/utils/guc_tables.inc.c:3702 utils/guc_tables.inc.c:3702 +#: ../include/utils/guc_tables.inc.c:3703 utils/guc_tables.inc.c:3703 msgid "Shows the maximum number of function arguments." msgstr "Setzt die maximale Anzahl von Funktionsargumenten." #. translator: GUC parameter "max_identifier_length" short description -#: ../include/utils/guc_tables.inc.c:3718 utils/guc_tables.inc.c:3718 +#: ../include/utils/guc_tables.inc.c:3719 utils/guc_tables.inc.c:3719 msgid "Shows the maximum identifier length." msgstr "Zeigt die maximale Länge von Bezeichnern." #. translator: GUC parameter "max_index_keys" short description -#: ../include/utils/guc_tables.inc.c:3734 utils/guc_tables.inc.c:3734 +#: ../include/utils/guc_tables.inc.c:3735 utils/guc_tables.inc.c:3735 msgid "Shows the maximum number of index keys." msgstr "Zeigt die maximale Anzahl von Indexschlüsseln." #. translator: GUC parameter "max_locks_per_transaction" short description -#: ../include/utils/guc_tables.inc.c:3750 utils/guc_tables.inc.c:3750 +#: ../include/utils/guc_tables.inc.c:3751 utils/guc_tables.inc.c:3751 msgid "Sets the maximum number of locks per transaction." msgstr "Setzt die maximale Anzahl Sperren pro Transaktion." #. translator: GUC parameter "max_locks_per_transaction" long description -#: ../include/utils/guc_tables.inc.c:3752 utils/guc_tables.inc.c:3752 +#: ../include/utils/guc_tables.inc.c:3753 utils/guc_tables.inc.c:3753 msgid "The shared lock table is sized on the assumption that at most \"max_locks_per_transaction\" objects per server process or prepared transaction will need to be locked at any one time." msgstr "Die globale Sperrentabelle wird mit der Annahme angelegt, das höchstens »max_locks_per_transaction« Objekte pro Serverprozess oder vorbereitete Transaktion gleichzeitig gesperrt werden müssen." #. translator: GUC parameter "max_logical_replication_workers" short description -#: ../include/utils/guc_tables.inc.c:3767 utils/guc_tables.inc.c:3767 +#: ../include/utils/guc_tables.inc.c:3768 utils/guc_tables.inc.c:3768 msgid "Maximum number of logical replication worker processes." msgstr "Maximale Anzahl Arbeitsprozesse für logische Replikation." #. translator: GUC parameter "max_notify_queue_pages" short description -#: ../include/utils/guc_tables.inc.c:3782 utils/guc_tables.inc.c:3782 +#: ../include/utils/guc_tables.inc.c:3783 utils/guc_tables.inc.c:3783 msgid "Sets the maximum number of allocated pages for NOTIFY / LISTEN queue." msgstr "Setzt die maximale Anzahl bereitgestellte Seiten für die NOTIFY/LISTEN-Warteschlange." #. translator: GUC parameter "max_parallel_apply_workers_per_subscription" short description -#: ../include/utils/guc_tables.inc.c:3797 utils/guc_tables.inc.c:3797 +#: ../include/utils/guc_tables.inc.c:3798 utils/guc_tables.inc.c:3798 msgid "Maximum number of parallel apply workers per subscription." msgstr "Maximale Anzahl Parallel-Apply-Worker pro Subskription." #. translator: GUC parameter "max_parallel_maintenance_workers" short description -#: ../include/utils/guc_tables.inc.c:3812 utils/guc_tables.inc.c:3812 +#: ../include/utils/guc_tables.inc.c:3813 utils/guc_tables.inc.c:3813 msgid "Sets the maximum number of parallel processes per maintenance operation." msgstr "Setzt die maximale Anzahl paralleler Prozesse pro Wartungsoperation." #. translator: GUC parameter "max_parallel_workers" short description -#: ../include/utils/guc_tables.inc.c:3827 utils/guc_tables.inc.c:3827 +#: ../include/utils/guc_tables.inc.c:3828 utils/guc_tables.inc.c:3828 msgid "Sets the maximum number of parallel workers that can be active at one time." msgstr "Setzt die maximale Anzahl paralleler Arbeitsprozesse, die gleichzeitig aktiv sein können." #. translator: GUC parameter "max_parallel_workers_per_gather" short description -#: ../include/utils/guc_tables.inc.c:3843 utils/guc_tables.inc.c:3843 +#: ../include/utils/guc_tables.inc.c:3844 utils/guc_tables.inc.c:3844 msgid "Sets the maximum number of parallel processes per executor node." msgstr "Setzt die maximale Anzahl paralleler Prozesse pro Executor-Knoten." #. translator: GUC parameter "max_pred_locks_per_page" short description -#: ../include/utils/guc_tables.inc.c:3859 utils/guc_tables.inc.c:3859 +#: ../include/utils/guc_tables.inc.c:3860 utils/guc_tables.inc.c:3860 msgid "Sets the maximum number of predicate-locked tuples per page." msgstr "Setzt die maximale Anzahl Prädikatsperren für Tupel pro Seite." #. translator: GUC parameter "max_pred_locks_per_page" long description -#: ../include/utils/guc_tables.inc.c:3861 utils/guc_tables.inc.c:3861 +#: ../include/utils/guc_tables.inc.c:3862 utils/guc_tables.inc.c:3862 msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." msgstr "Wenn mehr als diese Anzahl Tupel auf der selben Seite von einer Verbindung gesperrt sind, werden diese Sperren durch eine Sperre auf Seitenebene ersetzt." #. translator: GUC parameter "max_pred_locks_per_relation" short description -#: ../include/utils/guc_tables.inc.c:3876 utils/guc_tables.inc.c:3876 +#: ../include/utils/guc_tables.inc.c:3877 utils/guc_tables.inc.c:3877 msgid "Sets the maximum number of predicate-locked pages and tuples per relation." msgstr "Setzt die maximale Anzahl Prädikatsperren für Seiten und Tupel pro Relation." #. translator: GUC parameter "max_pred_locks_per_relation" long description -#: ../include/utils/guc_tables.inc.c:3878 utils/guc_tables.inc.c:3878 +#: ../include/utils/guc_tables.inc.c:3879 utils/guc_tables.inc.c:3879 msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." msgstr "Wenn mehr als diese Gesamtzahl Seiten und Tupel in der selben Relation von einer Verbindung gesperrt sind, werden diese Sperren durch eine Sperre auf Relationsebene ersetzt." #. translator: GUC parameter "max_pred_locks_per_transaction" short description -#: ../include/utils/guc_tables.inc.c:3893 utils/guc_tables.inc.c:3893 +#: ../include/utils/guc_tables.inc.c:3894 utils/guc_tables.inc.c:3894 msgid "Sets the maximum number of predicate locks per transaction." msgstr "Setzt die maximale Anzahl Prädikatsperren pro Transaktion." #. translator: GUC parameter "max_pred_locks_per_transaction" long description -#: ../include/utils/guc_tables.inc.c:3895 utils/guc_tables.inc.c:3895 +#: ../include/utils/guc_tables.inc.c:3896 utils/guc_tables.inc.c:3896 msgid "The shared predicate lock table is sized on the assumption that at most \"max_pred_locks_per_transaction\" objects per server process or prepared transaction will need to be locked at any one time." msgstr "Die globale Prädikatsperrentabelle wird mit der Annahme angelegt, das höchstens »max_pred_locks_per_transaction« Objekte pro Serverprozess oder vorbereitete Transaktion gleichzeitig gesperrt werden müssen." #. translator: GUC parameter "max_prepared_transactions" short description -#: ../include/utils/guc_tables.inc.c:3910 utils/guc_tables.inc.c:3910 +#: ../include/utils/guc_tables.inc.c:3911 utils/guc_tables.inc.c:3911 msgid "Sets the maximum number of simultaneously prepared transactions." msgstr "Setzt die maximale Anzahl von gleichzeitig vorbereiteten Transaktionen." #. translator: GUC parameter "max_repack_replication_slots" short description -#: ../include/utils/guc_tables.inc.c:3925 utils/guc_tables.inc.c:3925 +#: ../include/utils/guc_tables.inc.c:3926 utils/guc_tables.inc.c:3926 #, fuzzy #| msgid "Sets the maximum number of active replication origins." msgid "Sets the maximum number of replication slots for use by REPACK." msgstr "Setzt die maximale Anzahl aktiver Replication-Origins." #. translator: GUC parameter "max_replication_slots" short description -#: ../include/utils/guc_tables.inc.c:3940 utils/guc_tables.inc.c:3940 +#: ../include/utils/guc_tables.inc.c:3941 utils/guc_tables.inc.c:3941 msgid "Sets the maximum number of simultaneously defined replication slots." msgstr "Setzt die maximale Anzahl von gleichzeitig definierten Replikations-Slots." #. translator: GUC parameter "max_slot_wal_keep_size" short description -#: ../include/utils/guc_tables.inc.c:3955 utils/guc_tables.inc.c:3955 +#: ../include/utils/guc_tables.inc.c:3956 utils/guc_tables.inc.c:3956 msgid "Sets the maximum WAL size that can be reserved by replication slots." msgstr "Setzt die maximale WAL-Größe, die von Replikations-Slots reserviert werden kann." #. translator: GUC parameter "max_slot_wal_keep_size" long description -#: ../include/utils/guc_tables.inc.c:3957 utils/guc_tables.inc.c:3957 +#: ../include/utils/guc_tables.inc.c:3958 utils/guc_tables.inc.c:3958 msgid "Replication slots will be marked as failed, and segments released for deletion or recycling, if this much space is occupied by WAL on disk. -1 means no maximum." msgstr "Replikations-Slots werden als fehlgeschlagen markiert, und Segmente zum Löschen oder Wiederverwenden freigegeben, wenn so viel Platz von WAL auf der Festplatte belegt wird. -1 bedeutet kein Maximum." #. translator: GUC parameter "max_stack_depth" short description -#: ../include/utils/guc_tables.inc.c:3973 utils/guc_tables.inc.c:3973 +#: ../include/utils/guc_tables.inc.c:3974 utils/guc_tables.inc.c:3974 msgid "Sets the maximum stack depth, in kilobytes." msgstr "Setzt die maximale Stackgröße, in Kilobytes." #. translator: GUC parameter "max_standby_archive_delay" short description -#: ../include/utils/guc_tables.inc.c:3991 utils/guc_tables.inc.c:3991 +#: ../include/utils/guc_tables.inc.c:3992 utils/guc_tables.inc.c:3992 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." msgstr "Setzt die maximale Verzögerung bevor Anfragen storniert werden, wenn ein Hot-Standby-Server archivierte WAL-Daten verarbeitet." @@ -2670,161 +2680,161 @@ msgstr "Setzt die maximale Verzögerung bevor Anfragen storniert werden, wenn ei #. translator: GUC parameter "max_standby_streaming_delay" long description #. translator: GUC parameter "max_standby_archive_delay" long description #. translator: GUC parameter "max_standby_streaming_delay" long description -#: ../include/utils/guc_tables.inc.c:3993 -#: ../include/utils/guc_tables.inc.c:4011 utils/guc_tables.inc.c:3993 -#: utils/guc_tables.inc.c:4011 +#: ../include/utils/guc_tables.inc.c:3994 +#: ../include/utils/guc_tables.inc.c:4012 utils/guc_tables.inc.c:3994 +#: utils/guc_tables.inc.c:4012 msgid "-1 means wait forever." msgstr "-1 bedeutet ewig warten." #. translator: GUC parameter "max_standby_streaming_delay" short description -#: ../include/utils/guc_tables.inc.c:4009 utils/guc_tables.inc.c:4009 +#: ../include/utils/guc_tables.inc.c:4010 utils/guc_tables.inc.c:4010 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." msgstr "Setzt die maximale Verzögerung bevor Anfragen storniert werden, wenn ein Hot-Standby-Server gestreamte WAL-Daten verarbeitet." #. translator: GUC parameter "max_sync_workers_per_subscription" short description -#: ../include/utils/guc_tables.inc.c:4027 utils/guc_tables.inc.c:4027 +#: ../include/utils/guc_tables.inc.c:4028 utils/guc_tables.inc.c:4028 #, fuzzy #| msgid "Maximum number of parallel apply workers per subscription." msgid "Maximum number of workers per subscription for synchronizing tables and sequences." msgstr "Maximale Anzahl Parallel-Apply-Worker pro Subskription." #. translator: GUC parameter "max_wal_senders" short description -#: ../include/utils/guc_tables.inc.c:4042 utils/guc_tables.inc.c:4042 +#: ../include/utils/guc_tables.inc.c:4043 utils/guc_tables.inc.c:4043 msgid "Sets the maximum number of simultaneously running WAL sender processes." msgstr "Setzt die maximale Anzahl gleichzeitig laufender WAL-Sender-Prozesse." #. translator: GUC parameter "max_wal_size" short description -#: ../include/utils/guc_tables.inc.c:4057 utils/guc_tables.inc.c:4057 +#: ../include/utils/guc_tables.inc.c:4058 utils/guc_tables.inc.c:4058 msgid "Sets the WAL size that triggers a checkpoint." msgstr "Setzt die WAL-Größe, die einen Checkpoint auslöst." #. translator: GUC parameter "max_worker_processes" short description -#: ../include/utils/guc_tables.inc.c:4074 utils/guc_tables.inc.c:4074 +#: ../include/utils/guc_tables.inc.c:4075 utils/guc_tables.inc.c:4075 msgid "Maximum number of concurrent worker processes." msgstr "Maximale Anzahl gleichzeitiger Worker-Prozesse." #. translator: GUC parameter "md5_password_warnings" short description -#: ../include/utils/guc_tables.inc.c:4089 utils/guc_tables.inc.c:4089 +#: ../include/utils/guc_tables.inc.c:4090 utils/guc_tables.inc.c:4090 msgid "Enables deprecation warnings for MD5 passwords." msgstr "Ermöglicht Warnungen über veraltete Verwendung von MD5-Passwörtern." #. translator: GUC parameter "min_dynamic_shared_memory" short description -#: ../include/utils/guc_tables.inc.c:4102 utils/guc_tables.inc.c:4102 +#: ../include/utils/guc_tables.inc.c:4103 utils/guc_tables.inc.c:4103 msgid "Amount of dynamic shared memory reserved at startup." msgstr "Menge des beim Start reservierten dynamischen Shared Memory." #. translator: GUC parameter "min_eager_agg_group_size" short description -#: ../include/utils/guc_tables.inc.c:4118 utils/guc_tables.inc.c:4118 +#: ../include/utils/guc_tables.inc.c:4119 utils/guc_tables.inc.c:4119 msgid "Sets the minimum average group size required to consider applying eager aggregation." msgstr "" #. translator: GUC parameter "min_parallel_index_scan_size" short description -#: ../include/utils/guc_tables.inc.c:4134 utils/guc_tables.inc.c:4134 +#: ../include/utils/guc_tables.inc.c:4135 utils/guc_tables.inc.c:4135 msgid "Sets the minimum amount of index data for a parallel scan." msgstr "Setzt die Mindestmenge an Indexdaten für einen parallelen Scan." #. translator: GUC parameter "min_parallel_index_scan_size" long description -#: ../include/utils/guc_tables.inc.c:4136 utils/guc_tables.inc.c:4136 +#: ../include/utils/guc_tables.inc.c:4137 utils/guc_tables.inc.c:4137 msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." msgstr "Wenn der Planer schätzt, dass zu wenige Indexseiten gelesen werden werden um diesen Wert zu erreichen, dann wird kein paralleler Scan in Erwägung gezogen werden." #. translator: GUC parameter "min_parallel_table_scan_size" short description -#: ../include/utils/guc_tables.inc.c:4152 utils/guc_tables.inc.c:4152 +#: ../include/utils/guc_tables.inc.c:4153 utils/guc_tables.inc.c:4153 msgid "Sets the minimum amount of table data for a parallel scan." msgstr "Setzt die Mindestmenge an Tabellendaten für einen parallelen Scan." #. translator: GUC parameter "min_parallel_table_scan_size" long description -#: ../include/utils/guc_tables.inc.c:4154 utils/guc_tables.inc.c:4154 +#: ../include/utils/guc_tables.inc.c:4155 utils/guc_tables.inc.c:4155 msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." msgstr "Wenn der Planer schätzt, dass zu wenige Tabellenseiten gelesen werden werden um diesen Wert zu erreichen, dann wird kein paralleler Scan in Erwägung gezogen werden." #. translator: GUC parameter "min_wal_size" short description -#: ../include/utils/guc_tables.inc.c:4170 utils/guc_tables.inc.c:4170 +#: ../include/utils/guc_tables.inc.c:4171 utils/guc_tables.inc.c:4171 msgid "Sets the minimum size to shrink the WAL to." msgstr "Setzt die minimale Größe, auf die der WAL geschrumpft wird." #. translator: GUC parameter "multixact_member_buffers" short description -#: ../include/utils/guc_tables.inc.c:4186 utils/guc_tables.inc.c:4186 +#: ../include/utils/guc_tables.inc.c:4187 utils/guc_tables.inc.c:4187 msgid "Sets the size of the dedicated buffer pool used for the MultiXact member cache." msgstr "Setzt die Größe des für den MultiXact-Member-Cache bestimmten Buffer-Pools." #. translator: GUC parameter "multixact_offset_buffers" short description -#: ../include/utils/guc_tables.inc.c:4203 utils/guc_tables.inc.c:4203 +#: ../include/utils/guc_tables.inc.c:4204 utils/guc_tables.inc.c:4204 msgid "Sets the size of the dedicated buffer pool used for the MultiXact offset cache." msgstr "Setzt die Größe des für den MultiXact-Offset-Cache bestimmten Buffer-Pools." #. translator: GUC parameter "notify_buffers" short description -#: ../include/utils/guc_tables.inc.c:4220 utils/guc_tables.inc.c:4220 +#: ../include/utils/guc_tables.inc.c:4221 utils/guc_tables.inc.c:4221 msgid "Sets the size of the dedicated buffer pool used for the LISTEN/NOTIFY message cache." msgstr "Setzt die Größe des für den LISTEN/NOTIFY-Message-Cache bestimmten Buffer-Pools." #. translator: GUC parameter "num_os_semaphores" short description -#: ../include/utils/guc_tables.inc.c:4237 utils/guc_tables.inc.c:4237 +#: ../include/utils/guc_tables.inc.c:4238 utils/guc_tables.inc.c:4238 msgid "Shows the number of semaphores required for the server." msgstr "Zeigt die Anzahl der vom Server benötigten Semaphore." #. translator: GUC parameter "oauth_validator_libraries" short description -#: ../include/utils/guc_tables.inc.c:4253 utils/guc_tables.inc.c:4253 +#: ../include/utils/guc_tables.inc.c:4254 utils/guc_tables.inc.c:4254 msgid "Lists libraries that may be called to validate OAuth v2 bearer tokens." msgstr "Listet Bibliotheken, die aufgerufen werden können, um OAuth-v2-Bearer-Tokens zu validieren." #. translator: GUC parameter "optimize_bounded_sort" short description -#: ../include/utils/guc_tables.inc.c:4268 utils/guc_tables.inc.c:4268 +#: ../include/utils/guc_tables.inc.c:4269 utils/guc_tables.inc.c:4269 msgid "Enables bounded sorting using heap sort." msgstr "Ermöglicht Bounded Sorting mittels Heap-Sort." #. translator: GUC parameter "parallel_leader_participation" short description -#: ../include/utils/guc_tables.inc.c:4283 utils/guc_tables.inc.c:4283 +#: ../include/utils/guc_tables.inc.c:4284 utils/guc_tables.inc.c:4284 msgid "Controls whether Gather and Gather Merge also run subplans." msgstr "Kontrolliert, ob Gather und Gather Merge auch Subpläne ausführen." #. translator: GUC parameter "parallel_leader_participation" long description -#: ../include/utils/guc_tables.inc.c:4285 utils/guc_tables.inc.c:4285 +#: ../include/utils/guc_tables.inc.c:4286 utils/guc_tables.inc.c:4286 msgid "Should gather nodes also run subplans or just gather tuples?" msgstr "Sollen Gather-Knoten auch Subpläne ausführen oder nur Tupel sammeln?" #. translator: GUC parameter "parallel_setup_cost" short description -#: ../include/utils/guc_tables.inc.c:4299 utils/guc_tables.inc.c:4299 +#: ../include/utils/guc_tables.inc.c:4300 utils/guc_tables.inc.c:4300 msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." msgstr "Setzt den vom Planer geschätzten Aufwand für das Starten von Arbeitsprozessen für parallele Anfragen." #. translator: GUC parameter "parallel_tuple_cost" short description -#: ../include/utils/guc_tables.inc.c:4315 utils/guc_tables.inc.c:4315 +#: ../include/utils/guc_tables.inc.c:4316 utils/guc_tables.inc.c:4316 msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to leader backend." msgstr "Setzt den vom Planer geschätzten Aufwand, um eine Zeile vom Arbeitsprozess an das Leader-Backend zu senden." #. translator: GUC parameter "password_encryption" short description -#: ../include/utils/guc_tables.inc.c:4331 utils/guc_tables.inc.c:4331 +#: ../include/utils/guc_tables.inc.c:4332 utils/guc_tables.inc.c:4332 msgid "Chooses the algorithm for encrypting passwords." msgstr "Wählt den Algorithmus zum Verschlüsseln von Passwörtern." #. translator: GUC parameter "password_expiration_warning_threshold" short description -#: ../include/utils/guc_tables.inc.c:4345 utils/guc_tables.inc.c:4345 +#: ../include/utils/guc_tables.inc.c:4346 utils/guc_tables.inc.c:4346 msgid "Threshold for password expiration warnings." msgstr "" #. translator: GUC parameter "password_expiration_warning_threshold" long description -#: ../include/utils/guc_tables.inc.c:4347 utils/guc_tables.inc.c:4347 +#: ../include/utils/guc_tables.inc.c:4348 utils/guc_tables.inc.c:4348 msgid "0 means not to emit these warnings." msgstr "" #. translator: GUC parameter "plan_cache_mode" short description -#: ../include/utils/guc_tables.inc.c:4363 utils/guc_tables.inc.c:4363 +#: ../include/utils/guc_tables.inc.c:4364 utils/guc_tables.inc.c:4364 msgid "Controls the planner's selection of custom or generic plan." msgstr "Kontrolliert, ob der Planer einen maßgeschneiderten oder einen allgemeinen Plan verwendet." #. translator: GUC parameter "plan_cache_mode" long description -#: ../include/utils/guc_tables.inc.c:4365 utils/guc_tables.inc.c:4365 +#: ../include/utils/guc_tables.inc.c:4366 utils/guc_tables.inc.c:4366 msgid "Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better. This can be set to override the default behavior." msgstr "Vorbereitete Anweisungen können maßgeschneiderte oder allgemeine Pläne haben und der Planer wird versuchen, den besseren auszuwählen. Diese Einstellung kann das Standardverhalten außer Kraft setzen." #. translator: GUC parameter "port" short description -#: ../include/utils/guc_tables.inc.c:4380 utils/guc_tables.inc.c:4380 +#: ../include/utils/guc_tables.inc.c:4381 utils/guc_tables.inc.c:4381 msgid "Sets the TCP port the server listens on." msgstr "Setzt den TCP-Port, auf dem der Server auf Verbindungen wartet." #. translator: GUC parameter "post_auth_delay" short description -#: ../include/utils/guc_tables.inc.c:4395 utils/guc_tables.inc.c:4395 +#: ../include/utils/guc_tables.inc.c:4396 utils/guc_tables.inc.c:4396 msgid "Sets the amount of time to wait after authentication on connection startup." msgstr "Setzt die Zeit, die nach der Authentifizierung beim Verbindungsstart gewartet wird." @@ -2832,915 +2842,915 @@ msgstr "Setzt die Zeit, die nach der Authentifizierung beim Verbindungsstart gew #. translator: GUC parameter "pre_auth_delay" long description #. translator: GUC parameter "post_auth_delay" long description #. translator: GUC parameter "pre_auth_delay" long description -#: ../include/utils/guc_tables.inc.c:4397 -#: ../include/utils/guc_tables.inc.c:4415 utils/guc_tables.inc.c:4397 -#: utils/guc_tables.inc.c:4415 +#: ../include/utils/guc_tables.inc.c:4398 +#: ../include/utils/guc_tables.inc.c:4416 utils/guc_tables.inc.c:4398 +#: utils/guc_tables.inc.c:4416 msgid "This allows attaching a debugger to the process." msgstr "Das ermöglicht es, einen Debugger in den Prozess einzuhängen." #. translator: GUC parameter "pre_auth_delay" short description -#: ../include/utils/guc_tables.inc.c:4413 utils/guc_tables.inc.c:4413 +#: ../include/utils/guc_tables.inc.c:4414 utils/guc_tables.inc.c:4414 msgid "Sets the amount of time to wait before authentication on connection startup." msgstr "Setzt die Zeit, die vor der Authentifizierung beim Verbindungsstart gewartet wird." #. translator: GUC parameter "primary_conninfo" short description -#: ../include/utils/guc_tables.inc.c:4431 utils/guc_tables.inc.c:4431 +#: ../include/utils/guc_tables.inc.c:4432 utils/guc_tables.inc.c:4432 msgid "Sets the connection string to be used to connect to the sending server." msgstr "Setzt die Verbindungszeichenkette zur Verbindung mit dem sendenden Server." #. translator: GUC parameter "primary_slot_name" short description -#: ../include/utils/guc_tables.inc.c:4445 utils/guc_tables.inc.c:4445 +#: ../include/utils/guc_tables.inc.c:4446 utils/guc_tables.inc.c:4446 msgid "Sets the name of the replication slot to use on the sending server." msgstr "Setzt den Namen des zu verwendenden Replikations-Slots auf dem sendenden Server." #. translator: GUC parameter "quote_all_identifiers" short description -#: ../include/utils/guc_tables.inc.c:4459 utils/guc_tables.inc.c:4459 +#: ../include/utils/guc_tables.inc.c:4460 utils/guc_tables.inc.c:4460 msgid "When generating SQL fragments, quote all identifiers." msgstr "Wenn SQL-Fragmente erzeugt werden, alle Bezeichner quoten." #. translator: GUC parameter "random_page_cost" short description -#: ../include/utils/guc_tables.inc.c:4472 utils/guc_tables.inc.c:4472 +#: ../include/utils/guc_tables.inc.c:4473 utils/guc_tables.inc.c:4473 msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." msgstr "Setzt den vom Planer geschätzten Aufwand, um eine nichtsequenzielle Diskseite zu lesen." #. translator: GUC parameter "recovery_end_command" short description -#: ../include/utils/guc_tables.inc.c:4488 utils/guc_tables.inc.c:4488 +#: ../include/utils/guc_tables.inc.c:4489 utils/guc_tables.inc.c:4489 msgid "Sets the shell command that will be executed once at the end of recovery." msgstr "Setzt den Shell-Befehl, der einmal am Ende der Wiederherstellung ausgeführt wird." #. translator: GUC parameter "recovery_init_sync_method" short description -#: ../include/utils/guc_tables.inc.c:4501 utils/guc_tables.inc.c:4501 +#: ../include/utils/guc_tables.inc.c:4502 utils/guc_tables.inc.c:4502 msgid "Sets the method for synchronizing the data directory before crash recovery." msgstr "Setzt die Methode für das Synchronisieren des Datenverzeichnisses vor der Wiederherstellung nach einem Absturz." #. translator: GUC parameter "recovery_min_apply_delay" short description -#: ../include/utils/guc_tables.inc.c:4515 utils/guc_tables.inc.c:4515 +#: ../include/utils/guc_tables.inc.c:4516 utils/guc_tables.inc.c:4516 msgid "Sets the minimum delay for applying changes during recovery." msgstr "Setzt die minimale Verzögerung für das Einspielen von Änderungen während der Wiederherstellung." #. translator: GUC parameter "recovery_prefetch" short description -#: ../include/utils/guc_tables.inc.c:4531 utils/guc_tables.inc.c:4531 +#: ../include/utils/guc_tables.inc.c:4532 utils/guc_tables.inc.c:4532 msgid "Prefetch referenced blocks during recovery." msgstr "Während der Wiederherstellung Blöcke, auf die verwiesen wird, vorab einlesen." #. translator: GUC parameter "recovery_prefetch" long description -#: ../include/utils/guc_tables.inc.c:4533 utils/guc_tables.inc.c:4533 +#: ../include/utils/guc_tables.inc.c:4534 utils/guc_tables.inc.c:4534 msgid "Look ahead in the WAL to find references to uncached data." msgstr "Im WAL vorausschauen, um Verweise auf ungecachte Daten zu finden." #. translator: GUC parameter "recovery_target" short description -#: ../include/utils/guc_tables.inc.c:4549 utils/guc_tables.inc.c:4549 +#: ../include/utils/guc_tables.inc.c:4550 utils/guc_tables.inc.c:4550 msgid "Set to \"immediate\" to end recovery as soon as a consistent state is reached." msgstr "Auf »immediate« setzen, um die Wiederherstellung zu beenden, sobald ein konsistenter Zustand erreicht ist." #. translator: GUC parameter "recovery_target_action" short description -#: ../include/utils/guc_tables.inc.c:4564 utils/guc_tables.inc.c:4564 +#: ../include/utils/guc_tables.inc.c:4565 utils/guc_tables.inc.c:4565 msgid "Sets the action to perform upon reaching the recovery target." msgstr "Setzt die Aktion, die beim Erreichen des Wiederherstellungsziels durchgeführt wird." #. translator: GUC parameter "recovery_target_inclusive" short description -#: ../include/utils/guc_tables.inc.c:4578 utils/guc_tables.inc.c:4578 +#: ../include/utils/guc_tables.inc.c:4579 utils/guc_tables.inc.c:4579 msgid "Sets whether to include or exclude transaction with recovery target." msgstr "Setzt ob die Transaktion mit dem Wiederherstellungsziel einbezogen oder ausgeschlossen wird." #. translator: GUC parameter "recovery_target_lsn" short description -#: ../include/utils/guc_tables.inc.c:4591 utils/guc_tables.inc.c:4591 +#: ../include/utils/guc_tables.inc.c:4592 utils/guc_tables.inc.c:4592 msgid "Sets the LSN of the write-ahead log location up to which recovery will proceed." msgstr "Setzt die LSN der Write-Ahead-Log-Position, bis zu der die Wiederherstellung voranschreiten wird." #. translator: GUC parameter "recovery_target_name" short description -#: ../include/utils/guc_tables.inc.c:4606 utils/guc_tables.inc.c:4606 +#: ../include/utils/guc_tables.inc.c:4607 utils/guc_tables.inc.c:4607 msgid "Sets the named restore point up to which recovery will proceed." msgstr "Setzt den benannten Restore-Punkt, bis zu dem die Wiederherstellung voranschreiten wird." #. translator: GUC parameter "recovery_target_time" short description -#: ../include/utils/guc_tables.inc.c:4621 utils/guc_tables.inc.c:4621 +#: ../include/utils/guc_tables.inc.c:4622 utils/guc_tables.inc.c:4622 msgid "Sets the time stamp up to which recovery will proceed." msgstr "Setzt den Zeitstempel, bis zu dem die Wiederherstellung voranschreiten wird." #. translator: GUC parameter "recovery_target_timeline" short description -#: ../include/utils/guc_tables.inc.c:4636 utils/guc_tables.inc.c:4636 +#: ../include/utils/guc_tables.inc.c:4637 utils/guc_tables.inc.c:4637 msgid "Specifies the timeline to recover into." msgstr "Gibt die Zeitleiste für die Wiederherstellung an." #. translator: GUC parameter "recovery_target_xid" short description -#: ../include/utils/guc_tables.inc.c:4651 utils/guc_tables.inc.c:4651 +#: ../include/utils/guc_tables.inc.c:4652 utils/guc_tables.inc.c:4652 msgid "Sets the transaction ID up to which recovery will proceed." msgstr "Setzt die Transaktions-ID, bis zu der die Wiederherstellung voranschreiten wird." #. translator: GUC parameter "recursive_worktable_factor" short description -#: ../include/utils/guc_tables.inc.c:4666 utils/guc_tables.inc.c:4666 +#: ../include/utils/guc_tables.inc.c:4667 utils/guc_tables.inc.c:4667 msgid "Sets the planner's estimate of the average size of a recursive query's working table." msgstr "Setzt die Planerschätzung für die durchschnittliche Größe der Arbeitstabelle einer rekursiven Anfrage." #. translator: GUC parameter "remove_temp_files_after_crash" short description -#: ../include/utils/guc_tables.inc.c:4682 utils/guc_tables.inc.c:4682 +#: ../include/utils/guc_tables.inc.c:4683 utils/guc_tables.inc.c:4683 msgid "Remove temporary files after backend crash." msgstr "Temporäre Dateien nach Absturz eines Serverprozesses löschen." #. translator: GUC parameter "reserved_connections" short description -#: ../include/utils/guc_tables.inc.c:4696 utils/guc_tables.inc.c:4696 +#: ../include/utils/guc_tables.inc.c:4697 utils/guc_tables.inc.c:4697 msgid "Sets the number of connection slots reserved for roles with privileges of pg_use_reserved_connections." msgstr "Setzt die Anzahl der Verbindungen, die für Rollen mit den Privilegien der Rolle pg_use_reserved_connections reserviert sind." #. translator: GUC parameter "restart_after_crash" short description -#: ../include/utils/guc_tables.inc.c:4711 utils/guc_tables.inc.c:4711 +#: ../include/utils/guc_tables.inc.c:4712 utils/guc_tables.inc.c:4712 msgid "Reinitialize server after backend crash." msgstr "Server nach Absturz eines Serverprozesses reinitialisieren." #. translator: GUC parameter "restore_command" short description -#: ../include/utils/guc_tables.inc.c:4724 utils/guc_tables.inc.c:4724 +#: ../include/utils/guc_tables.inc.c:4725 utils/guc_tables.inc.c:4725 msgid "Sets the shell command that will be called to retrieve an archived WAL file." msgstr "Setzt den Shell-Befehl, der aufgerufen wird, um eine archivierte WAL-Datei zurückzuholen." #. translator: GUC parameter "restrict_nonsystem_relation_kind" short description -#: ../include/utils/guc_tables.inc.c:4737 utils/guc_tables.inc.c:4737 +#: ../include/utils/guc_tables.inc.c:4738 utils/guc_tables.inc.c:4738 msgid "Prohibits access to non-system relations of specified kinds." msgstr "Verbietet Zugriff auf Nicht-System-Relationen der angegeben Arten." #. translator: GUC parameter "role" short description -#: ../include/utils/guc_tables.inc.c:4753 utils/guc_tables.inc.c:4753 +#: ../include/utils/guc_tables.inc.c:4754 utils/guc_tables.inc.c:4754 msgid "Sets the current role." msgstr "Setzt die aktuelle Rolle." #. translator: GUC parameter "row_security" short description -#: ../include/utils/guc_tables.inc.c:4770 utils/guc_tables.inc.c:4770 +#: ../include/utils/guc_tables.inc.c:4771 utils/guc_tables.inc.c:4771 msgid "Enables row security." msgstr "Schaltet Sicherheit auf Zeilenebene ein." #. translator: GUC parameter "row_security" long description -#: ../include/utils/guc_tables.inc.c:4772 utils/guc_tables.inc.c:4772 +#: ../include/utils/guc_tables.inc.c:4773 utils/guc_tables.inc.c:4773 msgid "When enabled, row security will be applied to all users." msgstr "Wenn eingeschaltet, wird Sicherheit auf Zeilenebene auf alle Benutzer angewendet." #. translator: GUC parameter "scram_iterations" short description -#: ../include/utils/guc_tables.inc.c:4785 utils/guc_tables.inc.c:4785 +#: ../include/utils/guc_tables.inc.c:4786 utils/guc_tables.inc.c:4786 msgid "Sets the iteration count for SCRAM secret generation." msgstr "Setzt die Iterationszahl für die Erzeugung von SCRAM-Geheimnissen." #. translator: GUC parameter "search_path" short description -#: ../include/utils/guc_tables.inc.c:4801 utils/guc_tables.inc.c:4801 +#: ../include/utils/guc_tables.inc.c:4802 utils/guc_tables.inc.c:4802 msgid "Sets the schema search order for names that are not schema-qualified." msgstr "Setzt die Schemasuchreihenfolge für Namen ohne Schemaqualifikation." #. translator: GUC parameter "seed" short description -#: ../include/utils/guc_tables.inc.c:4817 utils/guc_tables.inc.c:4817 +#: ../include/utils/guc_tables.inc.c:4818 utils/guc_tables.inc.c:4818 msgid "Sets the seed for random-number generation." msgstr "Setzt den Ausgangswert für die Zufallszahlenerzeugung." #. translator: GUC parameter "segment_size" short description -#: ../include/utils/guc_tables.inc.c:4836 utils/guc_tables.inc.c:4836 +#: ../include/utils/guc_tables.inc.c:4837 utils/guc_tables.inc.c:4837 msgid "Shows the number of pages per disk file." msgstr "Zeigt die Anzahl Seiten pro Diskdatei." #. translator: GUC parameter "send_abort_for_crash" short description -#: ../include/utils/guc_tables.inc.c:4852 utils/guc_tables.inc.c:4852 +#: ../include/utils/guc_tables.inc.c:4853 utils/guc_tables.inc.c:4853 msgid "Send SIGABRT not SIGQUIT to child processes after backend crash." msgstr "SIGABRT statt SIGQUIT an Kindprozesse noch Absturz eines Serverprozesses senden." #. translator: GUC parameter "send_abort_for_kill" short description -#: ../include/utils/guc_tables.inc.c:4866 utils/guc_tables.inc.c:4866 +#: ../include/utils/guc_tables.inc.c:4867 utils/guc_tables.inc.c:4867 msgid "Send SIGABRT not SIGKILL to stuck child processes." msgstr "SIGABRT statt SIGKILL an feststeckende Kindprozesse senden." #. translator: GUC parameter "seq_page_cost" short description -#: ../include/utils/guc_tables.inc.c:4880 utils/guc_tables.inc.c:4880 +#: ../include/utils/guc_tables.inc.c:4881 utils/guc_tables.inc.c:4881 msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." msgstr "Setzt den vom Planer geschätzten Aufwand, um eine sequenzielle Diskseite zu lesen." #. translator: GUC parameter "serializable_buffers" short description -#: ../include/utils/guc_tables.inc.c:4896 utils/guc_tables.inc.c:4896 +#: ../include/utils/guc_tables.inc.c:4897 utils/guc_tables.inc.c:4897 msgid "Sets the size of the dedicated buffer pool used for the serializable transaction cache." msgstr "Setzt die Größe des für den Cache für serialisierbare Transaktionen bestimmten Buffer-Pools." #. translator: GUC parameter "server_encoding" short description -#: ../include/utils/guc_tables.inc.c:4913 utils/guc_tables.inc.c:4913 +#: ../include/utils/guc_tables.inc.c:4914 utils/guc_tables.inc.c:4914 msgid "Shows the server (database) character set encoding." msgstr "Zeigt die Zeichensatzkodierung des Servers (der Datenbank)." #. translator: GUC parameter "server_version" short description -#: ../include/utils/guc_tables.inc.c:4927 utils/guc_tables.inc.c:4927 +#: ../include/utils/guc_tables.inc.c:4928 utils/guc_tables.inc.c:4928 msgid "Shows the server version." msgstr "Zeigt die Serverversion." #. translator: GUC parameter "server_version_num" short description -#: ../include/utils/guc_tables.inc.c:4941 utils/guc_tables.inc.c:4941 +#: ../include/utils/guc_tables.inc.c:4942 utils/guc_tables.inc.c:4942 msgid "Shows the server version as an integer." msgstr "Zeigt die Serverversion als Zahl." #. translator: GUC parameter "session_authorization" short description -#: ../include/utils/guc_tables.inc.c:4957 utils/guc_tables.inc.c:4957 +#: ../include/utils/guc_tables.inc.c:4958 utils/guc_tables.inc.c:4958 msgid "Sets the session user name." msgstr "Setzt den Sitzungsbenutzernamen." #. translator: GUC parameter "session_preload_libraries" short description -#: ../include/utils/guc_tables.inc.c:4973 utils/guc_tables.inc.c:4973 +#: ../include/utils/guc_tables.inc.c:4974 utils/guc_tables.inc.c:4974 msgid "Lists shared libraries to preload into each backend." msgstr "Listet dynamische Bibliotheken, die vorab in jeden Serverprozess geladen werden." #. translator: GUC parameter "session_replication_role" short description -#: ../include/utils/guc_tables.inc.c:4987 utils/guc_tables.inc.c:4987 +#: ../include/utils/guc_tables.inc.c:4988 utils/guc_tables.inc.c:4988 msgid "Sets the session's behavior for triggers and rewrite rules." msgstr "Setzt das Sitzungsverhalten für Trigger und Regeln." #. translator: GUC parameter "shared_buffers" short description -#: ../include/utils/guc_tables.inc.c:5002 utils/guc_tables.inc.c:5002 +#: ../include/utils/guc_tables.inc.c:5003 utils/guc_tables.inc.c:5003 msgid "Sets the number of shared memory buffers used by the server." msgstr "Setzt die Anzahl der vom Server verwendeten Shared-Memory-Puffer." #. translator: GUC parameter "shared_memory_size" short description -#: ../include/utils/guc_tables.inc.c:5018 utils/guc_tables.inc.c:5018 +#: ../include/utils/guc_tables.inc.c:5019 utils/guc_tables.inc.c:5019 msgid "Shows the size of the server's main shared memory area (rounded up to the nearest MB)." msgstr "Zeigt die Größe des primären Shared-Memory-Bereichs des Servers (aufgerundet zum nächsten MB)." #. translator: GUC parameter "shared_memory_size_in_huge_pages" short description -#: ../include/utils/guc_tables.inc.c:5034 utils/guc_tables.inc.c:5034 +#: ../include/utils/guc_tables.inc.c:5035 utils/guc_tables.inc.c:5035 msgid "Shows the number of huge pages needed for the main shared memory area." msgstr "Zeigt die Anzahl der Huge Pages, die für den primären Shared-Memory-Bereich benötigt werden." #. translator: GUC parameter "shared_memory_size_in_huge_pages" long description -#: ../include/utils/guc_tables.inc.c:5036 utils/guc_tables.inc.c:5036 +#: ../include/utils/guc_tables.inc.c:5037 utils/guc_tables.inc.c:5037 msgid "-1 means huge pages are not supported." msgstr "-1 bedeutet, dass Huge Page nicht unterstützt werden." #. translator: GUC parameter "shared_memory_type" short description -#: ../include/utils/guc_tables.inc.c:5052 utils/guc_tables.inc.c:5052 +#: ../include/utils/guc_tables.inc.c:5053 utils/guc_tables.inc.c:5053 msgid "Selects the shared memory implementation used for the main shared memory region." msgstr "Wählt die Shared-Memory-Implementierung, die für den Haupt-Shared-Memory-Bereich verwendet wird." #. translator: GUC parameter "shared_preload_libraries" short description -#: ../include/utils/guc_tables.inc.c:5066 utils/guc_tables.inc.c:5066 +#: ../include/utils/guc_tables.inc.c:5067 utils/guc_tables.inc.c:5067 msgid "Lists shared libraries to preload into server." msgstr "Listet dynamische Bibliotheken, die vorab in den Server geladen werden." #. translator: GUC parameter "ssl" short description -#: ../include/utils/guc_tables.inc.c:5080 utils/guc_tables.inc.c:5080 +#: ../include/utils/guc_tables.inc.c:5081 utils/guc_tables.inc.c:5081 msgid "Enables SSL connections." msgstr "Ermöglicht SSL-Verbindungen." #. translator: GUC parameter "ssl_ca_file" short description -#: ../include/utils/guc_tables.inc.c:5094 utils/guc_tables.inc.c:5094 +#: ../include/utils/guc_tables.inc.c:5095 utils/guc_tables.inc.c:5095 msgid "Location of the SSL certificate authority file." msgstr "Ort der SSL-Certificate-Authority-Datei." #. translator: GUC parameter "ssl_cert_file" short description -#: ../include/utils/guc_tables.inc.c:5107 utils/guc_tables.inc.c:5107 +#: ../include/utils/guc_tables.inc.c:5108 utils/guc_tables.inc.c:5108 msgid "Location of the SSL server certificate file." msgstr "Ort der SSL-Serverzertifikatsdatei." #. translator: GUC parameter "ssl_ciphers" short description -#: ../include/utils/guc_tables.inc.c:5120 utils/guc_tables.inc.c:5120 +#: ../include/utils/guc_tables.inc.c:5121 utils/guc_tables.inc.c:5121 msgid "Sets the list of allowed TLSv1.2 (and lower) ciphers." msgstr "Setzt die Liste der erlaubten Verschlüsselungsalgorithmen für TLSv1.2 (und älter)." #. translator: GUC parameter "ssl_crl_dir" short description -#: ../include/utils/guc_tables.inc.c:5134 utils/guc_tables.inc.c:5134 +#: ../include/utils/guc_tables.inc.c:5135 utils/guc_tables.inc.c:5135 msgid "Location of the SSL certificate revocation list directory." msgstr "Ort des SSL-Certificate-Revocation-List-Verzeichnisses." #. translator: GUC parameter "ssl_crl_file" short description -#: ../include/utils/guc_tables.inc.c:5147 utils/guc_tables.inc.c:5147 +#: ../include/utils/guc_tables.inc.c:5148 utils/guc_tables.inc.c:5148 msgid "Location of the SSL certificate revocation list file." msgstr "Ort der SSL-Certificate-Revocation-List-Datei." #. translator: GUC parameter "ssl_dh_params_file" short description -#: ../include/utils/guc_tables.inc.c:5160 utils/guc_tables.inc.c:5160 +#: ../include/utils/guc_tables.inc.c:5161 utils/guc_tables.inc.c:5161 msgid "Location of the SSL DH parameters file." msgstr "Setzt den Ort der SSL-DH-Parameter-Datei." #. translator: GUC parameter "ssl_dh_params_file" long description -#: ../include/utils/guc_tables.inc.c:5162 utils/guc_tables.inc.c:5162 +#: ../include/utils/guc_tables.inc.c:5163 utils/guc_tables.inc.c:5163 msgid "An empty string means use compiled-in default parameters." msgstr "Eine leere Zeichenkette bedeutet, die einkompilierten Standardparameter zu verwenden." #. translator: GUC parameter "ssl_groups" short description -#: ../include/utils/guc_tables.inc.c:5176 utils/guc_tables.inc.c:5176 +#: ../include/utils/guc_tables.inc.c:5177 utils/guc_tables.inc.c:5177 msgid "Sets the group(s) to use for Diffie-Hellman key exchange." msgstr "Setzt die für Diffie-Hellman-Schlüsselaustausch zu verwendenden Gruppen." #. translator: GUC parameter "ssl_groups" long description -#: ../include/utils/guc_tables.inc.c:5178 utils/guc_tables.inc.c:5178 +#: ../include/utils/guc_tables.inc.c:5179 utils/guc_tables.inc.c:5179 msgid "Multiple groups can be specified using a colon-separated list." msgstr "Mehrere Gruppen können in einer durch Doppelpunkte getrennten Liste angegeben werden." #. translator: GUC parameter "ssl_key_file" short description -#: ../include/utils/guc_tables.inc.c:5192 utils/guc_tables.inc.c:5192 +#: ../include/utils/guc_tables.inc.c:5193 utils/guc_tables.inc.c:5193 msgid "Location of the SSL server private key file." msgstr "Setzt den Ort der Datei mit dem privaten SSL-Server-Schlüssel." #. translator: GUC parameter "ssl_library" short description -#: ../include/utils/guc_tables.inc.c:5205 utils/guc_tables.inc.c:5205 +#: ../include/utils/guc_tables.inc.c:5206 utils/guc_tables.inc.c:5206 msgid "Shows the name of the SSL library." msgstr "Zeigt den Namen der SSL-Bibliothek." #. translator: GUC parameter "ssl_max_protocol_version" short description -#: ../include/utils/guc_tables.inc.c:5219 utils/guc_tables.inc.c:5219 +#: ../include/utils/guc_tables.inc.c:5220 utils/guc_tables.inc.c:5220 msgid "Sets the maximum SSL/TLS protocol version to use." msgstr "Setzt die maximale zu verwendende SSL/TLS-Protokollversion." #. translator: GUC parameter "ssl_min_protocol_version" short description -#: ../include/utils/guc_tables.inc.c:5234 utils/guc_tables.inc.c:5234 +#: ../include/utils/guc_tables.inc.c:5235 utils/guc_tables.inc.c:5235 msgid "Sets the minimum SSL/TLS protocol version to use." msgstr "Setzt die minimale zu verwendende SSL/TLS-Protokollversion." #. translator: GUC parameter "ssl_passphrase_command" short description -#: ../include/utils/guc_tables.inc.c:5249 utils/guc_tables.inc.c:5249 +#: ../include/utils/guc_tables.inc.c:5250 utils/guc_tables.inc.c:5250 msgid "Command to obtain passphrases for SSL." msgstr "Befehl zum Einlesen von Passphrasen für SSL." #. translator: GUC parameter "ssl_passphrase_command" long description -#: ../include/utils/guc_tables.inc.c:5251 utils/guc_tables.inc.c:5251 +#: ../include/utils/guc_tables.inc.c:5252 utils/guc_tables.inc.c:5252 msgid "An empty string means use the built-in prompting mechanism." msgstr "Eine leere Zeichenkette bedeutet, den eingebauten Prompt-Mechanismus zu verwenden." #. translator: GUC parameter "ssl_passphrase_command_supports_reload" short description -#: ../include/utils/guc_tables.inc.c:5265 utils/guc_tables.inc.c:5265 +#: ../include/utils/guc_tables.inc.c:5266 utils/guc_tables.inc.c:5266 msgid "Controls whether \"ssl_passphrase_command\" is called during server reload." msgstr "Kontrolliert, ob »ssl_passphrase_command« beim Neuladen des Servers aufgerufen wird." #. translator: GUC parameter "ssl_prefer_server_ciphers" short description -#: ../include/utils/guc_tables.inc.c:5278 utils/guc_tables.inc.c:5278 +#: ../include/utils/guc_tables.inc.c:5279 utils/guc_tables.inc.c:5279 msgid "Give priority to server ciphersuite order." msgstr "Der Ciphersuite-Reihenfolge des Servers Vorrang geben." #. translator: GUC parameter "ssl_renegotiation_limit" short description -#: ../include/utils/guc_tables.inc.c:5291 utils/guc_tables.inc.c:5291 +#: ../include/utils/guc_tables.inc.c:5292 utils/guc_tables.inc.c:5292 msgid "SSL renegotiation is no longer supported; this can only be 0." msgstr "SSL-Renegotiation wird nicht mehr unterstützt; kann nur auf 0 gesetzt werden." #. translator: GUC parameter "ssl_sni" short description -#: ../include/utils/guc_tables.inc.c:5307 utils/guc_tables.inc.c:5307 +#: ../include/utils/guc_tables.inc.c:5308 utils/guc_tables.inc.c:5308 msgid "Sets whether to interpret SNI extensions in SSL connections." msgstr "" #. translator: GUC parameter "ssl_tls13_ciphers" short description -#: ../include/utils/guc_tables.inc.c:5322 utils/guc_tables.inc.c:5322 +#: ../include/utils/guc_tables.inc.c:5323 utils/guc_tables.inc.c:5323 msgid "Sets the list of allowed TLSv1.3 cipher suites." msgstr "Setzt die Liste der erlaubten Verschlüsselungsalgorithmen für TLSv1.3." #. translator: GUC parameter "ssl_tls13_ciphers" long description -#: ../include/utils/guc_tables.inc.c:5324 utils/guc_tables.inc.c:5324 +#: ../include/utils/guc_tables.inc.c:5325 utils/guc_tables.inc.c:5325 msgid "An empty string means use the default cipher suites." msgstr "Eine leere Zeichenkette bedeutet, die voreingestellten Verschlüsselungsalgorithmen zu verwenden." #. translator: GUC parameter "standard_conforming_strings" short description -#: ../include/utils/guc_tables.inc.c:5338 utils/guc_tables.inc.c:5338 +#: ../include/utils/guc_tables.inc.c:5339 utils/guc_tables.inc.c:5339 #, fuzzy #| msgid "SSL renegotiation is no longer supported; this can only be 0." msgid "Nonstandard strings are no longer supported; this can only be true." msgstr "SSL-Renegotiation wird nicht mehr unterstützt; kann nur auf 0 gesetzt werden." #. translator: GUC parameter "statement_timeout" short description -#: ../include/utils/guc_tables.inc.c:5353 utils/guc_tables.inc.c:5353 +#: ../include/utils/guc_tables.inc.c:5354 utils/guc_tables.inc.c:5354 msgid "Sets the maximum allowed duration of any statement." msgstr "Setzt die maximal erlaubte Dauer jeder Anweisung." #. translator: GUC parameter "stats_fetch_consistency" short description -#: ../include/utils/guc_tables.inc.c:5371 utils/guc_tables.inc.c:5371 +#: ../include/utils/guc_tables.inc.c:5372 utils/guc_tables.inc.c:5372 msgid "Sets the consistency of accesses to statistics data." msgstr "Setzt die Konsistenz von Zugriffen auf Statistikdaten." #. translator: GUC parameter "subtransaction_buffers" short description -#: ../include/utils/guc_tables.inc.c:5386 utils/guc_tables.inc.c:5386 +#: ../include/utils/guc_tables.inc.c:5387 utils/guc_tables.inc.c:5387 msgid "Sets the size of the dedicated buffer pool used for the subtransaction cache." msgstr "Setzt die Größe des für den Subtransaktions-Cache bestimmten Buffer-Pools." #. translator: GUC parameter "summarize_wal" short description -#: ../include/utils/guc_tables.inc.c:5405 utils/guc_tables.inc.c:5405 +#: ../include/utils/guc_tables.inc.c:5406 utils/guc_tables.inc.c:5406 msgid "Starts the WAL summarizer process to enable incremental backup." msgstr "Startet den WAL-Summarizer-Prozess, um inkrementelle Backups zu ermöglichen." #. translator: GUC parameter "superuser_reserved_connections" short description -#: ../include/utils/guc_tables.inc.c:5418 utils/guc_tables.inc.c:5418 +#: ../include/utils/guc_tables.inc.c:5419 utils/guc_tables.inc.c:5419 msgid "Sets the number of connection slots reserved for superusers." msgstr "Setzt die Anzahl der für Superuser reservierten Verbindungen." #. translator: GUC parameter "sync_replication_slots" short description -#: ../include/utils/guc_tables.inc.c:5433 utils/guc_tables.inc.c:5433 +#: ../include/utils/guc_tables.inc.c:5434 utils/guc_tables.inc.c:5434 msgid "Enables a physical standby to synchronize logical failover replication slots from the primary server." msgstr "Ermöglicht, dass ein physischer Standby logische Failover-Replikations-Slots vom Primärserver synchronisiert." #. translator: GUC parameter "synchronize_seqscans" short description -#: ../include/utils/guc_tables.inc.c:5446 utils/guc_tables.inc.c:5446 +#: ../include/utils/guc_tables.inc.c:5447 utils/guc_tables.inc.c:5447 msgid "Enables synchronized sequential scans." msgstr "Ermöglicht synchronisierte sequenzielle Scans." #. translator: GUC parameter "synchronized_standby_slots" short description -#: ../include/utils/guc_tables.inc.c:5459 utils/guc_tables.inc.c:5459 +#: ../include/utils/guc_tables.inc.c:5460 utils/guc_tables.inc.c:5460 msgid "Lists streaming replication standby server replication slot names that logical WAL sender processes will wait for." msgstr "Listet Replikations-Slot-Namen von Streaming-Replication-Standby-Servern, auf die logische WAL-Sender warten werden." #. translator: GUC parameter "synchronized_standby_slots" long description -#: ../include/utils/guc_tables.inc.c:5461 utils/guc_tables.inc.c:5461 +#: ../include/utils/guc_tables.inc.c:5462 utils/guc_tables.inc.c:5462 msgid "Logical WAL sender processes will send decoded changes to output plugins only after the specified replication slots have confirmed receiving WAL." msgstr "Logische WAL-Sender-Prozesse werden dekodierte Änderungen erst an die Ausgabe-Plugins senden, nachdem die angegebenen Replikations-Slots den Empfang von WAL bestätigt haben." #. translator: GUC parameter "synchronous_commit" short description -#: ../include/utils/guc_tables.inc.c:5477 utils/guc_tables.inc.c:5477 +#: ../include/utils/guc_tables.inc.c:5478 utils/guc_tables.inc.c:5478 msgid "Sets the current transaction's synchronization level." msgstr "Setzt den Synchronisationsgrad der aktuellen Transaktion." #. translator: GUC parameter "synchronous_standby_names" short description -#: ../include/utils/guc_tables.inc.c:5492 utils/guc_tables.inc.c:5492 +#: ../include/utils/guc_tables.inc.c:5493 utils/guc_tables.inc.c:5493 msgid "Number of synchronous standbys and list of names of potential synchronous ones." msgstr "Anzahl synchroner Standbys und Liste der Namen der möglichen synchronen Standbys." #. translator: GUC parameter "syslog_facility" short description -#: ../include/utils/guc_tables.inc.c:5508 utils/guc_tables.inc.c:5508 +#: ../include/utils/guc_tables.inc.c:5509 utils/guc_tables.inc.c:5509 msgid "Sets the syslog \"facility\" to be used when syslog enabled." msgstr "Setzt die zu verwendende Syslog-»Facility«, wenn Syslog angeschaltet ist." #. translator: GUC parameter "syslog_ident" short description -#: ../include/utils/guc_tables.inc.c:5523 utils/guc_tables.inc.c:5523 +#: ../include/utils/guc_tables.inc.c:5524 utils/guc_tables.inc.c:5524 msgid "Sets the program name used to identify PostgreSQL messages in syslog." msgstr "Setzt den Programmnamen, mit dem PostgreSQL-Meldungen im Syslog identifiziert werden." #. translator: GUC parameter "syslog_sequence_numbers" short description -#: ../include/utils/guc_tables.inc.c:5537 utils/guc_tables.inc.c:5537 +#: ../include/utils/guc_tables.inc.c:5538 utils/guc_tables.inc.c:5538 msgid "Add sequence number to syslog messages to avoid duplicate suppression." msgstr "Syslog-Nachrichten mit Sequenznummern versehen, um Unterdrückung doppelter Nachrichten zu unterbinden." #. translator: GUC parameter "syslog_split_messages" short description -#: ../include/utils/guc_tables.inc.c:5550 utils/guc_tables.inc.c:5550 +#: ../include/utils/guc_tables.inc.c:5551 utils/guc_tables.inc.c:5551 msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." msgstr "An Syslog gesendete Nachrichten nach Zeilen und in maximal 1024 Bytes aufteilen." #. translator: GUC parameter "tcp_keepalives_count" short description -#: ../include/utils/guc_tables.inc.c:5563 utils/guc_tables.inc.c:5563 +#: ../include/utils/guc_tables.inc.c:5564 utils/guc_tables.inc.c:5564 msgid "Maximum number of TCP keepalive retransmits." msgstr "Maximale Anzahl an TCP-Keepalive-Neuübertragungen." #. translator: GUC parameter "tcp_keepalives_count" long description -#: ../include/utils/guc_tables.inc.c:5565 utils/guc_tables.inc.c:5565 +#: ../include/utils/guc_tables.inc.c:5566 utils/guc_tables.inc.c:5566 msgid "Number of consecutive keepalive retransmits that can be lost before a connection is considered dead. 0 means use the system default." msgstr "Anzahl von aufeinanderfolgenden Keepalive-Neuübertragungen, die verloren gehen dürfen, bis die Verbindung als tot betrachtet wird. 0 bedeutet, die Betriebssystemvoreinstellung zu verwenden." #. translator: GUC parameter "tcp_keepalives_idle" short description -#: ../include/utils/guc_tables.inc.c:5582 utils/guc_tables.inc.c:5582 +#: ../include/utils/guc_tables.inc.c:5583 utils/guc_tables.inc.c:5583 msgid "Time between issuing TCP keepalives." msgstr "Zeit zwischen TCP-Keepalive-Sendungen." #. translator: GUC parameter "tcp_keepalives_interval" short description -#: ../include/utils/guc_tables.inc.c:5602 utils/guc_tables.inc.c:5602 +#: ../include/utils/guc_tables.inc.c:5603 utils/guc_tables.inc.c:5603 msgid "Time between TCP keepalive retransmits." msgstr "Zeit zwischen TCP-Keepalive-Neuübertragungen." #. translator: GUC parameter "tcp_user_timeout" short description -#: ../include/utils/guc_tables.inc.c:5622 utils/guc_tables.inc.c:5622 +#: ../include/utils/guc_tables.inc.c:5623 utils/guc_tables.inc.c:5623 msgid "TCP user timeout." msgstr "TCP-User-Timeout." #. translator: GUC parameter "temp_buffers" short description -#: ../include/utils/guc_tables.inc.c:5642 utils/guc_tables.inc.c:5642 +#: ../include/utils/guc_tables.inc.c:5643 utils/guc_tables.inc.c:5643 msgid "Sets the maximum number of temporary buffers used by each session." msgstr "Setzt die maximale Anzahl der von jeder Sitzung verwendeten temporären Puffer." #. translator: GUC parameter "temp_file_limit" short description -#: ../include/utils/guc_tables.inc.c:5659 utils/guc_tables.inc.c:5659 +#: ../include/utils/guc_tables.inc.c:5660 utils/guc_tables.inc.c:5660 msgid "Limits the total size of all temporary files used by each process." msgstr "Beschränkt die Gesamtgröße aller temporären Dateien, die von einem Prozess verwendet werden." #. translator: GUC parameter "temp_file_limit" long description -#: ../include/utils/guc_tables.inc.c:5661 utils/guc_tables.inc.c:5661 +#: ../include/utils/guc_tables.inc.c:5662 utils/guc_tables.inc.c:5662 msgid "-1 means no limit." msgstr "-1 bedeutet keine Grenze." #. translator: GUC parameter "temp_tablespaces" short description -#: ../include/utils/guc_tables.inc.c:5677 utils/guc_tables.inc.c:5677 +#: ../include/utils/guc_tables.inc.c:5678 utils/guc_tables.inc.c:5678 msgid "Sets the tablespace(s) to use for temporary tables and sort files." msgstr "Setzt den oder die Tablespaces für temporäre Tabellen und Sortierdateien." #. translator: GUC parameter "TimeZone" short description -#: ../include/utils/guc_tables.inc.c:5695 utils/guc_tables.inc.c:5695 +#: ../include/utils/guc_tables.inc.c:5696 utils/guc_tables.inc.c:5696 msgid "Sets the time zone for displaying and interpreting time stamps." msgstr "Setzt die Zeitzone, in der Zeitangaben interpretiert und ausgegeben werden." #. translator: GUC parameter "timezone_abbreviations" short description -#: ../include/utils/guc_tables.inc.c:5712 utils/guc_tables.inc.c:5712 +#: ../include/utils/guc_tables.inc.c:5713 utils/guc_tables.inc.c:5713 msgid "Selects a file of time zone abbreviations." msgstr "Wählt eine Datei mit Zeitzonenabkürzungen." #. translator: GUC parameter "timing_clock_source" short description -#: ../include/utils/guc_tables.inc.c:5727 utils/guc_tables.inc.c:5727 +#: ../include/utils/guc_tables.inc.c:5728 utils/guc_tables.inc.c:5728 msgid "Controls the clock source used for collecting timing measurements." msgstr "" #. translator: GUC parameter "timing_clock_source" long description -#: ../include/utils/guc_tables.inc.c:5729 utils/guc_tables.inc.c:5729 +#: ../include/utils/guc_tables.inc.c:5730 utils/guc_tables.inc.c:5730 msgid "This enables the use of specialized clock sources, specifically the RDTSC clock source on x86-64 systems (if available), to support timing measurements with lower overhead during EXPLAIN and other instrumentation." msgstr "" #. translator: GUC parameter "trace_connection_negotiation" short description -#: ../include/utils/guc_tables.inc.c:5746 utils/guc_tables.inc.c:5746 +#: ../include/utils/guc_tables.inc.c:5747 utils/guc_tables.inc.c:5747 msgid "Logs details of pre-authentication connection handshake." msgstr "Schreibt Details über den Verbindungs-Handshake vor der Authentifizierung in den Log." #. translator: GUC parameter "trace_lock_oidmin" short description -#: ../include/utils/guc_tables.inc.c:5761 utils/guc_tables.inc.c:5761 +#: ../include/utils/guc_tables.inc.c:5762 utils/guc_tables.inc.c:5762 msgid "Sets the minimum OID of tables for tracking locks." msgstr "Setzt die minimale Tabellen-OID für das Verfolgen von Sperren." #. translator: GUC parameter "trace_lock_oidmin" long description -#: ../include/utils/guc_tables.inc.c:5763 utils/guc_tables.inc.c:5763 +#: ../include/utils/guc_tables.inc.c:5764 utils/guc_tables.inc.c:5764 msgid "Is used to avoid output on system tables." msgstr "Wird verwendet, um Ausgabe für Systemtabellen zu vermeiden." #. translator: GUC parameter "trace_lock_table" short description -#: ../include/utils/guc_tables.inc.c:5781 utils/guc_tables.inc.c:5781 +#: ../include/utils/guc_tables.inc.c:5782 utils/guc_tables.inc.c:5782 msgid "Sets the OID of the table with unconditionally lock tracing." msgstr "Setzt die OID der Tabelle mit bedingungsloser Sperrenverfolgung." #. translator: GUC parameter "trace_locks" short description -#: ../include/utils/guc_tables.inc.c:5799 utils/guc_tables.inc.c:5799 +#: ../include/utils/guc_tables.inc.c:5800 utils/guc_tables.inc.c:5800 msgid "Emits information about lock usage." msgstr "Gibt Informationen über Sperrenverwendung aus." #. translator: GUC parameter "trace_lwlocks" short description -#: ../include/utils/guc_tables.inc.c:5815 utils/guc_tables.inc.c:5815 +#: ../include/utils/guc_tables.inc.c:5816 utils/guc_tables.inc.c:5816 msgid "Emits information about lightweight lock usage." msgstr "Gibt Informationen über die Verwendung von Lightweight Locks aus." #. translator: GUC parameter "trace_notify" short description -#: ../include/utils/guc_tables.inc.c:5830 utils/guc_tables.inc.c:5830 +#: ../include/utils/guc_tables.inc.c:5831 utils/guc_tables.inc.c:5831 msgid "Generates debugging output for LISTEN and NOTIFY." msgstr "Erzeugt Debug-Ausgabe für LISTEN und NOTIFY." #. translator: GUC parameter "trace_sort" short description -#: ../include/utils/guc_tables.inc.c:5844 utils/guc_tables.inc.c:5844 +#: ../include/utils/guc_tables.inc.c:5845 utils/guc_tables.inc.c:5845 msgid "Emit information about resource usage in sorting." msgstr "Gibt Informationen über die Ressourcenverwendung beim Sortieren aus." #. translator: GUC parameter "trace_syncscan" short description -#: ../include/utils/guc_tables.inc.c:5859 utils/guc_tables.inc.c:5859 +#: ../include/utils/guc_tables.inc.c:5860 utils/guc_tables.inc.c:5860 msgid "Generate debugging output for synchronized scanning." msgstr "Erzeugt Debug-Ausgabe für synchronisiertes Scannen." #. translator: GUC parameter "trace_userlocks" short description -#: ../include/utils/guc_tables.inc.c:5875 utils/guc_tables.inc.c:5875 +#: ../include/utils/guc_tables.inc.c:5876 utils/guc_tables.inc.c:5876 msgid "Emits information about user lock usage." msgstr "Gibt Informationen über Benutzersperrenverwendung aus." #. translator: GUC parameter "track_activities" short description -#: ../include/utils/guc_tables.inc.c:5890 utils/guc_tables.inc.c:5890 +#: ../include/utils/guc_tables.inc.c:5891 utils/guc_tables.inc.c:5891 msgid "Collects information about executing commands." msgstr "Sammelt Informationen über ausgeführte Befehle." #. translator: GUC parameter "track_activities" long description -#: ../include/utils/guc_tables.inc.c:5892 utils/guc_tables.inc.c:5892 +#: ../include/utils/guc_tables.inc.c:5893 utils/guc_tables.inc.c:5893 msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." msgstr "Schaltet die Sammlung von Informationen über den aktuell ausgeführten Befehl jeder Sitzung ein, einschließlich der Zeit, and dem die Befehlsausführung begann." #. translator: GUC parameter "track_activity_query_size" short description -#: ../include/utils/guc_tables.inc.c:5905 utils/guc_tables.inc.c:5905 +#: ../include/utils/guc_tables.inc.c:5906 utils/guc_tables.inc.c:5906 msgid "Sets the size reserved for pg_stat_activity.query, in bytes." msgstr "Setzt die für pg_stat_activity.query reservierte Größe, in Bytes." #. translator: GUC parameter "track_commit_timestamp" short description -#: ../include/utils/guc_tables.inc.c:5921 utils/guc_tables.inc.c:5921 +#: ../include/utils/guc_tables.inc.c:5922 utils/guc_tables.inc.c:5922 msgid "Collects transaction commit time." msgstr "Sammelt Commit-Timestamps von Transaktionen." #. translator: GUC parameter "track_cost_delay_timing" short description -#: ../include/utils/guc_tables.inc.c:5934 utils/guc_tables.inc.c:5934 +#: ../include/utils/guc_tables.inc.c:5935 utils/guc_tables.inc.c:5935 msgid "Collects timing statistics for cost-based vacuum delay." msgstr "Sammelt Zeitmessungsstatistiken über kostenbasierte Vacuum-Verzögerung." #. translator: GUC parameter "track_counts" short description -#: ../include/utils/guc_tables.inc.c:5947 utils/guc_tables.inc.c:5947 +#: ../include/utils/guc_tables.inc.c:5948 utils/guc_tables.inc.c:5948 msgid "Collects statistics on database activity." msgstr "Sammelt Statistiken über Datenbankaktivität." #. translator: GUC parameter "track_functions" short description -#: ../include/utils/guc_tables.inc.c:5960 utils/guc_tables.inc.c:5960 +#: ../include/utils/guc_tables.inc.c:5961 utils/guc_tables.inc.c:5961 msgid "Collects function-level statistics on database activity." msgstr "Sammelt Statistiken auf Funktionsebene über Datenbankaktivität." #. translator: GUC parameter "track_io_timing" short description -#: ../include/utils/guc_tables.inc.c:5974 utils/guc_tables.inc.c:5974 +#: ../include/utils/guc_tables.inc.c:5975 utils/guc_tables.inc.c:5975 msgid "Collects timing statistics for database I/O activity." msgstr "Sammelt Zeitmessungsstatistiken über Datenbank-I/O-Aktivität." #. translator: GUC parameter "track_wal_io_timing" short description -#: ../include/utils/guc_tables.inc.c:5987 utils/guc_tables.inc.c:5987 +#: ../include/utils/guc_tables.inc.c:5988 utils/guc_tables.inc.c:5988 msgid "Collects timing statistics for WAL I/O activity." msgstr "Sammelt Zeitmessungsstatistiken über WAL-I/O-Aktivität." #. translator: GUC parameter "transaction_buffers" short description -#: ../include/utils/guc_tables.inc.c:6000 utils/guc_tables.inc.c:6000 +#: ../include/utils/guc_tables.inc.c:6001 utils/guc_tables.inc.c:6001 msgid "Sets the size of the dedicated buffer pool used for the transaction status cache." msgstr "Setzt die Größe des für den Transaktionsstatus-Cache bestimmten Buffer-Pools." #. translator: GUC parameter "transaction_deferrable" short description -#: ../include/utils/guc_tables.inc.c:6019 utils/guc_tables.inc.c:6019 +#: ../include/utils/guc_tables.inc.c:6020 utils/guc_tables.inc.c:6020 msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." msgstr "Ob eine serialisierbare Read-Only-Transaktion aufgeschoben werden soll, bis sie ohne mögliche Serialisierungsfehler ausgeführt werden kann." #. translator: GUC parameter "transaction_isolation" short description -#: ../include/utils/guc_tables.inc.c:6034 utils/guc_tables.inc.c:6034 +#: ../include/utils/guc_tables.inc.c:6035 utils/guc_tables.inc.c:6035 msgid "Sets the current transaction's isolation level." msgstr "Zeigt den Isolationsgrad der aktuellen Transaktion." #. translator: GUC parameter "transaction_read_only" short description -#: ../include/utils/guc_tables.inc.c:6050 utils/guc_tables.inc.c:6050 +#: ../include/utils/guc_tables.inc.c:6051 utils/guc_tables.inc.c:6051 msgid "Sets the current transaction's read-only status." msgstr "Setzt die Read-Only-Einstellung der aktuellen Transaktion." #. translator: GUC parameter "transaction_timeout" short description -#: ../include/utils/guc_tables.inc.c:6065 utils/guc_tables.inc.c:6065 +#: ../include/utils/guc_tables.inc.c:6066 utils/guc_tables.inc.c:6066 msgid "Sets the maximum allowed duration of any transaction within a session (not a prepared transaction)." msgstr "Setzt die maximal erlaubte Dauer jeder Transaktion innerhalb einer Sitzung (keine vorbereitete Transaktion)." #. translator: GUC parameter "transform_null_equals" short description -#: ../include/utils/guc_tables.inc.c:6084 utils/guc_tables.inc.c:6084 +#: ../include/utils/guc_tables.inc.c:6085 utils/guc_tables.inc.c:6085 msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." msgstr "Behandelt »ausdruck=NULL« als »ausdruck IS NULL«." #. translator: GUC parameter "transform_null_equals" long description -#: ../include/utils/guc_tables.inc.c:6086 utils/guc_tables.inc.c:6086 +#: ../include/utils/guc_tables.inc.c:6087 utils/guc_tables.inc.c:6087 msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." msgstr "Wenn an, dann werden Ausdrücke der Form ausdruck = NULL (oder NULL = ausdruck) wie ausdruck IS NULL behandelt, das heißt, sie ergeben wahr, wenn das Ergebnis von ausdruck der NULL-Wert ist, und ansonsten falsch. Das korrekte Verhalten von ausdruck = NULL ist immer den NULL-Wert (für unbekannt) zurückzugeben." #. translator: GUC parameter "unix_socket_directories" short description -#: ../include/utils/guc_tables.inc.c:6099 utils/guc_tables.inc.c:6099 +#: ../include/utils/guc_tables.inc.c:6100 utils/guc_tables.inc.c:6100 msgid "Sets the directories where Unix-domain sockets will be created." msgstr "Setzt die Verzeichnisse, in denen Unix-Domain-Sockets erzeugt werden sollen." #. translator: GUC parameter "unix_socket_group" short description -#: ../include/utils/guc_tables.inc.c:6113 utils/guc_tables.inc.c:6113 +#: ../include/utils/guc_tables.inc.c:6114 utils/guc_tables.inc.c:6114 msgid "Sets the owning group of the Unix-domain socket." msgstr "Setzt die Eigentümergruppe der Unix-Domain-Socket." #. translator: GUC parameter "unix_socket_group" long description -#: ../include/utils/guc_tables.inc.c:6115 utils/guc_tables.inc.c:6115 +#: ../include/utils/guc_tables.inc.c:6116 utils/guc_tables.inc.c:6116 msgid "The owning user of the socket is always the user that starts the server. An empty string means use the user's default group." msgstr "Der Eigentümer ist immer der Benutzer, der den Server startet. Eine leere Zeichenkette bedeutet, die Standardgruppe des Benutzers zu verwenden." #. translator: GUC parameter "unix_socket_permissions" short description -#: ../include/utils/guc_tables.inc.c:6128 utils/guc_tables.inc.c:6128 +#: ../include/utils/guc_tables.inc.c:6129 utils/guc_tables.inc.c:6129 msgid "Sets the access permissions of the Unix-domain socket." msgstr "Setzt die Zugriffsrechte für die Unix-Domain-Socket." #. translator: GUC parameter "unix_socket_permissions" long description -#: ../include/utils/guc_tables.inc.c:6130 utils/guc_tables.inc.c:6130 +#: ../include/utils/guc_tables.inc.c:6131 utils/guc_tables.inc.c:6131 msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "Unix-Domain-Sockets verwenden die üblichen Zugriffsrechte für Unix-Dateisysteme. Der Wert dieser Option muss ein numerischer Wert in der von den Systemaufrufen chmod und umask verwendeten Form sein. (Um das gebräuchliche Oktalformat zu verwenden, muss die Zahl mit 0 (einer Null) anfangen.)" #. translator: GUC parameter "update_process_title" short description -#: ../include/utils/guc_tables.inc.c:6146 utils/guc_tables.inc.c:6146 +#: ../include/utils/guc_tables.inc.c:6147 utils/guc_tables.inc.c:6147 msgid "Updates the process title to show the active SQL command." msgstr "Der Prozesstitel wird aktualisiert, um den aktuellen SQL-Befehl anzuzeigen." #. translator: GUC parameter "update_process_title" long description -#: ../include/utils/guc_tables.inc.c:6148 utils/guc_tables.inc.c:6148 +#: ../include/utils/guc_tables.inc.c:6149 utils/guc_tables.inc.c:6149 msgid "Enables updating of the process title every time a new SQL command is received by the server." msgstr "Ermöglicht das Aktualisieren des Prozesstitels bei jedem von Server empfangenen neuen SQL-Befehl." #. translator: GUC parameter "vacuum_buffer_usage_limit" short description -#: ../include/utils/guc_tables.inc.c:6161 utils/guc_tables.inc.c:6161 +#: ../include/utils/guc_tables.inc.c:6162 utils/guc_tables.inc.c:6162 msgid "Sets the buffer pool size for VACUUM, ANALYZE, and autovacuum." msgstr "Setzt die Buffer-Pool-Größe für VACUUM, ANALYZE und Autovacuum." #. translator: GUC parameter "vacuum_cost_delay" short description -#: ../include/utils/guc_tables.inc.c:6178 utils/guc_tables.inc.c:6178 +#: ../include/utils/guc_tables.inc.c:6179 utils/guc_tables.inc.c:6179 msgid "Vacuum cost delay in milliseconds." msgstr "Vacuum-Kosten-Verzögerung in Millisekunden." #. translator: GUC parameter "vacuum_cost_limit" short description -#: ../include/utils/guc_tables.inc.c:6194 utils/guc_tables.inc.c:6194 +#: ../include/utils/guc_tables.inc.c:6195 utils/guc_tables.inc.c:6195 msgid "Vacuum cost amount available before napping." msgstr "Verfügbare Vacuum-Kosten vor Nickerchen." #. translator: GUC parameter "vacuum_cost_page_dirty" short description -#: ../include/utils/guc_tables.inc.c:6209 utils/guc_tables.inc.c:6209 +#: ../include/utils/guc_tables.inc.c:6210 utils/guc_tables.inc.c:6210 msgid "Vacuum cost for a page dirtied by vacuum." msgstr "Vacuum-Kosten für eine durch Vacuum schmutzig gemachte Seite." #. translator: GUC parameter "vacuum_cost_page_hit" short description -#: ../include/utils/guc_tables.inc.c:6224 utils/guc_tables.inc.c:6224 +#: ../include/utils/guc_tables.inc.c:6225 utils/guc_tables.inc.c:6225 msgid "Vacuum cost for a page found in the buffer cache." msgstr "Vacuum-Kosten für eine im Puffer-Cache gefundene Seite." #. translator: GUC parameter "vacuum_cost_page_miss" short description -#: ../include/utils/guc_tables.inc.c:6239 utils/guc_tables.inc.c:6239 +#: ../include/utils/guc_tables.inc.c:6240 utils/guc_tables.inc.c:6240 msgid "Vacuum cost for a page not found in the buffer cache." msgstr "Vacuum-Kosten für eine nicht im Puffer-Cache gefundene Seite." #. translator: GUC parameter "vacuum_failsafe_age" short description -#: ../include/utils/guc_tables.inc.c:6254 utils/guc_tables.inc.c:6254 +#: ../include/utils/guc_tables.inc.c:6255 utils/guc_tables.inc.c:6255 msgid "Age at which VACUUM should trigger failsafe to avoid a wraparound outage." msgstr "Alter, bei dem VACUUM die Ausfallsicherung auslösen soll, um Ausfall wegen Transaktionsnummernüberlauf zu verhindern." #. translator: GUC parameter "vacuum_freeze_min_age" short description -#: ../include/utils/guc_tables.inc.c:6269 utils/guc_tables.inc.c:6269 +#: ../include/utils/guc_tables.inc.c:6270 utils/guc_tables.inc.c:6270 msgid "Minimum age at which VACUUM should freeze a table row." msgstr "Mindestalter, bei dem VACUUM eine Tabellenzeile einfrieren soll." #. translator: GUC parameter "vacuum_freeze_table_age" short description -#: ../include/utils/guc_tables.inc.c:6284 utils/guc_tables.inc.c:6284 +#: ../include/utils/guc_tables.inc.c:6285 utils/guc_tables.inc.c:6285 msgid "Age at which VACUUM should scan whole table to freeze tuples." msgstr "Alter, bei dem VACUUM die ganze Tabelle durchsuchen soll, um Zeilen einzufrieren." #. translator: GUC parameter "vacuum_max_eager_freeze_failure_rate" short description -#: ../include/utils/guc_tables.inc.c:6299 utils/guc_tables.inc.c:6299 +#: ../include/utils/guc_tables.inc.c:6300 utils/guc_tables.inc.c:6300 msgid "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning." msgstr "Bruchteil an Seiten in einer Relation, die Vacuum scannen kann aber nicht einfrieren kann, bevor Eager Scanning ausgeschaltet wird." #. translator: GUC parameter "vacuum_max_eager_freeze_failure_rate" long description -#: ../include/utils/guc_tables.inc.c:6301 utils/guc_tables.inc.c:6301 +#: ../include/utils/guc_tables.inc.c:6302 utils/guc_tables.inc.c:6302 msgid "A value of 0.0 disables eager scanning and a value of 1.0 will eagerly scan up to 100 percent of the all-visible pages in the relation. If vacuum successfully freezes these pages, the cap is lower than 100 percent, because the goal is to amortize page freezing across multiple vacuums." msgstr "Der Wert 0.0 schaltet Eager Scanning aus und der Wert 1.0 wird bis zu 100 Prozent der all-visible Seiten in der Relation mit Eager Scanning lesen. Wenn Vacuum diese Seiten erfolgreich einfriert, dann ist die Deckelung niedriger als 100 Prozent, weil das Ziel ist, die Kosten für das Einfrieren von Seiten über mehrere Vacuums zu amortisieren." #. translator: GUC parameter "vacuum_multixact_failsafe_age" short description -#: ../include/utils/guc_tables.inc.c:6316 utils/guc_tables.inc.c:6316 +#: ../include/utils/guc_tables.inc.c:6317 utils/guc_tables.inc.c:6317 msgid "Multixact age at which VACUUM should trigger failsafe to avoid a wraparound outage." msgstr "Multixact-Alter, bei dem VACUUM die Ausfallsicherung auslösen soll, um Ausfall wegen Transaktionsnummernüberlauf zu verhindern." #. translator: GUC parameter "vacuum_multixact_freeze_min_age" short description -#: ../include/utils/guc_tables.inc.c:6331 utils/guc_tables.inc.c:6331 +#: ../include/utils/guc_tables.inc.c:6332 utils/guc_tables.inc.c:6332 msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." msgstr "Mindestalter, bei dem VACUUM eine MultiXactId in einer Tabellenzeile einfrieren soll." #. translator: GUC parameter "vacuum_multixact_freeze_table_age" short description -#: ../include/utils/guc_tables.inc.c:6346 utils/guc_tables.inc.c:6346 +#: ../include/utils/guc_tables.inc.c:6347 utils/guc_tables.inc.c:6347 msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." msgstr "Multixact-Alter, bei dem VACUUM die ganze Tabelle durchsuchen soll, um Zeilen einzufrieren." #. translator: GUC parameter "vacuum_truncate" short description -#: ../include/utils/guc_tables.inc.c:6361 utils/guc_tables.inc.c:6361 +#: ../include/utils/guc_tables.inc.c:6362 utils/guc_tables.inc.c:6362 msgid "Enables vacuum to truncate empty pages at the end of the table." msgstr "Ermöglicht es Vacuum, leere Seiten am Ende der Tabelle abzuschneiden." #. translator: GUC parameter "wal_block_size" short description -#: ../include/utils/guc_tables.inc.c:6374 utils/guc_tables.inc.c:6374 +#: ../include/utils/guc_tables.inc.c:6375 utils/guc_tables.inc.c:6375 msgid "Shows the block size in the write ahead log." msgstr "Zeigt die Blockgröße im Write-Ahead-Log." #. translator: GUC parameter "wal_buffers" short description -#: ../include/utils/guc_tables.inc.c:6390 utils/guc_tables.inc.c:6390 +#: ../include/utils/guc_tables.inc.c:6391 utils/guc_tables.inc.c:6391 msgid "Sets the number of disk-page buffers in shared memory for WAL." msgstr "Setzt die Anzahl Diskseitenpuffer für WAL im Shared Memory." #. translator: GUC parameter "wal_buffers" long description -#: ../include/utils/guc_tables.inc.c:6392 utils/guc_tables.inc.c:6392 +#: ../include/utils/guc_tables.inc.c:6393 utils/guc_tables.inc.c:6393 msgid "-1 means use a fraction of \"shared_buffers\"." msgstr "-1 bedeutet, einen Bruchteil von »shared_buffers« zu verwenden." #. translator: GUC parameter "wal_compression" short description -#: ../include/utils/guc_tables.inc.c:6409 utils/guc_tables.inc.c:6409 +#: ../include/utils/guc_tables.inc.c:6410 utils/guc_tables.inc.c:6410 msgid "Compresses full-page writes written in WAL file with specified method." msgstr "Komprimiert in WAL-Dateien geschriebene volle Seiten mit der angegebenen Methode." #. translator: GUC parameter "wal_consistency_checking" short description -#: ../include/utils/guc_tables.inc.c:6423 utils/guc_tables.inc.c:6423 +#: ../include/utils/guc_tables.inc.c:6424 utils/guc_tables.inc.c:6424 msgid "Sets the WAL resource managers for which WAL consistency checks are done." msgstr "Setzt die WAL-Resource-Manager, für die WAL-Konsistenzprüfungen durchgeführt werden." #. translator: GUC parameter "wal_consistency_checking" long description -#: ../include/utils/guc_tables.inc.c:6425 utils/guc_tables.inc.c:6425 +#: ../include/utils/guc_tables.inc.c:6426 utils/guc_tables.inc.c:6426 msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." msgstr "Volle Seitenabbilder werden für alle Datenblöcke geloggt und gegen die Resultate der WAL-Wiederherstellung geprüft." #. translator: GUC parameter "wal_debug" short description -#: ../include/utils/guc_tables.inc.c:6442 utils/guc_tables.inc.c:6442 +#: ../include/utils/guc_tables.inc.c:6443 utils/guc_tables.inc.c:6443 msgid "Emit WAL-related debugging output." msgstr "Gibt diverse Debug-Meldungen über WAL aus." #. translator: GUC parameter "wal_decode_buffer_size" short description -#: ../include/utils/guc_tables.inc.c:6457 utils/guc_tables.inc.c:6457 +#: ../include/utils/guc_tables.inc.c:6458 utils/guc_tables.inc.c:6458 msgid "Buffer size for reading ahead in the WAL during recovery." msgstr "Puffergröße für WAL-Read-Ahead während der Wiederherstellung." #. translator: GUC parameter "wal_decode_buffer_size" long description -#: ../include/utils/guc_tables.inc.c:6459 utils/guc_tables.inc.c:6459 +#: ../include/utils/guc_tables.inc.c:6460 utils/guc_tables.inc.c:6460 msgid "Maximum distance to read ahead in the WAL to prefetch referenced data blocks." msgstr "Maximale Entfernung, die im WAL vorausgelesen wird, um Datenblöcke, auf die verwiesen wird, vorab einzulesen." #. translator: GUC parameter "wal_init_zero" short description -#: ../include/utils/guc_tables.inc.c:6475 utils/guc_tables.inc.c:6475 +#: ../include/utils/guc_tables.inc.c:6476 utils/guc_tables.inc.c:6476 msgid "Writes zeroes to new WAL files before first use." msgstr "Schreibt Nullen in neue WAL-Dateien vor der ersten Verwendung." #. translator: GUC parameter "wal_keep_size" short description -#: ../include/utils/guc_tables.inc.c:6488 utils/guc_tables.inc.c:6488 +#: ../include/utils/guc_tables.inc.c:6489 utils/guc_tables.inc.c:6489 msgid "Sets the size of WAL files held for standby servers." msgstr "Setzt die Größe der für Standby-Server vorgehaltenen WAL-Dateien." #. translator: GUC parameter "wal_level" short description -#: ../include/utils/guc_tables.inc.c:6504 utils/guc_tables.inc.c:6504 +#: ../include/utils/guc_tables.inc.c:6505 utils/guc_tables.inc.c:6505 msgid "Sets the level of information written to the WAL." msgstr "Setzt den Umfang der in den WAL geschriebenen Informationen." #. translator: GUC parameter "wal_log_hints" short description -#: ../include/utils/guc_tables.inc.c:6518 utils/guc_tables.inc.c:6518 +#: ../include/utils/guc_tables.inc.c:6519 utils/guc_tables.inc.c:6519 msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modification." msgstr "Schreibt volle Seiten in den WAL, sobald sie nach einem Checkpoint geändert werden, auch für eine nicht kritische Änderung." #. translator: GUC parameter "wal_receiver_create_temp_slot" short description -#: ../include/utils/guc_tables.inc.c:6531 utils/guc_tables.inc.c:6531 +#: ../include/utils/guc_tables.inc.c:6532 utils/guc_tables.inc.c:6532 msgid "Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured." msgstr "Bestimmt, ob der WAL-Receiver einen temporären Replikations-Slot erzeugen soll, wenn kein permanenter Slot konfiguriert ist." #. translator: GUC parameter "wal_receiver_status_interval" short description -#: ../include/utils/guc_tables.inc.c:6544 utils/guc_tables.inc.c:6544 +#: ../include/utils/guc_tables.inc.c:6545 utils/guc_tables.inc.c:6545 msgid "Sets the maximum interval between WAL receiver status reports to the sending server." msgstr "Setzt das maximale Intervall zwischen Statusberichten des WAL-Receivers an den sendenden Server." #. translator: GUC parameter "wal_receiver_timeout" short description -#: ../include/utils/guc_tables.inc.c:6560 utils/guc_tables.inc.c:6560 +#: ../include/utils/guc_tables.inc.c:6561 utils/guc_tables.inc.c:6561 msgid "Sets the maximum wait time to receive data from the sending server." msgstr "Setzt die maximale Zeit, um auf den Empfang von Daten vom sendenden Server zu warten." #. translator: GUC parameter "wal_recycle" short description -#: ../include/utils/guc_tables.inc.c:6578 utils/guc_tables.inc.c:6578 +#: ../include/utils/guc_tables.inc.c:6579 utils/guc_tables.inc.c:6579 msgid "Recycles WAL files by renaming them." msgstr "WAL-Dateien werden durch Umbenennen wiederverwendet." #. translator: GUC parameter "wal_retrieve_retry_interval" short description -#: ../include/utils/guc_tables.inc.c:6591 utils/guc_tables.inc.c:6591 +#: ../include/utils/guc_tables.inc.c:6592 utils/guc_tables.inc.c:6592 msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." msgstr "Setzt die Zeit, die gewartet wird, bevor nach einem fehlgeschlagenen Versuch neue WAL-Daten angefordert werden." #. translator: GUC parameter "wal_segment_size" short description -#: ../include/utils/guc_tables.inc.c:6607 utils/guc_tables.inc.c:6607 +#: ../include/utils/guc_tables.inc.c:6608 utils/guc_tables.inc.c:6608 msgid "Shows the size of write ahead log segments." msgstr "Zeigt die Größe eines Write-Ahead-Log-Segments." #. translator: GUC parameter "wal_sender_shutdown_timeout" short description -#: ../include/utils/guc_tables.inc.c:6624 utils/guc_tables.inc.c:6624 +#: ../include/utils/guc_tables.inc.c:6625 utils/guc_tables.inc.c:6625 #, fuzzy #| msgid "Sets the maximum time to wait for WAL replication." msgid "Sets the maximum time the server waits during shutdown for all WAL data to be replicated to the receiver." msgstr "Setzt die maximale Zeit, um auf WAL-Replikation zu warten." #. translator: GUC parameter "wal_sender_shutdown_timeout" long description -#: ../include/utils/guc_tables.inc.c:6626 utils/guc_tables.inc.c:6626 +#: ../include/utils/guc_tables.inc.c:6627 utils/guc_tables.inc.c:6627 #, fuzzy #| msgid "0 disables the timeout." msgid "-1 disables the timeout" msgstr "0 schaltet Zeitüberschreitungen aus." #. translator: GUC parameter "wal_sender_timeout" short description -#: ../include/utils/guc_tables.inc.c:6642 utils/guc_tables.inc.c:6642 +#: ../include/utils/guc_tables.inc.c:6643 utils/guc_tables.inc.c:6643 msgid "Sets the maximum time to wait for WAL replication." msgstr "Setzt die maximale Zeit, um auf WAL-Replikation zu warten." #. translator: GUC parameter "wal_skip_threshold" short description -#: ../include/utils/guc_tables.inc.c:6658 utils/guc_tables.inc.c:6658 +#: ../include/utils/guc_tables.inc.c:6659 utils/guc_tables.inc.c:6659 msgid "Minimum size of new file to fsync instead of writing WAL." msgstr "Mindestgröße ab der neue Datei gefsynct wird statt WAL zu schreiben." #. translator: GUC parameter "wal_summary_keep_time" short description -#: ../include/utils/guc_tables.inc.c:6674 utils/guc_tables.inc.c:6674 +#: ../include/utils/guc_tables.inc.c:6675 utils/guc_tables.inc.c:6675 msgid "Time for which WAL summary files should be kept." msgstr "Zeit, für die WAL-Summary-Dateien aufgehoben werden sollen." #. translator: GUC parameter "wal_summary_keep_time" long description -#: ../include/utils/guc_tables.inc.c:6676 utils/guc_tables.inc.c:6676 +#: ../include/utils/guc_tables.inc.c:6677 utils/guc_tables.inc.c:6677 msgid "0 disables automatic summary file deletion." msgstr "0 schaltet das automatische Löschen von Summary-Dateien aus." #. translator: GUC parameter "wal_sync_method" short description -#: ../include/utils/guc_tables.inc.c:6692 utils/guc_tables.inc.c:6692 +#: ../include/utils/guc_tables.inc.c:6693 utils/guc_tables.inc.c:6693 msgid "Selects the method used for forcing WAL updates to disk." msgstr "Wählt die Methode, um das Schreiben von WAL-Änderungen auf die Festplatte zu erzwingen." #. translator: GUC parameter "wal_writer_delay" short description -#: ../include/utils/guc_tables.inc.c:6707 utils/guc_tables.inc.c:6707 +#: ../include/utils/guc_tables.inc.c:6708 utils/guc_tables.inc.c:6708 msgid "Time between WAL flushes performed in the WAL writer." msgstr "Zeit zwischen WAL-Flush-Operationen im WAL-Writer." #. translator: GUC parameter "wal_writer_flush_after" short description -#: ../include/utils/guc_tables.inc.c:6723 utils/guc_tables.inc.c:6723 +#: ../include/utils/guc_tables.inc.c:6724 utils/guc_tables.inc.c:6724 msgid "Amount of WAL written out by WAL writer that triggers a flush." msgstr "Ein Flush wird ausgelöst, wenn diese Menge WAL vom WAL-Writer geschrieben worden ist." #. translator: GUC parameter "work_mem" short description -#: ../include/utils/guc_tables.inc.c:6739 utils/guc_tables.inc.c:6739 +#: ../include/utils/guc_tables.inc.c:6740 utils/guc_tables.inc.c:6740 msgid "Sets the maximum memory to be used for query workspaces." msgstr "Setzt die maximale Speichergröße für Anfrage-Arbeitsbereiche." #. translator: GUC parameter "work_mem" long description -#: ../include/utils/guc_tables.inc.c:6741 utils/guc_tables.inc.c:6741 +#: ../include/utils/guc_tables.inc.c:6742 utils/guc_tables.inc.c:6742 msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." msgstr "Gibt die Speichermenge an, die für interne Sortiervorgänge und Hashtabellen verwendet werden kann, bevor auf temporäre Dateien umgeschaltet wird." #. translator: GUC parameter "xmlbinary" short description -#: ../include/utils/guc_tables.inc.c:6757 utils/guc_tables.inc.c:6757 +#: ../include/utils/guc_tables.inc.c:6758 utils/guc_tables.inc.c:6758 msgid "Sets how binary values are to be encoded in XML." msgstr "Setzt, wie binäre Werte in XML kodiert werden." #. translator: GUC parameter "xmloption" short description -#: ../include/utils/guc_tables.inc.c:6771 utils/guc_tables.inc.c:6771 +#: ../include/utils/guc_tables.inc.c:6772 utils/guc_tables.inc.c:6772 msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." msgstr "Setzt, ob XML-Daten in impliziten Parse- und Serialisierungsoperationen als Dokument oder Fragment betrachtet werden sollen." #. translator: GUC parameter "zero_damaged_pages" short description -#: ../include/utils/guc_tables.inc.c:6785 utils/guc_tables.inc.c:6785 +#: ../include/utils/guc_tables.inc.c:6786 utils/guc_tables.inc.c:6786 msgid "Continues processing past damaged page headers." msgstr "Setzt die Verarbeitung trotz kaputter Seitenköpfe fort." #. translator: GUC parameter "zero_damaged_pages" long description -#: ../include/utils/guc_tables.inc.c:6787 utils/guc_tables.inc.c:6787 +#: ../include/utils/guc_tables.inc.c:6788 utils/guc_tables.inc.c:6788 msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting \"zero_damaged_pages\" to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." msgstr "Wenn ein kaputter Seitenkopf entdeckt wird, gibt PostgreSQL normalerweise einen Fehler aus und bricht die aktuelle Transaktion ab. Wenn »zero_damaged_pages« an ist, dann wird eine Warnung ausgegeben, die kaputte Seite mit Nullen gefüllt und die Verarbeitung geht weiter. Dieses Verhalten zerstört Daten, nämlich alle Zeilen in der kaputten Seite." @@ -3797,7 +3807,7 @@ msgstr "Versuche werden für 30 Sekunden wiederholt." msgid "You might have antivirus, backup, or similar software interfering with the database system." msgstr "Möglicherweise stört eine Antivirus-, Datensicherungs- oder ähnliche Software das Datenbanksystem." -#: ../port/path.c:853 +#: ../port/path.c:870 #, c-format msgid "could not get current working directory: %m\n" msgstr "konnte aktuelles Arbeitsverzeichnis nicht ermitteln: %m\n" @@ -3833,8 +3843,8 @@ msgstr "Aufforderung für BRIN-Range-Summarization für Index »%s« Seite %u wu #: access/transam/xlogfuncs.c:332 access/transam/xlogfuncs.c:353 #: access/transam/xlogfuncs.c:419 access/transam/xlogfuncs.c:478 #: commands/wait.c:192 statistics/attribute_stats.c:180 -#: statistics/attribute_stats.c:602 statistics/extended_stats_funcs.c:370 -#: statistics/extended_stats_funcs.c:1747 statistics/relation_stats.c:97 +#: statistics/attribute_stats.c:619 statistics/extended_stats_funcs.c:370 +#: statistics/extended_stats_funcs.c:1778 statistics/relation_stats.c:97 #, c-format msgid "recovery is in progress" msgstr "Wiederherstellung läuft" @@ -3860,14 +3870,14 @@ msgid "could not open parent table of index \"%s\"" msgstr "konnte Basistabelle von Index »%s« nicht öffnen" #: access/brin/brin.c:1477 access/brin/brin.c:1573 access/gin/ginfast.c:1085 -#: parser/parse_utilcmd.c:2456 +#: parser/parse_utilcmd.c:2460 #, c-format msgid "index \"%s\" is not valid" msgstr "Index »%s« ist nicht gültig" #: access/brin/brin_bloom.c:786 access/brin/brin_bloom.c:828 #: access/brin/brin_minmax_multi.c:2982 access/brin/brin_minmax_multi.c:3119 -#: statistics/mcv.c:1478 statistics/mcv.c:1509 utils/adt/pg_dependencies.c:858 +#: statistics/mcv.c:1478 statistics/mcv.c:1509 utils/adt/pg_dependencies.c:857 #: utils/adt/pg_ndistinct.c:836 utils/adt/pseudotypes.c:40 #: utils/adt/pseudotypes.c:74 utils/adt/tsgistidx.c:94 #, c-format @@ -3991,7 +4001,7 @@ msgid "index row requires %zu bytes, maximum size is %zu" msgstr "Indexzeile benötigt %zu Bytes, Maximalgröße ist %zu" #: access/common/printtup.c:293 commands/explain_dr.c:95 tcop/fastpath.c:106 -#: tcop/fastpath.c:453 tcop/postgres.c:1964 +#: tcop/fastpath.c:453 tcop/postgres.c:1965 #, c-format msgid "unsupported format code: %d" msgstr "nicht unterstützter Formatcode: %d" @@ -4040,12 +4050,11 @@ msgid "parameter \"%s\" specified more than once" msgstr "Parameter »%s« mehrmals angegeben" #: access/common/reloptions.c:1715 access/common/reloptions.c:1729 -#: utils/adt/ddlutils.c:195 #, c-format msgid "invalid value for boolean option \"%s\": %s" msgstr "ungültiger Wert für Boole’sche Option »%s«: »%s«" -#: access/common/reloptions.c:1741 utils/adt/ddlutils.c:215 +#: access/common/reloptions.c:1741 #, c-format msgid "invalid value for integer option \"%s\": %s" msgstr "ungültiger Wert für ganzzahlige Option »%s«: »%s«" @@ -4128,8 +4137,8 @@ msgid "failed to re-find tuple within index \"%s\"" msgstr "konnte Tupel mit Index »%s« nicht erneut finden" #: access/gin/gininsert.c:1324 access/gin/ginutil.c:155 -#: executor/execExpr.c:2276 utils/adt/array_userfuncs.c:1972 -#: utils/adt/arrayfuncs.c:4040 utils/adt/arrayfuncs.c:6745 +#: executor/execExpr.c:2243 utils/adt/array_userfuncs.c:1972 +#: utils/adt/arrayfuncs.c:4040 utils/adt/arrayfuncs.c:6752 #: utils/adt/rowtypes.c:974 utils/sort/tuplesortvariants.c:647 #, c-format msgid "could not identify a comparison function for type %s" @@ -4219,19 +4228,19 @@ msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY op msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält ungültige ORDER-BY-Operatorfamilienangabe für Operator %s" #: access/hash/hashfunc.c:280 access/hash/hashfunc.c:335 -#: utils/adt/varchar.c:1000 utils/adt/varchar.c:1056 +#: utils/adt/varchar.c:1003 utils/adt/varchar.c:1059 #, c-format msgid "could not determine which collation to use for string hashing" msgstr "konnte die für das Zeichenketten-Hashing zu verwendende Sortierfolge nicht bestimmen" -#: access/hash/hashfunc.c:281 access/hash/hashfunc.c:336 catalog/heap.c:688 -#: catalog/heap.c:694 commands/createas.c:203 commands/createas.c:515 -#: commands/indexcmds.c:2110 commands/tablecmds.c:20266 commands/view.c:79 +#: access/hash/hashfunc.c:281 access/hash/hashfunc.c:336 catalog/heap.c:703 +#: catalog/heap.c:709 commands/createas.c:203 commands/createas.c:515 +#: commands/indexcmds.c:2110 commands/tablecmds.c:20644 commands/view.c:79 #: regex/regc_pg_locale.c:48 utils/adt/formatting.c:1638 #: utils/adt/formatting.c:1702 utils/adt/formatting.c:1766 #: utils/adt/formatting.c:1830 utils/adt/like.c:151 utils/adt/like.c:182 -#: utils/adt/like_support.c:1095 utils/adt/varchar.c:738 -#: utils/adt/varchar.c:1001 utils/adt/varchar.c:1057 utils/adt/varlena.c:1337 +#: utils/adt/like_support.c:1107 utils/adt/varchar.c:741 +#: utils/adt/varchar.c:1004 utils/adt/varchar.c:1060 utils/adt/varlena.c:1337 #, c-format msgid "Use the COLLATE clause to set the collation explicitly." msgstr "Verwenden Sie die COLLATE-Klausel, um die Sortierfolge explizit zu setzen." @@ -4303,7 +4312,7 @@ msgstr "während einer parallelen Operation können keine Tupel gelöscht werden msgid "attempted to delete invisible tuple" msgstr "Versuch ein unsichtbares Tupel zu löschen" -#: access/heap/heapam.c:3264 access/index/genam.c:840 +#: access/heap/heapam.c:3264 access/index/genam.c:832 #, c-format msgid "cannot update tuples during a parallel operation" msgstr "während einer parallelen Operation können keine Tupel aktualisiert werden" @@ -4320,7 +4329,7 @@ msgid "could not obtain lock on row in relation \"%s\"" msgstr "konnte Sperre für Zeile in Relation »%s« nicht setzen" #: access/heap/heapam.c:6392 commands/trigger.c:3402 -#: executor/nodeModifyTable.c:2868 executor/nodeModifyTable.c:2958 +#: executor/nodeModifyTable.c:2875 executor/nodeModifyTable.c:2965 #, c-format msgid "tuple to be updated was already modified by an operation triggered by the current command" msgstr "das zu aktualisierende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" @@ -4369,13 +4378,13 @@ msgstr "konnte nicht in Datei »%s« schreiben, %d von %d geschrieben: %m" #: access/heap/rewriteheap.c:980 access/heap/rewriteheap.c:1097 #: access/transam/timeline.c:330 access/transam/timeline.c:482 -#: access/transam/xlog.c:3298 access/transam/xlog.c:3506 -#: access/transam/xlog.c:4377 access/transam/xlog.c:9952 +#: access/transam/xlog.c:3294 access/transam/xlog.c:3502 +#: access/transam/xlog.c:4373 access/transam/xlog.c:9940 #: access/transam/xlogfuncs.c:712 backup/basebackup_server.c:149 #: backup/basebackup_server.c:242 commands/dbcommands.c:498 #: postmaster/launch_backend.c:332 postmaster/postmaster.c:4142 #: postmaster/walsummarizer.c:1218 replication/logical/origin.c:644 -#: replication/slot.c:2565 storage/file/copydir.c:174 +#: replication/slot.c:2561 storage/file/copydir.c:174 #: storage/file/copydir.c:262 storage/smgr/md.c:263 utils/time/snapmgr.c:1254 #, c-format msgid "could not create file \"%s\": %m" @@ -4388,12 +4397,12 @@ msgstr "konnte Datei »%s« nicht auf %u kürzen: %m" #: access/heap/rewriteheap.c:1125 access/transam/timeline.c:385 #: access/transam/timeline.c:425 access/transam/timeline.c:499 -#: access/transam/xlog.c:3359 access/transam/xlog.c:3562 -#: access/transam/xlog.c:4389 commands/dbcommands.c:510 +#: access/transam/xlog.c:3347 access/transam/xlog.c:3558 +#: access/transam/xlog.c:4385 commands/dbcommands.c:510 #: postmaster/launch_backend.c:343 postmaster/launch_backend.c:355 #: replication/logical/origin.c:656 replication/logical/origin.c:698 -#: replication/logical/origin.c:717 replication/logical/snapbuild.c:1725 -#: replication/slot.c:2601 storage/file/buffile.c:546 +#: replication/logical/origin.c:717 replication/logical/snapbuild.c:1669 +#: replication/slot.c:2597 storage/file/buffile.c:546 #: storage/file/copydir.c:214 utils/init/miscinit.c:1611 #: utils/init/miscinit.c:1622 utils/init/miscinit.c:1630 utils/misc/guc.c:4389 #: utils/misc/guc.c:4420 utils/misc/guc.c:5579 utils/misc/guc.c:5597 @@ -4662,19 +4671,19 @@ msgstr "Zugriffsmethode »%s« ist nicht vom Typ %s" msgid "index access method \"%s\" does not have a handler" msgstr "Indexzugriffsmethode »%s« hat keinen Handler" -#: access/index/genam.c:507 +#: access/index/genam.c:499 #, c-format msgid "transaction aborted during system catalog scan" msgstr "Transaktion während eines Systemkatalog-Scans abgebrochen" -#: access/index/genam.c:672 access/index/indexam.c:83 +#: access/index/genam.c:664 access/index/indexam.c:83 #, c-format msgid "cannot access index \"%s\" while it is being reindexed" msgstr "auf Index »%s« kann nicht zugegriffen werden, während er reindiziert wird" -#: access/index/indexam.c:204 catalog/objectaddress.c:1449 +#: access/index/indexam.c:204 catalog/objectaddress.c:1455 #: commands/indexcmds.c:3039 commands/tablecmds.c:288 commands/tablecmds.c:312 -#: commands/tablecmds.c:19945 commands/tablecmds.c:21896 +#: commands/tablecmds.c:20323 commands/tablecmds.c:22267 #, c-format msgid "\"%s\" is not an index" msgstr "»%s« ist kein Index" @@ -4700,7 +4709,7 @@ msgid "This may be because of a non-immutable index expression." msgstr "Das kann daran liegen, dass der Indexausdruck nicht »immutable« ist." #: access/nbtree/nbtpage.c:158 access/nbtree/nbtpage.c:616 -#: parser/parse_utilcmd.c:2506 +#: parser/parse_utilcmd.c:2510 #, c-format msgid "index \"%s\" is not a btree" msgstr "Index »%s« ist kein B-Tree" @@ -4745,10 +4754,10 @@ msgid "operator family \"%s\" of access method %s is missing support function fo msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlt Support-Funktion für Typen %s und %s" #: access/sequence/sequence.c:75 catalog/aclchk.c:1842 -#: catalog/objectaddress.c:1463 commands/tablecmds.c:270 -#: commands/tablecmds.c:19913 utils/adt/acl.c:2150 utils/adt/acl.c:2180 -#: utils/adt/acl.c:2213 utils/adt/acl.c:2249 utils/adt/acl.c:2280 -#: utils/adt/acl.c:2311 +#: catalog/objectaddress.c:1469 commands/tablecmds.c:270 +#: commands/tablecmds.c:20291 utils/adt/acl.c:2153 utils/adt/acl.c:2183 +#: utils/adt/acl.c:2216 utils/adt/acl.c:2252 utils/adt/acl.c:2283 +#: utils/adt/acl.c:2314 #, c-format msgid "\"%s\" is not a sequence" msgstr "»%s« ist keine Sequenz" @@ -4788,7 +4797,7 @@ msgstr "tid (%u, %u) ist nicht gültig für Relation »%s«" msgid "\"%s\" cannot be empty." msgstr "»%s« kann nicht leer sein." -#: access/table/tableamapi.c:112 access/transam/xlogrecovery.c:4876 +#: access/table/tableamapi.c:112 access/transam/xlogrecovery.c:4881 #, c-format msgid "\"%s\" is too long (maximum %d characters)." msgstr "»%s« ist zu lang (maximal %d Zeichen)." @@ -4847,11 +4856,13 @@ msgstr "Datenbank nimmt keine Befehle an, die neue MultiXactIds zuweisen, um Dat #: access/transam/multixact.c:1042 access/transam/multixact.c:1049 #: access/transam/multixact.c:1075 access/transam/multixact.c:1086 -#: access/transam/varsup.c:149 access/transam/varsup.c:156 -#, c-format +#, fuzzy, c-format +#| msgid "" +#| "Execute a database-wide VACUUM in that database.\n" +#| "You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgid "" "Execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +"You might also need to commit or roll back old prepared transactions." msgstr "" "Führen Sie ein datenbankweites VACUUM in dieser Datenbank aus.\n" "Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." @@ -4925,10 +4936,13 @@ msgid "MultiXact %u has too many members (%)" msgstr "Indikator-Struct »%s« hat zu viele Mitglieder" #: access/transam/multixact.c:2213 access/transam/multixact.c:2224 -#, c-format +#, fuzzy, c-format +#| msgid "" +#| "To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" +#| "You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgid "" "To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +"You might also need to commit or roll back old prepared transactions." msgstr "" "Um Scheitern von MultiXactId-Zuweisungen zu vermeiden, führen Sie ein komplettes VACUUM über diese Datenbank aus.\n" "Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." @@ -4989,7 +5003,7 @@ msgstr "Verbindung mit parallelem Arbeitsprozess verloren" msgid "parallel worker" msgstr "paralleler Arbeitsprozess" -#: access/transam/parallel.c:1356 commands/repack_worker.c:83 +#: access/transam/parallel.c:1356 commands/repack_worker.c:78 #: replication/logical/applyparallelworker.c:909 #, c-format msgid "could not map dynamic shared memory segment" @@ -5245,7 +5259,7 @@ msgstr "berechnete CRC-Prüfsumme stimmt nicht mit dem Wert in Datei »%s« übe #: access/transam/twophase.c:1433 access/transam/xlogrecovery.c:510 #: postmaster/walsummarizer.c:936 replication/logical/logical.c:202 -#: replication/walsender.c:854 +#: replication/walsender.c:861 #, c-format msgid "Failed while allocating a WAL reading processor." msgstr "Fehlgeschlagen beim Anlegen eines WAL-Leseprozessors." @@ -5343,6 +5357,15 @@ msgstr "konnte nicht auf Datei »%s« zugreifen: %m" msgid "database is not accepting commands that assign new transaction IDs to avoid wraparound data loss in database \"%s\"" msgstr "Datenbank nimmt keine Befehle an, die neue Transaktions-IDs zuweisen, um Datenverlust wegen Transaktionsnummernüberlauf in Datenbank »%s« zu vermeiden" +#: access/transam/varsup.c:149 access/transam/varsup.c:156 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Führen Sie ein datenbankweites VACUUM in dieser Datenbank aus.\n" +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." + #: access/transam/varsup.c:154 #, c-format msgid "database is not accepting commands that assign new transaction IDs to avoid wraparound data loss in database with OID %u" @@ -5408,92 +5431,92 @@ msgstr "kann nicht mehr als 2^32-2 Befehle in einer Transaktion ausführen" msgid "maximum number of committed subtransactions (%d) exceeded" msgstr "maximale Anzahl committeter Subtransaktionen (%d) überschritten" -#: access/transam/xact.c:2659 +#: access/transam/xact.c:2660 #, c-format msgid "cannot PREPARE a transaction that has operated on temporary objects" msgstr "PREPARE kann nicht für eine Transaktion ausgeführt werden, die temporäre Objekte bearbeitet hat" -#: access/transam/xact.c:2669 +#: access/transam/xact.c:2670 #, c-format msgid "cannot PREPARE a transaction that has exported snapshots" msgstr "PREPARE kann nicht für eine Transaktion ausgeführt werden, die Snapshots exportiert hat" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3707 +#: access/transam/xact.c:3710 #, c-format msgid "%s cannot run inside a transaction block" msgstr "%s kann nicht in einem Transaktionsblock laufen" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3717 +#: access/transam/xact.c:3720 #, c-format msgid "%s cannot run inside a subtransaction" msgstr "%s kann nicht in einer Subtransaktion laufen" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3727 +#: access/transam/xact.c:3730 #, fuzzy, c-format #| msgid "%s cannot be executed from a function" msgid "%s cannot be executed from a function or procedure" msgstr "%s kann nicht aus einer Funktion ausgeführt werden" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3799 access/transam/xact.c:4121 -#: access/transam/xact.c:4200 access/transam/xact.c:4323 -#: access/transam/xact.c:4474 access/transam/xact.c:4543 -#: access/transam/xact.c:4654 +#: access/transam/xact.c:3802 access/transam/xact.c:4124 +#: access/transam/xact.c:4203 access/transam/xact.c:4326 +#: access/transam/xact.c:4477 access/transam/xact.c:4546 +#: access/transam/xact.c:4657 #, c-format msgid "%s can only be used in transaction blocks" msgstr "%s kann nur in Transaktionsblöcken verwendet werden" -#: access/transam/xact.c:4007 +#: access/transam/xact.c:4010 #, c-format msgid "there is already a transaction in progress" msgstr "eine Transaktion ist bereits begonnen" -#: access/transam/xact.c:4126 access/transam/xact.c:4205 -#: access/transam/xact.c:4328 +#: access/transam/xact.c:4129 access/transam/xact.c:4208 +#: access/transam/xact.c:4331 #, c-format msgid "there is no transaction in progress" msgstr "keine Transaktion offen" -#: access/transam/xact.c:4216 +#: access/transam/xact.c:4219 #, c-format msgid "cannot commit during a parallel operation" msgstr "während einer parallelen Operation kann nicht committet werden" -#: access/transam/xact.c:4339 +#: access/transam/xact.c:4342 #, c-format msgid "cannot abort during a parallel operation" msgstr "während einer parallelen Operation kann nicht abgebrochen werden" -#: access/transam/xact.c:4438 +#: access/transam/xact.c:4441 #, c-format msgid "cannot define savepoints during a parallel operation" msgstr "während einer parallelen Operation können keine Sicherungspunkte definiert werden" -#: access/transam/xact.c:4525 +#: access/transam/xact.c:4528 #, c-format msgid "cannot release savepoints during a parallel operation" msgstr "während einer parallelen Operation können keine Sicherungspunkte freigegeben werden" -#: access/transam/xact.c:4535 access/transam/xact.c:4586 -#: access/transam/xact.c:4646 access/transam/xact.c:4695 +#: access/transam/xact.c:4538 access/transam/xact.c:4589 +#: access/transam/xact.c:4649 access/transam/xact.c:4698 #, c-format msgid "savepoint \"%s\" does not exist" msgstr "Sicherungspunkt »%s« existiert nicht" -#: access/transam/xact.c:4592 access/transam/xact.c:4701 +#: access/transam/xact.c:4595 access/transam/xact.c:4704 #, c-format msgid "savepoint \"%s\" does not exist within current savepoint level" msgstr "Sicherungspunkt »%s« existiert nicht innerhalb der aktuellen Sicherungspunktebene" -#: access/transam/xact.c:4634 +#: access/transam/xact.c:4637 #, c-format msgid "cannot rollback to savepoints during a parallel operation" msgstr "während einer parallelen Operation kann nicht auf einen Sicherungspunkt zurückgerollt werden" -#: access/transam/xact.c:5489 +#: access/transam/xact.c:5497 #, c-format msgid "cannot have more than 2^32-1 subtransactions in a transaction" msgstr "kann nicht mehr als 2^32-1 Subtransaktionen in einer Transaktion haben" @@ -5510,110 +5533,110 @@ msgstr "Flush hinter das Ende des erzeugten WAL angefordert; Anforderung %X/%X, msgid "cannot read past end of generated WAL: requested %X/%08X, current position %X/%08X" msgstr "kann nicht hinter das Ende des erzeugten WAL lesen: Anforderung %X/%X, aktuelle Position %X/%X" -#: access/transam/xlog.c:2239 access/transam/xlog.c:4607 +#: access/transam/xlog.c:2239 access/transam/xlog.c:4603 #, c-format msgid "The WAL segment size must be a power of two between 1 MB and 1 GB." msgstr "Die WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein." -#: access/transam/xlog.c:2475 +#: access/transam/xlog.c:2472 #, c-format msgid "could not write to log file \"%s\" at offset %u, length %zu: %m" msgstr "konnte nicht in Logdatei »%s« bei Position %u, Länge %zu schreiben: %m" -#: access/transam/xlog.c:3799 access/transam/xlogutils.c:820 -#: replication/walsender.c:3294 +#: access/transam/xlog.c:3795 access/transam/xlogutils.c:844 +#: replication/walsender.c:3323 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "das angeforderte WAL-Segment %s wurde schon entfernt" -#: access/transam/xlog.c:4121 +#: access/transam/xlog.c:4117 #, c-format msgid "could not rename file \"%s\": %m" msgstr "konnte Datei »%s« nicht umbenennen: %m" -#: access/transam/xlog.c:4164 access/transam/xlog.c:4175 -#: access/transam/xlog.c:4196 +#: access/transam/xlog.c:4160 access/transam/xlog.c:4171 +#: access/transam/xlog.c:4192 #, c-format msgid "required WAL directory \"%s\" does not exist" msgstr "benötigtes WAL-Verzeichnis »%s« existiert nicht" -#: access/transam/xlog.c:4181 access/transam/xlog.c:4202 +#: access/transam/xlog.c:4177 access/transam/xlog.c:4198 #, c-format msgid "creating missing WAL directory \"%s\"" msgstr "erzeuge fehlendes WAL-Verzeichnis »%s«" -#: access/transam/xlog.c:4185 access/transam/xlog.c:4205 +#: access/transam/xlog.c:4181 access/transam/xlog.c:4201 #: commands/dbcommands.c:3300 #, c-format msgid "could not create missing directory \"%s\": %m" msgstr "konnte fehlendes Verzeichnis »%s« nicht erzeugen: %m" -#: access/transam/xlog.c:4272 +#: access/transam/xlog.c:4268 #, c-format msgid "could not generate secret authorization token" msgstr "konnte geheimes Autorisierungstoken nicht erzeugen" -#: access/transam/xlog.c:4457 access/transam/xlog.c:4467 -#: access/transam/xlog.c:4493 access/transam/xlog.c:4503 -#: access/transam/xlog.c:4513 access/transam/xlog.c:4519 -#: access/transam/xlog.c:4529 access/transam/xlog.c:4539 -#: access/transam/xlog.c:4549 access/transam/xlog.c:4559 -#: access/transam/xlog.c:4569 access/transam/xlog.c:4579 -#: access/transam/xlog.c:4589 utils/init/miscinit.c:1768 +#: access/transam/xlog.c:4453 access/transam/xlog.c:4463 +#: access/transam/xlog.c:4489 access/transam/xlog.c:4499 +#: access/transam/xlog.c:4509 access/transam/xlog.c:4515 +#: access/transam/xlog.c:4525 access/transam/xlog.c:4535 +#: access/transam/xlog.c:4545 access/transam/xlog.c:4555 +#: access/transam/xlog.c:4565 access/transam/xlog.c:4575 +#: access/transam/xlog.c:4585 utils/init/miscinit.c:1768 #, c-format msgid "database files are incompatible with server" msgstr "Datenbankdateien sind inkompatibel mit Server" -#: access/transam/xlog.c:4458 +#: access/transam/xlog.c:4454 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." msgstr "Der Datenbank-Cluster wurde mit PG_CONTROL_VERSION %d (0x%08x) initialisiert, aber der Server wurde mit PG_CONTROL_VERSION %d (0x%08x) kompiliert." -#: access/transam/xlog.c:4462 +#: access/transam/xlog.c:4458 #, c-format msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." msgstr "Das Problem könnte eine falsche Byte-Reihenfolge sein. Es sieht so aus, dass Sie initdb ausführen müssen." -#: access/transam/xlog.c:4468 +#: access/transam/xlog.c:4464 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." msgstr "Der Datenbank-Cluster wurde mit PG_CONTROL_VERSION %d initialisiert, aber der Server wurde mit PG_CONTROL_VERSION %d kompiliert." -#: access/transam/xlog.c:4471 access/transam/xlog.c:4499 -#: access/transam/xlog.c:4509 access/transam/xlog.c:4515 +#: access/transam/xlog.c:4467 access/transam/xlog.c:4495 +#: access/transam/xlog.c:4505 access/transam/xlog.c:4511 #, c-format msgid "It looks like you need to initdb." msgstr "Es sieht so aus, dass Sie initdb ausführen müssen." -#: access/transam/xlog.c:4483 +#: access/transam/xlog.c:4479 #, c-format msgid "incorrect checksum in control file" msgstr "falsche Prüfsumme in Kontrolldatei" #. translator: %s is a variable name and %d is its value -#: access/transam/xlog.c:4495 access/transam/xlog.c:4505 -#: access/transam/xlog.c:4521 access/transam/xlog.c:4531 -#: access/transam/xlog.c:4541 access/transam/xlog.c:4551 -#: access/transam/xlog.c:4561 access/transam/xlog.c:4571 -#: access/transam/xlog.c:4581 access/transam/xlog.c:4591 +#: access/transam/xlog.c:4491 access/transam/xlog.c:4501 +#: access/transam/xlog.c:4517 access/transam/xlog.c:4527 +#: access/transam/xlog.c:4537 access/transam/xlog.c:4547 +#: access/transam/xlog.c:4557 access/transam/xlog.c:4567 +#: access/transam/xlog.c:4577 access/transam/xlog.c:4587 #, c-format msgid "The database cluster was initialized with %s %d, but the server was compiled with %s %d." msgstr "Der Datenbank-Cluster wurde mit %s %d initialisiert, aber der Server wurde mit %s %d kompiliert." -#: access/transam/xlog.c:4514 +#: access/transam/xlog.c:4510 #, c-format msgid "The database cluster appears to use a different floating-point number format than the server executable." msgstr "Der Datenbank-Cluster verwendet anscheinend ein anderes Fließkommazahlenformat als das Serverprogramm." -#: access/transam/xlog.c:4525 access/transam/xlog.c:4535 -#: access/transam/xlog.c:4545 access/transam/xlog.c:4555 -#: access/transam/xlog.c:4565 access/transam/xlog.c:4575 -#: access/transam/xlog.c:4585 access/transam/xlog.c:4595 +#: access/transam/xlog.c:4521 access/transam/xlog.c:4531 +#: access/transam/xlog.c:4541 access/transam/xlog.c:4551 +#: access/transam/xlog.c:4561 access/transam/xlog.c:4571 +#: access/transam/xlog.c:4581 access/transam/xlog.c:4591 #, c-format msgid "It looks like you need to recompile or initdb." msgstr "Es sieht so aus, dass Sie neu kompilieren oder initdb ausführen müssen." -#: access/transam/xlog.c:4603 +#: access/transam/xlog.c:4599 #, c-format msgid "invalid WAL segment size in control file (%d byte)" msgid_plural "invalid WAL segment size in control file (%d bytes)" @@ -5621,21 +5644,21 @@ msgstr[0] "ungültige WAL-Segmentgröße in Kontrolldatei (%d Byte)" msgstr[1] "ungültige WAL-Segmentgröße in Kontrolldatei (%d Bytes)" #. translator: both %s are GUC names -#: access/transam/xlog.c:4617 access/transam/xlog.c:4623 +#: access/transam/xlog.c:4613 access/transam/xlog.c:4619 #, c-format msgid "\"%s\" must be at least twice \"%s\"" msgstr "»%s« muss mindestens zweimal so groß wie »%s« sein" -#: access/transam/xlog.c:5091 catalog/namespace.c:4768 +#: access/transam/xlog.c:5092 catalog/namespace.c:4768 #: commands/tablespace.c:1224 commands/user.c:2544 commands/variable.c:72 -#: replication/slot.c:2980 tcop/postgres.c:3707 utils/error/elog.c:2389 +#: replication/slot.c:2976 tcop/postgres.c:3708 utils/error/elog.c:2389 #: utils/error/elog.c:2693 #, c-format msgid "List syntax is invalid." msgstr "Die Listensyntax ist ungültig." -#: access/transam/xlog.c:5137 commands/user.c:2560 commands/variable.c:173 -#: tcop/postgres.c:3723 utils/error/elog.c:2719 +#: access/transam/xlog.c:5138 commands/user.c:2560 commands/variable.c:173 +#: tcop/postgres.c:3724 utils/error/elog.c:2719 #, c-format msgid "Unrecognized key word: \"%s\"." msgstr "Unbekanntes Schlüsselwort: »%s«." @@ -5745,178 +5768,178 @@ msgstr "gewählte neue Zeitleisten-ID: %u" msgid "archive recovery complete" msgstr "Wiederherstellung aus Archiv abgeschlossen" -#: access/transam/xlog.c:6613 +#: access/transam/xlog.c:6616 #, c-format msgid "enabling data checksums was interrupted" msgstr "" -#: access/transam/xlog.c:6614 +#: access/transam/xlog.c:6617 #, c-format -msgid "Data checksum processing must be manually restarted for checksums to be enabled" +msgid "Data checksum processing must be manually restarted for checksums to be enabled." msgstr "" -#: access/transam/xlog.c:7111 +#: access/transam/xlog.c:7117 #, c-format msgid "shutting down" msgstr "fahre herunter" #. translator: the placeholder shows checkpoint options -#: access/transam/xlog.c:7172 +#: access/transam/xlog.c:7178 #, fuzzy, c-format #| msgid "restartpoint starting:%s%s%s%s%s%s%s%s" msgid "restartpoint starting:%s" msgstr "Restart-Punkt beginnt:%s%s%s%s%s%s%s%s" #. translator: the placeholder shows checkpoint options -#: access/transam/xlog.c:7177 +#: access/transam/xlog.c:7183 #, fuzzy, c-format #| msgid "checkpoint starting:%s%s%s%s%s%s%s%s" msgid "checkpoint starting:%s" msgstr "Checkpoint beginnt:%s%s%s%s%s%s%s%s" -#: access/transam/xlog.c:7235 +#: access/transam/xlog.c:7241 #, fuzzy, c-format #| msgid "restartpoint complete: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X" msgid "restartpoint complete:%s: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB; lsn=%X/%08X, redo lsn=%X/%08X" msgstr "Restart-Punkt komplett: %d Puffer geschrieben (%.1f%%), %d SLRU-Puffer geschrieben; %d WAL-Datei(en) hinzugefügt, %d entfernt, %d wiederverwendet; Schreiben=%ld,%03d s, Sync=%ld,%03d s, gesamt=%ld,%03d s; sync. Dateien=%d, längste=%ld,%03d s, Durchschnitt=%ld.%03d s; Entfernung=%d kB, Schätzung=%d kB; LSN=%X/%X, Redo-LSN=%X/%X" -#: access/transam/xlog.c:7260 +#: access/transam/xlog.c:7266 #, fuzzy, c-format #| msgid "checkpoint complete: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X" msgid "checkpoint complete:%s: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB; lsn=%X/%08X, redo lsn=%X/%08X" msgstr "Checkpoint komplett: %d Puffer geschrieben (%.1f%%), %d SLRU-Puffer geschrieben; %d WAL-Datei(en) hinzugefügt, %d entfernt, %d wiederverwendet; Schreiben=%ld,%03d s, Sync=%ld,%03d s, gesamt=%ld,%03d s; sync. Dateien=%d, längste=%ld,%03d s, Durchschnitt=%ld.%03d s; Entfernung=%d kB, Schätzung=%d kB; LSN=%X/%X, Redo-LSN=%X/%X" -#: access/transam/xlog.c:7774 +#: access/transam/xlog.c:7778 #, c-format msgid "concurrent write-ahead log activity while database system is shutting down" msgstr "gleichzeitige Write-Ahead-Log-Aktivität während das Datenbanksystem herunterfährt" -#: access/transam/xlog.c:8373 +#: access/transam/xlog.c:8374 #, fuzzy, c-format #| msgid "recovery restart point at %X/%X" msgid "recovery restart point at %X/%08X" msgstr "Recovery-Restart-Punkt bei %X/%X" -#: access/transam/xlog.c:8375 +#: access/transam/xlog.c:8376 #, c-format msgid "Last completed transaction was at log time %s." msgstr "Die letzte vollständige Transaktion war bei Logzeit %s." -#: access/transam/xlog.c:8639 +#: access/transam/xlog.c:8640 #, fuzzy, c-format #| msgid "restore point \"%s\" created at %X/%X" msgid "restore point \"%s\" created at %X/%08X" msgstr "Restore-Punkt »%s« erzeugt bei %X/%X" -#: access/transam/xlog.c:8893 +#: access/transam/xlog.c:8889 #, c-format msgid "online backup was canceled, recovery cannot continue" msgstr "Online-Sicherung wurde storniert, Wiederherstellung kann nicht fortgesetzt werden" -#: access/transam/xlog.c:8947 +#: access/transam/xlog.c:8945 #, c-format msgid "unexpected timeline ID %u (should be %u) in shutdown checkpoint record" msgstr "unerwartete Zeitleisten-ID %u (sollte %u sein) im Shutdown-Checkpoint-Datensatz" -#: access/transam/xlog.c:9012 +#: access/transam/xlog.c:9006 #, c-format msgid "unexpected timeline ID %u (should be %u) in online checkpoint record" msgstr "unerwartete Zeitleisten-ID %u (sollte %u sein) im Online-Checkpoint-Datensatz" -#: access/transam/xlog.c:9061 +#: access/transam/xlog.c:9043 #, c-format msgid "unexpected timeline ID %u (should be %u) in end-of-recovery record" msgstr "unerwartete Zeitleisten-ID %u (sollte %u sein) im End-of-Recovery-Datensatz" -#: access/transam/xlog.c:9405 +#: access/transam/xlog.c:9393 #, c-format msgid "could not fsync write-through file \"%s\": %m" msgstr "konnte Write-Through-Logdatei »%s« nicht fsyncen: %m" -#: access/transam/xlog.c:9410 +#: access/transam/xlog.c:9398 #, c-format msgid "could not fdatasync file \"%s\": %m" msgstr "konnte Datei »%s« nicht fdatasyncen: %m" -#: access/transam/xlog.c:9486 access/transam/xlog.c:9816 +#: access/transam/xlog.c:9474 access/transam/xlog.c:9804 #, c-format msgid "WAL level not sufficient for making an online backup" msgstr "WAL-Level nicht ausreichend, um Online-Sicherung durchzuführen" -#: access/transam/xlog.c:9487 access/transam/xlog.c:9817 -#: access/transam/xlogfuncs.c:279 commands/subscriptioncmds.c:3043 +#: access/transam/xlog.c:9475 access/transam/xlog.c:9805 +#: access/transam/xlogfuncs.c:279 commands/subscriptioncmds.c:3163 #, c-format msgid "\"wal_level\" must be set to \"replica\" or \"logical\" at server start." msgstr "»wal_level« muss beim Serverstart auf »replica« oder »logical« gesetzt werden." -#: access/transam/xlog.c:9492 +#: access/transam/xlog.c:9480 #, c-format msgid "backup label too long (max %d bytes)" msgstr "Backup-Label zu lang (maximal %d Bytes)" -#: access/transam/xlog.c:9607 +#: access/transam/xlog.c:9595 #, c-format msgid "WAL generated with \"full_page_writes=off\" was replayed since last restartpoint" msgstr "mit »full_page_writes=off« erzeugtes WAL wurde seit dem letzten Restart-Punkt zurückgespielt" -#: access/transam/xlog.c:9609 access/transam/xlog.c:9905 +#: access/transam/xlog.c:9597 access/transam/xlog.c:9893 #, c-format msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable \"full_page_writes\" and run CHECKPOINT on the primary, and then try an online backup again." msgstr "Das bedeutet, dass die aktuelle Datensicherung auf dem Standby-Server verfälscht ist und nicht verwendet werden sollte. Schalten Sie auf dem Primärserver »full_page_writes« ein, führen Sie dort CHECKPOINT aus und versuchen Sie dann die Online-Sicherung erneut." -#: access/transam/xlog.c:9689 backup/basebackup.c:1421 +#: access/transam/xlog.c:9677 backup/basebackup.c:1419 #: catalog/pg_tablespace.c:80 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" -#: access/transam/xlog.c:9696 backup/basebackup.c:1426 +#: access/transam/xlog.c:9684 backup/basebackup.c:1424 #: catalog/pg_tablespace.c:85 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "Ziel für symbolische Verknüpfung »%s« ist zu lang" -#: access/transam/xlog.c:9855 backup/basebackup.c:1285 +#: access/transam/xlog.c:9843 backup/basebackup.c:1283 #, c-format msgid "the standby was promoted during online backup" msgstr "der Standby-Server wurde während der Online-Sicherung zum Primärserver befördert" -#: access/transam/xlog.c:9856 backup/basebackup.c:1286 +#: access/transam/xlog.c:9844 backup/basebackup.c:1284 #, c-format msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." msgstr "Das bedeutet, dass die aktuelle Online-Sicherung verfälscht ist und nicht verwendet werden sollte. Versuchen Sie, eine neue Online-Sicherung durchzuführen." -#: access/transam/xlog.c:9903 +#: access/transam/xlog.c:9891 #, c-format msgid "WAL generated with \"full_page_writes=off\" was replayed during online backup" msgstr "mit »full_page_writes=off« erzeugtes WAL wurde während der Online-Sicherung zurückgespielt" -#: access/transam/xlog.c:10019 +#: access/transam/xlog.c:10007 #, c-format msgid "base backup done, waiting for required WAL segments to be archived" msgstr "Basissicherung beendet, warte bis die benötigten WAL-Segmente archiviert sind" -#: access/transam/xlog.c:10033 +#: access/transam/xlog.c:10021 #, c-format msgid "still waiting for all required WAL segments to be archived (%d seconds elapsed)" msgstr "warte immer noch, bis alle benötigten WAL-Segmente archiviert sind (%d Sekunden abgelaufen)" -#: access/transam/xlog.c:10035 +#: access/transam/xlog.c:10023 #, c-format msgid "Check that your \"archive_command\" is executing properly. You can safely cancel this backup, but the database backup will not be usable without all the WAL segments." msgstr "Prüfen Sie, ob das »archive_command« korrekt ausgeführt wird. Dieser Sicherungsvorgang kann gefahrlos abgebrochen werden, aber die Datenbanksicherung wird ohne die fehlenden WAL-Segmente nicht benutzbar sein." -#: access/transam/xlog.c:10042 +#: access/transam/xlog.c:10030 #, c-format msgid "all required WAL segments have been archived" msgstr "alle benötigten WAL-Segmente wurden archiviert" -#: access/transam/xlog.c:10046 +#: access/transam/xlog.c:10034 #, c-format msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" msgstr "WAL-Archivierung ist nicht eingeschaltet; Sie müssen dafür sorgen, dass alle benötigten WAL-Segmente auf andere Art kopiert werden, um die Sicherung abzuschließen" -#: access/transam/xlog.c:10085 +#: access/transam/xlog.c:10073 #, c-format msgid "aborting backup due to backend exiting before pg_backup_stop was called" msgstr "Backup wird abgebrochen, weil Backend-Prozess beendete, bevor pg_backup_stop aufgerufen wurde" @@ -5959,7 +5982,7 @@ msgstr "konnte Archivstatusdatei »%s« nicht erstellen: %m" msgid "could not write archive status file \"%s\": %m" msgstr "konnte Archivstatusdatei »%s« nicht schreiben: %m" -#: access/transam/xlogfuncs.c:100 backup/basebackup.c:1001 +#: access/transam/xlogfuncs.c:100 backup/basebackup.c:999 #, c-format msgid "a backup is already in progress in this session" msgstr "ein Backup läuft bereits in dieser Sitzung" @@ -6043,7 +6066,7 @@ msgstr "»wait_seconds« darf nicht negativ oder null sein" msgid "failed to send signal to postmaster: %m" msgstr "konnte Signal nicht an Postmaster senden: %m" -#: access/transam/xlogfuncs.c:759 access/transam/xlogwait.c:450 +#: access/transam/xlogfuncs.c:759 access/transam/xlogwait.c:475 #: libpq/be-secure.c:245 libpq/be-secure.c:354 #, c-format msgid "terminating connection due to unexpected postmaster exit" @@ -6061,7 +6084,7 @@ msgid_plural "server did not promote within %d seconds" msgstr[0] "Befördern des Servers wurde nicht innerhalb von %d Sekunde abgeschlossen" msgstr[1] "Befördern des Servers wurde nicht innerhalb von %d Sekunden abgeschlossen" -#: access/transam/xlogprefetcher.c:1091 +#: access/transam/xlogprefetcher.c:1092 #, c-format msgid "\"recovery_prefetch\" is not supported on platforms that lack support for issuing read-ahead advice." msgstr "»recovery_prefetch« wird auf Plattformen ohne Unterstützung für Read-Ahead-Advice nicht unterstützt." @@ -6141,82 +6164,82 @@ msgstr "unerwartete Pageaddr %X/%08X in WAL-Segment %s, LSN %X/%08X, Offset %u" msgid "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%08X, offset %u" msgstr "Zeitleisten-ID %u außer der Reihe (nach %u) in WAL-Segment %s, LSN %X/%08X, Offset %u" -#: access/transam/xlogreader.c:1788 +#: access/transam/xlogreader.c:1790 #, c-format msgid "out-of-order block_id %u at %X/%08X" msgstr "block_id %u außer der Reihe bei %X/%08X" -#: access/transam/xlogreader.c:1812 +#: access/transam/xlogreader.c:1814 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%08X" msgstr "BKPBLOCK_HAS_DATA gesetzt, aber keine Daten enthalten bei %X/%08X" -#: access/transam/xlogreader.c:1819 +#: access/transam/xlogreader.c:1821 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %d at %X/%08X" msgstr "BKPBLOCK_HAS_DATA nicht gesetzt, aber Datenlänge ist %d bei %X/%08X" -#: access/transam/xlogreader.c:1855 +#: access/transam/xlogreader.c:1857 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %d length %d block image length %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLE gesetzt, aber Loch Offset %d Länge %d Block-Abbild-Länge %d bei %X/%08X" -#: access/transam/xlogreader.c:1871 +#: access/transam/xlogreader.c:1873 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %d length %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLE nicht gesetzt, aber Loch Offset %d Länge %d bei %X/%08X" -#: access/transam/xlogreader.c:1885 +#: access/transam/xlogreader.c:1887 #, c-format msgid "BKPIMAGE_COMPRESSED set, but block image length %d at %X/%08X" msgstr "BKPIMAGE_COMPRESSED gesetzt, aber Block-Abbild-Länge %d bei %X/%08X" -#: access/transam/xlogreader.c:1900 +#: access/transam/xlogreader.c:1902 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image length is %d at %X/%08X" msgstr "weder BKPIMAGE_HAS_HOLE noch BKPIMAGE_COMPRESSED gesetzt, aber Block-Abbild-Länge ist %d bei %X/%08X" -#: access/transam/xlogreader.c:1916 +#: access/transam/xlogreader.c:1918 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%08X" msgstr "BKPBLOCK_SAME_REL gesetzt, aber keine vorangehende Relation bei %X/%08X" -#: access/transam/xlogreader.c:1928 +#: access/transam/xlogreader.c:1930 #, c-format msgid "invalid block_id %u at %X/%08X" msgstr "ungültige block_id %u bei %X/%08X" -#: access/transam/xlogreader.c:1995 +#: access/transam/xlogreader.c:1997 #, c-format msgid "record with invalid length at %X/%08X" msgstr "Datensatz mit ungültiger Länge bei %X/%08X" -#: access/transam/xlogreader.c:2021 +#: access/transam/xlogreader.c:2023 #, c-format msgid "could not locate backup block with ID %d in WAL record" msgstr "konnte Backup-Block mit ID %d nicht im WAL-Eintrag finden" -#: access/transam/xlogreader.c:2105 +#: access/transam/xlogreader.c:2107 #, c-format msgid "could not restore image at %X/%08X with invalid block %d specified" msgstr "konnte Abbild bei %X/%08X mit ungültigem angegebenen Block %d nicht wiederherstellen" -#: access/transam/xlogreader.c:2112 +#: access/transam/xlogreader.c:2114 #, c-format msgid "could not restore image at %X/%08X with invalid state, block %d" msgstr "konnte Abbild mit ungültigem Zustand bei %X/%08X nicht wiederherstellen, Block %d" -#: access/transam/xlogreader.c:2139 access/transam/xlogreader.c:2156 +#: access/transam/xlogreader.c:2141 access/transam/xlogreader.c:2158 #, c-format msgid "could not restore image at %X/%08X compressed with %s not supported by build, block %d" msgstr "konnte Abbild bei %X/%08X nicht wiederherstellen, komprimiert mit %s, nicht unterstützt von dieser Installation, Block %d" -#: access/transam/xlogreader.c:2165 +#: access/transam/xlogreader.c:2167 #, c-format msgid "could not restore image at %X/%08X compressed with unknown method, block %d" msgstr "konnte Abbild bei %X/%08X nicht wiederherstellen, komprimiert mit unbekannter Methode, Block %d" -#: access/transam/xlogreader.c:2173 +#: access/transam/xlogreader.c:2175 #, c-format msgid "could not decompress image at %X/%08X, block %d" msgstr "konnte Abbild bei %X/%08X nicht dekomprimieren, Block %d" @@ -6440,327 +6463,326 @@ msgstr "Redo beginnt bei %X/%X" msgid "redo in progress, elapsed time: %ld.%02d s, current LSN: %X/%08X" msgstr "Redo im Gang, abgelaufene Zeit: %ld.%02d s, aktuelle LSN: %X/%X" -#: access/transam/xlogrecovery.c:1813 +#: access/transam/xlogrecovery.c:1816 #, c-format msgid "requested recovery stop point is before consistent recovery point" msgstr "angeforderter Recovery-Endpunkt ist vor konsistentem Recovery-Punkt" -#: access/transam/xlogrecovery.c:1846 +#: access/transam/xlogrecovery.c:1849 #, fuzzy, c-format #| msgid "redo done at %X/%X system usage: %s" msgid "redo done at %X/%08X system usage: %s" msgstr "Redo fertig bei %X/%X Systembenutzung: %s" -#: access/transam/xlogrecovery.c:1852 +#: access/transam/xlogrecovery.c:1855 #, c-format msgid "last completed transaction was at log time %s" msgstr "letzte vollständige Transaktion war bei Logzeit %s" -#: access/transam/xlogrecovery.c:1861 +#: access/transam/xlogrecovery.c:1864 #, c-format msgid "redo is not required" msgstr "Redo nicht nötig" -#: access/transam/xlogrecovery.c:1873 +#: access/transam/xlogrecovery.c:1876 #, c-format msgid "recovery ended before configured recovery target was reached" msgstr "Wiederherstellung endete bevor das konfigurierte Wiederherstellungsziel erreicht wurde" -#: access/transam/xlogrecovery.c:2067 +#: access/transam/xlogrecovery.c:2070 #, fuzzy, c-format #| msgid "successfully skipped missing contrecord at %X/%X, overwritten at %s" msgid "successfully skipped missing contrecord at %X/%08X, overwritten at %s" msgstr "fehlender Contrecord bei %X/%X erfolgreich übersprungen, überschrieben am %s" -#: access/transam/xlogrecovery.c:2134 +#: access/transam/xlogrecovery.c:2137 #, c-format msgid "unexpected directory entry \"%s\" found in %s" msgstr "unerwarteter Verzeichniseintrag »%s« in %s gefunden" -#: access/transam/xlogrecovery.c:2136 +#: access/transam/xlogrecovery.c:2139 #, c-format msgid "All directory entries in %s/ should be symbolic links." msgstr "Alle Verzeichniseinträge in %s/ sollten symbolische Verknüpfungen sein." -#: access/transam/xlogrecovery.c:2138 +#: access/transam/xlogrecovery.c:2141 #, c-format msgid "Remove those directories, or set \"allow_in_place_tablespaces\" to ON transiently to let recovery complete." msgstr "Entfernen Sie diese Verzeichnisse oder setzen Sie »allow_in_place_tablespaces« vorrübergehend auf ON, damit die Wiederherstellung abschließen kann." -#: access/transam/xlogrecovery.c:2190 +#: access/transam/xlogrecovery.c:2193 #, fuzzy, c-format #| msgid "completed backup recovery with redo LSN %X/%X and end LSN %X/%X" msgid "completed backup recovery with redo LSN %X/%08X and end LSN %X/%08X" msgstr "Wiederherstellung aus Backup abgeschlossen mit Redo-LSN %X/%X und End-LSN %X/%X" -#: access/transam/xlogrecovery.c:2221 +#: access/transam/xlogrecovery.c:2224 #, fuzzy, c-format #| msgid "consistent recovery state reached at %X/%X" msgid "consistent recovery state reached at %X/%08X" msgstr "konsistenter Wiederherstellungszustand erreicht bei %X/%X" #. translator: %s is a WAL record description -#: access/transam/xlogrecovery.c:2259 +#: access/transam/xlogrecovery.c:2262 #, fuzzy, c-format #| msgid "WAL redo at %X/%X for %s" msgid "WAL redo at %X/%08X for %s" msgstr "WAL-Redo bei %X/%X für %s" -#: access/transam/xlogrecovery.c:2357 +#: access/transam/xlogrecovery.c:2360 #, c-format msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" msgstr "unerwartete vorherige Zeitleisten-ID %u (aktuelle Zeitleisten-ID %u) im Checkpoint-Datensatz" -#: access/transam/xlogrecovery.c:2366 +#: access/transam/xlogrecovery.c:2369 #, c-format msgid "unexpected timeline ID %u (after %u) in checkpoint record" msgstr "unerwartete Zeitleisten-ID %u (nach %u) im Checkpoint-Datensatz" -#: access/transam/xlogrecovery.c:2382 +#: access/transam/xlogrecovery.c:2385 #, fuzzy, c-format #| msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%08X on timeline %u" msgstr "unerwartete Zeitleisten-ID %u in Checkpoint-Datensatz, bevor der minimale Wiederherstellungspunkt %X/%X auf Zeitleiste %u erreicht wurde" -#: access/transam/xlogrecovery.c:2566 access/transam/xlogrecovery.c:2842 +#: access/transam/xlogrecovery.c:2569 access/transam/xlogrecovery.c:2845 #, c-format msgid "recovery stopping after reaching consistency" msgstr "Wiederherstellung beendet nachdem Konsistenz erreicht wurde" -#: access/transam/xlogrecovery.c:2587 +#: access/transam/xlogrecovery.c:2590 #, fuzzy, c-format #| msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" msgid "recovery stopping before WAL location (LSN) \"%X/%08X\"" msgstr "Wiederherstellung beendet vor WAL-Position (LSN) »%X/%X«" -#: access/transam/xlogrecovery.c:2677 +#: access/transam/xlogrecovery.c:2680 #, c-format msgid "recovery stopping before commit of transaction %u, time %s" msgstr "Wiederherstellung beendet vor Commit der Transaktion %u, Zeit %s" -#: access/transam/xlogrecovery.c:2684 +#: access/transam/xlogrecovery.c:2687 #, c-format msgid "recovery stopping before abort of transaction %u, time %s" msgstr "Wiederherstellung beendet vor Abbruch der Transaktion %u, Zeit %s" -#: access/transam/xlogrecovery.c:2737 +#: access/transam/xlogrecovery.c:2740 #, c-format msgid "recovery stopping at restore point \"%s\", time %s" msgstr "Wiederherstellung beendet bei Restore-Punkt »%s«, Zeit %s" -#: access/transam/xlogrecovery.c:2755 +#: access/transam/xlogrecovery.c:2758 #, fuzzy, c-format #| msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" msgid "recovery stopping after WAL location (LSN) \"%X/%08X\"" msgstr "Wiederherstellung beendet nach WAL-Position (LSN) »%X/%X«" -#: access/transam/xlogrecovery.c:2822 +#: access/transam/xlogrecovery.c:2825 #, c-format msgid "recovery stopping after commit of transaction %u, time %s" msgstr "Wiederherstellung beendet nach Commit der Transaktion %u, Zeit %s" -#: access/transam/xlogrecovery.c:2830 +#: access/transam/xlogrecovery.c:2833 #, c-format msgid "recovery stopping after abort of transaction %u, time %s" msgstr "Wiederherstellung beendet nach Abbruch der Transaktion %u, Zeit %s" -#: access/transam/xlogrecovery.c:2911 +#: access/transam/xlogrecovery.c:2914 #, c-format msgid "pausing at the end of recovery" msgstr "pausiere am Ende der Wiederherstellung" -#: access/transam/xlogrecovery.c:2912 +#: access/transam/xlogrecovery.c:2915 #, c-format msgid "Execute pg_wal_replay_resume() to promote." msgstr "Führen Sie pg_wal_replay_resume() aus, um den Server zum Primärserver zu befördern." -#: access/transam/xlogrecovery.c:2915 access/transam/xlogrecovery.c:4684 +#: access/transam/xlogrecovery.c:2918 access/transam/xlogrecovery.c:4689 #, c-format msgid "recovery has paused" msgstr "Wiederherstellung wurde pausiert" -#: access/transam/xlogrecovery.c:2916 +#: access/transam/xlogrecovery.c:2919 #, c-format msgid "Execute pg_wal_replay_resume() to continue." msgstr "Führen Sie pg_wal_replay_resume() aus um fortzusetzen." -#: access/transam/xlogrecovery.c:3181 +#: access/transam/xlogrecovery.c:3184 #, fuzzy, c-format #| msgid "unexpected timeline ID %u in WAL segment %s, LSN %X/%X, offset %u" msgid "unexpected timeline ID %u in WAL segment %s, LSN %X/%08X, offset %u" msgstr "unerwartete Zeitleisten-ID %u in WAL-Segment %s, LSN %X/%X, Offset %u" -#: access/transam/xlogrecovery.c:3399 +#: access/transam/xlogrecovery.c:3404 #, fuzzy, c-format #| msgid "could not read from WAL segment %s, LSN %X/%X, offset %u: %m" msgid "could not read from WAL segment %s, LSN %X/%08X, offset %u: %m" msgstr "konnte nicht aus WAL-Segment %s, LSN %X/%X, Position %u lesen: %m" -#: access/transam/xlogrecovery.c:3406 +#: access/transam/xlogrecovery.c:3411 #, fuzzy, c-format #| msgid "could not read from WAL segment %s, LSN %X/%X, offset %u: read %d of %zu" msgid "could not read from WAL segment %s, LSN %X/%08X, offset %u: read %d of %zu" msgstr "konnte nicht aus WAL-Segment %s, LSN %X/%X, Position %u lesen: %d von %zu gelesen" -#: access/transam/xlogrecovery.c:4068 +#: access/transam/xlogrecovery.c:4073 #, c-format msgid "invalid checkpoint location" msgstr "ungültige Checkpoint-Position" -#: access/transam/xlogrecovery.c:4078 +#: access/transam/xlogrecovery.c:4083 #, c-format msgid "invalid checkpoint record" msgstr "ungültiger Checkpoint-Datensatz" -#: access/transam/xlogrecovery.c:4084 +#: access/transam/xlogrecovery.c:4089 #, c-format msgid "invalid resource manager ID in checkpoint record" msgstr "ungültige Resource-Manager-ID im Checkpoint-Datensatz" -#: access/transam/xlogrecovery.c:4092 +#: access/transam/xlogrecovery.c:4097 #, c-format msgid "invalid xl_info in checkpoint record" msgstr "ungültige xl_info im Checkpoint-Datensatz" -#: access/transam/xlogrecovery.c:4098 +#: access/transam/xlogrecovery.c:4103 #, c-format msgid "invalid length of checkpoint record" msgstr "ungültige Länge des Checkpoint-Datensatzes" -#: access/transam/xlogrecovery.c:4152 +#: access/transam/xlogrecovery.c:4157 #, c-format msgid "new timeline %u is not a child of database system timeline %u" msgstr "neue Zeitleiste %u ist kein Kind der Datenbanksystemzeitleiste %u" -#: access/transam/xlogrecovery.c:4166 +#: access/transam/xlogrecovery.c:4171 #, fuzzy, c-format #| msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%08X" msgstr "neue Zeitleiste %u zweigte von der aktuellen Datenbanksystemzeitleiste %u vor dem aktuellen Wiederherstellungspunkt %X/%X ab" -#: access/transam/xlogrecovery.c:4185 +#: access/transam/xlogrecovery.c:4190 #, c-format msgid "new target timeline is %u" msgstr "neue Zielzeitleiste ist %u" -#: access/transam/xlogrecovery.c:4386 +#: access/transam/xlogrecovery.c:4391 #, c-format msgid "WAL receiver process shutdown requested" msgstr "Herunterfahren des WAL-Receiver-Prozesses verlangt" -#: access/transam/xlogrecovery.c:4446 +#: access/transam/xlogrecovery.c:4451 #, c-format msgid "received promote request" msgstr "Anforderung zum Befördern empfangen" -#: access/transam/xlogrecovery.c:4675 +#: access/transam/xlogrecovery.c:4680 #, c-format msgid "hot standby is not possible because of insufficient parameter settings" msgstr "Hot Standby ist nicht möglich wegen unzureichender Parametereinstellungen" -#: access/transam/xlogrecovery.c:4676 access/transam/xlogrecovery.c:4703 -#: access/transam/xlogrecovery.c:4733 +#: access/transam/xlogrecovery.c:4681 access/transam/xlogrecovery.c:4708 +#: access/transam/xlogrecovery.c:4738 #, c-format msgid "%s = %d is a lower setting than on the primary server, where its value was %d." msgstr "%s = %d ist eine niedrigere Einstellung als auf dem Primärserver, wo der Wert %d war." -#: access/transam/xlogrecovery.c:4685 +#: access/transam/xlogrecovery.c:4690 #, c-format msgid "If recovery is unpaused, the server will shut down." msgstr "Wenn die Wiederherstellungspause beendet wird, wird der Server herunterfahren." -#: access/transam/xlogrecovery.c:4686 +#: access/transam/xlogrecovery.c:4691 #, c-format msgid "You can then restart the server after making the necessary configuration changes." msgstr "Sie können den Server dann neu starten, nachdem die nötigen Konfigurationsänderungen getätigt worden sind." -#: access/transam/xlogrecovery.c:4697 +#: access/transam/xlogrecovery.c:4702 #, c-format msgid "promotion is not possible because of insufficient parameter settings" msgstr "Beförderung ist nicht möglich wegen unzureichender Parametereinstellungen" -#: access/transam/xlogrecovery.c:4707 +#: access/transam/xlogrecovery.c:4712 #, c-format msgid "Restart the server after making the necessary configuration changes." msgstr "Starten Sie den Server neu, nachdem die nötigen Konfigurationsänderungen getätigt worden sind." -#: access/transam/xlogrecovery.c:4731 +#: access/transam/xlogrecovery.c:4736 #, c-format msgid "recovery aborted because of insufficient parameter settings" msgstr "Wiederherstellung abgebrochen wegen unzureichender Parametereinstellungen" -#: access/transam/xlogrecovery.c:4737 +#: access/transam/xlogrecovery.c:4742 #, c-format msgid "You can restart the server after making the necessary configuration changes." msgstr "Sie können den Server neu starten, nachdem die nötigen Konfigurationsänderungen getätigt worden sind." -#: access/transam/xlogrecovery.c:4757 access/transam/xlogrecovery.c:4759 +#: access/transam/xlogrecovery.c:4762 access/transam/xlogrecovery.c:4764 #: catalog/dependency.c:1219 catalog/dependency.c:1226 -#: catalog/dependency.c:1237 commands/repack_worker.c:418 -#: commands/tablecmds.c:1580 commands/tablecmds.c:17023 -#: commands/tablespace.c:468 commands/user.c:1309 commands/view.c:441 -#: commands/wait.c:108 executor/execExprInterp.c:5215 -#: executor/execExprInterp.c:5223 libpq/auth-oauth.c:700 libpq/auth.c:314 -#: replication/logical/applyparallelworker.c:1060 replication/slot.c:1853 -#: replication/slot.c:2995 replication/slot.c:2997 replication/syncrep.c:1087 +#: catalog/dependency.c:1237 commands/tablecmds.c:1588 +#: commands/tablecmds.c:17401 commands/tablespace.c:468 commands/user.c:1309 +#: commands/view.c:441 commands/wait.c:108 executor/execExprInterp.c:5285 +#: executor/execExprInterp.c:5293 libpq/auth-oauth.c:700 libpq/auth.c:316 +#: replication/logical/applyparallelworker.c:1060 replication/slot.c:1849 +#: replication/slot.c:2991 replication/slot.c:2993 replication/syncrep.c:1088 #: storage/aio/method_io_uring.c:399 storage/lmgr/deadlock.c:1137 -#: storage/lmgr/proc.c:1533 utils/init/postinit.c:1530 -#: utils/init/postinit.c:1531 utils/misc/guc.c:3063 utils/misc/guc.c:3104 +#: storage/lmgr/proc.c:1566 utils/init/postinit.c:1557 +#: utils/init/postinit.c:1558 utils/misc/guc.c:3063 utils/misc/guc.c:3104 #: utils/misc/guc.c:3188 utils/misc/guc.c:6703 utils/misc/guc.c:6737 #: utils/misc/guc.c:6771 utils/misc/guc.c:6814 utils/misc/guc.c:6856 #, c-format msgid "%s" msgstr "%s" -#: access/transam/xlogrecovery.c:4789 +#: access/transam/xlogrecovery.c:4794 #, c-format msgid "multiple recovery targets specified" msgstr "mehrere Wiederherstellungsziele angegeben" -#: access/transam/xlogrecovery.c:4790 +#: access/transam/xlogrecovery.c:4795 #, c-format msgid "At most one of \"recovery_target\", \"recovery_target_lsn\", \"recovery_target_name\", \"recovery_target_time\", \"recovery_target_xid\" may be set." msgstr "Höchstens eins aus »recovery_target«, »recovery_target_lsn«, »recovery_target_name«, »recovery_target_time«, »recovery_target_xid« darf gesetzt sein." -#: access/transam/xlogrecovery.c:4801 +#: access/transam/xlogrecovery.c:4806 #, c-format msgid "The only allowed value is \"immediate\"." msgstr "Der einzige erlaubte Wert ist »immediate«." -#: access/transam/xlogrecovery.c:4955 +#: access/transam/xlogrecovery.c:4960 #, c-format msgid "Timestamp out of range: \"%s\"." msgstr "Timestamp ist außerhalb des gültigen Bereichs: »%s«." -#: access/transam/xlogrecovery.c:5004 access/transam/xlogrecovery.c:5069 +#: access/transam/xlogrecovery.c:5009 access/transam/xlogrecovery.c:5074 #, fuzzy, c-format #| msgid "\"%s\" is not a number" msgid "\"%s\" is not a valid number." msgstr "»%s« ist keine Zahl" -#: access/transam/xlogrecovery.c:5011 +#: access/transam/xlogrecovery.c:5016 #, fuzzy, c-format #| msgid "\"%s\" must be 0 or between %d kB and %d kB." msgid "\"%s\" must be between %u and %u." msgstr "»%s« muss 0 sein oder zwischen %d kB und %d kB liegen." -#: access/transam/xlogrecovery.c:5076 +#: access/transam/xlogrecovery.c:5081 #, fuzzy, c-format #| msgid "transaction ID (-x) must be greater than or equal to %u" msgid "\"%s\" without epoch must be greater than or equal to %u." msgstr "Transaktions-ID (-x) muss größer oder gleich %u sein" -#: access/transam/xlogutils.c:1023 +#: access/transam/xlogutils.c:1059 #, c-format msgid "could not read from WAL segment %s, offset %d: %m" msgstr "konnte nicht aus WAL-Segment %s, Position %d lesen: %m" -#: access/transam/xlogutils.c:1030 +#: access/transam/xlogutils.c:1066 #, c-format msgid "could not read from WAL segment %s, offset %d: read %d of %d" msgstr "konnte nicht aus WAL-Segment %s, Position %d lesen: %d von %d gelesen" -#: access/transam/xlogwait.c:451 +#: access/transam/xlogwait.c:476 #, fuzzy, c-format #| msgid "while waiting on promotion" msgid "while waiting for LSN" @@ -6844,119 +6866,119 @@ msgstr[1] "%lld Prüfsummenfehler insgesamt" msgid "checksum verification failure during base backup" msgstr "Prüfsummenüberprüfung bei der Basissicherung fehlgeschlagen" -#: backup/basebackup.c:737 backup/basebackup.c:746 backup/basebackup.c:757 -#: backup/basebackup.c:774 backup/basebackup.c:783 backup/basebackup.c:792 -#: backup/basebackup.c:807 backup/basebackup.c:824 backup/basebackup.c:833 -#: backup/basebackup.c:845 backup/basebackup.c:869 backup/basebackup.c:883 -#: backup/basebackup.c:894 backup/basebackup.c:905 backup/basebackup.c:918 +#: backup/basebackup.c:735 backup/basebackup.c:744 backup/basebackup.c:755 +#: backup/basebackup.c:772 backup/basebackup.c:781 backup/basebackup.c:790 +#: backup/basebackup.c:805 backup/basebackup.c:822 backup/basebackup.c:831 +#: backup/basebackup.c:843 backup/basebackup.c:867 backup/basebackup.c:881 +#: backup/basebackup.c:892 backup/basebackup.c:903 backup/basebackup.c:916 #, c-format msgid "duplicate option \"%s\"" msgstr "doppelte Option »%s«" -#: backup/basebackup.c:765 +#: backup/basebackup.c:763 #, c-format msgid "unrecognized checkpoint type: \"%s\"" msgstr "unbekannter Checkpoint-Typ: »%s«" -#: backup/basebackup.c:797 +#: backup/basebackup.c:795 #, c-format msgid "incremental backups cannot be taken unless WAL summarization is enabled" msgstr "inkrementelle Backups können nicht durchgeführt werden, wenn WAL-Zusammenfassung nicht eingeschaltet ist" -#: backup/basebackup.c:813 +#: backup/basebackup.c:811 #, fuzzy, c-format #| msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" msgid "% is outside the valid range for parameter \"%s\" (%d .. %d)" msgstr "%d ist außerhalb des gültigen Bereichs für Parameter »%s« (%d ... %d)" -#: backup/basebackup.c:858 +#: backup/basebackup.c:856 #, c-format msgid "unrecognized manifest option: \"%s\"" msgstr "unbekannte Manifestoption: »%s«" -#: backup/basebackup.c:909 +#: backup/basebackup.c:907 #, c-format msgid "unrecognized compression algorithm: \"%s\"" msgstr "unbekannter Komprimierungsalgorithmus: »%s«" -#: backup/basebackup.c:925 +#: backup/basebackup.c:923 #, c-format msgid "unrecognized base backup option: \"%s\"" msgstr "unbekannte Base-Backup-Option: »%s«" -#: backup/basebackup.c:936 +#: backup/basebackup.c:934 #, c-format msgid "manifest checksums require a backup manifest" msgstr "Manifest-Prüfsummen benötigen ein Backup-Manifest" -#: backup/basebackup.c:945 +#: backup/basebackup.c:943 #, c-format msgid "target detail cannot be used without target" msgstr "Zieldetail kann nicht ohne Ziel verwendet werden" -#: backup/basebackup.c:954 backup/basebackup_target.c:218 +#: backup/basebackup.c:952 backup/basebackup_target.c:218 #, c-format msgid "target \"%s\" does not accept a target detail" msgstr "Ziel »%s« akzeptiert kein Zieldetail" -#: backup/basebackup.c:965 +#: backup/basebackup.c:963 #, c-format msgid "compression detail cannot be specified unless compression is enabled" msgstr "Komprimierungsdetail kann nicht angegeben werden, wenn Komprimierung nicht eingeschaltet ist" -#: backup/basebackup.c:978 +#: backup/basebackup.c:976 #, c-format msgid "invalid compression specification: %s" msgstr "ungültige Komprimierungsangabe: %s" -#: backup/basebackup.c:1028 +#: backup/basebackup.c:1026 #, c-format msgid "must UPLOAD_MANIFEST before performing an incremental BASE_BACKUP" msgstr "UPLOAD_MANIFEST muss vor einem inkrementellen BASE_BACKUP ausgeführt werden" -#: backup/basebackup.c:1161 backup/basebackup.c:1362 +#: backup/basebackup.c:1159 backup/basebackup.c:1360 #, c-format msgid "could not stat file or directory \"%s\": %m" msgstr "konnte »stat« für Datei oder Verzeichnis »%s« nicht ausführen: %m" -#: backup/basebackup.c:1548 +#: backup/basebackup.c:1546 #, c-format msgid "skipping special file \"%s\"" msgstr "überspringe besondere Datei »%s«" -#: backup/basebackup.c:1756 +#: backup/basebackup.c:1754 #, c-format msgid "could not verify checksum in file \"%s\", block %u: read buffer size %d and page size %d differ" msgstr "konnte Prüfsumme in Datei »%s«, Block %u nicht überprüfen: gelesene Puffergröße %d und Seitengröße %d sind verschieden" -#: backup/basebackup.c:1818 +#: backup/basebackup.c:1816 #, c-format msgid "file \"%s\" has a total of %d checksum verification failure" msgid_plural "file \"%s\" has a total of %d checksum verification failures" msgstr[0] "Datei »%s« hat insgesamt %d Prüfsummenfehler" msgstr[1] "Datei »%s« hat insgesamt %d Prüfsummenfehler" -#: backup/basebackup.c:1936 +#: backup/basebackup.c:1934 #, c-format msgid "checksum verification failed in file \"%s\", block %u: calculated %X but expected %X" msgstr "Prüfsummenüberprüfung fehlgeschlagen in Datei »%s«, Block %u: berechnet %X, aber erwartet %X" -#: backup/basebackup.c:1943 +#: backup/basebackup.c:1941 #, c-format msgid "further checksum verification failures in file \"%s\" will not be reported" msgstr "weitere Prüfsummenfehler in Datei »%s« werden nicht berichtet werden" -#: backup/basebackup.c:2071 +#: backup/basebackup.c:2069 #, c-format msgid "file name too long for tar format: \"%s\"" msgstr "Dateiname zu lang für Tar-Format: »%s«" -#: backup/basebackup.c:2077 +#: backup/basebackup.c:2075 #, c-format msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" msgstr "Ziel der symbolischen Verknüpfung zu lang für Tar-Format: Dateiname »%s«, Ziel »%s«" -#: backup/basebackup.c:2151 +#: backup/basebackup.c:2149 #, c-format msgid "could not read file \"%s\": read %zd of %zu" msgstr "konnte Datei »%s« nicht lesen: %zd von %zu gelesen" @@ -7060,7 +7082,7 @@ msgstr "relativer Pfad nicht erlaubt für auf dem Server abgelegtes Backup" #: backup/basebackup_server.c:102 commands/dbcommands.c:481 #: commands/tablespace.c:159 commands/tablespace.c:175 -#: commands/tablespace.c:601 commands/tablespace.c:646 replication/slot.c:2492 +#: commands/tablespace.c:601 commands/tablespace.c:646 replication/slot.c:2488 #: storage/file/copydir.c:59 #, c-format msgid "could not create directory \"%s\": %m" @@ -7071,7 +7093,7 @@ msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" msgid "directory \"%s\" exists but is not empty" msgstr "Verzeichnis »%s« existiert aber ist nicht leer" -#: backup/basebackup_server.c:123 utils/init/postinit.c:1188 +#: backup/basebackup_server.c:123 utils/init/postinit.c:1211 #, c-format msgid "could not access directory \"%s\": %m" msgstr "konnte nicht auf Verzeichnis »%s« zugreifen: %m" @@ -7087,7 +7109,7 @@ msgstr "Prüfen Sie den freien Festplattenplatz." #: backup/basebackup_server.c:179 backup/basebackup_server.c:272 #, fuzzy, c-format #| msgid "could not write file \"%s\": wrote only %d of %d bytes at offset %u" -msgid "could not write file \"%s\": wrote only %d of %zu bytes at offset %u" +msgid "could not write file \"%s\": wrote only %d of %zu bytes at offset %lld" msgstr "konnte Datei »%s« nicht schreiben: es wurden nur %d von %d Bytes bei Offset %u geschrieben" #: backup/basebackup_target.c:146 @@ -7125,17 +7147,17 @@ msgstr "konnte Datei »%s« nicht schreiben: es wurden nur %d von %d Bytes bei O msgid "invalid timeline %" msgstr "ungültige Zeitleiste %" -#: bootstrap/bootstrap.c:280 postmaster/postmaster.c:631 tcop/postgres.c:3942 +#: bootstrap/bootstrap.c:280 postmaster/postmaster.c:631 tcop/postgres.c:3943 #, c-format msgid "--%s must be first argument" msgstr "--%s muss erstes Argument sein" -#: bootstrap/bootstrap.c:294 postmaster/postmaster.c:645 tcop/postgres.c:3956 +#: bootstrap/bootstrap.c:294 postmaster/postmaster.c:645 tcop/postgres.c:3957 #, c-format msgid "--%s requires a value" msgstr "--%s benötigt einen Wert" -#: bootstrap/bootstrap.c:299 postmaster/postmaster.c:650 tcop/postgres.c:3961 +#: bootstrap/bootstrap.c:299 postmaster/postmaster.c:650 tcop/postgres.c:3962 #, c-format msgid "-c %s requires a value" msgstr "-c %s benötigt einen Wert" @@ -7272,10 +7294,9 @@ msgid "invalid privilege type %s for parameter" msgstr "ungültiger Privilegtyp %s für Parameter" #: catalog/aclchk.c:528 catalog/aclchk.c:1027 -#, fuzzy, c-format -#| msgid "invalid privilege type %s for type" +#, c-format msgid "invalid privilege type %s for property graph" -msgstr "ungültiger Privilegtyp %s für Typ" +msgstr "ungültiger Privilegtyp %s für Property-Graph" #: catalog/aclchk.c:567 #, c-format @@ -7297,25 +7318,25 @@ msgstr "keine Berechtigung, um Vorgabeprivilegien zu ändern" msgid "cannot use IN SCHEMA clause when using %s" msgstr "Klausel IN SCHEMA kann nicht verwendet werden, wenn %s verwendet wird" -#: catalog/aclchk.c:1582 catalog/catalog.c:684 catalog/heap.c:2621 -#: catalog/heap.c:2943 catalog/objectaddress.c:1623 -#: catalog/pg_publication.c:682 commands/analyze.c:1061 commands/copy.c:1123 +#: catalog/aclchk.c:1582 catalog/catalog.c:684 catalog/heap.c:2641 +#: catalog/heap.c:2963 catalog/objectaddress.c:1629 +#: catalog/pg_publication.c:689 commands/analyze.c:1061 commands/copy.c:1123 #: commands/propgraphcmds.c:539 commands/sequence.c:1660 -#: commands/tablecmds.c:7876 commands/tablecmds.c:8054 -#: commands/tablecmds.c:8255 commands/tablecmds.c:8384 -#: commands/tablecmds.c:8538 commands/tablecmds.c:8632 -#: commands/tablecmds.c:8735 commands/tablecmds.c:8888 -#: commands/tablecmds.c:8918 commands/tablecmds.c:9073 -#: commands/tablecmds.c:9176 commands/tablecmds.c:9310 -#: commands/tablecmds.c:9423 commands/tablecmds.c:14679 -#: commands/tablecmds.c:14882 commands/tablecmds.c:15043 -#: commands/tablecmds.c:16271 commands/tablecmds.c:19030 commands/trigger.c:949 -#: parser/analyze.c:1351 parser/analyze.c:2984 parser/parse_relation.c:745 +#: commands/tablecmds.c:7859 commands/tablecmds.c:8037 +#: commands/tablecmds.c:8238 commands/tablecmds.c:8367 +#: commands/tablecmds.c:8521 commands/tablecmds.c:8615 +#: commands/tablecmds.c:8718 commands/tablecmds.c:8878 +#: commands/tablecmds.c:8908 commands/tablecmds.c:9063 +#: commands/tablecmds.c:9166 commands/tablecmds.c:9300 +#: commands/tablecmds.c:9413 commands/tablecmds.c:14889 +#: commands/tablecmds.c:15092 commands/tablecmds.c:15253 +#: commands/tablecmds.c:16649 commands/tablecmds.c:19408 commands/trigger.c:949 +#: parser/analyze.c:1354 parser/analyze.c:2981 parser/parse_relation.c:777 #: parser/parse_target.c:1075 parser/parse_type.c:144 -#: parser/parse_utilcmd.c:3953 parser/parse_utilcmd.c:3993 -#: parser/parse_utilcmd.c:4035 statistics/attribute_stats.c:201 -#: statistics/attribute_stats.c:621 utils/adt/acl.c:2966 -#: utils/adt/ruleutils.c:3216 +#: parser/parse_utilcmd.c:3956 parser/parse_utilcmd.c:3996 +#: parser/parse_utilcmd.c:4038 statistics/attribute_stats.c:201 +#: statistics/attribute_stats.c:638 utils/adt/acl.c:2969 +#: utils/adt/ruleutils.c:3218 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" msgstr "Spalte »%s« von Relation »%s« existiert nicht" @@ -7325,18 +7346,17 @@ msgstr "Spalte »%s« von Relation »%s« existiert nicht" msgid "\"%s\" is an index" msgstr "»%s« ist ein Index" -#: catalog/aclchk.c:1834 commands/tablecmds.c:16429 commands/tablecmds.c:19954 +#: catalog/aclchk.c:1834 commands/tablecmds.c:16807 commands/tablecmds.c:20332 #, c-format msgid "\"%s\" is a composite type" msgstr "»%s« ist ein zusammengesetzter Typ" -#: catalog/aclchk.c:1849 catalog/objectaddress.c:1456 commands/tablecmds.c:318 -#: commands/tablecmds.c:19938 parser/parse_clause.c:925 -#: utils/adt/ruleutils.c:1639 -#, fuzzy, c-format -#| msgid "List of property graphs" +#: catalog/aclchk.c:1849 catalog/objectaddress.c:1462 commands/tablecmds.c:318 +#: commands/tablecmds.c:20316 parser/parse_clause.c:927 +#: utils/adt/ruleutils.c:1641 +#, c-format msgid "\"%s\" is not a property graph" -msgstr "Liste der Property-Graphs" +msgstr "»%s« ist kein Property-Graph" #: catalog/aclchk.c:1889 #, c-format @@ -7504,10 +7524,9 @@ msgid "permission denied for procedure %s" msgstr "keine Berechtigung für Prozedur %s" #: catalog/aclchk.c:2753 -#, fuzzy, c-format -#| msgid "permission denied for operator %s" +#, c-format msgid "permission denied for property graph %s" -msgstr "keine Berechtigung für Operator %s" +msgstr "keine Berechtigung für Property-Graph %s" #: catalog/aclchk.c:2756 #, c-format @@ -7666,10 +7685,9 @@ msgid "must be owner of procedure %s" msgstr "Berechtigung nur für Eigentümer der Prozedur %s" #: catalog/aclchk.c:2882 -#, fuzzy, c-format -#| msgid "must be owner of operator %s" +#, c-format msgid "must be owner of property graph %s" -msgstr "Berechtigung nur für Eigentümer des Operators %s" +msgstr "Berechtigung nur für Eigentümer des Property-Graphs %s" #: catalog/aclchk.c:2885 #, c-format @@ -7741,36 +7759,36 @@ msgstr "Berechtigung nur für Eigentümer der Relation %s" msgid "permission denied for column \"%s\" of relation \"%s\"" msgstr "keine Berechtigung für Spalte »%s« von Relation »%s«" -#: catalog/aclchk.c:3213 catalog/aclchk.c:3232 +#: catalog/aclchk.c:3214 catalog/aclchk.c:3233 #, c-format msgid "attribute %d of relation with OID %u does not exist" msgstr "Attribut %d der Relation mit OID %u existiert nicht" -#: catalog/aclchk.c:3270 catalog/aclchk.c:3333 catalog/aclchk.c:3990 +#: catalog/aclchk.c:3271 catalog/aclchk.c:3334 catalog/aclchk.c:3991 #, c-format msgid "relation with OID %u does not exist" msgstr "Relation mit OID %u existiert nicht" -#: catalog/aclchk.c:3518 +#: catalog/aclchk.c:3519 #, c-format msgid "parameter ACL with OID %u does not exist" msgstr "Parameter-ACL mit OID %u existiert nicht" -#: catalog/aclchk.c:3597 catalog/objectaddress.c:1143 +#: catalog/aclchk.c:3598 catalog/objectaddress.c:1149 #: catalog/pg_largeobject.c:127 libpq/be-fsstubs.c:323 #: storage/large_object/inv_api.c:247 #, c-format msgid "large object %u does not exist" msgstr "Large Object %u existiert nicht" -#: catalog/aclchk.c:3709 commands/collationcmds.c:854 +#: catalog/aclchk.c:3710 commands/collationcmds.c:854 #: commands/publicationcmds.c:2030 #, c-format msgid "schema with OID %u does not exist" msgstr "Schema mit OID %u existiert nicht" -#: catalog/aclchk.c:3783 catalog/aclchk.c:3810 catalog/aclchk.c:3839 -#: utils/cache/typcache.c:476 utils/cache/typcache.c:531 +#: catalog/aclchk.c:3784 catalog/aclchk.c:3811 catalog/aclchk.c:3840 +#: utils/cache/typcache.c:485 utils/cache/typcache.c:540 #, c-format msgid "type with OID %u does not exist" msgstr "Typ mit OID %u existiert nicht" @@ -7804,7 +7822,7 @@ msgstr "nur Superuser können %s() aufrufen" msgid "pg_nextoid() can only be used on system catalogs" msgstr "pg_nextoid() kann nur mit Systemkatalogen verwendet werden" -#: catalog/catalog.c:676 parser/parse_utilcmd.c:2449 +#: catalog/catalog.c:676 parser/parse_utilcmd.c:2453 #, c-format msgid "index \"%s\" does not belong to table \"%s\"" msgstr "Index »%s« gehört nicht zu Tabelle »%s«" @@ -7892,278 +7910,278 @@ msgstr[1] "Löschvorgang löscht ebenfalls %d weitere Objekte" msgid "constant of the type %s cannot be used here" msgstr "Konstante vom Typ %s kann hier nicht verwendet werden" -#: catalog/dependency.c:2320 +#: catalog/dependency.c:2339 #, c-format msgid "transition table \"%s\" cannot be referenced in a persistent object" msgstr "auf Übergangstabelle »%s« kann in einem persistenten Objekt nicht verwiesen werden" -#: catalog/dependency.c:2505 parser/parse_relation.c:3598 -#: parser/parse_relation.c:3608 statistics/attribute_stats.c:213 +#: catalog/dependency.c:2524 parser/parse_relation.c:3630 +#: parser/parse_relation.c:3640 statistics/attribute_stats.c:213 #: statistics/stat_utils.c:457 statistics/stat_utils.c:465 #, c-format msgid "column %d of relation \"%s\" does not exist" msgstr "Spalte %d von Relation »%s« existiert nicht" -#: catalog/heap.c:321 +#: catalog/heap.c:322 #, c-format msgid "permission denied to create \"%s.%s\"" msgstr "keine Berechtigung, um »%s.%s« zu erzeugen" -#: catalog/heap.c:323 +#: catalog/heap.c:324 #, c-format msgid "System catalog modifications are currently disallowed." msgstr "Änderungen an Systemkatalogen sind gegenwärtig nicht erlaubt." -#: catalog/heap.c:463 commands/tablecmds.c:2630 commands/tablecmds.c:3081 -#: commands/tablecmds.c:7461 +#: catalog/heap.c:464 commands/tablecmds.c:2638 commands/tablecmds.c:3089 +#: commands/tablecmds.c:7469 #, c-format msgid "tables can have at most %d columns" msgstr "Tabellen können höchstens %d Spalten haben" -#: catalog/heap.c:481 commands/tablecmds.c:7788 +#: catalog/heap.c:482 commands/tablecmds.c:7771 #, c-format msgid "column name \"%s\" conflicts with a system column name" msgstr "Spaltenname »%s« steht im Konflikt mit dem Namen einer Systemspalte" -#: catalog/heap.c:497 +#: catalog/heap.c:498 #, c-format msgid "column name \"%s\" specified more than once" msgstr "Spaltenname »%s« mehrmals angegeben" #. translator: first %s is an integer not a name -#: catalog/heap.c:575 +#: catalog/heap.c:580 #, c-format msgid "partition key column %s has pseudo-type %s" msgstr "Partitionierungsschlüsselspalte %s hat Pseudotyp %s" -#: catalog/heap.c:580 +#: catalog/heap.c:585 #, c-format msgid "column \"%s\" has pseudo-type %s" msgstr "Spalte »%s« hat Pseudotyp %s" -#: catalog/heap.c:595 +#: catalog/heap.c:600 #, c-format msgid "virtual generated column \"%s\" cannot have a domain type" msgstr "virtuelle generierte Spalte »%s« kann keinen Domänentyp haben" -#: catalog/heap.c:622 +#: catalog/heap.c:627 #, c-format msgid "composite type %s cannot be made a member of itself" msgstr "zusammengesetzter Typ %s kann nicht Teil von sich selbst werden" -#: catalog/heap.c:673 +#: catalog/heap.c:688 #, c-format msgid "virtual generated column \"%s\" cannot have a user-defined type" msgstr "virtuelle generierte Spalte »%s« kann keinen benutzerdefinierten Typ haben" -#: catalog/heap.c:674 catalog/heap.c:3297 +#: catalog/heap.c:689 catalog/heap.c:3317 #, c-format msgid "Virtual generated columns that make use of user-defined types are not yet supported." msgstr "Virtuelle generierte Spalten, die benutzerdefinierte Typen verwenden, werden noch nicht unterstützt." #. translator: first %s is an integer not a name -#: catalog/heap.c:686 +#: catalog/heap.c:701 #, c-format msgid "no collation was derived for partition key column %s with collatable type %s" msgstr "für Partitionierungsschlüsselspalte %s mit sortierbarem Typ %s wurde keine Sortierfolge abgeleitet" -#: catalog/heap.c:692 commands/createas.c:200 commands/createas.c:512 +#: catalog/heap.c:707 commands/createas.c:200 commands/createas.c:512 #, c-format msgid "no collation was derived for column \"%s\" with collatable type %s" msgstr "für Spalte »%s« mit sortierbarem Typ %s wurde keine Sortierfolge abgeleitet" -#: catalog/heap.c:1179 catalog/index.c:906 commands/createas.c:408 -#: commands/tablecmds.c:4363 commands/tablecmds.c:22789 -#: commands/tablecmds.c:23350 commands/tablecmds.c:23780 +#: catalog/heap.c:1197 catalog/index.c:906 commands/createas.c:408 +#: commands/tablecmds.c:4371 commands/tablecmds.c:23161 +#: commands/tablecmds.c:23759 commands/tablecmds.c:24189 #, c-format msgid "relation \"%s\" already exists" msgstr "Relation »%s« existiert bereits" -#: catalog/heap.c:1195 catalog/pg_type.c:432 catalog/pg_type.c:803 +#: catalog/heap.c:1213 catalog/pg_type.c:432 catalog/pg_type.c:803 #: catalog/pg_type.c:975 commands/typecmds.c:255 commands/typecmds.c:267 #: commands/typecmds.c:760 commands/typecmds.c:1215 commands/typecmds.c:1446 -#: commands/typecmds.c:1626 commands/typecmds.c:2619 +#: commands/typecmds.c:1633 commands/typecmds.c:2626 #, c-format msgid "type \"%s\" already exists" msgstr "Typ »%s« existiert bereits" -#: catalog/heap.c:1196 +#: catalog/heap.c:1214 #, c-format msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." msgstr "Eine Relation hat einen zugehörigen Typ mit dem selben Namen, daher müssen Sie einen Namen wählen, der nicht mit einem bestehenden Typ kollidiert." -#: catalog/heap.c:1236 +#: catalog/heap.c:1254 #, c-format msgid "toast relfilenumber value not set when in binary upgrade mode" msgstr "TOAST-Relfile-Nummer-Wert ist im Binary-Upgrade-Modus nicht gesetzt" -#: catalog/heap.c:1247 +#: catalog/heap.c:1265 #, c-format msgid "pg_class heap OID value not set when in binary upgrade mode" msgstr "Heap-OID-Wert für pg_class ist im Binary-Upgrade-Modus nicht gesetzt" -#: catalog/heap.c:1257 +#: catalog/heap.c:1275 #, c-format msgid "relfilenumber value not set when in binary upgrade mode" msgstr "Relfile-Nummer-Wert ist im Binary-Upgrade-Modus nicht gesetzt" -#: catalog/heap.c:2202 +#: catalog/heap.c:2222 #, c-format msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" msgstr "zur partitionierten Tabelle »%s« kann kein NO-INHERIT-Constraint hinzugefügt werden" -#: catalog/heap.c:2525 +#: catalog/heap.c:2545 #, c-format msgid "check constraint \"%s\" already exists" msgstr "Check-Constraint »%s« existiert bereits" -#: catalog/heap.c:2626 catalog/heap.c:2949 +#: catalog/heap.c:2646 catalog/heap.c:2969 #, c-format msgid "cannot add not-null constraint on system column \"%s\"" msgstr "zur Systemspalte »%s« kann kein Not-Null-Constraint hinzugefügt werden" -#: catalog/heap.c:2654 catalog/heap.c:2780 catalog/heap.c:3033 -#: catalog/index.c:920 catalog/pg_constraint.c:1027 commands/tablecmds.c:9934 +#: catalog/heap.c:2674 catalog/heap.c:2800 catalog/heap.c:3053 +#: catalog/index.c:920 catalog/pg_constraint.c:1027 commands/tablecmds.c:9924 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" msgstr "Constraint »%s« existiert bereits für Relation »%s«" -#: catalog/heap.c:2787 +#: catalog/heap.c:2807 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" msgstr "Constraint »%s« kollidiert mit nicht vererbtem Constraint für Relation »%s«" -#: catalog/heap.c:2798 +#: catalog/heap.c:2818 #, c-format msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" msgstr "Constraint »%s« kollidiert mit vererbtem Constraint für Relation »%s«" -#: catalog/heap.c:2808 +#: catalog/heap.c:2828 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" msgstr "Constraint »%s« kollidiert mit NOT-VALID-Constraint für Relation »%s«" -#: catalog/heap.c:2820 +#: catalog/heap.c:2840 #, c-format msgid "constraint \"%s\" conflicts with NOT ENFORCED constraint on relation \"%s\"" msgstr "Constraint »%s« kollidiert mit NOT-ENFORCED-Constraint für Relation »%s«" -#: catalog/heap.c:2825 +#: catalog/heap.c:2845 #, c-format msgid "merging constraint \"%s\" with inherited definition" msgstr "Constraint »%s« wird mit geerbter Definition zusammengeführt" -#: catalog/heap.c:2849 catalog/pg_constraint.c:803 catalog/pg_constraint.c:1156 -#: commands/tablecmds.c:3246 commands/tablecmds.c:3566 -#: commands/tablecmds.c:7386 commands/tablecmds.c:8092 -#: commands/tablecmds.c:17862 commands/tablecmds.c:18044 +#: catalog/heap.c:2869 catalog/pg_constraint.c:803 catalog/pg_constraint.c:1156 +#: commands/tablecmds.c:3254 commands/tablecmds.c:3574 +#: commands/tablecmds.c:7394 commands/tablecmds.c:8075 +#: commands/tablecmds.c:18240 commands/tablecmds.c:18422 #, c-format msgid "too many inheritance parents" msgstr "zu viele Elterntabellen" -#: catalog/heap.c:2968 parser/parse_utilcmd.c:2657 +#: catalog/heap.c:2988 parser/parse_utilcmd.c:2661 #, c-format msgid "conflicting NO INHERIT declaration for not-null constraint on column \"%s\"" msgstr "widersprüchliche NO INHERIT-Deklaration für Not-Null-Constraint für Spalte »%s«" -#: catalog/heap.c:2982 +#: catalog/heap.c:3002 #, c-format msgid "conflicting not-null constraint names \"%s\" and \"%s\"" msgstr "widersprüchliche Not-Null-Constraint-Namen »%s« und »%s«" -#: catalog/heap.c:3012 +#: catalog/heap.c:3032 #, c-format msgid "cannot define not-null constraint with NO INHERIT on column \"%s\"" msgstr "kann keinen Not-Null-Constraint mit NO INHERIT für Spalte »%s« definieren" -#: catalog/heap.c:3014 +#: catalog/heap.c:3034 #, c-format msgid "The column has an inherited not-null constraint." msgstr "Die Spalte hat einen geerbten Not-Null-Constraint." -#: catalog/heap.c:3204 +#: catalog/heap.c:3224 #, c-format msgid "cannot use generated column \"%s\" in column generation expression" msgstr "generierte Spalte »%s« kann nicht im Spaltengenerierungsausdruck verwendet werden" -#: catalog/heap.c:3206 +#: catalog/heap.c:3226 #, c-format msgid "A generated column cannot reference another generated column." msgstr "Eine generierte Spalte kann nicht auf eine andere generierte Spalte verweisen." -#: catalog/heap.c:3212 +#: catalog/heap.c:3232 #, c-format msgid "cannot use whole-row variable in column generation expression" msgstr "Variable mit Verweis auf die ganze Zeile kann nicht im Spaltengenerierungsausdruck verwendet werden" -#: catalog/heap.c:3213 +#: catalog/heap.c:3233 #, c-format msgid "This would cause the generated column to depend on its own value." msgstr "Dadurch würde die generierte Spalte von ihrem eigenen Wert abhängen." -#: catalog/heap.c:3280 +#: catalog/heap.c:3300 #, c-format msgid "generation expression uses user-defined function" msgstr "Generierungsausdruck verwendet benutzerdefinierte Funktion" -#: catalog/heap.c:3281 +#: catalog/heap.c:3301 #, c-format msgid "Virtual generated columns that make use of user-defined functions are not yet supported." msgstr "Virtuelle generierte Spalten, die benutzerdefinierte Funktionen verwenden, werden noch nicht unterstützt." -#: catalog/heap.c:3296 +#: catalog/heap.c:3316 #, c-format msgid "generation expression uses user-defined type" msgstr "Generierungsausdruck verwendet benutzerdefinierten Typ" -#: catalog/heap.c:3348 +#: catalog/heap.c:3368 #, c-format msgid "generation expression is not immutable" msgstr "Generierungsausdruck ist nicht »immutable«" -#: catalog/heap.c:3380 rewrite/rewriteHandler.c:1337 +#: catalog/heap.c:3400 rewrite/rewriteHandler.c:1337 #, c-format msgid "column \"%s\" is of type %s but default expression is of type %s" msgstr "Spalte »%s« hat Typ %s, aber der Vorgabeausdruck hat Typ %s" -#: catalog/heap.c:3385 commands/prepare.c:336 parser/analyze.c:3350 +#: catalog/heap.c:3405 commands/prepare.c:336 parser/analyze.c:3347 #: parser/parse_target.c:600 parser/parse_target.c:890 #: parser/parse_target.c:900 rewrite/rewriteHandler.c:1342 #, c-format msgid "You will need to rewrite or cast the expression." msgstr "Sie müssen den Ausdruck umschreiben oder eine Typumwandlung vornehmen." -#: catalog/heap.c:3432 +#: catalog/heap.c:3452 #, c-format msgid "only table \"%s\" can be referenced in check constraint" msgstr "nur Verweise auf Tabelle »%s« sind im Check-Constraint zugelassen" -#: catalog/heap.c:3739 +#: catalog/heap.c:3759 #, c-format msgid "unsupported ON COMMIT and foreign key combination" msgstr "nicht unterstützte Kombination aus ON COMMIT und Fremdschlüssel" -#: catalog/heap.c:3740 +#: catalog/heap.c:3760 #, c-format msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." msgstr "Tabelle »%s« verweist auf »%s«, aber sie haben nicht die gleiche ON-COMMIT-Einstellung." -#: catalog/heap.c:3745 +#: catalog/heap.c:3765 #, c-format msgid "cannot truncate a table referenced in a foreign key constraint" msgstr "kann eine Tabelle, die in einen Fremdschlüssel-Constraint eingebunden ist, nicht leeren" -#: catalog/heap.c:3746 +#: catalog/heap.c:3766 #, c-format msgid "Table \"%s\" references \"%s\"." msgstr "Tabelle »%s« verweist auf »%s«." -#: catalog/heap.c:3748 +#: catalog/heap.c:3768 #, c-format msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." msgstr "Leeren Sie die Tabelle »%s« gleichzeitig oder verwenden Sie TRUNCATE ... CASCADE." -#: catalog/index.c:221 parser/parse_utilcmd.c:2354 +#: catalog/index.c:221 parser/parse_utilcmd.c:2358 #, c-format msgid "multiple primary keys for table \"%s\" are not allowed" msgstr "mehrere Primärschlüssel für Tabelle »%s« nicht erlaubt" @@ -8219,7 +8237,7 @@ msgstr "Relation »%s« existiert bereits, wird übersprungen" msgid "pg_class index OID value not set when in binary upgrade mode" msgstr "Index-OID-Wert für pg_class ist im Binary-Upgrade-Modus nicht gesetzt" -#: catalog/index.c:958 utils/cache/relcache.c:3787 +#: catalog/index.c:958 utils/cache/relcache.c:3799 #, c-format msgid "index relfilenumber value not set when in binary upgrade mode" msgstr "Index-Relfile-Nummer-Wert ist im Binary-Upgrade-Modus nicht gesetzt" @@ -8240,7 +8258,7 @@ msgid "cannot reindex invalid index on TOAST table" msgstr "ungültiger Index einer TOAST-Tabelle kann nicht reindiziert werden" #: catalog/index.c:3777 commands/indexcmds.c:3697 commands/indexcmds.c:3843 -#: commands/tablecmds.c:3770 +#: commands/tablecmds.c:3778 #, c-format msgid "cannot move system relation \"%s\"" msgstr "Systemrelation »%s« kann nicht verschoben werden" @@ -8256,7 +8274,7 @@ msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" msgstr "ungültiger Index »%s.%s« einer TOAST-Tabelle kann nicht reindizert werden, wird übersprungen" #: catalog/namespace.c:463 catalog/namespace.c:667 catalog/namespace.c:759 -#: commands/trigger.c:5892 +#: commands/trigger.c:5897 #, c-format msgid "cross-database references are not implemented: \"%s.%s.%s\"" msgstr "Verweise auf andere Datenbanken sind nicht implementiert: »%s.%s.%s«" @@ -8276,19 +8294,19 @@ msgstr "konnte Sperre für Relation »%s.%s« nicht setzen" msgid "could not obtain lock on relation \"%s\"" msgstr "konnte Sperre für Relation »%s« nicht setzen" -#: catalog/namespace.c:634 parser/parse_relation.c:1439 +#: catalog/namespace.c:634 parser/parse_relation.c:1471 #, c-format msgid "relation \"%s.%s\" does not exist" msgstr "Relation »%s.%s« existiert nicht" -#: catalog/namespace.c:639 parser/parse_relation.c:1452 -#: parser/parse_relation.c:1460 utils/adt/regproc.c:921 +#: catalog/namespace.c:639 parser/parse_relation.c:1484 +#: parser/parse_relation.c:1492 utils/adt/regproc.c:921 #, c-format msgid "relation \"%s\" does not exist" msgstr "Relation »%s« existiert nicht" -#: catalog/namespace.c:705 catalog/namespace.c:3594 commands/extension.c:1986 -#: commands/extension.c:1992 +#: catalog/namespace.c:705 catalog/namespace.c:3594 commands/extension.c:1988 +#: commands/extension.c:1994 #, c-format msgid "no schema has been selected to create in" msgstr "kein Schema für die Objekterzeugung ausgewählt" @@ -8298,7 +8316,7 @@ msgstr "kein Schema für die Objekterzeugung ausgewählt" msgid "cannot create relations in temporary schemas of other sessions" msgstr "kann keine Relationen in temporären Schemas anderer Sitzungen erzeugen" -#: catalog/namespace.c:861 parser/parse_utilcmd.c:4595 +#: catalog/namespace.c:861 parser/parse_utilcmd.c:4598 #, c-format msgid "cannot create temporary relation in non-temporary schema" msgstr "kann keine temporäre Relation in einem nicht-temporären Schema erzeugen" @@ -8356,7 +8374,7 @@ msgid "cannot move objects into or out of TOAST schema" msgstr "Objekte können nicht in oder aus TOAST-Schemas verschoben werden" #: catalog/namespace.c:3616 commands/schemacmds.c:265 commands/schemacmds.c:345 -#: commands/tablecmds.c:1525 utils/adt/regproc.c:1696 +#: commands/tablecmds.c:1533 utils/adt/regproc.c:1696 #, c-format msgid "schema \"%s\" does not exist" msgstr "Schema »%s« existiert nicht" @@ -8391,249 +8409,249 @@ msgstr "während der Wiederherstellung können keine temporären Tabellen erzeug msgid "cannot create temporary tables during a parallel operation" msgstr "während einer parallelen Operation können keine temporären Tabellen erzeugt werden" -#: catalog/objectaddress.c:1471 commands/policy.c:93 commands/policy.c:373 -#: commands/tablecmds.c:264 commands/tablecmds.c:306 commands/tablecmds.c:2452 -#: commands/tablecmds.c:14817 parser/parse_utilcmd.c:3537 +#: catalog/objectaddress.c:1477 commands/policy.c:93 commands/policy.c:373 +#: commands/tablecmds.c:264 commands/tablecmds.c:306 commands/tablecmds.c:2460 +#: commands/tablecmds.c:15027 parser/parse_utilcmd.c:3541 #, c-format msgid "\"%s\" is not a table" msgstr "»%s« ist keine Tabelle" -#: catalog/objectaddress.c:1478 commands/tablecmds.c:276 -#: commands/tablecmds.c:19918 commands/view.c:112 +#: catalog/objectaddress.c:1484 commands/tablecmds.c:276 +#: commands/tablecmds.c:20296 commands/view.c:112 #, c-format msgid "\"%s\" is not a view" msgstr "»%s« ist keine Sicht" -#: catalog/objectaddress.c:1485 commands/matview.c:200 commands/tablecmds.c:282 -#: commands/tablecmds.c:19923 +#: catalog/objectaddress.c:1491 commands/matview.c:200 commands/tablecmds.c:282 +#: commands/tablecmds.c:20301 #, c-format msgid "\"%s\" is not a materialized view" msgstr "»%s« ist keine materialisierte Sicht" -#: catalog/objectaddress.c:1492 commands/tablecmds.c:300 -#: commands/tablecmds.c:19928 +#: catalog/objectaddress.c:1498 commands/tablecmds.c:300 +#: commands/tablecmds.c:20306 #, c-format msgid "\"%s\" is not a foreign table" msgstr "»%s« ist keine Fremdtabelle" -#: catalog/objectaddress.c:1533 +#: catalog/objectaddress.c:1539 #, c-format msgid "must specify relation and object name" msgstr "Relations- und Objektname müssen angegeben werden" -#: catalog/objectaddress.c:1609 catalog/objectaddress.c:1662 +#: catalog/objectaddress.c:1615 catalog/objectaddress.c:1668 #, c-format msgid "column name must be qualified" msgstr "Spaltenname muss qualifiziert werden" -#: catalog/objectaddress.c:1681 +#: catalog/objectaddress.c:1687 #, c-format msgid "default value for column \"%s\" of relation \"%s\" does not exist" msgstr "Vorgabewert für Spalte »%s« von Relation »%s« existiert nicht" -#: catalog/objectaddress.c:1718 commands/functioncmds.c:133 -#: commands/tablecmds.c:292 commands/typecmds.c:280 commands/typecmds.c:3886 +#: catalog/objectaddress.c:1724 commands/functioncmds.c:133 +#: commands/tablecmds.c:292 commands/typecmds.c:280 commands/typecmds.c:3883 #: parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:801 -#: utils/adt/acl.c:4603 +#: utils/adt/acl.c:4606 #, c-format msgid "type \"%s\" does not exist" msgstr "Typ »%s« existiert nicht" -#: catalog/objectaddress.c:1729 +#: catalog/objectaddress.c:1735 #, c-format msgid "\"%s\" is not a domain" msgstr "»%s« ist keine Domäne" -#: catalog/objectaddress.c:1837 +#: catalog/objectaddress.c:1843 #, c-format msgid "operator %d (%s, %s) of %s does not exist" msgstr "Operator %d (%s, %s) von %s existiert nicht" -#: catalog/objectaddress.c:1868 +#: catalog/objectaddress.c:1874 #, c-format msgid "function %d (%s, %s) of %s does not exist" msgstr "Funktion %d (%s, %s) von %s existiert nicht" -#: catalog/objectaddress.c:1919 catalog/objectaddress.c:1945 +#: catalog/objectaddress.c:1925 catalog/objectaddress.c:1951 #, c-format msgid "user mapping for user \"%s\" on server \"%s\" does not exist" msgstr "Benutzerabbildung für Benutzer »%s« auf Server »%s« existiert nicht" -#: catalog/objectaddress.c:1934 commands/foreigncmds.c:441 +#: catalog/objectaddress.c:1940 commands/foreigncmds.c:441 #: commands/foreigncmds.c:1099 commands/foreigncmds.c:1462 #: foreign/foreign.c:745 #, c-format msgid "server \"%s\" does not exist" msgstr "Server »%s« existiert nicht" -#: catalog/objectaddress.c:2001 +#: catalog/objectaddress.c:2007 #, c-format msgid "publication relation \"%s\" in publication \"%s\" does not exist" msgstr "Publikationsrelation »%s« in Publikation »%s« existiert nicht" -#: catalog/objectaddress.c:2048 +#: catalog/objectaddress.c:2054 #, c-format msgid "publication schema \"%s\" in publication \"%s\" does not exist" msgstr "Publikationsschema »%s« in Publikation »%s« existiert nicht" -#: catalog/objectaddress.c:2109 +#: catalog/objectaddress.c:2115 #, c-format msgid "unrecognized default ACL object type \"%c\"" msgstr "unbekannter Standard-ACL-Objekttyp »%c«" -#: catalog/objectaddress.c:2110 +#: catalog/objectaddress.c:2116 #, c-format msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." msgstr "Gültige Objekttypen sind »%c«, »%c«, »%c«, »%c«, »%c«, »%c«." -#: catalog/objectaddress.c:2162 +#: catalog/objectaddress.c:2168 #, c-format msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" msgstr "Standard-ACL für Benutzer »%s« in Schema »%s« für %s existiert nicht" -#: catalog/objectaddress.c:2167 +#: catalog/objectaddress.c:2173 #, c-format msgid "default ACL for user \"%s\" on %s does not exist" msgstr "Standard-ACL für Benutzer »%s« für %s existiert nicht" -#: catalog/objectaddress.c:2193 catalog/objectaddress.c:2250 -#: catalog/objectaddress.c:2305 +#: catalog/objectaddress.c:2199 catalog/objectaddress.c:2256 +#: catalog/objectaddress.c:2311 #, c-format msgid "name or argument lists may not contain nulls" msgstr "Namens- oder Argumentlisten dürfen keine NULL-Werte enthalten" -#: catalog/objectaddress.c:2227 +#: catalog/objectaddress.c:2233 #, c-format msgid "unsupported object type \"%s\"" msgstr "nicht unterstützter Objekttyp »%s«" -#: catalog/objectaddress.c:2246 catalog/objectaddress.c:2263 -#: catalog/objectaddress.c:2328 catalog/objectaddress.c:2413 +#: catalog/objectaddress.c:2252 catalog/objectaddress.c:2269 +#: catalog/objectaddress.c:2334 catalog/objectaddress.c:2419 #, c-format msgid "name list length must be exactly %d" msgstr "Länge der Namensliste muss genau %d sein" -#: catalog/objectaddress.c:2267 +#: catalog/objectaddress.c:2273 #, c-format msgid "large object OID may not be null" msgstr "Large-Object-OID darf nicht NULL sein" -#: catalog/objectaddress.c:2276 catalog/objectaddress.c:2346 -#: catalog/objectaddress.c:2353 +#: catalog/objectaddress.c:2282 catalog/objectaddress.c:2352 +#: catalog/objectaddress.c:2359 #, c-format msgid "name list length must be at least %d" msgstr "Länge der Namensliste muss mindestens %d sein" -#: catalog/objectaddress.c:2339 catalog/objectaddress.c:2360 +#: catalog/objectaddress.c:2345 catalog/objectaddress.c:2366 #, c-format msgid "argument list length must be exactly %d" msgstr "Länge der Argumentliste muss genau %d sein" -#: catalog/objectaddress.c:2576 libpq/be-fsstubs.c:334 +#: catalog/objectaddress.c:2582 libpq/be-fsstubs.c:334 #, c-format msgid "must be owner of large object %u" msgstr "Berechtigung nur für Eigentümer des Large Object %u" -#: catalog/objectaddress.c:2591 commands/functioncmds.c:1581 +#: catalog/objectaddress.c:2597 commands/functioncmds.c:1581 #, c-format msgid "must be owner of type %s or type %s" msgstr "Berechtigung nur für Eigentümer des Typs %s oder des Typs %s" -#: catalog/objectaddress.c:2618 catalog/objectaddress.c:2627 -#: catalog/objectaddress.c:2633 +#: catalog/objectaddress.c:2624 catalog/objectaddress.c:2633 +#: catalog/objectaddress.c:2639 #, c-format msgid "permission denied" msgstr "keine Berechtigung" -#: catalog/objectaddress.c:2619 catalog/objectaddress.c:2628 +#: catalog/objectaddress.c:2625 catalog/objectaddress.c:2634 #, c-format msgid "The current user must have the %s attribute." msgstr "Der aktuelle Benutzer muss das %s-Attribut haben." -#: catalog/objectaddress.c:2634 +#: catalog/objectaddress.c:2640 #, c-format msgid "The current user must have the %s option on role \"%s\"." msgstr "Der aktuelle Benutzer muss die %s-Option für Rolle »%s« haben." -#: catalog/objectaddress.c:2648 +#: catalog/objectaddress.c:2654 #, c-format msgid "must be superuser" msgstr "Berechtigung nur für Superuser" -#: catalog/objectaddress.c:2717 +#: catalog/objectaddress.c:2723 #, c-format msgid "unrecognized object type \"%s\"" msgstr "unbekannter Objekttyp »%s«" #. translator: second %s is, e.g., "table %s" -#: catalog/objectaddress.c:3034 +#: catalog/objectaddress.c:3040 #, c-format msgid "column %s of %s" msgstr "Spalte %s von %s" -#: catalog/objectaddress.c:3049 +#: catalog/objectaddress.c:3055 #, c-format msgid "function %s" msgstr "Funktion %s" -#: catalog/objectaddress.c:3062 +#: catalog/objectaddress.c:3068 #, c-format msgid "type %s" msgstr "Typ %s" -#: catalog/objectaddress.c:3099 +#: catalog/objectaddress.c:3105 #, c-format msgid "cast from %s to %s" msgstr "Typumwandlung von %s in %s" -#: catalog/objectaddress.c:3132 +#: catalog/objectaddress.c:3138 #, c-format msgid "collation %s" msgstr "Sortierfolge %s" #. translator: second %s is, e.g., "table %s" -#: catalog/objectaddress.c:3163 +#: catalog/objectaddress.c:3169 #, c-format msgid "constraint %s on %s" msgstr "Constraint %s für %s" -#: catalog/objectaddress.c:3169 +#: catalog/objectaddress.c:3175 #, c-format msgid "constraint %s" msgstr "Constraint %s" -#: catalog/objectaddress.c:3201 +#: catalog/objectaddress.c:3207 #, c-format msgid "conversion %s" msgstr "Konversion %s" #. translator: %s is typically "column %s of table %s" -#: catalog/objectaddress.c:3223 +#: catalog/objectaddress.c:3229 #, c-format msgid "default value for %s" msgstr "Vorgabewert für %s" -#: catalog/objectaddress.c:3234 +#: catalog/objectaddress.c:3240 #, c-format msgid "language %s" msgstr "Sprache %s" -#: catalog/objectaddress.c:3242 +#: catalog/objectaddress.c:3248 #, c-format msgid "large object %u" msgstr "Large Object %u" -#: catalog/objectaddress.c:3255 +#: catalog/objectaddress.c:3261 #, c-format msgid "operator %s" msgstr "Operator %s" -#: catalog/objectaddress.c:3292 +#: catalog/objectaddress.c:3298 #, c-format msgid "operator class %s for access method %s" msgstr "Operatorklasse %s für Zugriffsmethode %s" -#: catalog/objectaddress.c:3320 +#: catalog/objectaddress.c:3326 #, c-format msgid "access method %s" msgstr "Zugriffsmethode %s" @@ -8642,7 +8660,7 @@ msgstr "Zugriffsmethode %s" #. first two %s's are data type names, the third %s is the #. description of the operator family, and the last %s is the #. textual form of the operator with arguments. -#: catalog/objectaddress.c:3375 +#: catalog/objectaddress.c:3381 #, c-format msgid "operator %d (%s, %s) of %s: %s" msgstr "Operator %d (%s, %s) von %s: %s" @@ -8651,274 +8669,268 @@ msgstr "Operator %d (%s, %s) von %s: %s" #. are data type names, the third %s is the description of the #. operator family, and the last %s is the textual form of the #. function with arguments. -#: catalog/objectaddress.c:3440 +#: catalog/objectaddress.c:3446 #, c-format msgid "function %d (%s, %s) of %s: %s" msgstr "Funktion %d (%s, %s) von %s: %s" #. translator: second %s is, e.g., "table %s" -#: catalog/objectaddress.c:3494 +#: catalog/objectaddress.c:3500 #, c-format msgid "rule %s on %s" msgstr "Regel %s für %s" #. translator: second %s is, e.g., "table %s" -#: catalog/objectaddress.c:3540 +#: catalog/objectaddress.c:3546 #, c-format msgid "trigger %s on %s" msgstr "Trigger %s für %s" -#: catalog/objectaddress.c:3560 +#: catalog/objectaddress.c:3566 #, c-format msgid "schema %s" msgstr "Schema %s" -#: catalog/objectaddress.c:3588 +#: catalog/objectaddress.c:3594 #, c-format msgid "statistics object %s" msgstr "Statistikobjekt %s" -#: catalog/objectaddress.c:3619 +#: catalog/objectaddress.c:3625 #, c-format msgid "text search parser %s" msgstr "Textsucheparser %s" -#: catalog/objectaddress.c:3650 +#: catalog/objectaddress.c:3656 #, c-format msgid "text search dictionary %s" msgstr "Textsuchewörterbuch %s" -#: catalog/objectaddress.c:3681 +#: catalog/objectaddress.c:3687 #, c-format msgid "text search template %s" msgstr "Textsuchevorlage %s" -#: catalog/objectaddress.c:3712 +#: catalog/objectaddress.c:3718 #, c-format msgid "text search configuration %s" msgstr "Textsuchekonfiguration %s" -#: catalog/objectaddress.c:3725 +#: catalog/objectaddress.c:3731 #, c-format msgid "role %s" msgstr "Rolle %s" -#: catalog/objectaddress.c:3762 catalog/objectaddress.c:5855 +#: catalog/objectaddress.c:3768 #, c-format msgid "membership of role %s in role %s" msgstr "Mitgliedschaft von Rolle %s in Rolle %s" -#: catalog/objectaddress.c:3783 +#: catalog/objectaddress.c:3789 #, c-format msgid "database %s" msgstr "Datenbank %s" -#: catalog/objectaddress.c:3799 +#: catalog/objectaddress.c:3805 #, c-format msgid "tablespace %s" msgstr "Tablespace %s" -#: catalog/objectaddress.c:3810 +#: catalog/objectaddress.c:3816 #, c-format msgid "foreign-data wrapper %s" msgstr "Fremddaten-Wrapper %s" -#: catalog/objectaddress.c:3820 +#: catalog/objectaddress.c:3826 #, c-format msgid "server %s" msgstr "Server %s" -#: catalog/objectaddress.c:3853 +#: catalog/objectaddress.c:3859 #, c-format msgid "user mapping for %s on server %s" msgstr "Benutzerabbildung für %s auf Server %s" -#: catalog/objectaddress.c:3905 +#: catalog/objectaddress.c:3911 #, c-format msgid "default privileges on new relations belonging to role %s in schema %s" msgstr "Vorgabeprivilegien für neue Relationen von Rolle %s in Schema %s" -#: catalog/objectaddress.c:3909 +#: catalog/objectaddress.c:3915 #, c-format msgid "default privileges on new relations belonging to role %s" msgstr "Vorgabeprivilegien für neue Relationen von Rolle %s" -#: catalog/objectaddress.c:3915 +#: catalog/objectaddress.c:3921 #, c-format msgid "default privileges on new sequences belonging to role %s in schema %s" msgstr "Vorgabeprivilegien für neue Sequenzen von Rolle %s in Schema %s" -#: catalog/objectaddress.c:3919 +#: catalog/objectaddress.c:3925 #, c-format msgid "default privileges on new sequences belonging to role %s" msgstr "Vorgabeprivilegien für neue Sequenzen von Rolle %s" -#: catalog/objectaddress.c:3925 +#: catalog/objectaddress.c:3931 #, c-format msgid "default privileges on new functions belonging to role %s in schema %s" msgstr "Vorgabeprivilegien für neue Funktionen von Rolle %s in Schema %s" -#: catalog/objectaddress.c:3929 +#: catalog/objectaddress.c:3935 #, c-format msgid "default privileges on new functions belonging to role %s" msgstr "Vorgabeprivilegien für neue Funktionen von Rolle %s" -#: catalog/objectaddress.c:3935 +#: catalog/objectaddress.c:3941 #, c-format msgid "default privileges on new types belonging to role %s in schema %s" msgstr "Vorgabeprivilegien für neue Typen von Rolle %s in Schema %s" -#: catalog/objectaddress.c:3939 +#: catalog/objectaddress.c:3945 #, c-format msgid "default privileges on new types belonging to role %s" msgstr "Vorgabeprivilegien für neue Typen von Rolle %s" -#: catalog/objectaddress.c:3945 +#: catalog/objectaddress.c:3951 #, c-format msgid "default privileges on new schemas belonging to role %s" msgstr "Vorgabeprivilegien für neue Schemas von Rolle %s" -#: catalog/objectaddress.c:3951 +#: catalog/objectaddress.c:3957 #, c-format msgid "default privileges on new large objects belonging to role %s" msgstr "Vorgabeprivilegien für neue Large Objects von Rolle %s" -#: catalog/objectaddress.c:3958 +#: catalog/objectaddress.c:3964 #, c-format msgid "default privileges belonging to role %s in schema %s" msgstr "Vorgabeprivilegien von Rolle %s in Schema %s" -#: catalog/objectaddress.c:3962 +#: catalog/objectaddress.c:3968 #, c-format msgid "default privileges belonging to role %s" msgstr "Vorgabeprivilegien von Rolle %s" -#: catalog/objectaddress.c:3984 +#: catalog/objectaddress.c:3990 #, c-format msgid "extension %s" msgstr "Erweiterung %s" -#: catalog/objectaddress.c:4001 +#: catalog/objectaddress.c:4007 #, c-format msgid "event trigger %s" msgstr "Ereignistrigger %s" -#: catalog/objectaddress.c:4025 +#: catalog/objectaddress.c:4031 #, c-format msgid "parameter %s" msgstr "Parameter %s" #. translator: second %s is, e.g., "table %s" -#: catalog/objectaddress.c:4068 +#: catalog/objectaddress.c:4074 #, c-format msgid "policy %s on %s" msgstr "Policy %s für %s" -#. translator: followed by, e.g., "property graph %s" -#: catalog/objectaddress.c:4094 -#, fuzzy, c-format -#| msgid "rule %s on %s" -msgid "vertex %s of " -msgstr "Regel %s für %s" +#: catalog/objectaddress.c:4103 +#, c-format +msgid "vertex %s of %s" +msgstr "Knoten %s von %s" -#. translator: followed by, e.g., "property graph %s" -#: catalog/objectaddress.c:4097 +#: catalog/objectaddress.c:4105 #, c-format -msgid "edge %s of " -msgstr "" +msgid "edge %s of %s" +msgstr "Kante %s von %s" -#. translator: followed by, e.g., "property graph %s" -#: catalog/objectaddress.c:4135 catalog/objectaddress.c:4160 +#: catalog/objectaddress.c:4137 catalog/objectaddress.c:4164 #, fuzzy, c-format #| msgid "rule %s on %s" -msgid "label %s of " +msgid "label %s of %s" msgstr "Regel %s für %s" -#. translator: followed by, e.g., "property graph %s" -#: catalog/objectaddress.c:4195 catalog/objectaddress.c:4220 +#: catalog/objectaddress.c:4195 catalog/objectaddress.c:4222 #, fuzzy, c-format #| msgid "improper use of \"*\"" -msgid "property %s of " +msgid "property %s of %s" msgstr "unzulässige Verwendung von »*«" -#: catalog/objectaddress.c:4232 +#: catalog/objectaddress.c:4235 #, c-format msgid "publication %s" msgstr "Publikation %s" -#: catalog/objectaddress.c:4245 +#: catalog/objectaddress.c:4248 #, c-format msgid "publication of schema %s in publication %s" msgstr "Publikation von Schema %s in Publikation %s" #. translator: first %s is, e.g., "table %s" -#: catalog/objectaddress.c:4276 +#: catalog/objectaddress.c:4279 #, c-format msgid "publication of %s in publication %s" msgstr "Publikation von %s in Publikation %s" -#: catalog/objectaddress.c:4289 +#: catalog/objectaddress.c:4292 #, c-format msgid "subscription %s" msgstr "Subskription %s" -#: catalog/objectaddress.c:4310 +#: catalog/objectaddress.c:4313 #, c-format msgid "transform for %s language %s" msgstr "Transformation %s für Sprache %s" -#: catalog/objectaddress.c:4379 +#: catalog/objectaddress.c:4382 #, c-format msgid "table %s" msgstr "Tabelle %s" -#: catalog/objectaddress.c:4384 +#: catalog/objectaddress.c:4387 #, c-format msgid "index %s" msgstr "Index %s" -#: catalog/objectaddress.c:4388 +#: catalog/objectaddress.c:4391 #, c-format msgid "sequence %s" msgstr "Sequenz %s" -#: catalog/objectaddress.c:4392 +#: catalog/objectaddress.c:4395 #, c-format msgid "toast table %s" msgstr "TOAST-Tabelle %s" -#: catalog/objectaddress.c:4396 +#: catalog/objectaddress.c:4399 #, c-format msgid "view %s" msgstr "Sicht %s" -#: catalog/objectaddress.c:4400 +#: catalog/objectaddress.c:4403 #, c-format msgid "materialized view %s" msgstr "materialisierte Sicht %s" -#: catalog/objectaddress.c:4404 +#: catalog/objectaddress.c:4407 #, c-format msgid "composite type %s" msgstr "zusammengesetzter Typ %s" -#: catalog/objectaddress.c:4408 +#: catalog/objectaddress.c:4411 #, c-format msgid "foreign table %s" msgstr "Fremdtabelle %s" -#: catalog/objectaddress.c:4412 -#, fuzzy, c-format -#| msgid "property graph" +#: catalog/objectaddress.c:4415 +#, c-format msgid "property graph %s" -msgstr "Property-Graph" +msgstr "Property-Graph %s" -#: catalog/objectaddress.c:4417 +#: catalog/objectaddress.c:4420 #, c-format msgid "relation %s" msgstr "Relation %s" -#: catalog/objectaddress.c:4458 +#: catalog/objectaddress.c:4461 #, c-format msgid "operator family %s for access method %s" msgstr "Operatorfamilie %s für Zugriffsmethode %s" @@ -8960,7 +8972,7 @@ msgstr "Anfangswert darf nicht ausgelassen werden, wenn Übergangsfunktion strik msgid "return type of inverse transition function %s is not %s" msgstr "Rückgabetyp der inversen Übergangsfunktion %s ist nicht %s" -#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:3179 +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:3180 #, c-format msgid "strictness of aggregate's forward and inverse transition functions must match" msgstr "Striktheit der vorwärtigen und inversen Übergangsfunktionen einer Aggregatfunktion müssen übereinstimmen" @@ -9036,12 +9048,12 @@ msgid "cannot change number of direct arguments of an aggregate function" msgstr "die Anzahl direkter Argumente einer Aggregatfunktion kann nicht geändert werden" #: catalog/pg_aggregate.c:861 commands/functioncmds.c:704 -#: commands/typecmds.c:2048 commands/typecmds.c:2094 commands/typecmds.c:2146 -#: commands/typecmds.c:2183 commands/typecmds.c:2217 commands/typecmds.c:2251 -#: commands/typecmds.c:2285 commands/typecmds.c:2314 commands/typecmds.c:2401 -#: commands/typecmds.c:2443 parser/parse_func.c:422 parser/parse_func.c:453 -#: parser/parse_func.c:480 parser/parse_func.c:494 parser/parse_func.c:625 -#: parser/parse_func.c:645 parser/parse_func.c:2297 parser/parse_func.c:2570 +#: commands/typecmds.c:2055 commands/typecmds.c:2101 commands/typecmds.c:2153 +#: commands/typecmds.c:2190 commands/typecmds.c:2224 commands/typecmds.c:2258 +#: commands/typecmds.c:2292 commands/typecmds.c:2321 commands/typecmds.c:2408 +#: commands/typecmds.c:2450 parser/parse_func.c:429 parser/parse_func.c:460 +#: parser/parse_func.c:487 parser/parse_func.c:501 parser/parse_func.c:631 +#: parser/parse_func.c:651 parser/parse_func.c:2304 parser/parse_func.c:2577 #, c-format msgid "function %s does not exist" msgstr "Funktion %s existiert nicht" @@ -9117,10 +9129,9 @@ msgid "This operation is not supported for partitioned indexes." msgstr "Diese Operation wird für partitionierte Indexe nicht unterstützt." #: catalog/pg_class.c:49 -#, fuzzy, c-format -#| msgid "This operation is not supported for composite types." +#, c-format msgid "This operation is not supported for property graphs." -msgstr "Diese Operation wird für zusammengesetzte Typen nicht unterstützt." +msgstr "Diese Operation wird für Property-Graphs nicht unterstützt." #: catalog/pg_collation.c:101 catalog/pg_collation.c:159 #, c-format @@ -9142,23 +9153,23 @@ msgstr "Sortierfolge »%s« existiert bereits" msgid "collation \"%s\" for encoding \"%s\" already exists" msgstr "Sortierfolge »%s« für Kodierung »%s« existiert bereits" -#: catalog/pg_constraint.c:764 commands/tablecmds.c:8077 +#: catalog/pg_constraint.c:764 commands/tablecmds.c:8060 #, c-format msgid "cannot change NO INHERIT status of NOT NULL constraint \"%s\" on relation \"%s\"" msgstr "NO INHERIT-Status von NOT-NULL-Constraint »%s« von Relation »%s« kann nicht geändert werden" -#: catalog/pg_constraint.c:766 commands/tablecmds.c:9696 +#: catalog/pg_constraint.c:766 commands/tablecmds.c:9686 #, c-format msgid "You might need to make the existing constraint inheritable using %s." msgstr "Sie müssen möglicherweise den bestehenden Constraint mit %s vererbbar machen." -#: catalog/pg_constraint.c:776 commands/tablecmds.c:8426 +#: catalog/pg_constraint.c:776 commands/tablecmds.c:8409 #, c-format msgid "incompatible NOT VALID constraint \"%s\" on relation \"%s\"" msgstr "inkompatibler NOT-VALID-Constraint »%s« für Relation »%s«" -#: catalog/pg_constraint.c:778 commands/tablecmds.c:8428 -#: commands/tablecmds.c:9708 +#: catalog/pg_constraint.c:778 commands/tablecmds.c:8411 +#: commands/tablecmds.c:9698 #, c-format msgid "You might need to validate it using %s." msgstr "Sie müssen ihn möglicherweise mit %s validieren." @@ -9208,31 +9219,43 @@ msgstr "Konversion »%s« existiert bereits" msgid "default conversion for %s to %s already exists" msgstr "Standardumwandlung von %s nach %s existiert bereits" -#: catalog/pg_depend.c:225 commands/extension.c:3881 +#: catalog/pg_depend.c:236 commands/extension.c:3883 #, c-format msgid "%s is already a member of extension \"%s\"" msgstr "%s ist schon Mitglied der Erweiterung »%s«" -#: catalog/pg_depend.c:232 catalog/pg_depend.c:283 commands/extension.c:3921 +#: catalog/pg_depend.c:243 catalog/pg_depend.c:294 commands/extension.c:3923 #, c-format msgid "%s is not a member of extension \"%s\"" msgstr "%s ist kein Mitglied der Erweiterung »%s«" -#: catalog/pg_depend.c:235 +#: catalog/pg_depend.c:246 #, c-format msgid "An extension is not allowed to replace an object that it does not own." msgstr "Eine Erweiterung darf kein Objekt ersetzen, das ihr nicht gehört." -#: catalog/pg_depend.c:286 +#: catalog/pg_depend.c:297 #, c-format msgid "An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns." msgstr "Eine Erweiterung darf CREATE .. IF NOT EXISTS zum Überspringen der Erzeugung eines Objekts nur verwenden, wenn ihr das vorhandene Objekt schon gehört." -#: catalog/pg_depend.c:649 +#: catalog/pg_depend.c:667 #, c-format msgid "cannot remove dependency on %s because it is a system object" msgstr "kann Abhängigkeit von %s nicht entfernen, weil es ein Systemobjekt ist" +#: catalog/pg_depend.c:812 +#, fuzzy, c-format +#| msgid "role %u was concurrently dropped" +msgid "referenced %s was concurrently dropped" +msgstr "Rolle %u wurde gleichzeitig gelöscht" + +#: catalog/pg_depend.c:844 +#, fuzzy, c-format +#| msgid "role %u was concurrently dropped" +msgid "referenced relation was concurrently dropped" +msgstr "Rolle %u wurde gleichzeitig gelöscht" + #: catalog/pg_enum.c:170 catalog/pg_enum.c:327 catalog/pg_enum.c:637 #, c-format msgid "invalid enum label \"%s\"" @@ -9284,8 +9307,8 @@ msgstr "Partition »%s« kann nicht abgetrennt werden" msgid "The partition is being detached concurrently or has an unfinished detach." msgstr "Die Partition wird nebenläufig abgetrennt oder hat eine unfertige Abtrennoperation." -#: catalog/pg_inherits.c:596 commands/tablecmds.c:4988 -#: commands/tablecmds.c:18165 +#: catalog/pg_inherits.c:596 commands/tablecmds.c:4996 +#: commands/tablecmds.c:18543 #, c-format msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation." msgstr "Verwendet Sie ALTER TABLE ... DETACH PARTITION ... FINALIZE, um die unerledigte Abtrennoperation abzuschließen." @@ -9390,7 +9413,7 @@ msgstr "Negator-Operator %s ist bereits der Negator des Operators %u" msgid "parameter ACL \"%s\" does not exist" msgstr "Parameter-ACL »%s« existiert nicht" -#: catalog/pg_proc.c:160 parser/parse_func.c:2359 +#: catalog/pg_proc.c:160 parser/parse_func.c:2366 #, c-format msgid "functions cannot have more than %d argument" msgid_plural "functions cannot have more than %d arguments" @@ -9494,74 +9517,74 @@ msgstr "SQL-Funktionen können keine Argumente vom Typ »%s« haben" msgid "SQL function \"%s\"" msgstr "SQL-Funktion »%s«" -#: catalog/pg_publication.c:62 +#: catalog/pg_publication.c:65 #, fuzzy, c-format #| msgid "cannot add relation \"%s\" to publication" msgid "cannot specify relation \"%s\" in the publication EXCEPT clause" msgstr "Relation »%s« kann nicht zu Publikation hinzugefügt werden" -#: catalog/pg_publication.c:64 +#: catalog/pg_publication.c:70 #, c-format msgid "cannot add relation \"%s\" to publication" msgstr "Relation »%s« kann nicht zu Publikation hinzugefügt werden" -#: catalog/pg_publication.c:71 +#: catalog/pg_publication.c:78 #, fuzzy, c-format #| msgid "This operation is not supported for partitioned tables." msgid "This operation is not supported for individual partitions." msgstr "Diese Operation wird für partitionierte Tabellen nicht unterstützt." -#: catalog/pg_publication.c:86 +#: catalog/pg_publication.c:93 #, c-format msgid "This operation is not supported for system tables." msgstr "Diese Operation wird für Systemtabellen nicht unterstützt." -#: catalog/pg_publication.c:93 +#: catalog/pg_publication.c:100 #, c-format msgid "This operation is not supported for temporary tables." msgstr "Diese Operation wird für temporäre Tabellen nicht unterstützt." -#: catalog/pg_publication.c:98 +#: catalog/pg_publication.c:105 #, c-format msgid "This operation is not supported for unlogged tables." msgstr "Diese Operation wird für ungeloggte Tabellen nicht unterstützt." -#: catalog/pg_publication.c:112 catalog/pg_publication.c:120 +#: catalog/pg_publication.c:119 catalog/pg_publication.c:127 #, c-format msgid "cannot add schema \"%s\" to publication" msgstr "Schema »%s« kann nicht zu Publikation hinzugefügt werden" -#: catalog/pg_publication.c:114 +#: catalog/pg_publication.c:121 #, c-format msgid "This operation is not supported for system schemas." msgstr "Diese Operation wird für Systemschemas nicht unterstützt." -#: catalog/pg_publication.c:122 +#: catalog/pg_publication.c:129 #, c-format msgid "Temporary schemas cannot be replicated." msgstr "Temporäre Schemas können nicht repliziert werden." -#: catalog/pg_publication.c:551 +#: catalog/pg_publication.c:558 #, c-format msgid "relation \"%s\" is already member of publication \"%s\"" msgstr "Relation »%s« ist schon Mitglied der Publikation »%s«" -#: catalog/pg_publication.c:688 +#: catalog/pg_publication.c:695 #, c-format msgid "cannot use system column \"%s\" in publication column list" msgstr "Systemspalte »%s« kann nicht in der Publikationspaltenliste verwendet werden" -#: catalog/pg_publication.c:694 +#: catalog/pg_publication.c:701 #, c-format msgid "cannot use virtual generated column \"%s\" in publication column list" msgstr "virtuelle generierte Spalte »%s« kann nicht in der Publikationsspaltenliste verwendet werden" -#: catalog/pg_publication.c:700 +#: catalog/pg_publication.c:707 #, c-format msgid "duplicate column \"%s\" in publication column list" msgstr "doppelte Spalte »%s« in Publikationsspaltenliste" -#: catalog/pg_publication.c:812 +#: catalog/pg_publication.c:819 #, c-format msgid "schema \"%s\" is already member of publication \"%s\"" msgstr "Schema »%s« ist schon Mitglied der Publikation »%s«" @@ -9639,19 +9662,32 @@ msgstr "kann Objekte, die %s gehören, nicht löschen, weil sie vom Datenbanksys msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" msgstr "kann den Eigentümer von den Objekten, die %s gehören, nicht ändern, weil die Objekte vom Datenbanksystem benötigt werden" -#: catalog/pg_subscription.c:140 commands/subscriptioncmds.c:1842 -#: commands/subscriptioncmds.c:2266 +#: catalog/pg_subscription.c:70 commands/tablecmds.c:21005 +#: replication/logical/relation.c:252 +#, c-format +msgid "\"%s\"" +msgstr "»%s«" + +#: catalog/pg_subscription.c:72 commands/tablecmds.c:21007 +#: replication/logical/relation.c:254 +#, fuzzy, c-format +#| msgid "\"%s\"" +msgid ", \"%s\"" +msgstr "»%s«" + +#: catalog/pg_subscription.c:155 commands/subscriptioncmds.c:1935 +#: commands/subscriptioncmds.c:2291 #, fuzzy, c-format #| msgid "user mapping for \"%s\" does not exist for server \"%s\"" msgid "subscription owner \"%s\" does not have permission on foreign server \"%s\"" msgstr "Benutzerabbildung für »%s« existiert nicht für Server »%s«" -#: catalog/pg_subscription.c:525 +#: catalog/pg_subscription.c:541 #, c-format msgid "could not drop relation mapping for subscription \"%s\"" msgstr "konnte Relation-Mapping für Subskription »%s« nicht löschen" -#: catalog/pg_subscription.c:527 +#: catalog/pg_subscription.c:543 #, c-format msgid "Table synchronization for relation \"%s\" is in progress and is in state \"%c\"." msgstr "Tabellensynchronisierung für Relation »%s« ist im Gang und hat Status »%c«." @@ -9659,7 +9695,7 @@ msgstr "Tabellensynchronisierung für Relation »%s« ist im Gang und hat Status #. translator: first %s is a SQL ALTER command and second %s is a #. SQL DROP command #. -#: catalog/pg_subscription.c:534 +#: catalog/pg_subscription.c:550 #, c-format msgid "Use %s to enable subscription if not already enabled or use %s to drop the subscription." msgstr "Verwenden Sie %s um die Subskription zu aktivieren, falls noch nicht aktiviert, oder %s um die Subskription zu löschen." @@ -9690,7 +9726,7 @@ msgstr "interne Größe %d ist ungültig für Typen mit Wertübergabe" msgid "alignment \"%c\" is invalid for variable-length type" msgstr "Ausrichtung »%c« ist ungültig für Typen variabler Länge" -#: catalog/pg_type.c:323 commands/typecmds.c:4406 +#: catalog/pg_type.c:323 commands/typecmds.c:4403 #, c-format msgid "fixed-size types must have storage PLAIN" msgstr "Typen mit fester Größe müssen Storage-Typ PLAIN haben" @@ -9705,7 +9741,7 @@ msgstr "Fehler während der Erzeugung eines Multirange-Typs für Typ »%s«." msgid "You can manually specify a multirange type name using the \"multirange_type_name\" attribute." msgstr "Sie können einen Multirange-Typnamen manuell angeben, mit dem Attribut »multirange_type_name«." -#: catalog/storage.c:549 storage/buffer/bufmgr.c:8840 +#: catalog/storage.c:549 storage/buffer/bufmgr.c:8889 #, c-format msgid "invalid page in block %u of relation \"%s\"" msgstr "ungültige Seite in Block %u von Relation »%s«" @@ -9825,7 +9861,7 @@ msgstr "Sprache »%s« existiert bereits" msgid "publication \"%s\" already exists" msgstr "Publikation »%s« existiert bereits" -#: commands/alter.c:98 commands/subscriptioncmds.c:709 +#: commands/alter.c:98 commands/subscriptioncmds.c:740 #, c-format msgid "subscription \"%s\" already exists" msgstr "Subskription »%s« existiert bereits" @@ -9865,16 +9901,16 @@ msgstr "Textsuchekonfiguration »%s« existiert bereits in Schema »%s«" msgid "must be superuser to rename %s" msgstr "nur Superuser können %s umbenennen" -#: commands/alter.c:250 commands/subscriptioncmds.c:688 -#: commands/subscriptioncmds.c:1477 commands/subscriptioncmds.c:1566 -#: commands/subscriptioncmds.c:2572 +#: commands/alter.c:250 commands/subscriptioncmds.c:719 +#: commands/subscriptioncmds.c:1585 commands/subscriptioncmds.c:1660 +#: commands/subscriptioncmds.c:2682 #, c-format msgid "password_required=false is superuser-only" msgstr "password_required=false ist nur für Superuser" -#: commands/alter.c:251 commands/subscriptioncmds.c:689 -#: commands/subscriptioncmds.c:1478 commands/subscriptioncmds.c:1567 -#: commands/subscriptioncmds.c:2573 +#: commands/alter.c:251 commands/subscriptioncmds.c:720 +#: commands/subscriptioncmds.c:1586 commands/subscriptioncmds.c:1661 +#: commands/subscriptioncmds.c:2683 #, c-format msgid "Subscriptions with the password_required option set to false may only be created or modified by the superuser." msgstr "Subskriptionen mit der Option password_required auf falsch gesetzt können nur vom Superuser erzeugt oder geändert werden." @@ -9912,7 +9948,7 @@ msgstr "keine Handler-Funktion angegeben" #: commands/amcmds.c:264 commands/event_trigger.c:206 #: commands/foreigncmds.c:500 commands/foreigncmds.c:548 commands/proclang.c:79 -#: commands/trigger.c:707 parser/parse_clause.c:1065 +#: commands/trigger.c:707 parser/parse_clause.c:1077 #, c-format msgid "function %s must return type %s" msgstr "Funktion %s muss Rückgabetyp %s haben" @@ -9998,17 +10034,17 @@ msgstr "PREPARE kann nicht in einer Transaktion ausgeführt werden, die LISTEN, msgid "too many notifications in the NOTIFY queue" msgstr "zu viele Benachrichtigungen in NOTIFY-Schlange" -#: commands/async.c:2240 +#: commands/async.c:2237 #, c-format msgid "NOTIFY queue is %.0f%% full" msgstr "NOTIFY-Schlange ist %.0f%% voll" -#: commands/async.c:2242 +#: commands/async.c:2239 #, c-format msgid "The server process with PID %d is among those with the oldest transactions." msgstr "Der Serverprozess mit PID %d gehört zu denen mit den ältesten Transaktionen." -#: commands/async.c:2245 +#: commands/async.c:2242 #, c-format msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." msgstr "Die NOTIFY-Schlange kann erst geleert werden, wenn dieser Prozess seine aktuelle Transaktion beendet." @@ -10019,14 +10055,14 @@ msgid "collation attribute \"%s\" not recognized" msgstr "Attribut »%s« für Sortierfolge unbekannt" #: commands/collationcmds.c:128 commands/collationcmds.c:134 -#: commands/define.c:374 commands/tablecmds.c:8519 +#: commands/define.c:374 commands/tablecmds.c:8502 #: replication/pgoutput/pgoutput.c:323 replication/pgoutput/pgoutput.c:346 #: replication/pgoutput/pgoutput.c:364 replication/pgoutput/pgoutput.c:374 #: replication/pgoutput/pgoutput.c:384 replication/pgoutput/pgoutput.c:394 -#: replication/pgoutput/pgoutput.c:406 replication/walsender.c:1166 -#: replication/walsender.c:1188 replication/walsender.c:1198 -#: replication/walsender.c:1207 replication/walsender.c:1458 -#: replication/walsender.c:1467 +#: replication/pgoutput/pgoutput.c:406 replication/walsender.c:1195 +#: replication/walsender.c:1217 replication/walsender.c:1227 +#: replication/walsender.c:1236 replication/walsender.c:1487 +#: replication/walsender.c:1496 #, c-format msgid "conflicting or redundant options" msgstr "widersprüchliche oder überflüssige Optionen" @@ -10094,11 +10130,11 @@ msgstr "Version der Standardsortierfolge kann nicht aufgefrischt werden" #. translator: %s is an SQL command #. translator: %s is an SQL ALTER command -#: commands/collationcmds.c:448 commands/subscriptioncmds.c:1970 -#: commands/tablecmds.c:8271 commands/tablecmds.c:8281 -#: commands/tablecmds.c:8283 commands/tablecmds.c:16432 -#: commands/tablecmds.c:19956 commands/tablecmds.c:19977 -#: commands/typecmds.c:3830 commands/typecmds.c:3915 commands/typecmds.c:4269 +#: commands/collationcmds.c:448 commands/subscriptioncmds.c:2064 +#: commands/tablecmds.c:8254 commands/tablecmds.c:8264 +#: commands/tablecmds.c:8266 commands/tablecmds.c:16810 +#: commands/tablecmds.c:20334 commands/tablecmds.c:20355 +#: commands/typecmds.c:3827 commands/typecmds.c:3912 commands/typecmds.c:4266 #, c-format msgid "Use %s instead." msgstr "Verwenden Sie stattdessen %s." @@ -10114,7 +10150,7 @@ msgid "version has not changed" msgstr "Version hat sich nicht geändert" #: commands/collationcmds.c:529 commands/dbcommands.c:2811 -#: utils/adt/dbsize.c:180 utils/adt/ddlutils.c:879 +#: utils/adt/dbsize.c:180 utils/adt/ddlutils.c:677 #, c-format msgid "database with OID %u does not exist" msgstr "Datenbank mit OID %u existiert nicht" @@ -10138,8 +10174,8 @@ msgstr "keine brauchbaren System-Locales gefunden" #: commands/dbcommands.c:2056 commands/dbcommands.c:2254 #: commands/dbcommands.c:2495 commands/dbcommands.c:2588 #: commands/dbcommands.c:2712 commands/dbcommands.c:3223 -#: utils/adt/regproc.c:1813 utils/init/postinit.c:1044 -#: utils/init/postinit.c:1108 utils/init/postinit.c:1181 +#: utils/adt/regproc.c:1813 utils/init/postinit.c:1067 +#: utils/init/postinit.c:1131 utils/init/postinit.c:1204 #, c-format msgid "database \"%s\" does not exist" msgstr "Datenbank »%s« existiert nicht" @@ -10149,12 +10185,12 @@ msgstr "Datenbank »%s« existiert nicht" msgid "cannot set comment on relation \"%s\"" msgstr "Kommentar von Relation »%s« kann nicht gesetzt werden" -#: commands/constraint.c:61 utils/adt/ri_triggers.c:2306 +#: commands/constraint.c:61 utils/adt/ri_triggers.c:2329 #, c-format msgid "function \"%s\" was not called by trigger manager" msgstr "Funktion »%s« wurde nicht von Triggermanager aufgerufen" -#: commands/constraint.c:68 utils/adt/ri_triggers.c:2315 +#: commands/constraint.c:68 utils/adt/ri_triggers.c:2338 #, c-format msgid "function \"%s\" must be fired AFTER ROW" msgstr "Funktion »%s« muss AFTER ROW ausgelöst werden" @@ -10241,8 +10277,8 @@ msgstr "Spalte »%s« ist eine generierte Spalte." msgid "generated columns are not supported in COPY FROM WHERE conditions" msgstr "generierte Spalten werden in COPY-FROM-WHERE-Bedingungen nicht unterstützt" -#: commands/copy.c:203 commands/tablecmds.c:14700 commands/tablecmds.c:20103 -#: commands/tablecmds.c:20185 commands/trigger.c:661 +#: commands/copy.c:203 commands/tablecmds.c:14910 commands/tablecmds.c:20481 +#: commands/tablecmds.c:20563 commands/trigger.c:661 #: rewrite/rewriteHandler.c:1001 rewrite/rewriteHandler.c:1036 #, c-format msgid "Column \"%s\" is a generated column." @@ -10443,16 +10479,16 @@ msgid "Generated columns cannot be used in COPY." msgstr "Generierte Spalten können nicht in COPY verwendet werden." #: commands/copy.c:1128 commands/indexcmds.c:1972 commands/statscmds.c:263 -#: commands/tablecmds.c:2661 commands/tablecmds.c:3168 -#: commands/tablecmds.c:3997 parser/parse_relation.c:3883 -#: parser/parse_relation.c:3893 parser/parse_relation.c:3911 -#: parser/parse_relation.c:3918 parser/parse_relation.c:3932 -#: utils/adt/tsvector_op.c:2858 +#: commands/tablecmds.c:2669 commands/tablecmds.c:3176 +#: commands/tablecmds.c:4005 parser/parse_relation.c:3916 +#: parser/parse_relation.c:3926 parser/parse_relation.c:3944 +#: parser/parse_relation.c:3951 parser/parse_relation.c:3965 +#: utils/adt/tsvector_op.c:2831 #, c-format msgid "column \"%s\" does not exist" msgstr "Spalte »%s« existiert nicht" -#: commands/copy.c:1135 commands/tablecmds.c:2687 commands/trigger.c:958 +#: commands/copy.c:1135 commands/tablecmds.c:2695 commands/trigger.c:958 #: parser/parse_target.c:1091 parser/parse_target.c:1102 #, c-format msgid "column \"%s\" specified more than once" @@ -10556,32 +10592,32 @@ msgstr[1] "% Zeilen wurden übersprungen wegen Datentypinkompatibilität #. translator: first %s is the name of a COPY option, e.g. FORCE_NOT_NULL #. translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL -#: commands/copyfrom.c:1617 commands/copyfrom.c:1681 commands/copyto.c:1095 +#: commands/copyfrom.c:1617 commands/copyfrom.c:1677 commands/copyto.c:1117 #, c-format msgid "%s column \"%s\" not referenced by COPY" msgstr "Spalte »%s« mit %s wird von COPY nicht verwendet" -#: commands/copyfrom.c:1734 utils/mb/mbutils.c:394 +#: commands/copyfrom.c:1730 utils/mb/mbutils.c:394 #, c-format msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" msgstr "Standardumwandlung von Kodierung »%s« nach »%s« existiert nicht" -#: commands/copyfrom.c:1910 +#: commands/copyfrom.c:1906 #, c-format msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." msgstr "Mit COPY FROM liest der PostgreSQL-Serverprozess eine Datei. Möglicherweise möchten Sie Funktionalität auf Client-Seite verwenden, wie zum Beispiel \\copy in psql." -#: commands/copyfrom.c:1923 commands/copyto.c:1200 +#: commands/copyfrom.c:1919 commands/copyto.c:1222 #, c-format msgid "\"%s\" is a directory" msgstr "»%s« ist ein Verzeichnis" -#: commands/copyfrom.c:1981 commands/copyto.c:714 libpq/be-secure-common.c:90 +#: commands/copyfrom.c:1977 commands/copyto.c:732 libpq/be-secure-common.c:90 #, c-format msgid "could not close pipe to external command: %m" msgstr "konnte Pipe zu externem Programm nicht schließen: %m" -#: commands/copyfrom.c:1996 commands/copyto.c:719 +#: commands/copyfrom.c:1992 commands/copyto.c:737 #, c-format msgid "program \"%s\" failed" msgstr "Programm »%s« fehlgeschlagen" @@ -10622,17 +10658,17 @@ msgid "could not read from COPY file: %m" msgstr "konnte nicht aus COPY-Datei lesen: %m" #: commands/copyfromparse.c:284 commands/copyfromparse.c:309 -#: replication/walsender.c:774 replication/walsender.c:800 tcop/postgres.c:381 +#: replication/walsender.c:781 replication/walsender.c:807 tcop/postgres.c:382 #, c-format msgid "unexpected EOF on client connection with an open transaction" msgstr "unerwartetes EOF auf Client-Verbindung mit einer offenen Transaktion" -#: commands/copyfromparse.c:300 replication/walsender.c:790 +#: commands/copyfromparse.c:300 replication/walsender.c:797 #, c-format msgid "unexpected message type 0x%02X during COPY from stdin" msgstr "unerwarteter Messagetyp 0x%02X während COPY FROM STDIN" -#: commands/copyfromparse.c:323 replication/walsender.c:821 +#: commands/copyfromparse.c:323 replication/walsender.c:828 #, c-format msgid "COPY from stdin failed: %s" msgstr "COPY FROM STDIN fehlgeschlagen: %s" @@ -10663,7 +10699,7 @@ msgstr "zusätzliche Daten nach letzter erwarteter Spalte" msgid "missing data for column \"%s\"" msgstr "fehlende Daten für Spalte »%s«" -#: commands/copyfromparse.c:1087 executor/execExprInterp.c:4419 +#: commands/copyfromparse.c:1087 executor/execExprInterp.c:4489 #: utils/adt/domains.c:158 #, c-format msgid "domain %s does not allow null values" @@ -10781,108 +10817,108 @@ msgstr "ungültige Feldgröße" msgid "incorrect binary data format" msgstr "falsches Binärdatenformat" -#: commands/copyto.c:618 +#: commands/copyto.c:636 #, c-format msgid "could not write to COPY program: %m" msgstr "konnte nicht zum COPY-Programm schreiben: %m" -#: commands/copyto.c:623 +#: commands/copyto.c:641 #, c-format msgid "could not write to COPY file: %m" msgstr "konnte nicht in COPY-Datei schreiben: %m" -#: commands/copyto.c:799 +#: commands/copyto.c:817 #, c-format msgid "cannot copy from view \"%s\"" msgstr "kann nicht aus Sicht »%s« kopieren" -#: commands/copyto.c:801 commands/copyto.c:816 commands/copyto.c:843 +#: commands/copyto.c:819 commands/copyto.c:834 commands/copyto.c:861 #, c-format msgid "Try the COPY (SELECT ...) TO variant." msgstr "Versuchen Sie die Variante COPY (SELECT ...) TO." -#: commands/copyto.c:807 +#: commands/copyto.c:825 #, c-format msgid "cannot copy from unpopulated materialized view \"%s\"" msgstr "kann nicht aus unbefüllter materialisierter Sicht »%s« kopieren" -#: commands/copyto.c:809 executor/execUtils.c:786 +#: commands/copyto.c:827 executor/execUtils.c:786 #, c-format msgid "Use the REFRESH MATERIALIZED VIEW command." msgstr "Verwenden Sie den Befehl REFRESH MATERIALIZED VIEW." -#: commands/copyto.c:814 commands/copyto.c:840 +#: commands/copyto.c:832 commands/copyto.c:858 #, c-format msgid "cannot copy from foreign table \"%s\"" msgstr "kann nicht aus Fremdtabelle »%s« kopieren" -#: commands/copyto.c:820 +#: commands/copyto.c:838 #, c-format msgid "cannot copy from sequence \"%s\"" msgstr "kann nicht aus Sequenz »%s« kopieren" -#: commands/copyto.c:841 +#: commands/copyto.c:859 #, fuzzy, c-format #| msgid "partition \"%s\" already pending detach in partitioned table \"%s.%s\"" msgid "Partition \"%s\" is a foreign table in partitioned table \"%s\"" msgstr "Partition »%s« hat schon eine unerledigte Abtrennoperation in der partitionierten Tabelle »%s.%s«" -#: commands/copyto.c:854 +#: commands/copyto.c:872 #, c-format msgid "cannot copy from non-table relation \"%s\"" msgstr "kann nicht aus Relation »%s«, die keine Tabelle ist, kopieren" -#: commands/copyto.c:912 +#: commands/copyto.c:930 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for COPY" msgstr "DO-INSTEAD-NOTHING-Regeln werden für COPY nicht unterstützt" -#: commands/copyto.c:926 +#: commands/copyto.c:944 #, c-format msgid "conditional DO INSTEAD rules are not supported for COPY" msgstr "DO-INSTEAD-Regeln mit Bedingung werden für COPY nicht unterstützt" -#: commands/copyto.c:930 +#: commands/copyto.c:948 #, c-format msgid "DO ALSO rules are not supported for COPY" msgstr "DO-ALSO-Regeln werden für COPY nicht unterstützt" -#: commands/copyto.c:935 +#: commands/copyto.c:953 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for COPY" msgstr "DO-INSTEAD-Regeln mit mehreren Anweisungen werden für COPY nicht unterstützt" -#: commands/copyto.c:945 +#: commands/copyto.c:963 #, c-format msgid "COPY (SELECT INTO) is not supported" msgstr "COPY (SELECT INTO) wird nicht unterstützt" -#: commands/copyto.c:951 +#: commands/copyto.c:969 #, c-format msgid "COPY query must not be a utility command" msgstr "COPY-Anfrage darf kein Utility-Befehl sein" -#: commands/copyto.c:967 +#: commands/copyto.c:985 #, c-format msgid "COPY query must have a RETURNING clause" msgstr "COPY-Anfrage muss eine RETURNING-Klausel haben" -#: commands/copyto.c:996 +#: commands/copyto.c:1014 #, c-format msgid "relation referenced by COPY statement has changed" msgstr "die von der COPY-Anweisung verwendete Relation hat sich geändert" -#: commands/copyto.c:1165 +#: commands/copyto.c:1187 #, c-format msgid "relative path not allowed for COPY to file" msgstr "relativer Pfad bei COPY in Datei nicht erlaubt" -#: commands/copyto.c:1184 +#: commands/copyto.c:1206 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "konnte Datei »%s« nicht zum Schreiben öffnen: %m" -#: commands/copyto.c:1187 +#: commands/copyto.c:1209 #, c-format msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." msgstr "Mit COPY TO schreibt der PostgreSQL-Serverprozess eine Datei. Möglicherweise möchten Sie Funktionalität auf Client-Seite verwenden, wie zum Beispiel \\copy in psql." @@ -10955,7 +10991,7 @@ msgid "cannot use invalid database \"%s\" as template" msgstr "ungültige Datenbank »%s« kann nicht als Template verwendet werden" #: commands/dbcommands.c:1023 commands/dbcommands.c:2506 -#: utils/init/postinit.c:1123 +#: utils/init/postinit.c:1146 #, c-format msgid "Use DROP DATABASE to drop invalid databases." msgstr "Verwenden Sie DROP DATABASE, um ungültige Datenbanken zu löschen." @@ -11240,7 +11276,7 @@ msgid "some useless files may be left behind in old database directory \"%s\"" msgstr "einige nutzlose Dateien wurde möglicherweise im alten Datenbankverzeichnis »%s« zurückgelassen" #: commands/dbcommands.c:2378 commands/explain_state.c:170 -#: commands/indexcmds.c:2874 commands/repack.c:266 commands/vacuum.c:236 +#: commands/indexcmds.c:2874 commands/repack.c:281 commands/vacuum.c:236 #: commands/vacuum.c:299 postmaster/checkpointer.c:1031 #, c-format msgid "unrecognized %s option \"%s\"" @@ -11278,7 +11314,7 @@ msgid_plural "There are %d other sessions using the database." msgstr[0] "%d andere Sitzung verwendet die Datenbank." msgstr[1] "%d andere Sitzungen verwenden die Datenbank." -#: commands/dbcommands.c:3175 storage/ipc/procarray.c:3880 +#: commands/dbcommands.c:3175 storage/ipc/procarray.c:3867 #, c-format msgid "There is %d prepared transaction using the database." msgid_plural "There are %d prepared transactions using the database." @@ -11328,7 +11364,7 @@ msgid "invalid argument for %s: \"%s\"" msgstr "ungültiges Argument für %s: »%s«" #: commands/dropcmds.c:96 commands/functioncmds.c:1403 -#: utils/adt/ruleutils.c:3314 +#: utils/adt/ruleutils.c:3316 #, c-format msgid "\"%s\" is an aggregate function" msgstr "»%s« ist eine Aggregatfunktion" @@ -11338,14 +11374,14 @@ msgstr "»%s« ist eine Aggregatfunktion" msgid "Use DROP AGGREGATE to drop aggregate functions." msgstr "Verwenden Sie DROP AGGREGATE, um Aggregatfunktionen zu löschen." -#: commands/dropcmds.c:153 commands/propgraphcmds.c:1305 -#: commands/sequence.c:457 commands/tablecmds.c:4081 commands/tablecmds.c:4242 -#: commands/tablecmds.c:4294 commands/tablecmds.c:19228 tcop/utility.c:1331 +#: commands/dropcmds.c:153 commands/propgraphcmds.c:1312 +#: commands/sequence.c:457 commands/tablecmds.c:4089 commands/tablecmds.c:4250 +#: commands/tablecmds.c:4302 commands/tablecmds.c:19606 tcop/utility.c:1331 #, c-format msgid "relation \"%s\" does not exist, skipping" msgstr "Relation »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:183 commands/dropcmds.c:282 commands/tablecmds.c:1530 +#: commands/dropcmds.c:183 commands/dropcmds.c:282 commands/tablecmds.c:1538 #, c-format msgid "schema \"%s\" does not exist, skipping" msgstr "Schema »%s« existiert nicht, wird übersprungen" @@ -11547,23 +11583,23 @@ msgstr "keine Berechtigung, um Eigentümer des Ereignistriggers »%s« zu änder msgid "The owner of an event trigger must be a superuser." msgstr "Der Eigentümer eines Ereignistriggers muss ein Superuser sein." -#: commands/event_trigger.c:1538 +#: commands/event_trigger.c:1546 #, c-format msgid "%s can only be called in a sql_drop event trigger function" msgstr "%s kann nur in einer sql_drop-Ereignistriggerfunktion aufgerufen werden" -#: commands/event_trigger.c:1631 commands/event_trigger.c:1652 +#: commands/event_trigger.c:1639 commands/event_trigger.c:1660 #, c-format msgid "%s can only be called in a table_rewrite event trigger function" msgstr "%s kann nur in einer table_rewrite-Ereignistriggerfunktion aufgerufen werden" -#: commands/event_trigger.c:2068 +#: commands/event_trigger.c:2076 #, c-format msgid "%s can only be called in an event trigger function" msgstr "%s kann nur in einer Ereignistriggerfunktion aufgerufen werden" #: commands/explain_state.c:136 commands/explain_state.c:161 commands/wait.c:87 -#: postmaster/checkpointer.c:1022 replication/walsender.c:1180 +#: postmaster/checkpointer.c:1022 replication/walsender.c:1209 #, c-format msgid "unrecognized value for %s option \"%s\": \"%s\"" msgstr "unbekannter Wert für %s-Option »%s«: »%s«" @@ -11591,7 +11627,7 @@ msgstr "unbekannte %s-Option »%s«" msgid "EXPLAIN option \"%s\" requires a Boolean value" msgstr "Parameter »%s« erfordert einen Boole’schen Wert" -#: commands/extension.c:239 commands/extension.c:3515 +#: commands/extension.c:239 commands/extension.c:3517 #, c-format msgid "extension \"%s\" does not exist" msgstr "Erweiterung »%s« existiert nicht" @@ -11648,243 +11684,243 @@ msgstr "Versionsnamen dürfen nicht mit »-« anfangen oder aufhören." msgid "Version names must not contain directory separator characters." msgstr "Versionsnamen dürfen keine Verzeichnistrennzeichen enthalten." -#: commands/extension.c:722 +#: commands/extension.c:724 #, c-format msgid "extension \"%s\" is not available" msgstr "Erweiterung »%s« ist nicht verfügbar" -#: commands/extension.c:723 +#: commands/extension.c:725 #, c-format msgid "The extension must first be installed on the system where PostgreSQL is running." msgstr "Die Erweiterung muss zuerst auf dem System, auf dem PostgreSQL läuft, installiert werden." -#: commands/extension.c:745 +#: commands/extension.c:747 #, c-format msgid "could not open extension control file \"%s\": %m" msgstr "konnte Erweiterungskontrolldatei »%s« nicht öffnen: %m" -#: commands/extension.c:768 commands/extension.c:778 +#: commands/extension.c:770 commands/extension.c:780 #, c-format msgid "parameter \"%s\" cannot be set in a secondary extension control file" msgstr "Parameter »%s« kann nicht in einer sekundären Erweitungskontrolldatei gesetzt werden" -#: commands/extension.c:800 commands/extension.c:808 commands/extension.c:816 +#: commands/extension.c:802 commands/extension.c:810 commands/extension.c:818 #: utils/misc/guc.c:3041 #, c-format msgid "parameter \"%s\" requires a Boolean value" msgstr "Parameter »%s« erfordert einen Boole’schen Wert" -#: commands/extension.c:825 +#: commands/extension.c:827 #, c-format msgid "\"%s\" is not a valid encoding name" msgstr "»%s« ist kein gültiger Kodierungsname" -#: commands/extension.c:839 commands/extension.c:854 +#: commands/extension.c:841 commands/extension.c:856 #, c-format msgid "parameter \"%s\" must be a list of extension names" msgstr "Parameter »%s« muss eine Liste von Erweiterungsnamen sein" -#: commands/extension.c:861 +#: commands/extension.c:863 #, c-format msgid "unrecognized parameter \"%s\" in file \"%s\"" msgstr "unbekannter Parameter »%s« in Datei »%s«" -#: commands/extension.c:870 +#: commands/extension.c:872 #, c-format msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" msgstr "Parameter »schema« kann nicht angegeben werden, wenn »relocatable« an ist" -#: commands/extension.c:1046 +#: commands/extension.c:1048 #, c-format msgid "SQL statement \"%.*s\"" msgstr "SQL-Anweisung »%.*s«" -#: commands/extension.c:1075 +#: commands/extension.c:1077 #, c-format msgid "extension script file \"%s\", near line %d" msgstr "Erweiterungs-Skript-Datei »%s«, in der Nähe von Zeile %d" -#: commands/extension.c:1079 +#: commands/extension.c:1081 #, c-format msgid "extension script file \"%s\"" msgstr "Erweiterungs-Skript-Datei »%s«" -#: commands/extension.c:1191 +#: commands/extension.c:1193 #, c-format msgid "transaction control statements are not allowed within an extension script" msgstr "Transaktionskontrollanweisungen sind nicht in einem Erweiterungsskript erlaubt" -#: commands/extension.c:1273 +#: commands/extension.c:1275 #, c-format msgid "permission denied to create extension \"%s\"" msgstr "keine Berechtigung, um Erweiterung »%s« zu erzeugen" -#: commands/extension.c:1276 +#: commands/extension.c:1278 #, c-format msgid "Must have CREATE privilege on current database to create this extension." msgstr "CREATE-Privileg für die aktuelle Datenbank wird benötigt, um diese Erweiterung anzulegen." -#: commands/extension.c:1277 +#: commands/extension.c:1279 #, c-format msgid "Must be superuser to create this extension." msgstr "Nur Superuser können diese Erweiterung anlegen." -#: commands/extension.c:1281 +#: commands/extension.c:1283 #, c-format msgid "permission denied to update extension \"%s\"" msgstr "keine Berechtigung, um Erweiterung »%s« zu aktualisieren" -#: commands/extension.c:1284 +#: commands/extension.c:1286 #, c-format msgid "Must have CREATE privilege on current database to update this extension." msgstr "CREATE-Privileg für die aktuelle Datenbank wird benötigt, um diese Erweiterung zu aktualisieren." -#: commands/extension.c:1285 +#: commands/extension.c:1287 #, c-format msgid "Must be superuser to update this extension." msgstr "Nur Superuser können diese Erweiterung aktualisieren." -#: commands/extension.c:1418 +#: commands/extension.c:1420 #, c-format msgid "invalid character in extension owner: must not contain any of \"%s\"" msgstr "ungültiges Zeichen im Erweiterungseigentümer: darf keins aus »%s« enthalten" -#: commands/extension.c:1442 commands/extension.c:1469 +#: commands/extension.c:1444 commands/extension.c:1471 #, c-format msgid "invalid character in extension \"%s\" schema: must not contain any of \"%s\"" msgstr "ungültiges Zeichen in Schema von Erweiterung »%s«: darf keins aus »%s« enthalten" -#: commands/extension.c:1664 +#: commands/extension.c:1666 #, c-format msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" msgstr "Erweiterung »%s« hat keinen Aktualisierungspfad von Version »%s« auf Version »%s«" -#: commands/extension.c:1872 commands/extension.c:3573 +#: commands/extension.c:1874 commands/extension.c:3575 #, c-format msgid "version to install must be specified" msgstr "die zu installierende Version muss angegeben werden" -#: commands/extension.c:1909 +#: commands/extension.c:1911 #, c-format msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" msgstr "Erweiterung »%s« hat kein Installationsskript und keinen Aktualisierungspfad für Version »%s«" -#: commands/extension.c:1943 +#: commands/extension.c:1945 #, c-format msgid "extension \"%s\" must be installed in schema \"%s\"" msgstr "Erweiterung »%s« muss in Schema »%s« installiert werden" -#: commands/extension.c:2106 +#: commands/extension.c:2108 #, c-format msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" msgstr "zyklische Abhängigkeit zwischen Erweiterungen »%s« und »%s« entdeckt" -#: commands/extension.c:2111 +#: commands/extension.c:2113 #, c-format msgid "installing required extension \"%s\"" msgstr "installiere benötigte Erweiterung »%s«" -#: commands/extension.c:2134 +#: commands/extension.c:2136 #, c-format msgid "required extension \"%s\" is not installed" msgstr "benötigte Erweiterung »%s« ist nicht installiert" -#: commands/extension.c:2137 +#: commands/extension.c:2139 #, c-format msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." msgstr "Verwenden Sie CREATE EXTENSION ... CASCADE, um die benötigten Erweiterungen ebenfalls zu installieren." -#: commands/extension.c:2172 +#: commands/extension.c:2174 #, c-format msgid "extension \"%s\" already exists, skipping" msgstr "Erweiterung »%s« existiert bereits, wird übersprungen" -#: commands/extension.c:2179 +#: commands/extension.c:2181 #, c-format msgid "extension \"%s\" already exists" msgstr "Erweiterung »%s« existiert bereits" -#: commands/extension.c:2190 +#: commands/extension.c:2192 #, c-format msgid "nested CREATE EXTENSION is not supported" msgstr "geschachteltes CREATE EXTENSION wird nicht unterstützt" -#: commands/extension.c:2354 +#: commands/extension.c:2356 #, c-format msgid "cannot drop extension \"%s\" because it is being modified" msgstr "Erweiterung »%s« kann nicht gelöscht werden, weil sie gerade geändert wird" -#: commands/extension.c:2881 +#: commands/extension.c:2883 #, c-format msgid "%s can only be called from an SQL script executed by CREATE EXTENSION" msgstr "%s kann nur von einem SQL-Skript aufgerufen werden, das von CREATE EXTENSION ausgeführt wird" -#: commands/extension.c:2893 +#: commands/extension.c:2895 #, c-format msgid "OID %u does not refer to a table" msgstr "OID %u bezieht sich nicht auf eine Tabelle" -#: commands/extension.c:2898 +#: commands/extension.c:2900 #, c-format msgid "table \"%s\" is not a member of the extension being created" msgstr "Tabelle »%s« ist kein Mitglied der anzulegenden Erweiterung" -#: commands/extension.c:3297 +#: commands/extension.c:3299 #, c-format msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" msgstr "kann Erweiterung »%s« nicht in Schema »%s« verschieben, weil die Erweiterung das Schema enthält" -#: commands/extension.c:3338 commands/extension.c:3432 +#: commands/extension.c:3340 commands/extension.c:3434 #, c-format msgid "extension \"%s\" does not support SET SCHEMA" msgstr "Erweiterung »%s« unterstützt SET SCHEMA nicht" -#: commands/extension.c:3395 +#: commands/extension.c:3397 #, c-format msgid "cannot SET SCHEMA of extension \"%s\" because other extensions prevent it" msgstr "SET SCHEMA für Erweiterung »%s« ist nicht möglich, weil andere Erweiterungen es verhindern" -#: commands/extension.c:3397 +#: commands/extension.c:3399 #, c-format msgid "Extension \"%s\" requests no relocation of extension \"%s\"." msgstr "Erweiterung »%s« verhindert Verlagerung von Erweiterung »%s«." -#: commands/extension.c:3434 +#: commands/extension.c:3436 #, c-format msgid "%s is not in the extension's schema \"%s\"" msgstr "%s ist nicht im Schema der Erweiterung (»%s«)" -#: commands/extension.c:3495 +#: commands/extension.c:3497 #, c-format msgid "nested ALTER EXTENSION is not supported" msgstr "geschachteltes ALTER EXTENSION wird nicht unterstützt" -#: commands/extension.c:3584 +#: commands/extension.c:3586 #, c-format msgid "version \"%s\" of extension \"%s\" is already installed" msgstr "Version »%s« von Erweiterung »%s« ist bereits installiert" -#: commands/extension.c:3795 +#: commands/extension.c:3797 #, c-format msgid "cannot add an object of this type to an extension" msgstr "ein Objekt dieses Typs kann nicht zu einer Erweiterung hinzugefügt werden" -#: commands/extension.c:3893 +#: commands/extension.c:3895 #, c-format msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" msgstr "kann Schema »%s« nicht zu Erweiterung »%s« hinzufügen, weil das Schema die Erweiterung enthält" -#: commands/extension.c:3975 commands/typecmds.c:4085 utils/fmgr/funcapi.c:727 +#: commands/extension.c:3977 commands/typecmds.c:4082 utils/fmgr/funcapi.c:727 #, c-format msgid "could not find multirange type for data type %s" msgstr "konnte Multirange-Typ für Datentyp %s nicht finden" -#: commands/extension.c:4017 +#: commands/extension.c:4019 #, c-format msgid "file \"%s\" is too large" msgstr "Datei »%s« ist zu groß" -#: commands/extension.c:4109 utils/fmgr/dfmgr.c:625 +#: commands/extension.c:4111 utils/fmgr/dfmgr.c:625 #, c-format msgid "component in parameter \"%s\" is not an absolute path" msgstr "eine Komponente im Parameter »%s« ist kein absoluter Pfad" @@ -12404,12 +12440,13 @@ msgstr "kann Index für partitionierte Tabelle »%s« nicht nebenläufig erzeuge msgid "cannot create indexes on temporary tables of other sessions" msgstr "kann keine Indexe für temporäre Tabellen anderer Sitzungen erzeugen" -#: commands/indexcmds.c:790 commands/tablecmds.c:939 commands/tablespace.c:1192 +#: commands/indexcmds.c:790 commands/tablecmds.c:947 commands/tablespace.c:1192 #, c-format msgid "cannot specify default tablespace for partitioned relations" msgstr "für partitionierte Relationen kann kein Standard-Tablespace angegeben werden" -#: commands/indexcmds.c:822 commands/tablecmds.c:970 commands/tablecmds.c:3777 +#: commands/indexcmds.c:822 commands/tablecmds.c:978 commands/tablecmds.c:3785 +#: commands/tablecmds.c:23210 #, c-format msgid "only shared relations can be placed in pg_global tablespace" msgstr "nur geteilte Relationen können in den Tablespace »pg_global« gelegt werden" @@ -12459,7 +12496,7 @@ msgstr "%s-Constraints können nicht verwendet werden, wenn Partitionierungsschl #: parser/parse_cte.c:303 parser/parse_oper.c:224 #: utils/adt/array_userfuncs.c:1419 utils/adt/array_userfuncs.c:1562 #: utils/adt/arrayfuncs.c:3878 utils/adt/arrayfuncs.c:4431 -#: utils/adt/arrayfuncs.c:6458 utils/adt/rowtypes.c:1220 +#: utils/adt/arrayfuncs.c:6465 utils/adt/rowtypes.c:1220 #, c-format msgid "could not identify an equality operator for type %s" msgstr "konnte keinen Ist-Gleich-Operator für Typ %s ermitteln" @@ -12522,8 +12559,8 @@ msgstr "Tabelle »%s« enthält Partitionen, die Fremdtabellen sind." msgid "functions in index predicate must be marked IMMUTABLE" msgstr "Funktionen im Indexprädikat müssen als IMMUTABLE markiert sein" -#: commands/indexcmds.c:1966 parser/parse_utilcmd.c:2737 -#: parser/parse_utilcmd.c:2926 +#: commands/indexcmds.c:1966 parser/parse_utilcmd.c:2741 +#: parser/parse_utilcmd.c:2930 #, c-format msgid "column \"%s\" named in key does not exist" msgstr "Spalte »%s«, die im Schlüssel verwendet wird, existiert nicht" @@ -12563,8 +12600,8 @@ msgstr "inkludierte Spalte unterstützt die Optionen NULLS FIRST/LAST nicht" msgid "could not determine which collation to use for index expression" msgstr "konnte die für den Indexausdruck zu verwendende Sortierfolge nicht bestimmen" -#: commands/indexcmds.c:2118 commands/tablecmds.c:20273 commands/typecmds.c:814 -#: parser/parse_expr.c:2837 parser/parse_type.c:568 parser/parse_utilcmd.c:4386 +#: commands/indexcmds.c:2118 commands/tablecmds.c:20651 commands/typecmds.c:814 +#: parser/parse_expr.c:2837 parser/parse_type.c:568 parser/parse_utilcmd.c:4389 #: utils/adt/misc.c:603 #, c-format msgid "collations are not supported by type %s" @@ -12600,8 +12637,8 @@ msgstr "Zugriffsmethode »%s« unterstützt die Optionen ASC/DESC nicht" msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "Zugriffsmethode »%s« unterstützt die Optionen NULLS FIRST/LAST nicht" -#: commands/indexcmds.c:2303 commands/tablecmds.c:20298 -#: commands/tablecmds.c:20304 commands/typecmds.c:2374 parser/analyze.c:1505 +#: commands/indexcmds.c:2303 commands/tablecmds.c:20676 +#: commands/tablecmds.c:20682 commands/typecmds.c:2381 parser/analyze.c:1505 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" msgstr "Datentyp %s hat keine Standardoperatorklasse für Zugriffsmethode »%s«" @@ -12617,7 +12654,7 @@ msgstr "Sie müssen für den Index eine Operatorklasse angeben oder eine Standar msgid "operator class \"%s\" does not exist for access method \"%s\"" msgstr "Operatorklasse »%s« existiert nicht für Zugriffsmethode »%s«" -#: commands/indexcmds.c:2356 commands/typecmds.c:2362 +#: commands/indexcmds.c:2356 commands/typecmds.c:2369 #, c-format msgid "operator class \"%s\" does not accept data type %s" msgstr "Operatorklasse »%s« akzeptiert Datentyp %s nicht" @@ -12637,7 +12674,7 @@ msgstr "konnte keinen Überlappungsoperator für Typ %s ermitteln" msgid "could not identify a contained-by operator for type %s" msgstr "konnte keinen Contained-By-Operator für Typ %s ermitteln" -#: commands/indexcmds.c:2501 commands/tablecmds.c:10471 +#: commands/indexcmds.c:2501 commands/tablecmds.c:10461 #, c-format msgid "Could not translate compare type %d for operator family \"%s\" of access method \"%s\"." msgstr "Konnte Vergleichstyp %d für Operatorfamilie »%s« von Zugriffsmethode »%s« nicht übersetzen." @@ -13055,13 +13092,13 @@ msgstr "Join-Schätzfunktion %s muss Typ %s zurückgeben" msgid "must be superuser to specify a non-built-in join estimator function" msgstr "nur Superuser können eine nicht eingebaute Join-Schätzfunktion angeben" -#: commands/operatorcmds.c:421 parser/parse_oper.c:122 parser/parse_oper.c:644 +#: commands/operatorcmds.c:421 parser/parse_oper.c:122 parser/parse_oper.c:650 #: utils/adt/regproc.c:516 utils/adt/regproc.c:691 #, c-format msgid "operator does not exist: %s" msgstr "Operator existiert nicht: %s" -#: commands/operatorcmds.c:429 parser/parse_oper.c:747 parser/parse_oper.c:860 +#: commands/operatorcmds.c:429 parser/parse_oper.c:753 parser/parse_oper.c:866 #, c-format msgid "operator is only a shell: %s" msgstr "Operator ist nur eine Hülle: %s" @@ -13077,13 +13114,13 @@ msgstr "Operator-Attribut »%s« kann nicht geändert werden" msgid "operator attribute \"%s\" cannot be changed if it has already been set" msgstr "Operator-Attribut »%s« kann nicht geändert werden, wenn es schon gesetzt wurde" -#: commands/policy.c:86 commands/policy.c:379 commands/repack.c:615 -#: commands/statscmds.c:154 commands/tablecmds.c:1865 commands/tablecmds.c:2468 -#: commands/tablecmds.c:3891 commands/tablecmds.c:6893 -#: commands/tablecmds.c:10227 commands/tablecmds.c:19839 -#: commands/tablecmds.c:19874 commands/trigger.c:320 commands/trigger.c:1339 +#: commands/policy.c:86 commands/policy.c:379 commands/repack.c:637 +#: commands/statscmds.c:154 commands/tablecmds.c:1873 commands/tablecmds.c:2476 +#: commands/tablecmds.c:3899 commands/tablecmds.c:6901 +#: commands/tablecmds.c:10217 commands/tablecmds.c:20217 +#: commands/tablecmds.c:20252 commands/trigger.c:320 commands/trigger.c:1339 #: commands/trigger.c:1449 rewrite/rewriteDefine.c:268 -#: rewrite/rewriteDefine.c:778 rewrite/rewriteRemove.c:74 +#: rewrite/rewriteDefine.c:763 rewrite/rewriteRemove.c:74 #, c-format msgid "permission denied: \"%s\" is a system catalog" msgstr "keine Berechtigung: »%s« ist ein Systemkatalog" @@ -13180,10 +13217,9 @@ msgid "must be superuser to create custom procedural language" msgstr "nur Superuser können maßgeschneiderte prozedurale Sprachen erzeugen" #: commands/propgraphcmds.c:118 -#, fuzzy, c-format -#| msgid "views cannot be unlogged because they do not have storage" +#, c-format msgid "property graphs cannot be unlogged because they do not have storage" -msgstr "Sichten können nicht ungeloggt sein, weil sie keinen Speicherplatz verwenden" +msgstr "Property-Graphs können nicht ungeloggt sein, weil sie keinen Speicherplatz verwenden" #: commands/propgraphcmds.c:146 commands/propgraphcmds.c:189 #, fuzzy, c-format @@ -13192,16 +13228,14 @@ msgid "alias \"%s\" used more than once as element table" msgstr "gemeinsamer Spaltenname »%s« erscheint mehrmals in der linken Tabelle" #: commands/propgraphcmds.c:215 -#, fuzzy, c-format -#| msgid "source encoding \"%s\" does not exist" +#, c-format msgid "source vertex \"%s\" of edge \"%s\" does not exist" -msgstr "Quellkodierung »%s« existiert nicht" +msgstr "Quellknoten »%s« von Kante »%s« existiert nicht" #: commands/propgraphcmds.c:221 -#, fuzzy, c-format -#| msgid "destination encoding \"%s\" does not exist" +#, c-format msgid "destination vertex \"%s\" of edge \"%s\" does not exist" -msgstr "Zielkodierung »%s« existiert nicht" +msgstr "Zielknoten »%s« von Kante »%s« existiert nicht" #: commands/propgraphcmds.c:260 #, fuzzy, c-format @@ -13252,96 +13286,103 @@ msgstr "die Liste der Spalten, auf die ein Fremdschlüssel verweist, darf keine msgid "property name required" msgstr "Sichtname wird benötigt" -#: commands/propgraphcmds.c:985 +#: commands/propgraphcmds.c:987 #, c-format msgid "property \"%s\" data type mismatch: %s vs. %s" msgstr "" -#: commands/propgraphcmds.c:987 +#: commands/propgraphcmds.c:989 #, c-format msgid "In a property graph, a property of the same name has to have the same data type in each label." msgstr "" -#: commands/propgraphcmds.c:995 +#: commands/propgraphcmds.c:997 #, c-format msgid "property \"%s\" collation mismatch: %s vs. %s" msgstr "" -#: commands/propgraphcmds.c:997 +#: commands/propgraphcmds.c:999 #, c-format msgid "In a property graph, a property of the same name has to have the same collation in each label." msgstr "" -#: commands/propgraphcmds.c:1143 +#: commands/propgraphcmds.c:1145 #, fuzzy, c-format #| msgid "column \"%s\" is of type %s but expression is of type %s" msgid "element \"%s\" property \"%s\" expression mismatch: %s vs. %s" msgstr "Spalte »%s« hat Typ %s, aber der Ausdruck hat Typ %s" -#: commands/propgraphcmds.c:1145 +#: commands/propgraphcmds.c:1147 #, c-format msgid "In a property graph element, a property of the same name has to have the same expression in each label." msgstr "" -#: commands/propgraphcmds.c:1261 +#: commands/propgraphcmds.c:1263 #, fuzzy, c-format #| msgid "invalid number of parents %d for table \"%s\"" msgid "mismatching number of properties in definition of label \"%s\"" msgstr "ungültige Anzahl Eltern %d für Tabelle »%s«" -#: commands/propgraphcmds.c:1269 +#: commands/propgraphcmds.c:1271 #, fuzzy, c-format #| msgid "merging multiple inherited definitions of column \"%s\"" -msgid "mismatching properties names in definition of label \"%s\"" +msgid "mismatching property names in definition of label \"%s\"" msgstr "geerbte Definitionen von Spalte »%s« werden zusammengeführt" -#: commands/propgraphcmds.c:1329 commands/propgraphcmds.c:1379 +#: commands/propgraphcmds.c:1336 commands/propgraphcmds.c:1386 #, fuzzy, c-format #| msgid "cannot create temporary relation in non-temporary schema" msgid "cannot add temporary element table to non-temporary property graph" msgstr "kann keine temporäre Relation in einem nicht-temporären Schema erzeugen" -#: commands/propgraphcmds.c:1330 commands/propgraphcmds.c:1380 +#: commands/propgraphcmds.c:1337 commands/propgraphcmds.c:1387 #, fuzzy, c-format #| msgid "view \"%s\" will be a temporary view" msgid "Table \"%s\" is a temporary table." msgstr "Sicht »%s« wird eine temporäre Sicht" -#: commands/propgraphcmds.c:1349 commands/propgraphcmds.c:1418 -#, fuzzy, c-format -#| msgid "wait event \"%s\" already exists in type \"%s\"" +#: commands/propgraphcmds.c:1356 commands/propgraphcmds.c:1425 +#, c-format msgid "alias \"%s\" already exists in property graph \"%s\"" -msgstr "Wait-Event »%s« existiert bereits in Typ »%s«" +msgstr "Alias »%s« existiert bereits in Property-Graph »%s«" -#: commands/propgraphcmds.c:1509 commands/propgraphcmds.c:1521 -#: commands/propgraphcmds.c:1555 commands/propgraphcmds.c:1566 -#: commands/propgraphcmds.c:1598 commands/propgraphcmds.c:1610 +#: commands/propgraphcmds.c:1521 commands/propgraphcmds.c:1557 +#: commands/propgraphcmds.c:1607 commands/propgraphcmds.c:1645 #, c-format msgid "property graph \"%s\" element \"%s\" has no label \"%s\"" -msgstr "" +msgstr "Property-Graph »%s« Element »%s« hat kein Label »%s«" + +#: commands/propgraphcmds.c:1568 +#, fuzzy, c-format +#| msgid "cannot delete from table \"%s\"" +msgid "cannot drop the last label from element \"%s\"" +msgstr "kann nicht aus Tabelle »%s« löschen" + +#: commands/propgraphcmds.c:1570 +#, fuzzy, c-format +#| msgid "RETURNING must have at least one column" +msgid "Every element must have at least one label." +msgstr "RETURNING muss mindestens eine Spalte haben" -#: commands/propgraphcmds.c:1627 +#: commands/propgraphcmds.c:1667 #, c-format msgid "property graph \"%s\" element \"%s\" label \"%s\" has no property \"%s\"" msgstr "" -#: commands/propgraphcmds.c:1693 commands/propgraphcmds.c:1725 -#, fuzzy, c-format -#| msgid "cursor \"%s\" has no argument named \"%s\"" +#: commands/propgraphcmds.c:1731 commands/propgraphcmds.c:1763 +#, c-format msgid "property graph \"%s\" has no element with alias \"%s\"" -msgstr "Cursor »%s« hat kein Argument namens »%s«" +msgstr "Property-Graph »%s« hat kein Element mit Alias »%s«" -#: commands/propgraphcmds.c:1700 -#, fuzzy, c-format -#| msgid "column \"%s\" of relation \"%s\" is not a generated column" +#: commands/propgraphcmds.c:1738 +#, c-format msgid "element \"%s\" of property graph \"%s\" is not a vertex" -msgstr "Spalte »%s« von Relation »%s« ist keine generierte Spalte" +msgstr "Element »%s« von Property-Graph »%s« ist kein Knoten" -#: commands/propgraphcmds.c:1732 -#, fuzzy, c-format -#| msgid "column \"%s\" of relation \"%s\" is not an identity column" +#: commands/propgraphcmds.c:1770 +#, c-format msgid "element \"%s\" of property graph \"%s\" is not an edge" -msgstr "Spalte »%s« von Relation »%s« ist keine Identitätsspalte" +msgstr "Element »%s« von Property-Graph »%s« ist keine Kante" #: commands/publicationcmds.c:134 libpq/auth-oauth.c:887 #: postmaster/postmaster.c:1145 postmaster/postmaster.c:1247 @@ -13560,7 +13601,7 @@ msgid "This operation requires the publication to be defined as FOR ALL TABLES/S msgstr "" #: commands/publicationcmds.c:1671 commands/publicationcmds.c:1711 -#: commands/publicationcmds.c:2245 utils/cache/lsyscache.c:3854 +#: commands/publicationcmds.c:2245 utils/cache/lsyscache.c:3995 #, c-format msgid "publication \"%s\" does not exist" msgstr "Publikation »%s« existiert nicht" @@ -13621,151 +13662,170 @@ msgstr "ungültiger Wert für Publikationsparameter »%s«: »%s«" msgid "Valid values are \"%s\" and \"%s\"." msgstr "Gültige Werte sind »%s« und »%s«." -#: commands/repack.c:259 +#: commands/repack.c:274 #, fuzzy, c-format #| msgid "This operation is not supported for views." msgid "CONCURRENTLY option not supported for %s" msgstr "Diese Operation wird für Sichten nicht unterstützt." -#: commands/repack.c:308 +#: commands/repack.c:328 #, fuzzy, c-format #| msgid "cannot execute MERGE on relation \"%s\"" msgid "cannot execute %s on multiple tables" msgstr "MERGE kann für Relation »%s« nicht ausgeführt werden" -#: commands/repack.c:324 +#: commands/repack.c:344 #, fuzzy, c-format #| msgid "This operation is not supported for partitioned tables." -msgid "REPACK (CONCURRENTLY) is not supported for partitioned tables" +msgid "%s is not supported for partitioned tables" msgstr "Diese Operation wird für partitionierte Tabellen nicht unterstützt." -#: commands/repack.c:325 +#: commands/repack.c:346 #, c-format msgid "Consider running the command on individual partitions." msgstr "" -#: commands/repack.c:330 -#, c-format -msgid "REPACK (CONCURRENTLY) requires an explicit table name" -msgstr "" +#: commands/repack.c:351 +#, fuzzy, c-format +#| msgid "%s requires a numeric value" +msgid "%s requires an explicit table name" +msgstr "%s erfordert einen numerischen Wert" -#: commands/repack.c:387 commands/repack.c:2421 +#: commands/repack.c:409 commands/repack.c:2500 #, c-format msgid "there is no previously clustered index for table \"%s\"" msgstr "es gibt keinen bereits geclusterten Index für Tabelle »%s«" #. translator: first %s is name of a SQL command, eg. REPACK -#: commands/repack.c:393 +#: commands/repack.c:415 #, fuzzy, c-format #| msgid "cannot create index on partitioned table \"%s\" concurrently" msgid "cannot execute %s on partitioned table \"%s\" USING INDEX with no index name" msgstr "kann Index für partitionierte Tabelle »%s« nicht nebenläufig erzeugen" #. translator: first %s is name of a SQL command, eg. REPACK -#: commands/repack.c:565 +#: commands/repack.c:587 #, fuzzy, c-format #| msgid "cannot cluster a shared catalog" msgid "cannot execute %s on a shared catalog" msgstr "globaler Katalog kann nicht geclustert werden" #. translator: first %s is name of a SQL command, eg. REPACK -#: commands/repack.c:582 commands/repack.c:2341 +#: commands/repack.c:604 commands/repack.c:2420 #, fuzzy, c-format #| msgid "cannot cluster temporary tables of other sessions" msgid "cannot execute %s on temporary tables of other sessions" msgstr "kann temporäre Tabellen anderer Sitzungen nicht clustern" -#: commands/repack.c:617 +#: commands/repack.c:639 #, c-format msgid "System catalogs can only be clustered by the index they're already clustered on, if any, unless \"%s\" is enabled." msgstr "" -#: commands/repack.c:764 commands/tablecmds.c:18797 +#: commands/repack.c:785 commands/tablecmds.c:19175 #, c-format msgid "\"%s\" is not an index for table \"%s\"" msgstr "»%s« ist kein Index für Tabelle »%s«" -#: commands/repack.c:772 +#: commands/repack.c:793 #, c-format msgid "cannot cluster on index \"%s\" because access method does not support clustering" msgstr "kann nicht anhand des Index »%s« clustern, weil die Indexmethode Clustern nicht unterstützt" -#: commands/repack.c:784 +#: commands/repack.c:805 #, c-format msgid "cannot cluster on partial index \"%s\"" msgstr "kann nicht anhand des partiellen Index »%s« clustern" -#: commands/repack.c:798 +#: commands/repack.c:819 #, c-format msgid "cannot cluster on invalid index \"%s\"" msgstr "kann nicht anhand des ungültigen Index »%s« clustern" -#: commands/repack.c:887 commands/repack.c:898 commands/repack.c:906 -#: commands/repack.c:915 +#: commands/repack.c:907 #, fuzzy, c-format -#| msgid "cannot lock relation \"%s\"" -msgid "cannot repack relation \"%s\"" -msgstr "kann Relation »%s« nicht sperren" +#| msgid "cannot execute %s in a read-only transaction" +msgid "cannot execute %s in this configuration" +msgstr "%s kann nicht in einer Read-Only-Transaktion ausgeführt werden" + +#: commands/repack.c:909 +#, fuzzy, c-format +#| msgid "Change \"wal_level\" to be \"replica\" or higher." +msgid "%s requires \"wal_level\" to be set to \"replica\" or higher." +msgstr "Ändern Sie »wal_level« in »replica« oder höher." + +#: commands/repack.c:916 commands/repack.c:928 commands/repack.c:937 +#: commands/repack.c:951 commands/repack.c:972 commands/repack.c:981 +#, fuzzy, c-format +#| msgid "cannot execute MERGE on relation \"%s\"" +msgid "cannot execute %s on relation \"%s\"" +msgstr "MERGE kann für Relation »%s« nicht ausgeführt werden" -#: commands/repack.c:889 +#: commands/repack.c:918 #, fuzzy, c-format #| msgid "WHERE CURRENT OF is not supported for this table type" -msgid "REPACK CONCURRENTLY is not supported for catalog relations." +msgid "%s is not supported for catalog relations." msgstr "WHERE CURRENT OF wird für diesen Tabellentyp nicht unterstützt" -#: commands/repack.c:900 +#: commands/repack.c:930 #, fuzzy, c-format #| msgid "MERGE is not supported for relations with rules." -msgid "REPACK CONCURRENTLY is not supported for TOAST relations" +msgid "%s is not supported for TOAST relations." msgstr "MERGE wird für Relationen mit Regeln nicht unterstützt." -#: commands/repack.c:908 -#, c-format -msgid "REPACK CONCURRENTLY is only allowed for permanent relations." -msgstr "" +#: commands/repack.c:939 +#, fuzzy, c-format +#| msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgid "%s is only allowed for permanent relations." +msgstr "ALTER SUBSCRIPTION mit Refresh ist für deaktivierte Subskriptionen nicht erlaubt" -#: commands/repack.c:917 +#: commands/repack.c:953 #, fuzzy, c-format -#| msgid "column \"%s\" is in index used as replica identity" -msgid "Relation \"%s\" has insufficient replication identity." -msgstr "Spalte »%s« ist in einem Index, der als Replik-Identität verwendet wird" +#| msgid "this build does not support compression with %s" +msgid "%s does not support tables with %s." +msgstr "diese Installation unterstützt keine Komprimierung mit %s" -#: commands/repack.c:933 +#: commands/repack.c:975 #, fuzzy, c-format -#| msgid "cannot open relation \"%s\"" -msgid "cannot process relation \"%s\"" -msgstr "kann Relation »%s« nicht öffnen" +#| msgid "XML does not support infinite date values." +msgid "%s does not support deferrable primary keys." +msgstr "XML unterstützt keine unendlichen Datumswerte." + +#: commands/repack.c:977 +#, c-format +msgid "Use ALTER TABLE ... REPLICA IDENTITY USING INDEX to designate another index as replica identity." +msgstr "" -#: commands/repack.c:935 +#: commands/repack.c:983 #, fuzzy, c-format #| msgid "table \"%s\" has no indexes to reindex" msgid "Relation \"%s\" has no identity index." msgstr "Tabelle »%s« hat keine zu reindizierenden Indexe" -#: commands/repack.c:1376 +#: commands/repack.c:1432 #, fuzzy, c-format #| msgid "clustering \"%s.%s\" using index scan on \"%s\"" msgid "repacking \"%s.%s\" using index scan on \"%s\"" msgstr "clustere »%s.%s« durch Index-Scan von »%s«" -#: commands/repack.c:1382 +#: commands/repack.c:1438 #, fuzzy, c-format #| msgid "clustering \"%s.%s\" using sequential scan and sort" msgid "repacking \"%s.%s\" using sequential scan and sort" msgstr "clustere »%s.%s« durch sequenziellen Scan und Sortieren" -#: commands/repack.c:1387 +#: commands/repack.c:1443 #, fuzzy, c-format #| msgid "analyzing \"%s.%s\" inheritance tree" msgid "repacking \"%s.%s\" in physical order" msgstr "analysiere Vererbungsbaum von »%s.%s«" -#: commands/repack.c:1419 +#: commands/repack.c:1475 #, c-format msgid "\"%s.%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" msgstr "»%s.%s«: %.0f entfernbare, %.0f nicht entfernbare Zeilenversionen in %u Seiten gefunden" -#: commands/repack.c:1424 +#: commands/repack.c:1480 #, c-format msgid "" "%.0f dead row versions cannot be removed yet.\n" @@ -13774,46 +13834,37 @@ msgstr "" "%.0f tote Zeilenversionen können noch nicht entfernt werden.\n" "%s." -#: commands/repack.c:2287 +#: commands/repack.c:2366 #, fuzzy, c-format #| msgid "permission denied to cluster \"%s\", skipping it" msgid "permission denied to execute %s on \"%s\", skipping it" msgstr "keine Berechtigung für Clustern von »%s«, wird übersprungen" -#: commands/repack.c:2323 commands/vacuum.c:351 +#: commands/repack.c:2402 commands/vacuum.c:351 #, c-format msgid "ANALYZE option must be specified when a column list is provided" msgstr "Option ANALYZE muss angegeben werden, wenn eine Spaltenliste angegeben ist" -#: commands/repack.c:2431 commands/tablecmds.c:16730 commands/tablecmds.c:18787 +#: commands/repack.c:2510 commands/tablecmds.c:17108 commands/tablecmds.c:19165 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "Index »%s« für Tabelle »%s« existiert nicht" -#: commands/repack.c:2627 -#, c-format -msgid "failed to apply concurrent UPDATE" -msgstr "" - -#: commands/repack.c:2663 -#, c-format -msgid "failed to apply concurrent DELETE" -msgstr "" - -#: commands/repack.c:2738 -#, c-format -msgid "insufficient number of attributes stored separately" -msgstr "" +#: commands/repack.c:2707 commands/repack.c:2745 +#, fuzzy, c-format +#| msgid "cannot alter constraint \"%s\" on relation \"%s\"" +msgid "could not apply concurrent %s on relation \"%s\"" +msgstr "Constraint »%s« von Relation »%s« kann nicht geändert werden" -#: commands/repack.c:3356 replication/logical/launcher.c:565 +#: commands/repack.c:3654 replication/logical/launcher.c:565 #, c-format msgid "out of background worker slots" msgstr "alle Slots für Background-Worker belegt" #. translator: %s is a GUC variable name -#: commands/repack.c:3357 replication/logical/launcher.c:468 -#: replication/logical/launcher.c:566 replication/slot.c:1818 -#: replication/slot.c:1838 storage/lmgr/lock.c:1051 storage/lmgr/lock.c:1089 +#: commands/repack.c:3655 replication/logical/launcher.c:468 +#: replication/logical/launcher.c:566 replication/slot.c:1814 +#: replication/slot.c:1834 storage/lmgr/lock.c:1051 storage/lmgr/lock.c:1089 #: storage/lmgr/lock.c:3009 storage/lmgr/lock.c:4386 storage/lmgr/lock.c:4451 #: storage/lmgr/lock.c:4801 storage/lmgr/predicate.c:2408 #: storage/lmgr/predicate.c:2423 storage/lmgr/predicate.c:3820 @@ -13821,23 +13872,29 @@ msgstr "alle Slots für Background-Worker belegt" msgid "You might need to increase \"%s\"." msgstr "Sie müssen möglicherweise »%s« erhöhen." -#: commands/repack.c:3413 +#: commands/repack.c:3707 #, fuzzy, c-format #| msgid "postmaster exited during a parallel transaction" msgid "postmaster exited during REPACK command" msgstr "Postmaster beendete während einer parallelen Transaktion" -#: commands/repack.c:3627 commands/repack.c:3629 +#: commands/repack.c:3934 commands/repack.c:3936 msgid "REPACK decoding worker" msgstr "" -#: commands/repack_worker.c:431 +#: commands/repack_worker.c:412 postmaster/walsummarizer.c:1051 +#, fuzzy, c-format +#| msgid "could not read WAL from timeline %u at %X/%X: %s" +msgid "could not read WAL from timeline %u at %X/%08X: %s" +msgstr "konnte WAL aus Zeitleiste %u bei %X/%X nicht lesen: %s" + +#: commands/repack_worker.c:429 #, fuzzy, c-format #| msgid "could not read WAL record at %X/%08X" msgid "could not read WAL record" msgstr "konnte WAL-Eintrag bei %X/%08X nicht lesen" -#: commands/repack_worker.c:478 +#: commands/repack_worker.c:477 #, c-format msgid "waiting for WAL failed" msgstr "" @@ -13997,8 +14054,8 @@ msgstr "Sequenz muss im selben Schema wie die verknüpfte Tabelle sein" msgid "cannot change ownership of identity sequence" msgstr "kann Eigentümer einer Identitätssequenz nicht ändern" -#: commands/sequence.c:1676 commands/tablecmds.c:16419 -#: commands/tablecmds.c:19248 +#: commands/sequence.c:1676 commands/tablecmds.c:16797 +#: commands/tablecmds.c:19626 #, c-format msgid "Sequence \"%s\" is linked to table \"%s\"." msgstr "Sequenz »%s« ist mit Tabelle »%s« verknüpft." @@ -14082,12 +14139,12 @@ msgstr "doppelter Spaltenname in Statistikdefinition" msgid "duplicate expression in statistics definition" msgstr "doppelter Ausdruck in Statistikdefinition" -#: commands/statscmds.c:684 commands/tablecmds.c:9051 +#: commands/statscmds.c:684 commands/tablecmds.c:9041 #, c-format msgid "statistics target %d is too low" msgstr "Statistikziel %d ist zu niedrig" -#: commands/statscmds.c:692 commands/tablecmds.c:9059 +#: commands/statscmds.c:692 commands/tablecmds.c:9049 #, c-format msgid "lowering statistics target to %d" msgstr "setze Statistikziel auf %d herab" @@ -14097,223 +14154,229 @@ msgstr "setze Statistikziel auf %d herab" msgid "statistics object \"%s.%s\" does not exist, skipping" msgstr "Statistikobjekt »%s.%s« existiert nicht, wird übersprungen" -#: commands/subscriptioncmds.c:381 replication/pgoutput/pgoutput.c:417 +#: commands/subscriptioncmds.c:363 +#, fuzzy, c-format +#| msgid "\"timeout\" must not be negative" +msgid "max_retention_duration cannot be negative" +msgstr "»timeout« darf nicht negativ sein" + +#: commands/subscriptioncmds.c:386 replication/pgoutput/pgoutput.c:417 #, c-format msgid "unrecognized origin value: \"%s\"" msgstr "unbekannter Origin-Wert: »%s«" -#: commands/subscriptioncmds.c:404 +#: commands/subscriptioncmds.c:409 #, c-format msgid "invalid WAL location (LSN): %s" msgstr "ungültige WAL-Position (LSN): %s" -#: commands/subscriptioncmds.c:437 +#: commands/subscriptioncmds.c:442 #, c-format msgid "unrecognized subscription parameter: \"%s\"" msgstr "unbekannter Subskriptionsparameter: »%s«" #. translator: both %s are strings of the form "option = value" -#: commands/subscriptioncmds.c:452 commands/subscriptioncmds.c:459 -#: commands/subscriptioncmds.c:466 commands/subscriptioncmds.c:488 -#: commands/subscriptioncmds.c:504 +#: commands/subscriptioncmds.c:457 commands/subscriptioncmds.c:464 +#: commands/subscriptioncmds.c:471 commands/subscriptioncmds.c:493 +#: commands/subscriptioncmds.c:509 #, c-format msgid "%s and %s are mutually exclusive options" msgstr "die Optionen %s und %s schließen einander aus" #. translator: both %s are strings of the form "option = value" -#: commands/subscriptioncmds.c:494 commands/subscriptioncmds.c:510 +#: commands/subscriptioncmds.c:499 commands/subscriptioncmds.c:515 #, c-format msgid "subscription with %s must also set %s" msgstr "Subskription mit %s muss auch %s setzen" -#: commands/subscriptioncmds.c:540 +#: commands/subscriptioncmds.c:571 #, c-format msgid "could not receive list of publications from the publisher: %s" msgstr "konnte Liste der Publikationen nicht vom Publikationsserver empfangen: %s" -#: commands/subscriptioncmds.c:574 +#: commands/subscriptioncmds.c:605 #, c-format msgid "publication %s does not exist on the publisher" msgid_plural "publications %s do not exist on the publisher" msgstr[0] "Publikation %s existiert auf dem Publikationsserver nicht" msgstr[1] "Publikationen %s existieren auf dem Publikationsserver nicht" -#: commands/subscriptioncmds.c:666 +#: commands/subscriptioncmds.c:697 #, c-format msgid "permission denied to create subscription" msgstr "keine Berechtigung, um Subskription zu erzeugen" -#: commands/subscriptioncmds.c:667 +#: commands/subscriptioncmds.c:698 #, c-format msgid "Only roles with privileges of the \"%s\" role may create subscriptions." msgstr "Nur Rollen mit den Privilegien der Rolle »%s« können Subskriptionen erzeugen." -#: commands/subscriptioncmds.c:870 commands/subscriptioncmds.c:1034 -#: commands/subscriptioncmds.c:1286 commands/subscriptioncmds.c:2138 +#: commands/subscriptioncmds.c:901 commands/subscriptioncmds.c:1065 +#: commands/subscriptioncmds.c:1317 commands/subscriptioncmds.c:2229 #, c-format msgid "subscription \"%s\" could not connect to the publisher: %s" msgstr "Subskription »%s« konnte nicht mit dem Publikationsserver verbinden: %s" -#: commands/subscriptioncmds.c:961 +#: commands/subscriptioncmds.c:992 #, c-format msgid "created replication slot \"%s\" on publisher" msgstr "Replikations-Slot »%s« wurde auf dem Publikationsserver erzeugt" -#: commands/subscriptioncmds.c:973 +#: commands/subscriptioncmds.c:1004 #, c-format msgid "subscription was created, but is not connected" msgstr "Subskription wurde erzeugt, ist aber nicht verbunden" -#: commands/subscriptioncmds.c:974 +#: commands/subscriptioncmds.c:1005 #, fuzzy, c-format #| msgid "To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription." msgid "To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications." msgstr "Um die Replikation einzuleiten, müssen Sie den Replikations-Slot manuell erzeugen, die Subskription aktivieren und die Subskription auffrischen." -#: commands/subscriptioncmds.c:1383 +#: commands/subscriptioncmds.c:1414 #, c-format msgid "cannot set option \"%s\" for enabled subscription" msgstr "für eine aktivierte Subskription kann Option »%s« nicht gesetzt werden" -#: commands/subscriptioncmds.c:1397 +#: commands/subscriptioncmds.c:1428 #, c-format msgid "cannot set option \"%s\" for a subscription that does not have a slot name" msgstr "Option »%s« kann nicht für eine Subskription ohne Slot-Name gesetzt werden" -#: commands/subscriptioncmds.c:1445 commands/subscriptioncmds.c:2215 -#: commands/subscriptioncmds.c:2648 utils/cache/lsyscache.c:3904 +#: commands/subscriptioncmds.c:1478 commands/subscriptioncmds.c:2345 +#: commands/subscriptioncmds.c:2758 utils/cache/lsyscache.c:4045 #, c-format msgid "subscription \"%s\" does not exist" msgstr "Subskription »%s« existiert nicht" -#: commands/subscriptioncmds.c:1520 +#: commands/subscriptioncmds.c:1614 #, c-format msgid "cannot set %s for enabled subscription" msgstr "für eine aktivierte Subskription kann nicht %s gesetzt werden" -#: commands/subscriptioncmds.c:1605 +#: commands/subscriptioncmds.c:1699 #, c-format msgid "\"slot_name\" and \"two_phase\" cannot be altered at the same time" msgstr "»slot_name« und »two_phase« können nicht gleichzeitig geändert werden" -#: commands/subscriptioncmds.c:1621 +#: commands/subscriptioncmds.c:1715 #, c-format msgid "cannot alter \"two_phase\" when logical replication worker is still running" msgstr "»two_phase« kann nicht geändert werden, wenn ein Replikationsarbeitsprozess noch läuft" -#: commands/subscriptioncmds.c:1622 commands/subscriptioncmds.c:1706 +#: commands/subscriptioncmds.c:1716 commands/subscriptioncmds.c:1800 #, c-format msgid "Try again after some time." msgstr "Versuchen Sie es nach einer Weile erneut." -#: commands/subscriptioncmds.c:1635 +#: commands/subscriptioncmds.c:1729 #, c-format msgid "cannot disable \"two_phase\" when prepared transactions exist" msgstr "»two_phase« kann nicht ausgeschaltet werden, wenn vorbereitete Transaktionen existieren" -#: commands/subscriptioncmds.c:1636 +#: commands/subscriptioncmds.c:1730 #, c-format msgid "Resolve these transactions and try again." msgstr "Lösen Sie diese Transaktionen auf und versuchen Sie erneut." -#: commands/subscriptioncmds.c:1705 +#: commands/subscriptioncmds.c:1799 #, fuzzy, c-format #| msgid "cannot alter \"two_phase\" when logical replication worker is still running" msgid "cannot alter retain_dead_tuples when logical replication worker is still running" msgstr "»two_phase« kann nicht geändert werden, wenn ein Replikationsarbeitsprozess noch läuft" -#: commands/subscriptioncmds.c:1778 +#: commands/subscriptioncmds.c:1872 #, c-format msgid "cannot enable subscription that does not have a slot name" msgstr "eine Subskription ohne Slot-Name kann nicht aktiviert werden" -#: commands/subscriptioncmds.c:1917 commands/subscriptioncmds.c:1968 +#: commands/subscriptioncmds.c:2015 commands/subscriptioncmds.c:2062 #, c-format msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" msgstr "ALTER SUBSCRIPTION mit Refresh ist für deaktivierte Subskriptionen nicht erlaubt" -#: commands/subscriptioncmds.c:1918 +#: commands/subscriptioncmds.c:2016 #, c-format msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." msgstr "Verwenden Sie ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." -#: commands/subscriptioncmds.c:1927 commands/subscriptioncmds.c:1982 +#: commands/subscriptioncmds.c:2025 commands/subscriptioncmds.c:2076 #, c-format msgid "ALTER SUBSCRIPTION with refresh and copy_data is not allowed when two_phase is enabled" msgstr "ALTER SUBSCRIPTION mit »refresh« und »copy_data« ist nicht erlaubt, wenn »two_phase« eingeschaltet ist" -#: commands/subscriptioncmds.c:1928 +#: commands/subscriptioncmds.c:2026 #, c-format msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION with refresh = false, or with copy_data = false, or use DROP/CREATE SUBSCRIPTION." msgstr "Verwenden Sie ALTER SUBSCRIPTION ... SET PUBLICATION mit refresh = false, oder mit copy_data = false, oder verwenden Sie DROP/CREATE SUBSCRIPTION." #. translator: %s is an SQL ALTER command -#: commands/subscriptioncmds.c:1984 +#: commands/subscriptioncmds.c:2078 #, c-format msgid "Use %s with refresh = false, or with copy_data = false, or use DROP/CREATE SUBSCRIPTION." msgstr "Verwenden Sie %s mit refresh = false, oder mit copy_data = false, oder verwenden Sie DROP/CREATE SUBSCRIPTION." -#: commands/subscriptioncmds.c:2006 commands/subscriptioncmds.c:2047 +#: commands/subscriptioncmds.c:2100 commands/subscriptioncmds.c:2138 #, fuzzy, c-format #| msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" msgid "%s is not allowed for disabled subscriptions" msgstr "ALTER SUBSCRIPTION mit Refresh ist für deaktivierte Subskriptionen nicht erlaubt" -#: commands/subscriptioncmds.c:2032 +#: commands/subscriptioncmds.c:2123 #, fuzzy, c-format #| msgid "ALTER SUBSCRIPTION ... REFRESH with copy_data is not allowed when two_phase is enabled" msgid "ALTER SUBSCRIPTION ... REFRESH PUBLICATION with copy_data is not allowed when two_phase is enabled" msgstr "ALTER SUBSCRIPTION ... REFRESH mit »copy_data« ist nicht erlaubt, wenn »two_phase« eingeschaltet ist" -#: commands/subscriptioncmds.c:2033 +#: commands/subscriptioncmds.c:2124 #, fuzzy, c-format #| msgid "Use ALTER SUBSCRIPTION ... REFRESH with copy_data = false, or use DROP/CREATE SUBSCRIPTION." msgid "Use ALTER SUBSCRIPTION ... REFRESH PUBLICATION with copy_data = false, or use DROP/CREATE SUBSCRIPTION." msgstr "Verwenden Sie ALTER SUBSCRIPTION ... REFRESH mit copy_data = false, oder verwenden Sie DROP/CREATE SUBSCRIPTION." -#: commands/subscriptioncmds.c:2081 +#: commands/subscriptioncmds.c:2170 #, fuzzy, c-format #| msgid "skip WAL location (LSN %X/%X) must be greater than origin LSN %X/%X" msgid "skip WAL location (LSN %X/%08X) must be greater than origin LSN %X/%08X" msgstr "zu überspringende WAL-Position (LSN %X/%X) muss größer als Origin-LSN %X/%X sein" -#: commands/subscriptioncmds.c:2219 +#: commands/subscriptioncmds.c:2349 #, c-format msgid "subscription \"%s\" does not exist, skipping" msgstr "Subskription »%s« existiert nicht, wird übersprungen" -#: commands/subscriptioncmds.c:2517 +#: commands/subscriptioncmds.c:2627 #, c-format msgid "dropped replication slot \"%s\" on publisher" msgstr "Replikations-Slot »%s« auf dem Publikationsserver wurde gelöscht" -#: commands/subscriptioncmds.c:2526 commands/subscriptioncmds.c:2534 +#: commands/subscriptioncmds.c:2636 commands/subscriptioncmds.c:2644 #, c-format msgid "could not drop replication slot \"%s\" on publisher: %s" msgstr "konnte Replikations-Slot »%s« auf dem Publikationsserver nicht löschen: %s" -#: commands/subscriptioncmds.c:2604 +#: commands/subscriptioncmds.c:2714 #, fuzzy, c-format #| msgid "user mapping for \"%s\" does not exist for server \"%s\"" msgid "new subscription owner \"%s\" does not have permission on foreign server \"%s\"" msgstr "Benutzerabbildung für »%s« existiert nicht für Server »%s«" -#: commands/subscriptioncmds.c:2680 +#: commands/subscriptioncmds.c:2790 #, c-format msgid "subscription with OID %u does not exist" msgstr "Subskription mit OID %u existiert nicht" -#: commands/subscriptioncmds.c:2790 commands/subscriptioncmds.c:3169 +#: commands/subscriptioncmds.c:2905 commands/subscriptioncmds.c:3289 #, c-format msgid "could not receive list of replicated tables from the publisher: %s" msgstr "konnte Liste der replizierten Tabellen nicht vom Publikationsserver empfangen: %s" -#: commands/subscriptioncmds.c:2829 commands/subscriptioncmds.c:2944 +#: commands/subscriptioncmds.c:2944 commands/subscriptioncmds.c:3064 #, c-format msgid "subscription \"%s\" requested copy_data with origin = NONE but might copy data that had a different origin" msgstr "Subskription »%s« verlangte copy_data mit origin = NONE, aber könnte Daten kopieren, die einen anderen Origin hatten" -#: commands/subscriptioncmds.c:2831 commands/subscriptioncmds.c:2840 +#: commands/subscriptioncmds.c:2946 commands/subscriptioncmds.c:2955 #, fuzzy, c-format #| msgid "The subscription being created subscribes to a publication (%s) that contains tables that are written to by other subscriptions." #| msgid_plural "The subscription being created subscribes to publications (%s) that contain tables that are written to by other subscriptions." @@ -14322,28 +14385,28 @@ msgid_plural "The subscription subscribes to publications (%s) that contain tabl msgstr[0] "Die zu erzeugende Subskription hat eine Publikation (%s) abonniert, die Tabellen enthält, in die von anderen Subskriptionen geschrieben wird." msgstr[1] "Die zu erzeugende Subskription hat Publikationen (%s) abonniert, die Tabellen enthalten, in die von anderen Subskriptionen geschrieben wird." -#: commands/subscriptioncmds.c:2834 +#: commands/subscriptioncmds.c:2949 #, c-format msgid "Verify that initial data copied from the publisher tables did not come from other origins." msgstr "Überprüfen Sie, dass die von den publizierten Tabellen kopierten initialen Daten nicht von anderen Origins kamen." -#: commands/subscriptioncmds.c:2838 +#: commands/subscriptioncmds.c:2953 #, c-format msgid "subscription \"%s\" enabled retain_dead_tuples but might not reliably detect conflicts for changes from different origins" msgstr "" -#: commands/subscriptioncmds.c:2843 +#: commands/subscriptioncmds.c:2958 #, c-format msgid "Consider using origin = NONE or disabling retain_dead_tuples." msgstr "" -#: commands/subscriptioncmds.c:2912 +#: commands/subscriptioncmds.c:3032 #, fuzzy, c-format #| msgid "could not receive list of replicated tables from the publisher: %s" msgid "could not receive list of replicated sequences from the publisher: %s" msgstr "konnte Liste der replizierten Tabellen nicht vom Publikationsserver empfangen: %s" -#: commands/subscriptioncmds.c:2946 +#: commands/subscriptioncmds.c:3066 #, fuzzy, c-format #| msgid "The subscription being created subscribes to a publication (%s) that contains tables that are written to by other subscriptions." #| msgid_plural "The subscription being created subscribes to publications (%s) that contain tables that are written to by other subscriptions." @@ -14352,98 +14415,98 @@ msgid_plural "The subscription subscribes to publications (%s) that contain sequ msgstr[0] "Die zu erzeugende Subskription hat eine Publikation (%s) abonniert, die Tabellen enthält, in die von anderen Subskriptionen geschrieben wird." msgstr[1] "Die zu erzeugende Subskription hat Publikationen (%s) abonniert, die Tabellen enthalten, in die von anderen Subskriptionen geschrieben wird." -#: commands/subscriptioncmds.c:2949 +#: commands/subscriptioncmds.c:3069 #, fuzzy, c-format #| msgid "Verify that initial data copied from the publisher tables did not come from other origins." msgid "Verify that initial data copied from the publisher sequences did not come from other origins." msgstr "Überprüfen Sie, dass die von den publizierten Tabellen kopierten initialen Daten nicht von anderen Origins kamen." -#: commands/subscriptioncmds.c:2979 +#: commands/subscriptioncmds.c:3099 #, c-format msgid "cannot enable retain_dead_tuples if the publisher is running a version earlier than PostgreSQL 19" msgstr "" -#: commands/subscriptioncmds.c:2986 +#: commands/subscriptioncmds.c:3106 #, fuzzy, c-format #| msgid "could not obtain recovery progress: %s" msgid "could not obtain recovery progress from the publisher: %s" msgstr "konnte Recovery-Fortschritt nicht ermitteln: %s" -#: commands/subscriptioncmds.c:2998 +#: commands/subscriptioncmds.c:3118 #, c-format msgid "cannot enable retain_dead_tuples if the publisher is in recovery" msgstr "" -#: commands/subscriptioncmds.c:3042 +#: commands/subscriptioncmds.c:3162 #, fuzzy, c-format #| msgid "\"wal_level\" is insufficient to publish logical changes" msgid "\"wal_level\" is insufficient to create the replication slot required by retain_dead_tuples" msgstr "»wal_level« ist nicht ausreichend, um logische Veränderungen zu publizieren" -#: commands/subscriptioncmds.c:3048 +#: commands/subscriptioncmds.c:3168 #, c-format msgid "commit timestamp and origin data required for detecting conflicts won't be retained" msgstr "" -#: commands/subscriptioncmds.c:3049 +#: commands/subscriptioncmds.c:3169 #, c-format msgid "Consider setting \"%s\" to true." msgstr "" -#: commands/subscriptioncmds.c:3055 +#: commands/subscriptioncmds.c:3175 #, c-format msgid "deleted rows to detect conflicts would not be removed until the subscription is enabled" msgstr "" -#: commands/subscriptioncmds.c:3057 +#: commands/subscriptioncmds.c:3177 #, fuzzy, c-format #| msgid "Consider using tablespaces instead." msgid "Consider setting %s to false." msgstr "Verwenden Sie stattdessen Tablespaces." -#: commands/subscriptioncmds.c:3064 +#: commands/subscriptioncmds.c:3184 #, c-format msgid "max_retention_duration is ineffective when retain_dead_tuples is disabled" msgstr "" -#: commands/subscriptioncmds.c:3197 replication/logical/tablesync.c:851 +#: commands/subscriptioncmds.c:3317 replication/logical/tablesync.c:851 #: replication/pgoutput/pgoutput.c:1191 #, c-format msgid "cannot use different column lists for table \"%s.%s\" in different publications" msgstr "für Tabelle »%s.%s« können nicht verschiedene Spaltenlisten für verschiedene Publikationen verwendet werden" -#: commands/subscriptioncmds.c:3247 +#: commands/subscriptioncmds.c:3367 #, c-format msgid "could not connect to publisher when attempting to drop replication slot \"%s\": %s" msgstr "konnte beim Versuch den Replikations-Slot »%s« zu löschen nicht mit dem Publikationsserver verbinden: %s" #. translator: %s is an SQL ALTER command -#: commands/subscriptioncmds.c:3250 +#: commands/subscriptioncmds.c:3370 #, c-format msgid "Use %s to disable the subscription, and then use %s to disassociate it from the slot." msgstr "Verwenden Sie %s, um die Subskription zu deaktivieren, und dann %s, um sie vom Slot zu trennen." -#: commands/subscriptioncmds.c:3281 +#: commands/subscriptioncmds.c:3401 #, c-format msgid "publication name \"%s\" used more than once" msgstr "Publikationsname »%s« mehrmals angegeben" -#: commands/subscriptioncmds.c:3325 +#: commands/subscriptioncmds.c:3445 #, c-format msgid "publication \"%s\" is already in subscription \"%s\"" msgstr "Publikation »%s« ist bereits in Subskription »%s«" -#: commands/subscriptioncmds.c:3339 +#: commands/subscriptioncmds.c:3459 #, c-format msgid "publication \"%s\" is not in subscription \"%s\"" msgstr "Publikation »%s« ist nicht in Subskription »%s«" -#: commands/subscriptioncmds.c:3350 +#: commands/subscriptioncmds.c:3470 #, c-format msgid "cannot drop all the publications from a subscription" msgstr "kann nicht alle Publikationen von einer Subskription löschen" -#: commands/subscriptioncmds.c:3407 +#: commands/subscriptioncmds.c:3527 #, c-format msgid "%s requires a Boolean value or \"parallel\"" msgstr "%s erfordert einen Boole’schen Wert oder »parallel«" @@ -14504,8 +14567,8 @@ msgstr "materialisierte Sicht »%s« existiert nicht, wird übersprungen" msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." msgstr "Verwenden Sie DROP MATERIALIZED VIEW, um eine materialisierte Sicht zu löschen." -#: commands/tablecmds.c:286 commands/tablecmds.c:310 commands/tablecmds.c:21939 -#: parser/parse_utilcmd.c:2430 +#: commands/tablecmds.c:286 commands/tablecmds.c:310 commands/tablecmds.c:22310 +#: parser/parse_utilcmd.c:2434 #, c-format msgid "index \"%s\" does not exist" msgstr "Index »%s« existiert nicht" @@ -14528,8 +14591,8 @@ msgstr "»%s« ist kein Typ" msgid "Use DROP TYPE to remove a type." msgstr "Verwenden Sie DROP TYPE, um einen Typen zu löschen." -#: commands/tablecmds.c:298 commands/tablecmds.c:16257 -#: commands/tablecmds.c:18950 +#: commands/tablecmds.c:298 commands/tablecmds.c:16635 +#: commands/tablecmds.c:19328 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "Fremdtabelle »%s« existiert nicht" @@ -14544,1437 +14607,1431 @@ msgid "Use DROP FOREIGN TABLE to remove a foreign table." msgstr "Verwenden Sie DROP FOREIGN TABLE, um eine Fremdtabelle zu löschen." #: commands/tablecmds.c:316 -#, fuzzy, c-format -#| msgid "portal \"%s\" does not exist" +#, c-format msgid "property graph \"%s\" does not exist" -msgstr "Portal »%s« existiert nicht" +msgstr "Property-Graph »%s« existiert nicht" #: commands/tablecmds.c:317 -#, fuzzy, c-format -#| msgid "operator %s does not exist, skipping" +#, c-format msgid "property graph \"%s\" does not exist, skipping" -msgstr "Operator %s existiert nicht, wird übersprungen" +msgstr "Property-Graph »%s« existiert nicht, wird übersprungen" #: commands/tablecmds.c:319 -#, fuzzy -#| msgid "Use DROP TYPE to remove a type." msgid "Use DROP PROPERTY GRAPH to remove a property graph." -msgstr "Verwenden Sie DROP TYPE, um einen Typen zu löschen." +msgstr "Verwenden Sie DROP PROPERTY GRAPH, um einen Property-Graph zu löschen." -#: commands/tablecmds.c:849 +#: commands/tablecmds.c:857 #, c-format msgid "ON COMMIT can only be used on temporary tables" msgstr "ON COMMIT kann nur mit temporären Tabellen verwendet werden" -#: commands/tablecmds.c:866 +#: commands/tablecmds.c:874 #, c-format msgid "partitioned tables cannot be unlogged" msgstr "partitionierte Tabellen können nicht ungeloggt sein" -#: commands/tablecmds.c:886 +#: commands/tablecmds.c:894 #, c-format msgid "cannot create temporary table within security-restricted operation" msgstr "kann temporäre Tabelle nicht in einer sicherheitsbeschränkten Operation erzeugen" -#: commands/tablecmds.c:922 commands/tablecmds.c:17679 +#: commands/tablecmds.c:930 commands/tablecmds.c:18057 #, c-format msgid "relation \"%s\" would be inherited from more than once" msgstr "von der Relation »%s« würde mehrmals geerbt werden" -#: commands/tablecmds.c:1182 +#: commands/tablecmds.c:1190 #, c-format msgid "\"%s\" is not partitioned" msgstr "»%s« ist nicht partitioniert" -#: commands/tablecmds.c:1276 +#: commands/tablecmds.c:1284 #, c-format msgid "cannot partition using more than %d columns" msgstr "Partitionierung kann nicht mehr als %d Spalten verwenden" -#: commands/tablecmds.c:1332 +#: commands/tablecmds.c:1340 #, c-format msgid "cannot create foreign partition of partitioned table \"%s\"" msgstr "kann keine Fremdpartition der partitionierten Tabelle »%s« erzeugen" -#: commands/tablecmds.c:1334 +#: commands/tablecmds.c:1342 #, c-format msgid "Table \"%s\" contains indexes that are unique." msgstr "Tabelle »%s« enthält Unique Indexe." -#: commands/tablecmds.c:1474 commands/tablecmds.c:15234 +#: commands/tablecmds.c:1482 commands/tablecmds.c:15444 #, c-format msgid "too many array dimensions" msgstr "zu viele Array-Dimensionen" -#: commands/tablecmds.c:1479 parser/parse_clause.c:776 -#: parser/parse_relation.c:1918 +#: commands/tablecmds.c:1487 parser/parse_clause.c:778 +#: parser/parse_relation.c:1950 #, c-format msgid "column \"%s\" cannot be declared SETOF" msgstr "Spalte »%s« kann nicht als SETOF deklariert werden" -#: commands/tablecmds.c:1610 +#: commands/tablecmds.c:1618 #, c-format msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" msgstr "DROP INDEX CONCURRENTLY unterstützt das Löschen von mehreren Objekten nicht" -#: commands/tablecmds.c:1614 +#: commands/tablecmds.c:1622 #, c-format msgid "DROP INDEX CONCURRENTLY does not support CASCADE" msgstr "DROP INDEX CONCURRENTLY unterstützt kein CASCADE" -#: commands/tablecmds.c:1722 +#: commands/tablecmds.c:1730 #, c-format msgid "cannot drop partitioned index \"%s\" concurrently" msgstr "kann partitionierten Index »%s« nicht nebenläufig löschen" -#: commands/tablecmds.c:2010 +#: commands/tablecmds.c:2018 #, c-format msgid "cannot truncate only a partitioned table" msgstr "kann nicht nur eine partitionierte Tabelle leeren" -#: commands/tablecmds.c:2011 +#: commands/tablecmds.c:2019 #, c-format msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." msgstr "Lassen Sie das Schlüsselwort ONLY weg oder wenden Sie TRUNCATE ONLY direkt auf die Partitionen an." -#: commands/tablecmds.c:2084 +#: commands/tablecmds.c:2092 #, c-format msgid "truncate cascades to table \"%s\"" msgstr "Truncate-Vorgang leert ebenfalls Tabelle »%s«" -#: commands/tablecmds.c:2445 +#: commands/tablecmds.c:2453 #, c-format msgid "cannot truncate foreign table \"%s\"" msgstr "kann Fremdtabelle »%s« nicht leeren" -#: commands/tablecmds.c:2505 +#: commands/tablecmds.c:2513 #, c-format msgid "cannot truncate temporary tables of other sessions" msgstr "kann temporäre Tabellen anderer Sitzungen nicht leeren" -#: commands/tablecmds.c:2743 commands/tablecmds.c:17573 +#: commands/tablecmds.c:2751 commands/tablecmds.c:17951 #, c-format msgid "cannot inherit from partitioned table \"%s\"" msgstr "von partitionierter Tabelle »%s« kann nicht geerbt werden" -#: commands/tablecmds.c:2748 +#: commands/tablecmds.c:2756 #, c-format msgid "cannot inherit from partition \"%s\"" msgstr "von Partition »%s« kann nicht geerbt werden" -#: commands/tablecmds.c:2756 parser/parse_utilcmd.c:2701 -#: parser/parse_utilcmd.c:2895 +#: commands/tablecmds.c:2764 parser/parse_utilcmd.c:2705 +#: parser/parse_utilcmd.c:2899 #, c-format msgid "inherited relation \"%s\" is not a table or foreign table" msgstr "geerbte Relation »%s« ist keine Tabelle oder Fremdtabelle" -#: commands/tablecmds.c:2768 commands/tablecmds.c:22801 +#: commands/tablecmds.c:2776 commands/tablecmds.c:23173 #, c-format msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" msgstr "eine temporäre Relation kann nicht als Partition der permanenten Relation »%s« erzeugt werden" -#: commands/tablecmds.c:2777 commands/tablecmds.c:17554 +#: commands/tablecmds.c:2785 commands/tablecmds.c:17932 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "von temporärer Relation »%s« kann nicht geerbt werden" -#: commands/tablecmds.c:2786 commands/tablecmds.c:17561 +#: commands/tablecmds.c:2794 commands/tablecmds.c:17939 #, c-format msgid "cannot inherit from temporary relation of another session" msgstr "von temporärer Relation einer anderen Sitzung kann nicht geerbt werden" -#: commands/tablecmds.c:2941 commands/tablecmds.c:2995 -#: commands/tablecmds.c:14917 parser/parse_utilcmd.c:1438 +#: commands/tablecmds.c:2949 commands/tablecmds.c:3003 +#: commands/tablecmds.c:15127 parser/parse_utilcmd.c:1438 #: parser/parse_utilcmd.c:1482 parser/parse_utilcmd.c:1914 #: parser/parse_utilcmd.c:2026 #, c-format msgid "cannot convert whole-row table reference" msgstr "kann Verweis auf ganze Zeile der Tabelle nicht umwandeln" -#: commands/tablecmds.c:2942 parser/parse_utilcmd.c:1439 +#: commands/tablecmds.c:2950 parser/parse_utilcmd.c:1439 #, c-format msgid "Generation expression for column \"%s\" contains a whole-row reference to table \"%s\"." msgstr "Generierungsausdruck für Spalte »%s« enthält einen Verweis auf die ganze Zeile der Tabelle »%s«." -#: commands/tablecmds.c:2996 parser/parse_utilcmd.c:1483 +#: commands/tablecmds.c:3004 parser/parse_utilcmd.c:1483 #, c-format msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." msgstr "Constraint »%s« enthält einen Verweis auf die ganze Zeile der Tabelle »%s«." -#: commands/tablecmds.c:3118 commands/tablecmds.c:3412 +#: commands/tablecmds.c:3126 commands/tablecmds.c:3420 #, c-format msgid "column \"%s\" inherits from generated column but specifies default" msgstr "Spalte »%s« erbt von einer generierten Spalte aber hat einen Vorgabewert angegeben" -#: commands/tablecmds.c:3123 commands/tablecmds.c:3417 +#: commands/tablecmds.c:3131 commands/tablecmds.c:3425 #, c-format msgid "column \"%s\" inherits from generated column but specifies identity" msgstr "Spalte »%s« erbt von einer generierten Spalte aber ist als Identitätsspalte definiert" -#: commands/tablecmds.c:3131 commands/tablecmds.c:3425 +#: commands/tablecmds.c:3139 commands/tablecmds.c:3433 #, c-format msgid "child column \"%s\" specifies generation expression" msgstr "abgeleitete Spalte »%s« gibt einen Generierungsausdruck an" -#: commands/tablecmds.c:3133 commands/tablecmds.c:3427 +#: commands/tablecmds.c:3141 commands/tablecmds.c:3435 #, c-format msgid "A child table column cannot be generated unless its parent column is." msgstr "Eine Spalte einer abgeleiteten Tabelle kann nur generiert sein, wenn die Spalte in der Elterntabelle es auch ist." -#: commands/tablecmds.c:3139 commands/tablecmds.c:3433 -#: commands/tablecmds.c:17841 +#: commands/tablecmds.c:3147 commands/tablecmds.c:3441 +#: commands/tablecmds.c:18219 #, c-format msgid "column \"%s\" inherits from generated column of different kind" msgstr "Spalte »%s« erbt von einer generierten Spalte einer anderen Art" -#: commands/tablecmds.c:3141 commands/tablecmds.c:3435 -#: commands/tablecmds.c:17842 +#: commands/tablecmds.c:3149 commands/tablecmds.c:3443 +#: commands/tablecmds.c:18220 #, c-format msgid "Parent column is %s, child column is %s." msgstr "Spalte in Elterntabelle ist %s, Spalte in abgeleiteter Tabelle ist %s." -#: commands/tablecmds.c:3188 +#: commands/tablecmds.c:3196 #, c-format msgid "column \"%s\" inherits conflicting generation expressions" msgstr "Spalte »%s« erbt widersprüchliche Generierungsausdrücke" -#: commands/tablecmds.c:3190 +#: commands/tablecmds.c:3198 #, c-format msgid "To resolve the conflict, specify a generation expression explicitly." msgstr "Um den Konflikt zu lösen, geben Sie einen Generierungsausdruck ausdrücklich an." -#: commands/tablecmds.c:3194 +#: commands/tablecmds.c:3202 #, c-format msgid "column \"%s\" inherits conflicting default values" msgstr "Spalte »%s« erbt widersprüchliche Vorgabewerte" -#: commands/tablecmds.c:3196 +#: commands/tablecmds.c:3204 #, c-format msgid "To resolve the conflict, specify a default explicitly." msgstr "Um den Konflikt zu lösen, geben Sie einen Vorgabewert ausdrücklich an." -#: commands/tablecmds.c:3263 +#: commands/tablecmds.c:3271 #, c-format msgid "check constraint name \"%s\" appears multiple times but with different expressions" msgstr "Check-Constraint-Name »%s« erscheint mehrmals, aber mit unterschiedlichen Ausdrücken" -#: commands/tablecmds.c:3316 +#: commands/tablecmds.c:3324 #, c-format msgid "merging column \"%s\" with inherited definition" msgstr "Spalte »%s« wird mit geerbter Definition zusammengeführt" -#: commands/tablecmds.c:3320 +#: commands/tablecmds.c:3328 #, c-format msgid "moving and merging column \"%s\" with inherited definition" msgstr "Spalte »%s« wird verschoben und mit geerbter Definition zusammengeführt" -#: commands/tablecmds.c:3321 +#: commands/tablecmds.c:3329 #, c-format msgid "User-specified column moved to the position of the inherited column." msgstr "Benutzerdefinierte Spalte wurde auf die Position der geerbten Spalte verschoben." -#: commands/tablecmds.c:3333 +#: commands/tablecmds.c:3341 #, c-format msgid "column \"%s\" has a type conflict" msgstr "für Spalte »%s« besteht ein Typkonflikt" -#: commands/tablecmds.c:3335 commands/tablecmds.c:3369 -#: commands/tablecmds.c:3385 commands/tablecmds.c:3501 -#: commands/tablecmds.c:3529 commands/tablecmds.c:3545 -#: parser/parse_coerce.c:2191 parser/parse_coerce.c:2211 -#: parser/parse_coerce.c:2231 parser/parse_coerce.c:2252 -#: parser/parse_coerce.c:2307 parser/parse_coerce.c:2341 -#: parser/parse_coerce.c:2417 parser/parse_coerce.c:2448 -#: parser/parse_coerce.c:2487 parser/parse_coerce.c:2554 +#: commands/tablecmds.c:3343 commands/tablecmds.c:3377 +#: commands/tablecmds.c:3393 commands/tablecmds.c:3509 +#: commands/tablecmds.c:3537 commands/tablecmds.c:3553 +#: parser/parse_coerce.c:2190 parser/parse_coerce.c:2210 +#: parser/parse_coerce.c:2230 parser/parse_coerce.c:2251 +#: parser/parse_coerce.c:2306 parser/parse_coerce.c:2340 +#: parser/parse_coerce.c:2416 parser/parse_coerce.c:2447 +#: parser/parse_coerce.c:2486 parser/parse_coerce.c:2553 #: parser/parse_param.c:224 #, c-format msgid "%s versus %s" msgstr "%s gegen %s" -#: commands/tablecmds.c:3347 +#: commands/tablecmds.c:3355 #, c-format msgid "column \"%s\" has a collation conflict" msgstr "für Spalte »%s« besteht ein Sortierfolgenkonflikt" -#: commands/tablecmds.c:3349 commands/tablecmds.c:3515 -#: commands/tablecmds.c:7377 parser/parse_expr.c:4819 +#: commands/tablecmds.c:3357 commands/tablecmds.c:3523 +#: commands/tablecmds.c:7385 parser/parse_expr.c:4914 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "»%s« gegen »%s«" -#: commands/tablecmds.c:3367 +#: commands/tablecmds.c:3375 #, c-format msgid "column \"%s\" has a storage parameter conflict" msgstr "für Spalte »%s« besteht ein Konflikt bei einem Storage-Parameter" -#: commands/tablecmds.c:3383 commands/tablecmds.c:3543 +#: commands/tablecmds.c:3391 commands/tablecmds.c:3551 #, c-format msgid "column \"%s\" has a compression method conflict" msgstr "für Spalte »%s« besteht ein Komprimierungsmethodenkonflikt" -#: commands/tablecmds.c:3487 +#: commands/tablecmds.c:3495 #, c-format msgid "merging multiple inherited definitions of column \"%s\"" msgstr "geerbte Definitionen von Spalte »%s« werden zusammengeführt" -#: commands/tablecmds.c:3499 +#: commands/tablecmds.c:3507 #, c-format msgid "inherited column \"%s\" has a type conflict" msgstr "geerbte Spalte »%s« hat Typkonflikt" -#: commands/tablecmds.c:3513 +#: commands/tablecmds.c:3521 #, c-format msgid "inherited column \"%s\" has a collation conflict" msgstr "geerbte Spalte »%s« hat Sortierfolgenkonflikt" -#: commands/tablecmds.c:3527 +#: commands/tablecmds.c:3535 #, c-format msgid "inherited column \"%s\" has a storage parameter conflict" msgstr "geerbte Spalte »%s« hat einen Konflikt bei einem Storage-Parameter" -#: commands/tablecmds.c:3555 +#: commands/tablecmds.c:3563 #, c-format msgid "inherited column \"%s\" has a generation conflict" msgstr "geerbte Spalte »%s« hat einen Generierungskonflikt" -#: commands/tablecmds.c:3786 +#: commands/tablecmds.c:3794 #, c-format msgid "cannot move temporary tables of other sessions" msgstr "temporäre Tabellen anderer Sitzungen können nicht verschoben werden" -#: commands/tablecmds.c:3859 +#: commands/tablecmds.c:3867 #, c-format msgid "cannot rename column of typed table" msgstr "Spalte einer getypten Tabelle kann nicht umbenannt werden" -#: commands/tablecmds.c:3878 +#: commands/tablecmds.c:3886 #, c-format msgid "cannot rename columns of relation \"%s\"" msgstr "Spalten von Relation »%s« können nicht umbenannt werden" -#: commands/tablecmds.c:3973 +#: commands/tablecmds.c:3981 #, c-format msgid "inherited column \"%s\" must be renamed in child tables too" msgstr "vererbte Spalte »%s« muss ebenso in den abgeleiteten Tabellen umbenannt werden" -#: commands/tablecmds.c:4005 +#: commands/tablecmds.c:4013 #, c-format msgid "cannot rename system column \"%s\"" msgstr "Systemspalte »%s« kann nicht umbenannt werden" -#: commands/tablecmds.c:4020 +#: commands/tablecmds.c:4028 #, c-format msgid "cannot rename inherited column \"%s\"" msgstr "kann vererbte Spalte »%s« nicht umbenennen" -#: commands/tablecmds.c:4175 +#: commands/tablecmds.c:4183 #, c-format msgid "inherited constraint \"%s\" must be renamed in child tables too" msgstr "vererbter Constraint »%s« muss ebenso in den abgeleiteten Tabellen umbenannt werden" -#: commands/tablecmds.c:4182 +#: commands/tablecmds.c:4190 #, c-format msgid "cannot rename inherited constraint \"%s\"" msgstr "kann vererbten Constraint »%s« nicht umbenennen" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:4482 +#: commands/tablecmds.c:4490 #, c-format msgid "cannot %s \"%s\" because it is being used by active queries in this session" msgstr "%s mit Relation »%s« nicht möglich, weil sie von aktiven Anfragen in dieser Sitzung verwendet wird" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:4491 +#: commands/tablecmds.c:4499 #, c-format msgid "cannot %s \"%s\" because it has pending trigger events" msgstr "%s mit Relation »%s« nicht möglich, weil es anstehende Trigger-Ereignisse dafür gibt" -#: commands/tablecmds.c:4517 +#: commands/tablecmds.c:4525 #, c-format msgid "cannot alter temporary tables of other sessions" msgstr "kann temporäre Tabellen anderer Sitzungen nicht ändern" -#: commands/tablecmds.c:4986 +#: commands/tablecmds.c:4994 #, c-format msgid "cannot alter partition \"%s\" with an incomplete detach" msgstr "kann Partition »%s« mit einer unvollständigen Abtrennoperation nicht ändern" -#: commands/tablecmds.c:5215 +#: commands/tablecmds.c:5223 #, c-format msgid "cannot change persistence setting twice" msgstr "Persistenzeinstellung kann nicht zweimal geändert werden" -#: commands/tablecmds.c:5232 +#: commands/tablecmds.c:5240 #, c-format msgid "cannot have multiple SET ACCESS METHOD subcommands" msgstr "mehrere SET ACCESS METHOD Unterbefehle sind ungültig" -#: commands/tablecmds.c:5988 +#: commands/tablecmds.c:5996 #, c-format msgid "cannot rewrite system relation \"%s\"" msgstr "Systemrelation »%s« kann nicht neu geschrieben werden" -#: commands/tablecmds.c:5994 +#: commands/tablecmds.c:6002 #, c-format msgid "cannot rewrite table \"%s\" used as a catalog table" msgstr "Tabelle »%s«, die als Katalogtabelle verwendet wird, kann nicht neu geschrieben werden" -#: commands/tablecmds.c:6006 +#: commands/tablecmds.c:6014 #, c-format msgid "cannot rewrite temporary tables of other sessions" msgstr "kann temporäre Tabellen anderer Sitzungen nicht neu schreiben" -#: commands/tablecmds.c:6544 commands/tablecmds.c:6564 +#: commands/tablecmds.c:6552 commands/tablecmds.c:6572 #, c-format msgid "column \"%s\" of relation \"%s\" contains null values" msgstr "Spalte »%s« von Relation »%s« enthält NULL-Werte" -#: commands/tablecmds.c:6581 commands/tablecmds.c:22476 +#: commands/tablecmds.c:6589 commands/tablecmds.c:22847 #, c-format msgid "check constraint \"%s\" of relation \"%s\" is violated by some row" msgstr "Check-Constraint »%s« von Relation »%s« wird von irgendeiner Zeile verletzt" -#: commands/tablecmds.c:6601 partitioning/partbounds.c:3381 +#: commands/tablecmds.c:6609 partitioning/partbounds.c:3381 #, c-format msgid "updated partition constraint for default partition \"%s\" would be violated by some row" msgstr "aktualisierter Partitions-Constraint der Standardpartition »%s« würde von irgendeiner Zeile verletzt werden" -#: commands/tablecmds.c:6607 +#: commands/tablecmds.c:6615 #, c-format msgid "partition constraint of relation \"%s\" is violated by some row" msgstr "Partitions-Constraint von Relation »%s« wird von irgendeiner Zeile verletzt" #. translator: %s is a group of some SQL keywords -#: commands/tablecmds.c:6876 +#: commands/tablecmds.c:6884 #, c-format msgid "ALTER action %s cannot be performed on relation \"%s\"" msgstr "ALTER-Aktion %s kann nicht mit Relation »%s« ausgeführt werden" -#: commands/tablecmds.c:7131 commands/tablecmds.c:7138 +#: commands/tablecmds.c:7139 commands/tablecmds.c:7146 #, c-format msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" msgstr "kann Typ »%s« nicht ändern, weil Spalte »%s.%s« ihn verwendet" -#: commands/tablecmds.c:7145 +#: commands/tablecmds.c:7153 #, c-format msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" msgstr "kann Fremdtabelle »%s« nicht ändern, weil Spalte »%s.%s« ihren Zeilentyp verwendet" -#: commands/tablecmds.c:7152 +#: commands/tablecmds.c:7160 #, c-format msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" msgstr "kann Tabelle »%s« nicht ändern, weil Spalte »%s.%s« ihren Zeilentyp verwendet" -#: commands/tablecmds.c:7208 +#: commands/tablecmds.c:7216 #, c-format msgid "cannot alter type \"%s\" because it is the type of a typed table" msgstr "kann Typ »%s« nicht ändern, weil er der Typ einer getypten Tabelle ist" -#: commands/tablecmds.c:7210 +#: commands/tablecmds.c:7218 #, c-format msgid "Use ALTER ... CASCADE to alter the typed tables too." msgstr "Verwenden Sie ALTER ... CASCADE, um die getypten Tabellen ebenfalls zu ändern." -#: commands/tablecmds.c:7256 +#: commands/tablecmds.c:7264 #, c-format msgid "type %s is the row type of another table" msgstr "Typ %s ist der Zeilentyp einer anderen Tabelle" -#: commands/tablecmds.c:7258 +#: commands/tablecmds.c:7266 #, c-format msgid "A typed table must use a stand-alone composite type created with CREATE TYPE." msgstr "Eine getypte Tabelle muss einen alleinstehenden mit CREATE TYPE erzeugten Typ verwenden." -#: commands/tablecmds.c:7263 +#: commands/tablecmds.c:7271 #, c-format msgid "type %s is not a composite type" msgstr "Typ %s ist kein zusammengesetzter Typ" -#: commands/tablecmds.c:7290 +#: commands/tablecmds.c:7298 #, c-format msgid "cannot add column to typed table" msgstr "zu einer getypten Tabelle kann keine Spalte hinzugefügt werden" -#: commands/tablecmds.c:7340 +#: commands/tablecmds.c:7348 #, c-format msgid "cannot add column to a partition" msgstr "zu einer Partition kann keine Spalte hinzugefügt werden" -#: commands/tablecmds.c:7369 commands/tablecmds.c:17797 +#: commands/tablecmds.c:7377 commands/tablecmds.c:18175 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" msgstr "abgeleitete Tabelle »%s« hat unterschiedlichen Typ für Spalte »%s«" -#: commands/tablecmds.c:7375 commands/tablecmds.c:17803 +#: commands/tablecmds.c:7383 commands/tablecmds.c:18181 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" msgstr "abgeleitete Tabelle »%s« hat unterschiedliche Sortierfolge für Spalte »%s«" -#: commands/tablecmds.c:7393 +#: commands/tablecmds.c:7401 #, c-format msgid "merging definition of column \"%s\" for child \"%s\"" msgstr "Definition von Spalte »%s« für abgeleitete Tabelle »%s« wird zusammengeführt" -#: commands/tablecmds.c:7446 +#: commands/tablecmds.c:7454 #, c-format msgid "cannot recursively add identity column to table that has child tables" msgstr "eine Identitätsspalte kann nicht rekursiv zu einer Tabelle hinzugefügt werden, die abgeleitete Tabellen hat" -#: commands/tablecmds.c:7718 +#: commands/tablecmds.c:7701 #, c-format msgid "column must be added to child tables too" msgstr "Spalte muss ebenso in den abgeleiteten Tabellen hinzugefügt werden" -#: commands/tablecmds.c:7796 +#: commands/tablecmds.c:7779 #, c-format msgid "column \"%s\" of relation \"%s\" already exists, skipping" msgstr "Spalte »%s« von Relation »%s« existiert bereits, wird übersprungen" -#: commands/tablecmds.c:7803 +#: commands/tablecmds.c:7786 #, c-format msgid "column \"%s\" of relation \"%s\" already exists" msgstr "Spalte »%s« von Relation »%s« existiert bereits" -#: commands/tablecmds.c:7894 commands/tablecmds.c:8061 -#: commands/tablecmds.c:8262 commands/tablecmds.c:8393 -#: commands/tablecmds.c:8547 commands/tablecmds.c:8641 -#: commands/tablecmds.c:8744 commands/tablecmds.c:8927 -#: commands/tablecmds.c:9093 commands/tablecmds.c:9184 -#: commands/tablecmds.c:9318 commands/tablecmds.c:14689 -#: commands/tablecmds.c:16280 commands/tablecmds.c:19039 +#: commands/tablecmds.c:7877 commands/tablecmds.c:8044 +#: commands/tablecmds.c:8245 commands/tablecmds.c:8376 +#: commands/tablecmds.c:8530 commands/tablecmds.c:8624 +#: commands/tablecmds.c:8727 commands/tablecmds.c:8917 +#: commands/tablecmds.c:9083 commands/tablecmds.c:9174 +#: commands/tablecmds.c:9308 commands/tablecmds.c:14899 +#: commands/tablecmds.c:16658 commands/tablecmds.c:19417 #, c-format msgid "cannot alter system column \"%s\"" msgstr "Systemspalte »%s« kann nicht geändert werden" -#: commands/tablecmds.c:7900 commands/tablecmds.c:8268 -#: commands/tablecmds.c:14450 +#: commands/tablecmds.c:7883 commands/tablecmds.c:8251 +#: commands/tablecmds.c:14660 #, c-format msgid "column \"%s\" of relation \"%s\" is an identity column" msgstr "Spalte »%s« von Relation »%s« ist eine Identitätsspalte" -#: commands/tablecmds.c:7917 +#: commands/tablecmds.c:7900 #, c-format msgid "column \"%s\" is marked NOT NULL in parent table" msgstr "Spalte »%s« ist in Elterntabelle als NOT NULL markiert" -#: commands/tablecmds.c:8139 commands/tablecmds.c:10126 +#: commands/tablecmds.c:8122 commands/tablecmds.c:10116 #, c-format msgid "constraint must be added to child tables too" msgstr "Constraint muss ebenso in den abgeleiteten Tabellen hinzugefügt werden" -#: commands/tablecmds.c:8140 commands/tablecmds.c:8371 -#: commands/tablecmds.c:8503 commands/tablecmds.c:8620 -#: commands/tablecmds.c:9491 commands/tablecmds.c:12320 -#: commands/tablecmds.c:12730 +#: commands/tablecmds.c:8123 commands/tablecmds.c:8354 +#: commands/tablecmds.c:8486 commands/tablecmds.c:8603 +#: commands/tablecmds.c:9481 commands/tablecmds.c:12310 +#: commands/tablecmds.c:12783 #, c-format msgid "Do not specify the ONLY keyword." msgstr "Lassen Sie das Schlüsselwort ONLY weg." -#: commands/tablecmds.c:8277 +#: commands/tablecmds.c:8260 #, c-format msgid "column \"%s\" of relation \"%s\" is a generated column" msgstr "Spalte »%s« von Relation »%s« ist eine generierte Spalte" -#: commands/tablecmds.c:8370 +#: commands/tablecmds.c:8353 #, c-format msgid "cannot add identity to a column of only the partitioned table" msgstr "Identität kann nicht einer Spalte nur in der partitionierten Tabelle hinzugefügt werden" -#: commands/tablecmds.c:8376 +#: commands/tablecmds.c:8359 #, c-format msgid "cannot add identity to a column of a partition" msgstr "zu einer Spalte einer Partition kann keine Identität hinzugefügt werden" -#: commands/tablecmds.c:8404 +#: commands/tablecmds.c:8387 #, c-format msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" msgstr "Spalte »%s« von Relation »%s« muss als NOT NULL deklariert werden, bevor Sie Identitätsspalte werden kann" -#: commands/tablecmds.c:8435 +#: commands/tablecmds.c:8418 #, c-format msgid "column \"%s\" of relation \"%s\" is already an identity column" msgstr "Spalte »%s« von Relation »%s« ist bereits eine Identitätsspalte" -#: commands/tablecmds.c:8441 +#: commands/tablecmds.c:8424 #, c-format msgid "column \"%s\" of relation \"%s\" already has a default value" msgstr "Spalte »%s« von Relation »%s« hat bereits einen Vorgabewert" -#: commands/tablecmds.c:8502 +#: commands/tablecmds.c:8485 #, c-format msgid "cannot change identity column of only the partitioned table" msgstr "Identitätsspalte kann nicht nur in der partitionierten Tabelle geändert werden" -#: commands/tablecmds.c:8508 +#: commands/tablecmds.c:8491 #, c-format msgid "cannot change identity column of a partition" msgstr "Identitätsspalte einer Partition kann nicht geändert werden" -#: commands/tablecmds.c:8553 commands/tablecmds.c:8649 +#: commands/tablecmds.c:8536 commands/tablecmds.c:8632 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column" msgstr "Spalte »%s« von Relation »%s« ist keine Identitätsspalte" -#: commands/tablecmds.c:8619 +#: commands/tablecmds.c:8602 #, c-format msgid "cannot drop identity from a column of only the partitioned table" msgstr "Identität kann nicht von einer Spalte nur in der partitionierten Tabelle gelöscht werden" -#: commands/tablecmds.c:8625 +#: commands/tablecmds.c:8608 #, c-format msgid "cannot drop identity from a column of a partition" msgstr "Identität kann nicht von einer Spalte einer Partition gelöscht werden" -#: commands/tablecmds.c:8654 +#: commands/tablecmds.c:8637 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" msgstr "Spalte »%s« von Relation »%s« ist keine Identitätsspalte, wird übersprungen" -#: commands/tablecmds.c:8751 commands/tablecmds.c:8948 +#: commands/tablecmds.c:8734 commands/tablecmds.c:8938 #, c-format msgid "column \"%s\" of relation \"%s\" is not a generated column" msgstr "Spalte »%s« von Relation »%s« ist keine generierte Spalte" -#: commands/tablecmds.c:8768 +#: commands/tablecmds.c:8751 #, c-format msgid "ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns in tables that are part of a publication" msgstr "ALTER TABLE / SET EXPRESSION wird nicht unterstützt für virtuelle generierte Spalten in Tabellen, die Teil einer Publikation sind" -#: commands/tablecmds.c:8769 commands/tablecmds.c:8940 +#: commands/tablecmds.c:8752 commands/tablecmds.c:8930 #, c-format msgid "Column \"%s\" of relation \"%s\" is a virtual generated column." msgstr "Spalte »%s« von Relation »%s« ist eine virtuelle generierte Spalte." -#: commands/tablecmds.c:8874 +#: commands/tablecmds.c:8864 #, c-format msgid "ALTER TABLE / DROP EXPRESSION must be applied to child tables too" msgstr "ALTER TABLE / DROP EXPRESSION muss auch auf abgeleitete Tabellen angewendet werden" -#: commands/tablecmds.c:8896 +#: commands/tablecmds.c:8886 #, c-format msgid "cannot drop generation expression from inherited column" msgstr "Generierungsausdruck von vererbter Spalte kann nicht gelöscht werden" -#: commands/tablecmds.c:8939 +#: commands/tablecmds.c:8929 #, c-format msgid "ALTER TABLE / DROP EXPRESSION is not supported for virtual generated columns" msgstr "ALTER TABLE / DROP EXPRESSION wird für virtuelle generierte Spalten nicht unterstützt" -#: commands/tablecmds.c:8953 +#: commands/tablecmds.c:8943 #, c-format msgid "column \"%s\" of relation \"%s\" is not a generated column, skipping" msgstr "Spalte »%s« von Relation »%s« ist keine generierte Spalte, wird übersprungen" -#: commands/tablecmds.c:9031 +#: commands/tablecmds.c:9021 #, c-format msgid "cannot refer to non-index column by number" msgstr "auf eine Nicht-Index-Spalte kann nicht per Nummer verwiesen werden" -#: commands/tablecmds.c:9083 +#: commands/tablecmds.c:9073 #, c-format msgid "column number %d of relation \"%s\" does not exist" msgstr "Spalte Nummer %d von Relation »%s« existiert nicht" -#: commands/tablecmds.c:9103 +#: commands/tablecmds.c:9093 #, c-format msgid "cannot alter statistics on virtual generated column \"%s\"" msgstr "Statistiken von virtueller generierter Spalte »%s« können nicht geändert werden" -#: commands/tablecmds.c:9112 +#: commands/tablecmds.c:9102 #, c-format msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" msgstr "Statistiken von eingeschlossener Spalte »%s« von Index »%s« können nicht geändert werden" -#: commands/tablecmds.c:9117 +#: commands/tablecmds.c:9107 #, c-format msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" msgstr "kann Statistiken von Spalte »%s« von Index »%s«, welche kein Ausdruck ist, nicht ändern" -#: commands/tablecmds.c:9119 +#: commands/tablecmds.c:9109 #, c-format msgid "Alter statistics on table column instead." msgstr "Ändern Sie stattdessen die Statistiken für die Tabellenspalte." -#: commands/tablecmds.c:9365 +#: commands/tablecmds.c:9355 #, c-format msgid "cannot drop column from typed table" msgstr "aus einer getypten Tabelle können keine Spalten gelöscht werden" -#: commands/tablecmds.c:9429 +#: commands/tablecmds.c:9419 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" msgstr "Spalte »%s« von Relation »%s« existiert nicht, wird übersprungen" -#: commands/tablecmds.c:9442 +#: commands/tablecmds.c:9432 #, c-format msgid "cannot drop system column \"%s\"" msgstr "Systemspalte »%s« kann nicht gelöscht werden" -#: commands/tablecmds.c:9452 +#: commands/tablecmds.c:9442 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "geerbte Spalte »%s« kann nicht gelöscht werden" -#: commands/tablecmds.c:9465 +#: commands/tablecmds.c:9455 #, c-format msgid "cannot drop column \"%s\" because it is part of the partition key of relation \"%s\"" msgstr "Spalte »%s« kann nicht gelöscht werden, weil sie Teil des Partitionierungsschlüssels von Relation »%s« ist" -#: commands/tablecmds.c:9490 +#: commands/tablecmds.c:9480 #, c-format msgid "cannot drop column from only the partitioned table when partitions exist" msgstr "Spalte kann nicht nur aus der partitionierten Tabelle gelöscht werden, wenn Partitionen existieren" -#: commands/tablecmds.c:9655 +#: commands/tablecmds.c:9645 #, c-format msgid "column \"%s\" of table \"%s\" is not marked NOT NULL" msgstr "Spalte »%s« von Tabelle »%s« ist nicht als NOT NULL markiert" -#: commands/tablecmds.c:9691 commands/tablecmds.c:9703 +#: commands/tablecmds.c:9681 commands/tablecmds.c:9693 #, c-format msgid "cannot create primary key on column \"%s\"" msgstr "kann keinen Primärschlüssel über Spalte »%s« erzeugen" #. translator: fourth %s is a constraint characteristic such as NOT VALID -#: commands/tablecmds.c:9693 commands/tablecmds.c:9705 +#: commands/tablecmds.c:9683 commands/tablecmds.c:9695 #, c-format msgid "The constraint \"%s\" on column \"%s\" of table \"%s\", marked %s, is incompatible with a primary key." msgstr "Der Constraint »%s« für Spalte »%s« von Tabelle »%s«, markiert als %s, ist inkompatibel mit einem Primärschlüssel." -#: commands/tablecmds.c:9830 +#: commands/tablecmds.c:9820 #, c-format msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX wird für partitionierte Tabellen nicht unterstützt" -#: commands/tablecmds.c:9855 +#: commands/tablecmds.c:9845 #, c-format msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX benennt Index »%s« um in »%s«" -#: commands/tablecmds.c:10213 +#: commands/tablecmds.c:10203 #, c-format msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" msgstr "ONLY nicht möglich für Fremdschlüssel für partitionierte Tabelle »%s« verweisend auf Relation »%s«" -#: commands/tablecmds.c:10221 commands/tablecmds.c:10848 +#: commands/tablecmds.c:10211 commands/tablecmds.c:10838 #, c-format msgid "referenced relation \"%s\" is not a table" msgstr "Relation »%s«, auf die verwiesen wird, ist keine Tabelle" -#: commands/tablecmds.c:10244 +#: commands/tablecmds.c:10234 #, c-format msgid "constraints on permanent tables may reference only permanent tables" msgstr "Constraints für permanente Tabellen dürfen nur auf permanente Tabellen verweisen" -#: commands/tablecmds.c:10251 +#: commands/tablecmds.c:10241 #, c-format msgid "constraints on unlogged tables may reference only permanent or unlogged tables" msgstr "Constraints für ungeloggte Tabellen dürfen nur auf permanente oder ungeloggte Tabellen verweisen" -#: commands/tablecmds.c:10257 +#: commands/tablecmds.c:10247 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "Constraints für temporäre Tabellen dürfen nur auf temporäre Tabellen verweisen" -#: commands/tablecmds.c:10261 +#: commands/tablecmds.c:10251 #, c-format msgid "constraints on temporary tables must involve temporary tables of this session" msgstr "Constraints für temporäre Tabellen müssen temporäre Tabellen dieser Sitzung beinhalten" -#: commands/tablecmds.c:10276 commands/tablecmds.c:10304 +#: commands/tablecmds.c:10266 commands/tablecmds.c:10294 #, c-format msgid "foreign key uses PERIOD on the referenced table but not the referencing table" msgstr "Fremdschlüssel verwendet PERIOD für die Tabelle, auf die verwiesen wird, aber nicht für die verweisende Tabelle" -#: commands/tablecmds.c:10316 +#: commands/tablecmds.c:10306 #, c-format msgid "foreign key uses PERIOD on the referencing table but not the referenced table" msgstr "Fremdschlüssel verwendet PERIOD für die verweisende Tabelle, aber nicht für die Tabelle, auf die verwiesen wird" -#: commands/tablecmds.c:10330 +#: commands/tablecmds.c:10320 #, c-format msgid "foreign key must use PERIOD when referencing a primary key using WITHOUT OVERLAPS" msgstr "Fremdschlüssel muss PERIOD verwenden, wenn auf einen Primärschlüssel verwiesen wird, der WITHOUT OVERLAPS verwendet" -#: commands/tablecmds.c:10354 commands/tablecmds.c:10360 +#: commands/tablecmds.c:10344 commands/tablecmds.c:10350 #, c-format msgid "invalid %s action for foreign key constraint containing generated column" msgstr "ungültige %s-Aktion für Fremdschlüssel-Constraint, der eine generierte Spalte enthält" -#: commands/tablecmds.c:10375 +#: commands/tablecmds.c:10365 #, c-format msgid "foreign key constraints on virtual generated columns are not supported" msgstr "Fremdschlüssel-Constraints für virtuelle generierte Spalten werden nicht unterstützt" -#: commands/tablecmds.c:10389 commands/tablecmds.c:10398 +#: commands/tablecmds.c:10379 commands/tablecmds.c:10388 #, c-format msgid "unsupported %s action for foreign key constraint using PERIOD" msgstr "nicht unterstützte %s-Aktion für Fremdschlüssel-Constraint, der PERIOD verwendet" -#: commands/tablecmds.c:10413 +#: commands/tablecmds.c:10403 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "Anzahl der Quell- und Zielspalten im Fremdschlüssel stimmt nicht überein" -#: commands/tablecmds.c:10469 +#: commands/tablecmds.c:10459 #, c-format msgid "could not identify an overlaps operator for foreign key" msgstr "konnte keinen Überlappungsoperator für den Fremdschlüssel ermitteln" -#: commands/tablecmds.c:10470 +#: commands/tablecmds.c:10460 #, c-format msgid "could not identify an equality operator for foreign key" msgstr "konnte keinen Ist-Gleich-Operator für den Fremdschlüssel ermitteln" -#: commands/tablecmds.c:10535 commands/tablecmds.c:10569 +#: commands/tablecmds.c:10525 commands/tablecmds.c:10559 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "Fremdschlüssel-Constraint »%s« kann nicht implementiert werden" -#: commands/tablecmds.c:10537 +#: commands/tablecmds.c:10527 #, c-format msgid "Key columns \"%s\" of the referencing table and \"%s\" of the referenced table are of incompatible types: %s and %s." msgstr "Schlüsselspalten »%s« der referenzierenden Tabelle und »%s« der referenzierten Tabelle haben inkompatible Typen: %s und %s." -#: commands/tablecmds.c:10570 +#: commands/tablecmds.c:10560 #, c-format msgid "Key columns \"%s\" of the referencing table and \"%s\" of the referenced table have incompatible collations: \"%s\" and \"%s\". If either collation is nondeterministic, then both collations have to be the same." msgstr "Schlüsselspalten »%s« der referenzierenden Tabelle und »%s« der referenzierten Tabelle haben inkompatible Sortierfolgen: »%s« und »%s«. Wenn eine der Sortierfolgen nichtdeterministisch ist, dann müssen beide Sortierfolgen die selbe sein." -#: commands/tablecmds.c:10776 +#: commands/tablecmds.c:10766 #, c-format msgid "column \"%s\" referenced in ON DELETE SET action must be part of foreign key" msgstr "Spalte »%s«, auf die in der ON-DELETE-SET-Aktion verwiesen wird, muss Teil des Fremdschlüssels sein" -#: commands/tablecmds.c:11160 commands/tablecmds.c:11593 +#: commands/tablecmds.c:11150 commands/tablecmds.c:11583 #: parser/parse_utilcmd.c:939 parser/parse_utilcmd.c:1084 #, c-format msgid "foreign key constraints are not supported on foreign tables" msgstr "Fremdschlüssel-Constraints auf Fremdtabellen werden nicht unterstützt" -#: commands/tablecmds.c:11576 +#: commands/tablecmds.c:11566 #, c-format msgid "cannot attach table \"%s\" as a partition because it is referenced by foreign key \"%s\"" msgstr "kann Tabelle »%s« nicht als Partition anfügen, weil auf sie von Fremdschlüssel »%s« verwiesen wird" -#: commands/tablecmds.c:11857 +#: commands/tablecmds.c:11847 #, c-format msgid "constraint \"%s\" enforceability conflicts with constraint \"%s\" on relation \"%s\"" msgstr "ENFORCED-Einstellung von Constraint »%s« kollidiert mit Constraint »%s« für Relation »%s«" -#: commands/tablecmds.c:12319 +#: commands/tablecmds.c:12309 #, c-format msgid "constraint must be altered in child tables too" msgstr "Constraint muss ebenso in den abgeleiteten Tabellen geändert werden" -#: commands/tablecmds.c:12348 commands/tablecmds.c:12810 -#: commands/tablecmds.c:13214 commands/tablecmds.c:14329 -#: commands/tablecmds.c:14558 +#: commands/tablecmds.c:12338 commands/tablecmds.c:12890 +#: commands/tablecmds.c:13421 commands/tablecmds.c:14539 +#: commands/tablecmds.c:14768 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "Constraint »%s« von Relation »%s« existiert nicht" -#: commands/tablecmds.c:12355 +#: commands/tablecmds.c:12345 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "Constraint »%s« von Relation »%s« ist kein Fremdschlüssel-Constraint" -#: commands/tablecmds.c:12361 +#: commands/tablecmds.c:12351 #, c-format msgid "cannot alter enforceability of constraint \"%s\" of relation \"%s\"" msgstr "ENFORCED-Einstellung des Constraints »%s« von Relation »%s« kann nicht geändert werden" -#: commands/tablecmds.c:12363 +#: commands/tablecmds.c:12353 #, c-format msgid "Only foreign key and check constraints can change enforceability." msgstr "" -#: commands/tablecmds.c:12368 +#: commands/tablecmds.c:12358 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a not-null constraint" msgstr "Constraint »%s« von Relation »%s« ist kein Not-Null-Constraint" -#: commands/tablecmds.c:12376 +#: commands/tablecmds.c:12364 +#, fuzzy, c-format +#| msgid "not-null constraints on partitioned tables cannot be NO INHERIT" +msgid "not-null constraint \"%s\" on partitioned table \"%s\" cannot be NO INHERIT" +msgstr "Not-Null-Constraints für partitionierte Tabellen können nicht NO INHERIT sein" + +#: commands/tablecmds.c:12372 #, c-format msgid "cannot alter inherited constraint \"%s\" on relation \"%s\"" msgstr "geerbter Constraint »%s« von Relation »%s« kann nicht geändert werden" -#: commands/tablecmds.c:12416 +#: commands/tablecmds.c:12412 #, c-format msgid "cannot alter constraint \"%s\" on relation \"%s\"" msgstr "Constraint »%s« von Relation »%s« kann nicht geändert werden" -#: commands/tablecmds.c:12419 +#: commands/tablecmds.c:12415 #, c-format msgid "Constraint \"%s\" is derived from constraint \"%s\" of relation \"%s\"." msgstr "Constraint »%s« ist von Constraint »%s« von Relation »%s« abgeleitet." -#: commands/tablecmds.c:12421 +#: commands/tablecmds.c:12417 #, c-format msgid "You may alter the constraint it derives from instead." msgstr "Sie können stattdessen den Constraint, von dem er abgeleitet ist, ändern." -#: commands/tablecmds.c:12729 +#: commands/tablecmds.c:12713 +#, fuzzy, c-format +#| msgid "cannot rename inherited constraint \"%s\"" +msgid "cannot mark inherited constraint \"%s\" as %s" +msgstr "kann vererbten Constraint »%s« nicht umbenennen" + +#: commands/tablecmds.c:12716 +#, fuzzy, c-format +#| msgid "Make sure the configuration parameter \"%s\" is set." +msgid "The matching constraint on parent table \"%s\" is %s." +msgstr "Stellen Sie sicher, dass der Konfigurationsparameter »%s« gesetzt ist." + +#: commands/tablecmds.c:12782 #, fuzzy, c-format #| msgid "constraint must be altered in child tables too" msgid "constraint must be altered on child tables too" msgstr "Constraint muss ebenso in den abgeleiteten Tabellen geändert werden" -#: commands/tablecmds.c:13223 +#: commands/tablecmds.c:13430 #, c-format msgid "cannot validate constraint \"%s\" of relation \"%s\"" msgstr "Constraint »%s« von Relation »%s« kann nicht validiert werden" -#: commands/tablecmds.c:13225 +#: commands/tablecmds.c:13432 #, c-format msgid "This operation is not supported for this type of constraint." msgstr "Diese Operation wird für diese Art von Constraint nicht unterstützt." -#: commands/tablecmds.c:13230 +#: commands/tablecmds.c:13437 #, c-format msgid "cannot validate NOT ENFORCED constraint" msgstr "auf NOT ENFORCED gesetzter Constraint kann nicht validiert werden" -#: commands/tablecmds.c:13439 commands/tablecmds.c:13539 +#: commands/tablecmds.c:13649 commands/tablecmds.c:13749 #, c-format msgid "constraint must be validated on child tables too" msgstr "Constraint muss ebenso in den abgeleiteten Tabellen validiert werden" -#: commands/tablecmds.c:13616 +#: commands/tablecmds.c:13826 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" msgstr "Spalte »%s«, die im Fremdschlüssel verwendet wird, existiert nicht" -#: commands/tablecmds.c:13622 +#: commands/tablecmds.c:13832 #, c-format msgid "system columns cannot be used in foreign keys" msgstr "Systemspalten können nicht in Fremdschlüsseln verwendet werden" -#: commands/tablecmds.c:13626 +#: commands/tablecmds.c:13836 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "Fremdschlüssel kann nicht mehr als %d Schlüssel haben" -#: commands/tablecmds.c:13694 +#: commands/tablecmds.c:13904 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "aufschiebbarer Primärschlüssel kann nicht für Tabelle »%s«, auf die verwiesen wird, verwendet werden" -#: commands/tablecmds.c:13711 +#: commands/tablecmds.c:13921 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "in Tabelle »%s«, auf die verwiesen wird, gibt es keinen Primärschlüssel" -#: commands/tablecmds.c:13784 +#: commands/tablecmds.c:13994 #, c-format msgid "foreign key referenced-columns list must not contain duplicates" msgstr "die Liste der Spalten, auf die ein Fremdschlüssel verweist, darf keine doppelten Einträge enthalten" -#: commands/tablecmds.c:13887 +#: commands/tablecmds.c:14097 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "aufschiebbarer Unique-Constraint kann nicht für Tabelle »%s«, auf die verwiesen wird, verwendet werden" -#: commands/tablecmds.c:13892 +#: commands/tablecmds.c:14102 #, c-format msgid "there is no unique constraint matching given keys for referenced table \"%s\"" msgstr "in Tabelle »%s«, auf die verwiesen wird, gibt es keinen Unique-Constraint, der auf die angegebenen Schlüssel passt" -#: commands/tablecmds.c:14333 +#: commands/tablecmds.c:14543 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" msgstr "Constraint »%s« von Relation »%s« existiert nicht, wird übersprungen" -#: commands/tablecmds.c:14378 +#: commands/tablecmds.c:14588 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "geerbter Constraint »%s« von Relation »%s« kann nicht gelöscht werden" -#: commands/tablecmds.c:14430 +#: commands/tablecmds.c:14640 #, c-format msgid "column \"%s\" is in a primary key" msgstr "Spalte »%s« ist in einem Primärschlüssel" -#: commands/tablecmds.c:14438 +#: commands/tablecmds.c:14648 #, c-format msgid "column \"%s\" is in index used as replica identity" msgstr "Spalte »%s« ist in einem Index, der als Replik-Identität verwendet wird" -#: commands/tablecmds.c:14671 +#: commands/tablecmds.c:14881 #, c-format msgid "cannot alter column type of typed table" msgstr "Spaltentyp einer getypten Tabelle kann nicht geändert werden" -#: commands/tablecmds.c:14699 +#: commands/tablecmds.c:14909 #, c-format msgid "cannot specify USING when altering type of generated column" msgstr "USING kann nicht angegeben werden, wenn der Typ einer generierten Spalte geändert wird" -#: commands/tablecmds.c:14711 +#: commands/tablecmds.c:14921 #, c-format msgid "cannot alter inherited column \"%s\"" msgstr "kann vererbte Spalte »%s« nicht ändern" -#: commands/tablecmds.c:14720 +#: commands/tablecmds.c:14930 #, c-format msgid "cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"" msgstr "Spalte »%s« kann nicht geändert werden, weil sie Teil des Partitionierungsschlüssels von Relation »%s« ist" -#: commands/tablecmds.c:14775 +#: commands/tablecmds.c:14985 #, c-format msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" msgstr "Ergebnis der USING-Klausel für Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" -#: commands/tablecmds.c:14778 +#: commands/tablecmds.c:14988 #, c-format msgid "You might need to add an explicit cast." msgstr "Sie müssen möglicherweise eine ausdrückliche Typumwandlung hinzufügen." -#: commands/tablecmds.c:14782 +#: commands/tablecmds.c:14992 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" msgstr "Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" #. translator: USING is SQL, don't translate it -#: commands/tablecmds.c:14786 +#: commands/tablecmds.c:14996 #, c-format msgid "You might need to specify \"USING %s::%s\"." msgstr "Sie müssen möglicherweise »USING %s::%s« angeben." -#: commands/tablecmds.c:14889 +#: commands/tablecmds.c:15099 #, c-format msgid "cannot alter inherited column \"%s\" of relation \"%s\"" msgstr "geerbte Spalte »%s« von Relation »%s« kann nicht geändert werden" -#: commands/tablecmds.c:14918 +#: commands/tablecmds.c:15128 #, c-format msgid "USING expression contains a whole-row table reference." msgstr "USING-Ausdruck enthält einen Verweis auf die ganze Zeile der Tabelle." -#: commands/tablecmds.c:14929 +#: commands/tablecmds.c:15139 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" msgstr "Typ der vererbten Spalte »%s« muss ebenso in den abgeleiteten Tabellen geändert werden" -#: commands/tablecmds.c:15054 +#: commands/tablecmds.c:15264 #, c-format msgid "cannot alter type of column \"%s\" twice" msgstr "Typ der Spalte »%s« kann nicht zweimal geändert werden" -#: commands/tablecmds.c:15092 +#: commands/tablecmds.c:15302 #, c-format msgid "generation expression for column \"%s\" cannot be cast automatically to type %s" msgstr "Generierungsausdruck der Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" -#: commands/tablecmds.c:15097 +#: commands/tablecmds.c:15307 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "Vorgabewert der Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" -#: commands/tablecmds.c:15401 +#: commands/tablecmds.c:15611 #, c-format msgid "cannot alter type of a column used by a function or procedure" msgstr "Typ einer Spalte, die von einer Funktion oder Prozedur verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:15402 commands/tablecmds.c:15417 -#: commands/tablecmds.c:15437 commands/tablecmds.c:15456 -#: commands/tablecmds.c:15515 +#: commands/tablecmds.c:15612 commands/tablecmds.c:15627 +#: commands/tablecmds.c:15647 commands/tablecmds.c:15666 +#: commands/tablecmds.c:15725 #, c-format msgid "%s depends on column \"%s\"" msgstr "%s hängt von Spalte »%s« ab" -#: commands/tablecmds.c:15416 +#: commands/tablecmds.c:15626 #, c-format msgid "cannot alter type of a column used by a view or rule" msgstr "Typ einer Spalte, die von einer Sicht oder Regel verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:15436 +#: commands/tablecmds.c:15646 #, c-format msgid "cannot alter type of a column used in a trigger definition" msgstr "Typ einer Spalte, die in einer Trigger-Definition verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:15455 +#: commands/tablecmds.c:15665 #, c-format msgid "cannot alter type of a column used in a policy definition" msgstr "Typ einer Spalte, die in einer Policy-Definition verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:15486 +#: commands/tablecmds.c:15696 #, c-format msgid "cannot alter type of a column used by a generated column" msgstr "Typ einer Spalte, die von einer generierten Spalte verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:15487 +#: commands/tablecmds.c:15697 #, c-format msgid "Column \"%s\" is used by generated column \"%s\"." msgstr "Spalte »%s« wird von generierter Spalte »%s« verwendet." -#: commands/tablecmds.c:15514 +#: commands/tablecmds.c:15724 #, c-format msgid "cannot alter type of a column used by a publication WHERE clause" msgstr "Typ einer Spalte, die in der WHERE-Klausel einer Publikation verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:16389 commands/tablecmds.c:16401 +#: commands/tablecmds.c:16767 commands/tablecmds.c:16779 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "kann Eigentümer des Index »%s« nicht ändern" -#: commands/tablecmds.c:16391 commands/tablecmds.c:16403 +#: commands/tablecmds.c:16769 commands/tablecmds.c:16781 #, c-format msgid "Change the ownership of the index's table instead." msgstr "Ändern Sie stattdessen den Eigentümer der Tabelle des Index." -#: commands/tablecmds.c:16417 +#: commands/tablecmds.c:16795 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "kann Eigentümer der Sequenz »%s« nicht ändern" -#: commands/tablecmds.c:16442 +#: commands/tablecmds.c:16820 #, c-format msgid "cannot change owner of relation \"%s\"" msgstr "kann Eigentümer der Relation »%s« nicht ändern" -#: commands/tablecmds.c:16909 +#: commands/tablecmds.c:17287 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "mehrere SET TABLESPACE Unterbefehle sind ungültig" -#: commands/tablecmds.c:16988 +#: commands/tablecmds.c:17366 #, c-format msgid "cannot set options for relation \"%s\"" msgstr "für Relation »%s« können keine Optionen gesetzt werden" -#: commands/tablecmds.c:17022 commands/view.c:440 +#: commands/tablecmds.c:17400 commands/view.c:440 #, c-format msgid "WITH CHECK OPTION is supported only on automatically updatable views" msgstr "WITH CHECK OPTION wird nur für automatisch aktualisierbare Sichten unterstützt" -#: commands/tablecmds.c:17275 +#: commands/tablecmds.c:17653 #, c-format msgid "only tables, indexes, and materialized views exist in tablespaces" msgstr "nur Tabellen, Indexe und materialisierte Sichten existieren in Tablespaces" -#: commands/tablecmds.c:17287 +#: commands/tablecmds.c:17665 #, c-format msgid "cannot move relations in to or out of pg_global tablespace" msgstr "Relationen können nicht in den oder aus dem Tablespace »pg_global« verschoben werden" -#: commands/tablecmds.c:17379 +#: commands/tablecmds.c:17757 #, c-format msgid "aborting because lock on relation \"%s.%s\" is not available" msgstr "Abbruch weil Sperre für Relation »%s.%s« nicht verfügbar ist" -#: commands/tablecmds.c:17395 +#: commands/tablecmds.c:17773 #, c-format msgid "no matching relations in tablespace \"%s\" found" msgstr "keine passenden Relationen in Tablespace »%s« gefunden" -#: commands/tablecmds.c:17515 +#: commands/tablecmds.c:17893 #, c-format msgid "cannot change inheritance of typed table" msgstr "Vererbung einer getypten Tabelle kann nicht geändert werden" -#: commands/tablecmds.c:17520 +#: commands/tablecmds.c:17898 #, c-format msgid "cannot change inheritance of a partition" msgstr "Vererbung einer Partition kann nicht geändert werden" -#: commands/tablecmds.c:17567 +#: commands/tablecmds.c:17945 #, c-format msgid "cannot inherit to temporary relation of another session" msgstr "an temporäre Relation einer anderen Sitzung kann nicht vererbt werden" -#: commands/tablecmds.c:17580 +#: commands/tablecmds.c:17958 #, c-format msgid "cannot inherit from a partition" msgstr "von einer Partition kann nicht geerbt werden" -#: commands/tablecmds.c:17602 commands/tablecmds.c:20705 +#: commands/tablecmds.c:17980 commands/tablecmds.c:21076 #, c-format msgid "circular inheritance not allowed" msgstr "zirkuläre Vererbung ist nicht erlaubt" -#: commands/tablecmds.c:17603 commands/tablecmds.c:20706 +#: commands/tablecmds.c:17981 commands/tablecmds.c:21077 #, c-format msgid "\"%s\" is already a child of \"%s\"." msgstr "»%s« ist schon von »%s« abgeleitet." -#: commands/tablecmds.c:17616 +#: commands/tablecmds.c:17994 #, c-format msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" msgstr "Trigger »%s« verhindert, dass Tabelle »%s« ein Vererbungskind werden kann" -#: commands/tablecmds.c:17618 +#: commands/tablecmds.c:17996 #, c-format msgid "ROW triggers with transition tables are not supported in inheritance hierarchies." msgstr "ROW-Trigger mit Übergangstabellen werden in Vererbungshierarchien nicht unterstützt." -#: commands/tablecmds.c:17822 commands/tablecmds.c:18071 +#: commands/tablecmds.c:18200 commands/tablecmds.c:18449 #, c-format msgid "column \"%s\" in child table \"%s\" must be marked NOT NULL" msgstr "Spalte »%s« in abgeleiteter Tabelle »%s« muss als NOT NULL markiert sein" -#: commands/tablecmds.c:17832 +#: commands/tablecmds.c:18210 #, c-format msgid "column \"%s\" in child table must be a generated column" msgstr "Spalte »%s« in abgeleiteter Tabelle muss eine generierte Spalte sein" -#: commands/tablecmds.c:17836 +#: commands/tablecmds.c:18214 #, c-format msgid "column \"%s\" in child table must not be a generated column" msgstr "Spalte »%s« in abgeleiteter Tabelle darf keine generierte Spalte sein" -#: commands/tablecmds.c:17882 +#: commands/tablecmds.c:18260 #, c-format msgid "child table is missing column \"%s\"" msgstr "Spalte »%s« fehlt in abgeleiteter Tabelle" -#: commands/tablecmds.c:17999 +#: commands/tablecmds.c:18377 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" msgstr "abgeleitete Tabelle »%s« hat unterschiedliche Definition für Check-Constraint »%s«" -#: commands/tablecmds.c:18008 +#: commands/tablecmds.c:18386 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" msgstr "Constraint »%s« kollidiert mit nicht vererbtem Constraint für abgeleitete Tabelle »%s«" -#: commands/tablecmds.c:18019 +#: commands/tablecmds.c:18397 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" msgstr "Constraint »%s« kollidiert mit NOT-VALID-Constraint für abgeleitete Tabelle »%s«" -#: commands/tablecmds.c:18030 +#: commands/tablecmds.c:18408 #, c-format msgid "constraint \"%s\" conflicts with NOT ENFORCED constraint on child table \"%s\"" msgstr "Constraint »%s« kollidiert mit NOT-ENFORCED-Constraint für abgeleitete Tabelle »%s«" -#: commands/tablecmds.c:18079 +#: commands/tablecmds.c:18457 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "Constraint »%s« fehlt in abgeleiteter Tabelle" -#: commands/tablecmds.c:18161 +#: commands/tablecmds.c:18539 #, c-format msgid "partition \"%s\" already pending detach in partitioned table \"%s.%s\"" msgstr "Partition »%s« hat schon eine unerledigte Abtrennoperation in der partitionierten Tabelle »%s.%s«" -#: commands/tablecmds.c:18190 commands/tablecmds.c:18238 -#: parser/parse_utilcmd.c:3554 +#: commands/tablecmds.c:18568 commands/tablecmds.c:18616 +#: parser/parse_utilcmd.c:3558 #, c-format msgid "relation \"%s\" is not a partition of relation \"%s\"" msgstr "Relation »%s« ist keine Partition von Relation »%s«" -#: commands/tablecmds.c:18244 +#: commands/tablecmds.c:18622 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "Relation »%s« ist keine Basisrelation von Relation »%s«" -#: commands/tablecmds.c:18515 +#: commands/tablecmds.c:18893 #, c-format msgid "typed tables cannot inherit" msgstr "getypte Tabellen können nicht erben" -#: commands/tablecmds.c:18545 +#: commands/tablecmds.c:18923 #, c-format msgid "table is missing column \"%s\"" msgstr "Spalte »%s« fehlt in Tabelle" -#: commands/tablecmds.c:18556 +#: commands/tablecmds.c:18934 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" msgstr "Tabelle hat Spalte »%s«, aber Typ benötigt »%s«" -#: commands/tablecmds.c:18565 +#: commands/tablecmds.c:18943 #, c-format msgid "table \"%s\" has different type for column \"%s\"" msgstr "Tabelle »%s« hat unterschiedlichen Typ für Spalte »%s«" -#: commands/tablecmds.c:18579 +#: commands/tablecmds.c:18957 #, c-format msgid "table has extra column \"%s\"" msgstr "Tabelle hat zusätzliche Spalte »%s«" -#: commands/tablecmds.c:18631 +#: commands/tablecmds.c:19009 #, c-format msgid "\"%s\" is not a typed table" msgstr "»%s« ist keine getypte Tabelle" -#: commands/tablecmds.c:18811 +#: commands/tablecmds.c:19189 #, c-format msgid "cannot use non-unique index \"%s\" as replica identity" msgstr "nicht eindeutiger Index »%s« kann nicht als Replik-Identität verwendet werden" -#: commands/tablecmds.c:18817 +#: commands/tablecmds.c:19195 #, c-format msgid "cannot use non-immediate index \"%s\" as replica identity" msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil er nicht IMMEDIATE ist" -#: commands/tablecmds.c:18823 +#: commands/tablecmds.c:19201 #, c-format msgid "cannot use expression index \"%s\" as replica identity" msgstr "Ausdrucksindex »%s« kann nicht als Replik-Identität verwendet werden" -#: commands/tablecmds.c:18829 +#: commands/tablecmds.c:19207 #, c-format msgid "cannot use partial index \"%s\" as replica identity" msgstr "partieller Index »%s« kann nicht als Replik-Identität verwendet werden" -#: commands/tablecmds.c:18846 +#: commands/tablecmds.c:19224 #, c-format msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil Spalte %d eine Systemspalte ist" -#: commands/tablecmds.c:18853 +#: commands/tablecmds.c:19231 #, c-format msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil Spalte »%s« NULL-Werte akzeptiert" -#: commands/tablecmds.c:19102 +#: commands/tablecmds.c:19480 #, c-format msgid "cannot change logged status of table \"%s\" because it is temporary" msgstr "kann den geloggten Status der Tabelle »%s« nicht ändern, weil sie temporär ist" -#: commands/tablecmds.c:19126 +#: commands/tablecmds.c:19504 #, c-format msgid "cannot change table \"%s\" to unlogged because it is part of a publication" msgstr "kann Tabelle »%s« nicht in ungeloggt ändern, weil sie Teil einer Publikation ist" -#: commands/tablecmds.c:19128 +#: commands/tablecmds.c:19506 #, c-format msgid "Unlogged relations cannot be replicated." msgstr "Ungeloggte Relationen können nicht repliziert werden." -#: commands/tablecmds.c:19173 +#: commands/tablecmds.c:19551 #, c-format msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" msgstr "konnte Tabelle »%s« nicht in geloggt ändern, weil sie auf die ungeloggte Tabelle »%s« verweist" -#: commands/tablecmds.c:19183 +#: commands/tablecmds.c:19561 #, c-format msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" msgstr "konnte Tabelle »%s« nicht in ungeloggt ändern, weil sie auf die geloggte Tabelle »%s« verweist" -#: commands/tablecmds.c:19247 +#: commands/tablecmds.c:19625 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "einer Tabelle zugeordnete Sequenz kann nicht in ein anderes Schema verschoben werden" -#: commands/tablecmds.c:19355 +#: commands/tablecmds.c:19733 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "Relation »%s« existiert bereits in Schema »%s«" -#: commands/tablecmds.c:19780 +#: commands/tablecmds.c:20158 #, c-format msgid "\"%s\" is not a table or materialized view" msgstr "»%s« ist keine Tabelle oder materialisierte Sicht" -#: commands/tablecmds.c:19933 +#: commands/tablecmds.c:20311 #, c-format msgid "\"%s\" is not a composite type" msgstr "»%s« ist kein zusammengesetzter Typ" -#: commands/tablecmds.c:19968 +#: commands/tablecmds.c:20346 #, c-format msgid "cannot change schema of index \"%s\"" msgstr "kann Schema des Index »%s« nicht ändern" -#: commands/tablecmds.c:19970 commands/tablecmds.c:19984 +#: commands/tablecmds.c:20348 commands/tablecmds.c:20362 #, c-format msgid "Change the schema of the table instead." msgstr "Ändern Sie stattdessen das Schema der Tabelle." -#: commands/tablecmds.c:19974 +#: commands/tablecmds.c:20352 #, c-format msgid "cannot change schema of composite type \"%s\"" msgstr "kann Schema des zusammengesetzten Typs »%s« nicht ändern" -#: commands/tablecmds.c:19982 +#: commands/tablecmds.c:20360 #, c-format msgid "cannot change schema of TOAST table \"%s\"" msgstr "kann Schema der TOAST-Tabelle »%s« nicht ändern" -#: commands/tablecmds.c:20014 +#: commands/tablecmds.c:20392 #, c-format msgid "cannot use \"list\" partition strategy with more than one column" msgstr "Partitionierungsstrategie »list« kann nicht mit mehr als einer Spalte verwendet werden" -#: commands/tablecmds.c:20080 +#: commands/tablecmds.c:20458 #, c-format msgid "column \"%s\" named in partition key does not exist" msgstr "Spalte »%s«, die im Partitionierungsschlüssel verwendet wird, existiert nicht" -#: commands/tablecmds.c:20088 +#: commands/tablecmds.c:20466 #, c-format msgid "cannot use system column \"%s\" in partition key" msgstr "Systemspalte »%s« kann nicht im Partitionierungsschlüssel verwendet werden" -#: commands/tablecmds.c:20102 commands/tablecmds.c:20184 +#: commands/tablecmds.c:20480 commands/tablecmds.c:20562 #, c-format msgid "cannot use generated column in partition key" msgstr "generierte Spalte kann nicht im Partitionierungsschlüssel verwendet werden" -#: commands/tablecmds.c:20171 +#: commands/tablecmds.c:20549 #, c-format msgid "partition key expressions cannot contain system column references" msgstr "Partitionierungsschlüsselausdruck kann nicht auf Systemspalten verweisen" -#: commands/tablecmds.c:20235 +#: commands/tablecmds.c:20613 #, c-format msgid "functions in partition key expression must be marked IMMUTABLE" msgstr "Funktionen im Partitionierungsschlüsselausdruck müssen als IMMUTABLE markiert sein" -#: commands/tablecmds.c:20244 +#: commands/tablecmds.c:20622 #, c-format msgid "cannot use constant expression as partition key" msgstr "Partitionierungsschlüssel kann kein konstanter Ausdruck sein" -#: commands/tablecmds.c:20265 +#: commands/tablecmds.c:20643 #, c-format msgid "could not determine which collation to use for partition expression" msgstr "konnte die für den Partitionierungsausdruck zu verwendende Sortierfolge nicht bestimmen" -#: commands/tablecmds.c:20300 +#: commands/tablecmds.c:20678 #, c-format msgid "You must specify a hash operator class or define a default hash operator class for the data type." msgstr "Sie müssen eine hash-Operatorklasse angeben oder eine hash-Standardoperatorklasse für den Datentyp definieren." -#: commands/tablecmds.c:20306 +#: commands/tablecmds.c:20684 #, c-format msgid "You must specify a btree operator class or define a default btree operator class for the data type." msgstr "Sie müssen eine btree-Operatorklasse angeben oder eine btree-Standardoperatorklasse für den Datentyp definieren." -#: commands/tablecmds.c:20601 +#: commands/tablecmds.c:20979 #, c-format msgid "\"%s\" is already a partition" msgstr "»%s« ist bereits eine Partition" -#: commands/tablecmds.c:20607 +#: commands/tablecmds.c:20985 #, c-format msgid "cannot attach a typed table as partition" msgstr "eine getypte Tabelle kann nicht als Partition angefügt werden" -#. translator: This is a separator in a list of publication -#. names. -#. -#. translator: This is a separator in a list of conflicting keys -#. and tuple data. -#. -#. translator: This is a separator in a list of entity names. -#. translator: This is a separator in a list of entity -#. names. -#. -#: commands/tablecmds.c:20632 replication/logical/conflict.c:228 -#: replication/logical/relation.c:254 utils/misc/guc.c:3182 -msgid ", " -msgstr ", " - -#: commands/tablecmds.c:20637 replication/logical/relation.c:256 -#, c-format -msgid "\"%s\"" -msgstr "»%s«" - -#: commands/tablecmds.c:20642 +#: commands/tablecmds.c:21013 #, fuzzy, c-format #| msgid "cannot attach table \"%s\" as a partition because it is referenced by foreign key \"%s\"" msgid "cannot attach table \"%s\" as partition because it is referenced in publication %s EXCEPT clause" @@ -15982,196 +16039,196 @@ msgid_plural "cannot attach table \"%s\" as partition because it is referenced i msgstr[0] "kann Tabelle »%s« nicht als Partition anfügen, weil auf sie von Fremdschlüssel »%s« verwiesen wird" msgstr[1] "kann Tabelle »%s« nicht als Partition anfügen, weil auf sie von Fremdschlüssel »%s« verwiesen wird" -#: commands/tablecmds.c:20647 +#: commands/tablecmds.c:21018 #, c-format msgid "The publication EXCEPT clause cannot contain tables that are partitions." msgstr "" -#: commands/tablecmds.c:20648 +#: commands/tablecmds.c:21019 #, c-format msgid "Change the publication's EXCEPT clause using ALTER PUBLICATION ... SET ALL TABLES." msgstr "" -#: commands/tablecmds.c:20667 +#: commands/tablecmds.c:21038 #, c-format msgid "cannot attach inheritance child as partition" msgstr "ein Vererbungskind kann nicht als Partition angefügt werden" -#: commands/tablecmds.c:20681 +#: commands/tablecmds.c:21052 #, c-format msgid "cannot attach inheritance parent as partition" msgstr "eine Tabelle mit abgeleiteten Tabellen kann nicht als Partition angefügt werden" -#: commands/tablecmds.c:20715 +#: commands/tablecmds.c:21086 #, c-format msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" msgstr "eine temporäre Relation kann nicht als Partition an permanente Relation »%s« angefügt werden" -#: commands/tablecmds.c:20723 +#: commands/tablecmds.c:21094 #, c-format msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" msgstr "eine permanente Relation kann nicht als Partition an temporäre Relation »%s« angefügt werden" -#: commands/tablecmds.c:20730 +#: commands/tablecmds.c:21101 #, c-format msgid "cannot attach as partition of temporary relation of another session" msgstr "kann nicht als Partition an temporäre Relation einer anderen Sitzung anfügen" -#: commands/tablecmds.c:20736 +#: commands/tablecmds.c:21107 #, c-format msgid "cannot attach temporary relation of another session as partition" msgstr "temporäre Relation einer anderen Sitzung kann nicht als Partition angefügt werden" -#: commands/tablecmds.c:20756 +#: commands/tablecmds.c:21127 #, c-format msgid "table \"%s\" being attached contains an identity column \"%s\"" msgstr "anzufügende Tabelle »%s« enthält eine Identitätsspalte »%s«" -#: commands/tablecmds.c:20758 +#: commands/tablecmds.c:21129 #, c-format msgid "The new partition may not contain an identity column." msgstr "Die neue Partition darf keine Identitätsspalte enthalten." -#: commands/tablecmds.c:20766 +#: commands/tablecmds.c:21137 #, c-format msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" msgstr "Tabelle »%s« enthält Spalte »%s«, die nicht in der Elterntabelle »%s« gefunden wurde" -#: commands/tablecmds.c:20769 +#: commands/tablecmds.c:21140 #, c-format msgid "The new partition may contain only the columns present in parent." msgstr "Die neue Partition darf nur Spalten enthalten, die auch die Elterntabelle hat." -#: commands/tablecmds.c:20781 +#: commands/tablecmds.c:21152 #, c-format msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" msgstr "Trigger »%s« verhindert, dass Tabelle »%s« eine Partition werden kann" -#: commands/tablecmds.c:20783 +#: commands/tablecmds.c:21154 #, c-format msgid "ROW triggers with transition tables are not supported on partitions." msgstr "ROW-Trigger mit Übergangstabellen werden für Partitionen nicht unterstützt." -#: commands/tablecmds.c:20949 +#: commands/tablecmds.c:21320 #, c-format msgid "cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"" msgstr "kann Fremdtabelle »%s« nicht als Partition an partitionierte Tabelle »%s« anfügen" -#: commands/tablecmds.c:20952 +#: commands/tablecmds.c:21323 #, c-format msgid "Partitioned table \"%s\" contains unique indexes." msgstr "Partitionierte Tabelle »%s« enthält Unique-Indexe." -#: commands/tablecmds.c:21276 +#: commands/tablecmds.c:21647 #, c-format msgid "cannot detach partitions concurrently when a default partition exists" msgstr "nebenläufiges Abtrennen einer Partition ist nicht möglich, wenn eine Standardpartition existiert" -#: commands/tablecmds.c:21379 +#: commands/tablecmds.c:21750 #, c-format msgid "partitioned table \"%s\" was removed concurrently" msgstr "partitionierte Tabelle »%s« wurde nebenläufig entfernt" -#: commands/tablecmds.c:21385 +#: commands/tablecmds.c:21756 #, c-format msgid "partition \"%s\" was removed concurrently" msgstr "Partition »%s« wurde nebenläufig entfernt" -#: commands/tablecmds.c:21976 commands/tablecmds.c:21996 -#: commands/tablecmds.c:22017 commands/tablecmds.c:22036 -#: commands/tablecmds.c:22093 +#: commands/tablecmds.c:22347 commands/tablecmds.c:22367 +#: commands/tablecmds.c:22388 commands/tablecmds.c:22407 +#: commands/tablecmds.c:22464 #, c-format msgid "cannot attach index \"%s\" as a partition of index \"%s\"" msgstr "kann Index »%s« nicht als Partition an Index »%s« anfügen" -#: commands/tablecmds.c:21979 +#: commands/tablecmds.c:22350 #, c-format msgid "Index \"%s\" is already attached to another index." msgstr "Index »%s« ist bereits an einen anderen Index angefügt." -#: commands/tablecmds.c:21999 +#: commands/tablecmds.c:22370 #, c-format msgid "Index \"%s\" is not an index on any partition of table \"%s\"." msgstr "Index »%s« ist kein Index irgendeiner Partition von Tabelle »%s«." -#: commands/tablecmds.c:22020 +#: commands/tablecmds.c:22391 #, c-format msgid "The index definitions do not match." msgstr "Die Indexdefinitionen stimmen nicht überein." -#: commands/tablecmds.c:22039 +#: commands/tablecmds.c:22410 #, c-format msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." msgstr "Der Index »%s« gehört zu einem Constraint in Tabelle »%s«, aber kein Constraint existiert für Index »%s«." -#: commands/tablecmds.c:22096 +#: commands/tablecmds.c:22467 #, fuzzy, c-format #| msgid "Another index is already attached for partition \"%s\"." msgid "Another index \"%s\" is already attached for partition \"%s\"." msgstr "Ein anderer Index ist bereits für Partition »%s« angefügt." -#: commands/tablecmds.c:22220 +#: commands/tablecmds.c:22591 #, c-format msgid "invalid primary key definition" msgstr "ungültige Primärschlüsseldefinition" -#: commands/tablecmds.c:22221 +#: commands/tablecmds.c:22592 #, c-format msgid "Column \"%s\" of relation \"%s\" is not marked NOT NULL." msgstr "Spalte »%s« von Relation »%s« ist nicht als NOT NULL markiert." -#: commands/tablecmds.c:22356 +#: commands/tablecmds.c:22727 #, c-format msgid "column data type %s does not support compression" msgstr "Spaltendatentyp %s unterstützt keine Komprimierung" -#: commands/tablecmds.c:22363 +#: commands/tablecmds.c:22734 #, c-format msgid "invalid compression method \"%s\"" msgstr "ungültige Komprimierungsmethode »%s«" -#: commands/tablecmds.c:22389 +#: commands/tablecmds.c:22760 #, c-format msgid "invalid storage type \"%s\"" msgstr "ungültiger Storage-Typ »%s«" -#: commands/tablecmds.c:22399 +#: commands/tablecmds.c:22770 #, c-format msgid "column data type %s can only have storage PLAIN" msgstr "Spaltendatentyp %s kann nur Storage-Typ PLAIN" -#: commands/tablecmds.c:22772 +#: commands/tablecmds.c:23144 #, fuzzy, c-format #| msgid "cannot attach as partition of temporary relation of another session" msgid "cannot create as partition of temporary relation of another session" msgstr "kann nicht als Partition an temporäre Relation einer anderen Sitzung anfügen" -#: commands/tablecmds.c:22809 +#: commands/tablecmds.c:23181 #, fuzzy, c-format #| msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" msgid "cannot create a permanent relation as partition of temporary relation \"%s\"" msgstr "eine permanente Relation kann nicht als Partition an temporäre Relation »%s« angefügt werden" -#: commands/tablecmds.c:23161 +#: commands/tablecmds.c:23570 #, fuzzy, c-format #| msgid "cannot alter partition \"%s\" with an incomplete detach" msgid "cannot merge partitions with conflicting extension dependencies" msgstr "kann Partition »%s« mit einer unvollständigen Abtrennoperation nicht ändern" -#: commands/tablecmds.c:23162 +#: commands/tablecmds.c:23571 #, c-format msgid "Partition indexes \"%s\" and \"%s\" depend on different extensions." msgstr "" -#: commands/tablecmds.c:23298 +#: commands/tablecmds.c:23707 #, c-format msgid "partitions being merged have different owners" msgstr "" -#: commands/tablecmds.c:23664 +#: commands/tablecmds.c:24073 #, fuzzy, c-format #| msgid "cannot inherit from a partition" -msgid "can not find partition for split partition row" +msgid "cannot find partition for split partition row" msgstr "von einer Partition kann nicht geerbt werden" #: commands/tablespace.c:195 commands/tablespace.c:652 @@ -16548,26 +16605,26 @@ msgstr "Vor der Ausführung von Trigger »%s« gehörte die Zeile in Partition msgid "cannot collect transition tuples from child foreign tables" msgstr "aus abgeleiteten Fremdtabellen können keine Übergangstupel gesammelt werden" -#: commands/trigger.c:3403 executor/nodeModifyTable.c:1974 -#: executor/nodeModifyTable.c:2048 executor/nodeModifyTable.c:2869 -#: executor/nodeModifyTable.c:2959 executor/nodeModifyTable.c:3784 -#: executor/nodeModifyTable.c:3981 +#: commands/trigger.c:3403 executor/nodeModifyTable.c:1962 +#: executor/nodeModifyTable.c:2036 executor/nodeModifyTable.c:2876 +#: executor/nodeModifyTable.c:2966 executor/nodeModifyTable.c:3791 +#: executor/nodeModifyTable.c:3988 #, c-format msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." msgstr "Verwenden Sie einen AFTER-Trigger anstelle eines BEFORE-Triggers, um Änderungen an andere Zeilen zu propagieren." #: commands/trigger.c:3445 executor/nodeLockRows.c:228 -#: executor/nodeLockRows.c:237 executor/nodeModifyTable.c:410 -#: executor/nodeModifyTable.c:1990 executor/nodeModifyTable.c:2885 -#: executor/nodeModifyTable.c:3091 executor/nodeModifyTable.c:3822 -#: utils/adt/ri_triggers.c:3247 utils/adt/ri_triggers.c:3254 +#: executor/nodeModifyTable.c:413 executor/nodeModifyTable.c:1978 +#: executor/nodeModifyTable.c:2892 executor/nodeModifyTable.c:3098 +#: executor/nodeModifyTable.c:3829 utils/adt/ri_triggers.c:3314 #, c-format msgid "could not serialize access due to concurrent update" msgstr "konnte Zugriff nicht serialisieren wegen gleichzeitiger Aktualisierung" -#: commands/trigger.c:3453 executor/nodeModifyTable.c:2080 -#: executor/nodeModifyTable.c:2976 executor/nodeModifyTable.c:3107 -#: executor/nodeModifyTable.c:3802 +#: commands/trigger.c:3453 executor/nodeLockRows.c:237 +#: executor/nodeModifyTable.c:2068 executor/nodeModifyTable.c:2983 +#: executor/nodeModifyTable.c:3114 executor/nodeModifyTable.c:3809 +#: utils/adt/ri_triggers.c:3307 #, c-format msgid "could not serialize access due to concurrent delete" msgstr "konnte Zugriff nicht serialisieren wegen gleichzeitigem Löschen" @@ -16577,12 +16634,12 @@ msgstr "konnte Zugriff nicht serialisieren wegen gleichzeitigem Löschen" msgid "cannot fire deferred trigger within security-restricted operation" msgstr "aufgeschobener Trigger kann nicht in einer sicherheitsbeschränkten Operation ausgelöst werden" -#: commands/trigger.c:5943 +#: commands/trigger.c:5948 #, c-format msgid "constraint \"%s\" is not deferrable" msgstr "Constraint »%s« ist nicht aufschiebbar" -#: commands/trigger.c:5966 +#: commands/trigger.c:5971 #, c-format msgid "constraint \"%s\" does not exist" msgstr "Constraint »%s« existiert nicht" @@ -16692,7 +16749,7 @@ msgstr "nur Superuser können Basistypen anlegen" msgid "Create the type as a shell type, then create its I/O functions, then do a full CREATE TYPE." msgstr "Erzeugen Sie den Typ als Shell-Typ, legen Sie dann die I/O-Funktionen an und führen Sie dann das volle CREATE TYPE aus." -#: commands/typecmds.c:333 commands/typecmds.c:1501 commands/typecmds.c:4523 +#: commands/typecmds.c:333 commands/typecmds.c:1508 commands/typecmds.c:4520 #, c-format msgid "type attribute \"%s\" not recognized" msgstr "Typ-Attribut »%s« nicht erkannt" @@ -16712,7 +16769,7 @@ msgstr "Arrayelementtyp kann nicht %s sein" msgid "alignment \"%s\" not recognized" msgstr "Ausrichtung »%s« nicht erkannt" -#: commands/typecmds.c:456 commands/typecmds.c:4397 +#: commands/typecmds.c:456 commands/typecmds.c:4394 #, c-format msgid "storage \"%s\" not recognized" msgstr "Storage-Typ »%s« nicht erkannt" @@ -16802,248 +16859,248 @@ msgstr "Angabe von GENERATED wird für Domänen nicht unterstützt" msgid "specifying constraint enforceability not supported for domains" msgstr "Angabe von ENFORCED/NOT ENFORCED wird für Domänen nicht unterstützt" -#: commands/typecmds.c:1363 utils/cache/typcache.c:2782 +#: commands/typecmds.c:1363 utils/cache/typcache.c:2784 #, c-format msgid "%s is not an enum" msgstr "»%s« ist kein Enum" -#: commands/typecmds.c:1509 +#: commands/typecmds.c:1516 #, c-format msgid "type attribute \"subtype\" is required" msgstr "Typ-Attribut »subtype« muss angegeben werden" -#: commands/typecmds.c:1514 +#: commands/typecmds.c:1521 #, c-format msgid "range subtype cannot be %s" msgstr "Bereichtsuntertyp kann nicht %s sein" -#: commands/typecmds.c:1533 +#: commands/typecmds.c:1540 #, c-format msgid "range collation specified but subtype does not support collation" msgstr "Sortierfolge für Bereichstyp angegeben, aber Untertyp unterstützt keine Sortierfolgen" -#: commands/typecmds.c:1543 +#: commands/typecmds.c:1550 #, c-format msgid "cannot specify a canonical function without a pre-created shell type" msgstr "Canonical-Funktion kann nicht angegeben werden ohne einen vorher angelegten Shell-Typ" -#: commands/typecmds.c:1544 +#: commands/typecmds.c:1551 #, c-format msgid "Create the type as a shell type, then create its canonicalization function, then do a full CREATE TYPE." msgstr "Erzeugen Sie den Typ als Shell-Typ, legen Sie dann die Canonicalization-Funktion an und führen Sie dann das volle CREATE TYPE aus." -#: commands/typecmds.c:2038 +#: commands/typecmds.c:2045 #, c-format msgid "type input function %s has multiple matches" msgstr "Typeingabefunktion %s hat mehrere Übereinstimmungen" -#: commands/typecmds.c:2056 +#: commands/typecmds.c:2063 #, c-format msgid "type input function %s must return type %s" msgstr "Typeingabefunktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:2072 +#: commands/typecmds.c:2079 #, c-format msgid "type input function %s should not be volatile" msgstr "Typeingabefunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:2100 +#: commands/typecmds.c:2107 #, c-format msgid "type output function %s must return type %s" msgstr "Typausgabefunktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:2107 +#: commands/typecmds.c:2114 #, c-format msgid "type output function %s should not be volatile" msgstr "Typausgabefunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:2136 +#: commands/typecmds.c:2143 #, c-format msgid "type receive function %s has multiple matches" msgstr "Typempfangsfunktion %s hat mehrere Übereinstimmungen" -#: commands/typecmds.c:2154 +#: commands/typecmds.c:2161 #, c-format msgid "type receive function %s must return type %s" msgstr "Typempfangsfunktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:2161 +#: commands/typecmds.c:2168 #, c-format msgid "type receive function %s should not be volatile" msgstr "Typempfangsfunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:2189 +#: commands/typecmds.c:2196 #, c-format msgid "type send function %s must return type %s" msgstr "Typsendefunktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:2196 +#: commands/typecmds.c:2203 #, c-format msgid "type send function %s should not be volatile" msgstr "Typsendefunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:2223 +#: commands/typecmds.c:2230 #, c-format msgid "typmod_in function %s must return type %s" msgstr "typmod_in-Funktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:2230 +#: commands/typecmds.c:2237 #, c-format msgid "type modifier input function %s should not be volatile" msgstr "Typmodifikatoreingabefunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:2257 +#: commands/typecmds.c:2264 #, c-format msgid "typmod_out function %s must return type %s" msgstr "typmod_out-Funktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:2264 +#: commands/typecmds.c:2271 #, c-format msgid "type modifier output function %s should not be volatile" msgstr "Typmodifikatorausgabefunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:2291 +#: commands/typecmds.c:2298 #, c-format msgid "type analyze function %s must return type %s" msgstr "Typanalysefunktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:2320 +#: commands/typecmds.c:2327 #, c-format msgid "type subscripting function %s must return type %s" msgstr "Typ-Subscript-Funktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:2330 +#: commands/typecmds.c:2337 #, c-format msgid "user-defined types cannot use subscripting function %s" msgstr "benutzerdefinierte Typen können Subscript-Funktion %s nicht verwenden" -#: commands/typecmds.c:2376 +#: commands/typecmds.c:2383 #, c-format msgid "You must specify an operator class for the range type or define a default operator class for the subtype." msgstr "Sie müssen für den Bereichstyp eine Operatorklasse angeben oder eine Standardoperatorklasse für den Untertyp definieren." -#: commands/typecmds.c:2407 +#: commands/typecmds.c:2414 #, c-format msgid "range canonical function %s must return range type" msgstr "Bereichstyp-Canonical-Funktion %s muss Bereichstyp zurückgeben" -#: commands/typecmds.c:2413 +#: commands/typecmds.c:2420 #, c-format msgid "range canonical function %s must be immutable" msgstr "Bereichstyp-Canonical-Funktion %s muss »immutable« sein" -#: commands/typecmds.c:2449 +#: commands/typecmds.c:2456 #, c-format msgid "range subtype diff function %s must return type %s" msgstr "Bereichstyp-Untertyp-Diff-Funktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:2456 +#: commands/typecmds.c:2463 #, c-format msgid "range subtype diff function %s must be immutable" msgstr "Bereichstyp-Untertyp-Diff-Funktion %s muss »immutable« sein" -#: commands/typecmds.c:2483 +#: commands/typecmds.c:2490 #, c-format msgid "pg_type array OID value not set when in binary upgrade mode" msgstr "Array-OID-Wert für pg_type ist im Binary-Upgrade-Modus nicht gesetzt" -#: commands/typecmds.c:2516 +#: commands/typecmds.c:2523 #, c-format msgid "pg_type multirange OID value not set when in binary upgrade mode" msgstr "Multirange-OID-Wert für pg_type ist im Binary-Upgrade-Modus nicht gesetzt" -#: commands/typecmds.c:2549 +#: commands/typecmds.c:2556 #, c-format msgid "pg_type multirange array OID value not set when in binary upgrade mode" msgstr "Multirange-Array-OID-Wert für pg_type ist im Binary-Upgrade-Modus nicht gesetzt" -#: commands/typecmds.c:2931 commands/typecmds.c:3116 +#: commands/typecmds.c:2938 commands/typecmds.c:3123 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist" msgstr "Constraint »%s« von Domäne »%s« existiert nicht" -#: commands/typecmds.c:2935 +#: commands/typecmds.c:2942 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" msgstr "Constraint »%s« von Domäne »%s« existiert nicht, wird übersprungen" -#: commands/typecmds.c:3123 +#: commands/typecmds.c:3130 #, c-format msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" msgstr "Constraint »%s« von Domäne »%s« ist kein Check-Constraint" -#: commands/typecmds.c:3212 +#: commands/typecmds.c:3214 #, c-format msgid "column \"%s\" of table \"%s\" contains null values" msgstr "Spalte »%s« von Tabelle »%s« enthält NULL-Werte" -#: commands/typecmds.c:3308 +#: commands/typecmds.c:3305 #, c-format msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" msgstr "Spalte »%s« von Tabelle »%s« enthält Werte, die den neuen Constraint verletzen" -#: commands/typecmds.c:3537 commands/typecmds.c:3815 commands/typecmds.c:3900 -#: commands/typecmds.c:4116 +#: commands/typecmds.c:3534 commands/typecmds.c:3812 commands/typecmds.c:3897 +#: commands/typecmds.c:4113 #, c-format msgid "%s is not a domain" msgstr "%s ist keine Domäne" -#: commands/typecmds.c:3571 commands/typecmds.c:3727 +#: commands/typecmds.c:3568 commands/typecmds.c:3724 #, c-format msgid "constraint \"%s\" for domain \"%s\" already exists" msgstr "Constraint »%s« für Domäne »%s« existiert bereits" -#: commands/typecmds.c:3622 +#: commands/typecmds.c:3619 #, c-format msgid "cannot use table references in domain check constraint" msgstr "Tabellenverweise können in Domänen-Check-Constraints nicht verwendet werden" -#: commands/typecmds.c:3827 commands/typecmds.c:3912 commands/typecmds.c:4266 +#: commands/typecmds.c:3824 commands/typecmds.c:3909 commands/typecmds.c:4263 #, c-format msgid "%s is a table's row type" msgstr "%s ist der Zeilentyp einer Tabelle" -#: commands/typecmds.c:3837 commands/typecmds.c:3922 commands/typecmds.c:4164 +#: commands/typecmds.c:3834 commands/typecmds.c:3919 commands/typecmds.c:4161 #, c-format msgid "cannot alter array type %s" msgstr "Array-Typ %s kann nicht verändert werden" -#: commands/typecmds.c:3839 commands/typecmds.c:3924 commands/typecmds.c:4166 +#: commands/typecmds.c:3836 commands/typecmds.c:3921 commands/typecmds.c:4163 #, c-format msgid "You can alter type %s, which will alter the array type as well." msgstr "Sie können den Typ %s ändern, wodurch der Array-Typ ebenfalls geändert wird." -#: commands/typecmds.c:3935 +#: commands/typecmds.c:3932 #, c-format msgid "cannot alter multirange type %s" msgstr "Multirange-Typ %s kann nicht verändert werden" -#: commands/typecmds.c:3938 +#: commands/typecmds.c:3935 #, c-format msgid "You can alter type %s, which will alter the multirange type as well." msgstr "Sie können den Typ %s ändern, wodurch der Multirange-Typ ebenfalls geändert wird." -#: commands/typecmds.c:4245 +#: commands/typecmds.c:4242 #, c-format msgid "type \"%s\" already exists in schema \"%s\"" msgstr "Typ %s existiert bereits in Schema »%s«" -#: commands/typecmds.c:4425 +#: commands/typecmds.c:4422 #, c-format msgid "cannot change type's storage to PLAIN" msgstr "Storage-Typ eines Typs kann nicht in PLAIN geändert werden" -#: commands/typecmds.c:4518 +#: commands/typecmds.c:4515 #, c-format msgid "type attribute \"%s\" cannot be changed" msgstr "Typ-Attribut »%s« kann nicht geändert werden" -#: commands/typecmds.c:4536 +#: commands/typecmds.c:4533 #, c-format msgid "must be superuser to alter a type" msgstr "nur Superuser können Typen ändern" -#: commands/typecmds.c:4557 commands/typecmds.c:4566 +#: commands/typecmds.c:4554 commands/typecmds.c:4563 #, c-format msgid "%s is not a base type" msgstr "%s ist kein Basistyp" @@ -17077,8 +17134,8 @@ msgid "Only roles with the %s attribute may create roles with the %s attribute." msgstr "Nur Rollen mit dem %s-Attribut können Rollen mit dem %s-Attribut erzeugen." #: commands/user.c:361 commands/user.c:1399 commands/user.c:1406 gram.y:18610 -#: gram.y:18656 utils/adt/acl.c:5759 utils/adt/acl.c:5765 -#: utils/adt/ddlutils.c:356 +#: gram.y:18656 utils/adt/acl.c:5762 utils/adt/acl.c:5768 +#: utils/adt/ddlutils.c:187 #, c-format msgid "role name \"%s\" is reserved" msgstr "Rollenname »%s« ist reserviert" @@ -17173,8 +17230,8 @@ msgstr "in DROP ROLE kann kein Rollenplatzhalter verwendet werden" #: commands/user.c:1142 commands/user.c:1370 commands/variable.c:864 #: commands/variable.c:867 commands/variable.c:983 commands/variable.c:986 -#: utils/adt/acl.c:391 utils/adt/acl.c:415 utils/adt/acl.c:5614 -#: utils/adt/acl.c:5662 utils/adt/acl.c:5690 utils/adt/acl.c:5709 +#: utils/adt/acl.c:391 utils/adt/acl.c:415 utils/adt/acl.c:5617 +#: utils/adt/acl.c:5665 utils/adt/acl.c:5693 utils/adt/acl.c:5712 #: utils/adt/regproc.c:1579 utils/init/miscinit.c:754 #, c-format msgid "role \"%s\" does not exist" @@ -17365,12 +17422,12 @@ msgstr "keine Berechtigung, um von Rolle »%s« gewährte Privilegien zu entzieh msgid "Only roles with privileges of role \"%s\" may revoke privileges granted by this role." msgstr "Nur Rollen mit den Privilegien der Rolle »%s« können von dieser Rolle gewährte Privilegien entziehen." -#: commands/user.c:2506 utils/adt/acl.c:1369 +#: commands/user.c:2506 utils/adt/acl.c:1372 #, c-format msgid "dependent privileges exist" msgstr "abhängige Privilegien existieren" -#: commands/user.c:2507 utils/adt/acl.c:1370 +#: commands/user.c:2507 utils/adt/acl.c:1373 #, c-format msgid "Use CASCADE to revoke them too." msgstr "Verwenden Sie CASCADE, um diese auch zu entziehen." @@ -17462,12 +17519,12 @@ msgstr "überspringe Analyze von »%s« --- Relation existiert nicht mehr" msgid "VACUUM ONLY of partitioned table \"%s\" has no effect" msgstr "VACUUM ONLY für partitionierte Tabelle »%s« hat keine Auswirkung" -#: commands/vacuum.c:1168 +#: commands/vacuum.c:1173 #, c-format msgid "cutoff for removing and freezing tuples is far in the past" msgstr "Obergrenze für das Entfernen und Einfrieren von Tuples ist weit in der Vergangenheit" -#: commands/vacuum.c:1169 commands/vacuum.c:1174 +#: commands/vacuum.c:1174 #, c-format msgid "" "Close open transactions soon to avoid wraparound problems.\n" @@ -17476,37 +17533,49 @@ msgstr "" "Schließen Sie bald alle offenen Transaktionen, um Überlaufprobleme zu vermeiden.\n" "Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." -#: commands/vacuum.c:1173 +#: commands/vacuum.c:1178 #, c-format msgid "cutoff for freezing multixacts is far in the past" msgstr "Obergrenze für das Einfrieren von Multixacts ist weit in der Vergangenheit" -#: commands/vacuum.c:1939 +#: commands/vacuum.c:1179 +#, fuzzy, c-format +#| msgid "" +#| "Close open transactions soon to avoid wraparound problems.\n" +#| "You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions." +msgstr "" +"Schließen Sie bald alle offenen Transaktionen, um Überlaufprobleme zu vermeiden.\n" +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." + +#: commands/vacuum.c:1944 #, c-format msgid "some databases have not been vacuumed in over 2 billion transactions" msgstr "einige Datenbanken sind seit über 2 Milliarden Transaktionen nicht gevacuumt worden" -#: commands/vacuum.c:1940 +#: commands/vacuum.c:1945 #, c-format msgid "You might have already suffered transaction-wraparound data loss." msgstr "Sie haben möglicherweise bereits Daten wegen Transaktionsnummernüberlauf verloren." -#: commands/vacuum.c:2130 +#: commands/vacuum.c:2135 #, c-format msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" msgstr "überspringe »%s« --- kann Nicht-Tabellen oder besondere Systemtabellen nicht vacuumen" -#: commands/vacuum.c:2666 +#: commands/vacuum.c:2671 #, c-format msgid "scanned index \"%s\" to remove % row versions" msgstr "Index »%s« gelesen und % Zeilenversionen entfernt" -#: commands/vacuum.c:2685 +#: commands/vacuum.c:2690 #, c-format msgid "index \"%s\" now contains %.0f row versions in %u pages" msgstr "Index »%s« enthält %.0f Zeilenversionen in %u Seiten" -#: commands/vacuum.c:2689 +#: commands/vacuum.c:2694 #, c-format msgid "" "%.0f index row versions were removed.\n" @@ -17846,172 +17915,172 @@ msgstr "Cursor »%s« ist nicht auf eine Zeile positioniert" msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" msgstr "Cursor »%s« ist kein einfach aktualisierbarer Scan der Tabelle »%s«" -#: executor/execCurrent.c:280 executor/execExprInterp.c:3095 +#: executor/execCurrent.c:280 executor/execExprInterp.c:3103 #, c-format msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" msgstr "Typ von Parameter %d (%s) stimmt nicht mit dem überein, als der Plan vorbereitet worden ist (%s)" -#: executor/execCurrent.c:292 executor/execExprInterp.c:3107 +#: executor/execCurrent.c:292 executor/execExprInterp.c:3115 #, c-format msgid "no value found for parameter %d" msgstr "kein Wert für Parameter %d gefunden" -#: executor/execExpr.c:688 executor/execExpr.c:695 executor/execExpr.c:701 -#: executor/execExprInterp.c:5443 executor/execExprInterp.c:5460 -#: executor/execExprInterp.c:5559 executor/nodeModifyTable.c:235 -#: executor/nodeModifyTable.c:254 executor/nodeModifyTable.c:271 -#: executor/nodeModifyTable.c:281 executor/nodeModifyTable.c:291 +#: executor/execExpr.c:667 executor/execExpr.c:674 executor/execExpr.c:680 +#: executor/execExprInterp.c:5513 executor/execExprInterp.c:5530 +#: executor/execExprInterp.c:5629 executor/nodeModifyTable.c:238 +#: executor/nodeModifyTable.c:257 executor/nodeModifyTable.c:274 +#: executor/nodeModifyTable.c:284 executor/nodeModifyTable.c:294 #, c-format msgid "table row type and query-specified row type do not match" msgstr "Zeilentyp der Tabelle und der von der Anfrage angegebene Zeilentyp stimmen nicht überein" -#: executor/execExpr.c:689 executor/nodeModifyTable.c:236 +#: executor/execExpr.c:668 executor/nodeModifyTable.c:239 #, c-format msgid "Query has too many columns." msgstr "Anfrage hat zu viele Spalten." -#: executor/execExpr.c:696 executor/nodeModifyTable.c:255 +#: executor/execExpr.c:675 executor/nodeModifyTable.c:258 #, c-format msgid "Query provides a value for a dropped column at ordinal position %d." msgstr "Anfrage liefert einen Wert für eine gelöschte Spalte auf Position %d." -#: executor/execExpr.c:702 executor/execExprInterp.c:5461 -#: executor/nodeModifyTable.c:282 +#: executor/execExpr.c:681 executor/execExprInterp.c:5531 +#: executor/nodeModifyTable.c:285 #, c-format msgid "Table has type %s at ordinal position %d, but query expects %s." msgstr "Tabelle hat Typ %s auf Position %d, aber Anfrage erwartet %s." -#: executor/execExpr.c:1190 parser/parse_agg.c:912 +#: executor/execExpr.c:1157 parser/parse_agg.c:912 #, c-format msgid "window function calls cannot be nested" msgstr "Aufrufe von Fensterfunktionen können nicht geschachtelt werden" -#: executor/execExpr.c:1722 +#: executor/execExpr.c:1689 #, c-format msgid "target type is not an array" msgstr "Zieltyp ist kein Array" -#: executor/execExpr.c:2065 +#: executor/execExpr.c:2032 #, c-format msgid "ROW() column has type %s instead of type %s" msgstr "ROW()-Spalte hat Typ %s statt Typ %s" -#: executor/execExpr.c:2755 executor/execSRF.c:720 parser/parse_func.c:142 -#: parser/parse_func.c:669 parser/parse_func.c:1146 +#: executor/execExpr.c:2722 executor/execSRF.c:720 parser/parse_func.c:142 +#: parser/parse_func.c:675 parser/parse_func.c:1154 #, c-format msgid "cannot pass more than %d argument to a function" msgid_plural "cannot pass more than %d arguments to a function" msgstr[0] "kann nicht mehr als %d Argument an eine Funktion übergeben" msgstr[1] "kann nicht mehr als %d Argumente an eine Funktion übergeben" -#: executor/execExpr.c:2782 executor/execSRF.c:740 executor/functions.c:1605 +#: executor/execExpr.c:2749 executor/execSRF.c:740 executor/functions.c:1605 #: utils/adt/jsonfuncs.c:4056 utils/fmgr/funcapi.c:89 utils/fmgr/funcapi.c:143 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "Funktion mit Mengenergebnis in einem Zusammenhang aufgerufen, der keine Mengenergebnisse verarbeiten kann" -#: executor/execExpr.c:3290 parser/parse_node.c:272 parser/parse_node.c:322 +#: executor/execExpr.c:3257 parser/parse_node.c:272 parser/parse_node.c:322 #, c-format msgid "cannot subscript type %s because it does not support subscripting" msgstr "kann aus Typ %s kein Element auswählen, weil er Subscripting nicht unterstützt" -#: executor/execExpr.c:3418 executor/execExpr.c:3440 +#: executor/execExpr.c:3385 executor/execExpr.c:3407 #, c-format msgid "type %s does not support subscripted assignment" msgstr "Typ %s unterstützt Wertzuweisungen in Elemente nicht" -#: executor/execExprInterp.c:2417 +#: executor/execExprInterp.c:2425 #, c-format msgid "attribute %d of type %s has been dropped" msgstr "Attribut %d von Typ %s wurde gelöscht" -#: executor/execExprInterp.c:2423 +#: executor/execExprInterp.c:2431 #, c-format msgid "attribute %d of type %s has wrong type" msgstr "Attribut %d von Typ %s hat falschen Typ" -#: executor/execExprInterp.c:2425 executor/execExprInterp.c:3784 -#: executor/execExprInterp.c:3830 +#: executor/execExprInterp.c:2433 executor/execExprInterp.c:3792 +#: executor/execExprInterp.c:3838 #, c-format msgid "Table has type %s, but query expects %s." msgstr "Tabelle hat Typ %s, aber Anfrage erwartet %s." -#: executor/execExprInterp.c:2505 utils/adt/expandedrecord.c:99 -#: utils/adt/expandedrecord.c:231 utils/cache/typcache.c:1866 -#: utils/cache/typcache.c:2025 utils/cache/typcache.c:2172 +#: executor/execExprInterp.c:2513 utils/adt/expandedrecord.c:99 +#: utils/adt/expandedrecord.c:231 utils/cache/typcache.c:1868 +#: utils/cache/typcache.c:2027 utils/cache/typcache.c:2174 #: utils/fmgr/funcapi.c:571 #, c-format msgid "type %s is not composite" msgstr "Typ %s ist kein zusammengesetzter Typ" -#: executor/execExprInterp.c:3268 +#: executor/execExprInterp.c:3276 #, c-format msgid "WHERE CURRENT OF is not supported for this table type" msgstr "WHERE CURRENT OF wird für diesen Tabellentyp nicht unterstützt" -#: executor/execExprInterp.c:3481 +#: executor/execExprInterp.c:3489 #, c-format msgid "cannot merge incompatible arrays" msgstr "kann inkompatible Arrays nicht verschmelzen" -#: executor/execExprInterp.c:3482 +#: executor/execExprInterp.c:3490 #, c-format msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." msgstr "Arrayelement mit Typ %s kann nicht in ARRAY-Konstrukt mit Elementtyp %s verwendet werden." -#: executor/execExprInterp.c:3503 utils/adt/arrayfuncs.c:1309 -#: utils/adt/arrayfuncs.c:3522 utils/adt/arrayfuncs.c:5620 -#: utils/adt/arrayfuncs.c:6140 utils/adt/arraysubs.c:152 +#: executor/execExprInterp.c:3511 utils/adt/arrayfuncs.c:1309 +#: utils/adt/arrayfuncs.c:3522 utils/adt/arrayfuncs.c:5629 +#: utils/adt/arrayfuncs.c:6147 utils/adt/arraysubs.c:152 #: utils/adt/arraysubs.c:490 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "Anzahl der Arraydimensionen (%d) überschreitet erlaubtes Maximum (%d)" -#: executor/execExprInterp.c:3523 executor/execExprInterp.c:3558 +#: executor/execExprInterp.c:3531 executor/execExprInterp.c:3566 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "mehrdimensionale Arrays müssen Arraysausdrücke mit gleicher Anzahl Dimensionen haben" -#: executor/execExprInterp.c:3535 utils/adt/arrayutils.c:83 +#: executor/execExprInterp.c:3543 utils/adt/arrayutils.c:83 #: utils/adt/arrayutils.c:92 utils/adt/arrayutils.c:99 #, c-format msgid "array size exceeds the maximum allowed (%d)" msgstr "Arraygröße überschreitet erlaubtes Maximum (%d)" -#: executor/execExprInterp.c:3783 executor/execExprInterp.c:3829 +#: executor/execExprInterp.c:3791 executor/execExprInterp.c:3837 #, c-format msgid "attribute %d has wrong type" msgstr "Attribut %d hat falschen Typ" -#: executor/execExprInterp.c:4434 utils/adt/domains.c:196 +#: executor/execExprInterp.c:4504 utils/adt/domains.c:196 #, c-format msgid "value for domain %s violates check constraint \"%s\"" msgstr "Wert für Domäne %s verletzt Check-Constraint »%s«" -#: executor/execExprInterp.c:5007 +#: executor/execExprInterp.c:5077 #, c-format msgid "no SQL/JSON item found for specified path of column \"%s\"" msgstr "kein SQL/JSON-Item für angegebenen Pfad von Spalte »%s« gefunden" -#: executor/execExprInterp.c:5012 +#: executor/execExprInterp.c:5082 #, c-format msgid "no SQL/JSON item found for specified path" msgstr "kein SQL/JSON-Item für angegebenen Pfad gefunden" #. translator: first %s is a SQL/JSON clause (e.g. ON ERROR) -#: executor/execExprInterp.c:5212 executor/execExprInterp.c:5220 +#: executor/execExprInterp.c:5282 executor/execExprInterp.c:5290 #, c-format msgid "could not coerce %s expression (%s) to the RETURNING type" msgstr "konnte %s-Ausdruck (%s) nicht in RETURNING-Typ umwandeln" -#: executor/execExprInterp.c:5444 +#: executor/execExprInterp.c:5514 #, c-format msgid "Table row contains %d attribute, but query expects %d." msgid_plural "Table row contains %d attributes, but query expects %d." msgstr[0] "Tabellenzeile enthält %d Attribut, aber Anfrage erwartet %d." msgstr[1] "Tabellenzeile enthält %d Attribute, aber Anfrage erwartet %d." -#: executor/execExprInterp.c:5560 executor/execSRF.c:980 +#: executor/execExprInterp.c:5630 executor/execSRF.c:980 #, c-format msgid "Physical storage mismatch on dropped attribute at ordinal position %d." msgstr "Physischer Speicher stimmt nicht überein mit gelöschtem Attribut auf Position %d." @@ -18056,145 +18125,156 @@ msgstr "Der Schlüssel kollidiert mit einem vorhandenen Schlüssel." msgid "empty WITHOUT OVERLAPS value found in column \"%s\" in relation \"%s\"" msgstr "leerer WITHOUT-OVERLAPS-Wert gefunden in Spalte »%s« in Relation »%s«" -#: executor/execMain.c:1100 +#: executor/execMain.c:1101 #, c-format msgid "cannot change sequence \"%s\"" msgstr "kann Sequenz »%s« nicht ändern" -#: executor/execMain.c:1106 +#: executor/execMain.c:1107 #, c-format msgid "cannot change TOAST relation \"%s\"" msgstr "kann TOAST-Relation »%s« nicht ändern" -#: executor/execMain.c:1125 +#: executor/execMain.c:1126 #, c-format msgid "cannot change materialized view \"%s\"" msgstr "kann materialisierte Sicht »%s« nicht ändern" -#: executor/execMain.c:1137 +#: executor/execMain.c:1134 +#, fuzzy, c-format +#| msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" +msgid "foreign tables don't support FOR PORTION OF" +msgstr "Fremddaten-Wrapper »%s« unterstützt IMPORT FOREIGN SCHEMA nicht" + +#: executor/execMain.c:1135 +#, fuzzy, c-format +#| msgid "\"%s\" is a foreign table" +msgid "\"%s\" is a foreign table." +msgstr "»%s« ist eine Fremdtabelle" + +#: executor/execMain.c:1146 #, c-format msgid "cannot insert into foreign table \"%s\"" msgstr "kann nicht in Fremdtabelle »%s« einfügen" -#: executor/execMain.c:1143 +#: executor/execMain.c:1152 #, c-format msgid "foreign table \"%s\" does not allow inserts" msgstr "Fremdtabelle »%s« erlaubt kein Einfügen" -#: executor/execMain.c:1150 +#: executor/execMain.c:1159 #, c-format msgid "cannot update foreign table \"%s\"" msgstr "kann Fremdtabelle »%s« nicht aktualisieren" -#: executor/execMain.c:1156 +#: executor/execMain.c:1165 #, c-format msgid "foreign table \"%s\" does not allow updates" msgstr "Fremdtabelle »%s« erlaubt kein Aktualisieren" -#: executor/execMain.c:1163 +#: executor/execMain.c:1172 #, c-format msgid "cannot delete from foreign table \"%s\"" msgstr "kann nicht aus Fremdtabelle »%s« löschen" -#: executor/execMain.c:1169 +#: executor/execMain.c:1178 #, c-format msgid "foreign table \"%s\" does not allow deletes" msgstr "Fremdtabelle »%s« erlaubt kein Löschen" -#: executor/execMain.c:1180 -#, fuzzy, c-format -#| msgid "cannot change relation \"%s\"" +#: executor/execMain.c:1189 +#, c-format msgid "cannot change property graph \"%s\"" -msgstr "kann Relation »%s« nicht ändern" +msgstr "kann Property-Graph »%s« nicht ändern" -#: executor/execMain.c:1186 +#: executor/execMain.c:1195 #, c-format msgid "cannot change relation \"%s\"" msgstr "kann Relation »%s« nicht ändern" -#: executor/execMain.c:1213 +#: executor/execMain.c:1222 #, c-format msgid "cannot lock rows in sequence \"%s\"" msgstr "kann Zeilen in Sequenz »%s« nicht sperren" -#: executor/execMain.c:1220 +#: executor/execMain.c:1229 #, c-format msgid "cannot lock rows in TOAST relation \"%s\"" msgstr "kann Zeilen in TOAST-Relation »%s« nicht sperren" -#: executor/execMain.c:1227 +#: executor/execMain.c:1236 #, c-format msgid "cannot lock rows in view \"%s\"" msgstr "kann Zeilen in Sicht »%s« nicht sperren" -#: executor/execMain.c:1235 +#: executor/execMain.c:1244 #, c-format msgid "cannot lock rows in materialized view \"%s\"" msgstr "kann Zeilen in materialisierter Sicht »%s« nicht sperren" -#: executor/execMain.c:1244 executor/execMain.c:2893 +#: executor/execMain.c:1253 executor/execMain.c:2902 #: executor/nodeLockRows.c:135 #, c-format msgid "cannot lock rows in foreign table \"%s\"" msgstr "kann Zeilen in Fremdtabelle »%s« nicht sperren" -#: executor/execMain.c:1257 +#: executor/execMain.c:1266 #, c-format msgid "cannot lock rows in relation \"%s\"" msgstr "kann Zeilen in Relation »%s« nicht sperren" -#: executor/execMain.c:1991 +#: executor/execMain.c:2000 #, c-format msgid "new row for relation \"%s\" violates partition constraint" msgstr "neue Zeile für Relation »%s« verletzt Partitions-Constraint" -#: executor/execMain.c:1993 executor/execMain.c:2105 executor/execMain.c:2243 -#: executor/execMain.c:2351 +#: executor/execMain.c:2002 executor/execMain.c:2114 executor/execMain.c:2252 +#: executor/execMain.c:2360 #, c-format msgid "Failing row contains %s." msgstr "Fehlgeschlagene Zeile enthält %s." -#: executor/execMain.c:2103 +#: executor/execMain.c:2112 #, c-format msgid "new row for relation \"%s\" violates check constraint \"%s\"" msgstr "neue Zeile für Relation »%s« verletzt Check-Constraint »%s«" -#: executor/execMain.c:2240 +#: executor/execMain.c:2249 #, c-format msgid "null value in column \"%s\" of relation \"%s\" violates not-null constraint" msgstr "NULL-Wert in Spalte »%s« von Relation »%s« verletzt Not-Null-Constraint" -#: executor/execMain.c:2349 +#: executor/execMain.c:2358 #, c-format msgid "new row violates check option for view \"%s\"" msgstr "neue Zeile verletzt Check-Option für Sicht »%s«" -#: executor/execMain.c:2359 +#: executor/execMain.c:2368 #, c-format msgid "new row violates row-level security policy \"%s\" for table \"%s\"" msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene »%s« für Tabelle »%s«" -#: executor/execMain.c:2364 +#: executor/execMain.c:2373 #, c-format msgid "new row violates row-level security policy for table \"%s\"" msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene für Tabelle »%s«" -#: executor/execMain.c:2372 +#: executor/execMain.c:2381 #, c-format msgid "target row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" msgstr "Zielzeile verletzt Policy für Sicherheit auf Zeilenebene »%s« (USING-Ausdruck) für Tabelle »%s«" -#: executor/execMain.c:2377 +#: executor/execMain.c:2386 #, c-format msgid "target row violates row-level security policy (USING expression) for table \"%s\"" msgstr "Zielzeile verletzt Policy für Sicherheit auf Zeilenebene (USING-Ausdruck) für Tabelle »%s«" -#: executor/execMain.c:2384 +#: executor/execMain.c:2393 #, c-format msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene »%s« (USING-Ausdruck) für Tabelle »%s«" -#: executor/execMain.c:2389 +#: executor/execMain.c:2398 #, c-format msgid "new row violates row-level security policy (USING expression) for table \"%s\"" msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene (USING-Ausdruck) für Tabelle »%s«" @@ -18436,7 +18516,7 @@ msgstr "Rückgabetyp %s wird von SQL-Funktionen nicht unterstützt" msgid "TSC is not supported as timing clock source" msgstr "LOCATION wird nicht mehr unterstützt" -#: executor/nodeAgg.c:4036 executor/nodeWindowAgg.c:3163 +#: executor/nodeAgg.c:4036 executor/nodeWindowAgg.c:3164 #, c-format msgid "aggregate %u needs to have compatible input type and transition type" msgstr "Aggregatfunktion %u muss kompatiblen Eingabe- und Übergangstyp haben" @@ -18481,74 +18561,74 @@ msgstr "RIGHT JOIN wird nur für Merge-Verbund-fähige Verbundbedingungen unters msgid "FULL JOIN is only supported with merge-joinable join conditions" msgstr "FULL JOIN wird nur für Merge-Verbund-fähige Verbundbedingungen unterstützt" -#: executor/nodeModifyTable.c:272 +#: executor/nodeModifyTable.c:275 #, c-format msgid "Query provides a value for a generated column at ordinal position %d." msgstr "Anfrage liefert einen Wert für eine generierte Spalte auf Position %d." -#: executor/nodeModifyTable.c:292 +#: executor/nodeModifyTable.c:295 #, c-format msgid "Query has too few columns." msgstr "Anfrage hat zu wenige Spalten." -#: executor/nodeModifyTable.c:1973 executor/nodeModifyTable.c:2047 +#: executor/nodeModifyTable.c:1961 executor/nodeModifyTable.c:2035 #, c-format msgid "tuple to be deleted was already modified by an operation triggered by the current command" msgstr "das zu löschende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" -#: executor/nodeModifyTable.c:2246 +#: executor/nodeModifyTable.c:2234 #, c-format msgid "invalid ON UPDATE specification" msgstr "ungültige ON-UPDATE-Angabe" -#: executor/nodeModifyTable.c:2247 +#: executor/nodeModifyTable.c:2235 #, c-format msgid "The result tuple would appear in a different partition than the original tuple." msgstr "Das Ergebnistupel würde in einer anderen Partition erscheinen als das ursprüngliche Tupel." -#: executor/nodeModifyTable.c:2717 +#: executor/nodeModifyTable.c:2705 #, c-format msgid "cannot move tuple across partitions when a non-root ancestor of the source partition is directly referenced in a foreign key" msgstr "Tupel kann nicht zwischen Partitionen bewegt werden, wenn ein Fremdschlüssel direkt auf einen Vorgänger (außer der Wurzel) der Quellpartition verweist" -#: executor/nodeModifyTable.c:2718 +#: executor/nodeModifyTable.c:2706 #, c-format msgid "A foreign key points to ancestor \"%s\" but not the root ancestor \"%s\"." msgstr "Ein Fremdschlüssel verweist auf den Vorgänger »%s«, aber nicht auf den Wurzelvorgänger »%s«." -#: executor/nodeModifyTable.c:2721 +#: executor/nodeModifyTable.c:2709 #, c-format msgid "Consider defining the foreign key on table \"%s\"." msgstr "Definieren Sie den Fremdschlüssel eventuell für Tabelle »%s«." #. translator: %s is a SQL command name -#: executor/nodeModifyTable.c:3069 executor/nodeModifyTable.c:3790 -#: executor/nodeModifyTable.c:3987 +#: executor/nodeModifyTable.c:3076 executor/nodeModifyTable.c:3797 +#: executor/nodeModifyTable.c:3994 #, c-format msgid "%s command cannot affect row a second time" msgstr "Befehl in %s kann eine Zeile nicht ein zweites Mal ändern" -#: executor/nodeModifyTable.c:3071 +#: executor/nodeModifyTable.c:3078 #, c-format msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." msgstr "Stellen Sie sicher, dass keine im selben Befehl fürs Einfügen vorgesehene Zeilen doppelte Werte haben, die einen Constraint verletzen würden." -#: executor/nodeModifyTable.c:3783 executor/nodeModifyTable.c:3980 +#: executor/nodeModifyTable.c:3790 executor/nodeModifyTable.c:3987 #, c-format msgid "tuple to be updated or deleted was already modified by an operation triggered by the current command" msgstr "das zu aktualisierende oder zu löschende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" -#: executor/nodeModifyTable.c:3792 executor/nodeModifyTable.c:3989 +#: executor/nodeModifyTable.c:3799 executor/nodeModifyTable.c:3996 #, c-format msgid "Ensure that not more than one source row matches any one target row." msgstr "Stellen Sie sicher, dass nicht mehr als eine Quellzeile auf jede Zielzeile passt." -#: executor/nodeModifyTable.c:3866 +#: executor/nodeModifyTable.c:3873 #, c-format msgid "tuple to be merged was already moved to another partition due to concurrent update" msgstr "das zu mergende Tupel wurde schon durch ein gleichzeitiges Update in eine andere Partition verschoben" -#: executor/nodeModifyTable.c:5603 +#: executor/nodeModifyTable.c:5638 #, c-format msgid "FOR PORTION OF target was null" msgstr "" @@ -18594,37 +18674,37 @@ msgstr "Filter für Spalte »%s« ist NULL." msgid "null is not allowed in column \"%s\"" msgstr "NULL ist in Spalte »%s« nicht erlaubt" -#: executor/nodeWindowAgg.c:402 +#: executor/nodeWindowAgg.c:403 #, c-format msgid "moving-aggregate transition function must not return null" msgstr "Moving-Aggregat-Übergangsfunktion darf nicht NULL zurückgeben" -#: executor/nodeWindowAgg.c:2223 +#: executor/nodeWindowAgg.c:2224 #, c-format msgid "frame starting offset must not be null" msgstr "Frame-Start-Offset darf nicht NULL sein" -#: executor/nodeWindowAgg.c:2237 +#: executor/nodeWindowAgg.c:2238 #, c-format msgid "frame starting offset must not be negative" msgstr "Frame-Start-Offset darf nicht negativ sein" -#: executor/nodeWindowAgg.c:2250 +#: executor/nodeWindowAgg.c:2251 #, c-format msgid "frame ending offset must not be null" msgstr "Frame-Ende-Offset darf nicht NULL sein" -#: executor/nodeWindowAgg.c:2264 +#: executor/nodeWindowAgg.c:2265 #, c-format msgid "frame ending offset must not be negative" msgstr "Frame-Ende-Offset darf nicht negativ sein" -#: executor/nodeWindowAgg.c:3079 +#: executor/nodeWindowAgg.c:3080 #, c-format msgid "aggregate function %s does not support use as a window function" msgstr "Aggregatfunktion %s unterstützt die Verwendung als Fensterfunktion nicht" -#: executor/nodeWindowAgg.c:3641 +#: executor/nodeWindowAgg.c:3664 #, c-format msgid "function %s does not allow RESPECT/IGNORE NULLS" msgstr "" @@ -18675,7 +18755,7 @@ msgstr "%s kann nicht als Cursor geöffnet werden" msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE wird nicht unterstützt" -#: executor/spi.c:1720 parser/analyze.c:3431 +#: executor/spi.c:1720 parser/analyze.c:3428 #, c-format msgid "Scrollable cursors must be READ ONLY." msgstr "Scrollbare Cursor müssen READ ONLY sein." @@ -18839,7 +18919,7 @@ msgstr "die Verwendung von GLOBAL beim Erzeugen einer temporären Tabelle ist ve msgid "for a generated column, GENERATED ALWAYS must be specified" msgstr "für eine generierte Spalte muss GENERATED ALWAYS angegeben werden" -#: gram.y:4628 utils/adt/ri_triggers.c:2390 +#: gram.y:4628 utils/adt/ri_triggers.c:2413 #, c-format msgid "MATCH PARTIAL not yet implemented" msgstr "MATCH PARTIAL ist noch nicht implementiert" @@ -18879,7 +18959,7 @@ msgstr "CREATE OR REPLACE CONSTRAINT TRIGGER wird nicht unterstützt" msgid "duplicate trigger events specified" msgstr "mehrere Trigger-Ereignisse angegeben" -#: gram.y:6425 parser/parse_utilcmd.c:4268 parser/parse_utilcmd.c:4294 +#: gram.y:6425 parser/parse_utilcmd.c:4271 parser/parse_utilcmd.c:4297 #, c-format msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" msgstr "Constraint, der als INITIALLY DEFERRED deklariert wurde, muss DEFERRABLE sein" @@ -19217,7 +19297,7 @@ msgstr "zu viele Syntaxfehler gefunden, Datei »%s« wird aufgegeben" #: jsonpath_gram.y:270 jsonpath_gram.y:631 jsonpath_scan.l:625 #: jsonpath_scan.l:636 jsonpath_scan.l:646 jsonpath_scan.l:698 -#: utils/adt/bytea.c:259 utils/adt/encode.c:755 utils/adt/encode.c:820 +#: utils/adt/bytea.c:258 utils/adt/encode.c:755 utils/adt/encode.c:820 #: utils/adt/jsonfuncs.c:664 #, c-format msgid "invalid input syntax for type %s" @@ -19255,7 +19335,7 @@ msgstr "ungültige hexadezimale Zeichensequenz" msgid "unexpected end after backslash" msgstr "unerwartetes Ende nach Backslash" -#: jsonpath_scan.l:201 repl_scanner.l:217 scan.l:719 +#: jsonpath_scan.l:201 repl_scanner.l:221 scan.l:719 msgid "unterminated quoted string" msgstr "Zeichenkette in Anführungszeichen nicht abgeschlossen" @@ -19424,8 +19504,9 @@ msgid "OAuth is not properly configured for this user" msgstr "OAuth ist für diesen Benutzer nicht richtig konfiguriert." #: libpq/auth-oauth.c:545 -#, c-format -msgid "The issuer and scope parameters must be set in pg_hba.conf." +#, fuzzy, c-format +#| msgid "The issuer and scope parameters must be set in pg_hba.conf." +msgid "The options \"issuer\" and \"scope\" must be set in pg_hba.conf." msgstr "Die Parameter issuer und scope müssen in pg_hba.conf gesetzt sein." #: libpq/auth-oauth.c:619 libpq/auth-oauth.c:636 libpq/auth-oauth.c:658 @@ -19467,13 +19548,15 @@ msgid "Validator provided no identity." msgstr "Validator hat keine Identität angegeben." #: libpq/auth-oauth.c:794 -#, c-format -msgid "%s module \"%s\" must define the symbol %s" +#, fuzzy, c-format +#| msgid "%s module \"%s\" must define the symbol %s" +msgid "OAuth validator module \"%s\" must define the symbol \"%s\"" msgstr "%s-Modul »%s« muss das Symbol %s definieren" #: libpq/auth-oauth.c:807 -#, c-format -msgid "%s module \"%s\": magic number mismatch" +#, fuzzy, c-format +#| msgid "%s module \"%s\": magic number mismatch" +msgid "OAuth validator module \"%s\": magic number mismatch" msgstr "%s-Modul »%s«: magische Zahl stimmt nicht überein" #: libpq/auth-oauth.c:809 @@ -19482,23 +19565,25 @@ msgid "Server has magic number 0x%08X, module has 0x%08X." msgstr "Server hat magische Zahl 0x%08X, Modul hat 0x%08X." #: libpq/auth-oauth.c:818 -#, c-format -msgid "%s module \"%s\" must provide a %s callback" +#, fuzzy, c-format +#| msgid "%s module \"%s\" must provide a %s callback" +msgid "OAuth validator module \"%s\" must provide a \"%s\" callback" msgstr "%s-Modul »%s« muss einen %s-Callback zur Verfügung stellen" #: libpq/auth-oauth.c:870 -#, c-format -msgid "oauth_validator_libraries must be set for authentication method %s" +#, fuzzy, c-format +#| msgid "oauth_validator_libraries must be set for authentication method %s" +msgid "parameter \"%s\" must be set for authentication method \"%s\"" msgstr "oauth_validator_libraries muss gesetzt sein für Authentifizierungsmethode \"%s\"" -#: libpq/auth-oauth.c:872 libpq/auth-oauth.c:905 libpq/auth-oauth.c:921 -#: libpq/auth-oauth.c:1074 libpq/be-secure-common.c:223 +#: libpq/auth-oauth.c:872 libpq/auth-oauth.c:906 libpq/auth-oauth.c:923 +#: libpq/auth-oauth.c:1076 libpq/be-secure-common.c:223 #: libpq/be-secure-common.c:238 libpq/be-secure-common.c:248 #: libpq/be-secure-common.c:262 libpq/be-secure-common.c:272 #: libpq/be-secure-common.c:289 libpq/be-secure-common.c:306 #: libpq/be-secure-common.c:334 libpq/be-secure-common.c:344 -#: libpq/be-secure-openssl.c:272 libpq/be-secure-openssl.c:286 -#: libpq/be-secure-openssl.c:311 libpq/hba.c:327 libpq/hba.c:662 +#: libpq/be-secure-openssl.c:270 libpq/be-secure-openssl.c:284 +#: libpq/be-secure-openssl.c:309 libpq/hba.c:327 libpq/hba.c:662 #: libpq/hba.c:1247 libpq/hba.c:1267 libpq/hba.c:1290 libpq/hba.c:1303 #: libpq/hba.c:1356 libpq/hba.c:1384 libpq/hba.c:1392 libpq/hba.c:1404 #: libpq/hba.c:1425 libpq/hba.c:1438 libpq/hba.c:1463 libpq/hba.c:1490 @@ -19515,39 +19600,41 @@ msgid "line %d of configuration file \"%s\"" msgstr "Zeile %d in Konfigurationsdatei »%s«" #: libpq/auth-oauth.c:904 -#, c-format -msgid "authentication method \"oauth\" requires argument \"validator\" to be set when oauth_validator_libraries contains multiple options" +#, fuzzy, c-format +#| msgid "authentication method \"oauth\" requires argument \"validator\" to be set when oauth_validator_libraries contains multiple options" +msgid "authentication method \"oauth\" requires option \"validator\" to be set when \"%s\" contains multiple options" msgstr "Authentifizierungsmethode »oauth« erfordert, dass das Argument »validator« gesetzt ist, wenn oauth_validator_libraries mehrere Optionen enthält" -#: libpq/auth-oauth.c:919 -#, c-format -msgid "validator \"%s\" is not permitted by %s" +#: libpq/auth-oauth.c:921 +#, fuzzy, c-format +#| msgid "validator \"%s\" is not permitted by %s" +msgid "validator \"%s\" is not permitted by \"%s\"" msgstr "Validator »%s« ist nicht durch %s erlaubt" -#: libpq/auth-oauth.c:971 +#: libpq/auth-oauth.c:973 #, c-format msgid "HBA option name \"%s\" is invalid and will be ignored" msgstr "" #. translator: the second %s is a function name -#: libpq/auth-oauth.c:974 +#: libpq/auth-oauth.c:976 #, fuzzy, c-format #| msgid "validator \"%s\" is not permitted by %s" msgid "validator module \"%s\", in call to %s" msgstr "Validator »%s« ist nicht durch %s erlaubt" -#: libpq/auth-oauth.c:1064 libpq/auth-oauth.c:1068 libpq/hba.c:2322 +#: libpq/auth-oauth.c:1066 libpq/auth-oauth.c:1070 libpq/hba.c:2322 #, c-format msgid "unrecognized authentication option name: \"%s\"" msgstr "unbekannter Authentifizierungsoptionsname: »%s«" #. translator: the first %s is the name of the module -#: libpq/auth-oauth.c:1071 +#: libpq/auth-oauth.c:1073 #, c-format msgid "The installed validator module (\"%s\") did not define an option named \"%s\"." msgstr "" -#: libpq/auth-oauth.c:1073 +#: libpq/auth-oauth.c:1075 #, c-format msgid "All OAuth connections matching this line will fail. Correct the option and reload the server configuration." msgstr "" @@ -19677,456 +19764,467 @@ msgstr "Fehlerhafter Proof in »client-final-message«." msgid "Garbage found at the end of client-final-message." msgstr "Müll am Ende der »client-final-message« gefunden." -#: libpq/auth.c:259 +#: libpq/auth.c:261 #, c-format msgid "authentication failed for user \"%s\": host rejected" msgstr "Authentifizierung für Benutzer »%s« fehlgeschlagen: Host abgelehnt" -#: libpq/auth.c:262 +#: libpq/auth.c:264 #, c-format msgid "\"trust\" authentication failed for user \"%s\"" msgstr "»trust«-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:265 +#: libpq/auth.c:267 #, c-format msgid "Ident authentication failed for user \"%s\"" msgstr "Ident-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:268 +#: libpq/auth.c:270 #, c-format msgid "Peer authentication failed for user \"%s\"" msgstr "Peer-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:273 +#: libpq/auth.c:275 #, c-format msgid "password authentication failed for user \"%s\"" msgstr "Passwort-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:278 +#: libpq/auth.c:280 #, c-format msgid "GSSAPI authentication failed for user \"%s\"" msgstr "GSSAPI-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:281 +#: libpq/auth.c:283 #, c-format msgid "SSPI authentication failed for user \"%s\"" msgstr "SSPI-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:284 +#: libpq/auth.c:286 #, c-format msgid "PAM authentication failed for user \"%s\"" msgstr "PAM-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:287 +#: libpq/auth.c:289 #, c-format msgid "BSD authentication failed for user \"%s\"" msgstr "BSD-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:290 +#: libpq/auth.c:292 #, c-format msgid "LDAP authentication failed for user \"%s\"" msgstr "LDAP-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:293 +#: libpq/auth.c:295 #, c-format msgid "certificate authentication failed for user \"%s\"" msgstr "Zertifikatauthentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:296 +#: libpq/auth.c:298 #, c-format msgid "OAuth bearer authentication failed for user \"%s\"" msgstr "OAuth-Bearer-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:299 +#: libpq/auth.c:301 #, c-format msgid "authentication failed for user \"%s\": invalid authentication method" msgstr "Authentifizierung für Benutzer »%s« fehlgeschlagen: ungültige Authentifizierungsmethode" -#: libpq/auth.c:303 +#: libpq/auth.c:305 #, c-format msgid "Connection matched file \"%s\" line %d: \"%s\"" msgstr "Verbindung stimmte mit Datei »%s« Zeile %d überein: »%s«" -#: libpq/auth.c:349 +#: libpq/auth.c:351 #, c-format msgid "authentication identifier set more than once" msgstr "Authentifizierungsbezeichner mehrmals gesetzt" -#: libpq/auth.c:350 +#: libpq/auth.c:352 #, c-format msgid "previous identifier: \"%s\"; new identifier: \"%s\"" msgstr "vorheriger Bezeichner: »%s«; neuer Bezeichner: »%s«" -#: libpq/auth.c:360 +#: libpq/auth.c:362 #, c-format msgid "connection authenticated: identity=\"%s\" method=%s (%s:%d)" msgstr "Verbindung authentifiziert: Identität=»%s« Methode=%s (%s:%d)" -#: libpq/auth.c:409 +#: libpq/auth.c:411 #, c-format msgid "client certificates can only be checked if a root certificate store is available" msgstr "Client-Zertifikate können nur überprüft werden, wenn Wurzelzertifikat verfügbar ist" -#: libpq/auth.c:420 +#: libpq/auth.c:422 #, c-format msgid "connection requires a valid client certificate" msgstr "Verbindung erfordert ein gültiges Client-Zertifikat" -#: libpq/auth.c:451 libpq/auth.c:497 +#: libpq/auth.c:453 libpq/auth.c:499 msgid "GSS encryption" msgstr "GSS-Verschlüsselung" -#: libpq/auth.c:454 libpq/auth.c:500 +#: libpq/auth.c:456 libpq/auth.c:502 msgid "SSL encryption" msgstr "SSL-Verschlüsselung" -#: libpq/auth.c:456 libpq/auth.c:502 +#: libpq/auth.c:458 libpq/auth.c:504 msgid "no encryption" msgstr "keine Verschlüsselung" #. translator: last %s describes encryption state -#: libpq/auth.c:462 +#: libpq/auth.c:464 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" msgstr "pg_hba.conf lehnt Replikationsverbindung ab für Host »%s«, Benutzer »%s«, %s" #. translator: last %s describes encryption state -#: libpq/auth.c:469 +#: libpq/auth.c:471 #, c-format msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "pg_hba.conf lehnt Verbindung ab für Host »%s«, Benutzer »%s«, Datenbank »%s«, %s" -#: libpq/auth.c:507 +#: libpq/auth.c:509 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup matches." msgstr "Auflösung der Client-IP-Adresse ergab »%s«, Vorwärtsauflösung stimmt überein." -#: libpq/auth.c:510 +#: libpq/auth.c:512 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup not checked." msgstr "Auflösung der Client-IP-Adresse ergab »%s«, Vorwärtsauflösung nicht geprüft." -#: libpq/auth.c:513 +#: libpq/auth.c:515 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup does not match." msgstr "Auflösung der Client-IP-Adresse ergab »%s«, Vorwärtsauflösung stimmt nicht überein." -#: libpq/auth.c:516 +#: libpq/auth.c:518 #, c-format msgid "Could not translate client host name \"%s\" to IP address: %s." msgstr "Konnte Client-Hostnamen »%s« nicht in IP-Adresse übersetzen: %s." -#: libpq/auth.c:521 +#: libpq/auth.c:523 #, c-format msgid "Could not resolve client IP address to a host name: %s." msgstr "Konnte Client-IP-Adresse nicht in einen Hostnamen auflösen: %s." #. translator: last %s describes encryption state -#: libpq/auth.c:529 +#: libpq/auth.c:531 #, c-format msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" msgstr "kein pg_hba.conf-Eintrag für Replikationsverbindung von Host »%s«, Benutzer »%s«, %s" #. translator: last %s describes encryption state -#: libpq/auth.c:537 +#: libpq/auth.c:539 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "kein pg_hba.conf-Eintrag für Host »%s«, Benutzer »%s«, Datenbank »%s«, %s" -#: libpq/auth.c:659 +#: libpq/auth.c:661 #, c-format msgid "connection authenticated: user=\"%s\" method=%s (%s:%d)" msgstr "Verbindung authentifiziert: Benutzer=»%s« Methode=%s (%s:%d)" -#: libpq/auth.c:731 +#: libpq/auth.c:733 #, c-format msgid "expected password response, got message type %d" msgstr "Passwort-Antwort erwartet, Message-Typ %d empfangen" -#: libpq/auth.c:752 +#: libpq/auth.c:754 #, c-format msgid "invalid password packet size" msgstr "ungültige Größe des Passwortpakets" -#: libpq/auth.c:770 +#: libpq/auth.c:772 #, c-format msgid "empty password returned by client" msgstr "Client gab leeres Passwort zurück" -#: libpq/auth.c:898 +#: libpq/auth.c:906 #, c-format msgid "could not generate random MD5 salt" msgstr "konnte zufälliges MD5-Salt nicht erzeugen" -#: libpq/auth.c:949 libpq/be-secure-gssapi.c:555 +#: libpq/auth.c:945 +#, fuzzy +#| msgid "setting an MD5-encrypted password" +msgid "authenticated with an MD5-encrypted password" +msgstr "ein MD5-verschlüsseltes Passwort wird gesetzt" + +#: libpq/auth.c:946 libpq/crypt.c:247 +#, c-format +msgid "MD5 password support is deprecated and will be removed in a future release of PostgreSQL." +msgstr "Unterstützung für MD5-Passwörter ist veraltet und wird in einer zukünftigen Version von PostgreSQL entfernt werden." + +#: libpq/auth.c:982 libpq/be-secure-gssapi.c:555 #, c-format msgid "could not set environment: %m" msgstr "konnte Umgebung nicht setzen: %m" -#: libpq/auth.c:988 +#: libpq/auth.c:1021 #, c-format msgid "expected GSS response, got message type %d" msgstr "GSS-Antwort erwartet, Message-Typ %d empfangen" -#: libpq/auth.c:1054 +#: libpq/auth.c:1087 msgid "accepting GSS security context failed" msgstr "Annahme des GSS-Sicherheitskontexts fehlgeschlagen" -#: libpq/auth.c:1095 +#: libpq/auth.c:1128 msgid "retrieving GSS user name failed" msgstr "Abfrage des GSS-Benutzernamens fehlgeschlagen" -#: libpq/auth.c:1241 +#: libpq/auth.c:1274 msgid "could not acquire SSPI credentials" msgstr "konnte SSPI-Credentials nicht erhalten" -#: libpq/auth.c:1266 +#: libpq/auth.c:1299 #, c-format msgid "expected SSPI response, got message type %d" msgstr "SSPI-Antwort erwartet, Message-Typ %d empfangen" -#: libpq/auth.c:1344 +#: libpq/auth.c:1377 msgid "could not accept SSPI security context" msgstr "konnte SSPI-Sicherheitskontext nicht akzeptieren" -#: libpq/auth.c:1385 +#: libpq/auth.c:1418 msgid "could not get token from SSPI security context" msgstr "konnte kein Token vom SSPI-Sicherheitskontext erhalten" -#: libpq/auth.c:1521 libpq/auth.c:1540 +#: libpq/auth.c:1554 libpq/auth.c:1573 #, c-format msgid "could not translate name" msgstr "konnte Namen nicht umwandeln" -#: libpq/auth.c:1553 +#: libpq/auth.c:1586 #, c-format msgid "realm name too long" msgstr "Realm-Name zu lang" -#: libpq/auth.c:1568 +#: libpq/auth.c:1601 #, c-format msgid "translated account name too long" msgstr "umgewandelter Account-Name zu lang" -#: libpq/auth.c:1756 +#: libpq/auth.c:1789 #, c-format msgid "could not create socket for Ident connection: %m" msgstr "konnte Socket für Ident-Verbindung nicht erzeugen: %m" -#: libpq/auth.c:1771 +#: libpq/auth.c:1804 #, c-format msgid "could not bind to local address \"%s\": %m" msgstr "konnte nicht mit lokaler Adresse »%s« verbinden: %m" -#: libpq/auth.c:1783 +#: libpq/auth.c:1816 #, c-format msgid "could not connect to Ident server at address \"%s\", port %s: %m" msgstr "konnte nicht mit Ident-Server auf Adresse »%s«, Port %s verbinden: %m" -#: libpq/auth.c:1805 +#: libpq/auth.c:1838 #, c-format msgid "could not send query to Ident server at address \"%s\", port %s: %m" msgstr "konnte Anfrage an Ident-Server auf Adresse »%s«, Port %s nicht senden: %m" -#: libpq/auth.c:1822 +#: libpq/auth.c:1855 #, c-format msgid "could not receive response from Ident server at address \"%s\", port %s: %m" msgstr "konnte Antwort von Ident-Server auf Adresse »%s«, Port %s nicht empfangen: %m" -#: libpq/auth.c:1832 +#: libpq/auth.c:1865 #, c-format msgid "invalidly formatted response from Ident server: \"%s\"" msgstr "ungültig formatierte Antwort vom Ident-Server: »%s«" -#: libpq/auth.c:1888 +#: libpq/auth.c:1921 #, c-format msgid "peer authentication is not supported on this platform" msgstr "Peer-Authentifizierung wird auf dieser Plattform nicht unterstützt" -#: libpq/auth.c:1892 +#: libpq/auth.c:1925 #, c-format msgid "could not get peer credentials: %m" msgstr "konnte Credentials von Gegenstelle nicht ermitteln: %m" -#: libpq/auth.c:1902 +#: libpq/auth.c:1935 #, c-format msgid "could not look up local user ID %ld: %m" msgstr "konnte lokale Benutzer-ID %ld nicht nachschlagen: %m" -#: libpq/auth.c:1908 +#: libpq/auth.c:1941 #, c-format msgid "local user with ID %ld does not exist" msgstr "lokaler Benutzer mit ID %ld existiert nicht" -#: libpq/auth.c:2008 +#: libpq/auth.c:2041 #, c-format msgid "error from underlying PAM layer: %s" msgstr "Fehler von der unteren PAM-Ebene: %s" -#: libpq/auth.c:2019 +#: libpq/auth.c:2052 #, c-format msgid "unsupported PAM conversation %d/\"%s\"" msgstr "nicht unterstützte PAM-Conversation: %d/»%s«" -#: libpq/auth.c:2076 +#: libpq/auth.c:2109 #, c-format msgid "could not create PAM authenticator: %s" msgstr "konnte PAM-Authenticator nicht erzeugen: %s" -#: libpq/auth.c:2087 +#: libpq/auth.c:2120 #, c-format msgid "pam_set_item(PAM_USER) failed: %s" msgstr "pam_set_item(PAM_USER) fehlgeschlagen: %s" -#: libpq/auth.c:2119 +#: libpq/auth.c:2152 #, c-format msgid "pam_set_item(PAM_RHOST) failed: %s" msgstr "pam_set_item(PAM_RHOST) fehlgeschlagen: %s" -#: libpq/auth.c:2131 +#: libpq/auth.c:2164 #, c-format msgid "pam_set_item(PAM_CONV) failed: %s" msgstr "pam_set_item(PAM_CONV) fehlgeschlagen: %s" -#: libpq/auth.c:2144 +#: libpq/auth.c:2177 #, c-format msgid "pam_authenticate failed: %s" msgstr "pam_authenticate fehlgeschlagen: %s" -#: libpq/auth.c:2157 +#: libpq/auth.c:2190 #, c-format msgid "pam_acct_mgmt failed: %s" msgstr "pam_acct_mgmt fehlgeschlagen: %s" -#: libpq/auth.c:2168 +#: libpq/auth.c:2201 #, c-format msgid "could not release PAM authenticator: %s" msgstr "konnte PAM-Authenticator nicht freigeben: %s" -#: libpq/auth.c:2248 +#: libpq/auth.c:2281 #, fuzzy, c-format #| msgid "could not initialize LDAP: error code %d" msgid "could not initialize LDAP: error code %lu" msgstr "konnte LDAP nicht initialisieren: Fehlercode %d" -#: libpq/auth.c:2285 +#: libpq/auth.c:2318 #, c-format msgid "could not extract domain name from ldapbasedn" msgstr "konnte keinen Domain-Namen aus ldapbasedn herauslesen" -#: libpq/auth.c:2293 +#: libpq/auth.c:2326 #, c-format msgid "LDAP authentication could not find DNS SRV records for \"%s\"" msgstr "LDAP-Authentifizierung konnte keine DNS-SRV-Einträge für »%s« finden" -#: libpq/auth.c:2295 +#: libpq/auth.c:2328 #, c-format msgid "Set an LDAP server name explicitly." msgstr "Geben Sie einen LDAP-Servernamen explizit an." -#: libpq/auth.c:2347 +#: libpq/auth.c:2380 #, c-format msgid "could not initialize LDAP: %s" msgstr "konnte LDAP nicht initialisieren: %s" -#: libpq/auth.c:2357 +#: libpq/auth.c:2390 #, c-format msgid "ldaps not supported with this LDAP library" msgstr "ldaps wird mit dieser LDAP-Bibliothek nicht unterstützt" -#: libpq/auth.c:2365 +#: libpq/auth.c:2398 #, c-format msgid "could not initialize LDAP: %m" msgstr "konnte LDAP nicht initialisieren: %m" -#: libpq/auth.c:2375 +#: libpq/auth.c:2408 #, c-format msgid "could not set LDAP protocol version: %s" msgstr "konnte LDAP-Protokollversion nicht setzen: %s" -#: libpq/auth.c:2391 +#: libpq/auth.c:2424 #, c-format msgid "could not start LDAP TLS session: %s" msgstr "konnte LDAP-TLS-Sitzung nicht starten: %s" -#: libpq/auth.c:2468 +#: libpq/auth.c:2501 #, c-format msgid "LDAP server not specified, and no ldapbasedn" msgstr "LDAP-Server nicht angegeben, und kein ldapbasedn" -#: libpq/auth.c:2475 +#: libpq/auth.c:2508 #, c-format msgid "LDAP server not specified" msgstr "LDAP-Server nicht angegeben" -#: libpq/auth.c:2537 +#: libpq/auth.c:2570 #, c-format msgid "invalid character in user name for LDAP authentication" msgstr "ungültiges Zeichen im Benutzernamen für LDAP-Authentifizierung" -#: libpq/auth.c:2554 +#: libpq/auth.c:2587 #, c-format msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" msgstr "erstes LDAP-Binden für ldapbinddn »%s« auf Server »%s« fehlgeschlagen: %s" -#: libpq/auth.c:2584 +#: libpq/auth.c:2617 #, c-format msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" msgstr "konnte LDAP nicht mit Filter »%s« auf Server »%s« durchsuchen: %s" -#: libpq/auth.c:2600 +#: libpq/auth.c:2633 #, c-format msgid "LDAP user \"%s\" does not exist" msgstr "LDAP-Benutzer »%s« existiert nicht" -#: libpq/auth.c:2601 +#: libpq/auth.c:2634 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." msgstr "LDAP-Suche nach Filter »%s« auf Server »%s« gab keine Einträge zurück." -#: libpq/auth.c:2605 +#: libpq/auth.c:2638 #, c-format msgid "LDAP user \"%s\" is not unique" msgstr "LDAP-Benutzer »%s« ist nicht eindeutig" -#: libpq/auth.c:2606 +#: libpq/auth.c:2639 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." msgstr[0] "LDAP-Suche nach Filter »%s« auf Server »%s« gab %d Eintrag zurück." msgstr[1] "LDAP-Suche nach Filter »%s« auf Server »%s« gab %d Einträge zurück." -#: libpq/auth.c:2626 +#: libpq/auth.c:2659 #, c-format msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" msgstr "konnte DN fũr den ersten Treffer für »%s« auf Server »%s« nicht lesen: %s" -#: libpq/auth.c:2653 +#: libpq/auth.c:2686 #, c-format msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" msgstr "LDAP-Login fehlgeschlagen für Benutzer »%s« auf Server »%s«: %s" -#: libpq/auth.c:2685 +#: libpq/auth.c:2718 #, c-format msgid "LDAP diagnostics: %s" msgstr "LDAP-Diagnostik: %s" -#: libpq/auth.c:2723 +#: libpq/auth.c:2756 #, c-format msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" msgstr "Zertifikatauthentifizierung für Benutzer »%s« fehlgeschlagen: Client-Zertifikat enthält keinen Benutzernamen" -#: libpq/auth.c:2744 +#: libpq/auth.c:2777 #, c-format msgid "certificate authentication failed for user \"%s\": unable to retrieve subject DN" msgstr "Zertifikatauthentifizierung für Benutzer »%s« fehlgeschlagen: konnte Subject-DN nicht abfragen" -#: libpq/auth.c:2767 +#: libpq/auth.c:2800 #, c-format msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": DN mismatch" msgstr "Zertifikatüberprüfung (clientcert=verify=full) für Benutzer »%s« fehlgeschlagen: DN stimmt nicht überein" -#: libpq/auth.c:2772 +#: libpq/auth.c:2805 #, c-format msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch" msgstr "Zertifikatüberprüfung (clientcert=verify=full) für Benutzer »%s« fehlgeschlagen: CN stimmt nicht überein" @@ -20300,295 +20398,295 @@ msgstr "konnte GSSAPI-Sicherheitskontext nicht akzeptieren" msgid "GSSAPI size check error" msgstr "GSSAPI-Fehler bei der Größenprüfung" -#: libpq/be-secure-openssl.c:216 +#: libpq/be-secure-openssl.c:214 #, fuzzy, c-format #| msgid "ldaps not supported with this LDAP library" msgid "ssl_sni is not supported with LibreSSL" msgstr "ldaps wird mit dieser LDAP-Bibliothek nicht unterstützt" -#: libpq/be-secure-openssl.c:233 +#: libpq/be-secure-openssl.c:231 #, fuzzy, c-format #| msgid "could not load library \"%s\": %s" msgid "could not load \"%s\": %s" msgstr "konnte Bibliothek »%s« nicht laden: %s" -#: libpq/be-secure-openssl.c:271 +#: libpq/be-secure-openssl.c:269 #, fuzzy, c-format #| msgid "multiple recovery targets specified" msgid "multiple default hosts specified" msgstr "mehrere Wiederherstellungsziele angegeben" -#: libpq/be-secure-openssl.c:285 +#: libpq/be-secure-openssl.c:283 #, fuzzy, c-format #| msgid "multiple recovery targets specified" msgid "multiple no_sni hosts specified" msgstr "mehrere Wiederherstellungsziele angegeben" -#: libpq/be-secure-openssl.c:309 +#: libpq/be-secure-openssl.c:307 #, fuzzy, c-format #| msgid "multiple recovery targets specified" msgid "multiple entries for host \"%s\" specified" msgstr "mehrere Wiederherstellungsziele angegeben" -#: libpq/be-secure-openssl.c:367 +#: libpq/be-secure-openssl.c:365 #, fuzzy, c-format #| msgid "SSL configuration was not reloaded" msgid "no SSL configurations loaded" msgstr "SSL-Konfiguration wurde nicht neu geladen" #. translator: The two %s contain filenames -#: libpq/be-secure-openssl.c:369 +#: libpq/be-secure-openssl.c:367 #, fuzzy, c-format #| msgid "line %d of configuration file \"%s\": \"%s\"" msgid "If ssl_sni is enabled then add configuration to \"%s\", else \"%s\"" msgstr "Zeile %d in Konfigurationsdatei »%s«: »%s«" -#: libpq/be-secure-openssl.c:390 libpq/be-secure-openssl.c:622 +#: libpq/be-secure-openssl.c:388 libpq/be-secure-openssl.c:620 #, c-format msgid "could not create SSL context: %s" msgstr "konnte SSL-Kontext nicht erzeugen: %s" #. translator: first %s is a GUC option name, second %s is its value -#: libpq/be-secure-openssl.c:425 libpq/be-secure-openssl.c:448 +#: libpq/be-secure-openssl.c:423 libpq/be-secure-openssl.c:446 #, c-format msgid "\"%s\" setting \"%s\" not supported by this build" msgstr "»%s«-Wert »%s« wird von dieser Installation nicht unterstützt" -#: libpq/be-secure-openssl.c:435 +#: libpq/be-secure-openssl.c:433 #, c-format msgid "could not set minimum SSL protocol version" msgstr "konnte minimale SSL-Protokollversion nicht setzen" -#: libpq/be-secure-openssl.c:458 +#: libpq/be-secure-openssl.c:456 #, c-format msgid "could not set maximum SSL protocol version" msgstr "konnte maximale SSL-Protokollversion nicht setzen" -#: libpq/be-secure-openssl.c:475 +#: libpq/be-secure-openssl.c:473 #, c-format msgid "could not set SSL protocol version range" msgstr "konnte SSL-Protokollversionsbereich nicht setzen" -#: libpq/be-secure-openssl.c:476 +#: libpq/be-secure-openssl.c:474 #, c-format msgid "\"%s\" cannot be higher than \"%s\"" msgstr "»%s« kann nicht höher als »%s« sein" -#: libpq/be-secure-openssl.c:529 +#: libpq/be-secure-openssl.c:527 #, c-format msgid "could not set the TLSv1.2 cipher list (no valid ciphers available)" msgstr "konnte TLSv1.2-Cipher-Liste nicht setzen (keine gültigen Ciphers verfügbar)" -#: libpq/be-secure-openssl.c:544 +#: libpq/be-secure-openssl.c:542 #, c-format msgid "could not set the TLSv1.3 cipher suites (no valid ciphers available)" msgstr "konnte TLSv1.3-Cipher-Suites nicht setzen (keine gültigen Ciphers verfügbar)" -#: libpq/be-secure-openssl.c:643 +#: libpq/be-secure-openssl.c:641 #, c-format msgid "SNI is enabled; installed TLS init hook will be ignored" msgstr "" #. translator: first %s is a GUC, second %s contains a filename -#: libpq/be-secure-openssl.c:645 +#: libpq/be-secure-openssl.c:643 #, c-format msgid "TLS init hooks are incompatible with SNI. Set \"%s\" to \"off\" to make use of the hook that is currently installed, or remove the hook and use per-host passphrase commands in \"%s\"." msgstr "" -#: libpq/be-secure-openssl.c:697 +#: libpq/be-secure-openssl.c:695 #, c-format msgid "could not load server certificate file \"%s\": %s" msgstr "konnte Serverzertifikatsdatei »%s« nicht laden: %s" -#: libpq/be-secure-openssl.c:721 +#: libpq/be-secure-openssl.c:719 #, c-format msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" msgstr "private Schlüsseldatei »%s« kann nicht neu geladen werden, weil sie eine Passphrase benötigt" -#: libpq/be-secure-openssl.c:726 +#: libpq/be-secure-openssl.c:724 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "konnte private Schlüsseldatei »%s« nicht laden: %s" -#: libpq/be-secure-openssl.c:735 +#: libpq/be-secure-openssl.c:733 #, c-format msgid "check of private key failed: %s" msgstr "Überprüfung des privaten Schlüssels fehlgeschlagen: %s" -#: libpq/be-secure-openssl.c:752 +#: libpq/be-secure-openssl.c:750 #, c-format msgid "could not load root certificate file \"%s\": %s" msgstr "konnte Root-Zertifikat-Datei »%s« nicht laden: %s" -#: libpq/be-secure-openssl.c:791 +#: libpq/be-secure-openssl.c:789 #, c-format msgid "could not load SSL certificate revocation list file \"%s\": %s" msgstr "konnte SSL-Certificate-Revocation-List-Datei »%s« nicht laden: %s" -#: libpq/be-secure-openssl.c:799 +#: libpq/be-secure-openssl.c:797 #, c-format msgid "could not load SSL certificate revocation list directory \"%s\": %s" msgstr "konnte SSL-Certificate-Revocation-List-Verzeichnis »%s« nicht laden: %s" -#: libpq/be-secure-openssl.c:807 +#: libpq/be-secure-openssl.c:805 #, c-format msgid "could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s" msgstr "konnte SSL-Certificate-Revocation-List-Datei »%s« oder -Verzeichnis »%s« nicht laden: %s" -#: libpq/be-secure-openssl.c:850 +#: libpq/be-secure-openssl.c:848 #, c-format msgid "could not initialize SSL connection: SSL context not set up" msgstr "konnte SSL-Verbindung nicht initialisieren: SSL-Kontext nicht eingerichtet" -#: libpq/be-secure-openssl.c:864 +#: libpq/be-secure-openssl.c:862 #, c-format msgid "could not initialize SSL connection: %s" msgstr "konnte SSL-Verbindung nicht initialisieren: %s" -#: libpq/be-secure-openssl.c:872 +#: libpq/be-secure-openssl.c:870 #, c-format msgid "could not set SSL socket: %s" msgstr "konnte SSL-Socket nicht setzen: %s" -#: libpq/be-secure-openssl.c:964 +#: libpq/be-secure-openssl.c:962 #, c-format msgid "could not accept SSL connection: %m" msgstr "konnte SSL-Verbindung nicht annehmen: %m" -#: libpq/be-secure-openssl.c:968 libpq/be-secure-openssl.c:1026 +#: libpq/be-secure-openssl.c:966 libpq/be-secure-openssl.c:1024 #, c-format msgid "could not accept SSL connection: EOF detected" msgstr "konnte SSL-Verbindung nicht annehmen: EOF entdeckt" -#: libpq/be-secure-openssl.c:1009 +#: libpq/be-secure-openssl.c:1007 #, c-format msgid "could not accept SSL connection: %s" msgstr "konnte SSL-Verbindung nicht annehmen: %s" -#: libpq/be-secure-openssl.c:1013 +#: libpq/be-secure-openssl.c:1011 #, c-format msgid "This may indicate that the client does not support any SSL protocol version between %s and %s." msgstr "Das zeigt möglicherweise an, dass der Client keine SSL-Protokollversion zwischen %s und %s unterstützt." -#: libpq/be-secure-openssl.c:1031 libpq/be-secure-openssl.c:1246 -#: libpq/be-secure-openssl.c:1316 +#: libpq/be-secure-openssl.c:1029 libpq/be-secure-openssl.c:1244 +#: libpq/be-secure-openssl.c:1314 #, c-format msgid "unrecognized SSL error code: %d" msgstr "unbekannter SSL-Fehlercode: %d" -#: libpq/be-secure-openssl.c:1059 +#: libpq/be-secure-openssl.c:1057 #, c-format msgid "received SSL connection request with unexpected ALPN protocol" msgstr "SSL-Verbindungsanfrage mit unerwartetem ALPN-Protokoll erhalten" -#: libpq/be-secure-openssl.c:1103 +#: libpq/be-secure-openssl.c:1101 #, c-format msgid "SSL certificate's common name contains embedded null" msgstr "Common-Name im SSL-Zertifikat enthält Null-Byte" -#: libpq/be-secure-openssl.c:1149 +#: libpq/be-secure-openssl.c:1147 #, c-format msgid "SSL certificate's distinguished name contains embedded null" msgstr "Distinguished Name im SSL-Zertifikat enthält Null-Byte" -#: libpq/be-secure-openssl.c:1235 libpq/be-secure-openssl.c:1300 +#: libpq/be-secure-openssl.c:1233 libpq/be-secure-openssl.c:1298 #, c-format msgid "SSL error: %s" msgstr "SSL-Fehler: %s" -#: libpq/be-secure-openssl.c:1483 +#: libpq/be-secure-openssl.c:1481 #, c-format msgid "could not open DH parameters file \"%s\": %m" msgstr "konnte DH-Parameterdatei »%s« nicht öffnen: %m" -#: libpq/be-secure-openssl.c:1495 +#: libpq/be-secure-openssl.c:1493 #, c-format msgid "could not load DH parameters file: %s" msgstr "konnte DH-Parameterdatei nicht laden: %s" -#: libpq/be-secure-openssl.c:1505 +#: libpq/be-secure-openssl.c:1503 #, c-format msgid "invalid DH parameters: %s" msgstr "ungültige DH-Parameter: %s" -#: libpq/be-secure-openssl.c:1514 +#: libpq/be-secure-openssl.c:1512 #, c-format msgid "invalid DH parameters: p is not prime" msgstr "ungültige DH-Parameter: p ist keine Primzahl" -#: libpq/be-secure-openssl.c:1523 +#: libpq/be-secure-openssl.c:1521 #, c-format msgid "invalid DH parameters: neither suitable generator or safe prime" msgstr "ungültige DH-Parameter: weder geeigneter Generator noch sichere Primzahl" -#: libpq/be-secure-openssl.c:1669 +#: libpq/be-secure-openssl.c:1667 #, c-format msgid "Client certificate verification failed at depth %d: %s." msgstr "Überprüfung des Client-Zertifikats ist auf Tiefe %d fehlgeschlagen: %s." -#: libpq/be-secure-openssl.c:1706 +#: libpq/be-secure-openssl.c:1704 #, c-format msgid "Failed certificate data (unverified): subject \"%s\", serial number %s, issuer \"%s\"." msgstr "Daten des fehlgeschlagenen Zertifikats (nicht verifiziert): Subject »%s«, Seriennummer %s, Aussteller »%s«." -#: libpq/be-secure-openssl.c:1707 +#: libpq/be-secure-openssl.c:1705 msgid "unknown" msgstr "unbekannt" -#: libpq/be-secure-openssl.c:2032 +#: libpq/be-secure-openssl.c:2030 #, c-format msgid "no hostname provided in callback, and no fallback configured" msgstr "" -#: libpq/be-secure-openssl.c:2056 +#: libpq/be-secure-openssl.c:2054 #, c-format msgid "failed to switch to SSL configuration for host, terminating connection" msgstr "" -#: libpq/be-secure-openssl.c:2092 +#: libpq/be-secure-openssl.c:2090 #, c-format msgid "DH: could not load DH parameters" msgstr "DH: konnte DH-Parameter nicht laden" -#: libpq/be-secure-openssl.c:2100 +#: libpq/be-secure-openssl.c:2098 #, c-format msgid "DH: could not set DH parameters: %s" msgstr "DH: konnte DH-Parameter nicht setzen: %s" -#: libpq/be-secure-openssl.c:2130 +#: libpq/be-secure-openssl.c:2127 #, c-format msgid "could not set group names specified in ssl_groups: %s" msgstr "konnte die in ssl_groups angegebenen Gruppennamen nicht setzen: %s" -#: libpq/be-secure-openssl.c:2132 +#: libpq/be-secure-openssl.c:2129 msgid "No valid groups found" msgstr "Keine gültigen Gruppen gefunden" -#: libpq/be-secure-openssl.c:2133 +#: libpq/be-secure-openssl.c:2130 #, c-format msgid "Ensure that each group name is spelled correctly and supported by the installed version of OpenSSL." msgstr "Stellen Sie sicher, dass jeder Gruppenname richtig geschrieben ist und von der installierten Version von OpenSSL unterstützt wird." -#: libpq/be-secure-openssl.c:2179 +#: libpq/be-secure-openssl.c:2175 msgid "no SSL error reported" msgstr "kein SSL-Fehler berichtet" -#: libpq/be-secure-openssl.c:2197 +#: libpq/be-secure-openssl.c:2193 #, c-format msgid "SSL error code %lu" msgstr "SSL-Fehlercode %lu" -#: libpq/be-secure-openssl.c:2354 +#: libpq/be-secure-openssl.c:2350 #, c-format msgid "could not create BIO" msgstr "konnte BIO nicht erzeugen" -#: libpq/be-secure-openssl.c:2364 +#: libpq/be-secure-openssl.c:2360 #, c-format msgid "could not get NID for ASN1_OBJECT object" msgstr "konnte NID für ASN1_OBJECT-Objekt nicht ermitteln" -#: libpq/be-secure-openssl.c:2372 +#: libpq/be-secure-openssl.c:2368 #, c-format msgid "could not convert NID %d to an ASN1_OBJECT structure" msgstr "konnte NID %d nicht in eine ASN1_OBJECT-Struktur umwandeln" @@ -20656,11 +20754,6 @@ msgstr "Verschlüsselte Passwörter dürfen nicht länger als %d Bytes sein." msgid "setting an MD5-encrypted password" msgstr "ein MD5-verschlüsseltes Passwort wird gesetzt" -#: libpq/crypt.c:247 libpq/crypt.c:309 -#, c-format -msgid "MD5 password support is deprecated and will be removed in a future release of PostgreSQL." -msgstr "Unterstützung für MD5-Passwörter ist veraltet und wird in einer zukünftigen Version von PostgreSQL entfernt werden." - #: libpq/crypt.c:248 #, c-format msgid "Refer to the PostgreSQL documentation for details about migrating to another password type." @@ -20671,18 +20764,12 @@ msgstr "Lesen Sie in der PostgreSQL-Dokumentation, wie man zu einem anderen Pass msgid "User \"%s\" has a password that cannot be used with MD5 authentication." msgstr "Benutzer »%s« hat ein Passwort, das nicht mit MD5-Authentifizierung verwendet werden kann." -#: libpq/crypt.c:308 -#, fuzzy -#| msgid "setting an MD5-encrypted password" -msgid "authenticated with an MD5-encrypted password" -msgstr "ein MD5-verschlüsseltes Passwort wird gesetzt" - -#: libpq/crypt.c:317 libpq/crypt.c:359 libpq/crypt.c:379 +#: libpq/crypt.c:301 libpq/crypt.c:343 libpq/crypt.c:364 #, c-format msgid "Password does not match for user \"%s\"." msgstr "Passwort stimmt nicht überein für Benutzer »%s«." -#: libpq/crypt.c:398 +#: libpq/crypt.c:383 #, c-format msgid "Password of user \"%s\" is in unrecognized format." msgstr "Passwort von Benutzer »%s« hat unbekanntes Format." @@ -21108,7 +21195,7 @@ msgstr "es besteht keine Client-Verbindung" msgid "could not receive data from client: %m" msgstr "konnte Daten vom Client nicht empfangen: %m" -#: libpq/pqcomm.c:1151 tcop/postgres.c:4589 +#: libpq/pqcomm.c:1151 tcop/postgres.c:4590 #, c-format msgid "terminating connection because protocol synchronization was lost" msgstr "Verbindung wird abgebrochen, weil Protokollsynchronisierung verloren wurde" @@ -21470,9 +21557,9 @@ msgstr "ExtensibleNodeMethods »%s« wurde nicht registriert" msgid "relation \"%s\" does not have a composite type" msgstr "Relation »%s« hat keinen zusammengesetzten Typ" -#: nodes/nodeFuncs.c:118 nodes/nodeFuncs.c:149 parser/parse_coerce.c:2603 -#: parser/parse_coerce.c:2741 parser/parse_coerce.c:2788 -#: parser/parse_expr.c:2152 parser/parse_func.c:724 parser/parse_oper.c:914 +#: nodes/nodeFuncs.c:118 nodes/nodeFuncs.c:149 parser/parse_coerce.c:2602 +#: parser/parse_coerce.c:2740 parser/parse_coerce.c:2787 +#: parser/parse_expr.c:2152 parser/parse_func.c:730 parser/parse_oper.c:920 #: utils/adt/array_userfuncs.c:1959 utils/fmgr/funcapi.c:671 #, c-format msgid "could not find array type for data type %s" @@ -21500,50 +21587,61 @@ msgid "cannot execute MERGE on relation \"%s\"" msgstr "MERGE kann für Relation »%s« nicht ausgeführt werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/initsplan.c:2142 +#: optimizer/plan/initsplan.c:2193 #, c-format msgid "%s cannot be applied to the nullable side of an outer join" msgstr "%s kann nicht auf die nullbare Seite eines äußeren Verbundes angewendet werden" +#: optimizer/plan/planner.c:873 +#, fuzzy, c-format +#| msgid "cannot set generated column \"%s\"" +msgid "cannot use generated column \"%s\" in FOR PORTION OF" +msgstr "kann generierte Spalte »%s« nicht setzen" + +#: optimizer/plan/planner.c:1114 +#, c-format +msgid "FOR PORTION OF bounds cannot contain volatile functions" +msgstr "" + #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1611 parser/analyze.c:2192 parser/analyze.c:2451 -#: parser/analyze.c:3754 +#: optimizer/plan/planner.c:1782 parser/analyze.c:2188 parser/analyze.c:2447 +#: parser/analyze.c:3751 #, c-format msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" msgstr "%s ist nicht in UNION/INTERSECT/EXCEPT erlaubt" -#: optimizer/plan/planner.c:2357 optimizer/plan/planner.c:4236 +#: optimizer/plan/planner.c:2528 optimizer/plan/planner.c:4407 #, c-format msgid "could not implement GROUP BY" msgstr "konnte GROUP BY nicht implementieren" -#: optimizer/plan/planner.c:2358 optimizer/plan/planner.c:4237 -#: optimizer/plan/planner.c:4918 optimizer/prep/prepunion.c:1127 +#: optimizer/plan/planner.c:2529 optimizer/plan/planner.c:4408 +#: optimizer/plan/planner.c:5089 optimizer/prep/prepunion.c:1127 #, c-format msgid "Some of the datatypes only support hashing, while others only support sorting." msgstr "Einige Datentypen unterstützen nur Hashing, während andere nur Sortieren unterstützen." -#: optimizer/plan/planner.c:4917 +#: optimizer/plan/planner.c:5088 #, c-format msgid "could not implement DISTINCT" msgstr "konnte DISTINCT nicht implementieren" -#: optimizer/plan/planner.c:6382 +#: optimizer/plan/planner.c:6553 #, c-format msgid "could not implement window PARTITION BY" msgstr "konnte PARTITION BY für Fenster nicht implementieren" -#: optimizer/plan/planner.c:6383 +#: optimizer/plan/planner.c:6554 #, c-format msgid "Window partitioning columns must be of sortable datatypes." msgstr "Fensterpartitionierungsspalten müssen sortierbare Datentypen haben." -#: optimizer/plan/planner.c:6387 +#: optimizer/plan/planner.c:6558 #, c-format msgid "could not implement window ORDER BY" msgstr "konnte ORDER BY für Fenster nicht implementieren" -#: optimizer/plan/planner.c:6388 +#: optimizer/plan/planner.c:6559 #, c-format msgid "Window ordering columns must be of sortable datatypes." msgstr "Fenstersortierspalten müssen sortierbare Datentypen haben." @@ -21574,7 +21672,7 @@ msgstr "Attribut »%s« von Relation »%s« stimmt nicht mit dem Typ der Elternt msgid "attribute \"%s\" of relation \"%s\" does not match parent's collation" msgstr "Attribut »%s« von Relation »%s« stimmt nicht mit der Sortierfolge der Elterntabelle überein" -#: optimizer/util/clauses.c:5701 +#: optimizer/util/clauses.c:5733 #, c-format msgid "SQL function \"%s\" during inlining" msgstr "SQL-Funktion »%s« beim Inlining" @@ -21605,303 +21703,305 @@ msgstr "ON CONFLICT DO UPDATE nicht unterstützt mit Exclusion-Constraints" msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" msgstr "es gibt keinen Unique-Constraint oder Exclusion-Constraint, der auf die ON-CONFLICT-Angabe passt" -#: parser/analyze.c:604 parser/analyze.c:2885 +#: parser/analyze.c:605 parser/analyze.c:2881 #, c-format msgid "WHERE CURRENT OF on a view is not implemented" msgstr "WHERE CURRENT OF mit einer Sicht ist nicht implementiert" -#: parser/analyze.c:910 parser/analyze.c:1971 +#: parser/analyze.c:912 parser/analyze.c:1967 #, c-format msgid "VALUES lists must all be the same length" msgstr "VALUES-Listen müssen alle die gleiche Länge haben" -#: parser/analyze.c:1065 rewrite/rewriteHandler.c:706 +#: parser/analyze.c:1067 rewrite/rewriteHandler.c:706 #, c-format msgid "ON CONFLICT DO SELECT requires a RETURNING clause" msgstr "" -#: parser/analyze.c:1121 +#: parser/analyze.c:1123 #, c-format msgid "INSERT has more expressions than target columns" msgstr "INSERT hat mehr Ausdrücke als Zielspalten" -#: parser/analyze.c:1139 +#: parser/analyze.c:1141 #, c-format msgid "INSERT has more target columns than expressions" msgstr "INSERT hat mehr Zielspalten als Ausdrücke" -#: parser/analyze.c:1143 +#: parser/analyze.c:1145 #, c-format msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" msgstr "Der einzufügende Wert ist ein Zeilenausdruck mit der gleichen Anzahl Spalten wie von INSERT erwartet. Haben Sie versehentlich zu viele Klammern gesetzt?" -#: parser/analyze.c:1342 +#: parser/analyze.c:1345 #, fuzzy, c-format -#| msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" -msgid "foreign tables don't support FOR PORTION OF" -msgstr "Fremddaten-Wrapper »%s« unterstützt IMPORT FOREIGN SCHEMA nicht" +#| msgid "WHERE CURRENT OF on a view is not implemented" +msgid "WHERE CURRENT OF with FOR PORTION OF is not implemented" +msgstr "WHERE CURRENT OF mit einer Sicht ist nicht implementiert" -#: parser/analyze.c:1398 +#: parser/analyze.c:1401 #, fuzzy, c-format #| msgid "could not close target file \"%s\": %m" msgid "could not coerce FOR PORTION OF target from %s to %s" msgstr "konnte Zieldatei »%s« nicht schließen: %m" -#: parser/analyze.c:1419 +#: parser/analyze.c:1422 #, fuzzy, c-format #| msgid "column \"%s\" of relation \"%s\" is not a generated column" msgid "column \"%s\" of relation \"%s\" is not a range or multirange type" msgstr "Spalte »%s« von Relation »%s« ist keine generierte Spalte" -#: parser/analyze.c:1440 +#: parser/analyze.c:1443 #, fuzzy, c-format #| msgid "column \"%s\" of relation \"%s\" is not a generated column" msgid "column \"%s\" of relation \"%s\" is not a range type" msgstr "Spalte »%s« von Relation »%s« ist keine generierte Spalte" -#: parser/analyze.c:1472 parser/analyze.c:1480 +#: parser/analyze.c:1475 parser/analyze.c:1483 #, fuzzy, c-format #| msgid "could not create symbolic link from \"%s\" to \"%s\": %m" msgid "could not coerce FOR PORTION OF %s bound from %s to %s" msgstr "konnte symbolische Verknüpfung von »%s« nach »%s« nicht erzeugen: %m" -#: parser/analyze.c:1494 -#, c-format -msgid "FOR PORTION OF bounds cannot contain volatile functions" -msgstr "" - #: parser/analyze.c:1507 #, fuzzy, c-format #| msgid "You must specify a hash operator class or define a default hash operator class for the data type." msgid "You must define a default operator class for the data type." msgstr "Sie müssen eine hash-Operatorklasse angeben oder eine hash-Standardoperatorklasse für den Datentyp definieren." -#: parser/analyze.c:1573 +#: parser/analyze.c:1574 #, fuzzy, c-format #| msgid "could not identify a hash function for type %s" msgid "could not identify an intersect function for type %s" msgstr "konnte keine Hash-Funktion für Typ %s ermitteln" -#: parser/analyze.c:1768 parser/analyze.c:2165 +#: parser/analyze.c:1764 parser/analyze.c:2161 #, c-format msgid "SELECT ... INTO is not allowed here" msgstr "SELECT ... INTO ist hier nicht erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2094 parser/analyze.c:3986 +#: parser/analyze.c:2090 parser/analyze.c:3983 #, c-format msgid "%s cannot be applied to VALUES" msgstr "%s kann nicht auf VALUES angewendet werden" -#: parser/analyze.c:2332 +#: parser/analyze.c:2328 #, c-format msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" msgstr "ungültige ORDER-BY-Klausel mit UNION/INTERSECT/EXCEPT" -#: parser/analyze.c:2333 +#: parser/analyze.c:2329 #, c-format msgid "Only result column names can be used, not expressions or functions." msgstr "Es können nur Ergebnisspaltennamen verwendet werden, keine Ausdrücke oder Funktionen." -#: parser/analyze.c:2334 +#: parser/analyze.c:2330 #, c-format msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." msgstr "Fügen Sie den Ausdrück/die Funktion jedem SELECT hinzu oder verlegen Sie die UNION in eine FROM-Klausel." -#: parser/analyze.c:2441 +#: parser/analyze.c:2437 #, c-format msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" msgstr "INTO ist nur im ersten SELECT von UNION/INTERSECT/EXCEPT erlaubt" -#: parser/analyze.c:2511 +#: parser/analyze.c:2507 #, c-format msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" msgstr "Teilanweisung von UNION/INTERSECT/EXCEPT kann nicht auf andere Relationen auf der selben Anfrageebene verweisen" -#: parser/analyze.c:2623 +#: parser/analyze.c:2619 #, c-format msgid "each %s query must have the same number of columns" msgstr "jede %s-Anfrage muss die gleiche Anzahl Spalten haben" -#: parser/analyze.c:2989 +#: parser/analyze.c:2986 #, c-format msgid "SET target columns cannot be qualified with the relation name." msgstr "SET-Zielspalten können nicht mit dem Relationsnamen qualifiziert werden." -#: parser/analyze.c:3001 +#: parser/analyze.c:2998 #, fuzzy, c-format #| msgid "cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"" msgid "cannot update column \"%s\" because it is used in FOR PORTION OF" msgstr "Spalte »%s« kann nicht geändert werden, weil sie Teil des Partitionierungsschlüssels von Relation »%s« ist" #. translator: %s is OLD or NEW -#: parser/analyze.c:3090 parser/analyze.c:3100 +#: parser/analyze.c:3087 parser/analyze.c:3097 #, c-format msgid "%s cannot be specified multiple times" msgstr "%s kann nicht mehrmals angegeben werden" -#: parser/analyze.c:3112 parser/parse_relation.c:469 +#: parser/analyze.c:3109 parser/parse_relation.c:469 #, c-format msgid "table name \"%s\" specified more than once" msgstr "Tabellenname »%s« mehrmals angegeben" -#: parser/analyze.c:3160 +#: parser/analyze.c:3157 #, c-format msgid "RETURNING must have at least one column" msgstr "RETURNING muss mindestens eine Spalte haben" -#: parser/analyze.c:3284 +#: parser/analyze.c:3281 #, c-format msgid "assignment source returned %d column" msgid_plural "assignment source returned %d columns" msgstr[0] "Quelle der Wertzuweisung hat %d Spalte zurückgegeben" msgstr[1] "Quelle der Wertzuweisung hat %d Spalten zurückgegeben" -#: parser/analyze.c:3345 +#: parser/analyze.c:3342 #, c-format msgid "variable \"%s\" is of type %s but expression is of type %s" msgstr "Variable »%s« hat Typ %s, aber der Ausdruck hat Typ %s" #. translator: %s is a SQL keyword -#: parser/analyze.c:3381 parser/analyze.c:3389 +#: parser/analyze.c:3378 parser/analyze.c:3386 #, c-format msgid "cannot specify both %s and %s" msgstr "%s und %s können nicht beide angegeben werden" -#: parser/analyze.c:3409 +#: parser/analyze.c:3406 #, c-format msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" msgstr "DECLARE CURSOR darf keine datenmodifizierenden Anweisungen in WITH enthalten" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3417 +#: parser/analyze.c:3414 #, c-format msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" msgstr "DECLARE CURSOR WITH HOLD ... %s wird nicht unterstützt" -#: parser/analyze.c:3420 +#: parser/analyze.c:3417 #, c-format msgid "Holdable cursors must be READ ONLY." msgstr "Haltbare Cursor müssen READ ONLY sein." #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3428 +#: parser/analyze.c:3425 #, c-format msgid "DECLARE SCROLL CURSOR ... %s is not supported" msgstr "DECLARE SCROLL CURSOR ... %s wird nicht unterstützt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3439 +#: parser/analyze.c:3436 #, c-format msgid "DECLARE INSENSITIVE CURSOR ... %s is not valid" msgstr "DECLARE INSENSITIVE CURSOR ... %s ist nicht gültig" -#: parser/analyze.c:3442 +#: parser/analyze.c:3439 #, c-format msgid "Insensitive cursors must be READ ONLY." msgstr "Insensitive Cursor müssen READ ONLY sein." -#: parser/analyze.c:3538 +#: parser/analyze.c:3535 #, c-format msgid "materialized views must not use data-modifying statements in WITH" msgstr "materialisierte Sichten dürfen keine datenmodifizierenden Anweisungen in WITH verwenden" -#: parser/analyze.c:3548 +#: parser/analyze.c:3545 #, fuzzy, c-format #| msgid "materialized views must not use temporary tables or views" msgid "materialized views must not use temporary objects" msgstr "materialisierte Sichten dürfen keine temporären Tabellen oder Sichten verwenden" -#: parser/analyze.c:3549 +#: parser/analyze.c:3546 #, fuzzy, c-format #| msgid "%s depends on %s" msgid "This view depends on temporary %s." msgstr "%s hängt von %s ab" -#: parser/analyze.c:3560 +#: parser/analyze.c:3557 #, c-format msgid "materialized views may not be defined using bound parameters" msgstr "materialisierte Sichten können nicht unter Verwendung von gebundenen Parametern definiert werden" -#: parser/analyze.c:3572 +#: parser/analyze.c:3569 #, c-format msgid "materialized views cannot be unlogged" msgstr "materialisierte Sichten können nicht ungeloggt sein" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3761 +#: parser/analyze.c:3758 #, c-format msgid "%s is not allowed with DISTINCT clause" msgstr "%s ist nicht mit DISTINCT-Klausel erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3768 +#: parser/analyze.c:3765 #, c-format msgid "%s is not allowed with GROUP BY clause" msgstr "%s ist nicht mit GROUP-BY-Klausel erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3775 +#: parser/analyze.c:3772 #, c-format msgid "%s is not allowed with HAVING clause" msgstr "%s ist nicht mit HAVING-Klausel erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3782 +#: parser/analyze.c:3779 #, c-format msgid "%s is not allowed with aggregate functions" msgstr "%s ist nicht mit Aggregatfunktionen erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3789 +#: parser/analyze.c:3786 #, c-format msgid "%s is not allowed with window functions" msgstr "%s ist nicht mit Fensterfunktionen erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3796 +#: parser/analyze.c:3793 #, c-format msgid "%s is not allowed with set-returning functions in the target list" msgstr "%s ist nicht mit Funktionen mit Ergebnismenge in der Targetliste erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3895 +#: parser/analyze.c:3892 #, c-format msgid "%s must specify unqualified relation names" msgstr "%s muss unqualifizierte Relationsnamen angeben" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3959 +#: parser/analyze.c:3956 #, c-format msgid "%s cannot be applied to a join" msgstr "%s kann nicht auf einen Verbund angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3968 +#: parser/analyze.c:3965 #, c-format msgid "%s cannot be applied to a function" msgstr "%s kann nicht auf eine Funktion angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3977 +#: parser/analyze.c:3974 #, c-format msgid "%s cannot be applied to a table function" msgstr "%s kann nicht auf eine Tabellenfunktion angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3995 +#: parser/analyze.c:3992 #, c-format msgid "%s cannot be applied to a WITH query" msgstr "%s kann nicht auf eine WITH-Anfrage angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:4004 +#: parser/analyze.c:4001 #, c-format msgid "%s cannot be applied to a named tuplestore" msgstr "%s kann nicht auf einen benannten Tupelstore angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:4024 +#: parser/analyze.c:4010 +#, fuzzy, c-format +#| msgid "%s cannot be applied to VALUES" +msgid "%s cannot be applied to GRAPH_TABLE" +msgstr "%s kann nicht auf VALUES angewendet werden" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:4030 #, c-format msgid "relation \"%s\" in %s clause not found in FROM clause" msgstr "Relation »%s« in %s nicht in der FROM-Klausel gefunden" @@ -22114,7 +22214,7 @@ msgid "grouping operations are not allowed in property definition expressions" msgstr "Gruppieroperationen sind in Partitionierungsschlüsselausdrücken nicht erlaubt" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:622 parser/parse_clause.c:2098 +#: parser/parse_agg.c:622 parser/parse_clause.c:2110 #, c-format msgid "aggregate functions are not allowed in %s" msgstr "Aggregatfunktionen sind in %s nicht erlaubt" @@ -22146,7 +22246,7 @@ msgid "aggregate function calls cannot contain set-returning function calls" msgstr "Aufrufe von Aggregatfunktionen können keine Aufrufe von Funktionen mit Ergebnismenge enthalten" #: parser/parse_agg.c:830 parser/parse_expr.c:1788 parser/parse_expr.c:2287 -#: parser/parse_func.c:900 +#: parser/parse_func.c:906 #, c-format msgid "You might be able to move the set-returning function into a LATERAL FROM item." msgstr "Sie können möglicherweise die Funktion mit Ergebnismenge in ein LATERAL-FROM-Element verschieben." @@ -22241,12 +22341,12 @@ msgid "window functions are not allowed in FOR PORTION OF expressions" msgstr "Fensterfunktionen sind in DEFAULT-Ausdrücken nicht erlaubt" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:1066 parser/parse_clause.c:2107 +#: parser/parse_agg.c:1066 parser/parse_clause.c:2119 #, c-format msgid "window functions are not allowed in %s" msgstr "Fensterfunktionen sind in %s nicht erlaubt" -#: parser/parse_agg.c:1100 parser/parse_clause.c:3002 +#: parser/parse_agg.c:1100 parser/parse_clause.c:3012 #, c-format msgid "window \"%s\" does not exist" msgstr "Fenster »%s« existiert nicht" @@ -22286,438 +22386,438 @@ msgstr "Argumente von GROUPING müssen Gruppierausdrücke der zugehörigen Anfra msgid "relation \"%s\" cannot be the target of a modifying statement" msgstr "Relation »%s« kann nicht das Ziel einer datenverändernden Anweisung sein" -#: parser/parse_clause.c:571 parser/parse_clause.c:599 parser/parse_func.c:2678 +#: parser/parse_clause.c:573 parser/parse_clause.c:601 parser/parse_func.c:2685 #, c-format msgid "set-returning functions must appear at top level of FROM" msgstr "Funktionen mit Ergebnismenge müssen auf oberster Ebene von FROM erscheinen" -#: parser/parse_clause.c:611 +#: parser/parse_clause.c:613 #, c-format msgid "multiple column definition lists are not allowed for the same function" msgstr "mehrere Spaltendefinitionslisten für die selbe Funktion sind nicht erlaubt" -#: parser/parse_clause.c:644 +#: parser/parse_clause.c:646 #, c-format msgid "ROWS FROM() with multiple functions cannot have a column definition list" msgstr "ROWS FROM() mit mehreren Funktionen kann keine Spaltendefinitionsliste haben" -#: parser/parse_clause.c:645 +#: parser/parse_clause.c:647 #, c-format msgid "Put a separate column definition list for each function inside ROWS FROM()." msgstr "Geben Sie innerhalb von ROWS FROM() jeder Funktion eine eigene Spaltendefinitionsliste." -#: parser/parse_clause.c:651 +#: parser/parse_clause.c:653 #, c-format msgid "UNNEST() with multiple arguments cannot have a column definition list" msgstr "UNNEST() mit mehreren Argumenten kann keine Spaltendefinitionsliste haben" -#: parser/parse_clause.c:652 +#: parser/parse_clause.c:654 #, c-format msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." msgstr "Verwenden Sie getrennte UNNEST()-Aufrufe innerhalb von ROWS FROM() und geben Sie jeder eine eigene Spaltendefinitionsliste." -#: parser/parse_clause.c:659 +#: parser/parse_clause.c:661 #, c-format msgid "WITH ORDINALITY cannot be used with a column definition list" msgstr "WITH ORDINALITY kann nicht mit einer Spaltendefinitionsliste verwendet werden" -#: parser/parse_clause.c:660 +#: parser/parse_clause.c:662 #, c-format msgid "Put the column definition list inside ROWS FROM()." msgstr "Geben Sie die Spaltendefinitionsliste innerhalb von ROWS FROM() an." -#: parser/parse_clause.c:764 parser/parse_jsontable.c:293 +#: parser/parse_clause.c:766 parser/parse_jsontable.c:293 #, c-format msgid "only one FOR ORDINALITY column is allowed" msgstr "nur eine FOR-ORDINALITY-Spalte ist erlaubt" -#: parser/parse_clause.c:825 +#: parser/parse_clause.c:827 #, c-format msgid "column name \"%s\" is not unique" msgstr "Spaltenname »%s« ist nicht eindeutig" -#: parser/parse_clause.c:867 +#: parser/parse_clause.c:869 #, c-format msgid "namespace name \"%s\" is not unique" msgstr "Namensraumname »%s« ist nicht eindeutig" -#: parser/parse_clause.c:877 +#: parser/parse_clause.c:879 #, c-format msgid "only one default namespace is allowed" msgstr "nur ein Standardnamensraum ist erlaubt" -#: parser/parse_clause.c:994 +#: parser/parse_clause.c:996 #, c-format msgid "complex graph table column must specify an explicit column name" msgstr "" -#: parser/parse_clause.c:1019 +#: parser/parse_clause.c:1031 #, c-format msgid "subqueries within GRAPH_TABLE reference are not supported" msgstr "" -#: parser/parse_clause.c:1057 +#: parser/parse_clause.c:1069 #, c-format msgid "tablesample method %s does not exist" msgstr "Tablesample-Methode %s existiert nicht" -#: parser/parse_clause.c:1079 +#: parser/parse_clause.c:1091 #, c-format msgid "tablesample method %s requires %d argument, not %d" msgid_plural "tablesample method %s requires %d arguments, not %d" msgstr[0] "Tablesample-Methode %s benötigt %d Argument, nicht %d" msgstr[1] "Tablesample-Methode %s benötigt %d Argumente, nicht %d" -#: parser/parse_clause.c:1113 +#: parser/parse_clause.c:1125 #, c-format msgid "tablesample method %s does not support REPEATABLE" msgstr "Tablesample-Methode %s unterstützt REPEATABLE nicht" -#: parser/parse_clause.c:1278 +#: parser/parse_clause.c:1290 #, c-format msgid "TABLESAMPLE clause can only be applied to tables and materialized views" msgstr "TABLESAMPLE-Klausel kann nur auf Tabellen und materialisierte Sichten angewendet werden" -#: parser/parse_clause.c:1465 +#: parser/parse_clause.c:1477 #, c-format msgid "column name \"%s\" appears more than once in USING clause" msgstr "Spaltenname »%s« erscheint mehrmals in der USING-Klausel" -#: parser/parse_clause.c:1480 +#: parser/parse_clause.c:1492 #, c-format msgid "common column name \"%s\" appears more than once in left table" msgstr "gemeinsamer Spaltenname »%s« erscheint mehrmals in der linken Tabelle" -#: parser/parse_clause.c:1489 +#: parser/parse_clause.c:1501 #, c-format msgid "column \"%s\" specified in USING clause does not exist in left table" msgstr "Spalte »%s« aus der USING-Klausel existiert nicht in der linken Tabelle" -#: parser/parse_clause.c:1504 +#: parser/parse_clause.c:1516 #, c-format msgid "common column name \"%s\" appears more than once in right table" msgstr "gemeinsamer Spaltenname »%s« erscheint mehrmals in der rechten Tabelle" -#: parser/parse_clause.c:1513 +#: parser/parse_clause.c:1525 #, c-format msgid "column \"%s\" specified in USING clause does not exist in right table" msgstr "Spalte »%s« aus der USING-Klausel existiert nicht in der rechten Tabelle" -#: parser/parse_clause.c:2043 +#: parser/parse_clause.c:2055 #, c-format msgid "row count cannot be null in FETCH FIRST ... WITH TIES clause" msgstr "Zeilenzahl in FETCH FIRST ... WITH TIES darf nicht NULL sein" #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_clause.c:2068 +#: parser/parse_clause.c:2080 #, c-format msgid "argument of %s must not contain variables" msgstr "Argument von %s darf keine Variablen enthalten" #. translator: first %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:2233 +#: parser/parse_clause.c:2245 #, c-format msgid "%s \"%s\" is ambiguous" msgstr "%s »%s« ist nicht eindeutig" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:2261 +#: parser/parse_clause.c:2273 #, c-format msgid "non-integer constant in %s" msgstr "Konstante in %s ist keine ganze Zahl" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:2283 +#: parser/parse_clause.c:2295 #, c-format msgid "%s position %d is not in select list" msgstr "%s Position %d ist nicht in der Select-Liste" -#: parser/parse_clause.c:2722 +#: parser/parse_clause.c:2734 #, c-format msgid "CUBE is limited to 12 elements" msgstr "CUBE ist auf 12 Elemente begrenzt" -#: parser/parse_clause.c:2990 +#: parser/parse_clause.c:3000 #, c-format msgid "window \"%s\" is already defined" msgstr "Fenster »%s« ist bereits definiert" -#: parser/parse_clause.c:3052 +#: parser/parse_clause.c:3062 #, c-format msgid "cannot override PARTITION BY clause of window \"%s\"" msgstr "PARTITION-BY-Klausel von Fenster »%s« kann nicht aufgehoben werden" -#: parser/parse_clause.c:3064 +#: parser/parse_clause.c:3074 #, c-format msgid "cannot override ORDER BY clause of window \"%s\"" msgstr "ORDER-BY-Klausel von Fenster »%s« kann nicht aufgehoben werden" -#: parser/parse_clause.c:3094 parser/parse_clause.c:3100 +#: parser/parse_clause.c:3104 parser/parse_clause.c:3110 #, c-format msgid "cannot copy window \"%s\" because it has a frame clause" msgstr "kann Fenster »%s« nicht kopieren, weil es eine Frame-Klausel hat" -#: parser/parse_clause.c:3102 +#: parser/parse_clause.c:3112 #, c-format msgid "Omit the parentheses in this OVER clause." msgstr "Lassen Sie die Klammern in dieser OVER-Klausel weg." -#: parser/parse_clause.c:3122 +#: parser/parse_clause.c:3132 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" msgstr "RANGE mit Offset PRECEDING/FOLLOWING benötigt genau eine ORDER-BY-Spalte" -#: parser/parse_clause.c:3145 +#: parser/parse_clause.c:3155 #, c-format msgid "GROUPS mode requires an ORDER BY clause" msgstr "GROUPS-Modus erfordert eine ORDER-BY-Klausel" -#: parser/parse_clause.c:3215 +#: parser/parse_clause.c:3225 #, c-format msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" msgstr "in einer Aggregatfunktion mit DISTINCT müssen ORDER-BY-Ausdrücke in der Argumentliste erscheinen" -#: parser/parse_clause.c:3216 +#: parser/parse_clause.c:3226 #, c-format msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" msgstr "bei SELECT DISTINCT müssen ORDER-BY-Ausdrücke in der Select-Liste erscheinen" -#: parser/parse_clause.c:3248 +#: parser/parse_clause.c:3258 #, c-format msgid "an aggregate with DISTINCT must have at least one argument" msgstr "eine Aggregatfunktion mit DISTINCT muss mindestens ein Argument haben" -#: parser/parse_clause.c:3249 +#: parser/parse_clause.c:3259 #, c-format msgid "SELECT DISTINCT must have at least one column" msgstr "SELECT DISTINCT muss mindestens eine Spalte haben" -#: parser/parse_clause.c:3315 parser/parse_clause.c:3347 +#: parser/parse_clause.c:3325 parser/parse_clause.c:3357 #, c-format msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" msgstr "Ausdrücke in SELECT DISTINCT ON müssen mit den ersten Ausdrücken in ORDER BY übereinstimmen" -#: parser/parse_clause.c:3425 parser/parse_clause.c:3431 +#: parser/parse_clause.c:3435 parser/parse_clause.c:3441 #, fuzzy, c-format #| msgid "ASC/DESC is not allowed in ON CONFLICT clause" msgid "%s is not allowed in ON CONFLICT clause" msgstr "ASC/DESC ist in der ON-CONFLICT-Klausel nicht erlaubt" -#: parser/parse_clause.c:3437 +#: parser/parse_clause.c:3447 #, fuzzy, c-format #| msgid "ASC/DESC is not allowed in ON CONFLICT clause" msgid "operator class options are not allowed in ON CONFLICT clause" msgstr "ASC/DESC ist in der ON-CONFLICT-Klausel nicht erlaubt" -#: parser/parse_clause.c:3516 +#: parser/parse_clause.c:3526 #, fuzzy, c-format #| msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" msgid "ON CONFLICT DO %s requires inference specification or constraint name" msgstr "ON CONFLICT DO UPDATE benötigt Inferenzangabe oder Constraint-Namen" -#: parser/parse_clause.c:3518 +#: parser/parse_clause.c:3528 #, c-format msgid "For example, ON CONFLICT (column_name)." msgstr "Zum Bespiel ON CONFLICT (Spaltenname)." -#: parser/parse_clause.c:3529 +#: parser/parse_clause.c:3539 #, c-format msgid "ON CONFLICT is not supported with system catalog tables" msgstr "ON CONFLICT wird nicht mit Systemkatalogtabellen unterstützt" -#: parser/parse_clause.c:3537 +#: parser/parse_clause.c:3547 #, c-format msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" msgstr "ON CONFLICT wird nicht unterstützt mit Tabelle »%s«, die als Katalogtabelle verwendet wird" -#: parser/parse_clause.c:3668 +#: parser/parse_clause.c:3678 #, c-format msgid "operator %s is not a valid ordering operator" msgstr "Operator %s ist kein gültiger Sortieroperator" -#: parser/parse_clause.c:3670 +#: parser/parse_clause.c:3680 #, c-format msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." msgstr "Sortieroperatoren müssen die Mitglieder »<« oder »>« einer »btree«-Operatorfamilie sein." -#: parser/parse_clause.c:3984 +#: parser/parse_clause.c:3994 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" msgstr "RANGE mit Offset PRECEDING/FOLLOWING wird für Spaltentyp %s nicht unterstützt" -#: parser/parse_clause.c:3990 +#: parser/parse_clause.c:4000 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" msgstr "RANGE mit Offset PRECEDING/FOLLOWING wird für Spaltentyp %s und Offset-Typ %s nicht unterstützt" -#: parser/parse_clause.c:3993 +#: parser/parse_clause.c:4003 #, c-format msgid "Cast the offset value to an appropriate type." msgstr "Wandeln Sie den Offset-Wert in einen passenden Typ um." -#: parser/parse_clause.c:3998 +#: parser/parse_clause.c:4008 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" msgstr "RANGE mit Offset PRECEDING/FOLLOWING hat mehrere Interpretationen für Spaltentyp %s und Offset-Typ %s" -#: parser/parse_clause.c:4001 +#: parser/parse_clause.c:4011 #, c-format msgid "Cast the offset value to the exact intended type." msgstr "Wandeln Sie den Offset-Wert in den genauen beabsichtigten Typ um." -#: parser/parse_coerce.c:1049 parser/parse_coerce.c:1087 -#: parser/parse_coerce.c:1105 parser/parse_coerce.c:1120 +#: parser/parse_coerce.c:1048 parser/parse_coerce.c:1086 +#: parser/parse_coerce.c:1104 parser/parse_coerce.c:1119 #: parser/parse_expr.c:2186 parser/parse_expr.c:2806 parser/parse_expr.c:3461 -#: parser/parse_expr.c:3690 parser/parse_target.c:1006 +#: parser/parse_expr.c:3690 parser/parse_expr.c:4211 parser/parse_target.c:1006 #, c-format msgid "cannot cast type %s to %s" msgstr "kann Typ %s nicht in Typ %s umwandeln" -#: parser/parse_coerce.c:1090 +#: parser/parse_coerce.c:1089 #, c-format msgid "Input has too few columns." msgstr "Eingabe hat zu wenige Spalten." -#: parser/parse_coerce.c:1108 +#: parser/parse_coerce.c:1107 #, c-format msgid "Cannot cast type %s to %s in column %d." msgstr "Kann in Spalte %3$d Typ %1$s nicht in Typ %2$s umwandeln." -#: parser/parse_coerce.c:1123 +#: parser/parse_coerce.c:1122 #, c-format msgid "Input has too many columns." msgstr "Eingabe hat zu viele Spalten." #. translator: first %s is name of a SQL construct, eg WHERE #. translator: first %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1178 parser/parse_coerce.c:1226 +#: parser/parse_coerce.c:1177 parser/parse_coerce.c:1225 #, c-format msgid "argument of %s must be type %s, not type %s" msgstr "Argument von %s muss Typ %s haben, nicht Typ %s" #. translator: %s is name of a SQL construct, eg WHERE #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1189 parser/parse_coerce.c:1238 +#: parser/parse_coerce.c:1188 parser/parse_coerce.c:1237 #, c-format msgid "argument of %s must not return a set" msgstr "Argument von %s darf keine Ergebnismenge zurückgeben" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1419 +#: parser/parse_coerce.c:1418 #, c-format msgid "%s types %s and %s cannot be matched" msgstr "%s-Typen %s und %s passen nicht zusammen" -#: parser/parse_coerce.c:1535 +#: parser/parse_coerce.c:1534 #, c-format msgid "argument types %s and %s cannot be matched" msgstr "Argumenttypen %s und %s passen nicht zusammen" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1587 +#: parser/parse_coerce.c:1586 #, c-format msgid "%s could not convert type %s to %s" msgstr "%s konnte Typ %s nicht in %s umwandeln" -#: parser/parse_coerce.c:2190 parser/parse_coerce.c:2210 -#: parser/parse_coerce.c:2230 parser/parse_coerce.c:2251 -#: parser/parse_coerce.c:2306 parser/parse_coerce.c:2340 +#: parser/parse_coerce.c:2189 parser/parse_coerce.c:2209 +#: parser/parse_coerce.c:2229 parser/parse_coerce.c:2250 +#: parser/parse_coerce.c:2305 parser/parse_coerce.c:2339 #, c-format msgid "arguments declared \"%s\" are not all alike" msgstr "als »%s« deklarierte Argumente sind nicht alle gleich" -#: parser/parse_coerce.c:2285 parser/parse_coerce.c:2398 +#: parser/parse_coerce.c:2284 parser/parse_coerce.c:2397 #: utils/fmgr/funcapi.c:602 #, c-format msgid "argument declared %s is not an array but type %s" msgstr "als %s deklariertes Argument ist kein Array sondern Typ %s" -#: parser/parse_coerce.c:2318 parser/parse_coerce.c:2468 +#: parser/parse_coerce.c:2317 parser/parse_coerce.c:2467 #: utils/fmgr/funcapi.c:616 #, c-format msgid "argument declared %s is not a range type but type %s" msgstr "als %s deklariertes Argument ist kein Bereichstyp sondern Typ %s" -#: parser/parse_coerce.c:2352 parser/parse_coerce.c:2432 -#: parser/parse_coerce.c:2565 utils/fmgr/funcapi.c:634 utils/fmgr/funcapi.c:699 +#: parser/parse_coerce.c:2351 parser/parse_coerce.c:2431 +#: parser/parse_coerce.c:2564 utils/fmgr/funcapi.c:634 utils/fmgr/funcapi.c:699 #, c-format msgid "argument declared %s is not a multirange type but type %s" msgstr "als %s deklariertes Argument ist kein Multirange-Typ sondern Typ %s" -#: parser/parse_coerce.c:2389 +#: parser/parse_coerce.c:2388 #, c-format msgid "cannot determine element type of \"anyarray\" argument" msgstr "kann Elementtyp des Arguments mit Typ »anyarray« nicht bestimmen" -#: parser/parse_coerce.c:2415 parser/parse_coerce.c:2446 -#: parser/parse_coerce.c:2485 parser/parse_coerce.c:2551 +#: parser/parse_coerce.c:2414 parser/parse_coerce.c:2445 +#: parser/parse_coerce.c:2484 parser/parse_coerce.c:2550 #, c-format msgid "argument declared %s is not consistent with argument declared %s" msgstr "als %s deklariertes Argument ist nicht mit als %s deklariertem Argument konsistent" -#: parser/parse_coerce.c:2510 +#: parser/parse_coerce.c:2509 #, c-format msgid "could not determine polymorphic type because input has type %s" msgstr "konnte polymorphischen Typ nicht bestimmen, weil Eingabe Typ %s hat" -#: parser/parse_coerce.c:2524 +#: parser/parse_coerce.c:2523 #, c-format msgid "type matched to anynonarray is an array type: %s" msgstr "mit »anynonarray« gepaarter Typ ist ein Array-Typ: %s" -#: parser/parse_coerce.c:2534 +#: parser/parse_coerce.c:2533 #, c-format msgid "type matched to anyenum is not an enum type: %s" msgstr "mit »anyenum« gepaarter Typ ist kein Enum-Typ: %s" -#: parser/parse_coerce.c:2595 +#: parser/parse_coerce.c:2594 #, c-format msgid "arguments of anycompatible family cannot be cast to a common type" msgstr "Argumente der anycompatible-Familie können nicht in einen gemeinsamen Typ umgewandelt werden" -#: parser/parse_coerce.c:2613 parser/parse_coerce.c:2634 -#: parser/parse_coerce.c:2684 parser/parse_coerce.c:2689 -#: parser/parse_coerce.c:2753 parser/parse_coerce.c:2765 +#: parser/parse_coerce.c:2612 parser/parse_coerce.c:2633 +#: parser/parse_coerce.c:2683 parser/parse_coerce.c:2688 +#: parser/parse_coerce.c:2752 parser/parse_coerce.c:2764 #, c-format msgid "could not determine polymorphic type %s because input has type %s" msgstr "konnte polymorphischen Typ %s nicht bestimmen, weil Eingabe Typ %s hat" -#: parser/parse_coerce.c:2623 +#: parser/parse_coerce.c:2622 #, c-format msgid "anycompatiblerange type %s does not match anycompatible type %s" msgstr "anycompatiblerange-Typ %s stimmt nicht mit anycompatible-Typ %s überein" -#: parser/parse_coerce.c:2644 +#: parser/parse_coerce.c:2643 #, c-format msgid "anycompatiblemultirange type %s does not match anycompatible type %s" msgstr "anycompatiblemultirange-Typ %s stimmt nicht mit anycompatible-Typ %s überein" -#: parser/parse_coerce.c:2658 +#: parser/parse_coerce.c:2657 #, c-format msgid "type matched to anycompatiblenonarray is an array type: %s" msgstr "mit »anycompatiblenonarray« gepaarter Typ ist ein Array-Typ: %s" -#: parser/parse_coerce.c:2893 +#: parser/parse_coerce.c:2892 #, c-format msgid "A result of type %s requires at least one input of type anyrange or anymultirange." msgstr "Ein Ergebnis mit Typ %s benötigt mindestens eine Eingabe mit Typ anyrange oder anymultirange." -#: parser/parse_coerce.c:2910 +#: parser/parse_coerce.c:2909 #, c-format msgid "A result of type %s requires at least one input of type anycompatiblerange or anycompatiblemultirange." msgstr "Ein Ergebnis mit Typ %s benötigt mindestens eine Eingabe mit Typ anycompatiblerange oder anycompatiblemultirange." -#: parser/parse_coerce.c:2922 +#: parser/parse_coerce.c:2921 #, c-format msgid "A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange." msgstr "Ein Ergebnis mit Typ %s benötigt mindestens eine Eingabe mit Typ anyelement, anyarray, anynonarray, anyenum, anyrange oder anymultirange." -#: parser/parse_coerce.c:2934 +#: parser/parse_coerce.c:2933 #, c-format msgid "A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, anycompatiblerange, or anycompatiblemultirange." msgstr "Ein Ergebnis mit Typ %s benötigt mindestens eine Eingabe mit Typ anycompatible, anycompatiblearray, anycompatiblenonarray, anycompatiblerange oder anycompatiblemultirange." -#: parser/parse_coerce.c:2964 +#: parser/parse_coerce.c:2963 msgid "A result of type internal requires at least one input of type internal." msgstr "Ein Ergebnis mit Typ internal benötigt mindestens eine Eingabe mit Typ internal." @@ -22913,9 +23013,9 @@ msgstr "rekursiver Verweis auf Anfrage »%s« darf nicht mehrmals erscheinen" msgid "DEFAULT is not allowed in this context" msgstr "DEFAULT ist in diesem Zusammenhang nicht erlaubt" -#: parser/parse_expr.c:407 parser/parse_relation.c:3882 -#: parser/parse_relation.c:3892 parser/parse_relation.c:3910 -#: parser/parse_relation.c:3917 parser/parse_relation.c:3931 +#: parser/parse_expr.c:407 parser/parse_relation.c:3915 +#: parser/parse_relation.c:3925 parser/parse_relation.c:3943 +#: parser/parse_relation.c:3950 parser/parse_relation.c:3964 #, c-format msgid "column %s.%s does not exist" msgstr "Spalte %s.%s existiert nicht" @@ -22954,8 +23054,8 @@ msgstr "Spaltenverweise können nicht in Partitionsbegrenzungsausdrücken verwen msgid "cannot use column reference in FOR PORTION OF expression" msgstr "Spaltenverweise können nicht in DEFAULT-Ausdrücken verwendet werden" -#: parser/parse_expr.c:861 parser/parse_relation.c:844 -#: parser/parse_relation.c:926 parser/parse_target.c:1246 +#: parser/parse_expr.c:861 parser/parse_relation.c:876 +#: parser/parse_relation.c:958 parser/parse_target.c:1246 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "Spaltenverweis »%s« ist nicht eindeutig" @@ -22994,7 +23094,7 @@ msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() ex msgstr "die Quelle für ein UPDATE-Element mit mehreren Spalten muss ein Sub-SELECT oder ein ROW()-Ausdruck sein" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_expr.c:1786 parser/parse_expr.c:2285 parser/parse_func.c:2810 +#: parser/parse_expr.c:1786 parser/parse_expr.c:2285 parser/parse_func.c:2814 #, c-format msgid "set-returning functions are not allowed in %s" msgstr "Funktionen mit Ergebnismenge sind in %s nicht erlaubt" @@ -23063,7 +23163,7 @@ msgstr "Unteranfragen können nicht in Partitionierungsschlüsselausdrücken ver msgid "cannot use subquery in FOR PORTION OF expression" msgstr "Unteranfragen können nicht in DEFAULT-Ausdrücken verwendet werden" -#: parser/parse_expr.c:1946 parser/parse_expr.c:3820 +#: parser/parse_expr.c:1946 parser/parse_expr.c:3850 #, c-format msgid "subquery must return only one column" msgstr "Unteranfrage darf nur eine Spalte zurückgeben" @@ -23198,54 +23298,54 @@ msgstr "Rückgabe von SETOF-Typen wird in SQL/JSON-Funktionen nicht unterstützt msgid "returning pseudo-types is not supported in SQL/JSON functions" msgstr "Rückgabe von Pseudotypen wird in SQL/JSON-Funktionen nicht unterstützt" -#: parser/parse_expr.c:3905 parser/parse_func.c:881 +#: parser/parse_expr.c:3990 parser/parse_func.c:887 #, c-format msgid "aggregate ORDER BY is not implemented for window functions" msgstr "ORDER BY in Aggregatfunktion ist für Fensterfunktionen nicht implementiert" -#: parser/parse_expr.c:4128 +#: parser/parse_expr.c:4223 #, c-format msgid "cannot use JSON FORMAT ENCODING clause for non-bytea input types" msgstr "JSON-FORMAT-ENCODING-Klausel kann nur für Eingabetyp bytea verwendet werden" -#: parser/parse_expr.c:4148 +#: parser/parse_expr.c:4243 #, c-format msgid "cannot use type %s in IS JSON predicate" msgstr "Typ %s kann nicht im IS-JSON-Prädikat verwendet werden" -#: parser/parse_expr.c:4175 parser/parse_expr.c:4296 +#: parser/parse_expr.c:4270 parser/parse_expr.c:4391 #, c-format msgid "cannot use type %s in RETURNING clause of %s" msgstr "Typ %s kann nicht in der RETURNING-Klausel von %s verwendet werden" -#: parser/parse_expr.c:4177 +#: parser/parse_expr.c:4272 #, c-format msgid "Try returning json or jsonb." msgstr "Versuchen Sie json oder jsonb zurückzugeben." -#: parser/parse_expr.c:4225 +#: parser/parse_expr.c:4320 #, c-format msgid "cannot use non-string types with WITH UNIQUE KEYS clause" msgstr "Klausel WITH UNIQUE KEYS kann nicht mit Typen verwendet werden, die keine Zeichenketten sind" -#: parser/parse_expr.c:4299 +#: parser/parse_expr.c:4394 #, c-format msgid "Try returning a string type or bytea." msgstr "Versuchen Sie einen Zeichenkettentyp oder bytea zurückzugeben." -#: parser/parse_expr.c:4367 +#: parser/parse_expr.c:4462 #, c-format msgid "cannot specify FORMAT JSON in RETURNING clause of %s()" msgstr "FORMAT JSON kann nicht in der RETURNING-Klausel von %s() angegeben werden" -#: parser/parse_expr.c:4380 +#: parser/parse_expr.c:4475 #, c-format msgid "SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is used" msgstr "SQL/JSON-QUOTES-Verhalten darf nicht angegeben werden, wenn WITH WRAPPER verwendet wird" #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4394 parser/parse_expr.c:4423 parser/parse_expr.c:4454 -#: parser/parse_expr.c:4480 parser/parse_expr.c:4506 +#: parser/parse_expr.c:4489 parser/parse_expr.c:4518 parser/parse_expr.c:4549 +#: parser/parse_expr.c:4575 parser/parse_expr.c:4601 #: parser/parse_jsontable.c:92 #, c-format msgid "invalid %s behavior" @@ -23253,7 +23353,7 @@ msgstr "ungültiges »%s«-Verhalten" #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY), #. second %s is a SQL/JSON function name (e.g. JSON_QUERY) -#: parser/parse_expr.c:4397 parser/parse_expr.c:4426 +#: parser/parse_expr.c:4492 parser/parse_expr.c:4521 #, c-format msgid "Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for %s." msgstr "Nur ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT oder DEFAULT-Ausdruck sind erlaubt in %s für %s." @@ -23261,73 +23361,73 @@ msgstr "Nur ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT oder DEFAULT-Ausdruck sind er #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) #. translator: first %s is name a SQL/JSON clause (eg. ON EMPTY) #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4404 parser/parse_expr.c:4433 parser/parse_expr.c:4462 -#: parser/parse_expr.c:4490 parser/parse_expr.c:4516 +#: parser/parse_expr.c:4499 parser/parse_expr.c:4528 parser/parse_expr.c:4557 +#: parser/parse_expr.c:4585 parser/parse_expr.c:4611 #, c-format msgid "invalid %s behavior for column \"%s\"" msgstr "ungültiges »%s«-Verhalten für Spalte »%s«" #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4407 parser/parse_expr.c:4436 +#: parser/parse_expr.c:4502 parser/parse_expr.c:4531 #, c-format msgid "Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for formatted columns." msgstr "Nur ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT oder DEFAULT-Ausdruck sind erlaubt in %s für formatierte Spalten." -#: parser/parse_expr.c:4455 +#: parser/parse_expr.c:4550 #, c-format msgid "Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for %s." msgstr "Nur ERROR, TRUE, FALSE oder UNKNOWN sind erlaubt in %s für %s." #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4465 +#: parser/parse_expr.c:4560 #, c-format msgid "Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for EXISTS columns." msgstr "Nur ERROR, TRUE, FALSE oder UNKNOWN sind erlaubt in %s für EXISTS-Spalten." #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY), #. second %s is a SQL/JSON function name (e.g. JSON_QUERY) -#: parser/parse_expr.c:4483 parser/parse_expr.c:4509 +#: parser/parse_expr.c:4578 parser/parse_expr.c:4604 #, c-format msgid "Only ERROR, NULL, or DEFAULT expression is allowed in %s for %s." msgstr "Nur ERROR, NULL oder DEFAULT-Ausdruck sind erlaubt in %s für %s." #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4493 parser/parse_expr.c:4519 +#: parser/parse_expr.c:4588 parser/parse_expr.c:4614 #, c-format msgid "Only ERROR, NULL, or DEFAULT expression is allowed in %s for scalar columns." msgstr "Nur ERROR, NULL oder DEFAULT-Ausdruck sind erlaubt in %s für skalare Spalten." -#: parser/parse_expr.c:4553 +#: parser/parse_expr.c:4648 #, c-format msgid "JSON path expression must be of type %s, not of type %s" msgstr "JSON-Pfadausdruck muss Typ %s haben, nicht Typ %s" -#: parser/parse_expr.c:4793 +#: parser/parse_expr.c:4888 #, c-format msgid "can only specify a constant, non-aggregate function, or operator expression for DEFAULT" msgstr "für DEFAULT kann nur eine Konstante, Nicht-Aggregat-Funktion oder ein Operatorausdruck angegeben werden" -#: parser/parse_expr.c:4798 +#: parser/parse_expr.c:4893 #, c-format msgid "DEFAULT expression must not contain column references" msgstr "DEFAULT-Ausdruck darf keine Spaltenverweise enthalten" -#: parser/parse_expr.c:4803 +#: parser/parse_expr.c:4898 #, c-format msgid "DEFAULT expression must not return a set" msgstr "DEFAULT-Ausdruck darf keine Ergebnismenge zurückgeben" -#: parser/parse_expr.c:4818 +#: parser/parse_expr.c:4913 #, c-format msgid "collation of DEFAULT expression conflicts with RETURNING clause" msgstr "Sortierfolge des DEFAULT-Ausdrucks kollidiert mit der RETURNING-Klausel" -#: parser/parse_expr.c:4897 parser/parse_expr.c:4906 +#: parser/parse_expr.c:5001 parser/parse_expr.c:5010 #, c-format msgid "cannot cast behavior expression of type %s to %s" msgstr "kann Verhaltensausdruck nicht von Typ %s in %s umwandeln" -#: parser/parse_expr.c:4900 +#: parser/parse_expr.c:5004 #, c-format msgid "You will need to explicitly cast the expression to type %s." msgstr "Sie werden den Ausdruck ausdrücklich in Typ %s umwandeln müssen." @@ -23342,7 +23442,7 @@ msgstr "Argumentname »%s« mehrmals angegeben" msgid "positional argument cannot follow named argument" msgstr "Positionsargument kann nicht hinter benanntem Argument stehen" -#: parser/parse_func.c:292 parser/parse_func.c:2493 +#: parser/parse_func.c:292 parser/parse_func.c:2500 #, c-format msgid "%s is not a procedure" msgstr "%s ist keine Prozedur" @@ -23392,378 +23492,385 @@ msgstr "FILTER wurde angegeben, aber %s ist keine Aggregatfunktion" msgid "OVER specified, but %s is not a window function nor an aggregate function" msgstr "OVER angegeben, aber %s ist keine Fensterfunktion oder Aggregatfunktion" -#: parser/parse_func.c:389 +#. translator: first %s is a null treatment option, eg IGNORE NULLS +#: parser/parse_func.c:358 +#, fuzzy, c-format +#| msgid "%s(*) specified, but %s is not an aggregate function" +msgid "%s specified, but %s is not a window function" +msgstr "%s(*) angegeben, aber %s ist keine Aggregatfunktion" + +#: parser/parse_func.c:396 #, c-format msgid "WITHIN GROUP is required for ordered-set aggregate %s" msgstr "WITHIN GROUP muss angegeben werden für Ordered-Set-Aggregatfunktion %s" -#: parser/parse_func.c:395 +#: parser/parse_func.c:402 #, c-format msgid "OVER is not supported for ordered-set aggregate %s" msgstr "OVER wird für Ordered-Set-Aggregatfunktion %s nicht unterstützt" -#: parser/parse_func.c:426 parser/parse_func.c:457 +#: parser/parse_func.c:433 parser/parse_func.c:464 #, c-format msgid "There is an ordered-set aggregate %s, but it requires %d direct argument, not %d." msgid_plural "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." msgstr[0] "Es gibt eine Ordered-Set-Aggregatfunktion %s, aber sie benötigt %d direktes Argument, nicht %d." msgstr[1] "Es gibt eine Ordered-Set-Aggregatfunktion %s, aber sie benötigt %d direkte Argumente, nicht %d." -#: parser/parse_func.c:484 +#: parser/parse_func.c:491 #, c-format msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." msgstr "Um die Hypothetical-Set-Aggregatfunktion %s zu verwenden, muss die Anzahl der hypothetischen direkten Argumente (hier %d) mit der Anzahl der Sortierspalten (hier %d) übereinstimmen." -#: parser/parse_func.c:498 +#: parser/parse_func.c:505 #, c-format msgid "There is an ordered-set aggregate %s, but it requires at least %d direct argument." msgid_plural "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." msgstr[0] "Es gibt eine Ordered-Set-Aggregatfunktion %s, aber sie benötigt mindestens %d direktes Argument." msgstr[1] "Es gibt eine Ordered-Set-Aggregatfunktion %s, aber sie benötigt mindestens %d direkte Argumente." -#: parser/parse_func.c:519 +#: parser/parse_func.c:526 #, c-format msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" msgstr "%s ist keine Ordered-Set-Aggregatfunktion und kann deshalb kein WITHIN GROUP haben" -#: parser/parse_func.c:527 +#: parser/parse_func.c:534 #, fuzzy, c-format #| msgid "aggregate functions are not allowed in EXECUTE parameters" msgid "aggregate functions do not accept RESPECT/IGNORE NULLS" msgstr "Aggregatfunktionen sind in EXECUTE-Parametern nicht erlaubt" -#: parser/parse_func.c:539 +#: parser/parse_func.c:545 #, c-format msgid "window function %s requires an OVER clause" msgstr "Fensterfunktion %s erfordert eine OVER-Klausel" -#: parser/parse_func.c:546 +#: parser/parse_func.c:552 #, c-format msgid "window function %s cannot have WITHIN GROUP" msgstr "Fensterfunktion %s kann kein WITHIN GROUP haben" -#: parser/parse_func.c:575 +#: parser/parse_func.c:581 #, c-format msgid "procedure %s is not unique" msgstr "Prozedur %s ist nicht eindeutig" -#: parser/parse_func.c:578 +#: parser/parse_func.c:584 #, fuzzy, c-format #| msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." msgid "Could not choose a best candidate procedure." msgstr "Konnte keine beste Kandidatprozedur auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." -#: parser/parse_func.c:579 parser/parse_func.c:588 parser/parse_func.c:1018 -#: parser/parse_oper.c:639 parser/parse_oper.c:688 +#: parser/parse_func.c:585 parser/parse_func.c:594 parser/parse_func.c:1024 +#: parser/parse_oper.c:645 parser/parse_oper.c:694 #, fuzzy, c-format #| msgid "You might need to add an explicit cast." msgid "You might need to add explicit type casts." msgstr "Sie müssen möglicherweise eine ausdrückliche Typumwandlung hinzufügen." -#: parser/parse_func.c:584 +#: parser/parse_func.c:590 #, c-format msgid "function %s is not unique" msgstr "Funktion %s ist nicht eindeutig" -#: parser/parse_func.c:587 +#: parser/parse_func.c:593 #, fuzzy, c-format #| msgid "Could not choose a best candidate function. You might need to add explicit type casts." msgid "Could not choose a best candidate function." msgstr "Konnte keine beste Kandidatfunktion auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." -#: parser/parse_func.c:628 +#: parser/parse_func.c:634 #, fuzzy, c-format #| msgid "No function matches the given name and argument types. You might need to add explicit type casts." msgid "No aggregate function matches the given name and argument types." msgstr "Keine Funktion stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." -#: parser/parse_func.c:629 +#: parser/parse_func.c:635 #, fuzzy, c-format #| msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." msgid "Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." msgstr "Keine Aggregatfunktion stimmt mit dem angegebenen Namen und den Argumenttypen überein. Mõglicherweise steht ORDER BY an der falschen Stelle; ORDER BY muss hinter allen normalen Argumenten der Aggregatfunktion stehen." -#: parser/parse_func.c:636 parser/parse_func.c:2536 +#: parser/parse_func.c:642 parser/parse_func.c:2543 #, c-format msgid "procedure %s does not exist" msgstr "Prozedur %s existiert nicht" -#: parser/parse_func.c:750 +#: parser/parse_func.c:756 #, c-format msgid "VARIADIC argument must be an array" msgstr "VARIADIC-Argument muss ein Array sein" -#: parser/parse_func.c:805 parser/parse_func.c:871 +#: parser/parse_func.c:811 parser/parse_func.c:877 #, c-format msgid "%s(*) must be used to call a parameterless aggregate function" msgstr "beim Aufruf einer parameterlosen Aggregatfunktion muss %s(*) angegeben werden" -#: parser/parse_func.c:812 +#: parser/parse_func.c:818 #, c-format msgid "aggregates cannot return sets" msgstr "Aggregatfunktionen können keine Ergebnismengen zurückgeben" -#: parser/parse_func.c:827 +#: parser/parse_func.c:833 #, c-format msgid "aggregates cannot use named arguments" msgstr "Aggregatfunktionen können keine benannten Argumente verwenden" -#: parser/parse_func.c:861 +#: parser/parse_func.c:867 #, c-format msgid "DISTINCT is not implemented for window functions" msgstr "DISTINCT ist für Fensterfunktionen nicht implementiert" -#: parser/parse_func.c:890 +#: parser/parse_func.c:896 #, c-format msgid "FILTER is not implemented for non-aggregate window functions" msgstr "FILTER ist für Fensterfunktionen, die keine Aggregatfunktionen sind, nicht implementiert" -#: parser/parse_func.c:899 +#: parser/parse_func.c:905 #, c-format msgid "window function calls cannot contain set-returning function calls" msgstr "Aufrufe von Fensterfunktionen können keine Aufrufe von Funktionen mit Ergebnismenge enthalten" -#: parser/parse_func.c:907 +#: parser/parse_func.c:913 #, c-format msgid "window functions cannot return sets" msgstr "Fensterfunktionen können keine Ergebnismengen zurückgeben" -#: parser/parse_func.c:950 +#: parser/parse_func.c:956 #, fuzzy, c-format #| msgid "There is no previous error." msgid "There is no procedure of that name." msgstr "Es gibt keinen vorangegangenen Fehler." -#: parser/parse_func.c:952 +#: parser/parse_func.c:958 #, fuzzy, c-format #| msgid "there is no subtransaction to exit from" msgid "There is no function of that name." msgstr "es gibt keine Subtransaktion zu beenden" -#: parser/parse_func.c:957 +#: parser/parse_func.c:963 #, c-format msgid "A procedure of that name exists, but it is not in the search_path." msgstr "" -#: parser/parse_func.c:959 +#: parser/parse_func.c:965 #, c-format msgid "A function of that name exists, but it is not in the search_path." msgstr "" -#: parser/parse_func.c:971 +#: parser/parse_func.c:977 #, fuzzy, c-format #| msgid "procedures cannot accept set arguments" msgid "No procedure of that name accepts the given number of arguments." msgstr "Prozeduren können keine SETOF-Argumente haben" -#: parser/parse_func.c:973 +#: parser/parse_func.c:979 #, fuzzy, c-format #| msgid "cast function must take one to three arguments" msgid "No function of that name accepts the given number of arguments." msgstr "Typumwandlungsfunktion muss ein bis drei Argumente haben" -#: parser/parse_func.c:983 +#: parser/parse_func.c:989 #, fuzzy, c-format #| msgid "procedures cannot accept set arguments" msgid "No procedure of that name accepts the given argument names." msgstr "Prozeduren können keine SETOF-Argumente haben" -#: parser/parse_func.c:985 +#: parser/parse_func.c:991 #, fuzzy, c-format #| msgid "cast function must take one to three arguments" msgid "No function of that name accepts the given argument names." msgstr "Typumwandlungsfunktion muss ein bis drei Argumente haben" -#: parser/parse_func.c:998 +#: parser/parse_func.c:1004 #, c-format msgid "In the closest available match, an argument was specified both positionally and by name." msgstr "" -#: parser/parse_func.c:1002 +#: parser/parse_func.c:1008 #, c-format msgid "In the closest available match, not all required arguments were supplied." msgstr "" -#: parser/parse_func.c:1006 +#: parser/parse_func.c:1012 #, c-format msgid "This call would be correct if the variadic array were labeled VARIADIC and placed last." msgstr "" -#: parser/parse_func.c:1009 +#: parser/parse_func.c:1015 #, fuzzy, c-format #| msgid "VARIADIC parameter must be the last input parameter" msgid "The VARIADIC parameter must be placed last, even when using argument names." msgstr "VARIADIC-Parameter muss der letzte Eingabeparameter sein" -#: parser/parse_func.c:1015 +#: parser/parse_func.c:1021 #, fuzzy, c-format #| msgid "procedures cannot accept set arguments" msgid "No procedure of that name accepts the given argument types." msgstr "Prozeduren können keine SETOF-Argumente haben" -#: parser/parse_func.c:1017 +#: parser/parse_func.c:1023 #, fuzzy, c-format #| msgid "function \"%s\" already exists with same argument types" msgid "No function of that name accepts the given argument types." msgstr "Funktion »%s« existiert bereits mit den selben Argumenttypen" -#: parser/parse_func.c:2292 parser/parse_func.c:2565 +#: parser/parse_func.c:2299 parser/parse_func.c:2572 #, c-format msgid "could not find a function named \"%s\"" msgstr "konnte keine Funktion namens »%s« finden" -#: parser/parse_func.c:2306 parser/parse_func.c:2583 +#: parser/parse_func.c:2313 parser/parse_func.c:2590 #, c-format msgid "function name \"%s\" is not unique" msgstr "Funktionsname »%s« ist nicht eindeutig" -#: parser/parse_func.c:2308 parser/parse_func.c:2586 +#: parser/parse_func.c:2315 parser/parse_func.c:2593 #, c-format msgid "Specify the argument list to select the function unambiguously." msgstr "Geben Sie eine Argumentliste an, um die Funktion eindeutig auszuwählen." -#: parser/parse_func.c:2352 +#: parser/parse_func.c:2359 #, c-format msgid "procedures cannot have more than %d argument" msgid_plural "procedures cannot have more than %d arguments" msgstr[0] "Prozeduren können nicht mehr als %d Argument haben" msgstr[1] "Prozeduren können nicht mehr als %d Argumente haben" -#: parser/parse_func.c:2483 +#: parser/parse_func.c:2490 #, c-format msgid "%s is not a function" msgstr "%s ist keine Funktion" -#: parser/parse_func.c:2503 +#: parser/parse_func.c:2510 #, c-format msgid "function %s is not an aggregate" msgstr "Funktion %s ist keine Aggregatfunktion" -#: parser/parse_func.c:2531 +#: parser/parse_func.c:2538 #, c-format msgid "could not find a procedure named \"%s\"" msgstr "konnte keine Prozedur namens »%s« finden" -#: parser/parse_func.c:2545 +#: parser/parse_func.c:2552 #, c-format msgid "could not find an aggregate named \"%s\"" msgstr "konnte keine Aggregatfunktion namens »%s« finden" -#: parser/parse_func.c:2550 +#: parser/parse_func.c:2557 #, c-format msgid "aggregate %s(*) does not exist" msgstr "Aggregatfunktion %s(*) existiert nicht" -#: parser/parse_func.c:2555 +#: parser/parse_func.c:2562 #, c-format msgid "aggregate %s does not exist" msgstr "Aggregatfunktion %s existiert nicht" -#: parser/parse_func.c:2591 +#: parser/parse_func.c:2598 #, c-format msgid "procedure name \"%s\" is not unique" msgstr "Prozedurname »%s« ist nicht eindeutig" -#: parser/parse_func.c:2594 +#: parser/parse_func.c:2601 #, c-format msgid "Specify the argument list to select the procedure unambiguously." msgstr "Geben Sie eine Argumentliste an, um die Prozedur eindeutig auszuwählen." -#: parser/parse_func.c:2599 +#: parser/parse_func.c:2606 #, c-format msgid "aggregate name \"%s\" is not unique" msgstr "Aggregatfunktionsname »%s« ist nicht eindeutig" -#: parser/parse_func.c:2602 +#: parser/parse_func.c:2609 #, c-format msgid "Specify the argument list to select the aggregate unambiguously." msgstr "Geben Sie eine Argumentliste an, um die Aggregatfunktion eindeutig auszuwählen." -#: parser/parse_func.c:2607 +#: parser/parse_func.c:2614 #, c-format msgid "routine name \"%s\" is not unique" msgstr "Routinenname »%s« ist nicht eindeutig" -#: parser/parse_func.c:2610 +#: parser/parse_func.c:2617 #, c-format msgid "Specify the argument list to select the routine unambiguously." msgstr "Geben Sie eine Argumentliste an, um die Routine eindeutig auszuwählen." -#: parser/parse_func.c:2665 +#: parser/parse_func.c:2672 msgid "set-returning functions are not allowed in JOIN conditions" msgstr "Funktionen mit Ergebnismenge sind in JOIN-Bedingungen nicht erlaubt" -#: parser/parse_func.c:2686 +#: parser/parse_func.c:2693 msgid "set-returning functions are not allowed in policy expressions" msgstr "Funktionen mit Ergebnismenge sind in Policy-Ausdrücken nicht erlaubt" -#: parser/parse_func.c:2702 +#: parser/parse_func.c:2706 msgid "set-returning functions are not allowed in window definitions" msgstr "Funktionen mit Ergebnismenge sind in Fensterdefinitionen nicht erlaubt" -#: parser/parse_func.c:2740 +#: parser/parse_func.c:2744 msgid "set-returning functions are not allowed in MERGE WHEN conditions" msgstr "Funktionen mit Ergebnismenge sind in MERGE-WHEN-Bedingungen nicht erlaubt" -#: parser/parse_func.c:2744 +#: parser/parse_func.c:2748 msgid "set-returning functions are not allowed in check constraints" msgstr "Funktionen mit Ergebnismenge sind in Check-Constraints nicht erlaubt" -#: parser/parse_func.c:2748 +#: parser/parse_func.c:2752 msgid "set-returning functions are not allowed in DEFAULT expressions" msgstr "Funktionen mit Ergebnismenge sind in DEFAULT-Ausdrücken nicht erlaubt" -#: parser/parse_func.c:2751 +#: parser/parse_func.c:2755 msgid "set-returning functions are not allowed in index expressions" msgstr "Funktionen mit Ergebnismenge sind in Indexausdrücken nicht erlaubt" -#: parser/parse_func.c:2754 +#: parser/parse_func.c:2758 msgid "set-returning functions are not allowed in index predicates" msgstr "Funktionen mit Ergebnismenge sind in Indexprädikaten nicht erlaubt" -#: parser/parse_func.c:2757 +#: parser/parse_func.c:2761 msgid "set-returning functions are not allowed in statistics expressions" msgstr "Funktionen mit Ergebnismenge sind in Statistikausdrücken nicht erlaubt" -#: parser/parse_func.c:2760 +#: parser/parse_func.c:2764 msgid "set-returning functions are not allowed in transform expressions" msgstr "Funktionen mit Ergebnismenge sind in Umwandlungsausdrücken nicht erlaubt" -#: parser/parse_func.c:2763 +#: parser/parse_func.c:2767 msgid "set-returning functions are not allowed in EXECUTE parameters" msgstr "Funktionen mit Ergebnismenge sind in EXECUTE-Parametern nicht erlaubt" -#: parser/parse_func.c:2766 +#: parser/parse_func.c:2770 msgid "set-returning functions are not allowed in trigger WHEN conditions" msgstr "Funktionen mit Ergebnismenge sind in der WHEN-Bedingung eines Triggers nicht erlaubt" -#: parser/parse_func.c:2769 +#: parser/parse_func.c:2773 msgid "set-returning functions are not allowed in partition bound" msgstr "Funktionen mit Ergebnismenge sind in Partitionsbegrenzungen nicht erlaubt" -#: parser/parse_func.c:2772 +#: parser/parse_func.c:2776 msgid "set-returning functions are not allowed in partition key expressions" msgstr "Funktionen mit Ergebnismenge sind in Partitionierungsschlüsselausdrücken nicht erlaubt" -#: parser/parse_func.c:2775 +#: parser/parse_func.c:2779 msgid "set-returning functions are not allowed in CALL arguments" msgstr "Funktionen mit Ergebnismenge sind in CALL-Argumenten nicht erlaubt" -#: parser/parse_func.c:2778 +#: parser/parse_func.c:2782 msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" msgstr "Funktionen mit Ergebnismenge sind in COPY-FROM-WHERE-Bedingungen nicht erlaubt" -#: parser/parse_func.c:2781 +#: parser/parse_func.c:2785 msgid "set-returning functions are not allowed in column generation expressions" msgstr "Funktionen mit Ergebnismenge sind in Spaltengenerierungsausdrücken nicht erlaubt" -#: parser/parse_func.c:2787 +#: parser/parse_func.c:2791 #, fuzzy #| msgid "set-returning functions are not allowed in partition key expressions" msgid "set-returning functions are not allowed in property definition expressions" msgstr "Funktionen mit Ergebnismenge sind in Partitionierungsschlüsselausdrücken nicht erlaubt" -#: parser/parse_func.c:2790 +#: parser/parse_func.c:2794 #, fuzzy #| msgid "set-returning functions are not allowed in DEFAULT expressions" msgid "set-returning functions are not allowed in FOR PORTION OF expressions" @@ -23794,10 +23901,9 @@ msgid "property \"%s\" does not exist" msgstr "Portal »%s« existiert nicht" #: parser/parse_graphtable.c:191 -#, fuzzy, c-format -#| msgid "table \"%s\" does not exist, skipping" +#, c-format msgid "label \"%s\" does not exist in property graph \"%s\"" -msgstr "Tabelle »%s« existiert nicht, wird übersprungen" +msgstr "Label »%s« existiert nicht in Property-Graph »%s«" #: parser/parse_graphtable.c:246 #, fuzzy, c-format @@ -23805,35 +23911,35 @@ msgstr "Tabelle »%s« existiert nicht, wird übersprungen" msgid "element pattern quantifier is not supported" msgstr "Regeln für materialisierte Sichten werden nicht unterstützt" -#: parser/parse_graphtable.c:276 +#: parser/parse_graphtable.c:281 #, fuzzy, c-format #| msgid "unsupported object type \"%s\"" msgid "unsupported element pattern kind: \"%s\"" msgstr "nicht unterstützter Objekttyp »%s«" -#: parser/parse_graphtable.c:284 +#: parser/parse_graphtable.c:289 #, c-format msgid "path pattern cannot start with an edge pattern" msgstr "" -#: parser/parse_graphtable.c:289 +#: parser/parse_graphtable.c:294 #, c-format msgid "edge pattern must be preceded by a vertex pattern" msgstr "" -#: parser/parse_graphtable.c:297 +#: parser/parse_graphtable.c:302 #, fuzzy, c-format #| msgid "postfix operators are not supported" msgid "adjacent vertex patterns are not supported" msgstr "Postfix-Operatoren werden nicht unterstützt" -#: parser/parse_graphtable.c:313 +#: parser/parse_graphtable.c:318 #, fuzzy, c-format #| msgid "LIKE pattern must not end with escape character" msgid "path pattern cannot end with an edge pattern" msgstr "LIKE-Muster darf nicht mit Escape-Zeichen enden" -#: parser/parse_graphtable.c:341 +#: parser/parse_graphtable.c:346 #, c-format msgid "multiple path patterns in one GRAPH_TABLE clause not supported" msgstr "" @@ -23873,7 +23979,7 @@ msgstr "Der Name wird sowohl als MERGE-Zieltabelle als auch als Datenquelle verw msgid "target lists can have at most %d entries" msgstr "Targetlisten können höchstens %d Einträge haben" -#: parser/parse_oper.c:117 parser/parse_oper.c:723 +#: parser/parse_oper.c:117 parser/parse_oper.c:729 #, c-format msgid "postfix operators are not supported" msgstr "Postfix-Operatoren werden nicht unterstützt" @@ -23883,60 +23989,60 @@ msgstr "Postfix-Operatoren werden nicht unterstützt" msgid "Use an explicit ordering operator or modify the query." msgstr "Verwenden Sie einen ausdrücklichen Sortieroperator oder ändern Sie die Anfrage." -#: parser/parse_oper.c:478 +#: parser/parse_oper.c:482 #, c-format msgid "operator requires run-time type coercion: %s" msgstr "Operator erfordert Typumwandlung zur Laufzeit: %s" -#: parser/parse_oper.c:636 +#: parser/parse_oper.c:642 #, c-format msgid "operator is not unique: %s" msgstr "Operator ist nicht eindeutig: %s" -#: parser/parse_oper.c:638 +#: parser/parse_oper.c:644 #, fuzzy, c-format #| msgid "Could not choose a best candidate operator. You might need to add explicit type casts." msgid "Could not choose a best candidate operator." msgstr "Konnte keinen besten Kandidatoperator auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." -#: parser/parse_oper.c:672 +#: parser/parse_oper.c:678 #, fuzzy, c-format #| msgid "List of operators of operator families" msgid "There is no operator of that name." msgstr "Liste der Operatoren in Operatorfamilien" -#: parser/parse_oper.c:674 +#: parser/parse_oper.c:680 #, c-format msgid "An operator of that name exists, but it is not in the search_path." msgstr "" -#: parser/parse_oper.c:682 +#: parser/parse_oper.c:688 #, c-format msgid "No operator of that name accepts the given argument type." msgstr "" -#: parser/parse_oper.c:683 +#: parser/parse_oper.c:689 #, fuzzy, c-format #| msgid "You might need to add an explicit cast." msgid "You might need to add an explicit type cast." msgstr "Sie müssen möglicherweise eine ausdrückliche Typumwandlung hinzufügen." -#: parser/parse_oper.c:687 +#: parser/parse_oper.c:693 #, c-format msgid "No operator of that name accepts the given argument types." msgstr "" -#: parser/parse_oper.c:848 +#: parser/parse_oper.c:854 #, c-format msgid "op ANY/ALL (array) requires array on right side" msgstr "op ANY/ALL (array) erfordert Array auf der rechten Seite" -#: parser/parse_oper.c:889 +#: parser/parse_oper.c:895 #, c-format msgid "op ANY/ALL (array) requires operator to yield boolean" msgstr "op ANY/ALL (array) erfordert, dass Operator boolean ergibt" -#: parser/parse_oper.c:894 +#: parser/parse_oper.c:900 #, c-format msgid "op ANY/ALL (array) requires operator not to return a set" msgstr "op ANY/ALL (array) erfordert, dass Operator keine Ergebnismenge zurückgibt" @@ -23946,7 +24052,7 @@ msgstr "op ANY/ALL (array) erfordert, dass Operator keine Ergebnismenge zurückg msgid "inconsistent types deduced for parameter $%d" msgstr "inkonsistente Typen für Parameter $%d ermittelt" -#: parser/parse_param.c:310 tcop/postgres.c:750 +#: parser/parse_param.c:310 tcop/postgres.c:751 #, c-format msgid "could not determine data type of parameter $%d" msgstr "konnte Datentyp von Parameter $%d nicht ermitteln" @@ -23961,13 +24067,13 @@ msgstr "Tabellenbezug »%s« ist nicht eindeutig" msgid "table reference %u is ambiguous" msgstr "Tabellenbezug %u ist nicht eindeutig" -#: parser/parse_relation.c:498 parser/parse_relation.c:3824 -#: parser/parse_relation.c:3833 +#: parser/parse_relation.c:498 parser/parse_relation.c:3857 +#: parser/parse_relation.c:3866 #, c-format msgid "invalid reference to FROM-clause entry for table \"%s\"" msgstr "ungültiger Verweis auf FROM-Klausel-Eintrag für Tabelle »%s«" -#: parser/parse_relation.c:502 parser/parse_relation.c:3835 +#: parser/parse_relation.c:502 parser/parse_relation.c:3868 #, c-format msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." msgstr "Es gibt einen Eintrag für Tabelle »%s«, aber auf ihn kann aus diesem Teil der Anfrage nicht verwiesen werden." @@ -23977,149 +24083,149 @@ msgstr "Es gibt einen Eintrag für Tabelle »%s«, aber auf ihn kann aus diesem msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." msgstr "Der JOIN-Typ für LATERAL muss INNER oder LEFT sein." -#: parser/parse_relation.c:707 +#: parser/parse_relation.c:739 #, c-format msgid "system column \"%s\" reference in check constraint is invalid" msgstr "Verweis auf Systemspalte »%s« im Check-Constraint ist ungültig" -#: parser/parse_relation.c:720 +#: parser/parse_relation.c:752 #, c-format msgid "cannot use system column \"%s\" in column generation expression" msgstr "Systemspalte »%s« kann nicht in Spaltengenerierungsausdruck verwendet werden" -#: parser/parse_relation.c:731 +#: parser/parse_relation.c:763 #, c-format msgid "cannot use system column \"%s\" in MERGE WHEN condition" msgstr "Systemspalte »%s« kann nicht in MERGE-WHEN-Bedingung verwendet werden" -#: parser/parse_relation.c:1247 parser/parse_relation.c:1696 -#: parser/parse_relation.c:2485 +#: parser/parse_relation.c:1279 parser/parse_relation.c:1728 +#: parser/parse_relation.c:2517 #, c-format msgid "table \"%s\" has %d columns available but %d columns specified" msgstr "Tabelle »%s« hat %d Spalten, aber %d Spalten wurden angegeben" -#: parser/parse_relation.c:1454 +#: parser/parse_relation.c:1486 #, c-format msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." msgstr "Es gibt ein WITH-Element namens »%s«, aber darauf kann aus diesem Teil der Anfrage kein Bezug genommen werden." -#: parser/parse_relation.c:1456 +#: parser/parse_relation.c:1488 #, c-format msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." msgstr "Verwenden Sie WITH RECURSIVE oder sortieren Sie die WITH-Ausdrücke um, um Vorwärtsreferenzen zu entfernen." -#: parser/parse_relation.c:1838 +#: parser/parse_relation.c:1870 #, c-format msgid "a column definition list is redundant for a function with OUT parameters" msgstr "eine Spaltendefinitionsliste ist überflüssig bei einer Funktion mit OUT-Parametern" -#: parser/parse_relation.c:1844 +#: parser/parse_relation.c:1876 #, c-format msgid "a column definition list is redundant for a function returning a named composite type" msgstr "eine Spaltendefinitionsliste ist überflüssig bei einer Funktion, die einen benannten zusammengesetzten Typ zurückgibt" -#: parser/parse_relation.c:1851 +#: parser/parse_relation.c:1883 #, c-format msgid "a column definition list is only allowed for functions returning \"record\"" msgstr "eine Spaltendefinitionsliste ist nur erlaubt bei Funktionen, die »record« zurückgeben" -#: parser/parse_relation.c:1862 +#: parser/parse_relation.c:1894 #, c-format msgid "a column definition list is required for functions returning \"record\"" msgstr "eine Spaltendefinitionsliste ist erforderlich bei Funktionen, die »record« zurückgeben" -#: parser/parse_relation.c:1900 +#: parser/parse_relation.c:1932 #, c-format msgid "column definition lists can have at most %d entries" msgstr "Spaltendefinitionslisten können höchstens %d Einträge haben" -#: parser/parse_relation.c:1961 +#: parser/parse_relation.c:1993 #, c-format msgid "function \"%s\" in FROM has unsupported return type %s" msgstr "Funktion »%s« in FROM hat nicht unterstützten Rückgabetyp %s" -#: parser/parse_relation.c:1988 parser/parse_relation.c:2073 +#: parser/parse_relation.c:2020 parser/parse_relation.c:2105 #, c-format msgid "functions in FROM can return at most %d columns" msgstr "Funktionen in FROM können höchstens %d Spalten zurückgeben" -#: parser/parse_relation.c:2103 +#: parser/parse_relation.c:2135 #, c-format msgid "%s function has %d columns available but %d columns specified" msgstr "Funktion %s hat %d Spalten verfügbar, aber %d Spalten wurden angegeben" -#: parser/parse_relation.c:2184 +#: parser/parse_relation.c:2216 #, fuzzy, c-format #| msgid "table \"%s\" has %d columns available but %d columns specified" msgid "GRAPH_TABLE \"%s\" has %d columns available but %d columns specified" msgstr "Tabelle »%s« hat %d Spalten, aber %d Spalten wurden angegeben" -#: parser/parse_relation.c:2277 +#: parser/parse_relation.c:2309 #, c-format msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" msgstr "VALUES-Liste »%s« hat %d Spalten verfügbar, aber %d Spalten wurden angegeben" -#: parser/parse_relation.c:2342 +#: parser/parse_relation.c:2374 #, c-format msgid "joins can have at most %d columns" msgstr "Verbunde können höchstens %d Spalten haben" -#: parser/parse_relation.c:2367 +#: parser/parse_relation.c:2399 #, c-format msgid "join expression \"%s\" has %d columns available but %d columns specified" msgstr "Verbundausdruck »%s« hat %d Spalten verfügbar, aber %d Spalten wurden angegeben" -#: parser/parse_relation.c:2458 +#: parser/parse_relation.c:2490 #, c-format msgid "WITH query \"%s\" does not have a RETURNING clause" msgstr "WITH-Anfrage »%s« hat keine RETURNING-Klausel" -#: parser/parse_relation.c:3826 +#: parser/parse_relation.c:3859 #, c-format msgid "Perhaps you meant to reference the table alias \"%s\"." msgstr "Vielleicht wurde beabsichtigt, auf den Tabellenalias »%s« zu verweisen." -#: parser/parse_relation.c:3838 +#: parser/parse_relation.c:3871 #, c-format msgid "To reference that table, you must mark this subquery with LATERAL." msgstr "Um auf diese Tabelle zu verweisen, müssen Sie diese Unteranfrage mit LATERAL markieren." -#: parser/parse_relation.c:3844 +#: parser/parse_relation.c:3877 #, c-format msgid "missing FROM-clause entry for table \"%s\"" msgstr "fehlender Eintrag in FROM-Klausel für Tabelle »%s«" -#: parser/parse_relation.c:3884 +#: parser/parse_relation.c:3917 #, c-format msgid "There are columns named \"%s\", but they are in tables that cannot be referenced from this part of the query." msgstr "Es gibt Spalten namens »%s«, aber sie sind in Tabellen, auf die aus diesem Teil der Anfrage nicht verwiesen werden kann." -#: parser/parse_relation.c:3886 +#: parser/parse_relation.c:3919 #, c-format msgid "Try using a table-qualified name." msgstr "Versuchen Sie, einen tabellenqualifizierten Namen zu verwenden." -#: parser/parse_relation.c:3894 +#: parser/parse_relation.c:3927 #, c-format msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." msgstr "Es gibt eine Spalte namens »%s« in Tabelle »%s«, aber auf sie kann aus diesem Teil der Anfrage nicht verwiesen werden." -#: parser/parse_relation.c:3897 +#: parser/parse_relation.c:3930 #, c-format msgid "To reference that column, you must mark this subquery with LATERAL." msgstr "Um auf diese Spalte zu verweisen, müssen Sie diese Unteranfrage mit LATERAL markieren." -#: parser/parse_relation.c:3899 +#: parser/parse_relation.c:3932 #, c-format msgid "To reference that column, you must use a table-qualified name." msgstr "Um auf diese Spalte zu verweisen, müssen Sie einen tabellenqualifizierten Namen verwenden." -#: parser/parse_relation.c:3919 +#: parser/parse_relation.c:3952 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\"." msgstr "Vielleicht wurde beabsichtigt, auf die Spalte »%s.%s« zu verweisen." -#: parser/parse_relation.c:3933 +#: parser/parse_relation.c:3966 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." msgstr "Vielleicht wurde beabsichtigt, auf die Spalte »%s.%s« oder die Spalte »%s.%s« zu verweisen." @@ -24184,8 +24290,8 @@ msgstr "falscher %%TYPE-Verweis (zu viele Namensteile): %s" msgid "type reference %s converted to %s" msgstr "Typverweis %s in %s umgewandelt" -#: parser/parse_type.c:278 parser/parse_type.c:813 utils/cache/typcache.c:481 -#: utils/cache/typcache.c:536 +#: parser/parse_type.c:278 parser/parse_type.c:813 utils/cache/typcache.c:490 +#: utils/cache/typcache.c:545 #, c-format msgid "type \"%s\" is only a shell" msgstr "Typ »%s« ist nur eine Hülle" @@ -24306,329 +24412,331 @@ msgstr "Relation »%s« ist ungültig in der LIKE-Klausel" msgid "Index \"%s\" contains a whole-row table reference." msgstr "Index »%s« enthält einen Verweis auf die ganze Zeile der Tabelle." -#: parser/parse_utilcmd.c:2421 +#: parser/parse_utilcmd.c:2425 #, c-format msgid "cannot use an existing index in CREATE TABLE" msgstr "bestehender Index kann nicht in CREATE TABLE verwendet werden" -#: parser/parse_utilcmd.c:2441 +#: parser/parse_utilcmd.c:2445 #, c-format msgid "index \"%s\" is already associated with a constraint" msgstr "Index »%s« gehört bereits zu einem Constraint" -#: parser/parse_utilcmd.c:2467 +#: parser/parse_utilcmd.c:2471 #, c-format msgid "\"%s\" is not a unique index" msgstr "»%s« ist kein Unique Index" -#: parser/parse_utilcmd.c:2468 parser/parse_utilcmd.c:2475 -#: parser/parse_utilcmd.c:2482 parser/parse_utilcmd.c:2558 +#: parser/parse_utilcmd.c:2472 parser/parse_utilcmd.c:2479 +#: parser/parse_utilcmd.c:2486 parser/parse_utilcmd.c:2562 #, c-format msgid "Cannot create a primary key or unique constraint using such an index." msgstr "Ein Primärschlüssel oder Unique-Constraint kann nicht mit einem solchen Index erzeugt werden." -#: parser/parse_utilcmd.c:2474 +#: parser/parse_utilcmd.c:2478 #, c-format msgid "index \"%s\" contains expressions" msgstr "Index »%s« enthält Ausdrücke" -#: parser/parse_utilcmd.c:2481 +#: parser/parse_utilcmd.c:2485 #, c-format msgid "\"%s\" is a partial index" msgstr "»%s« ist ein partieller Index" -#: parser/parse_utilcmd.c:2493 +#: parser/parse_utilcmd.c:2497 #, c-format msgid "\"%s\" is a deferrable index" msgstr "»%s« ist ein aufschiebbarer Index" -#: parser/parse_utilcmd.c:2494 +#: parser/parse_utilcmd.c:2498 #, c-format msgid "Cannot create a non-deferrable constraint using a deferrable index." msgstr "Ein nicht aufschiebbarer Constraint kann nicht mit einem aufschiebbaren Index erzeugt werden." -#: parser/parse_utilcmd.c:2557 +#: parser/parse_utilcmd.c:2561 #, c-format msgid "index \"%s\" column number %d does not have default sorting behavior" msgstr "Index »%s« Spalte Nummer %d hat nicht das Standardsortierverhalten" -#: parser/parse_utilcmd.c:2749 +#: parser/parse_utilcmd.c:2753 #, c-format msgid "column \"%s\" appears twice in primary key constraint" msgstr "Spalte »%s« erscheint zweimal im Primärschlüssel-Constraint" -#: parser/parse_utilcmd.c:2755 +#: parser/parse_utilcmd.c:2759 #, c-format msgid "column \"%s\" appears twice in unique constraint" msgstr "Spalte »%s« erscheint zweimal im Unique-Constraint" -#: parser/parse_utilcmd.c:2805 +#: parser/parse_utilcmd.c:2809 #, c-format msgid "column \"%s\" in WITHOUT OVERLAPS is not a range or multirange type" msgstr "Spalte »%s« in WITHOUT OVERLAPS ist kein Range- oder Multirange-Typ" -#: parser/parse_utilcmd.c:2834 +#: parser/parse_utilcmd.c:2838 #, c-format msgid "constraint using WITHOUT OVERLAPS needs at least two columns" msgstr "Constraints, die WITHOUT OVERLAPS verwenden, benötigen mindestens zwei Spalten" -#: parser/parse_utilcmd.c:3132 +#: parser/parse_utilcmd.c:3136 #, c-format msgid "index expressions and predicates can refer only to the table being indexed" msgstr "Indexausdrücke und -prädikate können nur auf die zu indizierende Tabelle verweisen" -#: parser/parse_utilcmd.c:3204 +#: parser/parse_utilcmd.c:3208 #, c-format msgid "statistics expressions can refer only to the table being referenced" msgstr "Statistikausdrücke können nur auf die referenzierte Tabelle verweisen" -#: parser/parse_utilcmd.c:3247 +#: parser/parse_utilcmd.c:3251 #, c-format msgid "rules on materialized views are not supported" msgstr "Regeln für materialisierte Sichten werden nicht unterstützt" -#: parser/parse_utilcmd.c:3307 +#: parser/parse_utilcmd.c:3311 #, c-format msgid "rule WHERE condition cannot contain references to other relations" msgstr "WHERE-Bedingung einer Regel kann keine Verweise auf andere Relationen enthalten" -#: parser/parse_utilcmd.c:3379 +#: parser/parse_utilcmd.c:3383 #, c-format msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" msgstr "Regeln mit WHERE-Bedingungen können als Aktion nur SELECT, INSERT, UPDATE oder DELETE haben" -#: parser/parse_utilcmd.c:3397 parser/parse_utilcmd.c:3498 +#: parser/parse_utilcmd.c:3401 parser/parse_utilcmd.c:3502 #: rewrite/rewriteHandler.c:547 rewrite/rewriteManip.c:1199 #, c-format msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" msgstr "UNION/INTERSECTION/EXCEPT mit Bedingung sind nicht implementiert" -#: parser/parse_utilcmd.c:3415 +#: parser/parse_utilcmd.c:3419 #, c-format msgid "ON SELECT rule cannot use OLD" msgstr "ON-SELECT-Regel kann nicht OLD verwenden" -#: parser/parse_utilcmd.c:3419 +#: parser/parse_utilcmd.c:3423 #, c-format msgid "ON SELECT rule cannot use NEW" msgstr "ON-SELECT-Regel kann nicht NEW verwenden" -#: parser/parse_utilcmd.c:3428 +#: parser/parse_utilcmd.c:3432 #, c-format msgid "ON INSERT rule cannot use OLD" msgstr "ON-INSERT-Regel kann nicht OLD verwenden" -#: parser/parse_utilcmd.c:3434 +#: parser/parse_utilcmd.c:3438 #, c-format msgid "ON DELETE rule cannot use NEW" msgstr "ON-DELETE-Regel kann nicht NEW verwenden" -#: parser/parse_utilcmd.c:3462 +#: parser/parse_utilcmd.c:3466 #, c-format msgid "cannot refer to OLD within WITH query" msgstr "in WITH-Anfrage kann nicht auf OLD verweisen werden" -#: parser/parse_utilcmd.c:3469 +#: parser/parse_utilcmd.c:3473 #, c-format msgid "cannot refer to NEW within WITH query" msgstr "in WITH-Anfrage kann nicht auf NEW verwiesen werden" -#: parser/parse_utilcmd.c:3539 parser/parse_utilcmd.c:3548 -#: parser/parse_utilcmd.c:3557 +#: parser/parse_utilcmd.c:3543 parser/parse_utilcmd.c:3552 +#: parser/parse_utilcmd.c:3561 #, c-format -msgid "ALTER TABLE ... MERGE PARTITIONS can only merge partitions don't have sub-partitions." +msgid "ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions." msgstr "" -#: parser/parse_utilcmd.c:3540 parser/parse_utilcmd.c:3549 -#: parser/parse_utilcmd.c:3558 +#: parser/parse_utilcmd.c:3544 parser/parse_utilcmd.c:3553 +#: parser/parse_utilcmd.c:3562 #, c-format -msgid "ALTER TABLE ... SPLIT PARTITION can only split partitions don't have sub-partitions." +msgid "ALTER TABLE ... SPLIT PARTITION can only split partitions that don't have sub-partitions." msgstr "" -#: parser/parse_utilcmd.c:3545 +#: parser/parse_utilcmd.c:3549 #, fuzzy, c-format #| msgid "\"%s\" is not a hash partitioned table" msgid "\"%s\" is not a partition of partitioned table \"%s\"" msgstr "»%s« ist keine Hash-partitionierte Tabelle" -#: parser/parse_utilcmd.c:3621 -#, c-format -msgid "DEFAULT partition should be one" -msgstr "" +#: parser/parse_utilcmd.c:3625 +#, fuzzy, c-format +#| msgid "cannot insert a non-DEFAULT value into column \"%s\"" +msgid "cannot specify more than one DEFAULT partition" +msgstr "kann keinen Wert außer DEFAULT in Spalte »%s« einfügen" -#: parser/parse_utilcmd.c:3633 +#: parser/parse_utilcmd.c:3637 #, fuzzy, c-format #| msgid "partitioned tables cannot be unlogged" msgid "partition of hash-partitioned table cannot be split" msgstr "partitionierte Tabellen können nicht ungeloggt sein" -#: parser/parse_utilcmd.c:3648 +#: parser/parse_utilcmd.c:3652 #, fuzzy, c-format #| msgid "cannot detach partition \"%s\"" -msgid "can not split DEFAULT partition \"%s\"" +msgid "cannot split DEFAULT partition \"%s\"" msgstr "Partition »%s« kann nicht abgetrennt werden" -#: parser/parse_utilcmd.c:3650 +#: parser/parse_utilcmd.c:3654 #, c-format -msgid "To split DEFAULT partition one of the new partition must be DEFAULT." +msgid "To split a DEFAULT partition, one of the new partitions must be DEFAULT." msgstr "" -#: parser/parse_utilcmd.c:3665 +#: parser/parse_utilcmd.c:3668 #, fuzzy, c-format #| msgid "cannot insert a non-DEFAULT value into column \"%s\"" -msgid "can not split non-DEFAULT partition \"%s\"" +msgid "cannot split non-DEFAULT partition \"%s\"" msgstr "kann keinen Wert außer DEFAULT in Spalte »%s« einfügen" -#: parser/parse_utilcmd.c:3667 -#, c-format -msgid "new partition cannot be DEFAULT because DEFAULT partition \"%s\" already exists" -msgstr "" +#: parser/parse_utilcmd.c:3670 +#, fuzzy, c-format +#| msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgid "New partition cannot be DEFAULT because DEFAULT partition \"%s\" already exists." +msgstr "Partition »%s« kollidiert mit bestehender Standardpartition »%s«" -#: parser/parse_utilcmd.c:3690 parser/parse_utilcmd.c:3698 -#: parser/parse_utilcmd.c:3751 parser/parse_utilcmd.c:3780 +#: parser/parse_utilcmd.c:3693 parser/parse_utilcmd.c:3701 +#: parser/parse_utilcmd.c:3754 parser/parse_utilcmd.c:3783 #, fuzzy, c-format #| msgid "transaction identifier \"%s\" is already in use" msgid "partition with name \"%s\" is already used" msgstr "Transaktionsbezeichner »%s« wird bereits verwendet" -#: parser/parse_utilcmd.c:3734 +#: parser/parse_utilcmd.c:3737 #, fuzzy, c-format #| msgid "partitioned tables cannot be unlogged" msgid "partition of hash-partitioned table cannot be merged" msgstr "partitionierte Tabellen können nicht ungeloggt sein" -#: parser/parse_utilcmd.c:4087 +#: parser/parse_utilcmd.c:4090 #, fuzzy, c-format #| msgid "unique constraint on partitioned table must include all partitioning columns" msgid "list of partitions to be merged should include at least two partitions" msgstr "Unique-Constraint für partitionierte Tabelle muss alle Partitionierungsspalten enthalten" -#: parser/parse_utilcmd.c:4101 +#: parser/parse_utilcmd.c:4104 #, c-format msgid "list of new partitions should contain at least two partitions" msgstr "" -#: parser/parse_utilcmd.c:4240 +#: parser/parse_utilcmd.c:4243 #, c-format msgid "misplaced DEFERRABLE clause" msgstr "falsch platzierte DEFERRABLE-Klausel" -#: parser/parse_utilcmd.c:4245 parser/parse_utilcmd.c:4260 +#: parser/parse_utilcmd.c:4248 parser/parse_utilcmd.c:4263 #, c-format msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" msgstr "mehrere DEFERRABLE/NOT DEFERRABLE-Klauseln sind nicht erlaubt" -#: parser/parse_utilcmd.c:4255 +#: parser/parse_utilcmd.c:4258 #, c-format msgid "misplaced NOT DEFERRABLE clause" msgstr "falsch platzierte NOT DEFERRABLE-Klausel" -#: parser/parse_utilcmd.c:4276 +#: parser/parse_utilcmd.c:4279 #, c-format msgid "misplaced INITIALLY DEFERRED clause" msgstr "falsch platzierte INITIALLY DEFERRED-Klausel" -#: parser/parse_utilcmd.c:4281 parser/parse_utilcmd.c:4307 +#: parser/parse_utilcmd.c:4284 parser/parse_utilcmd.c:4310 #, c-format msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" msgstr "mehrere INITIALLY IMMEDIATE/DEFERRED-Klauseln sind nicht erlaubt" -#: parser/parse_utilcmd.c:4302 +#: parser/parse_utilcmd.c:4305 #, c-format msgid "misplaced INITIALLY IMMEDIATE clause" msgstr "falsch platzierte INITIALLY IMMEDIATE-Klausel" -#: parser/parse_utilcmd.c:4319 +#: parser/parse_utilcmd.c:4322 #, c-format msgid "misplaced ENFORCED clause" msgstr "falsch platzierte ENFORCED-Klausel" -#: parser/parse_utilcmd.c:4324 parser/parse_utilcmd.c:4341 +#: parser/parse_utilcmd.c:4327 parser/parse_utilcmd.c:4344 #, c-format msgid "multiple ENFORCED/NOT ENFORCED clauses not allowed" msgstr "mehrere ENFORCED/NOT ENFORCED-Klauseln sind nicht erlaubt" -#: parser/parse_utilcmd.c:4336 +#: parser/parse_utilcmd.c:4339 #, c-format msgid "misplaced NOT ENFORCED clause" msgstr "falsch platzierte NOT ENFORCED-Klausel" -#: parser/parse_utilcmd.c:4585 parser/parse_utilcmd.c:4619 +#: parser/parse_utilcmd.c:4588 parser/parse_utilcmd.c:4622 #, c-format msgid "CREATE specifies a schema (%s) different from the one being created (%s)" msgstr "CREATE gibt ein Schema an (%s) welches nicht gleich dem zu erzeugenden Schema ist (%s)" -#: parser/parse_utilcmd.c:4809 +#: parser/parse_utilcmd.c:4812 #, c-format msgid "\"%s\" is not a partitioned table" msgstr "»%s« ist keine partitionierte Tabelle" -#: parser/parse_utilcmd.c:4816 +#: parser/parse_utilcmd.c:4819 #, c-format msgid "table \"%s\" is not partitioned" msgstr "Tabelle »%s« ist nicht partitioniert" -#: parser/parse_utilcmd.c:4823 +#: parser/parse_utilcmd.c:4826 #, c-format msgid "index \"%s\" is not partitioned" msgstr "Index »%s« ist nicht partitioniert" -#: parser/parse_utilcmd.c:4863 +#: parser/parse_utilcmd.c:4866 #, c-format msgid "a hash-partitioned table may not have a default partition" msgstr "eine hashpartitionierte Tabelle kann keine Standardpartition haben" -#: parser/parse_utilcmd.c:4880 +#: parser/parse_utilcmd.c:4883 #, c-format msgid "invalid bound specification for a hash partition" msgstr "ungültige Begrenzungsangabe für eine Hash-Partition" -#: parser/parse_utilcmd.c:4886 partitioning/partbounds.c:4795 +#: parser/parse_utilcmd.c:4889 partitioning/partbounds.c:4795 #, c-format msgid "modulus for hash partition must be an integer value greater than zero" msgstr "Modulus für Hashpartition muss eine ganze Zahl größer als null sein" -#: parser/parse_utilcmd.c:4893 partitioning/partbounds.c:4803 +#: parser/parse_utilcmd.c:4896 partitioning/partbounds.c:4803 #, c-format msgid "remainder for hash partition must be less than modulus" msgstr "Rest für Hashpartition muss kleiner als Modulus sein" -#: parser/parse_utilcmd.c:4906 +#: parser/parse_utilcmd.c:4909 #, c-format msgid "invalid bound specification for a list partition" msgstr "ungültige Begrenzungsangabe für eine Listenpartition" -#: parser/parse_utilcmd.c:4959 +#: parser/parse_utilcmd.c:4962 #, c-format msgid "invalid bound specification for a range partition" msgstr "ungültige Begrenzungsangabe für eine Bereichspartition" -#: parser/parse_utilcmd.c:4965 +#: parser/parse_utilcmd.c:4968 #, c-format msgid "FROM must specify exactly one value per partitioning column" msgstr "FROM muss genau einen Wert pro Partitionierungsspalte angeben" -#: parser/parse_utilcmd.c:4969 +#: parser/parse_utilcmd.c:4972 #, c-format msgid "TO must specify exactly one value per partitioning column" msgstr "TO muss genau einen Wert pro Partitionierungsspalte angeben" -#: parser/parse_utilcmd.c:5085 +#: parser/parse_utilcmd.c:5088 #, c-format msgid "cannot specify NULL in range bound" msgstr "NULL kann nicht in der Bereichsgrenze angegeben werden" -#: parser/parse_utilcmd.c:5133 +#: parser/parse_utilcmd.c:5136 #, c-format msgid "every bound following MAXVALUE must also be MAXVALUE" msgstr "jede Begrenzung, die auf MAXVALUE folgt, muss auch MAXVALUE sein" -#: parser/parse_utilcmd.c:5140 +#: parser/parse_utilcmd.c:5143 #, c-format msgid "every bound following MINVALUE must also be MINVALUE" msgstr "jede Begrenzung, die auf MINVALUE folgt, muss auch MINVALUE sein" -#: parser/parse_utilcmd.c:5183 +#: parser/parse_utilcmd.c:5186 #, c-format msgid "specified value cannot be cast to type %s for column \"%s\"" msgstr "angegebener Wert kann nicht in Typ %s für Spalte »%s« umgewandelt werden" @@ -24646,7 +24754,7 @@ msgstr "ungültiges Unicode-Escape-Zeichen" msgid "invalid Unicode escape value" msgstr "ungültiger Unicode-Escape-Wert" -#: parser/parser.c:494 scan.l:682 utils/adt/varlena.c:5784 +#: parser/parser.c:494 scan.l:682 utils/adt/varlena.c:5787 #, c-format msgid "invalid Unicode escape" msgstr "ungültiges Unicode-Escape" @@ -24657,7 +24765,7 @@ msgid "Unicode escapes must be \\XXXX or \\+XXXXXX." msgstr "Unicode-Escapes müssen \\XXXX oder \\+XXXXXX sein." #: parser/parser.c:523 scan.l:643 scan.l:659 scan.l:675 -#: utils/adt/varlena.c:5809 +#: utils/adt/varlena.c:5812 #, c-format msgid "invalid Unicode surrogate pair" msgstr "ungültiges Unicode-Surrogatpaar" @@ -24688,12 +24796,12 @@ msgstr "Der neue Modulus %d ist kein Faktor von %d, dem Modulus der bestehenden msgid "The new modulus %d is not divisible by %d, the modulus of existing partition \"%s\"." msgstr "Der neue Modulus %d ist nicht durch %d, den Modulus der bestehenden Parition »%s«, teilbar." -#: partitioning/partbounds.c:3120 partitioning/partbounds.c:5363 +#: partitioning/partbounds.c:3120 partitioning/partbounds.c:5375 #, c-format msgid "empty range bound specified for partition \"%s\"" msgstr "leere Bereichsgrenze angegeben für Partition »%s«" -#: partitioning/partbounds.c:3122 partitioning/partbounds.c:5365 +#: partitioning/partbounds.c:3122 partitioning/partbounds.c:5377 #, c-format msgid "Specified lower bound %s is greater than or equal to upper bound %s." msgstr "Angegebene Untergrenze %s ist größer als oder gleich der Obergrenze %s." @@ -24718,7 +24826,7 @@ msgstr "Rest für Hashpartition muss eine ganze Zahl größer als oder gleich nu msgid "\"%s\" is not a hash partitioned table" msgstr "»%s« ist keine Hash-partitionierte Tabelle" -#: partitioning/partbounds.c:4834 partitioning/partbounds.c:4951 +#: partitioning/partbounds.c:4834 partitioning/partbounds.c:4963 #, c-format msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" msgstr "Anzahl der Partitionierungsspalten (%d) stimmt nicht mit der Anzahl der angegebenen Partitionierungsschlüssel (%d) überein" @@ -24728,97 +24836,121 @@ msgstr "Anzahl der Partitionierungsspalten (%d) stimmt nicht mit der Anzahl der msgid "column %d of the partition key has type %s, but supplied value is of type %s" msgstr "Spalte %d des Partitionierungsschlüssels hat Typ %s, aber der angegebene Wert hat Typ %s" -#: partitioning/partbounds.c:4888 +#: partitioning/partbounds.c:4894 #, c-format msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" msgstr "Spalte %d des Partitionierungsschlüssels hat Typ »%s«, aber der angegebene Wert hat Typ »%s«" -#: partitioning/partbounds.c:5033 +#: partitioning/partbounds.c:5045 #, fuzzy, c-format #| msgid "partition \"%s\" would overlap partition \"%s\"" -msgid "can not merge partition \"%s\" together with partition \"%s\"" +msgid "cannot merge partition \"%s\" together with partition \"%s\"" msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" -#: partitioning/partbounds.c:5035 partitioning/partbounds.c:5044 +#: partitioning/partbounds.c:5047 partitioning/partbounds.c:5056 #, fuzzy, c-format #| msgid "relation \"%s\" is not a partition of relation \"%s\"" -msgid "lower bound of partition \"%s\" is not equal to the upper bound of partition \"%s\"" +msgid "The lower bound of partition \"%s\" is not equal to the upper bound of partition \"%s\"." msgstr "Relation »%s« ist keine Partition von Relation »%s«" -#: partitioning/partbounds.c:5037 +#: partitioning/partbounds.c:5049 #, c-format msgid "ALTER TABLE ... MERGE PARTITIONS requires the partition bounds to be adjacent." msgstr "" -#: partitioning/partbounds.c:5042 +#: partitioning/partbounds.c:5054 #, fuzzy, c-format #| msgid "cannot set options for relation \"%s\"" -msgid "can not split to partition \"%s\" together with partition \"%s\"" +msgid "cannot split to partition \"%s\" together with partition \"%s\"" msgstr "für Relation »%s« können keine Optionen gesetzt werden" -#: partitioning/partbounds.c:5046 +#: partitioning/partbounds.c:5058 #, c-format msgid "ALTER TABLE ... SPLIT PARTITION requires the partition bounds to be adjacent." msgstr "" -#: partitioning/partbounds.c:5291 +#: partitioning/partbounds.c:5303 #, fuzzy, c-format #| msgid "partition \"%s\" would overlap partition \"%s\"" msgid "new partition \"%s\" would overlap with another new partition \"%s\"" msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" -#: partitioning/partbounds.c:5405 +#: partitioning/partbounds.c:5417 #, fuzzy, c-format #| msgid "partition \"%s\" would overlap partition \"%s\"" msgid "lower bound of partition \"%s\" is not equal to lower bound of split partition \"%s\"" msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" -#: partitioning/partbounds.c:5408 partitioning/partbounds.c:5418 -#: partitioning/partbounds.c:5450 partitioning/partbounds.c:5460 -#: partitioning/partbounds.c:5656 partitioning/partbounds.c:5699 -#, c-format -msgid "%s require combined bounds of new partitions must exactly match the bound of the split partition." -msgstr "" +#: partitioning/partbounds.c:5420 partitioning/partbounds.c:5462 +#: partitioning/partbounds.c:5667 partitioning/partbounds.c:5710 +#, fuzzy, c-format +#| msgid "partition \"%s\" would overlap partition \"%s\"" +msgid "%s requires the combined bounds of the new partitions to exactly match the bound of the split partition." +msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" -#: partitioning/partbounds.c:5415 +#: partitioning/partbounds.c:5427 #, fuzzy, c-format #| msgid "partition \"%s\" would overlap partition \"%s\"" msgid "lower bound of partition \"%s\" is less than lower bound of split partition \"%s\"" msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" -#: partitioning/partbounds.c:5447 +#: partitioning/partbounds.c:5430 partitioning/partbounds.c:5472 +#, c-format +msgid "Explicit partition bounds must be contained within the bounds of the split partition when a DEFAULT partition is specified." +msgstr "" + +#: partitioning/partbounds.c:5459 #, fuzzy, c-format #| msgid "relation \"%s\" is not a partition of relation \"%s\"" msgid "upper bound of partition \"%s\" is not equal to upper bound of split partition \"%s\"" msgstr "Relation »%s« ist keine Partition von Relation »%s«" -#: partitioning/partbounds.c:5457 +#: partitioning/partbounds.c:5469 #, c-format msgid "upper bound of partition \"%s\" is greater than upper bound of split partition \"%s\"" msgstr "" -#: partitioning/partbounds.c:5528 +#: partitioning/partbounds.c:5539 #, fuzzy, c-format #| msgid "partition \"%s\" conflicts with existing default partition \"%s\"" -msgid "new partition \"%s\" cannot have this value because split partition \"%s\" does not have" +msgid "new partition \"%s\" cannot have this value because split partition \"%s\" does not have it" msgstr "Partition »%s« kollidiert mit bestehender Standardpartition »%s«" -#: partitioning/partbounds.c:5545 -#, c-format -msgid "new partition \"%s\" cannot have NULL value because split partition \"%s\" does not have" -msgstr "" - #: partitioning/partbounds.c:5556 #, fuzzy, c-format +#| msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgid "new partition \"%s\" cannot have NULL value because split partition \"%s\" does not have it" +msgstr "Partition »%s« kollidiert mit bestehender Standardpartition »%s«" + +#: partitioning/partbounds.c:5567 +#, fuzzy, c-format #| msgid "partition \"%s\" would overlap partition \"%s\"" msgid "new partition \"%s\" would overlap with another (not split) partition \"%s\"" msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" -#: partitioning/partbounds.c:5653 partitioning/partbounds.c:5696 +#: partitioning/partbounds.c:5664 partitioning/partbounds.c:5707 +#, fuzzy, c-format +#| msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgid "new partitions' combined partition bounds do not contain value (%s) but split partition \"%s\" does" +msgstr "Partition »%s« kollidiert mit bestehender Standardpartition »%s«" + +#: partitioning/partbounds.c:5848 +#, fuzzy, c-format +#| msgid "cannot set options for relation \"%s\"" +msgid "cannot split partition \"%s\" only to add a DEFAULT partition" +msgstr "für Relation »%s« können keine Optionen gesetzt werden" + +#: partitioning/partbounds.c:5850 #, c-format -msgid "new partitions combined partition bounds do not contain value (%s) but split partition \"%s\" does" +msgid "The non-DEFAULT partition would keep the same partition bound." msgstr "" +#: partitioning/partbounds.c:5851 +#, fuzzy, c-format +#| msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation." +msgid "Use CREATE TABLE ... PARTITION OF ... DEFAULT to add a DEFAULT partition." +msgstr "Verwendet Sie ALTER TABLE ... DETACH PARTITION ... FINALIZE, um die unerledigte Abtrennoperation abzuschließen." + #: port/pg_sema.c:211 port/pg_shmem.c:719 port/posix_sema.c:211 #: port/sysv_sema.c:347 port/sysv_shmem.c:719 #, c-format @@ -25066,22 +25198,22 @@ msgstr "automatisches Analysieren der Tabelle »%s.%s.%s«" msgid "processing work entry for relation \"%s.%s.%s\"" msgstr "verarbeite Arbeitseintrag für Relation »%s.%s.%s«" -#: postmaster/autovacuum.c:3519 +#: postmaster/autovacuum.c:3524 #, c-format msgid "autovacuum not started because of misconfiguration" msgstr "Autovacuum wegen Fehlkonfiguration nicht gestartet" -#: postmaster/autovacuum.c:3520 +#: postmaster/autovacuum.c:3525 #, c-format msgid "Enable the \"track_counts\" option." msgstr "Schalten Sie die Option »track_counts« ein." -#: postmaster/autovacuum.c:3630 +#: postmaster/autovacuum.c:3635 #, c-format msgid "\"autovacuum_max_workers\" (%d) should be less than or equal to \"autovacuum_worker_slots\" (%d)" msgstr "»autovacuum_max_workers« (%d) sollte kleiner oder gleich »autovacuum_worker_slots« (%d) sein" -#: postmaster/autovacuum.c:3632 +#: postmaster/autovacuum.c:3637 #, c-format msgid "The server will only start up to \"autovacuum_worker_slots\" (%d) autovacuum workers at a given time." msgstr "Der Server wird nur bis zu »autovacuum_worker_slots« (%d) Autovacuum-Arbeitsprozesse gleichzeitig starten." @@ -25182,153 +25314,159 @@ msgstr "Checkpoint-Anforderung fehlgeschlagen" msgid "Consult recent messages in the server log for details." msgstr "Einzelheiten finden Sie in den letzten Meldungen im Serverlog." -#: postmaster/datachecksum_state.c:475 +#: postmaster/datachecksum_state.c:531 #, fuzzy, c-format #| msgid "incorrect checksum in control file" msgid "incorrect data checksum state %i for target state %i" msgstr "falsche Prüfsumme in Kontrolldatei" -#: postmaster/datachecksum_state.c:493 postmaster/datachecksum_state.c:513 +#: postmaster/datachecksum_state.c:551 postmaster/datachecksum_state.c:573 #, fuzzy, c-format #| msgid "must be superuser to create a base type" msgid "must be superuser to change data checksum state" msgstr "nur Superuser können Basistypen anlegen" -#: postmaster/datachecksum_state.c:518 +#: postmaster/datachecksum_state.c:578 #, fuzzy, c-format #| msgid "requested length cannot be negative" msgid "cost delay cannot be a negative value" msgstr "verlangte Länge darf nicht negativ sein" -#: postmaster/datachecksum_state.c:523 +#: postmaster/datachecksum_state.c:583 #, fuzzy, c-format #| msgid "count must be greater than zero" msgid "cost limit must be greater than zero" msgstr "Anzahl muss größer als null sein" -#: postmaster/datachecksum_state.c:611 +#: postmaster/datachecksum_state.c:651 +#, fuzzy, c-format +#| msgid "data checksums are already disabled in cluster" +msgid "data checksums already in desired state, exiting" +msgstr "Datenprüfsummen sind im Cluster bereits ausgeschaltet" + +#: postmaster/datachecksum_state.c:672 #, fuzzy, c-format #| msgid "could not fork background worker process: %m" msgid "failed to start background worker to process data checksums" msgstr "konnte Background-Worker-Prozess nicht starten (fork-Fehler): %m" -#: postmaster/datachecksum_state.c:617 +#: postmaster/datachecksum_state.c:677 #, fuzzy, c-format #| msgid "data checksums are already enabled in cluster" msgid "data checksum processing already running" msgstr "Datenprüfsummen sind im Cluster bereits eingeschaltet" -#: postmaster/datachecksum_state.c:791 postmaster/datachecksum_state.c:814 +#: postmaster/datachecksum_state.c:871 postmaster/datachecksum_state.c:895 #, fuzzy, c-format #| msgid "could not fork background worker process: %m" msgid "could not start background worker for enabling data checksums in database \"%s\"" msgstr "konnte Background-Worker-Prozess nicht starten (fork-Fehler): %m" -#: postmaster/datachecksum_state.c:793 +#: postmaster/datachecksum_state.c:873 #, c-format msgid "The \"%s\" setting might be too low." msgstr "" -#: postmaster/datachecksum_state.c:816 +#: postmaster/datachecksum_state.c:897 #, fuzzy, c-format #| msgid "More details may be available in the server log." msgid "More details on the error might be found in the server log." msgstr "Weitere Einzelheiten sind möglicherweise im Serverlog zu finden." -#: postmaster/datachecksum_state.c:839 +#: postmaster/datachecksum_state.c:919 #, c-format msgid "cannot enable data checksums without the postmaster process" msgstr "" -#: postmaster/datachecksum_state.c:840 postmaster/datachecksum_state.c:862 +#: postmaster/datachecksum_state.c:920 postmaster/datachecksum_state.c:943 #, c-format msgid "Restart the database and restart data checksum processing by calling pg_enable_data_checksums()." msgstr "" -#: postmaster/datachecksum_state.c:844 +#: postmaster/datachecksum_state.c:924 #, fuzzy, c-format #| msgid "%s: processing database \"%s\": %s\n" msgid "initiating data checksum processing in database \"%s\"" msgstr "%s: bearbeite Datenbank »%s«: %s\n" -#: postmaster/datachecksum_state.c:860 +#: postmaster/datachecksum_state.c:941 #, fuzzy, c-format #| msgid "postmaster exited during a parallel transaction" msgid "postmaster exited during data checksum processing in \"%s\"" msgstr "Postmaster beendete während einer parallelen Transaktion" -#: postmaster/datachecksum_state.c:866 +#: postmaster/datachecksum_state.c:953 #, fuzzy, c-format #| msgid "checksums enabled in file \"%s\"" msgid "data checksums processing was aborted in database \"%s\"" msgstr "Prüfsummen wurden eingeschaltet in Datei »%s«" -#: postmaster/datachecksum_state.c:896 +#: postmaster/datachecksum_state.c:980 #, c-format msgid "data checksums launcher exiting while worker is still running, signalling worker" msgstr "" -#: postmaster/datachecksum_state.c:987 +#: postmaster/datachecksum_state.c:1070 #, fuzzy, c-format #| msgid "postmaster exited during a parallel transaction" msgid "postmaster exited during data checksums processing" msgstr "Postmaster beendete während einer parallelen Transaktion" -#: postmaster/datachecksum_state.c:988 +#: postmaster/datachecksum_state.c:1071 #, c-format msgid "Data checksums processing must be restarted manually after cluster restart." msgstr "" -#: postmaster/datachecksum_state.c:1018 +#: postmaster/datachecksum_state.c:1097 #, c-format msgid "background worker \"datachecksums launcher\" started" msgstr "" -#: postmaster/datachecksum_state.c:1037 +#: postmaster/datachecksum_state.c:1116 #, c-format msgid "background worker \"datachecksums launcher\" already running, exiting" msgstr "" -#: postmaster/datachecksum_state.c:1076 +#: postmaster/datachecksum_state.c:1156 #, c-format msgid "enabling data checksums requested, starting data checksum calculation" msgstr "" -#: postmaster/datachecksum_state.c:1104 +#: postmaster/datachecksum_state.c:1180 #, fuzzy, c-format #| msgid " -e, --enable enable data checksums\n" msgid "unable to enable data checksums in cluster" msgstr " -e, --enable Datenprüfsummen einschalten\n" -#: postmaster/datachecksum_state.c:1114 +#: postmaster/datachecksum_state.c:1190 #, fuzzy, c-format #| msgid "data checksums are not enabled in cluster" msgid "data checksums are now enabled" msgstr "Datenprüfsummen sind im Cluster nicht eingeschaltet" -#: postmaster/datachecksum_state.c:1119 +#: postmaster/datachecksum_state.c:1195 #, c-format msgid "disabling data checksums requested" msgstr "" -#: postmaster/datachecksum_state.c:1125 +#: postmaster/datachecksum_state.c:1201 #, fuzzy, c-format #| msgid "Data page checksums are disabled.\n" msgid "data checksums are now disabled" msgstr "Datenseitenprüfsummen sind ausgeschaltet.\n" -#: postmaster/datachecksum_state.c:1241 +#: postmaster/datachecksum_state.c:1319 #, fuzzy, c-format #| msgid "data checksums are not enabled in cluster" msgid "data checksums failed to get enabled in all databases, aborting" msgstr "Datenprüfsummen sind im Cluster nicht eingeschaltet" -#: postmaster/datachecksum_state.c:1242 +#: postmaster/datachecksum_state.c:1320 #, c-format msgid "The server log might have more information on the cause of the error." msgstr "" -#: postmaster/datachecksum_state.c:1549 postmaster/datachecksum_state.c:1622 +#: postmaster/datachecksum_state.c:1701 postmaster/datachecksum_state.c:1774 #, fuzzy, c-format #| msgid "data checksums are not enabled in cluster" msgid "data checksum processing aborted in database OID %u" @@ -25576,7 +25714,7 @@ msgid "%s: could not write external PID file \"%s\": %m\n" msgstr "%s: konnte externe PID-Datei »%s« nicht schreiben: %m\n" #. translator: %s is a configuration file -#: postmaster/postmaster.c:1351 utils/init/postinit.c:234 +#: postmaster/postmaster.c:1351 utils/init/postinit.c:240 #, c-format msgid "could not load %s" msgstr "konnte %s nicht laden" @@ -25836,52 +25974,52 @@ msgstr "konnte Exitcode des Prozesses nicht lesen\n" msgid "could not post child completion status\n" msgstr "konnte Child-Completion-Status nicht versenden\n" -#: postmaster/syslogger.c:527 postmaster/syslogger.c:1172 +#: postmaster/syslogger.c:546 postmaster/syslogger.c:1191 #, c-format msgid "could not read from logger pipe: %m" msgstr "konnte nicht aus Logger-Pipe lesen: %m" -#: postmaster/syslogger.c:626 postmaster/syslogger.c:640 +#: postmaster/syslogger.c:645 postmaster/syslogger.c:659 #, c-format msgid "could not create pipe for syslog: %m" msgstr "konnte Pipe für Syslog nicht erzeugen: %m" -#: postmaster/syslogger.c:711 +#: postmaster/syslogger.c:730 #, c-format msgid "could not fork system logger: %m" msgstr "konnte Systemlogger nicht starten (fork-Fehler): %m" -#: postmaster/syslogger.c:730 +#: postmaster/syslogger.c:749 #, c-format msgid "redirecting log output to logging collector process" msgstr "Logausgabe wird an Logsammelprozess umgeleitet" -#: postmaster/syslogger.c:731 +#: postmaster/syslogger.c:750 #, c-format msgid "Future log output will appear in directory \"%s\"." msgstr "Die weitere Logausgabe wird im Verzeichnis »%s« erscheinen." -#: postmaster/syslogger.c:739 +#: postmaster/syslogger.c:758 #, c-format msgid "could not redirect stdout: %m" msgstr "konnte Standardausgabe nicht umleiten: %m" -#: postmaster/syslogger.c:744 postmaster/syslogger.c:761 +#: postmaster/syslogger.c:763 postmaster/syslogger.c:780 #, c-format msgid "could not redirect stderr: %m" msgstr "konnte Standardfehlerausgabe nicht umleiten: %m" -#: postmaster/syslogger.c:1127 +#: postmaster/syslogger.c:1146 #, c-format msgid "could not write to log file: %m\n" msgstr "konnte nicht in Logdatei schreiben: %m\n" -#: postmaster/syslogger.c:1247 +#: postmaster/syslogger.c:1266 #, c-format msgid "could not open log file \"%s\": %m" msgstr "konnte Logdatei »%s« nicht öffnen: %m" -#: postmaster/syslogger.c:1337 +#: postmaster/syslogger.c:1356 #, c-format msgid "disabling automatic rotation (use SIGHUP to re-enable)" msgstr "automatische Rotation abgeschaltet (SIGHUP zum Wiederanschalten verwenden)" @@ -25922,12 +26060,6 @@ msgstr "konnte keinen gültigen Datensatz nach %X/%08X finden: %s" msgid "could not find a valid record after %X/%08X" msgstr "konnte keinen gültigen Datensatz nach %X/%08X finden" -#: postmaster/walsummarizer.c:1051 -#, fuzzy, c-format -#| msgid "could not read WAL from timeline %u at %X/%X: %s" -msgid "could not read WAL from timeline %u at %X/%08X: %s" -msgstr "konnte WAL aus Zeitleiste %u bei %X/%X nicht lesen: %s" - #: postmaster/walsummarizer.c:1057 #, fuzzy, c-format #| msgid "could not read WAL from timeline %u at %X/%X" @@ -25953,18 +26085,18 @@ msgstr "ungültige Zeitleiste %u" msgid "invalid streaming start location" msgstr "ungültige Streaming-Startposition" -#: replication/libpqwalreceiver/libpqwalreceiver.c:243 +#: replication/libpqwalreceiver/libpqwalreceiver.c:246 #: replication/libpqwalreceiver/libpqwalreceiver.c:338 #, c-format msgid "password is required" msgstr "Passwort wird benötigt" -#: replication/libpqwalreceiver/libpqwalreceiver.c:244 +#: replication/libpqwalreceiver/libpqwalreceiver.c:247 #, c-format msgid "Non-superuser cannot connect if the server does not request a password." msgstr "Nicht-Superuser kann nicht verbinden, wenn der Server kein Passwort anfordert." -#: replication/libpqwalreceiver/libpqwalreceiver.c:245 +#: replication/libpqwalreceiver/libpqwalreceiver.c:248 #, c-format msgid "Target server's authentication method must be changed, or set password_required=false in the subscription parameters." msgstr "Die Authentifizierungsmethode des Zielservers muss geändern werden oder setzen Sie password_required=false in den Subskriptionsparametern." @@ -25996,7 +26128,7 @@ msgid "could not receive database system identifier and timeline ID from the pri msgstr "konnte Datenbanksystemidentifikator und Zeitleisten-ID nicht vom Primärserver empfangen: %s" #: replication/libpqwalreceiver/libpqwalreceiver.c:450 -#: replication/libpqwalreceiver/libpqwalreceiver.c:745 +#: replication/libpqwalreceiver/libpqwalreceiver.c:764 #, c-format msgid "invalid response from primary server" msgstr "ungültige Antwort vom Primärserver" @@ -26006,91 +26138,89 @@ msgstr "ungültige Antwort vom Primärserver" msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." msgstr "Konnte System nicht identifizieren: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet." -#: replication/libpqwalreceiver/libpqwalreceiver.c:591 -#: replication/libpqwalreceiver/libpqwalreceiver.c:598 -#: replication/libpqwalreceiver/libpqwalreceiver.c:628 +#: replication/libpqwalreceiver/libpqwalreceiver.c:647 #, c-format msgid "could not start WAL streaming: %s" msgstr "konnte WAL-Streaming nicht starten: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:651 +#: replication/libpqwalreceiver/libpqwalreceiver.c:670 #, c-format msgid "could not send end-of-streaming message to primary: %s" msgstr "konnte End-of-Streaming-Nachricht nicht an Primärserver senden: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:675 +#: replication/libpqwalreceiver/libpqwalreceiver.c:694 #, c-format msgid "unexpected result set after end-of-streaming" msgstr "unerwartete Ergebnismenge nach End-of-Streaming" -#: replication/libpqwalreceiver/libpqwalreceiver.c:691 +#: replication/libpqwalreceiver/libpqwalreceiver.c:710 #, c-format msgid "error while shutting down streaming COPY: %s" msgstr "Fehler beim Beenden des COPY-Datenstroms: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:702 +#: replication/libpqwalreceiver/libpqwalreceiver.c:721 #, c-format msgid "error reading result of streaming command: %s" msgstr "Fehler beim Lesen des Ergebnisses von Streaming-Befehl: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:712 -#: replication/libpqwalreceiver/libpqwalreceiver.c:839 +#: replication/libpqwalreceiver/libpqwalreceiver.c:731 +#: replication/libpqwalreceiver/libpqwalreceiver.c:858 #, c-format msgid "unexpected result after CommandComplete: %s" msgstr "unerwartetes Ergebnis nach CommandComplete: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:739 +#: replication/libpqwalreceiver/libpqwalreceiver.c:758 #, c-format msgid "could not receive timeline history file from the primary server: %s" msgstr "konnte Zeitleisten-History-Datei nicht vom Primärserver empfangen: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:746 +#: replication/libpqwalreceiver/libpqwalreceiver.c:765 #, c-format msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." msgstr "1 Tupel mit 2 Feldern erwartet, %d Tupel mit %d Feldern erhalten." -#: replication/libpqwalreceiver/libpqwalreceiver.c:800 -#: replication/libpqwalreceiver/libpqwalreceiver.c:853 -#: replication/libpqwalreceiver/libpqwalreceiver.c:859 +#: replication/libpqwalreceiver/libpqwalreceiver.c:819 +#: replication/libpqwalreceiver/libpqwalreceiver.c:872 +#: replication/libpqwalreceiver/libpqwalreceiver.c:878 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "konnte keine Daten vom WAL-Stream empfangen: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:879 +#: replication/libpqwalreceiver/libpqwalreceiver.c:898 #, c-format msgid "could not send data to WAL stream: %s" msgstr "konnte keine Daten an den WAL-Stream senden: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:980 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1000 #, c-format msgid "could not create replication slot \"%s\": %s" msgstr "konnte Replikations-Slot »%s« nicht erzeugen: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1031 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1052 #, c-format msgid "could not alter replication slot \"%s\": %s" msgstr "konnte Replikations-Slot »%s« nicht ändern: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1065 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1086 #, c-format msgid "invalid query response" msgstr "ungültige Antwort auf Anfrage" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1066 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1087 #, c-format msgid "Expected %d fields, got %d fields." msgstr "%d Felder erwartet, %d Feldern erhalten." -#: replication/libpqwalreceiver/libpqwalreceiver.c:1137 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1158 #, c-format msgid "the query interface requires a database connection" msgstr "Ausführen von Anfragen benötigt eine Datenbankverbindung" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1171 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1192 msgid "empty query" msgstr "leere Anfrage" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1177 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1198 msgid "unexpected pipeline mode" msgstr "unerwarteter Pipeline-Modus" @@ -26135,146 +26265,219 @@ msgstr "Apply-Worker für logische Replikation wird die restlichen Änderungen d msgid "conflict detected on relation \"%s.%s\": conflict=%s" msgstr "Konflikt entdeckt für Relation »%s.%s«: Konflikt=%s" -#. translator: The colon is used as a separator in conflict -#. messages. The first part, built in the caller, describes what -#. happened locally; the second part lists the conflicting keys -#. and tuple data. -#. -#: replication/logical/conflict.c:220 -msgid ": " -msgstr "" - -#. translator: This is the terminator of a conflict message -#. translator: This is the terminator of a list of entity -#. names. -#. -#: replication/logical/conflict.c:236 utils/misc/guc.c:3176 -msgid "." -msgstr "" +#: replication/logical/conflict.c:271 +#, fuzzy, c-format +#| msgid "could not translate name" +msgid "Could not apply remote change: %s.\n" +msgstr "konnte Namen nicht umwandeln" -#: replication/logical/conflict.c:287 +#: replication/logical/conflict.c:274 #, fuzzy #| msgid "could not translate name" -msgid "Could not apply remote change" +msgid "Could not apply remote change.\n" msgstr "konnte Namen nicht umwandeln" -#: replication/logical/conflict.c:297 +#: replication/logical/conflict.c:288 +#, fuzzy, c-format +#| msgid "Key already exists in unique index \"%s\", modified locally in transaction %u at %s." +msgid "Key already exists in unique index \"%s\", modified locally in transaction %u at %s: %s." +msgstr "Schlüssel existiert bereits in Unique Index »%s«, lokal modifiziert in Transaktion %u um %s." + +#: replication/logical/conflict.c:293 #, fuzzy, c-format #| msgid "Key already exists in unique index \"%s\", modified locally in transaction %u at %s." -msgid "Key already exists in unique index \"%s\", modified locally in transaction %u at %s" +msgid "Key already exists in unique index \"%s\", modified locally in transaction %u at %s." msgstr "Schlüssel existiert bereits in Unique Index »%s«, lokal modifiziert in Transaktion %u um %s." -#: replication/logical/conflict.c:301 +#: replication/logical/conflict.c:300 #, fuzzy, c-format #| msgid "Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s." -msgid "Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s" +msgid "Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s: %s." msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert von Origin »%s« in Transaktion %u um %s." -#: replication/logical/conflict.c:313 +#: replication/logical/conflict.c:305 +#, fuzzy, c-format +#| msgid "Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s." +msgid "Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s." +msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert von Origin »%s« in Transaktion %u um %s." + +#: replication/logical/conflict.c:320 #, fuzzy, c-format #| msgid "Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s." -msgid "Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s" +msgid "Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s: %s." msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert von nicht existierendem Origin in Transaktion %u um %s." -#: replication/logical/conflict.c:318 +#: replication/logical/conflict.c:325 +#, fuzzy, c-format +#| msgid "Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s." +msgid "Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s." +msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert von nicht existierendem Origin in Transaktion %u um %s." + +#: replication/logical/conflict.c:333 +#, fuzzy, c-format +#| msgid "Key already exists in unique index \"%s\", modified in transaction %u." +msgid "Key already exists in unique index \"%s\", modified in transaction %u: %s." +msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert in Transaktion %u." + +#: replication/logical/conflict.c:337 #, fuzzy, c-format #| msgid "Key already exists in unique index \"%s\", modified in transaction %u." -msgid "Key already exists in unique index \"%s\", modified in transaction %u" +msgid "Key already exists in unique index \"%s\", modified in transaction %u." msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert in Transaktion %u." -#: replication/logical/conflict.c:328 +#: replication/logical/conflict.c:351 #, fuzzy, c-format #| msgid "Updating the row that was modified locally in transaction %u at %s." -msgid "Updating the row that was modified locally in transaction %u at %s" +msgid "Updating the row that was modified locally in transaction %u at %s: %s." msgstr "Aktualisiere die Zeile, die lokal in Transaktion %u um %s modifiziert wurde." -#: replication/logical/conflict.c:331 +#: replication/logical/conflict.c:355 +#, fuzzy, c-format +#| msgid "Updating the row that was modified locally in transaction %u at %s." +msgid "Updating the row that was modified locally in transaction %u at %s." +msgstr "Aktualisiere die Zeile, die lokal in Transaktion %u um %s modifiziert wurde." + +#: replication/logical/conflict.c:361 #, fuzzy, c-format #| msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s." -msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s" +msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s: %s." msgstr "Aktualisiere die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde." -#: replication/logical/conflict.c:336 +#: replication/logical/conflict.c:366 +#, fuzzy, c-format +#| msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s." +msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s." +msgstr "Aktualisiere die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde." + +#: replication/logical/conflict.c:375 #, fuzzy, c-format #| msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s." -msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s" +msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s: %s." msgstr "Aktualisiere die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde." -#: replication/logical/conflict.c:346 replication/logical/conflict.c:372 +#: replication/logical/conflict.c:379 +#, fuzzy, c-format +#| msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s." +msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s." +msgstr "Aktualisiere die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde." + +#: replication/logical/conflict.c:390 +#, fuzzy, c-format +#| msgid "Could not find the row to be updated." +msgid "Could not find the row to be updated: %s.\n" +msgstr "Konnte die zu aktualisierende Zeile nicht finden." + +#: replication/logical/conflict.c:393 #, fuzzy #| msgid "Could not find the row to be updated." -msgid "Could not find the row to be updated" +msgid "Could not find the row to be updated.\n" msgstr "Konnte die zu aktualisierende Zeile nicht finden." -#: replication/logical/conflict.c:355 +#: replication/logical/conflict.c:398 #, fuzzy, c-format #| msgid "Updating the row that was modified locally in transaction %u at %s." msgid "The row to be updated was deleted locally in transaction %u at %s" msgstr "Aktualisiere die Zeile, die lokal in Transaktion %u um %s modifiziert wurde." -#: replication/logical/conflict.c:358 +#: replication/logical/conflict.c:401 #, fuzzy, c-format #| msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s." msgid "The row to be updated was deleted by a different origin \"%s\" in transaction %u at %s" msgstr "Aktualisiere die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde." -#: replication/logical/conflict.c:363 +#: replication/logical/conflict.c:406 #, fuzzy, c-format #| msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s." msgid "The row to be updated was deleted by a non-existent origin in transaction %u at %s" msgstr "Aktualisiere die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde." -#: replication/logical/conflict.c:367 +#: replication/logical/conflict.c:410 msgid "The row to be updated was deleted" msgstr "" -#: replication/logical/conflict.c:382 +#: replication/logical/conflict.c:419 +#, fuzzy, c-format +#| msgid "Could not find the row to be updated." +msgid "Could not find the row to be updated: %s." +msgstr "Konnte die zu aktualisierende Zeile nicht finden." + +#: replication/logical/conflict.c:422 +#, fuzzy +#| msgid "Could not find the row to be updated." +msgid "Could not find the row to be updated." +msgstr "Konnte die zu aktualisierende Zeile nicht finden." + +#: replication/logical/conflict.c:434 +#, fuzzy, c-format +#| msgid "Deleting the row that was modified locally in transaction %u at %s." +msgid "Deleting the row that was modified locally in transaction %u at %s: %s." +msgstr "Lösche die Zeile, die lokal in Transaktion %u um %s modifiziert wurde." + +#: replication/logical/conflict.c:438 #, fuzzy, c-format #| msgid "Deleting the row that was modified locally in transaction %u at %s." -msgid "Deleting the row that was modified locally in transaction %u at %s" +msgid "Deleting the row that was modified locally in transaction %u at %s." msgstr "Lösche die Zeile, die lokal in Transaktion %u um %s modifiziert wurde." -#: replication/logical/conflict.c:385 +#: replication/logical/conflict.c:444 #, fuzzy, c-format #| msgid "Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s." -msgid "Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s" +msgid "Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s: %s." msgstr "Lösche die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde." -#: replication/logical/conflict.c:390 +#: replication/logical/conflict.c:449 +#, fuzzy, c-format +#| msgid "Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s." +msgid "Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s." +msgstr "Lösche die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde." + +#: replication/logical/conflict.c:458 +#, fuzzy, c-format +#| msgid "Deleting the row that was modified by a non-existent origin in transaction %u at %s." +msgid "Deleting the row that was modified by a non-existent origin in transaction %u at %s: %s." +msgstr "Lösche die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde." + +#: replication/logical/conflict.c:462 #, fuzzy, c-format #| msgid "Deleting the row that was modified by a non-existent origin in transaction %u at %s." -msgid "Deleting the row that was modified by a non-existent origin in transaction %u at %s" +msgid "Deleting the row that was modified by a non-existent origin in transaction %u at %s." msgstr "Lösche die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde." -#: replication/logical/conflict.c:400 +#: replication/logical/conflict.c:473 +#, fuzzy, c-format +#| msgid "Could not find the row to be deleted." +msgid "Could not find the row to be deleted: %s." +msgstr "Konnte die zu löschende Zeile nicht finden." + +#: replication/logical/conflict.c:476 #, fuzzy #| msgid "Could not find the row to be deleted." -msgid "Could not find the row to be deleted" +msgid "Could not find the row to be deleted." msgstr "Konnte die zu löschende Zeile nicht finden." -#: replication/logical/conflict.c:456 +#: replication/logical/conflict.c:529 #, fuzzy, c-format #| msgid "Key %s" msgid "key %s" msgstr "Schlüssel %s" -#: replication/logical/conflict.c:469 +#: replication/logical/conflict.c:542 #, fuzzy, c-format #| msgid "existing local row %s" msgid "local row %s" msgstr "bestehende lokale Zeile %s" -#: replication/logical/conflict.c:490 +#: replication/logical/conflict.c:563 #, c-format msgid "remote row %s" msgstr "entfernte Zeile %s" -#: replication/logical/conflict.c:519 +#: replication/logical/conflict.c:592 #, c-format msgid "replica identity %s" msgstr "Replika-Identität %s" -#: replication/logical/conflict.c:521 +#: replication/logical/conflict.c:594 #, c-format msgid "replica identity full %s" msgstr "Replika-Identität Full %s" @@ -26299,7 +26502,7 @@ msgstr "Arbeitsprozess-Slot %d für logische Replikation ist leer, kann nicht zu msgid "logical replication worker slot %d is already used by another worker, cannot attach" msgstr "Arbeitsprozess-Slot %d für logische Replikation wird schon von einem anderen Arbeitsprozess verwendet, kann nicht zugeteilt werden" -#: replication/logical/launcher.c:1575 +#: replication/logical/launcher.c:1576 #, fuzzy, c-format #| msgid "Creating the replication conflict detection slot" msgid "creating replication conflict detection slot" @@ -26321,84 +26524,84 @@ msgstr "logische Dekodierung auf dem Standby-Server erfordert »wal_level« >= msgid "Set \"wal_level\" >= \"logical\" or create at least one logical slot when \"wal_level\" = \"replica\"." msgstr "" -#: replication/logical/logical.c:361 replication/logical/logical.c:517 +#: replication/logical/logical.c:358 replication/logical/logical.c:514 #, c-format msgid "cannot use physical replication slot for logical decoding" msgstr "physischer Replikations-Slot kann nicht für logisches Dekodieren verwendet werden" -#: replication/logical/logical.c:366 replication/logical/logical.c:527 +#: replication/logical/logical.c:363 replication/logical/logical.c:524 #, c-format msgid "replication slot \"%s\" was not created in this database" msgstr "Replikations-Slot »%s« wurde nicht in dieser Datenbank erzeugt" -#: replication/logical/logical.c:373 +#: replication/logical/logical.c:370 #, c-format msgid "cannot create logical replication slot in transaction that has performed writes" msgstr "logischer Replikations-Slot kann nicht in einer Transaktion erzeugt werden, die Schreibvorgänge ausgeführt hat" -#: replication/logical/logical.c:538 +#: replication/logical/logical.c:535 #, c-format msgid "cannot use replication slot \"%s\" for logical decoding" msgstr "physischer Replikations-Slot »%s« kann nicht für logisches Dekodieren verwendet werden" -#: replication/logical/logical.c:540 replication/slot.c:936 -#: replication/slot.c:986 +#: replication/logical/logical.c:537 replication/slot.c:927 +#: replication/slot.c:972 #, c-format msgid "This replication slot is being synchronized from the primary server." msgstr "Dieser Replikations-Slot wird vom Primärserver synchronisiert." -#: replication/logical/logical.c:541 +#: replication/logical/logical.c:538 #, c-format msgid "Specify another replication slot." msgstr "Geben Sie einen anderen Replikations-Slot an." -#: replication/logical/logical.c:607 +#: replication/logical/logical.c:604 #, c-format msgid "starting logical decoding for slot \"%s\"" msgstr "starte logisches Dekodieren für Slot »%s«" -#: replication/logical/logical.c:609 +#: replication/logical/logical.c:606 #, fuzzy, c-format #| msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." msgid "Streaming transactions committing after %X/%08X, reading WAL from %X/%08X." msgstr "Streaming beginnt bei Transaktionen, die nach %X/%X committen; lese WAL ab %X/%X." -#: replication/logical/logical.c:757 +#: replication/logical/logical.c:754 #, fuzzy, c-format #| msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%08X" msgstr "Slot »%s«, Ausgabe-Plugin »%s«, im Callback %s, zugehörige LSN %X/%X" -#: replication/logical/logical.c:763 +#: replication/logical/logical.c:760 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback" msgstr "Slot »%s«, Ausgabe-Plugin »%s«, im Callback %s" -#: replication/logical/logical.c:934 replication/logical/logical.c:979 -#: replication/logical/logical.c:1024 replication/logical/logical.c:1070 +#: replication/logical/logical.c:931 replication/logical/logical.c:976 +#: replication/logical/logical.c:1021 replication/logical/logical.c:1067 #, c-format msgid "logical replication at prepare time requires a %s callback" msgstr "logische Replikation bei PREPARE TRANSACTION benötigt einen %s-Callback" -#: replication/logical/logical.c:1302 replication/logical/logical.c:1351 -#: replication/logical/logical.c:1392 replication/logical/logical.c:1478 -#: replication/logical/logical.c:1527 +#: replication/logical/logical.c:1299 replication/logical/logical.c:1348 +#: replication/logical/logical.c:1389 replication/logical/logical.c:1475 +#: replication/logical/logical.c:1524 #, c-format msgid "logical streaming requires a %s callback" msgstr "logisches Streaming benötigt einen %s-Callback" -#: replication/logical/logical.c:1437 +#: replication/logical/logical.c:1434 #, c-format msgid "logical streaming at prepare time requires a %s callback" msgstr "logisches Streaming bei PREPARE TRANSACTION benötigt einen %s-Callback" -#: replication/logical/logicalctl.c:421 +#: replication/logical/logicalctl.c:413 #, fuzzy, c-format #| msgid "Logical replication is waiting for correction on replication slot \"%s\"." msgid "logical decoding is enabled upon creating a new logical replication slot" msgstr "Logische Replikation wartet auf Korrektur bei Replikations-Slot »%s«." -#: replication/logical/logicalctl.c:530 +#: replication/logical/logicalctl.c:537 #, fuzzy, c-format #| msgid "Checking for valid logical replication slots" msgid "logical decoding is disabled because there are no valid logical replication slots" @@ -26572,58 +26775,58 @@ msgstr "Replication-Origin-Name »%s« ist reserviert" msgid "Origin names \"%s\", \"%s\", and names starting with \"pg_\" are reserved." msgstr "Replication-Origin-Namen »%s«, »%s« und Namen, die mit »pg_« anfangen, sind reserviert." -#: replication/logical/relation.c:275 +#: replication/logical/relation.c:274 #, c-format msgid "logical replication target relation \"%s.%s\" is missing replicated column: %s" msgid_plural "logical replication target relation \"%s.%s\" is missing replicated columns: %s" msgstr[0] "in Zielrelation für logische Replikation »%s.%s« fehlt eine replizierte Spalte: %s" msgstr[1] "in Zielrelation für logische Replikation »%s.%s« fehlen replizierte Spalten: %s" -#: replication/logical/relation.c:286 +#: replication/logical/relation.c:285 #, c-format msgid "logical replication target relation \"%s.%s\" has incompatible generated column: %s" msgid_plural "logical replication target relation \"%s.%s\" has incompatible generated columns: %s" msgstr[0] "Zielrelation für logische Replikation »%s.%s« hat eine inkompatible generierte Spalte: %s" msgstr[1] "Zielrelation für logische Replikation »%s.%s« hat inkompatible generierte Spalten: %s" -#: replication/logical/relation.c:341 +#: replication/logical/relation.c:340 #, c-format msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" msgstr "Zielrelation für logische Replikation »%s.%s« verwendet Systemspalten in REPLICA-IDENTITY-Index" -#: replication/logical/relation.c:434 +#: replication/logical/relation.c:433 #, c-format msgid "logical replication target relation \"%s.%s\" does not exist" msgstr "Zielrelation für logische Replikation »%s.%s« existiert nicht" -#: replication/logical/reorderbuffer.c:4284 +#: replication/logical/reorderbuffer.c:4282 #, c-format msgid "could not write to data file for XID %u: %m" msgstr "konnte nicht in Datendatei für XID %u schreiben: %m" -#: replication/logical/reorderbuffer.c:4630 -#: replication/logical/reorderbuffer.c:4655 +#: replication/logical/reorderbuffer.c:4628 +#: replication/logical/reorderbuffer.c:4653 #, c-format msgid "could not read from reorderbuffer spill file: %m" msgstr "konnte nicht aus Reorder-Buffer-Spill-Datei lesen: %m" -#: replication/logical/reorderbuffer.c:4634 -#: replication/logical/reorderbuffer.c:4659 +#: replication/logical/reorderbuffer.c:4632 +#: replication/logical/reorderbuffer.c:4657 #, c-format msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" msgstr "konnte nicht aus Reorder-Buffer-Spill-Datei lesen: %d statt %u Bytes gelesen" -#: replication/logical/reorderbuffer.c:4908 +#: replication/logical/reorderbuffer.c:4906 #, c-format msgid "could not remove file \"%s\" during removal of %s/%s/xid*: %m" msgstr "konnte Datei »%s« nicht löschen, beim Löschen von %s/%s/xid*: %m" -#: replication/logical/reorderbuffer.c:5401 +#: replication/logical/reorderbuffer.c:5399 #, c-format msgid "could not read from file \"%s\": read %d instead of %d bytes" msgstr "konnte nicht aus Datei »%s« lesen: %d statt %d Bytes gelesen" -#: replication/logical/sequencesync.c:190 +#: replication/logical/sequencesync.c:195 #, fuzzy, c-format #| msgid "could not reset WAL on subscriber: %s" msgid "mismatched or renamed sequence on subscriber (%s)" @@ -26631,15 +26834,37 @@ msgid_plural "mismatched or renamed sequences on subscriber (%s)" msgstr[0] "konnte WAL auf dem Subskriptionsserver nicht zurücksetzen: %s" msgstr[1] "konnte WAL auf dem Subskriptionsserver nicht zurücksetzen: %s" -#: replication/logical/sequencesync.c:201 +#: replication/logical/sequencesync.c:214 +#, fuzzy, c-format +#| msgid "invalid privilege type %s for sequence" +msgid "insufficient privileges on subscriber sequence (%s)" +msgid_plural "insufficient privileges on subscriber sequences (%s)" +msgstr[0] "ungültiger Privilegtyp %s für Sequenz" +msgstr[1] "ungültiger Privilegtyp %s für Sequenz" + +#: replication/logical/sequencesync.c:219 +#, c-format +msgid "Grant UPDATE on the sequence to the subscription owner on the subscriber." +msgid_plural "Grant UPDATE on the sequences to the subscription owner on the subscriber." +msgstr[0] "" +msgstr[1] "" + +#: replication/logical/sequencesync.c:231 #, fuzzy, c-format #| msgid "invalid privilege type %s for sequence" -msgid "insufficient privileges on sequence (%s)" -msgid_plural "insufficient privileges on sequences (%s)" +msgid "insufficient privileges on publisher sequence (%s)" +msgid_plural "insufficient privileges on publisher sequences (%s)" msgstr[0] "ungültiger Privilegtyp %s für Sequenz" msgstr[1] "ungültiger Privilegtyp %s für Sequenz" -#: replication/logical/sequencesync.c:212 +#: replication/logical/sequencesync.c:235 +#, c-format +msgid "Grant SELECT on the sequence to the role used for the replication connection on the publisher." +msgid_plural "Grant SELECT on the sequences to the role used for the replication connection on the publisher." +msgstr[0] "" +msgstr[1] "" + +#: replication/logical/sequencesync.c:247 #, fuzzy, c-format #| msgid "checking settings on publisher" msgid "missing sequence on publisher (%s)" @@ -26647,24 +26872,24 @@ msgid_plural "missing sequences on publisher (%s)" msgstr[0] "prüfe Einstellungen auf dem Publikationsserver" msgstr[1] "prüfe Einstellungen auf dem Publikationsserver" -#: replication/logical/sequencesync.c:220 +#: replication/logical/sequencesync.c:255 #, fuzzy, c-format #| msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" msgid "logical replication sequence synchronization failed for subscription \"%s\"" msgstr "Arbeitsprozess für logische Replikation für Tabellensynchronisation für Subskription »%s«, Tabelle »%s« hat gestartet" -#: replication/logical/sequencesync.c:489 +#: replication/logical/sequencesync.c:533 #, fuzzy, c-format #| msgid "could not receive list of publications from the publisher: %s" msgid "could not fetch sequence information from the publisher: %s" msgstr "konnte Liste der Publikationen nicht vom Publikationsserver empfangen: %s" -#: replication/logical/sequencesync.c:559 +#: replication/logical/sequencesync.c:616 #, c-format msgid "skip synchronization of sequence \"%s.%s\" because it has been dropped concurrently" msgstr "" -#: replication/logical/sequencesync.c:720 +#: replication/logical/sequencesync.c:778 #, fuzzy, c-format #| msgid "apply worker for subscription \"%s\" could not connect to the publisher: %s" msgid "sequencesync worker for subscription \"%s\" could not connect to the publisher: %s" @@ -26693,43 +26918,43 @@ msgstr "Synchronisation könnte zu Datenverlust führen, weil der Remote-Slot WA msgid "Synchronization could lead to data loss, because the standby could not build a consistent snapshot to decode WALs at LSN %X/%08X." msgstr "Synchronisation könnte zu Datenverlust führen, weil der Standby keinen konsistenten Snapshot zum Dekodieren von WAL bei LSN %X/%X bauen konnte." -#: replication/logical/slotsync.c:577 +#: replication/logical/slotsync.c:582 #, c-format msgid "dropped replication slot \"%s\" of database with OID %u" msgstr "Replikations-Slot »%s« von Datenbank mit OID %u wurde gelöscht" -#: replication/logical/slotsync.c:705 +#: replication/logical/slotsync.c:714 #, c-format msgid "newly created replication slot \"%s\" is sync-ready now" msgstr "neu erzeugter Replikations-Slot »%s« ist jetzt bereit für die Synchronisierung" -#: replication/logical/slotsync.c:747 +#: replication/logical/slotsync.c:756 #, c-format msgid "exiting from slot synchronization because same name slot \"%s\" already exists on the standby" msgstr "verlasse Slot-Synchronisierung, weil der gleiche Slot »%s« schon auf dem Standby existiert" -#: replication/logical/slotsync.c:940 +#: replication/logical/slotsync.c:949 #, c-format msgid "could not fetch failover logical slots info from the primary server: %s" msgstr "konnte Informationen über logische Failover-Slots nicht vom Primärserver holen: %s" -#: replication/logical/slotsync.c:1104 +#: replication/logical/slotsync.c:1114 #, c-format msgid "could not fetch primary slot name \"%s\" info from the primary server: %s" msgstr "konnte Informationen über primary_slot_name »%s« nicht vom Primärserver holen: %s" -#: replication/logical/slotsync.c:1106 +#: replication/logical/slotsync.c:1116 #, c-format msgid "Check if \"primary_slot_name\" is configured correctly." msgstr "Prüfen Sie, ob »primary_slot_name« korrekt konfiguriert ist." -#: replication/logical/slotsync.c:1126 +#: replication/logical/slotsync.c:1136 #, c-format msgid "cannot synchronize replication slots from a standby server" msgstr "Replikations-Slots können nicht von einem Standby-Server synchronisiert werden" #. translator: second %s is a GUC variable name -#: replication/logical/slotsync.c:1135 +#: replication/logical/slotsync.c:1145 #, c-format msgid "replication slot \"%s\" specified by \"%s\" does not exist on primary server" msgstr "Replikations-Slot »%s«, der in »%s« angegeben ist, existiert auf dem Publikationsserver nicht" @@ -26737,158 +26962,158 @@ msgstr "Replikations-Slot »%s«, der in »%s« angegeben ist, existiert auf dem #. translator: first %s is a connection option; second %s is a GUC #. variable name #. -#: replication/logical/slotsync.c:1168 +#: replication/logical/slotsync.c:1178 #, c-format msgid "replication slot synchronization requires \"%s\" to be specified in \"%s\"" msgstr "Replikations-Slot-Synchronisierung erfordert, dass »%s« in »%s« angegeben wird" -#: replication/logical/slotsync.c:1187 +#: replication/logical/slotsync.c:1197 #, fuzzy, c-format #| msgid "replication slot synchronization requires \"wal_level\" >= \"logical\"" msgid "replication slot synchronization requires \"effective_wal_level\" >= \"logical\" on the primary" msgstr "Replikations-Slot-Synchronisierung erfordert »wal_level« >= »logical«" -#: replication/logical/slotsync.c:1188 +#: replication/logical/slotsync.c:1198 #, c-format msgid "To enable logical decoding on primary, set \"wal_level\" >= \"logical\" or create at least one logical slot when \"wal_level\" = \"replica\"." msgstr "" #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1204 replication/logical/slotsync.c:1232 +#: replication/logical/slotsync.c:1214 replication/logical/slotsync.c:1242 #, c-format msgid "replication slot synchronization requires \"%s\" to be set" msgstr "Replikations-Slot-Synchronisierung erfordert, dass »%s« definiert ist" #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1218 +#: replication/logical/slotsync.c:1228 #, c-format msgid "replication slot synchronization requires \"%s\" to be enabled" msgstr "Replikations-Slot-Synchronisierung erfordert, dass »%s« eingeschaltet ist" #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1275 +#: replication/logical/slotsync.c:1285 #, fuzzy, c-format #| msgid "replication slot synchronization worker will shut down because \"%s\" is disabled" msgid "replication slot synchronization worker will stop because \"%s\" is disabled" msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung wird herunterfahren, weil »%s« deaktiviert ist" -#: replication/logical/slotsync.c:1293 +#: replication/logical/slotsync.c:1303 #, c-format msgid "replication slot synchronization worker will restart because of a parameter change" msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung wird neu starten wegen einer Parameteränderung" -#: replication/logical/slotsync.c:1318 +#: replication/logical/slotsync.c:1328 #, fuzzy, c-format #| msgid "replication slot synchronization worker will restart because of a parameter change" msgid "replication slot synchronization will stop because of a parameter change" msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung wird neu starten wegen einer Parameteränderung" -#: replication/logical/slotsync.c:1354 +#: replication/logical/slotsync.c:1364 #, fuzzy, c-format #| msgid "replication slot synchronization worker is shutting down because promotion is triggered" msgid "replication slot synchronization worker will stop because promotion is triggered" msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung fährt herunter, weil Beförderung ausgelöst wurde" -#: replication/logical/slotsync.c:1368 +#: replication/logical/slotsync.c:1378 #, fuzzy, c-format #| msgid "replication slot synchronization worker is shutting down because promotion is triggered" msgid "replication slot synchronization will stop because promotion is triggered" msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung fährt herunter, weil Beförderung ausgelöst wurde" -#: replication/logical/slotsync.c:1488 +#: replication/logical/slotsync.c:1498 #, fuzzy, c-format #| msgid "replication slot synchronization worker is shutting down because promotion is triggered" msgid "replication slot synchronization worker will not start because promotion was triggered" msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung fährt herunter, weil Beförderung ausgelöst wurde" -#: replication/logical/slotsync.c:1500 +#: replication/logical/slotsync.c:1510 #, fuzzy, c-format #| msgid "replication slot synchronization worker is shutting down because promotion is triggered" msgid "replication slot synchronization will not start because promotion was triggered" msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung fährt herunter, weil Beförderung ausgelöst wurde" -#: replication/logical/slotsync.c:1509 +#: replication/logical/slotsync.c:1519 #, c-format msgid "cannot synchronize replication slots concurrently" msgstr "Replikations-Slots können nicht nebenläufig synchronisiert werden" -#: replication/logical/slotsync.c:1629 +#: replication/logical/slotsync.c:1639 #, c-format msgid "slot sync worker started" msgstr "Slot-Sync-Arbeitsprozess gestartet" -#: replication/logical/slotsync.c:1691 replication/slotfuncs.c:953 +#: replication/logical/slotsync.c:1701 replication/slotfuncs.c:953 #, c-format msgid "synchronization worker \"%s\" could not connect to the primary server: %s" msgstr "Synchronisierungs-Arbeitsprozess »%s« konnte nicht mit dem Primärserver verbinden: %s" -#: replication/logical/snapbuild.c:531 +#: replication/logical/snapbuild.c:517 #, c-format msgid "initial slot snapshot too large" msgstr "initialer Slot-Snapshot ist zu groß" -#: replication/logical/snapbuild.c:585 +#: replication/logical/snapbuild.c:571 #, c-format msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" msgstr[0] "logischer Dekodierungs-Snapshot exportiert: »%s« mit %u Transaktions-ID" msgstr[1] "logischer Dekodierungs-Snapshot exportiert: »%s« mit %u Transaktions-IDs" -#: replication/logical/snapbuild.c:1369 replication/logical/snapbuild.c:1466 -#: replication/logical/snapbuild.c:1976 +#: replication/logical/snapbuild.c:1317 replication/logical/snapbuild.c:1414 +#: replication/logical/snapbuild.c:1920 #, fuzzy, c-format #| msgid "logical decoding found consistent point at %X/%X" msgid "logical decoding found consistent point at %X/%08X" msgstr "logisches Dekodieren fand konsistenten Punkt bei %X/%X" -#: replication/logical/snapbuild.c:1371 +#: replication/logical/snapbuild.c:1319 #, c-format msgid "There are no running transactions." msgstr "Keine laufenden Transaktionen." -#: replication/logical/snapbuild.c:1418 +#: replication/logical/snapbuild.c:1366 #, fuzzy, c-format #| msgid "logical decoding found initial starting point at %X/%X" msgid "logical decoding found initial starting point at %X/%08X" msgstr "logisches Dekodieren fand initialen Startpunkt bei %X/%X" -#: replication/logical/snapbuild.c:1420 replication/logical/snapbuild.c:1444 +#: replication/logical/snapbuild.c:1368 replication/logical/snapbuild.c:1392 #, c-format msgid "Waiting for transactions (approximately %d) older than %u to end." msgstr "Warten auf Abschluss der Transaktionen (ungefähr %d), die älter als %u sind." -#: replication/logical/snapbuild.c:1442 +#: replication/logical/snapbuild.c:1390 #, fuzzy, c-format #| msgid "logical decoding found initial consistent point at %X/%X" msgid "logical decoding found initial consistent point at %X/%08X" msgstr "logisches Dekodieren fand initialen konsistenten Punkt bei %X/%X" -#: replication/logical/snapbuild.c:1468 +#: replication/logical/snapbuild.c:1416 #, c-format msgid "There are no old transactions anymore." msgstr "Es laufen keine alten Transaktionen mehr." -#: replication/logical/snapbuild.c:1843 +#: replication/logical/snapbuild.c:1787 #, c-format msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" msgstr "Scanbuild-State-Datei »%s« hat falsche magische Zahl %u statt %u" -#: replication/logical/snapbuild.c:1849 +#: replication/logical/snapbuild.c:1793 #, c-format msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" msgstr "Snapbuild-State-Datei »%s« hat nicht unterstützte Version: %u statt %u" -#: replication/logical/snapbuild.c:1890 +#: replication/logical/snapbuild.c:1834 #, c-format msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" msgstr "Prüfsummenfehler bei Snapbuild-State-Datei »%s«: ist %u, sollte %u sein" -#: replication/logical/snapbuild.c:1978 +#: replication/logical/snapbuild.c:1922 #, c-format msgid "Logical decoding will begin using saved snapshot." msgstr "Logische Dekodierung beginnt mit gespeichertem Snapshot." -#: replication/logical/snapbuild.c:2085 +#: replication/logical/snapbuild.c:2029 #, c-format msgid "could not parse file name \"%s\"" msgstr "konnte Dateinamen »%s« nicht parsen" @@ -26934,22 +27159,22 @@ msgstr "konnte WHERE-Klausel-Informationen für Tabelle »%s.%s« nicht vom Publ msgid "could not start initial contents copy for table \"%s.%s\": %s" msgstr "konnte Kopieren des Anfangsinhalts für Tabelle »%s.%s« nicht starten: %s" -#: replication/logical/tablesync.c:1313 +#: replication/logical/tablesync.c:1314 #, c-format msgid "table synchronization worker for subscription \"%s\" could not connect to the publisher: %s" msgstr "Arbeitsprozess für Tabellensynchronisation für Subskription »%s« konnte nicht mit dem Publikationsserver verbinden: %s" -#: replication/logical/tablesync.c:1413 +#: replication/logical/tablesync.c:1414 #, c-format msgid "table copy could not start transaction on publisher: %s" msgstr "beim Kopieren der Tabelle konnte die Transaktion auf dem Publikationsserver nicht gestartet werden: %s" -#: replication/logical/tablesync.c:1473 replication/logical/worker.c:2630 +#: replication/logical/tablesync.c:1474 replication/logical/worker.c:2640 #, c-format msgid "user \"%s\" cannot replicate into relation with row-level security enabled: \"%s\"" msgstr "Benutzer »%s« kann nicht in eine Relation mit Sicherheit auf Zeilenebene replizieren: »%s«" -#: replication/logical/tablesync.c:1486 +#: replication/logical/tablesync.c:1487 #, c-format msgid "table copy could not finish transaction on publisher: %s" msgstr "beim Kopieren der Tabelle konnte die Transaktion auf dem Publikationsserver nicht beenden werden: %s" @@ -26964,201 +27189,207 @@ msgstr "Parallel-Apply-Worker für logische Replikation für Subskription »%s« msgid "Cannot handle streamed replication transactions using parallel apply workers until all tables have been synchronized." msgstr "Gestreamte Replikationstransaktionen können erst mit parallelen Apply-Worker-Prozessen verarbeitet werden, wenn alle Tabellen synchronisiert worden sind." -#: replication/logical/worker.c:1079 replication/logical/worker.c:1194 +#: replication/logical/worker.c:1046 replication/logical/worker.c:1163 +#: replication/logical/worker.c:2886 +#, c-format +msgid "logical replication column %d not found in tuple: only %d column(s) received" +msgstr "" + +#: replication/logical/worker.c:1085 replication/logical/worker.c:1204 #, c-format msgid "incorrect binary data format in logical replication column %d" msgstr "falsches Binärdatenformat in Spalte %d in logischer Replikation" -#: replication/logical/worker.c:2777 +#: replication/logical/worker.c:2787 #, c-format msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" msgstr "Publikationsserver hat nicht die Replikidentitätsspalten gesendet, die von Replikationszielrelation »%s.%s« erwartet wurden" -#: replication/logical/worker.c:2784 +#: replication/logical/worker.c:2794 #, c-format msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" msgstr "Zielrelation für logische Replikation »%s.%s« hat weder REPLICA-IDENTITY-Index noch Primärschlüssel und die publizierte Relation hat kein REPLICA IDENTITY FULL" -#: replication/logical/worker.c:3325 +#: replication/logical/worker.c:3340 #, c-format msgid "could not detect conflict as the leader apply worker has exited" msgstr "" -#: replication/logical/worker.c:3881 +#: replication/logical/worker.c:3896 #, c-format msgid "invalid logical replication message type \"??? (%d)\"" msgstr "ungültiger Nachrichtentyp für logische Replikation »??? (%d)«" -#: replication/logical/worker.c:4054 +#: replication/logical/worker.c:4069 #, c-format msgid "data stream from publisher has ended" msgstr "Datenstrom vom Publikationsserver endete" -#: replication/logical/worker.c:4257 +#: replication/logical/worker.c:4272 #, c-format msgid "terminating logical replication worker due to timeout" msgstr "Arbeitsprozess für logische Replikation wird abgebrochen wegen Zeitüberschreitung" -#: replication/logical/worker.c:4829 +#: replication/logical/worker.c:4844 #, fuzzy, c-format #| msgid "logical replication worker for subscription \"%s\" will stop because the subscription was disabled" msgid "logical replication worker for subscription \"%s\" has stopped retaining the information for detecting conflicts" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird anhalten, weil die Subskription deaktiviert wurde" -#: replication/logical/worker.c:4831 +#: replication/logical/worker.c:4846 #, c-format msgid "Retention is stopped because the apply process has not caught up with the publisher within the configured max_retention_duration." msgstr "" -#: replication/logical/worker.c:4856 +#: replication/logical/worker.c:4871 #, fuzzy, c-format #| msgid "logical replication worker for subscription \"%s\" will restart because of a parameter change" msgid "logical replication worker for subscription \"%s\" will resume retaining the information for detecting conflicts" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird neu starten wegen einer Parameteränderung" -#: replication/logical/worker.c:4859 +#: replication/logical/worker.c:4874 #, c-format msgid "Retention is re-enabled because the apply process has caught up with the publisher within the configured max_retention_duration." msgstr "" -#: replication/logical/worker.c:4860 +#: replication/logical/worker.c:4875 #, c-format msgid "Retention is re-enabled because max_retention_duration has been set to unlimited." msgstr "" -#: replication/logical/worker.c:5074 +#: replication/logical/worker.c:5090 #, c-format msgid "logical replication worker for subscription \"%s\" will stop because the subscription was removed" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird anhalten, weil die Subskription entfernt wurde" -#: replication/logical/worker.c:5088 +#: replication/logical/worker.c:5104 #, c-format msgid "logical replication worker for subscription \"%s\" will stop because the subscription was disabled" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird anhalten, weil die Subskription deaktiviert wurde" -#: replication/logical/worker.c:5119 +#: replication/logical/worker.c:5135 #, c-format msgid "logical replication parallel apply worker for subscription \"%s\" will stop because of a parameter change" msgstr "Parallel-Apply-Worker für logische Replikation für Subskription »%s« wird anhalten wegen einer Parameteränderung" -#: replication/logical/worker.c:5123 +#: replication/logical/worker.c:5139 #, c-format msgid "logical replication worker for subscription \"%s\" will restart because of a parameter change" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird neu starten wegen einer Parameteränderung" -#: replication/logical/worker.c:5137 +#: replication/logical/worker.c:5153 #, c-format msgid "logical replication parallel apply worker for subscription \"%s\" will stop because the subscription owner's superuser privileges have been revoked" msgstr "Parallel-Apply-Worker für logische Replikation für Subskription »%s« wird anhalten, weil die Superuser-Privilegien des Eigentümers der Subskription entzogen wurden" -#: replication/logical/worker.c:5141 +#: replication/logical/worker.c:5157 #, c-format msgid "logical replication worker for subscription \"%s\" will restart because the subscription owner's superuser privileges have been revoked" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird neu starten, weil die Superuser-Privilegien des Eigentümers der Subskription entzogen wurden" -#: replication/logical/worker.c:5687 +#: replication/logical/worker.c:5703 #, c-format msgid "subscription has no replication slot set" msgstr "für die Subskription ist kein Replikations-Slot gesetzt" -#: replication/logical/worker.c:5712 +#: replication/logical/worker.c:5728 #, c-format msgid "apply worker for subscription \"%s\" could not connect to the publisher: %s" msgstr "Apply-Worker für Subskription »%s« konnte nicht mit dem Publikationsserver verbinden: %s" -#: replication/logical/worker.c:5819 +#: replication/logical/worker.c:5835 #, c-format msgid "logical replication worker for subscription %u will not start because the subscription was removed during startup" msgstr "Arbeitsprozess für logische Replikation für Subskription %u« wird nicht starten, weil die Subskription während des Starts entfernt wurde" -#: replication/logical/worker.c:5834 +#: replication/logical/worker.c:5850 #, c-format msgid "logical replication worker for subscription \"%s\" will not start because the subscription was disabled during startup" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird nicht starten, weil die Subskription während des Starts deaktiviert wurde" -#: replication/logical/worker.c:5859 +#: replication/logical/worker.c:5875 #, fuzzy, c-format #| msgid "logical replication worker for subscription \"%s\" will not start because the subscription was disabled during startup" msgid "logical replication worker for subscription \"%s\" will restart because the option %s was enabled during startup" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird nicht starten, weil die Subskription während des Starts deaktiviert wurde" -#: replication/logical/worker.c:5902 +#: replication/logical/worker.c:5918 #, c-format msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" msgstr "Arbeitsprozess für logische Replikation für Tabellensynchronisation für Subskription »%s«, Tabelle »%s« hat gestartet" -#: replication/logical/worker.c:5907 +#: replication/logical/worker.c:5923 #, fuzzy, c-format #| msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" msgid "logical replication sequence synchronization worker for subscription \"%s\" has started" msgstr "Arbeitsprozess für logische Replikation für Tabellensynchronisation für Subskription »%s«, Tabelle »%s« hat gestartet" -#: replication/logical/worker.c:5911 +#: replication/logical/worker.c:5927 #, c-format msgid "logical replication apply worker for subscription \"%s\" has started" msgstr "Apply-Worker für logische Replikation für Subskription »%s« hat gestartet" -#: replication/logical/worker.c:6046 +#: replication/logical/worker.c:6062 #, c-format msgid "subscription \"%s\" has been disabled because of an error" msgstr "Subskription »%s« wurde wegen eines Fehlers deaktiviert" -#: replication/logical/worker.c:6103 +#: replication/logical/worker.c:6119 #, fuzzy, c-format #| msgid "logical replication starts skipping transaction at LSN %X/%X" msgid "logical replication starts skipping transaction at LSN %X/%08X" msgstr "logische Replikation beginnt Überspringen von Transaktion bei %X/%X" -#: replication/logical/worker.c:6117 +#: replication/logical/worker.c:6133 #, fuzzy, c-format #| msgid "logical replication completed skipping transaction at LSN %X/%X" msgid "logical replication completed skipping transaction at LSN %X/%08X" msgstr "logische Replikation beendet Überspringen von Transaktion bei %X/%X" -#: replication/logical/worker.c:6205 +#: replication/logical/worker.c:6221 #, c-format msgid "skip-LSN of subscription \"%s\" cleared" msgstr "Skip-LSN von Subskription »%s« gelöscht" -#: replication/logical/worker.c:6206 +#: replication/logical/worker.c:6222 #, fuzzy, c-format #| msgid "Remote transaction's finish WAL location (LSN) %X/%X did not match skip-LSN %X/%X." msgid "Remote transaction's finish WAL location (LSN) %X/%08X did not match skip-LSN %X/%08X." msgstr "Die WAL-Endposition (LSN) %X/%X der Remote-Transaktion stimmte nicht mit der Skip-LSN %X/%X überein." -#: replication/logical/worker.c:6234 +#: replication/logical/worker.c:6250 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\"" msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s«" -#: replication/logical/worker.c:6238 +#: replication/logical/worker.c:6254 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" in transaction %u" msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« in Transaktion %u" -#: replication/logical/worker.c:6243 +#: replication/logical/worker.c:6259 #, fuzzy, c-format #| msgid "processing remote data for replication origin \"%s\" during message type \"%s\" in transaction %u, finished at %X/%X" msgid "processing remote data for replication origin \"%s\" during message type \"%s\" in transaction %u, finished at %X/%08X" msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« in Transaktion %u, beendet bei %X/%X" -#: replication/logical/worker.c:6254 +#: replication/logical/worker.c:6270 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" in transaction %u" msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« für Replikationszielrelation »%s.%s« in Transaktion %u" -#: replication/logical/worker.c:6261 +#: replication/logical/worker.c:6277 #, fuzzy, c-format #| msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" in transaction %u, finished at %X/%X" msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" in transaction %u, finished at %X/%08X" msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« für Replikationszielrelation »%s.%s« in Transaktion %u, beendet bei %X/%X" -#: replication/logical/worker.c:6272 +#: replication/logical/worker.c:6288 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" column \"%s\" in transaction %u" msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« für Replikationszielrelation »%s.%s« Spalte »%s« in Transaktion %u" -#: replication/logical/worker.c:6280 +#: replication/logical/worker.c:6296 #, fuzzy, c-format #| msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" column \"%s\" in transaction %u, finished at %X/%X" msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" column \"%s\" in transaction %u, finished at %X/%08X" @@ -27239,7 +27470,19 @@ msgstr "Die Publikation existiert an diesem Punkt im WAL nicht." msgid "Create the publication if it does not exist." msgstr "Erzeugen Sie die Publikation, wenn sie nicht existiert." -#: replication/pgrepack/pgrepack.c:66 +#: replication/pgrepack/pgrepack.c:59 +#, fuzzy, c-format +#| msgid "starting logical decoding for slot \"%s\"" +msgid "unsupported use of logical decoding plugin \"%s\"" +msgstr "starte logisches Dekodieren für Slot »%s«" + +#: replication/pgrepack/pgrepack.c:61 +#, fuzzy, c-format +#| msgid "option %s can only be used with %s" +msgid "This plugin can only be used by %s." +msgstr "Option %s kann nur mit %s verwendet werden" + +#: replication/pgrepack/pgrepack.c:80 #, fuzzy, c-format #| msgid "this build does not support compression with %s" msgid "this plugin does not expect any options" @@ -27281,7 +27524,7 @@ msgstr "Der Präfix »pg_« ist für Systemschemas reserviert." msgid "cannot enable failover for a replication slot created on the standby" msgstr "Failover kann nicht für einen auf dem Standby erzeugten Replikations-Slot eingeschaltet werden" -#: replication/slot.c:420 replication/slot.c:1008 +#: replication/slot.c:420 replication/slot.c:994 #, c-format msgid "cannot enable failover for a temporary replication slot" msgstr "Failover kann nicht für einen temporären Replikations-Slot eingeschaltet werden" @@ -27319,7 +27562,7 @@ msgstr "Replikations-Slot »%s« kann nicht geändert werden" msgid "The slot is reserved for conflict detection and can only be acquired by logical replication launcher." msgstr "" -#: replication/slot.c:717 replication/slot.c:1596 +#: replication/slot.c:717 replication/slot.c:1592 #, c-format msgid "replication slot \"%s\" is active for PID %d" msgstr "Replikations-Slot »%s« ist aktiv für PID %d" @@ -27344,69 +27587,69 @@ msgstr "logischer Replikations-Slot »%s« wurde akquiriert" msgid "acquired physical replication slot \"%s\"" msgstr "physischer Replikations-Slot »%s« wurde akquiriert" -#: replication/slot.c:849 +#: replication/slot.c:842 #, c-format msgid "released logical replication slot \"%s\"" msgstr "logischer Replikations-Slot »%s« wurde freigegeben" -#: replication/slot.c:851 +#: replication/slot.c:844 #, c-format msgid "released physical replication slot \"%s\"" msgstr "physischer Replikations-Slot »%s« wurde freigegeben" -#: replication/slot.c:935 +#: replication/slot.c:926 #, c-format msgid "cannot drop replication slot \"%s\"" msgstr "kann Replikations-Slot »%s« nicht löschen" -#: replication/slot.c:973 +#: replication/slot.c:959 #, c-format msgid "cannot use %s with a physical replication slot" msgstr "%s kann nicht mit einem physischem Replikations-Slot verwendet werden" -#: replication/slot.c:985 +#: replication/slot.c:971 #, c-format msgid "cannot alter replication slot \"%s\"" msgstr "Replikations-Slot »%s« kann nicht geändert werden" -#: replication/slot.c:995 +#: replication/slot.c:981 #, c-format msgid "cannot enable failover for a replication slot on the standby" msgstr "Failover kann nicht für einen Replikations-Slot auf dem Standby eingeschaltet werden" -#: replication/slot.c:1143 replication/slot.c:2433 replication/slot.c:2826 +#: replication/slot.c:1139 replication/slot.c:2429 replication/slot.c:2822 #, c-format msgid "could not remove directory \"%s\"" msgstr "konnte Verzeichnis »%s« nicht löschen" -#: replication/slot.c:1675 +#: replication/slot.c:1671 #, fuzzy, c-format #| msgid "replication slots can only be used if \"max_replication_slots\" > 0" msgid "replication slots can only be used if \"%s\" > 0" msgstr "Replikations-Slots können nur verwendet werden, wenn »max_replication_slots« > 0" -#: replication/slot.c:1681 +#: replication/slot.c:1677 #, fuzzy, c-format #| msgid "option %s can only be used with %s" msgid "REPACK can only be used if \"%s\" > 0" msgstr "Option %s kann nur mit %s verwendet werden" -#: replication/slot.c:1687 +#: replication/slot.c:1683 #, c-format msgid "replication slots can only be used if \"wal_level\" >= \"replica\"" msgstr "Replikations-Slots können nur verwendet werden, wenn »wal_level« >= replica" -#: replication/slot.c:1699 +#: replication/slot.c:1695 #, c-format msgid "permission denied to use replication slots" msgstr "keine Berechtigung, um Replikations-Slots zu verwenden" -#: replication/slot.c:1700 +#: replication/slot.c:1696 #, c-format msgid "Only roles with the %s attribute may use replication slots." msgstr "Nur Rollen mit dem %s-Attribut können Replikations-Slots verwenden." -#: replication/slot.c:1812 +#: replication/slot.c:1808 #, fuzzy, c-format #| msgid "The slot's restart_lsn %X/%X exceeds the limit by % byte." #| msgid_plural "The slot's restart_lsn %X/%X exceeds the limit by % bytes." @@ -27415,135 +27658,135 @@ msgid_plural "The slot's restart_lsn %X/%08X exceeds the limit by % byte msgstr[0] "Die restart_lsn des Slots %X/%X überschreitet das Maximum um % Byte." msgstr[1] "Die restart_lsn des Slots %X/%X überschreitet das Maximum um % Bytes." -#: replication/slot.c:1823 +#: replication/slot.c:1819 #, c-format msgid "The slot conflicted with xid horizon %u." msgstr "Der Slot kollidierte mit dem xid-Horizont %u." -#: replication/slot.c:1828 +#: replication/slot.c:1824 #, fuzzy #| msgid "Logical decoding on standby requires \"wal_level\" >= \"logical\" on the primary server." msgid "Logical decoding on standby requires the primary server to either set \"wal_level\" >= \"logical\" or have at least one logical slot when \"wal_level\" = \"replica\"." msgstr "Logische Dekodierung auf dem Standby-Server erfordert »wal_level« >= »logical« auf dem Primärserver." #. translator: %s is a GUC variable name -#: replication/slot.c:1834 +#: replication/slot.c:1830 #, c-format msgid "The slot's idle time of %lds exceeds the configured \"%s\" duration of %ds." msgstr "Die Leerlaufzeit des Slots von %lds überschreitet die durch »%s« konfigurierte Dauer von %ds." -#: replication/slot.c:1848 +#: replication/slot.c:1844 #, c-format msgid "terminating process %d to release replication slot \"%s\"" msgstr "Prozess %d wird beendet, um Replikations-Slot »%s« freizugeben" -#: replication/slot.c:1850 +#: replication/slot.c:1846 #, c-format msgid "invalidating obsolete replication slot \"%s\"" msgstr "obsoleter Replikations-Slot »%s« wird ungültig gemacht" -#: replication/slot.c:2764 +#: replication/slot.c:2760 #, c-format msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" msgstr "Replikations-Slot-Datei »%s« hat falsche magische Zahl: %u statt %u" -#: replication/slot.c:2771 +#: replication/slot.c:2767 #, c-format msgid "replication slot file \"%s\" has unsupported version %u" msgstr "Replikations-Slot-Datei »%s« hat nicht unterstützte Version %u" -#: replication/slot.c:2778 +#: replication/slot.c:2774 #, c-format msgid "replication slot file \"%s\" has corrupted length %u" msgstr "Replikations-Slot-Datei »%s« hat falsche Länge %u" -#: replication/slot.c:2814 +#: replication/slot.c:2810 #, c-format msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" msgstr "Prüfsummenfehler bei Replikations-Slot-Datei »%s«: ist %u, sollte %u sein" -#: replication/slot.c:2850 +#: replication/slot.c:2846 #, fuzzy, c-format #| msgid "logical replication slot \"%s\" exists, but \"wal_level\" < \"logical\"" msgid "logical replication slot \"%s\" exists, but \"wal_level\" < \"replica\"" msgstr "logischer Replikations-Slot »%s« existiert, aber »wal_level« < »logical«" -#: replication/slot.c:2852 replication/slot.c:2874 +#: replication/slot.c:2848 replication/slot.c:2870 #, c-format msgid "Change \"wal_level\" to be \"replica\" or higher." msgstr "Ändern Sie »wal_level« in »replica« oder höher." -#: replication/slot.c:2865 +#: replication/slot.c:2861 #, c-format msgid "logical replication slot \"%s\" exists on the standby, but \"hot_standby\" = \"off\"" msgstr "logischer Replikations-Slot »%s« existiert auf dem Standby, aber »hot_standby« = »off«" -#: replication/slot.c:2867 +#: replication/slot.c:2863 #, c-format msgid "Change \"hot_standby\" to be \"on\"." msgstr "Ändern Sie »hot_standby« auf »on«." -#: replication/slot.c:2872 +#: replication/slot.c:2868 #, c-format msgid "physical replication slot \"%s\" exists, but \"wal_level\" < \"replica\"" msgstr "physischer Replikations-Slot »%s« existiert, aber »wal_level« < »replica«" -#: replication/slot.c:2927 +#: replication/slot.c:2923 #, c-format msgid "too many replication slots active before shutdown" msgstr "zu viele aktive Replikations-Slots vor dem Herunterfahren" -#: replication/slot.c:2928 +#: replication/slot.c:2924 #, c-format msgid "Increase \"max_replication_slots\" and try again." msgstr "Erhöhen Sie »max_replication_slots« und versuchen Sie es erneut." -#: replication/slot.c:3165 +#: replication/slot.c:3161 #, c-format msgid "replication slot \"%s\" specified in parameter \"%s\" does not exist" msgstr "Replikations-Slot »%s«, der in Parameter »%s« angegeben ist, existiert nicht" -#: replication/slot.c:3167 replication/slot.c:3201 replication/slot.c:3216 +#: replication/slot.c:3163 replication/slot.c:3197 replication/slot.c:3212 #, c-format msgid "Logical replication is waiting on the standby associated with replication slot \"%s\"." msgstr "Logische Replikation wartet auf den Standby, der zum Replikations-Slot »%s« gehört." -#: replication/slot.c:3169 +#: replication/slot.c:3165 #, c-format msgid "Create the replication slot \"%s\" or amend parameter \"%s\"." msgstr "Erzeugen Sie den Replikations-Slot »%s« oder berichtigen Sie den Parameter »%s«." -#: replication/slot.c:3179 +#: replication/slot.c:3175 #, c-format msgid "cannot specify logical replication slot \"%s\" in parameter \"%s\"" msgstr "logischer Replikations-Slot »%s« kann nicht in Parameter »%s« angegeben werden" -#: replication/slot.c:3181 +#: replication/slot.c:3177 #, c-format msgid "Logical replication is waiting for correction on replication slot \"%s\"." msgstr "Logische Replikation wartet auf Korrektur bei Replikations-Slot »%s«." -#: replication/slot.c:3183 +#: replication/slot.c:3179 #, c-format msgid "Remove the logical replication slot \"%s\" from parameter \"%s\"." msgstr "Entfernen Sie den Replikations-Slot »%s« aus dem Parameter »%s«." -#: replication/slot.c:3199 +#: replication/slot.c:3195 #, c-format msgid "physical replication slot \"%s\" specified in parameter \"%s\" has been invalidated" msgstr "der physische Replikations-Slot »%s«, der in Parameter »%s« angegeben wurde, wurde ungültig gemacht" -#: replication/slot.c:3203 +#: replication/slot.c:3199 #, c-format msgid "Drop and recreate the replication slot \"%s\", or amend parameter \"%s\"." msgstr "Löschen Sie den Replikations-Slot »%s« und erzeugen Sie ihn neu, oder berichtigen Sie den Parameter »%s«." -#: replication/slot.c:3214 +#: replication/slot.c:3210 #, c-format msgid "replication slot \"%s\" specified in parameter \"%s\" does not have active_pid" msgstr "der Replikations-Slot »%s«, der in Parameter »%s« angegeben wurde, hat keine active_pid" -#: replication/slot.c:3218 +#: replication/slot.c:3214 #, c-format msgid "Start the standby associated with the replication slot \"%s\", or amend parameter \"%s\"." msgstr "Starten Sie den zum Replikations-Slot »%s« gehörenden Standby oder berichtigen Sie den Parameter »%s«." @@ -27624,260 +27867,261 @@ msgstr "Der Quell-Replikations-Slot wurde während der Kopieroperation ungültig msgid "replication slots can only be synchronized to a standby server" msgstr "Replikations-Slots können nur zu einem Standby-Server synchronisiert werden" -#: replication/syncrep.c:306 replication/syncrep.c:313 +#: replication/syncrep.c:306 replication/syncrep.c:314 #, c-format msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" msgstr "Warten auf synchrone Replikation wird storniert and Verbindung wird abgebrochen, aufgrund von Anweisung des Administrators" -#: replication/syncrep.c:307 +#: replication/syncrep.c:307 replication/syncrep.c:315 +#: replication/syncrep.c:332 +#, c-format +msgid "The transaction has already committed locally, but might not have been replicated to the standby." +msgstr "Die Transaktion wurde lokal bereits committet, aber möglicherweise noch nicht zum Standby repliziert." + +#: replication/syncrep.c:308 #, fuzzy, c-format #| msgid "The transaction has already committed locally, but might not have been replicated to the standby." msgid "The transaction has already committed locally, but might not have been replicated to the standby. Signal sent by PID %d, UID %d." msgstr "Die Transaktion wurde lokal bereits committet, aber möglicherweise noch nicht zum Standby repliziert." -#: replication/syncrep.c:314 replication/syncrep.c:331 -#, c-format -msgid "The transaction has already committed locally, but might not have been replicated to the standby." -msgstr "Die Transaktion wurde lokal bereits committet, aber möglicherweise noch nicht zum Standby repliziert." - -#: replication/syncrep.c:330 +#: replication/syncrep.c:331 #, c-format msgid "canceling wait for synchronous replication due to user request" msgstr "storniere Warten auf synchrone Replikation wegen Benutzeraufforderung" -#: replication/syncrep.c:537 +#: replication/syncrep.c:538 #, c-format msgid "standby \"%s\" is now a synchronous standby with priority %d" msgstr "Standby »%s« ist jetzt ein synchroner Standby mit Priorität %d" -#: replication/syncrep.c:541 +#: replication/syncrep.c:542 #, c-format msgid "standby \"%s\" is now a candidate for quorum synchronous standby" msgstr "Standby »%s« ist jetzt ein Kandidat für synchroner Standby mit Quorum" #. translator: %s is a GUC name -#: replication/syncrep.c:1090 +#: replication/syncrep.c:1091 #, c-format msgid "\"%s\" parser failed." msgstr "Parser für »%s« fehlgeschlagen." -#: replication/syncrep.c:1097 +#: replication/syncrep.c:1098 #, c-format msgid "number of synchronous standbys (%d) must be greater than zero" msgstr "Anzahl synchroner Standbys (%d) muss größer als null sein" -#: replication/walreceiver.c:276 +#: replication/walreceiver.c:290 #, c-format msgid "streaming replication receiver \"%s\" could not connect to the primary server: %s" msgstr "Streaming-Replication-Receiver »%s« konnte nicht mit dem Primärserver verbinden: %s" -#: replication/walreceiver.c:324 +#: replication/walreceiver.c:335 #, c-format msgid "database system identifier differs between the primary and standby" msgstr "Datenbanksystemidentifikator unterscheidet sich zwischen Primär- und Standby-Server" -#: replication/walreceiver.c:325 +#: replication/walreceiver.c:336 #, c-format msgid "The primary's identifier is %s, the standby's identifier is %s." msgstr "Identifikator des Primärservers ist %s, Identifikator des Standby ist %s." -#: replication/walreceiver.c:336 +#: replication/walreceiver.c:348 #, c-format msgid "highest timeline %u of the primary is behind recovery timeline %u" msgstr "höchste Zeitleiste %u des primären Servers liegt hinter Wiederherstellungszeitleiste %u zurück" -#: replication/walreceiver.c:389 +#: replication/walreceiver.c:401 #, fuzzy, c-format #| msgid "started streaming WAL from primary at %X/%X on timeline %u" msgid "started streaming WAL from primary at %X/%08X on timeline %u" msgstr "WAL-Streaming vom Primärserver gestartet bei %X/%X auf Zeitleiste %u" -#: replication/walreceiver.c:393 +#: replication/walreceiver.c:405 #, fuzzy, c-format #| msgid "restarted WAL streaming at %X/%X on timeline %u" msgid "restarted WAL streaming at %X/%08X on timeline %u" msgstr "WAL-Streaming neu gestartet bei %X/%X auf Zeitleiste %u" -#: replication/walreceiver.c:439 +#: replication/walreceiver.c:450 #, c-format msgid "cannot continue WAL streaming, recovery has already ended" msgstr "kann WAL-Streaming nicht fortsetzen, Wiederherstellung ist bereits beendet" -#: replication/walreceiver.c:483 +#: replication/walreceiver.c:494 #, c-format msgid "replication terminated by primary server" msgstr "Replikation wurde durch Primärserver beendet" -#: replication/walreceiver.c:484 +#: replication/walreceiver.c:495 #, fuzzy, c-format #| msgid "End of WAL reached on timeline %u at %X/%X." msgid "End of WAL reached on timeline %u at %X/%08X." msgstr "WAL-Ende erreicht auf Zeitleiste %u bei %X/%X." -#: replication/walreceiver.c:584 +#: replication/walreceiver.c:595 #, c-format msgid "terminating walreceiver due to timeout" msgstr "WAL-Receiver-Prozess wird abgebrochen wegen Zeitüberschreitung" -#: replication/walreceiver.c:616 +#: replication/walreceiver.c:627 #, c-format msgid "primary server contains no more WAL on requested timeline %u" msgstr "Primärserver enthält kein WAL mehr auf angeforderter Zeitleiste %u" -#: replication/walreceiver.c:632 replication/walreceiver.c:1092 +#: replication/walreceiver.c:643 replication/walreceiver.c:1098 #, c-format msgid "could not close WAL segment %s: %m" msgstr "konnte WAL-Segment %s nicht schließen: %m" -#: replication/walreceiver.c:751 +#: replication/walreceiver.c:762 #, c-format msgid "fetching timeline history file for timeline %u from primary server" msgstr "hole Zeitleisten-History-Datei für Zeitleiste %u vom Primärserver" -#: replication/walreceiver.c:963 +#: replication/walreceiver.c:971 #, fuzzy, c-format #| msgid "could not write to WAL segment %s at offset %d, length %lu: %m" msgid "could not write to WAL segment %s at offset %d, length %d: %m" msgstr "konnte nicht in WAL-Segment %s bei Position %d, Länge %lu schreiben: %m" -#: replication/walsender.c:546 +#: replication/walsender.c:553 #, c-format msgid "cannot use %s with a logical replication slot" msgstr "%s kann nicht mit einem logischem Replikations-Slot verwendet werden" -#: replication/walsender.c:651 storage/smgr/md.c:1892 +#: replication/walsender.c:658 storage/smgr/md.c:1892 #, c-format msgid "could not seek to end of file \"%s\": %m" msgstr "konnte Positionszeiger nicht ans Ende der Datei »%s« setzen: %m" -#: replication/walsender.c:655 +#: replication/walsender.c:662 #, c-format msgid "could not seek to beginning of file \"%s\": %m" msgstr "konnte Positionszeiger nicht den Anfang der Datei »%s« setzen: %m" -#: replication/walsender.c:871 +#: replication/walsender.c:878 #, c-format msgid "cannot use a logical replication slot for physical replication" msgstr "logischer Replikations-Slot kann nicht für physische Replikation verwendet werden" -#: replication/walsender.c:937 +#: replication/walsender.c:944 #, fuzzy, c-format #| msgid "requested starting point %X/%X on timeline %u is not in this server's history" msgid "requested starting point %X/%08X on timeline %u is not in this server's history" msgstr "angeforderter Startpunkt %X/%X auf Zeitleiste %u ist nicht in der History dieses Servers" -#: replication/walsender.c:940 +#: replication/walsender.c:947 #, fuzzy, c-format #| msgid "This server's history forked from timeline %u at %X/%X." msgid "This server's history forked from timeline %u at %X/%08X." msgstr "Die History dieses Servers zweigte von Zeitleiste %u bei %X/%X ab." -#: replication/walsender.c:984 +#: replication/walsender.c:991 #, fuzzy, c-format #| msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" msgid "requested starting point %X/%08X is ahead of the WAL flush position of this server %X/%08X" msgstr "angeforderter Startpunkt %X/%X ist vor der WAL-Flush-Position dieses Servers %X/%X" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1286 +#: replication/walsender.c:1315 #, c-format msgid "%s must not be called inside a transaction" msgstr "%s darf nicht in einer Transaktion aufgerufen werden" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1296 +#: replication/walsender.c:1325 #, c-format msgid "%s must be called inside a transaction" msgstr "%s muss in einer Transaktion aufgerufen werden" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1302 +#: replication/walsender.c:1331 #, c-format msgid "%s must be called in REPEATABLE READ isolation mode transaction" msgstr "%s muss in einer Transaktion im Isolationsmodus REPEATABLE READ aufgerufen werden" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1307 +#: replication/walsender.c:1336 #, c-format msgid "%s must be called in a read-only transaction" msgstr "%s muss in einer Read-Only-Transaktion aufgerufen werden" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1313 +#: replication/walsender.c:1342 #, c-format msgid "%s must be called before any query" msgstr "%s muss vor allen Anfragen aufgerufen werden" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1319 +#: replication/walsender.c:1348 #, c-format msgid "%s must not be called in a subtransaction" msgstr "%s darf nicht in einer Subtransaktion aufgerufen werden" -#: replication/walsender.c:1505 +#: replication/walsender.c:1534 #, c-format msgid "terminating walsender process after promotion" msgstr "WAL-Sender-Prozess wird nach Beförderung abgebrochen" -#: replication/walsender.c:2084 +#: replication/walsender.c:2113 #, c-format msgid "cannot execute new commands while WAL sender is in stopping mode" msgstr "während der WAL-Sender im Stoppmodus ist können keine neuen Befehle ausgeführt werden" -#: replication/walsender.c:2138 +#: replication/walsender.c:2167 #, c-format msgid "cannot execute SQL commands in WAL sender for physical replication" msgstr "im WAL-Sender für physische Replikation können keine SQL-Befehle ausgeführt werden" -#: replication/walsender.c:2169 +#: replication/walsender.c:2198 #, c-format msgid "received replication command: %s" msgstr "Replikationsbefehl empfangen: %s" -#: replication/walsender.c:2177 tcop/fastpath.c:208 tcop/postgres.c:1154 -#: tcop/postgres.c:1510 tcop/postgres.c:1761 tcop/postgres.c:2265 -#: tcop/postgres.c:2687 tcop/postgres.c:2763 +#: replication/walsender.c:2206 tcop/fastpath.c:208 tcop/postgres.c:1155 +#: tcop/postgres.c:1511 tcop/postgres.c:1762 tcop/postgres.c:2266 +#: tcop/postgres.c:2688 tcop/postgres.c:2764 #, c-format msgid "current transaction is aborted, commands ignored until end of transaction block" msgstr "aktuelle Transaktion wurde abgebrochen, Befehle werden bis zum Ende der Transaktion ignoriert" -#: replication/walsender.c:2337 replication/walsender.c:2372 +#: replication/walsender.c:2366 replication/walsender.c:2401 #, c-format msgid "unexpected EOF on standby connection" msgstr "unerwartetes EOF auf Standby-Verbindung" -#: replication/walsender.c:2360 +#: replication/walsender.c:2389 #, c-format msgid "invalid standby message type \"%c\"" msgstr "ungültiger Standby-Message-Typ »%c«" -#: replication/walsender.c:2456 +#: replication/walsender.c:2485 #, c-format msgid "unexpected message type \"%c\"" msgstr "unerwarteter Message-Typ »%c«" -#: replication/walsender.c:2954 +#: replication/walsender.c:2983 #, c-format msgid "terminating walsender process due to replication timeout" msgstr "WAL-Sender-Prozess wird abgebrochen wegen Zeitüberschreitung bei der Replikation" -#: replication/walsender.c:3745 +#: replication/walsender.c:3776 #, fuzzy, c-format #| msgid "terminating walsender process due to replication timeout" msgid "terminating walsender process due to replication shutdown timeout" msgstr "WAL-Sender-Prozess wird abgebrochen wegen Zeitüberschreitung bei der Replikation" -#: replication/walsender.c:3746 +#: replication/walsender.c:3777 #, c-format msgid "Walsender process might have been terminated before all WAL data was replicated to the receiver." msgstr "" -#: rewrite/rewriteDefine.c:104 rewrite/rewriteDefine.c:834 +#: rewrite/rewriteDefine.c:104 rewrite/rewriteDefine.c:819 #, c-format msgid "rule \"%s\" for relation \"%s\" already exists" msgstr "Regel »%s« für Relation »%s« existiert bereits" -#: rewrite/rewriteDefine.c:261 rewrite/rewriteDefine.c:772 +#: rewrite/rewriteDefine.c:261 rewrite/rewriteDefine.c:757 #, c-format msgid "relation \"%s\" cannot have rules" msgstr "Relation »%s« kann keine Regeln haben" @@ -27942,135 +28186,135 @@ msgstr "Ereignisqualifikationen sind nicht implementiert für SELECT-Regeln" msgid "\"%s\" is already a view" msgstr "»%s« ist bereits eine Sicht" -#: rewrite/rewriteDefine.c:408 +#: rewrite/rewriteDefine.c:395 #, c-format msgid "view rule for \"%s\" must be named \"%s\"" msgstr "Sicht-Regel für »%s« muss »%s« heißen" -#: rewrite/rewriteDefine.c:435 +#: rewrite/rewriteDefine.c:420 #, c-format msgid "cannot have multiple RETURNING lists in a rule" msgstr "Regel kann nicht mehrere RETURNING-Listen enthalten" -#: rewrite/rewriteDefine.c:440 +#: rewrite/rewriteDefine.c:425 #, c-format msgid "RETURNING lists are not supported in conditional rules" msgstr "RETURNING-Listen werden in Regeln mit Bedingung nicht unterstützt" -#: rewrite/rewriteDefine.c:444 +#: rewrite/rewriteDefine.c:429 #, c-format msgid "RETURNING lists are not supported in non-INSTEAD rules" msgstr "RETURNING-Listen werden nur in INSTEAD-Regeln unterstützt" -#: rewrite/rewriteDefine.c:458 +#: rewrite/rewriteDefine.c:443 rewrite/rewriteDefine.c:838 #, c-format msgid "non-view rule for \"%s\" must not be named \"%s\"" msgstr "Nicht-Sicht-Regel für »%s« darf nicht »%s« heißen" -#: rewrite/rewriteDefine.c:532 +#: rewrite/rewriteDefine.c:517 #, c-format msgid "SELECT rule's target list has too many entries" msgstr "Targetliste von SELECT-Regel hat zu viele Einträge" -#: rewrite/rewriteDefine.c:533 +#: rewrite/rewriteDefine.c:518 #, c-format msgid "RETURNING list has too many entries" msgstr "RETURNING-Liste hat zu viele Einträge" -#: rewrite/rewriteDefine.c:560 +#: rewrite/rewriteDefine.c:545 #, c-format msgid "cannot convert relation containing dropped columns to view" msgstr "kann Relation mit gelöschten Spalten nicht in Sicht umwandeln" -#: rewrite/rewriteDefine.c:561 +#: rewrite/rewriteDefine.c:546 #, c-format msgid "cannot create a RETURNING list for a relation containing dropped columns" msgstr "für eine Relation mit gelöschten Spalten kann keine RETURNING-Liste erzeugt werden" -#: rewrite/rewriteDefine.c:567 +#: rewrite/rewriteDefine.c:552 #, c-format msgid "SELECT rule's target entry %d has different column name from column \"%s\"" msgstr "Spaltenname in Targeteintrag %d von SELECT-Regel unterscheidet sich von Spalte »%s«" -#: rewrite/rewriteDefine.c:569 +#: rewrite/rewriteDefine.c:554 #, c-format msgid "SELECT target entry is named \"%s\"." msgstr "SELECT-Targeteintrag heißt »%s«." -#: rewrite/rewriteDefine.c:578 +#: rewrite/rewriteDefine.c:563 #, c-format msgid "SELECT rule's target entry %d has different type from column \"%s\"" msgstr "Typ von Targeteintrag %d von SELECT-Regel unterscheidet sich von Spalte »%s«" -#: rewrite/rewriteDefine.c:580 +#: rewrite/rewriteDefine.c:565 #, c-format msgid "RETURNING list's entry %d has different type from column \"%s\"" msgstr "Eintrag %d in RETURNING-Liste hat anderen Typ als Spalte »%s«" -#: rewrite/rewriteDefine.c:583 rewrite/rewriteDefine.c:607 +#: rewrite/rewriteDefine.c:568 rewrite/rewriteDefine.c:592 #, c-format msgid "SELECT target entry has type %s, but column has type %s." msgstr "SELECT-Targeteintrag hat Typ %s, aber Spalte hat Typ %s." -#: rewrite/rewriteDefine.c:586 rewrite/rewriteDefine.c:611 +#: rewrite/rewriteDefine.c:571 rewrite/rewriteDefine.c:596 #, c-format msgid "RETURNING list entry has type %s, but column has type %s." msgstr "Eintrag in RETURNING-Liste hat Typ %s, aber Spalte hat Typ %s." -#: rewrite/rewriteDefine.c:602 +#: rewrite/rewriteDefine.c:587 #, c-format msgid "SELECT rule's target entry %d has different size from column \"%s\"" msgstr "Größe von Targeteintrag %d von SELECT-Regel unterscheidet sich von Spalte »%s«" -#: rewrite/rewriteDefine.c:604 +#: rewrite/rewriteDefine.c:589 #, c-format msgid "RETURNING list's entry %d has different size from column \"%s\"" msgstr "Eintrag %d in RETURNING-Liste hat andere Größe als Spalte »%s«" -#: rewrite/rewriteDefine.c:621 +#: rewrite/rewriteDefine.c:606 #, c-format msgid "SELECT rule's target list has too few entries" msgstr "Targetliste von SELECT-Regeln hat zu wenige Einträge" -#: rewrite/rewriteDefine.c:622 +#: rewrite/rewriteDefine.c:607 #, c-format msgid "RETURNING list has too few entries" msgstr "RETURNING-Liste hat zu wenige Einträge" -#: rewrite/rewriteDefine.c:711 rewrite/rewriteDefine.c:825 +#: rewrite/rewriteDefine.c:696 rewrite/rewriteDefine.c:810 #: rewrite/rewriteSupport.c:108 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist" msgstr "Regel »%s« für Relation »%s« existiert nicht" -#: rewrite/rewriteDefine.c:844 +#: rewrite/rewriteDefine.c:829 #, c-format msgid "renaming an ON SELECT rule is not allowed" msgstr "Umbenennen einer ON-SELECT-Regel ist nicht erlaubt" -#: rewrite/rewriteGraphTable.c:211 +#: rewrite/rewriteGraphTable.c:212 #, c-format msgid "element patterns with same variable name \"%s\" but different element pattern types" msgstr "" -#: rewrite/rewriteGraphTable.c:228 +#: rewrite/rewriteGraphTable.c:229 #, fuzzy, c-format #| msgid "using variable \"%s\" in different declare statements is not supported" msgid "element patterns with same variable name \"%s\" but different label expressions are not supported" msgstr "Verwendung der Variable »%s« in verschiedenen DECLARE-Anweisungen wird nicht unterstützt" -#: rewrite/rewriteGraphTable.c:291 rewrite/rewriteGraphTable.c:300 -#: rewrite/rewriteGraphTable.c:315 rewrite/rewriteGraphTable.c:324 +#: rewrite/rewriteGraphTable.c:292 rewrite/rewriteGraphTable.c:301 +#: rewrite/rewriteGraphTable.c:316 rewrite/rewriteGraphTable.c:325 #, c-format -msgid "an edge cannot connect more than two vertexes even in a cyclic pattern" +msgid "an edge cannot connect more than two vertices even in a cyclic pattern" msgstr "" -#: rewrite/rewriteGraphTable.c:976 +#: rewrite/rewriteGraphTable.c:990 #, c-format msgid "no property graph element of type \"%s\" has label \"%s\" associated with it in property graph \"%s\"" msgstr "" -#: rewrite/rewriteGraphTable.c:1131 +#: rewrite/rewriteGraphTable.c:1145 #, fuzzy, c-format #| msgid "policy \"%s\" for table \"%s\" does not exist" msgid "property \"%s\" for element variable \"%s\" not found" @@ -28131,7 +28375,7 @@ msgstr "MERGE wird für Relationen mit Regeln nicht unterstützt." msgid "access to non-system view \"%s\" is restricted" msgstr "Zugriff auf Nicht-System-Sicht »%s« ist beschränkt" -#: rewrite/rewriteHandler.c:2192 rewrite/rewriteHandler.c:4449 +#: rewrite/rewriteHandler.c:2192 rewrite/rewriteHandler.c:4496 #, c-format msgid "infinite recursion detected in rules for relation \"%s\"" msgstr "unendliche Rekursion entdeckt in Regeln für Relation »%s«" @@ -28256,7 +28500,7 @@ msgstr "Um Löschen aus der Sicht zu ermöglichen, richten Sie einen INSTEAD OF msgid "cannot insert into column \"%s\" of view \"%s\"" msgstr "kann nicht in Spalte »%s« von Sicht »%s« einfügen" -#: rewrite/rewriteHandler.c:3463 +#: rewrite/rewriteHandler.c:3463 rewrite/rewriteHandler.c:3510 #, c-format msgid "cannot update column \"%s\" of view \"%s\"" msgstr "kann Spalte »%s« von Sicht »%s« nicht aktualisieren" @@ -28266,86 +28510,92 @@ msgstr "kann Spalte »%s« von Sicht »%s« nicht aktualisieren" msgid "cannot merge into column \"%s\" of view \"%s\"" msgstr "kann nicht in Spalte »%s« von Sicht »%s« mergen" -#: rewrite/rewriteHandler.c:3499 +#: rewrite/rewriteHandler.c:3518 +#, fuzzy, c-format +#| msgid "cannot delete from view \"%s\"" +msgid "cannot delete from view \"%s\" using FOR PORTION OF \"%s\"" +msgstr "kann nicht aus Sicht »%s« löschen" + +#: rewrite/rewriteHandler.c:3546 #, c-format msgid "cannot merge into view \"%s\"" msgstr "kann nicht in Sicht »%s« mergen" -#: rewrite/rewriteHandler.c:3501 +#: rewrite/rewriteHandler.c:3548 #, c-format msgid "MERGE is not supported for views with INSTEAD OF triggers for some actions but not all." msgstr "MERGE wird nicht unterstützt für Sichten mit INSTEAD-OF-Trigger für einige Aktionen aber nicht für alle." -#: rewrite/rewriteHandler.c:3502 +#: rewrite/rewriteHandler.c:3549 #, c-format msgid "To enable merging into the view, either provide a full set of INSTEAD OF triggers or drop the existing INSTEAD OF triggers." msgstr "Um Mergen in die Sicht zu ermöglichen, richten Sie entweder einen vollen Satz an INSTEAD-OF-Triggern ein oder löschen Sie die bestehenden INSTEAD-OF-Trigger." -#: rewrite/rewriteHandler.c:4057 +#: rewrite/rewriteHandler.c:4104 #, c-format msgid "DO INSTEAD NOTIFY rules are not supported for data-modifying statements in WITH" msgstr "DO-INSTEAD-NOTIFY-Regeln werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" -#: rewrite/rewriteHandler.c:4068 +#: rewrite/rewriteHandler.c:4115 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" msgstr "DO-INSTEAD-NOTHING-Regeln werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" -#: rewrite/rewriteHandler.c:4082 +#: rewrite/rewriteHandler.c:4129 #, c-format msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "DO-INSTEAD-Regeln mit Bedingung werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" -#: rewrite/rewriteHandler.c:4086 +#: rewrite/rewriteHandler.c:4133 #, c-format msgid "DO ALSO rules are not supported for data-modifying statements in WITH" msgstr "DO-ALSO-Regeln werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" -#: rewrite/rewriteHandler.c:4091 +#: rewrite/rewriteHandler.c:4138 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "DO-INSTEAD-Regeln mit mehreren Anweisungen werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" -#: rewrite/rewriteHandler.c:4401 +#: rewrite/rewriteHandler.c:4448 msgid "Views with conditional DO INSTEAD rules are not automatically updatable." msgstr "Sichten mit DO-INSTEAD-Regeln mit Bedingung sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:4499 +#: rewrite/rewriteHandler.c:4546 #, c-format msgid "cannot perform INSERT RETURNING on relation \"%s\"" msgstr "INSERT RETURNING kann in Relation »%s« nicht ausgeführt werden" -#: rewrite/rewriteHandler.c:4501 +#: rewrite/rewriteHandler.c:4548 #, c-format msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." msgstr "Sie benötigen eine ON INSERT DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." -#: rewrite/rewriteHandler.c:4506 +#: rewrite/rewriteHandler.c:4553 #, c-format msgid "cannot perform UPDATE RETURNING on relation \"%s\"" msgstr "UPDATE RETURNING kann in Relation »%s« nicht ausgeführt werden" -#: rewrite/rewriteHandler.c:4508 +#: rewrite/rewriteHandler.c:4555 #, c-format msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." msgstr "Sie benötigen eine ON UPDATE DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." -#: rewrite/rewriteHandler.c:4513 +#: rewrite/rewriteHandler.c:4560 #, c-format msgid "cannot perform DELETE RETURNING on relation \"%s\"" msgstr "DELETE RETURNING kann in Relation »%s« nicht ausgeführt werden" -#: rewrite/rewriteHandler.c:4515 +#: rewrite/rewriteHandler.c:4562 #, c-format msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." msgstr "Sie benötigen eine ON DELETE DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." -#: rewrite/rewriteHandler.c:4533 +#: rewrite/rewriteHandler.c:4580 #, c-format msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" msgstr "INSERT mit ON-CONFLICT-Klausel kann nicht mit Tabelle verwendet werden, die INSERT- oder UPDATE-Regeln hat" -#: rewrite/rewriteHandler.c:4590 +#: rewrite/rewriteHandler.c:4637 #, c-format msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" msgstr "WITH kann nicht in einer Anfrage verwendet werden, die durch Regeln in mehrere Anfragen umgeschrieben wird" @@ -28470,8 +28720,8 @@ msgstr "unbekannter Snowball-Parameter: »%s«" msgid "missing Language parameter" msgstr "Parameter »Language« fehlt" -#: statistics/attribute_stats.c:181 statistics/attribute_stats.c:603 -#: statistics/extended_stats_funcs.c:371 statistics/extended_stats_funcs.c:1748 +#: statistics/attribute_stats.c:181 statistics/attribute_stats.c:620 +#: statistics/extended_stats_funcs.c:371 statistics/extended_stats_funcs.c:1779 #: statistics/relation_stats.c:98 #, c-format msgid "Statistics cannot be modified during recovery." @@ -28513,7 +28763,13 @@ msgstr "konnte Kleiner-Als-Operator für Spalte »%s« nicht bestimmen" msgid "column \"%s\" is not a range type" msgstr "Spalte »%s« ist kein Range-Typ" -#: statistics/attribute_stats.c:615 +#: statistics/attribute_stats.c:385 statistics/extended_stats_funcs.c:1359 +#, fuzzy, c-format +#| msgid "could not parse numeric array \"%s\": invalid character in number" +msgid "could not parse \"%s\": incorrect number of elements (same as \"%s\" required)" +msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" + +#: statistics/attribute_stats.c:632 #, c-format msgid "cannot clear statistics on system column \"%s\"" msgstr "Statistiken für Systemspalte »%s« können nicht geleert werden" @@ -28529,13 +28785,13 @@ msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zah msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" msgstr "Statistikobjekt »%s.%s« konnte für Relation »%s.%s« nicht berechnet werden" -#: statistics/extended_stats_funcs.c:404 statistics/extended_stats_funcs.c:1768 +#: statistics/extended_stats_funcs.c:404 statistics/extended_stats_funcs.c:1799 #, fuzzy, c-format #| msgid "could not find WAL file \"%s\"" msgid "could not find schema \"%s\"" msgstr "konnte WAL-Datei »%s« nicht finden" -#: statistics/extended_stats_funcs.c:416 statistics/extended_stats_funcs.c:1780 +#: statistics/extended_stats_funcs.c:416 statistics/extended_stats_funcs.c:1811 #, fuzzy, c-format #| msgid "could not find index attname \"%s\"" msgid "could not find extended statistics object \"%s.%s\"" @@ -28564,12 +28820,12 @@ msgstr "Statistikobjekt »%s.%s« existiert nicht, wird übersprungen" #: statistics/extended_stats_funcs.c:523 #, fuzzy, c-format #| msgid "must specify either \"%s\" or \"%s\"" -msgid "cannot specify parameters \"%s\", \"%s\" or \"%s\"" +msgid "cannot specify parameters \"%s\", \"%s\", or \"%s\"" msgstr "entweder »%s« oder »%s« muss angegeben werden" #: statistics/extended_stats_funcs.c:547 #, c-format -msgid "could not use \"%s\", \"%s\" and \"%s\": missing one or more parameters" +msgid "could not use \"%s\", \"%s\", and \"%s\": missing one or more parameters" msgstr "" #: statistics/extended_stats_funcs.c:780 statistics/extended_stats_funcs.c:833 @@ -28595,73 +28851,85 @@ msgstr "" msgid "could not parse array \"%s\": found %d attributes but expected %d" msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" -#: statistics/extended_stats_funcs.c:951 +#: statistics/extended_stats_funcs.c:863 +#, fuzzy, c-format +#| msgid "could not parse numeric array \"%s\": invalid character in number" +msgid "could not parse array \"%s\": number of items (%d) exceeds maximum (%d)" +msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" + +#: statistics/extended_stats_funcs.c:967 #, c-format msgid "could not import element in expression %d: invalid key name" msgstr "" -#: statistics/extended_stats_funcs.c:1077 +#: statistics/extended_stats_funcs.c:1082 +#, fuzzy, c-format +#| msgid "thresholds must be one-dimensional array" +msgid "could not import element \"%s\" in expression %d: must be a one-dimensional array" +msgstr "Parameter »thresholds« muss ein eindimensionales Array sein" + +#: statistics/extended_stats_funcs.c:1091 #, c-format msgid "could not import element \"%s\" in expression %d: null value found" msgstr "" -#: statistics/extended_stats_funcs.c:1122 -#: statistics/extended_stats_funcs.c:1152 -#: statistics/extended_stats_funcs.c:1172 -#: statistics/extended_stats_funcs.c:1183 -#: statistics/extended_stats_funcs.c:1200 -#: statistics/extended_stats_funcs.c:1628 +#: statistics/extended_stats_funcs.c:1136 +#: statistics/extended_stats_funcs.c:1166 +#: statistics/extended_stats_funcs.c:1186 +#: statistics/extended_stats_funcs.c:1197 +#: statistics/extended_stats_funcs.c:1214 +#: statistics/extended_stats_funcs.c:1659 #, fuzzy, c-format #| msgid "could not parse numeric array \"%s\": invalid character in number" msgid "could not parse \"%s\": invalid element in expression %d" msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" -#: statistics/extended_stats_funcs.c:1153 +#: statistics/extended_stats_funcs.c:1167 #, fuzzy, c-format #| msgid "field \"%s\" must be an array of strings" -msgid "Value of element \"%s\" must be type a null or a string." +msgid "Value of element \"%s\" must be a null or a string." msgstr "Feld »%s« muss ein Array von Zeichenketten sein" -#: statistics/extended_stats_funcs.c:1174 -#: statistics/extended_stats_funcs.c:1185 +#: statistics/extended_stats_funcs.c:1188 +#: statistics/extended_stats_funcs.c:1199 #, c-format msgid "\"%s\" and \"%s\" must be both either strings or nulls." msgstr "" -#: statistics/extended_stats_funcs.c:1202 +#: statistics/extended_stats_funcs.c:1216 #, c-format msgid "\"%s\", \"%s\", and \"%s\" must be all either strings or all nulls." msgstr "" -#: statistics/extended_stats_funcs.c:1234 +#: statistics/extended_stats_funcs.c:1248 #, fuzzy, c-format #| msgid "could not parse numeric array \"%s\": invalid character in number" msgid "could not parse \"%s\": invalid element type in expression %d" msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" -#: statistics/extended_stats_funcs.c:1253 +#: statistics/extended_stats_funcs.c:1267 #, fuzzy, c-format #| msgid "could not parse numeric array \"%s\": invalid character in number" msgid "could not parse \"%s\": invalid data in expression %d" msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" -#: statistics/extended_stats_funcs.c:1255 +#: statistics/extended_stats_funcs.c:1269 #, c-format msgid "\"%s\", \"%s\", and \"%s\" can only be set for a range type." msgstr "" -#: statistics/extended_stats_funcs.c:1553 +#: statistics/extended_stats_funcs.c:1584 #, fuzzy, c-format #| msgid "could not parse %s array" msgid "could not parse \"%s\": root-level array required" msgstr "konnte %s-Array nicht interpretieren" -#: statistics/extended_stats_funcs.c:1568 +#: statistics/extended_stats_funcs.c:1599 #, c-format msgid "could not parse \"%s\": incorrect number of elements (%d required)" msgstr "" -#: statistics/extended_stats_funcs.c:1796 +#: statistics/extended_stats_funcs.c:1828 #, fuzzy, c-format #| msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" msgid "could not clear extended statistics object \"%s.%s\": incorrect relation \"%s.%s\" specified" @@ -28734,12 +29002,12 @@ msgstr "unbekannter Argumentname »%s«" msgid "argument \"%s\" has type %s, expected type %s" msgstr "Argument »%s« hat Typ %s, erwarteter Typ %s" -#: statistics/stat_utils.c:372 utils/adt/ddlutils.c:141 +#: statistics/stat_utils.c:372 #, c-format msgid "variadic arguments must be name/value pairs" msgstr "variadische Argumente müssen Name/Wert-Paare sein" -#: statistics/stat_utils.c:373 utils/adt/ddlutils.c:142 +#: statistics/stat_utils.c:373 #, c-format msgid "Provide an even number of variadic arguments that can be divided into pairs." msgstr "Geben Sie eine gerade Anzahl variadischer Argumente an, die in Paare aufgeteilt werden können." @@ -28754,12 +29022,18 @@ msgstr "Name auf variadischer Position %d ist NULL" msgid "name at variadic position %d has type %s, expected type %s" msgstr "Name auf variadischer Position %d hat Typ %s, erwarteter Typ %s" -#: statistics/stat_utils.c:607 +#: statistics/stat_utils.c:596 +#, fuzzy, c-format +#| msgid "thresholds must be one-dimensional array" +msgid "\"%s\" must be a one-dimensional array" +msgstr "Parameter »thresholds« muss ein eindimensionales Array sein" + +#: statistics/stat_utils.c:605 #, c-format msgid "\"%s\" array must not contain null values" msgstr "»%s«-Array darf keine NULL-Werte enthalten" -#: statistics/stat_utils.c:665 +#: statistics/stat_utils.c:663 #, c-format msgid "maximum number of statistics slots exceeded: %d" msgstr "maximale Anzahl Statistik-Slots überschritten: %d" @@ -28797,99 +29071,101 @@ msgstr "komplettiere I/O für Prozess %d" msgid "I/O worker executing I/O on behalf of process %d" msgstr "I/O-Worker, der I/O für Prozess %d ausführt" -#: storage/buffer/bufmgr.c:798 storage/buffer/bufmgr.c:939 +#: storage/aio/read_stream.c:787 storage/buffer/bufmgr.c:798 +#: storage/buffer/bufmgr.c:1296 storage/buffer/bufmgr.c:1392 +#: storage/buffer/bufmgr.c:2781 #, c-format msgid "cannot access temporary tables of other sessions" msgstr "auf temporäre Tabellen anderer Sitzungen kann nicht zugegriffen werden" -#: storage/buffer/bufmgr.c:2879 storage/buffer/localbuf.c:403 +#: storage/buffer/bufmgr.c:2902 storage/buffer/localbuf.c:403 #, c-format msgid "cannot extend relation %s beyond %u blocks" msgstr "kann Relation %s nicht auf über %u Blöcke erweitern" -#: storage/buffer/bufmgr.c:2943 +#: storage/buffer/bufmgr.c:2966 #, c-format msgid "unexpected data beyond EOF in block %u of relation \"%s\"" msgstr "unerwartete Daten hinter Dateiende in Block %u von Relation »%s«" -#: storage/buffer/bufmgr.c:7444 +#: storage/buffer/bufmgr.c:7493 #, c-format msgid "could not write block %u of %s" msgstr "konnte Block %u von %s nicht schreiben" -#: storage/buffer/bufmgr.c:7448 +#: storage/buffer/bufmgr.c:7497 #, c-format msgid "Multiple failures --- write error might be permanent." msgstr "Mehrere Fehlschläge --- Schreibfehler ist möglicherweise dauerhaft." -#: storage/buffer/bufmgr.c:7465 storage/buffer/bufmgr.c:7480 +#: storage/buffer/bufmgr.c:7514 storage/buffer/bufmgr.c:7529 #, c-format msgid "writing block %u of relation \"%s\"" msgstr "schreibe Block %u von Relation »%s«" -#: storage/buffer/bufmgr.c:8819 +#: storage/buffer/bufmgr.c:8868 #, c-format msgid "zeroing %u page(s) and ignoring %u checksum failure(s) among blocks %u..%u of relation \"%s\"" msgstr "%u Seite(n) werden mit Nullen gefüllt und %u Prüfsummenfehler werden ignoriert in den Blöcken %u..%u von Relation »%s«" -#: storage/buffer/bufmgr.c:8822 storage/buffer/bufmgr.c:8850 +#: storage/buffer/bufmgr.c:8871 storage/buffer/bufmgr.c:8899 #, c-format msgid "Block %u held the first zeroed page." msgstr "Block %u enthielt die erste mit Nullen gefüllte Seite." -#: storage/buffer/bufmgr.c:8824 +#: storage/buffer/bufmgr.c:8873 #, c-format msgid "See server log for details about the other %d invalid block." msgid_plural "See server log for details about the other %d invalid blocks." msgstr[0] "Details zu dem anderen %d ungültigen Block finden Sie im Serverlog." msgstr[1] "Details zu den anderen %d ungültigen Blöcken finden Sie im Serverlog." -#: storage/buffer/bufmgr.c:8841 +#: storage/buffer/bufmgr.c:8890 #, c-format msgid "%u invalid pages among blocks %u..%u of relation \"%s\"" msgstr "%u ungültige Seiten in den Blöcken %u..%u von Relation »%s«" -#: storage/buffer/bufmgr.c:8842 +#: storage/buffer/bufmgr.c:8891 #, c-format msgid "Block %u held the first invalid page." msgstr "Block %u enthielt die erste ungültige Seite." -#: storage/buffer/bufmgr.c:8843 +#: storage/buffer/bufmgr.c:8892 #, c-format msgid "See server log for the other %u invalid block(s)." msgstr "Die anderen %u ungültigen Blöcke finden Sie im Serverlog." -#: storage/buffer/bufmgr.c:8848 +#: storage/buffer/bufmgr.c:8897 #, c-format msgid "invalid page in block %u of relation \"%s\"; zeroing out page" msgstr "ungültige Seite in Block %u von Relation »%s«; fülle Seite mit Nullen" -#: storage/buffer/bufmgr.c:8849 +#: storage/buffer/bufmgr.c:8898 #, c-format msgid "zeroing out %u invalid pages among blocks %u..%u of relation \"%s\"" msgstr "%u ungültige Seiten werden mit Nullen gefüllt in den Blöcken %u..%u von Relation »%s«" -#: storage/buffer/bufmgr.c:8851 +#: storage/buffer/bufmgr.c:8900 #, c-format msgid "See server log for the other %u zeroed block(s)." msgstr "Die anderen %u mit Nullen gefüllten Blöcke finden Sie im Serverlog." -#: storage/buffer/bufmgr.c:8856 +#: storage/buffer/bufmgr.c:8905 #, c-format msgid "ignoring checksum failure in block %u of relation \"%s\"" msgstr "Prüfsummenfehler wird ignoriert in Block %u von Relation »%s«" -#: storage/buffer/bufmgr.c:8857 +#: storage/buffer/bufmgr.c:8906 #, c-format msgid "ignoring %u checksum failures among blocks %u..%u of relation \"%s\"" msgstr "%u Prüfsummenfehler werden ignoriert in den Blöcken %u..%u von Relation »%s«" -#: storage/buffer/bufmgr.c:8858 +#: storage/buffer/bufmgr.c:8907 #, c-format msgid "Block %u held the first ignored page." msgstr "Block %u enthielt die erste ignorierte Seite." -#: storage/buffer/bufmgr.c:8859 +#: storage/buffer/bufmgr.c:8908 #, c-format msgid "See server log for the other %u ignored block(s)." msgstr "Die anderen %u ignorierten Blöcke finden Sie im Serverlog." @@ -29060,12 +29336,12 @@ msgstr "synchronisiere Datenverzeichnis (fsync), abgelaufene Zeit: %ld.%02d s, a msgid "\"%s\" is not supported on this platform." msgstr "»%s« wird auf dieser Plattform nicht unterstützt." -#: storage/file/fd.c:4015 tcop/backend_startup.c:1094 +#: storage/file/fd.c:4015 tcop/backend_startup.c:1122 #, c-format msgid "Invalid list syntax in parameter \"%s\"." msgstr "Ungültige Listensyntax für Parameter »%s«." -#: storage/file/fd.c:4035 tcop/backend_startup.c:1068 +#: storage/file/fd.c:4035 tcop/backend_startup.c:1096 #, c-format msgid "Invalid option \"%s\"." msgstr "Ungültige Option »%s«." @@ -29243,44 +29519,44 @@ msgstr "" msgid "sorry, too many clients already" msgstr "tut mir leid, schon zu viele Verbindungen" -#: storage/ipc/procarray.c:3878 +#: storage/ipc/procarray.c:3865 #, c-format msgid "database \"%s\" is being used by prepared transactions" msgstr "Datenbank »%s« wird von vorbereiteten Transaktionen verwendet" -#: storage/ipc/procarray.c:3914 storage/ipc/procarray.c:3922 +#: storage/ipc/procarray.c:3901 storage/ipc/procarray.c:3909 #: storage/ipc/signalfuncs.c:254 storage/ipc/signalfuncs.c:261 #: storage/ipc/signalfuncs.c:268 #, c-format msgid "permission denied to terminate process" msgstr "keine Berechtigung, um Prozess zu beenden" -#: storage/ipc/procarray.c:3915 storage/ipc/signalfuncs.c:255 +#: storage/ipc/procarray.c:3902 storage/ipc/signalfuncs.c:255 #, c-format msgid "Only roles with the %s attribute may terminate processes of roles with the %s attribute." msgstr "Nur Rollen mit dem %s-Attribut können Prozesse von Rollen mit dem %s-Attribut beenden." -#: storage/ipc/procarray.c:3923 storage/ipc/signalfuncs.c:269 +#: storage/ipc/procarray.c:3910 storage/ipc/signalfuncs.c:269 #, c-format msgid "Only roles with privileges of the role whose process is being terminated or with privileges of the \"%s\" role may terminate this process." msgstr "Nur Rollen mit den Privilegien der Rolle deren Prozess beendet werden soll oder den Privilegien der Rolle »%s« können diesen Prozess beenden." -#: storage/ipc/procsignal.c:455 +#: storage/ipc/procsignal.c:463 #, c-format msgid "still waiting for backend with PID %d to accept ProcSignalBarrier" msgstr "warte immer noch darauf, dass Backend mit PID %d ProcSignalBarrier annimmt" -#: storage/ipc/procsignal.c:735 +#: storage/ipc/procsignal.c:743 #, c-format msgid "invalid cancel request with PID 0" msgstr "ungültige Stornierungsanfrage mit PID 0" -#: storage/ipc/procsignal.c:790 +#: storage/ipc/procsignal.c:798 #, c-format msgid "wrong key in cancel request for process %d" msgstr "falscher Schlüssel in Stornierungsanfrage für Prozess %d" -#: storage/ipc/procsignal.c:799 +#: storage/ipc/procsignal.c:807 #, c-format msgid "PID %d in cancel request did not match any process" msgstr "PID %d in Stornierungsanfrage stimmte mit keinem Prozess überein" @@ -29305,50 +29581,45 @@ msgstr "ungültige Nachrichtengröße %zu in Shared-Memory-Queue" msgid "out of shared memory" msgstr "Shared Memory aufgebraucht" -#: storage/ipc/shmem.c:373 +#: storage/ipc/shmem.c:372 #, fuzzy, c-format #| msgid "%s: service \"%s\" already registered\n" msgid "shared memory struct \"%s\" is already registered" msgstr "%s: Systemdienst »%s« ist bereits registriert\n" -#: storage/ipc/shmem.c:530 +#: storage/ipc/shmem.c:529 #, c-format msgid "could not create ShmemIndex entry for data structure \"%s\"" msgstr "konnte ShmemIndex-Eintrag für Datenstruktur »%s« nicht erzeugen" -#: storage/ipc/shmem.c:547 +#: storage/ipc/shmem.c:546 #, fuzzy, c-format #| msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" msgid "not enough shared memory for data structure \"%s\" (%zd bytes requested)" msgstr "nicht genug Shared-Memory für Datenstruktur »%s« (%zu Bytes angefordert)" -#: storage/ipc/shmem.c:593 +#: storage/ipc/shmem.c:592 #, fuzzy, c-format #| msgid "could not create ShmemIndex entry for data structure \"%s\"" msgid "could not find ShmemIndex entry for data structure \"%s\"" msgstr "konnte ShmemIndex-Eintrag für Datenstruktur »%s« nicht erzeugen" -#: storage/ipc/shmem.c:603 +#: storage/ipc/shmem.c:602 #, c-format msgid "shared memory struct \"%s\" was created with different size: existing %zu, requested %zd" msgstr "" -#: storage/ipc/shmem.c:676 storage/ipc/shmem.c:773 +#: storage/ipc/shmem.c:675 storage/ipc/shmem.c:772 #, c-format msgid "out of shared memory (%zu bytes requested)" msgstr "Shared Memory aufgebraucht (%zu Bytes angefordert)" -#: storage/ipc/shmem.c:1055 storage/ipc/shmem.c:1070 -#, c-format -msgid "requested shared memory size overflows size_t" -msgstr "angeforderte Shared-Memory-Größe übersteigt Kapazität von size_t" - #: storage/ipc/signalfuncs.c:75 #, c-format msgid "PID %d is not a PostgreSQL backend process" msgstr "PID %d ist kein PostgreSQL-Backend-Prozess" -#: storage/ipc/signalfuncs.c:121 storage/lmgr/proc.c:1554 +#: storage/ipc/signalfuncs.c:121 storage/lmgr/proc.c:1587 #: utils/adt/mcxtfuncs.c:305 #, c-format msgid "could not send signal to process %d: %m" @@ -29412,51 +29683,51 @@ msgstr "Wiederherstellung wartet immer noch nach %ld,%03d ms: %s" msgid "recovery finished waiting after %ld.%03d ms: %s" msgstr "Warten der Wiederherstellung beendet nach %ld,%03d ms: %s" -#: storage/ipc/standby.c:923 tcop/postgres.c:3288 +#: storage/ipc/standby.c:923 tcop/postgres.c:3289 #, c-format msgid "canceling statement due to conflict with recovery" msgstr "storniere Anfrage wegen Konflikt mit der Wiederherstellung" -#: storage/ipc/standby.c:924 tcop/postgres.c:2575 +#: storage/ipc/standby.c:924 tcop/postgres.c:2576 #, c-format msgid "User transaction caused buffer deadlock with recovery." msgstr "Benutzertransaktion hat Verklemmung (Deadlock) mit Wiederherstellung verursacht." -#: storage/ipc/standby.c:1517 +#: storage/ipc/standby.c:1497 msgid "unknown reason" msgstr "unbekannter Grund" -#: storage/ipc/standby.c:1522 +#: storage/ipc/standby.c:1502 msgid "recovery conflict on buffer pin" msgstr "Konflikt bei der Wiederherstellung wegen Buffer-Pin" -#: storage/ipc/standby.c:1525 +#: storage/ipc/standby.c:1505 msgid "recovery conflict on lock" msgstr "Konflikt bei Wiederherstellung wegen Sperre" -#: storage/ipc/standby.c:1528 +#: storage/ipc/standby.c:1508 msgid "recovery conflict on tablespace" msgstr "Konflikt bei Wiederherstellung wegen Tablespace" -#: storage/ipc/standby.c:1531 +#: storage/ipc/standby.c:1511 msgid "recovery conflict on snapshot" msgstr "Konflikt bei der Wiederherstellung wegen Snapshot" -#: storage/ipc/standby.c:1534 +#: storage/ipc/standby.c:1514 msgid "recovery conflict on replication slot" msgstr "Konflikt bei der Wiederherstellung wegen Replikations-Slot" -#: storage/ipc/standby.c:1537 +#: storage/ipc/standby.c:1517 #, fuzzy #| msgid "recovery conflict on lock" msgid "recovery conflict on deadlock" msgstr "Konflikt bei Wiederherstellung wegen Sperre" -#: storage/ipc/standby.c:1540 +#: storage/ipc/standby.c:1520 msgid "recovery conflict on buffer deadlock" msgstr "Konflikt bei der Wiederherstellung wegen Buffer-Deadlock" -#: storage/ipc/standby.c:1543 +#: storage/ipc/standby.c:1523 msgid "recovery conflict on database" msgstr "Konflikt bei Wiederherstellung wegen Datenbank" @@ -29738,27 +30009,27 @@ msgstr "Die Transaktion könnte erfolgreich sein, wenn sie erneut versucht würd msgid "number of requested standby connections exceeds \"max_wal_senders\" (currently %d)" msgstr "Anzahl angeforderter Standby-Verbindungen überschreitet »max_wal_senders« (aktuell %d)" -#: storage/lmgr/proc.c:1609 +#: storage/lmgr/proc.c:1643 #, c-format msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" msgstr "Prozess %d vermied Verklemmung wegen %s-Sperre auf %s durch Umordnen der Queue nach %ld,%03d ms" -#: storage/lmgr/proc.c:1624 +#: storage/lmgr/proc.c:1658 #, c-format msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" msgstr "Prozess %d hat Verklemmung festgestellt beim Warten auf %s-Sperre auf %s nach %ld,%03d ms" -#: storage/lmgr/proc.c:1648 +#: storage/lmgr/proc.c:1682 #, c-format msgid "process %d still waiting for %s on %s after %ld.%03d ms" msgstr "Prozess %d wartet immer noch auf %s-Sperre auf %s nach %ld,%03d ms" -#: storage/lmgr/proc.c:1658 +#: storage/lmgr/proc.c:1692 #, c-format msgid "process %d acquired %s on %s after %ld.%03d ms" msgstr "Prozess %d erlangte %s-Sperre auf %s nach %ld,%03d ms" -#: storage/lmgr/proc.c:1675 +#: storage/lmgr/proc.c:1709 #, c-format msgid "process %d failed to acquire %s on %s after %ld.%03d ms" msgstr "Prozess %d konnte %s-Sperre auf %s nach %ld,%03d ms nicht erlangen" @@ -29950,92 +30221,92 @@ msgstr "direkte SSL-Verbindung angenommen" msgid "direct SSL connection rejected" msgstr "direkte SSL-Verbindung abgelehnt" -#: tcop/backend_startup.c:528 tcop/backend_startup.c:556 +#: tcop/backend_startup.c:536 tcop/backend_startup.c:564 #, c-format msgid "incomplete startup packet" msgstr "unvollständiges Startpaket" -#: tcop/backend_startup.c:540 +#: tcop/backend_startup.c:548 #, c-format msgid "invalid length of startup packet" msgstr "ungültige Länge des Startpakets" -#: tcop/backend_startup.c:597 +#: tcop/backend_startup.c:605 #, c-format msgid "SSLRequest accepted" msgstr "SSLRequest akzeptiert" -#: tcop/backend_startup.c:600 +#: tcop/backend_startup.c:608 #, c-format msgid "SSLRequest rejected" msgstr "SSLRequest abgelehnt" -#: tcop/backend_startup.c:609 +#: tcop/backend_startup.c:617 #, c-format msgid "failed to send SSL negotiation response: %m" msgstr "konnte SSL-Verhandlungsantwort nicht senden: %m" -#: tcop/backend_startup.c:629 +#: tcop/backend_startup.c:638 #, c-format msgid "received unencrypted data after SSL request" msgstr "unverschlüsselte Daten nach SSL-Anforderung empfangen" -#: tcop/backend_startup.c:630 tcop/backend_startup.c:686 +#: tcop/backend_startup.c:639 tcop/backend_startup.c:705 #, c-format msgid "This could be either a client-software bug or evidence of an attempted man-in-the-middle attack." msgstr "Das könnte entweder ein Fehler in der Client-Software oder ein Hinweis auf einen versuchten Man-in-the-Middle-Angriff sein." -#: tcop/backend_startup.c:653 +#: tcop/backend_startup.c:671 #, c-format msgid "GSSENCRequest accepted" msgstr "GSSENCRequest akzeptiert" -#: tcop/backend_startup.c:656 +#: tcop/backend_startup.c:674 #, c-format msgid "GSSENCRequest rejected" msgstr "GSSENCRequest abgelehnt" -#: tcop/backend_startup.c:665 +#: tcop/backend_startup.c:683 #, c-format msgid "failed to send GSSAPI negotiation response: %m" msgstr "konnte GSSAPI-Verhandlungsantwort nicht senden: %m" -#: tcop/backend_startup.c:685 +#: tcop/backend_startup.c:704 #, c-format msgid "received unencrypted data after GSSAPI encryption request" msgstr "unverschlüsselte Daten nach GSSAPI-Verschlüsselungsanforderung empfangen" -#: tcop/backend_startup.c:713 +#: tcop/backend_startup.c:741 #, c-format msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" msgstr "nicht unterstütztes Frontend-Protokoll %u.%u: Server unterstützt %u.0 bis %u.%u" -#: tcop/backend_startup.c:776 +#: tcop/backend_startup.c:804 #, c-format msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." msgstr "Gültige Werte sind: »false«, 0, »true«, 1, »database«." -#: tcop/backend_startup.c:817 +#: tcop/backend_startup.c:845 #, c-format msgid "invalid startup packet layout: expected terminator as last byte" msgstr "ungültiges Layout des Startpakets: Abschluss als letztes Byte erwartet" -#: tcop/backend_startup.c:836 +#: tcop/backend_startup.c:864 #, c-format msgid "no PostgreSQL user name specified in startup packet" msgstr "kein PostgreSQL-Benutzername im Startpaket angegeben" -#: tcop/backend_startup.c:898 +#: tcop/backend_startup.c:926 #, c-format msgid "invalid length of cancel request packet" msgstr "ungültige Länge des Pakets zur Stornierungsanfrage" -#: tcop/backend_startup.c:906 +#: tcop/backend_startup.c:934 #, c-format msgid "invalid length of cancel key in cancel request packet" msgstr "ungültige Länge des Stornierungsschlüssels im Paket zur Stornierungsanfrage" -#: tcop/backend_startup.c:1036 +#: tcop/backend_startup.c:1064 #, c-format msgid "Cannot specify log_connections option \"%s\" in a list with other options." msgstr "log_connections-Option »%s« kann nicht in einer Liste mit anderen Optionen angegeben werden." @@ -30055,8 +30326,8 @@ msgstr "Funktion »%s« kann nicht via Fastpath-Interface aufgerufen werden" msgid "fastpath function call: \"%s\" (OID %u)" msgstr "Fastpath-Funktionsaufruf: »%s« (OID %u)" -#: tcop/fastpath.c:312 tcop/postgres.c:1379 tcop/postgres.c:1614 -#: tcop/postgres.c:2091 tcop/postgres.c:2362 +#: tcop/fastpath.c:312 tcop/postgres.c:1380 tcop/postgres.c:1615 +#: tcop/postgres.c:2092 tcop/postgres.c:2363 #, c-format msgid "duration: %s ms" msgstr "Dauer: %s ms" @@ -30086,326 +30357,326 @@ msgstr "ungültige Argumentgröße %d in Funktionsaufruf-Message" msgid "incorrect binary data format in function argument %d" msgstr "falsches Binärdatenformat in Funktionsargument %d" -#: tcop/postgres.c:119 +#: tcop/postgres.c:120 #, c-format msgid "Signal sent by PID %d, UID %d." msgstr "" -#: tcop/postgres.c:467 tcop/postgres.c:5107 +#: tcop/postgres.c:468 tcop/postgres.c:5108 #, c-format msgid "invalid frontend message type %d" msgstr "ungültiger Frontend-Message-Typ %d" -#: tcop/postgres.c:1087 +#: tcop/postgres.c:1088 #, c-format msgid "statement: %s" msgstr "Anweisung: %s" -#: tcop/postgres.c:1384 +#: tcop/postgres.c:1385 #, c-format msgid "duration: %s ms statement: %s" msgstr "Dauer: %s ms Anweisung: %s" -#: tcop/postgres.c:1490 +#: tcop/postgres.c:1491 #, c-format msgid "cannot insert multiple commands into a prepared statement" msgstr "kann nicht mehrere Befehle in vorbereitete Anweisung einfügen" -#: tcop/postgres.c:1619 +#: tcop/postgres.c:1620 #, c-format msgid "duration: %s ms parse %s: %s" msgstr "Dauer: %s ms Parsen %s: %s" -#: tcop/postgres.c:1686 tcop/postgres.c:2668 +#: tcop/postgres.c:1687 tcop/postgres.c:2669 #, c-format msgid "unnamed prepared statement does not exist" msgstr "unbenannte vorbereitete Anweisung existiert nicht" -#: tcop/postgres.c:1738 +#: tcop/postgres.c:1739 #, c-format msgid "bind message has %d parameter formats but %d parameters" msgstr "Binden-Nachricht hat %d Parameterformate aber %d Parameter" -#: tcop/postgres.c:1744 +#: tcop/postgres.c:1745 #, c-format msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" msgstr "Binden-Nachricht enthält %d Parameter, aber vorbereitete Anweisung »%s« erfordert %d" -#: tcop/postgres.c:1957 +#: tcop/postgres.c:1958 #, c-format msgid "incorrect binary data format in bind parameter %d" msgstr "falsches Binärdatenformat in Binden-Parameter %d" -#: tcop/postgres.c:2096 +#: tcop/postgres.c:2097 #, c-format msgid "duration: %s ms bind %s%s%s: %s" msgstr "Dauer: %s ms Binden %s%s%s: %s" -#: tcop/postgres.c:2151 tcop/postgres.c:2749 +#: tcop/postgres.c:2152 tcop/postgres.c:2750 #, c-format msgid "portal \"%s\" does not exist" msgstr "Portal »%s« existiert nicht" -#: tcop/postgres.c:2244 +#: tcop/postgres.c:2245 #, c-format msgid "%s %s%s%s: %s" msgstr "%s %s%s%s: %s" -#: tcop/postgres.c:2246 tcop/postgres.c:2370 +#: tcop/postgres.c:2247 tcop/postgres.c:2371 msgid "execute fetch from" msgstr "Ausführen Fetch von" -#: tcop/postgres.c:2247 tcop/postgres.c:2371 +#: tcop/postgres.c:2248 tcop/postgres.c:2372 msgid "execute" msgstr "Ausführen" -#: tcop/postgres.c:2367 +#: tcop/postgres.c:2368 #, c-format msgid "duration: %s ms %s %s%s%s: %s" msgstr "Dauer: %s ms %s %s%s%s: %s" -#: tcop/postgres.c:2515 +#: tcop/postgres.c:2516 #, c-format msgid "prepare: %s" msgstr "Vorbereiten: %s" -#: tcop/postgres.c:2540 +#: tcop/postgres.c:2541 #, c-format msgid "Parameters: %s" msgstr "Parameter: %s" -#: tcop/postgres.c:2557 +#: tcop/postgres.c:2558 #, c-format msgid "User was holding shared buffer pin for too long." msgstr "Benutzer hat Shared-Buffer-Pin zu lange gehalten." -#: tcop/postgres.c:2560 +#: tcop/postgres.c:2561 #, c-format msgid "User was holding a relation lock for too long." msgstr "Benutzer hat Relationssperre zu lange gehalten." -#: tcop/postgres.c:2563 +#: tcop/postgres.c:2564 #, c-format msgid "User was or might have been using tablespace that must be dropped." msgstr "Benutzer hat (möglicherweise) einen Tablespace verwendet, der gelöscht werden muss." -#: tcop/postgres.c:2566 +#: tcop/postgres.c:2567 #, c-format msgid "User query might have needed to see row versions that must be removed." msgstr "Benutzeranfrage hat möglicherweise Zeilenversionen sehen müssen, die entfernt werden müssen." -#: tcop/postgres.c:2569 +#: tcop/postgres.c:2570 #, c-format msgid "User was using a logical replication slot that must be invalidated." msgstr "Benutzer verwendete einen logischen Replikations-Slot, der ungültig gemacht werden muss." -#: tcop/postgres.c:2572 +#: tcop/postgres.c:2573 #, fuzzy, c-format #| msgid "User transaction caused buffer deadlock with recovery." msgid "User transaction caused deadlock with recovery." msgstr "Benutzertransaktion hat Verklemmung (Deadlock) mit Wiederherstellung verursacht." -#: tcop/postgres.c:2578 +#: tcop/postgres.c:2579 #, c-format msgid "User was connected to a database that must be dropped." msgstr "Benutzer war mit einer Datenbank verbunden, die gelöscht werden muss." -#: tcop/postgres.c:2614 +#: tcop/postgres.c:2615 #, c-format msgid "portal \"%s\" parameter $%d = %s" msgstr "Portal »%s« Parameter $%d = %s" -#: tcop/postgres.c:2617 +#: tcop/postgres.c:2618 #, c-format msgid "portal \"%s\" parameter $%d" msgstr "Portal »%s« Parameter $%d" -#: tcop/postgres.c:2623 +#: tcop/postgres.c:2624 #, c-format msgid "unnamed portal parameter $%d = %s" msgstr "unbenanntes Portal Parameter $%d = %s" -#: tcop/postgres.c:2626 +#: tcop/postgres.c:2627 #, c-format msgid "unnamed portal parameter $%d" msgstr "unbenanntes Portal Parameter $%d" -#: tcop/postgres.c:2979 +#: tcop/postgres.c:2980 #, c-format msgid "terminating connection because of unexpected SIGQUIT signal" msgstr "Verbindung wird abgebrochen wegen unerwartetem SIGQUIT-Signal" -#: tcop/postgres.c:2985 +#: tcop/postgres.c:2986 #, c-format msgid "terminating connection because of crash of another server process" msgstr "Verbindung wird abgebrochen wegen Absturz eines anderen Serverprozesses" -#: tcop/postgres.c:2986 +#: tcop/postgres.c:2987 #, c-format msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." msgstr "Der Postmaster hat diesen Serverprozess angewiesen, die aktuelle Transaktion zurückzurollen und die Sitzung zu beenden, weil ein anderer Serverprozess abnormal beendet wurde und möglicherweise das Shared Memory verfälscht hat." -#: tcop/postgres.c:2990 tcop/postgres.c:3302 +#: tcop/postgres.c:2991 tcop/postgres.c:3303 #, c-format msgid "In a moment you should be able to reconnect to the database and repeat your command." msgstr "In einem Moment sollten Sie wieder mit der Datenbank verbinden und Ihren Befehl wiederholen können." -#: tcop/postgres.c:2997 +#: tcop/postgres.c:2998 #, c-format msgid "terminating connection due to immediate shutdown command" msgstr "Verbindung wird abgebrochen aufgrund von Befehl für sofortiges Herunterfahren" -#: tcop/postgres.c:3086 +#: tcop/postgres.c:3087 #, c-format msgid "floating-point exception" msgstr "Fließkommafehler" -#: tcop/postgres.c:3087 +#: tcop/postgres.c:3088 #, c-format msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." msgstr "Eine ungültige Fließkommaoperation wurde signalisiert. Das bedeutet wahrscheinlich ein Ergebnis außerhalb des gültigen Bereichs oder eine ungültige Operation, zum Beispiel Division durch null." -#: tcop/postgres.c:3214 tcop/postgres.c:3300 +#: tcop/postgres.c:3215 tcop/postgres.c:3301 #, c-format msgid "terminating connection due to conflict with recovery" msgstr "Verbindung wird abgebrochen wegen Konflikt mit der Wiederherstellung" -#: tcop/postgres.c:3384 +#: tcop/postgres.c:3385 #, c-format msgid "canceling authentication due to timeout" msgstr "storniere Authentifizierung wegen Zeitüberschreitung" -#: tcop/postgres.c:3388 +#: tcop/postgres.c:3389 #, c-format msgid "terminating autovacuum process due to administrator command" msgstr "Autovacuum-Prozess wird abgebrochen aufgrund von Anweisung des Administrators" -#: tcop/postgres.c:3393 +#: tcop/postgres.c:3394 #, c-format msgid "terminating logical replication worker due to administrator command" msgstr "Arbeitsprozess für logische Replikation wird abgebrochen aufgrund von Anweisung des Administrators" -#: tcop/postgres.c:3410 +#: tcop/postgres.c:3411 #, c-format msgid "terminating walreceiver process due to administrator command" msgstr "WAL-Receiver-Prozess wird abgebrochen aufgrund von Anweisung des Administrators" -#: tcop/postgres.c:3415 +#: tcop/postgres.c:3416 #, c-format msgid "terminating background worker \"%s\" due to administrator command" msgstr "Background-Worker »%s« wird abgebrochen aufgrund von Anweisung des Administrators" -#: tcop/postgres.c:3429 +#: tcop/postgres.c:3430 #, c-format msgid "terminating connection due to administrator command" msgstr "Verbindung wird abgebrochen aufgrund von Anweisung des Administrators" -#: tcop/postgres.c:3461 +#: tcop/postgres.c:3462 #, c-format msgid "connection to client lost" msgstr "Verbindung zum Client wurde verloren" -#: tcop/postgres.c:3513 +#: tcop/postgres.c:3514 #, c-format msgid "canceling statement due to lock timeout" msgstr "storniere Anfrage wegen Zeitüberschreitung einer Sperre" -#: tcop/postgres.c:3520 +#: tcop/postgres.c:3521 #, c-format msgid "canceling statement due to statement timeout" msgstr "storniere Anfrage wegen Zeitüberschreitung der Anfrage" -#: tcop/postgres.c:3527 +#: tcop/postgres.c:3528 #, c-format msgid "canceling autovacuum task" msgstr "storniere Autovacuum-Aufgabe" -#: tcop/postgres.c:3540 +#: tcop/postgres.c:3541 #, c-format msgid "canceling statement due to user request" msgstr "storniere Anfrage wegen Benutzeraufforderung" -#: tcop/postgres.c:3561 +#: tcop/postgres.c:3562 #, c-format msgid "terminating connection due to idle-in-transaction timeout" msgstr "Verbindung wird abgebrochen wegen Zeitüberschreitung in inaktiver Transaktion" -#: tcop/postgres.c:3574 +#: tcop/postgres.c:3575 #, c-format msgid "terminating connection due to transaction timeout" msgstr "Verbindung wird abgebrochen wegen Zeitüberschreitung in Transaktion" -#: tcop/postgres.c:3587 +#: tcop/postgres.c:3588 #, c-format msgid "terminating connection due to idle-session timeout" msgstr "Verbindung wird abgebrochen wegen Zeitüberschreitung in inaktiver Sitzung" -#: tcop/postgres.c:3629 +#: tcop/postgres.c:3630 #, c-format msgid "\"client_connection_check_interval\" must be set to 0 on this platform." msgstr "»client_connection_check_interval« muss auf dieser Plattform auf 0 gesetzt sein." -#: tcop/postgres.c:3650 +#: tcop/postgres.c:3651 #, c-format msgid "Cannot enable parameter when \"log_statement_stats\" is true." msgstr "Kann Parameter nicht einschalten, wenn »log_statement_stats« an ist." -#: tcop/postgres.c:3665 +#: tcop/postgres.c:3666 #, c-format msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." msgstr "Kann »log_statement_stats« nicht einschalten, wenn »log_parser_stats«, »log_planner_stats« oder »log_executor_stats« an ist." -#: tcop/postgres.c:4108 +#: tcop/postgres.c:4109 #, c-format msgid "invalid command-line argument for server process: %s" msgstr "ungültiges Kommandozeilenargument für Serverprozess: %s" -#: tcop/postgres.c:4109 tcop/postgres.c:4115 +#: tcop/postgres.c:4110 tcop/postgres.c:4116 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Versuchen Sie »%s --help« für weitere Informationen." -#: tcop/postgres.c:4113 +#: tcop/postgres.c:4114 #, c-format msgid "%s: invalid command-line argument: %s" msgstr "%s: ungültiges Kommandozeilenargument: %s" -#: tcop/postgres.c:4157 +#: tcop/postgres.c:4158 #, c-format msgid "%s: no database nor user name specified" msgstr "%s: weder Datenbankname noch Benutzername angegeben" -#: tcop/postgres.c:4364 +#: tcop/postgres.c:4365 #, c-format msgid "could not generate random cancel key" msgstr "konnte zufälligen Stornierungsschlüssel nicht erzeugen" -#: tcop/postgres.c:4766 +#: tcop/postgres.c:4767 #, c-format msgid "connection ready: setup total=%.3f ms, fork=%.3f ms, authentication=%.3f ms" msgstr "Verbindung bereit: Setup gesamt=%.3f ms, Fork=%.3f ms, Authentifizierung=%.3f ms" -#: tcop/postgres.c:4997 +#: tcop/postgres.c:4998 #, c-format msgid "invalid CLOSE message subtype %d" msgstr "ungültiger Subtyp %d von CLOSE-Message" -#: tcop/postgres.c:5034 +#: tcop/postgres.c:5035 #, c-format msgid "invalid DESCRIBE message subtype %d" msgstr "ungültiger Subtyp %d von DESCRIBE-Message" -#: tcop/postgres.c:5128 +#: tcop/postgres.c:5129 #, c-format msgid "fastpath function calls not supported in a replication connection" msgstr "Fastpath-Funktionsaufrufe werden auf einer Replikationsverbindung nicht unterstützt" -#: tcop/postgres.c:5132 +#: tcop/postgres.c:5133 #, c-format msgid "extended query protocol not supported in a replication connection" msgstr "erweitertes Anfrageprotokoll wird nicht auf einer Replikationsverbindung unterstützt" -#: tcop/postgres.c:5278 +#: tcop/postgres.c:5279 #, c-format msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" msgstr "Verbindungsende: Sitzungszeit: %d:%02d:%02d.%03d Benutzer=%s Datenbank=%s Host=%s%s%s" @@ -30495,17 +30766,17 @@ msgstr "mehrere »Accept«-Parameter" msgid "unrecognized simple dictionary parameter: \"%s\"" msgstr "unbekannter Parameter für das einfache Wörterbuch: »%s«" -#: tsearch/dict_synonym.c:120 +#: tsearch/dict_synonym.c:119 #, c-format msgid "unrecognized synonym parameter: \"%s\"" msgstr "unbekannter Synonymparameter: »%s«" -#: tsearch/dict_synonym.c:127 +#: tsearch/dict_synonym.c:126 #, c-format msgid "missing Synonyms parameter" msgstr "Parameter »Synonyms« fehlt" -#: tsearch/dict_synonym.c:134 +#: tsearch/dict_synonym.c:133 #, c-format msgid "could not open synonym file \"%s\": %m" msgstr "konnte Synonymdatei »%s« nicht öffnen: %m" @@ -30637,7 +30908,7 @@ msgstr "Anzahl der Aliasse überschreitet angegebene Zahl %d" msgid "affix file contains both old-style and new-style commands" msgstr "Affixdatei enthält Befehle im alten und im neuen Stil" -#: tsearch/to_tsany.c:194 utils/adt/tsvector.c:274 utils/adt/tsvector_op.c:1127 +#: tsearch/to_tsany.c:194 utils/adt/tsvector.c:274 utils/adt/tsvector_op.c:1100 #, c-format msgid "string is too long for tsvector (%d bytes, max %d bytes)" msgstr "Zeichenkette ist zu lang für tsvector (%d Bytes, maximal %d Bytes)" @@ -30674,26 +30945,33 @@ msgstr "konnte Stoppwortdatei »%s« nicht öffnen: %m" msgid "text search parser does not support headline creation" msgstr "Textsucheparser unterstützt das Erzeugen von Headlines nicht" -#: tsearch/wparser_def.c:2620 +#: tsearch/wparser_def.c:2623 #, c-format msgid "unrecognized headline parameter: \"%s\"" msgstr "unbekannter Headline-Parameter: »%s«" -#: tsearch/wparser_def.c:2630 +#: tsearch/wparser_def.c:2633 #, c-format msgid "%s must be less than %s" msgstr "%s muss kleiner als %s sein" -#: tsearch/wparser_def.c:2634 +#: tsearch/wparser_def.c:2637 #, c-format msgid "%s must be positive" msgstr "%s muss positiv sein" -#: tsearch/wparser_def.c:2638 tsearch/wparser_def.c:2642 +#: tsearch/wparser_def.c:2641 tsearch/wparser_def.c:2645 #, c-format msgid "%s must be >= 0" msgstr "%s muss >= 0 sein" +#: tsearch/wparser_def.c:2684 tsearch/wparser_def.c:2688 +#: tsearch/wparser_def.c:2692 +#, fuzzy, c-format +#| msgid "tablespace location \"%s\" is too long" +msgid "value for \"%s\" is too long" +msgstr "Tablespace-Pfad »%s« ist zu lang" + #: utils/activity/pgstat.c:555 #, c-format msgid "could not unlink permanent statistics file \"%s\": %m" @@ -30886,37 +31164,37 @@ msgstr "ACL-Array darf keine NULL-Werte enthalten" msgid "extra garbage at the end of the ACL specification" msgstr "überflüssiger Müll am Ende der ACL-Angabe" -#: utils/adt/acl.c:1308 +#: utils/adt/acl.c:1311 #, c-format msgid "grant options cannot be granted back to your own grantor" msgstr "Grant-Optionen können nicht an den eigenen Grantor gegeben werden" -#: utils/adt/acl.c:1624 +#: utils/adt/acl.c:1627 #, c-format msgid "aclinsert is no longer supported" msgstr "aclinsert wird nicht mehr unterstützt" -#: utils/adt/acl.c:1634 +#: utils/adt/acl.c:1637 #, c-format msgid "aclremove is no longer supported" msgstr "aclremove wird nicht mehr unterstützt" -#: utils/adt/acl.c:1753 +#: utils/adt/acl.c:1756 #, c-format msgid "unrecognized privilege type: \"%s\"" msgstr "unbekannter Privilegtyp: »%s«" -#: utils/adt/acl.c:3593 utils/adt/regproc.c:103 utils/adt/regproc.c:271 +#: utils/adt/acl.c:3596 utils/adt/regproc.c:103 utils/adt/regproc.c:271 #, c-format msgid "function \"%s\" does not exist" msgstr "Funktion »%s« existiert nicht" -#: utils/adt/acl.c:5376 +#: utils/adt/acl.c:5379 #, c-format msgid "must be able to SET ROLE \"%s\"" msgstr "Berechtigung nur für Rollen, die SET ROLE \"%s\" ausführen können" -#: utils/adt/acl.c:5529 +#: utils/adt/acl.c:5532 #, fuzzy, c-format #| msgid "initial privileges for %s" msgid "must inherit privileges of role \"%s\"" @@ -30930,7 +31208,8 @@ msgstr "initiale Privilegien für %s" #: utils/adt/arrayfuncs.c:2900 utils/adt/arrayfuncs.c:2954 #: utils/adt/arrayfuncs.c:2969 utils/adt/arrayfuncs.c:3311 #: utils/adt/arrayfuncs.c:3552 utils/adt/arrayfuncs.c:5392 -#: utils/adt/arrayfuncs.c:6233 utils/adt/arrayfuncs.c:6579 +#: utils/adt/arrayfuncs.c:5614 utils/adt/arrayfuncs.c:6240 +#: utils/adt/arrayfuncs.c:6586 #, fuzzy, c-format #| msgid "array size exceeds the maximum allowed (%d)" msgid "array size exceeds the maximum allowed (%zu)" @@ -30950,15 +31229,15 @@ msgid "input data type is not an array" msgstr "Eingabedatentyp ist kein Array" #: utils/adt/array_userfuncs.c:168 utils/adt/array_userfuncs.c:250 -#: utils/adt/bytea.c:178 utils/adt/bytea.c:1286 utils/adt/float.c:1270 -#: utils/adt/float.c:1344 utils/adt/float.c:4259 utils/adt/float.c:4299 +#: utils/adt/bytea.c:177 utils/adt/bytea.c:1284 utils/adt/float.c:1270 +#: utils/adt/float.c:1344 utils/adt/float.c:4327 utils/adt/float.c:4367 #: utils/adt/int.c:807 utils/adt/int.c:829 utils/adt/int.c:843 #: utils/adt/int.c:857 utils/adt/int.c:888 utils/adt/int.c:909 #: utils/adt/int.c:1026 utils/adt/int.c:1040 utils/adt/int.c:1054 #: utils/adt/int.c:1087 utils/adt/int.c:1101 utils/adt/int.c:1115 -#: utils/adt/int.c:1146 utils/adt/int.c:1228 utils/adt/int.c:1292 -#: utils/adt/int.c:1360 utils/adt/int.c:1366 utils/adt/int8.c:1256 -#: utils/adt/numeric.c:2021 utils/adt/numeric.c:4392 +#: utils/adt/int.c:1146 utils/adt/int.c:1229 utils/adt/int.c:1293 +#: utils/adt/int.c:1361 utils/adt/int.c:1367 utils/adt/int8.c:1296 +#: utils/adt/numeric.c:2027 utils/adt/numeric.c:4398 #: utils/adt/rangetypes.c:1722 utils/adt/rangetypes.c:1735 #: utils/adt/varbit.c:1195 utils/adt/varbit.c:1596 utils/adt/varlena.c:875 #, c-format @@ -30998,7 +31277,7 @@ msgid "Arrays with differing dimensions are not compatible for concatenation." msgstr "Arrays mit unterschiedlichen Dimensionen sind nicht kompatibel für Aneinanderhängen." #: utils/adt/array_userfuncs.c:1053 utils/adt/array_userfuncs.c:1061 -#: utils/adt/arrayfuncs.c:5643 utils/adt/arrayfuncs.c:5649 +#: utils/adt/arrayfuncs.c:5652 utils/adt/arrayfuncs.c:5658 #, c-format msgid "cannot accumulate arrays of different dimensionality" msgstr "Arrays unterschiedlicher Dimensionalität können nicht akkumuliert werden" @@ -31116,7 +31395,7 @@ msgid "Unexpected end of input." msgstr "Unerwartetes Ende der Eingabe." #: utils/adt/arrayfuncs.c:1305 utils/adt/arrayfuncs.c:3518 -#: utils/adt/arrayfuncs.c:6136 +#: utils/adt/arrayfuncs.c:6143 #, c-format msgid "invalid number of dimensions: %d" msgstr "ungültige Anzahl Dimensionen: %d" @@ -31131,8 +31410,8 @@ msgstr "ungültige Array-Flags" msgid "binary data has array element type %u (%s) instead of expected %u (%s)" msgstr "binäre Daten haben Array-Elementtyp %u (%s) statt erwartet %u (%s)" -#: utils/adt/arrayfuncs.c:1382 utils/adt/multirangetypes.c:452 -#: utils/adt/rangetypes.c:357 utils/cache/lsyscache.c:3153 +#: utils/adt/arrayfuncs.c:1382 utils/adt/multirangetypes.c:453 +#: utils/adt/rangetypes.c:357 utils/cache/lsyscache.c:3274 #, c-format msgid "no binary input function available for type %s" msgstr "keine binäre Eingabefunktion verfügbar für Typ %s" @@ -31142,8 +31421,8 @@ msgstr "keine binäre Eingabefunktion verfügbar für Typ %s" msgid "improper binary format in array element %d" msgstr "falsches Binärformat in Arrayelement %d" -#: utils/adt/arrayfuncs.c:1593 utils/adt/multirangetypes.c:457 -#: utils/adt/rangetypes.c:362 utils/cache/lsyscache.c:3186 +#: utils/adt/arrayfuncs.c:1593 utils/adt/multirangetypes.c:458 +#: utils/adt/rangetypes.c:362 utils/cache/lsyscache.c:3307 #, c-format msgid "no binary output function available for type %s" msgstr "keine binäre Ausgabefunktion verfügbar für Typ %s" @@ -31155,8 +31434,8 @@ msgstr "Auswählen von Stücken aus Arrays mit fester Länge ist nicht implement #: utils/adt/arrayfuncs.c:2250 utils/adt/arrayfuncs.c:2272 #: utils/adt/arrayfuncs.c:2321 utils/adt/arrayfuncs.c:2575 -#: utils/adt/arrayfuncs.c:2920 utils/adt/arrayfuncs.c:6122 -#: utils/adt/arrayfuncs.c:6148 utils/adt/arrayfuncs.c:6159 +#: utils/adt/arrayfuncs.c:2920 utils/adt/arrayfuncs.c:6129 +#: utils/adt/arrayfuncs.c:6155 utils/adt/arrayfuncs.c:6166 #: utils/adt/json.c:1411 utils/adt/json.c:1479 utils/adt/jsonb.c:1322 #: utils/adt/jsonb.c:1406 utils/adt/jsonfuncs.c:4727 utils/adt/jsonfuncs.c:4874 #: utils/adt/jsonfuncs.c:4978 utils/adt/jsonfuncs.c:5023 @@ -31206,8 +31485,8 @@ msgstr "NULL-Werte im Array sind in diesem Zusammenhang nicht erlaubt" msgid "cannot compare arrays of different element types" msgstr "kann Arrays mit verschiedenen Elementtypen nicht vergleichen" -#: utils/adt/arrayfuncs.c:4201 utils/adt/multirangetypes.c:2880 -#: utils/adt/multirangetypes.c:2952 utils/adt/rangetypes.c:1595 +#: utils/adt/arrayfuncs.c:4201 utils/adt/multirangetypes.c:2881 +#: utils/adt/multirangetypes.c:2953 utils/adt/rangetypes.c:1595 #: utils/adt/rangetypes.c:1659 utils/adt/rowtypes.c:1893 #, c-format msgid "could not identify a hash function for type %s" @@ -31223,52 +31502,52 @@ msgstr "konnte keine erweiterte Hash-Funktion für Typ %s ermitteln" msgid "data type %s is not an array type" msgstr "Datentyp %s ist kein Array-Typ" -#: utils/adt/arrayfuncs.c:5588 +#: utils/adt/arrayfuncs.c:5589 #, c-format msgid "cannot accumulate null arrays" msgstr "Arrays, die NULL sind, können nicht akkumuliert werden" -#: utils/adt/arrayfuncs.c:5616 +#: utils/adt/arrayfuncs.c:5625 #, c-format msgid "cannot accumulate empty arrays" msgstr "leere Arrays können nicht akkumuliert werden" -#: utils/adt/arrayfuncs.c:6019 utils/adt/arrayfuncs.c:6059 +#: utils/adt/arrayfuncs.c:6026 utils/adt/arrayfuncs.c:6066 #, c-format msgid "dimension array or low bound array cannot be null" msgstr "Dimensions-Array oder Untergrenzen-Array darf nicht NULL sein" -#: utils/adt/arrayfuncs.c:6123 utils/adt/arrayfuncs.c:6149 +#: utils/adt/arrayfuncs.c:6130 utils/adt/arrayfuncs.c:6156 #, c-format msgid "Dimension array must be one dimensional." msgstr "Dimensions-Array muss eindimensional sein." -#: utils/adt/arrayfuncs.c:6128 utils/adt/arrayfuncs.c:6154 +#: utils/adt/arrayfuncs.c:6135 utils/adt/arrayfuncs.c:6161 #, c-format msgid "dimension values cannot be null" msgstr "Dimensionswerte dürfen nicht NULL sein" -#: utils/adt/arrayfuncs.c:6160 +#: utils/adt/arrayfuncs.c:6167 #, c-format msgid "Low bound array has different size than dimensions array." msgstr "Untergrenzen-Array hat andere Größe als Dimensions-Array." -#: utils/adt/arrayfuncs.c:6443 +#: utils/adt/arrayfuncs.c:6450 #, c-format msgid "removing elements from multidimensional arrays is not supported" msgstr "Entfernen von Elementen aus mehrdimensionalen Arrays wird nicht unterstützt" -#: utils/adt/arrayfuncs.c:6721 +#: utils/adt/arrayfuncs.c:6728 #, c-format msgid "thresholds must be one-dimensional array" msgstr "Parameter »thresholds« muss ein eindimensionales Array sein" -#: utils/adt/arrayfuncs.c:6726 +#: utils/adt/arrayfuncs.c:6733 #, c-format msgid "thresholds array must not contain NULLs" msgstr "»thresholds«-Array darf keine NULL-Werte enthalten" -#: utils/adt/arrayfuncs.c:6960 +#: utils/adt/arrayfuncs.c:6967 #, c-format msgid "number of elements to trim must be between 0 and %d" msgstr "Anzahl der zu entfernenden Elemente muss zwischen 0 und %d sein" @@ -31309,79 +31588,79 @@ msgid "encoding conversion from %s to ASCII not supported" msgstr "Kodierungsumwandlung zwischen %s und ASCII wird nicht unterstützt" #. translator: first %s is inet or cidr -#: utils/adt/bool.c:150 utils/adt/cash.c:355 utils/adt/datetime.c:4265 +#: utils/adt/bool.c:150 utils/adt/cash.c:356 utils/adt/datetime.c:4291 #: utils/adt/float.c:248 utils/adt/float.c:335 utils/adt/float.c:349 #: utils/adt/float.c:454 utils/adt/float.c:537 utils/adt/float.c:551 -#: utils/adt/geo_ops.c:251 utils/adt/geo_ops.c:336 utils/adt/geo_ops.c:992 -#: utils/adt/geo_ops.c:1435 utils/adt/geo_ops.c:1472 utils/adt/geo_ops.c:1480 -#: utils/adt/geo_ops.c:3475 utils/adt/geo_ops.c:4709 utils/adt/geo_ops.c:4724 -#: utils/adt/geo_ops.c:4731 utils/adt/int.c:198 utils/adt/int.c:210 +#: utils/adt/geo_ops.c:251 utils/adt/geo_ops.c:336 utils/adt/geo_ops.c:1020 +#: utils/adt/geo_ops.c:1466 utils/adt/geo_ops.c:1503 utils/adt/geo_ops.c:1511 +#: utils/adt/geo_ops.c:3512 utils/adt/geo_ops.c:4751 utils/adt/geo_ops.c:4766 +#: utils/adt/geo_ops.c:4773 utils/adt/int.c:198 utils/adt/int.c:210 #: utils/adt/jsonpath.c:185 utils/adt/mac.c:83 utils/adt/mac8.c:226 -#: utils/adt/network.c:97 utils/adt/numeric.c:788 utils/adt/numeric.c:6966 -#: utils/adt/numeric.c:7169 utils/adt/numeric.c:8016 utils/adt/numutils.c:355 +#: utils/adt/network.c:97 utils/adt/numeric.c:788 utils/adt/numeric.c:6972 +#: utils/adt/numeric.c:7175 utils/adt/numeric.c:8022 utils/adt/numutils.c:355 #: utils/adt/numutils.c:616 utils/adt/numutils.c:877 utils/adt/numutils.c:916 #: utils/adt/numutils.c:938 utils/adt/numutils.c:1002 utils/adt/numutils.c:1024 #: utils/adt/pg_lsn.c:59 utils/adt/tid.c:71 utils/adt/tid.c:79 -#: utils/adt/tid.c:93 utils/adt/tid.c:102 utils/adt/timestamp.c:504 +#: utils/adt/tid.c:93 utils/adt/tid.c:102 utils/adt/timestamp.c:508 #: utils/adt/uuid.c:176 utils/adt/xid8funcs.c:324 #, c-format msgid "invalid input syntax for type %s: \"%s\"" msgstr "ungültige Eingabesyntax für Typ %s: »%s«" -#: utils/adt/bytea.c:126 utils/adt/bytea.c:174 utils/adt/varbit.c:1081 +#: utils/adt/bytea.c:125 utils/adt/bytea.c:173 utils/adt/varbit.c:1081 #: utils/adt/varbit.c:1191 utils/adt/varlena.c:612 utils/adt/varlena.c:676 #: utils/adt/varlena.c:871 #, c-format msgid "negative substring length not allowed" msgstr "negative Teilzeichenkettenlänge nicht erlaubt" -#: utils/adt/bytea.c:652 utils/adt/bytea.c:719 +#: utils/adt/bytea.c:651 utils/adt/bytea.c:718 #, c-format msgid "index %d out of valid range, 0..%d" msgstr "Index %d ist außerhalb des gültigen Bereichs, 0..%d" -#: utils/adt/bytea.c:683 utils/adt/bytea.c:755 +#: utils/adt/bytea.c:682 utils/adt/bytea.c:754 #, c-format msgid "index % out of valid range, 0..%" msgstr "Index % ist außerhalb des gültigen Bereichs, 0..%" -#: utils/adt/bytea.c:768 utils/adt/varbit.c:1833 +#: utils/adt/bytea.c:767 utils/adt/varbit.c:1833 #, c-format msgid "new bit must be 0 or 1" msgstr "neues Bit muss 0 oder 1 sein" -#: utils/adt/bytea.c:1261 utils/adt/float.c:1295 utils/adt/float.c:1369 +#: utils/adt/bytea.c:1259 utils/adt/float.c:1295 utils/adt/float.c:1369 #: utils/adt/int.c:384 utils/adt/int.c:922 utils/adt/int.c:944 #: utils/adt/int.c:958 utils/adt/int.c:972 utils/adt/int.c:1004 -#: utils/adt/int.c:1242 utils/adt/int8.c:1277 utils/adt/numeric.c:4523 -#: utils/adt/numeric.c:4528 +#: utils/adt/int.c:1243 utils/adt/int8.c:1317 utils/adt/numeric.c:4529 +#: utils/adt/numeric.c:4534 #, c-format msgid "smallint out of range" msgstr "smallint ist außerhalb des gültigen Bereichs" -#: utils/adt/bytea.c:1311 utils/adt/cash.c:1170 utils/adt/cash.c:1202 -#: utils/adt/int8.c:448 utils/adt/int8.c:471 utils/adt/int8.c:485 -#: utils/adt/int8.c:499 utils/adt/int8.c:530 utils/adt/int8.c:554 -#: utils/adt/int8.c:636 utils/adt/int8.c:704 utils/adt/int8.c:710 -#: utils/adt/int8.c:727 utils/adt/int8.c:741 utils/adt/int8.c:899 -#: utils/adt/int8.c:913 utils/adt/int8.c:927 utils/adt/int8.c:958 -#: utils/adt/int8.c:980 utils/adt/int8.c:994 utils/adt/int8.c:1008 -#: utils/adt/int8.c:1041 utils/adt/int8.c:1055 utils/adt/int8.c:1069 -#: utils/adt/int8.c:1100 utils/adt/int8.c:1122 utils/adt/int8.c:1136 -#: utils/adt/int8.c:1150 utils/adt/int8.c:1312 utils/adt/int8.c:1347 -#: utils/adt/numeric.c:4468 utils/adt/rangetypes.c:1769 +#: utils/adt/bytea.c:1309 utils/adt/cash.c:1196 utils/adt/cash.c:1229 +#: utils/adt/int8.c:455 utils/adt/int8.c:478 utils/adt/int8.c:492 +#: utils/adt/int8.c:506 utils/adt/int8.c:537 utils/adt/int8.c:562 +#: utils/adt/int8.c:645 utils/adt/int8.c:713 utils/adt/int8.c:719 +#: utils/adt/int8.c:736 utils/adt/int8.c:750 utils/adt/int8.c:938 +#: utils/adt/int8.c:952 utils/adt/int8.c:966 utils/adt/int8.c:997 +#: utils/adt/int8.c:1019 utils/adt/int8.c:1033 utils/adt/int8.c:1047 +#: utils/adt/int8.c:1080 utils/adt/int8.c:1094 utils/adt/int8.c:1108 +#: utils/adt/int8.c:1139 utils/adt/int8.c:1161 utils/adt/int8.c:1175 +#: utils/adt/int8.c:1189 utils/adt/int8.c:1353 utils/adt/int8.c:1389 +#: utils/adt/numeric.c:4474 utils/adt/rangetypes.c:1769 #: utils/adt/rangetypes.c:1782 utils/adt/varbit.c:1676 #, c-format msgid "bigint out of range" msgstr "bigint ist außerhalb des gültigen Bereichs" -#: utils/adt/bytea.c:1356 +#: utils/adt/bytea.c:1354 #, fuzzy, c-format #| msgid "invalid input syntax for type %s" msgid "invalid input length for type %s" msgstr "ungültige Eingabesyntax für Typ %s" -#: utils/adt/bytea.c:1357 +#: utils/adt/bytea.c:1355 #, fuzzy, c-format #| msgid "Expected %d fields, got %d fields." msgid "Expected %d bytes, got %d." @@ -31393,21 +31672,21 @@ msgstr "%d Felder erwartet, %d Feldern erhalten." msgid "money out of range" msgstr "money ist außerhalb des gültigen Bereichs" -#: utils/adt/cash.c:162 utils/adt/cash.c:726 utils/adt/float.c:123 +#: utils/adt/cash.c:162 utils/adt/cash.c:731 utils/adt/float.c:123 #: utils/adt/float.c:147 utils/adt/int.c:872 utils/adt/int.c:988 #: utils/adt/int.c:1068 utils/adt/int.c:1130 utils/adt/int.c:1168 -#: utils/adt/int.c:1196 utils/adt/int8.c:514 utils/adt/int8.c:572 -#: utils/adt/int8.c:942 utils/adt/int8.c:1022 utils/adt/int8.c:1084 -#: utils/adt/int8.c:1164 utils/adt/numeric.c:3243 utils/adt/numeric.c:3278 -#: utils/adt/numeric.c:3296 utils/adt/numeric.c:3408 utils/adt/numeric.c:8941 -#: utils/adt/numeric.c:9465 utils/adt/numeric.c:9581 utils/adt/numeric.c:11092 -#: utils/adt/timestamp.c:3748 +#: utils/adt/int.c:1196 utils/adt/int8.c:521 utils/adt/int8.c:581 +#: utils/adt/int8.c:981 utils/adt/int8.c:1061 utils/adt/int8.c:1123 +#: utils/adt/int8.c:1203 utils/adt/numeric.c:3249 utils/adt/numeric.c:3284 +#: utils/adt/numeric.c:3302 utils/adt/numeric.c:3414 utils/adt/numeric.c:8947 +#: utils/adt/numeric.c:9471 utils/adt/numeric.c:9587 utils/adt/numeric.c:11098 +#: utils/adt/timestamp.c:3773 #, c-format msgid "division by zero" msgstr "Division durch Null" -#: utils/adt/cash.c:293 utils/adt/cash.c:318 utils/adt/cash.c:328 -#: utils/adt/cash.c:368 utils/adt/int.c:204 utils/adt/numutils.c:349 +#: utils/adt/cash.c:294 utils/adt/cash.c:319 utils/adt/cash.c:329 +#: utils/adt/cash.c:369 utils/adt/int.c:204 utils/adt/numutils.c:349 #: utils/adt/numutils.c:610 utils/adt/numutils.c:871 utils/adt/numutils.c:922 #: utils/adt/numutils.c:961 utils/adt/numutils.c:1008 #, c-format @@ -31440,172 +31719,172 @@ msgstr "Präzision von TIME(%d)%s darf nicht negativ sein" msgid "TIME(%d)%s precision reduced to maximum allowed, %d" msgstr "Präzision von TIME(%d)%s auf erlaubten Höchstwert %d reduziert" -#: utils/adt/date.c:161 utils/adt/date.c:169 utils/adt/formatting.c:4128 +#: utils/adt/date.c:162 utils/adt/date.c:170 utils/adt/formatting.c:4128 #: utils/adt/formatting.c:4136 utils/adt/formatting.c:4240 #: utils/adt/formatting.c:4249 #, c-format msgid "date out of range: \"%s\"" msgstr "date ist außerhalb des gültigen Bereichs: »%s«" -#: utils/adt/date.c:216 utils/adt/date.c:578 utils/adt/date.c:602 +#: utils/adt/date.c:218 utils/adt/date.c:582 utils/adt/date.c:607 #: utils/adt/rangetypes.c:1818 utils/adt/rangetypes.c:1833 utils/adt/xml.c:2596 #, c-format msgid "date out of range" msgstr "date ist außerhalb des gültigen Bereichs" -#: utils/adt/date.c:259 utils/adt/date.c:269 utils/adt/timestamp.c:592 +#: utils/adt/date.c:261 utils/adt/date.c:271 utils/adt/timestamp.c:596 #, c-format msgid "date field value out of range: %d-%02d-%02d" msgstr "Datum-Feldwert ist außerhalb des gültigen Bereichs: %d-%02d-%02d" -#: utils/adt/date.c:276 utils/adt/date.c:285 utils/adt/timestamp.c:598 +#: utils/adt/date.c:278 utils/adt/date.c:287 utils/adt/timestamp.c:602 #, c-format msgid "date out of range: %d-%02d-%02d" msgstr "date ist außerhalb des gültigen Bereichs: %d-%02d-%02d" -#: utils/adt/date.c:553 +#: utils/adt/date.c:556 #, c-format msgid "cannot subtract infinite dates" msgstr "kann unendliche date-Werte nicht subtrahieren" -#: utils/adt/date.c:641 utils/adt/date.c:693 utils/adt/date.c:718 -#: utils/adt/date.c:2995 utils/adt/date.c:3005 +#: utils/adt/date.c:646 utils/adt/date.c:698 utils/adt/date.c:723 +#: utils/adt/date.c:3032 utils/adt/date.c:3042 #, c-format msgid "date out of range for timestamp" msgstr "Datum ist außerhalb des gültigen Bereichs für Typ »timestamp«" -#: utils/adt/date.c:1143 utils/adt/date.c:1226 utils/adt/date.c:1242 -#: utils/adt/date.c:2304 utils/adt/date.c:3100 utils/adt/timestamp.c:4700 -#: utils/adt/timestamp.c:4791 utils/adt/timestamp.c:4939 -#: utils/adt/timestamp.c:5040 utils/adt/timestamp.c:5155 -#: utils/adt/timestamp.c:5207 utils/adt/timestamp.c:5464 -#: utils/adt/timestamp.c:5665 utils/adt/timestamp.c:5712 -#: utils/adt/timestamp.c:5936 utils/adt/timestamp.c:5983 -#: utils/adt/timestamp.c:6064 utils/adt/timestamp.c:6208 +#: utils/adt/date.c:1149 utils/adt/date.c:1232 utils/adt/date.c:1248 +#: utils/adt/date.c:2333 utils/adt/date.c:3138 utils/adt/timestamp.c:4729 +#: utils/adt/timestamp.c:4820 utils/adt/timestamp.c:4969 +#: utils/adt/timestamp.c:5070 utils/adt/timestamp.c:5188 +#: utils/adt/timestamp.c:5240 utils/adt/timestamp.c:5503 +#: utils/adt/timestamp.c:5705 utils/adt/timestamp.c:5752 +#: utils/adt/timestamp.c:5977 utils/adt/timestamp.c:6024 +#: utils/adt/timestamp.c:6105 utils/adt/timestamp.c:6250 #, c-format msgid "unit \"%s\" not supported for type %s" msgstr "Einheit »%s« nicht unterstützt für Typ %s" -#: utils/adt/date.c:1251 utils/adt/date.c:2320 utils/adt/date.c:3120 -#: utils/adt/timestamp.c:4805 utils/adt/timestamp.c:5057 -#: utils/adt/timestamp.c:5221 utils/adt/timestamp.c:5424 -#: utils/adt/timestamp.c:5721 utils/adt/timestamp.c:5992 -#: utils/adt/timestamp.c:6033 utils/adt/timestamp.c:6269 +#: utils/adt/date.c:1257 utils/adt/date.c:2349 utils/adt/date.c:3158 +#: utils/adt/timestamp.c:4834 utils/adt/timestamp.c:5087 +#: utils/adt/timestamp.c:5254 utils/adt/timestamp.c:5463 +#: utils/adt/timestamp.c:5761 utils/adt/timestamp.c:6033 +#: utils/adt/timestamp.c:6074 utils/adt/timestamp.c:6311 #, c-format msgid "unit \"%s\" not recognized for type %s" msgstr "Einheit »%s« nicht erkannt für Typ %s" -#: utils/adt/date.c:1368 utils/adt/date.c:1448 utils/adt/date.c:2008 -#: utils/adt/date.c:2039 utils/adt/date.c:2068 utils/adt/date.c:2958 -#: utils/adt/date.c:3190 utils/adt/datetime.c:433 utils/adt/datetime.c:1827 -#: utils/adt/ddlutils.c:416 utils/adt/formatting.c:3976 +#: utils/adt/date.c:1378 utils/adt/date.c:1460 utils/adt/date.c:2029 +#: utils/adt/date.c:2061 utils/adt/date.c:2091 utils/adt/date.c:2994 +#: utils/adt/date.c:3229 utils/adt/datetime.c:433 utils/adt/datetime.c:1833 +#: utils/adt/ddlutils.c:247 utils/adt/formatting.c:3976 #: utils/adt/formatting.c:4012 utils/adt/formatting.c:4097 #: utils/adt/formatting.c:4216 utils/adt/json.c:374 utils/adt/json.c:413 -#: utils/adt/timestamp.c:241 utils/adt/timestamp.c:273 -#: utils/adt/timestamp.c:699 utils/adt/timestamp.c:708 -#: utils/adt/timestamp.c:786 utils/adt/timestamp.c:819 -#: utils/adt/timestamp.c:3101 utils/adt/timestamp.c:3110 -#: utils/adt/timestamp.c:3127 utils/adt/timestamp.c:3132 -#: utils/adt/timestamp.c:3151 utils/adt/timestamp.c:3164 -#: utils/adt/timestamp.c:3175 utils/adt/timestamp.c:3181 -#: utils/adt/timestamp.c:3187 utils/adt/timestamp.c:3192 -#: utils/adt/timestamp.c:3245 utils/adt/timestamp.c:3254 -#: utils/adt/timestamp.c:3275 utils/adt/timestamp.c:3280 -#: utils/adt/timestamp.c:3301 utils/adt/timestamp.c:3314 -#: utils/adt/timestamp.c:3328 utils/adt/timestamp.c:3336 -#: utils/adt/timestamp.c:3342 utils/adt/timestamp.c:3347 -#: utils/adt/timestamp.c:4415 utils/adt/timestamp.c:4567 -#: utils/adt/timestamp.c:4643 utils/adt/timestamp.c:4709 -#: utils/adt/timestamp.c:4799 utils/adt/timestamp.c:4878 -#: utils/adt/timestamp.c:4948 utils/adt/timestamp.c:5051 -#: utils/adt/timestamp.c:5529 utils/adt/timestamp.c:5803 -#: utils/adt/timestamp.c:6337 utils/adt/timestamp.c:6347 -#: utils/adt/timestamp.c:6352 utils/adt/timestamp.c:6358 -#: utils/adt/timestamp.c:6398 utils/adt/timestamp.c:6476 -#: utils/adt/timestamp.c:6545 utils/adt/timestamp.c:6556 -#: utils/adt/timestamp.c:6611 utils/adt/timestamp.c:6615 -#: utils/adt/timestamp.c:6621 utils/adt/timestamp.c:6662 utils/adt/xml.c:2618 +#: utils/adt/timestamp.c:243 utils/adt/timestamp.c:275 +#: utils/adt/timestamp.c:703 utils/adt/timestamp.c:712 +#: utils/adt/timestamp.c:791 utils/adt/timestamp.c:824 +#: utils/adt/timestamp.c:3121 utils/adt/timestamp.c:3130 +#: utils/adt/timestamp.c:3147 utils/adt/timestamp.c:3152 +#: utils/adt/timestamp.c:3171 utils/adt/timestamp.c:3184 +#: utils/adt/timestamp.c:3195 utils/adt/timestamp.c:3201 +#: utils/adt/timestamp.c:3207 utils/adt/timestamp.c:3212 +#: utils/adt/timestamp.c:3266 utils/adt/timestamp.c:3275 +#: utils/adt/timestamp.c:3296 utils/adt/timestamp.c:3301 +#: utils/adt/timestamp.c:3322 utils/adt/timestamp.c:3335 +#: utils/adt/timestamp.c:3349 utils/adt/timestamp.c:3357 +#: utils/adt/timestamp.c:3363 utils/adt/timestamp.c:3368 +#: utils/adt/timestamp.c:4441 utils/adt/timestamp.c:4594 +#: utils/adt/timestamp.c:4671 utils/adt/timestamp.c:4738 +#: utils/adt/timestamp.c:4828 utils/adt/timestamp.c:4908 +#: utils/adt/timestamp.c:4978 utils/adt/timestamp.c:5081 +#: utils/adt/timestamp.c:5569 utils/adt/timestamp.c:5844 +#: utils/adt/timestamp.c:6380 utils/adt/timestamp.c:6390 +#: utils/adt/timestamp.c:6395 utils/adt/timestamp.c:6401 +#: utils/adt/timestamp.c:6442 utils/adt/timestamp.c:6522 +#: utils/adt/timestamp.c:6592 utils/adt/timestamp.c:6603 +#: utils/adt/timestamp.c:6659 utils/adt/timestamp.c:6663 +#: utils/adt/timestamp.c:6669 utils/adt/timestamp.c:6711 utils/adt/xml.c:2618 #: utils/adt/xml.c:2625 utils/adt/xml.c:2645 utils/adt/xml.c:2652 #, c-format msgid "timestamp out of range" msgstr "timestamp ist außerhalb des gültigen Bereichs" -#: utils/adt/date.c:1625 utils/adt/date.c:2441 utils/adt/formatting.c:4297 +#: utils/adt/date.c:1641 utils/adt/date.c:2471 utils/adt/formatting.c:4297 #, c-format msgid "time out of range" msgstr "time ist außerhalb des gültigen Bereichs" -#: utils/adt/date.c:1677 utils/adt/timestamp.c:607 +#: utils/adt/date.c:1693 utils/adt/timestamp.c:611 #, c-format msgid "time field value out of range: %d:%02d:%02g" msgstr "Zeit-Feldwert ist außerhalb des gültigen Bereichs: %d:%02d:%02g" -#: utils/adt/date.c:2109 +#: utils/adt/date.c:2134 #, c-format msgid "cannot convert infinite interval to time" msgstr "kann unendlichen interval-Wert nicht in time umwandeln" -#: utils/adt/date.c:2150 utils/adt/date.c:2694 +#: utils/adt/date.c:2177 utils/adt/date.c:2727 #, c-format msgid "cannot add infinite interval to time" msgstr "kann unendlichen interval-Wert nicht zu time addieren" -#: utils/adt/date.c:2173 utils/adt/date.c:2721 +#: utils/adt/date.c:2201 utils/adt/date.c:2755 #, c-format msgid "cannot subtract infinite interval from time" msgstr "kann unendlichen interval-Wert nicht von time subtrahieren" -#: utils/adt/date.c:2204 utils/adt/date.c:2756 utils/adt/float.c:1084 +#: utils/adt/date.c:2232 utils/adt/date.c:2790 utils/adt/float.c:1084 #: utils/adt/float.c:1160 utils/adt/int.c:664 utils/adt/int.c:711 -#: utils/adt/int.c:746 utils/adt/int8.c:413 utils/adt/numeric.c:2598 -#: utils/adt/timestamp.c:3845 utils/adt/timestamp.c:3882 -#: utils/adt/timestamp.c:3923 +#: utils/adt/int.c:746 utils/adt/int8.c:420 utils/adt/numeric.c:2604 +#: utils/adt/timestamp.c:3870 utils/adt/timestamp.c:3907 +#: utils/adt/timestamp.c:3948 #, c-format msgid "invalid preceding or following size in window function" msgstr "ungültige vorhergehende oder folgende Größe in Fensterfunktion" -#: utils/adt/date.c:2449 +#: utils/adt/date.c:2479 #, c-format msgid "time zone displacement out of range" msgstr "Zeitzonenunterschied ist außerhalb des gültigen Bereichs" -#: utils/adt/date.c:3221 utils/adt/timestamp.c:6380 utils/adt/timestamp.c:6644 +#: utils/adt/date.c:3261 utils/adt/timestamp.c:6424 utils/adt/timestamp.c:6693 #, c-format msgid "interval time zone \"%s\" must be finite" msgstr "Intervall-Zeitzone »%s« muss endlich sein" -#: utils/adt/date.c:3228 utils/adt/timestamp.c:6387 utils/adt/timestamp.c:6651 +#: utils/adt/date.c:3268 utils/adt/timestamp.c:6431 utils/adt/timestamp.c:6700 #, c-format msgid "interval time zone \"%s\" must not include months or days" msgstr "Intervall-Zeitzone »%s« darf keine Monate oder Tage enthalten" -#: utils/adt/datetime.c:3331 utils/adt/datetime.c:4250 -#: utils/adt/datetime.c:4256 utils/adt/timestamp.c:522 +#: utils/adt/datetime.c:3351 utils/adt/datetime.c:4276 +#: utils/adt/datetime.c:4282 utils/adt/timestamp.c:526 #, c-format msgid "time zone \"%s\" not recognized" msgstr "Zeitzone »%s« nicht erkannt" -#: utils/adt/datetime.c:4224 utils/adt/datetime.c:4231 +#: utils/adt/datetime.c:4250 utils/adt/datetime.c:4257 #, c-format msgid "date/time field value out of range: \"%s\"" msgstr "Datum/Zeit-Feldwert ist außerhalb des gültigen Bereichs: »%s«" -#: utils/adt/datetime.c:4233 +#: utils/adt/datetime.c:4259 #, c-format msgid "Perhaps you need a different \"DateStyle\" setting." msgstr "Möglicherweise benötigen Sie eine andere »DateStyle«-Einstellung." -#: utils/adt/datetime.c:4238 +#: utils/adt/datetime.c:4264 #, c-format msgid "interval field value out of range: \"%s\"" msgstr "»interval«-Feldwert ist außerhalb des gültigen Bereichs: »%s«" -#: utils/adt/datetime.c:4244 +#: utils/adt/datetime.c:4270 #, c-format msgid "time zone displacement out of range: \"%s\"" msgstr "Zeitzonenunterschied ist außerhalb des gültigen Bereichs: »%s«" -#: utils/adt/datetime.c:4258 +#: utils/adt/datetime.c:4284 #, c-format msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." msgstr "Dieser Zeitzonenname erscheint in der Konfigurationsdatei für Zeitzonenabkürzung »%s«." @@ -31615,7 +31894,8 @@ msgstr "Dieser Zeitzonenname erscheint in der Konfigurationsdatei für Zeitzonen msgid "invalid Datum pointer" msgstr "ungültiger »Datum«-Zeiger" -#: utils/adt/dbsize.c:293 utils/adt/ddlutils.c:674 utils/adt/genfile.c:657 +#: utils/adt/dbsize.c:293 utils/adt/ddlutils.c:495 utils/adt/ddlutils.c:790 +#: utils/adt/genfile.c:657 #, c-format msgid "tablespace with OID %u does not exist" msgstr "Tablespace mit OID %u existiert nicht" @@ -31635,83 +31915,65 @@ msgstr "Ungültige Größeneinheit: »%s«." msgid "Valid units are \"bytes\", \"B\", \"kB\", \"MB\", \"GB\", \"TB\", and \"PB\"." msgstr "Gültige Einheiten sind »bytes«, »B«, »kB«, »MB«, »GB«, »TB« und »PB«." -#: utils/adt/ddlutils.c:157 -#, fuzzy, c-format -#| msgid "name at variadic position %d is null" -msgid "option name at variadic position %d is null" -msgstr "Name auf variadischer Position %d ist NULL" - -#: utils/adt/ddlutils.c:164 -#, fuzzy, c-format -#| msgid "argument \"%s\" must not be null" -msgid "value for option \"%s\" must not be null" -msgstr "Argument »%s« darf nicht NULL sein" - -#: utils/adt/ddlutils.c:179 -#, fuzzy, c-format -#| msgid "unrecognized %s option \"%s\"" -msgid "unrecognized option: \"%s\"" -msgstr "unbekannte %s-Option »%s«" - -#: utils/adt/ddlutils.c:184 -#, fuzzy, c-format -#| msgid "column \"%s\" specified more than once" -msgid "option \"%s\" is specified more than once" -msgstr "Spalte »%s« mehrmals angegeben" - -#: utils/adt/ddlutils.c:335 utils/init/miscinit.c:762 +#: utils/adt/ddlutils.c:166 utils/init/miscinit.c:762 #, c-format msgid "role with OID %u does not exist" msgstr "Rolle mit OID %u existiert nicht" -#: utils/adt/ddlutils.c:346 +#: utils/adt/ddlutils.c:177 #, fuzzy, c-format #| msgid "permission denied for routine %s" msgid "permission denied for role %s" msgstr "keine Berechtigung für Routine %s" -#: utils/adt/ddlutils.c:357 +#: utils/adt/ddlutils.c:188 #, fuzzy, c-format #| msgid "Role names starting with \"pg_\" are reserved." msgid "Role names starting with \"pg_\" are reserved for system roles." msgstr "Rollennamen, die mit »pg_« anfangen, sind reserviert." -#: utils/adt/ddlutils.c:694 +#: utils/adt/ddlutils.c:515 #, fuzzy, c-format #| msgid "role name \"%s\" is reserved" msgid "tablespace name \"%s\" is reserved" msgstr "Rollenname »%s« ist reserviert" -#: utils/adt/ddlutils.c:695 +#: utils/adt/ddlutils.c:516 #, fuzzy, c-format #| msgid "The prefix \"pg_\" is reserved for system tablespaces." msgid "Tablespace names starting with \"pg_\" are reserved for system tablespaces." msgstr "Der Präfix »pg_« ist für System-Tablespaces reserviert." -#: utils/adt/ddlutils.c:897 +#: utils/adt/ddlutils.c:695 #, fuzzy, c-format #| msgid "cannot alter invalid database \"%s\"" msgid "cannot generate DDL for invalid database \"%s\"" msgstr "ungültige Datenbank »%s« kann nicht geändert werden" -#: utils/adt/ddlutils.c:907 +#: utils/adt/ddlutils.c:705 #, fuzzy, c-format #| msgid "database \"%s\" has disappeared from pg_database" msgid "database \"%s\" is a system database" msgstr "Datenbank »%s« ist aus pg_database verschwunden" -#: utils/adt/ddlutils.c:908 +#: utils/adt/ddlutils.c:706 #, fuzzy, c-format #| msgid "This operation is not supported for temporary tables." msgid "DDL generation is not supported for template0 and template1." msgstr "Diese Operation wird für temporäre Tabellen nicht unterstützt." -#: utils/adt/ddlutils.c:937 +#: utils/adt/ddlutils.c:735 #, fuzzy, c-format #| msgid "unrecognized locale provider: %s" msgid "unrecognized locale provider: %c" msgstr "unbekannter Locale-Provider: %s" +#: utils/adt/ddlutils.c:792 +#, fuzzy, c-format +#| msgid "database %u was concurrently dropped" +msgid "It may have been concurrently dropped." +msgstr "Datenbank %u wurde gleichzeitig gelöscht" + #: utils/adt/domains.c:95 #, c-format msgid "type %s is not a domain" @@ -31835,29 +32097,29 @@ msgstr "»%s« ist außerhalb des gültigen Bereichs für Typ real" msgid "\"%s\" is out of range for type double precision" msgstr "»%s« ist außerhalb des gültigen Bereichs für Typ double precision" -#: utils/adt/float.c:1495 utils/adt/numeric.c:3675 utils/adt/numeric.c:9996 +#: utils/adt/float.c:1495 utils/adt/numeric.c:3681 utils/adt/numeric.c:10002 #, c-format msgid "cannot take square root of a negative number" msgstr "Quadratwurzel von negativer Zahl kann nicht ermittelt werden" -#: utils/adt/float.c:1563 utils/adt/numeric.c:3963 utils/adt/numeric.c:4075 +#: utils/adt/float.c:1563 utils/adt/numeric.c:3969 utils/adt/numeric.c:4081 #, c-format msgid "zero raised to a negative power is undefined" msgstr "null hoch eine negative Zahl ist undefiniert" -#: utils/adt/float.c:1567 utils/adt/numeric.c:3967 utils/adt/numeric.c:10887 +#: utils/adt/float.c:1567 utils/adt/numeric.c:3973 utils/adt/numeric.c:10893 #, c-format msgid "a negative number raised to a non-integer power yields a complex result" msgstr "eine negative Zahl hoch eine nicht ganze Zahl ergibt ein komplexes Ergebnis" -#: utils/adt/float.c:1743 utils/adt/float.c:1776 utils/adt/numeric.c:3875 -#: utils/adt/numeric.c:10667 +#: utils/adt/float.c:1743 utils/adt/float.c:1776 utils/adt/numeric.c:3881 +#: utils/adt/numeric.c:10673 #, c-format msgid "cannot take logarithm of zero" msgstr "Logarithmus von null kann nicht ermittelt werden" -#: utils/adt/float.c:1747 utils/adt/float.c:1780 utils/adt/numeric.c:3813 -#: utils/adt/numeric.c:3870 utils/adt/numeric.c:10671 +#: utils/adt/float.c:1747 utils/adt/float.c:1780 utils/adt/numeric.c:3819 +#: utils/adt/numeric.c:3876 utils/adt/numeric.c:10677 #, c-format msgid "cannot take logarithm of a negative number" msgstr "Logarithmus negativer Zahlen kann nicht ermittelt werden" @@ -31871,25 +32133,25 @@ msgstr "Logarithmus negativer Zahlen kann nicht ermittelt werden" msgid "input is out of range" msgstr "Eingabe ist außerhalb des gültigen Bereichs" -#: utils/adt/float.c:4240 utils/adt/numeric.c:1965 +#: utils/adt/float.c:4308 utils/adt/numeric.c:1971 #, c-format msgid "count must be greater than zero" msgstr "Anzahl muss größer als null sein" -#: utils/adt/float.c:4245 utils/adt/numeric.c:1972 +#: utils/adt/float.c:4313 utils/adt/numeric.c:1978 #, fuzzy, c-format #| msgid "lower bound cannot be NaN" msgid "lower and upper bounds cannot be NaN" msgstr "Untergrenze kann nicht NaN sein" -#: utils/adt/float.c:4250 utils/adt/numeric.c:1977 +#: utils/adt/float.c:4318 utils/adt/numeric.c:1983 #: utils/adt/pseudorandomfuncs.c:214 utils/adt/pseudorandomfuncs.c:240 #: utils/adt/pseudorandomfuncs.c:266 #, c-format msgid "lower and upper bounds must be finite" msgstr "Untergrenze und Obergrenze müssen endlich sein" -#: utils/adt/float.c:4316 utils/adt/numeric.c:1991 +#: utils/adt/float.c:4384 utils/adt/numeric.c:1997 #, c-format msgid "lower bound cannot equal upper bound" msgstr "Untergrenze kann nicht gleich der Obergrenze sein" @@ -32196,48 +32458,48 @@ msgstr "konnte Positionszeiger in Datei »%s« nicht setzen: %m" msgid "file length too large" msgstr "Dateilänge zu groß" -#: utils/adt/geo_ops.c:1016 utils/adt/geo_ops.c:1070 +#: utils/adt/geo_ops.c:1044 utils/adt/geo_ops.c:1098 #, c-format msgid "invalid line specification: A and B cannot both be zero" msgstr "ungültige »line«-Angabe: A und B können nicht beide null sein" -#: utils/adt/geo_ops.c:1026 utils/adt/geo_ops.c:1142 +#: utils/adt/geo_ops.c:1054 utils/adt/geo_ops.c:1171 #, c-format msgid "invalid line specification: must be two distinct points" msgstr "ungültige »line«-Angabe: es müssen zwei verschiedene Punkte angegeben werden" -#: utils/adt/geo_ops.c:1456 utils/adt/geo_ops.c:3485 utils/adt/geo_ops.c:4424 -#: utils/adt/geo_ops.c:5348 +#: utils/adt/geo_ops.c:1487 utils/adt/geo_ops.c:3522 utils/adt/geo_ops.c:4462 +#: utils/adt/geo_ops.c:5414 #, c-format msgid "too many points requested" msgstr "zu viele Punkte verlangt" -#: utils/adt/geo_ops.c:1520 +#: utils/adt/geo_ops.c:1551 #, c-format msgid "invalid number of points in external \"path\" value" msgstr "ungültige Anzahl Punkte in externem »path«-Wert" -#: utils/adt/geo_ops.c:3534 +#: utils/adt/geo_ops.c:3571 #, c-format msgid "invalid number of points in external \"polygon\" value" msgstr "ungültige Anzahl Punkte in externem »polygon«-Wert" -#: utils/adt/geo_ops.c:4519 +#: utils/adt/geo_ops.c:4559 #, c-format msgid "open path cannot be converted to polygon" msgstr "offener Pfad kann nicht in Polygon umgewandelt werden" -#: utils/adt/geo_ops.c:4777 +#: utils/adt/geo_ops.c:4820 #, c-format msgid "invalid radius in external \"circle\" value" msgstr "ungültiger Radius in externem »circle«-Wert" -#: utils/adt/geo_ops.c:5334 +#: utils/adt/geo_ops.c:5400 #, c-format msgid "cannot convert circle with radius zero to polygon" msgstr "kann Kreis mit Radius null nicht in Polygon umwandeln" -#: utils/adt/geo_ops.c:5339 +#: utils/adt/geo_ops.c:5405 #, c-format msgid "must request at least 2 points" msgstr "mindestens 2 Punkte müssen angefordert werden" @@ -32252,13 +32514,13 @@ msgstr "Array ist kein gültiger int2vector" msgid "invalid int2vector data" msgstr "ungültige int2vector-Daten" -#: utils/adt/int.c:1558 utils/adt/int8.c:1411 utils/adt/numeric.c:1752 -#: utils/adt/timestamp.c:6710 utils/adt/timestamp.c:6795 +#: utils/adt/int.c:1559 utils/adt/int8.c:1453 utils/adt/numeric.c:1758 +#: utils/adt/timestamp.c:6760 utils/adt/timestamp.c:6846 #, c-format msgid "step size cannot equal zero" msgstr "Schrittgröße kann nicht gleich null sein" -#: utils/adt/int8.c:1360 +#: utils/adt/int8.c:1402 #, c-format msgid "OID out of range" msgstr "OID ist außerhalb des gültigen Bereichs" @@ -32677,8 +32939,8 @@ msgstr "Jsonpath-Item-Methode .%s() kann nur auf ein Array angewendet werden" #: utils/adt/jsonpath_exec.c:1195 utils/adt/jsonpath_exec.c:1221 #: utils/adt/jsonpath_exec.c:1307 utils/adt/jsonpath_exec.c:1332 #: utils/adt/jsonpath_exec.c:1383 utils/adt/jsonpath_exec.c:1403 -#: utils/adt/jsonpath_exec.c:1464 utils/adt/jsonpath_exec.c:1552 -#: utils/adt/jsonpath_exec.c:1585 utils/adt/jsonpath_exec.c:1609 +#: utils/adt/jsonpath_exec.c:1464 utils/adt/jsonpath_exec.c:1541 +#: utils/adt/jsonpath_exec.c:1573 utils/adt/jsonpath_exec.c:1597 #, c-format msgid "argument \"%s\" of jsonpath item method .%s() is invalid for type %s" msgstr "Argument »%s« der JSON-Path-Item-Methode .%s() ist ungültig für Typ %s" @@ -32690,7 +32952,7 @@ msgid "NaN or Infinity is not allowed for jsonpath item method .%s()" msgstr "NaN oder unendliche Werte sind für JSON-Path-Item-Methode .%s() nicht erlaubt" #: utils/adt/jsonpath_exec.c:1239 utils/adt/jsonpath_exec.c:1340 -#: utils/adt/jsonpath_exec.c:1480 utils/adt/jsonpath_exec.c:1617 +#: utils/adt/jsonpath_exec.c:1480 utils/adt/jsonpath_exec.c:1605 #, c-format msgid "jsonpath item method .%s() can only be applied to a string or numeric value" msgstr "JSON-Path-Item-Methode .%s() kann nur auf eine Zeichenkette oder einen numerischen Wert angewendet werden" @@ -32700,135 +32962,147 @@ msgstr "JSON-Path-Item-Methode .%s() kann nur auf eine Zeichenkette oder einen n msgid "jsonpath item method .%s() can only be applied to a boolean, string, or numeric value" msgstr "JSON-Path-Item-Methode .%s() kann nur auf boolean, eine Zeichenkette oder einen numerischen Wert angewendet werden" -#: utils/adt/jsonpath_exec.c:1511 +#: utils/adt/jsonpath_exec.c:1507 #, c-format msgid "precision of jsonpath item method .%s() is out of range for type integer" msgstr "Präzision der JSON-Path-Item-Methode .%s() ist außerhalb des gültigen Bereichs für Typ integer" -#: utils/adt/jsonpath_exec.c:1525 +#: utils/adt/jsonpath_exec.c:1521 #, c-format msgid "scale of jsonpath item method .%s() is out of range for type integer" msgstr "Skala der JSON-Path-Item-Methode .%s() ist außerhalb des gültigen Bereichs für Typ integer" -#: utils/adt/jsonpath_exec.c:1671 +#: utils/adt/jsonpath_exec.c:1659 #, c-format msgid "jsonpath item method .%s() can only be applied to a boolean, string, numeric, or datetime value" msgstr "JSON-Path-Item-Methode .%s() kann nur auf boolean, eine Zeichenkette, einen numerischen Wert oder einen datetime-Wert angewendet werden" -#: utils/adt/jsonpath_exec.c:2220 +#: utils/adt/jsonpath_exec.c:2208 #, c-format msgid "left operand of jsonpath operator %s is not a single numeric value" msgstr "linker Operand des JSON-Path-Operators %s ist kein einzelner numerischer Wert" -#: utils/adt/jsonpath_exec.c:2231 +#: utils/adt/jsonpath_exec.c:2219 #, c-format msgid "right operand of jsonpath operator %s is not a single numeric value" msgstr "rechter Operand des JSON-Path-Operators %s ist kein einzelner numerischer Wert" -#: utils/adt/jsonpath_exec.c:2312 +#: utils/adt/jsonpath_exec.c:2300 #, c-format msgid "operand of unary jsonpath operator %s is not a numeric value" msgstr "Operand des unären JSON-Path-Operators %s ist kein numerischer Wert" -#: utils/adt/jsonpath_exec.c:2418 +#: utils/adt/jsonpath_exec.c:2406 #, c-format msgid "jsonpath item method .%s() can only be applied to a numeric value" msgstr "JSON-Path-Item-Methode .%s() kann nur auf einen numerischen Wert angewendet werden" -#: utils/adt/jsonpath_exec.c:2463 utils/adt/jsonpath_exec.c:2929 +#: utils/adt/jsonpath_exec.c:2451 utils/adt/jsonpath_exec.c:2917 #, c-format msgid "jsonpath item method .%s() can only be applied to a string" msgstr "JSON-Path-Item-Methode .%s() kann nur auf eine Zeichenkette angewendet werden" -#: utils/adt/jsonpath_exec.c:2556 +#: utils/adt/jsonpath_exec.c:2544 #, c-format msgid "time precision of jsonpath item method .%s() is out of range for type integer" msgstr "Zeitpräzision der JSON-Path-Item-Methode .%s() ist außerhalb des gültigen Bereichs für Typ integer" -#: utils/adt/jsonpath_exec.c:2590 utils/adt/jsonpath_exec.c:2596 -#: utils/adt/jsonpath_exec.c:2623 utils/adt/jsonpath_exec.c:2651 -#: utils/adt/jsonpath_exec.c:2704 utils/adt/jsonpath_exec.c:2755 -#: utils/adt/jsonpath_exec.c:2826 +#: utils/adt/jsonpath_exec.c:2578 utils/adt/jsonpath_exec.c:2584 +#: utils/adt/jsonpath_exec.c:2611 utils/adt/jsonpath_exec.c:2639 +#: utils/adt/jsonpath_exec.c:2692 utils/adt/jsonpath_exec.c:2743 +#: utils/adt/jsonpath_exec.c:2814 #, c-format msgid "%s format is not recognized: \"%s\"" msgstr "%s-Format wird nicht erkannt: »%s«" -#: utils/adt/jsonpath_exec.c:2592 +#: utils/adt/jsonpath_exec.c:2580 #, c-format msgid "Use a datetime template argument to specify the input data format." msgstr "Verwenden Sie das Template-Argument für .datetime(), um das Eingabeformat anzugeben." -#: utils/adt/jsonpath_exec.c:2785 utils/adt/jsonpath_exec.c:2866 +#: utils/adt/jsonpath_exec.c:2773 utils/adt/jsonpath_exec.c:2854 #, c-format msgid "time precision of jsonpath item method .%s() is invalid" msgstr "Zeitpräzision der JSON-Path-Item-Methode .%s() ist ungültig" -#: utils/adt/jsonpath_exec.c:3104 +#: utils/adt/jsonpath_exec.c:3026 +#, fuzzy, c-format +#| msgid "time precision of jsonpath item method .%s() is out of range for type integer" +msgid "field position of jsonpath item method .%s() is out of range for type integer" +msgstr "Zeitpräzision der JSON-Path-Item-Methode .%s() ist außerhalb des gültigen Bereichs für Typ integer" + +#: utils/adt/jsonpath_exec.c:3032 +#, fuzzy, c-format +#| msgid "time precision of jsonpath item method .%s() is invalid" +msgid "field position of jsonpath item method .%s() must not be zero" +msgstr "Zeitpräzision der JSON-Path-Item-Methode .%s() ist ungültig" + +#: utils/adt/jsonpath_exec.c:3105 #, c-format msgid "jsonpath item method .%s() can only be applied to an object" msgstr "JSON-Path-Item-Methode .%s() kann nur auf ein Objekt angewendet werden" -#: utils/adt/jsonpath_exec.c:3388 +#: utils/adt/jsonpath_exec.c:3389 #, c-format msgid "could not convert value of type %s to jsonpath" msgstr "konnte Wert vom Typ %s nicht in jsonpath umwandeln" -#: utils/adt/jsonpath_exec.c:3422 +#: utils/adt/jsonpath_exec.c:3423 #, c-format msgid "could not find jsonpath variable \"%s\"" msgstr "konnte JSON-Path-Variable »%s« nicht finden" -#: utils/adt/jsonpath_exec.c:3475 +#: utils/adt/jsonpath_exec.c:3476 #, c-format msgid "\"vars\" argument is not an object" msgstr "Argument »vars« ist kein Objekt" -#: utils/adt/jsonpath_exec.c:3476 +#: utils/adt/jsonpath_exec.c:3477 #, c-format msgid "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." msgstr "JSON-Path-Parameter sollten als Schüssel-Wert-Paare im »vars«-Objekt kodiert werden." -#: utils/adt/jsonpath_exec.c:3748 +#: utils/adt/jsonpath_exec.c:3749 #, c-format msgid "jsonpath array subscript is not a single numeric value" msgstr "JSON-Path-Arrayindex ist kein einzelner numerischer Wert" -#: utils/adt/jsonpath_exec.c:3763 +#: utils/adt/jsonpath_exec.c:3764 #, c-format msgid "jsonpath array subscript is out of integer range" msgstr "JSON-Path-Arrayindex ist außerhalb des gültigen Bereichs für ganze Zahlen" -#: utils/adt/jsonpath_exec.c:3985 +#: utils/adt/jsonpath_exec.c:3986 #, c-format msgid "cannot convert value from %s to %s without time zone usage" msgstr "Wert kann nicht von %s nach %s konvertiert werden ohne Verwendung von Zeitzonen" -#: utils/adt/jsonpath_exec.c:3987 +#: utils/adt/jsonpath_exec.c:3988 #, c-format msgid "Use *_tz() function for time zone support." msgstr "Verwenden Sie die *_tz()-Funktion für Zeitzonenunterstützung." -#: utils/adt/jsonpath_exec.c:4291 +#: utils/adt/jsonpath_exec.c:4292 #, c-format msgid "JSON path expression for column \"%s\" must return single item when no wrapper is requested" msgstr "JSON-Path-Ausdruck für Spalte »%s« muss ein einzelnes Element zurückgeben, wenn kein Wrapper angefordert wurde" -#: utils/adt/jsonpath_exec.c:4293 utils/adt/jsonpath_exec.c:4298 +#: utils/adt/jsonpath_exec.c:4294 utils/adt/jsonpath_exec.c:4299 #, c-format msgid "Use the WITH WRAPPER clause to wrap SQL/JSON items into an array." msgstr "Verwenden Sie die WITH-WRAPPER-Klausel, um SQL/JSON-Elemente in ein Array einzupacken." -#: utils/adt/jsonpath_exec.c:4297 +#: utils/adt/jsonpath_exec.c:4298 #, c-format msgid "JSON path expression in JSON_QUERY must return single item when no wrapper is requested" msgstr "JSON-Pfad-Ausdruck in JSON_QUERY muss ein einzelnes Element zurückgeben, wenn kein Wrapper angefordert wurde" -#: utils/adt/jsonpath_exec.c:4354 utils/adt/jsonpath_exec.c:4378 +#: utils/adt/jsonpath_exec.c:4355 utils/adt/jsonpath_exec.c:4379 #, c-format msgid "JSON path expression for column \"%s\" must return single scalar item" msgstr "JSON-Path-Ausdruck für Spalte »%s« muss ein einzelnes skalares Element zurückgeben" -#: utils/adt/jsonpath_exec.c:4359 utils/adt/jsonpath_exec.c:4383 +#: utils/adt/jsonpath_exec.c:4360 utils/adt/jsonpath_exec.c:4384 #, c-format msgid "JSON path expression in JSON_VALUE must return single scalar item" msgstr "JSON-Pfad-Ausdruck in JSON_VALUE muss ein einzelnes skalares Element zurückgeben" @@ -32843,7 +33117,7 @@ msgstr "Levenshtein-Argument überschreitet die maximale Länge von %d Zeichen" msgid "could not determine which collation to use for LIKE" msgstr "konnte die für LIKE zu verwendende Sortierfolge nicht bestimmen" -#: utils/adt/like.c:181 utils/adt/like_support.c:1094 +#: utils/adt/like.c:181 utils/adt/like_support.c:1106 #, c-format msgid "could not determine which collation to use for ILIKE" msgstr "konnte die für ILIKE zu verwendende Sortierfolge nicht bestimmen" @@ -32853,28 +33127,28 @@ msgstr "konnte die für ILIKE zu verwendende Sortierfolge nicht bestimmen" msgid "nondeterministic collations are not supported for ILIKE" msgstr "nichtdeterministische Sortierfolgen werden von ILIKE nicht unterstützt" -#: utils/adt/like_match.c:111 utils/adt/like_match.c:173 -#: utils/adt/like_match.c:241 +#: utils/adt/like_match.c:168 utils/adt/like_match.c:236 +#: utils/adt/like_match.c:356 #, c-format msgid "LIKE pattern must not end with escape character" msgstr "LIKE-Muster darf nicht mit Escape-Zeichen enden" -#: utils/adt/like_match.c:441 utils/adt/regexp.c:804 +#: utils/adt/like_match.c:452 utils/adt/regexp.c:804 #, c-format msgid "invalid escape string" msgstr "ungültige ESCAPE-Zeichenkette" -#: utils/adt/like_match.c:442 utils/adt/regexp.c:805 +#: utils/adt/like_match.c:453 utils/adt/regexp.c:805 #, c-format msgid "Escape string must be empty or one character." msgstr "ESCAPE-Zeichenkette muss null oder ein Zeichen lang sein." -#: utils/adt/like_support.c:1084 +#: utils/adt/like_support.c:1096 #, c-format msgid "case insensitive matching not supported on type bytea" msgstr "Mustersuche ohne Rücksicht auf Groß-/Kleinschreibung wird für Typ bytea nicht unterstützt" -#: utils/adt/like_support.c:1180 +#: utils/adt/like_support.c:1192 #, c-format msgid "regular-expression matching not supported on type bytea" msgstr "Mustersuche mit regulären Ausdrücken wird für Typ bytea nicht unterstützt" @@ -32997,12 +33271,12 @@ msgstr "Start einer Range erwartet." msgid "Expected comma or end of multirange." msgstr "Komma oder Ende der Multirange erwartet." -#: utils/adt/multirangetypes.c:986 +#: utils/adt/multirangetypes.c:987 #, c-format msgid "multiranges cannot be constructed from multidimensional arrays" msgstr "Multiranges können nicht aus mehrdimensionalen Arrays konstruiert werden" -#: utils/adt/multirangetypes.c:1012 +#: utils/adt/multirangetypes.c:1013 #, c-format msgid "multirange values cannot contain null members" msgstr "Multirange-Werte können keine Mitglieder, die NULL sind, haben" @@ -33012,7 +33286,7 @@ msgstr "Multirange-Werte können keine Mitglieder, die NULL sind, haben" msgid "invalid MultiXactId: %u" msgstr "ungültige MultiXactId: %u" -#: utils/adt/multixactfuncs.c:115 +#: utils/adt/multixactfuncs.c:109 #, fuzzy, c-format #| msgid "first argument of %s must be a row type" msgid "return type must be a row type" @@ -33107,116 +33381,116 @@ msgstr "ungültige Skala in externem »numeric«-Wert" msgid "invalid digit in external \"numeric\" value" msgstr "ungültige Ziffer in externem »numeric«-Wert" -#: utils/adt/numeric.c:1323 utils/adt/numeric.c:1337 +#: utils/adt/numeric.c:1320 #, c-format msgid "NUMERIC precision %d must be between 1 and %d" msgstr "Präzision von NUMERIC (%d) muss zwischen 1 und %d liegen" -#: utils/adt/numeric.c:1328 +#: utils/adt/numeric.c:1325 #, c-format msgid "NUMERIC scale %d must be between %d and %d" msgstr "Skala von NUMERIC (%d) muss zwischen %d und %d liegen" -#: utils/adt/numeric.c:1346 +#: utils/adt/numeric.c:1352 #, c-format msgid "invalid NUMERIC type modifier" msgstr "ungültiker Modifikator für Typ NUMERIC" -#: utils/adt/numeric.c:1712 +#: utils/adt/numeric.c:1718 #, c-format msgid "start value cannot be NaN" msgstr "Startwert kann nicht NaN sein" -#: utils/adt/numeric.c:1716 +#: utils/adt/numeric.c:1722 #, c-format msgid "start value cannot be infinity" msgstr "Startwert kann nicht unendlich sein" -#: utils/adt/numeric.c:1723 +#: utils/adt/numeric.c:1729 #, c-format msgid "stop value cannot be NaN" msgstr "Stoppwert kann nicht NaN sein" -#: utils/adt/numeric.c:1727 +#: utils/adt/numeric.c:1733 #, c-format msgid "stop value cannot be infinity" msgstr "Stoppwert kann nicht unendlich sein" -#: utils/adt/numeric.c:1740 +#: utils/adt/numeric.c:1746 #, c-format msgid "step size cannot be NaN" msgstr "Schrittgröße kann nicht NaN sein" -#: utils/adt/numeric.c:1744 +#: utils/adt/numeric.c:1750 #, c-format msgid "step size cannot be infinity" msgstr "Schrittgröße kann nicht unendlich sein" -#: utils/adt/numeric.c:3615 +#: utils/adt/numeric.c:3621 #, c-format msgid "factorial of a negative number is undefined" msgstr "Fakultät einer negativen Zahl ist undefiniert" -#: utils/adt/numeric.c:3625 utils/adt/numeric.c:6961 utils/adt/numeric.c:7164 -#: utils/adt/numeric.c:7622 utils/adt/numeric.c:10470 utils/adt/numeric.c:10945 -#: utils/adt/numeric.c:11039 utils/adt/numeric.c:11174 +#: utils/adt/numeric.c:3631 utils/adt/numeric.c:6967 utils/adt/numeric.c:7170 +#: utils/adt/numeric.c:7628 utils/adt/numeric.c:10476 utils/adt/numeric.c:10951 +#: utils/adt/numeric.c:11045 utils/adt/numeric.c:11180 #, c-format msgid "value overflows numeric format" msgstr "Wert verursacht Überlauf im »numeric«-Format" -#: utils/adt/numeric.c:4222 +#: utils/adt/numeric.c:4228 #, c-format msgid "lower bound cannot be NaN" msgstr "Untergrenze kann nicht NaN sein" -#: utils/adt/numeric.c:4226 +#: utils/adt/numeric.c:4232 #, c-format msgid "lower bound cannot be infinity" msgstr "Untergrenze kann nicht unendlich sein" -#: utils/adt/numeric.c:4233 +#: utils/adt/numeric.c:4239 #, c-format msgid "upper bound cannot be NaN" msgstr "Obergrenze kann nicht NaN sein" -#: utils/adt/numeric.c:4237 +#: utils/adt/numeric.c:4243 #, c-format msgid "upper bound cannot be infinity" msgstr "Obergrenze kann nicht unendlich sein" -#: utils/adt/numeric.c:4379 utils/adt/numeric.c:4455 utils/adt/numeric.c:4510 -#: utils/adt/numeric.c:4719 +#: utils/adt/numeric.c:4385 utils/adt/numeric.c:4461 utils/adt/numeric.c:4516 +#: utils/adt/numeric.c:4725 #, c-format msgid "cannot convert NaN to %s" msgstr "kann NaN nicht in %s umwandeln" -#: utils/adt/numeric.c:4383 utils/adt/numeric.c:4459 utils/adt/numeric.c:4514 -#: utils/adt/numeric.c:4723 +#: utils/adt/numeric.c:4389 utils/adt/numeric.c:4465 utils/adt/numeric.c:4520 +#: utils/adt/numeric.c:4729 #, c-format msgid "cannot convert infinity to %s" msgstr "kann Unendlich nicht in %s umwandeln" -#: utils/adt/numeric.c:4732 +#: utils/adt/numeric.c:4738 #, c-format msgid "pg_lsn out of range" msgstr "pg_lsn ist außerhalb des gültigen Bereichs" -#: utils/adt/numeric.c:7710 utils/adt/numeric.c:7761 +#: utils/adt/numeric.c:7716 utils/adt/numeric.c:7767 #, c-format msgid "numeric field overflow" msgstr "Feldüberlauf bei Typ »numeric«" -#: utils/adt/numeric.c:7711 +#: utils/adt/numeric.c:7717 #, c-format msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." msgstr "Ein Feld mit Präzision %d, Skala %d muss beim Runden einen Betrag von weniger als %s%d ergeben." -#: utils/adt/numeric.c:7762 +#: utils/adt/numeric.c:7768 #, c-format msgid "A field with precision %d, scale %d cannot hold an infinite value." msgstr "Ein Feld mit Präzision %d, Skala %d kann keinen unendlichen Wert enthalten." -#: utils/adt/numeric.c:11243 utils/adt/pseudorandomfuncs.c:38 +#: utils/adt/numeric.c:11249 utils/adt/pseudorandomfuncs.c:38 #, c-format msgid "lower bound must be less than or equal to upper bound" msgstr "Untergrenze muss kleiner als oder gleich der Obergrenze sein" @@ -33267,17 +33541,17 @@ msgstr "Perzentilwert %g ist nicht zwischen 0 und 1" #: utils/adt/pg_dependencies.c:112 utils/adt/pg_dependencies.c:121 #: utils/adt/pg_dependencies.c:159 utils/adt/pg_dependencies.c:169 #: utils/adt/pg_dependencies.c:179 utils/adt/pg_dependencies.c:194 -#: utils/adt/pg_dependencies.c:223 utils/adt/pg_dependencies.c:271 -#: utils/adt/pg_dependencies.c:300 utils/adt/pg_dependencies.c:314 -#: utils/adt/pg_dependencies.c:351 utils/adt/pg_dependencies.c:368 -#: utils/adt/pg_dependencies.c:385 utils/adt/pg_dependencies.c:398 -#: utils/adt/pg_dependencies.c:425 utils/adt/pg_dependencies.c:435 -#: utils/adt/pg_dependencies.c:494 utils/adt/pg_dependencies.c:507 -#: utils/adt/pg_dependencies.c:521 utils/adt/pg_dependencies.c:539 -#: utils/adt/pg_dependencies.c:552 utils/adt/pg_dependencies.c:569 -#: utils/adt/pg_dependencies.c:580 utils/adt/pg_dependencies.c:673 -#: utils/adt/pg_dependencies.c:681 utils/adt/pg_dependencies.c:716 -#: utils/adt/pg_dependencies.c:803 +#: utils/adt/pg_dependencies.c:222 utils/adt/pg_dependencies.c:270 +#: utils/adt/pg_dependencies.c:299 utils/adt/pg_dependencies.c:313 +#: utils/adt/pg_dependencies.c:350 utils/adt/pg_dependencies.c:367 +#: utils/adt/pg_dependencies.c:384 utils/adt/pg_dependencies.c:397 +#: utils/adt/pg_dependencies.c:424 utils/adt/pg_dependencies.c:434 +#: utils/adt/pg_dependencies.c:493 utils/adt/pg_dependencies.c:506 +#: utils/adt/pg_dependencies.c:520 utils/adt/pg_dependencies.c:538 +#: utils/adt/pg_dependencies.c:551 utils/adt/pg_dependencies.c:568 +#: utils/adt/pg_dependencies.c:579 utils/adt/pg_dependencies.c:672 +#: utils/adt/pg_dependencies.c:680 utils/adt/pg_dependencies.c:715 +#: utils/adt/pg_dependencies.c:802 #, fuzzy, c-format #| msgid "malformed range literal: \"%s\"" msgid "malformed pg_dependencies: \"%s\"" @@ -33325,103 +33599,103 @@ msgstr "Erweiterungsnamen dürfen nicht »--« enthalten." msgid "The \"%s\" key must contain an array of at least %d and no more than %d elements." msgstr "" -#: utils/adt/pg_dependencies.c:224 +#: utils/adt/pg_dependencies.c:223 #, c-format msgid "Item \"%s\" with value %d has been found in the \"%s\" list." msgstr "" -#: utils/adt/pg_dependencies.c:272 utils/adt/pg_ndistinct.c:226 +#: utils/adt/pg_dependencies.c:271 utils/adt/pg_ndistinct.c:226 #, c-format msgid "Array has been found at an unexpected location." msgstr "" -#: utils/adt/pg_dependencies.c:301 utils/adt/pg_ndistinct.c:260 +#: utils/adt/pg_dependencies.c:300 utils/adt/pg_ndistinct.c:260 #, fuzzy, c-format #| msgid "field \"%s\" must be a number" msgid "The \"%s\" key must be a non-empty array." msgstr "Feld »%s« muss eine Zahl sein" -#: utils/adt/pg_dependencies.c:315 utils/adt/pg_ndistinct.c:275 +#: utils/adt/pg_dependencies.c:314 utils/adt/pg_ndistinct.c:275 #, fuzzy, c-format #| msgid "\"%s\" cannot be empty." msgid "Item array cannot be empty." msgstr "»%s« kann nicht leer sein." -#: utils/adt/pg_dependencies.c:352 utils/adt/pg_dependencies.c:369 -#: utils/adt/pg_dependencies.c:386 utils/adt/pg_ndistinct.c:312 +#: utils/adt/pg_dependencies.c:351 utils/adt/pg_dependencies.c:368 +#: utils/adt/pg_dependencies.c:385 utils/adt/pg_ndistinct.c:312 #: utils/adt/pg_ndistinct.c:328 #, fuzzy, c-format #| msgid "multiple WITH clauses not allowed" msgid "Multiple \"%s\" keys are not allowed." msgstr "mehrere WITH-Klauseln sind nicht erlaubt" -#: utils/adt/pg_dependencies.c:399 +#: utils/adt/pg_dependencies.c:398 #, fuzzy, c-format #| msgid "Valid values are \"%s\" and \"%s\"." -msgid "Only allowed keys are \"%s\", \"%s\" and \"%s\"." +msgid "Only allowed keys are \"%s\", \"%s\", and \"%s\"." msgstr "Gültige Werte sind »%s« und »%s«." -#: utils/adt/pg_dependencies.c:426 utils/adt/pg_ndistinct.c:366 +#: utils/adt/pg_dependencies.c:425 utils/adt/pg_ndistinct.c:366 #, fuzzy, c-format #| msgid "options array must not be null" msgid "Attribute number array cannot be null." msgstr "Optionen-Array darf nicht NULL sein" -#: utils/adt/pg_dependencies.c:436 utils/adt/pg_ndistinct.c:376 +#: utils/adt/pg_dependencies.c:435 utils/adt/pg_ndistinct.c:376 #, fuzzy, c-format #| msgid "RAISE statement option cannot be null" msgid "Item list elements cannot be null." msgstr "Option einer RAISE-Anweisung darf nicht NULL sein" -#: utils/adt/pg_dependencies.c:495 utils/adt/pg_dependencies.c:540 -#: utils/adt/pg_dependencies.c:570 utils/adt/pg_ndistinct.c:436 +#: utils/adt/pg_dependencies.c:494 utils/adt/pg_dependencies.c:539 +#: utils/adt/pg_dependencies.c:569 utils/adt/pg_ndistinct.c:436 #: utils/adt/pg_ndistinct.c:490 #, fuzzy, c-format #| msgid "Column \"%s\" has no default value." msgid "Key \"%s\" has an incorrect value." msgstr "Spalte »%s« hat keinen Vorgabewert." -#: utils/adt/pg_dependencies.c:508 utils/adt/pg_ndistinct.c:449 +#: utils/adt/pg_dependencies.c:507 utils/adt/pg_ndistinct.c:449 #, c-format msgid "Invalid \"%s\" element has been found: %d." msgstr "" -#: utils/adt/pg_dependencies.c:522 utils/adt/pg_ndistinct.c:463 +#: utils/adt/pg_dependencies.c:521 utils/adt/pg_ndistinct.c:463 #, c-format msgid "Invalid \"%s\" element has been found: %d cannot follow %d." msgstr "" -#: utils/adt/pg_dependencies.c:553 +#: utils/adt/pg_dependencies.c:552 #, fuzzy, c-format #| msgid "Column \"%s\" has no default value." msgid "Key \"%s\" has an incorrect value: %d." msgstr "Spalte »%s« hat keinen Vorgabewert." -#: utils/adt/pg_dependencies.c:581 utils/adt/pg_ndistinct.c:498 +#: utils/adt/pg_dependencies.c:580 utils/adt/pg_ndistinct.c:498 #, fuzzy, c-format #| msgid "Unexpected array element." msgid "Unexpected scalar has been found." msgstr "Unerwartetes Arrayelement." -#: utils/adt/pg_dependencies.c:674 utils/adt/pg_ndistinct.c:615 +#: utils/adt/pg_dependencies.c:673 utils/adt/pg_ndistinct.c:615 #, fuzzy, c-format #| msgid "\"%s\" cannot be empty." msgid "Value cannot be empty." msgstr "»%s« kann nicht leer sein." -#: utils/adt/pg_dependencies.c:682 utils/adt/pg_ndistinct.c:623 +#: utils/adt/pg_dependencies.c:681 utils/adt/pg_ndistinct.c:623 #, fuzzy, c-format #| msgid "expected %d check constraint on table \"%s\" but found %d" #| msgid_plural "expected %d check constraints on table \"%s\" but found %d" msgid "Unexpected end state has been found: %d." msgstr "%d Check-Constraint für Tabelle %s erwartet, aber %d gefunden" -#: utils/adt/pg_dependencies.c:717 +#: utils/adt/pg_dependencies.c:716 #, c-format msgid "Duplicated \"%s\" array has been found: [%s] for key \"%s\" and value %d." msgstr "" -#: utils/adt/pg_dependencies.c:804 utils/adt/pg_ndistinct.c:780 +#: utils/adt/pg_dependencies.c:803 utils/adt/pg_ndistinct.c:780 #, c-format msgid "Input data must be valid JSON." msgstr "" @@ -33452,7 +33726,7 @@ msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s msgstr "Bauen Sie alle von dieser Sortierfolge beinflussten Objekte neu und führen Sie ALTER COLLATION %s REFRESH VERSION aus, oder bauen Sie PostgreSQL mit der richtigen Bibliotheksversion." #: utils/adt/pg_locale.c:1679 utils/adt/pg_locale.c:1706 -#: utils/adt/pg_locale_builtin.c:295 +#: utils/adt/pg_locale_builtin.c:306 #, c-format msgid "invalid locale name \"%s\" for builtin provider" msgstr "ungültiger Locale-Name »%s« für Provider »builtin«" @@ -33463,7 +33737,7 @@ msgid "could not convert locale name \"%s\" to language tag: %s" msgstr "konnte Locale-Namen »%s« nicht in Sprach-Tag umwandeln: %s" #: utils/adt/pg_locale.c:1780 utils/adt/pg_locale.c:1855 -#: utils/adt/pg_locale_icu.c:400 +#: utils/adt/pg_locale_icu.c:415 #, c-format msgid "ICU is not supported in this build" msgstr "ICU wird in dieser Installation nicht unterstützt" @@ -33483,101 +33757,101 @@ msgstr "Um die Validierung von ICU-Locales auszuschalten, setzen Sie den Paramet msgid "ICU locale \"%s\" has unknown language \"%s\"" msgstr "ICU-Locale »%s« hat unbekannte Sprache »%s«" -#: utils/adt/pg_locale_icu.c:440 +#: utils/adt/pg_locale_icu.c:455 #, c-format msgid "could not get language from locale \"%s\": %s" msgstr "konnte Sprache nicht aus Locale »%s« ermitteln: %s" -#: utils/adt/pg_locale_icu.c:481 utils/adt/pg_locale_icu.c:498 +#: utils/adt/pg_locale_icu.c:496 utils/adt/pg_locale_icu.c:513 #, c-format msgid "could not open collator for locale \"%s\": %s" msgstr "konnte Collator für Locale »%s« nicht öffnen: %s" -#: utils/adt/pg_locale_icu.c:528 +#: utils/adt/pg_locale_icu.c:543 #, fuzzy, c-format #| msgid "could not open collator for locale \"%s\": %s" msgid "could not open casemap for locale \"%s\": %s" msgstr "konnte Collator für Locale »%s« nicht öffnen: %s" -#: utils/adt/pg_locale_icu.c:596 +#: utils/adt/pg_locale_icu.c:611 #, c-format msgid "could not open collator for locale \"%s\" with rules \"%s\": %s" msgstr "konnte Collator für Locale »%s« mit Regeln »%s« nicht öffnen: %s" -#: utils/adt/pg_locale_icu.c:644 utils/adt/pg_locale_icu.c:658 -#: utils/adt/pg_locale_icu.c:672 utils/adt/pg_locale_icu.c:686 -#: utils/adt/pg_locale_icu.c:937 +#: utils/adt/pg_locale_icu.c:659 utils/adt/pg_locale_icu.c:673 +#: utils/adt/pg_locale_icu.c:687 utils/adt/pg_locale_icu.c:701 +#: utils/adt/pg_locale_icu.c:992 #, c-format msgid "case conversion failed: %s" msgstr "Groß/Klein-Umwandlung fehlgeschlagen: %s" -#: utils/adt/pg_locale_icu.c:747 +#: utils/adt/pg_locale_icu.c:761 utils/adt/pg_locale_icu.c:781 #, c-format msgid "collation failed: %s" msgstr "Vergleichung fehlgeschlagen: %s" -#: utils/adt/pg_locale_icu.c:822 utils/adt/pg_locale_icu.c:1108 +#: utils/adt/pg_locale_icu.c:862 utils/adt/pg_locale_icu.c:1167 #, c-format msgid "sort key generation failed: %s" msgstr "Sortierschlüsselerzeugung fehlgeschlagen: %s" -#: utils/adt/pg_locale_icu.c:896 utils/adt/pg_locale_icu.c:908 -#: utils/adt/pg_locale_icu.c:1158 utils/adt/pg_locale_icu.c:1179 +#: utils/adt/pg_locale_icu.c:951 utils/adt/pg_locale_icu.c:963 +#: utils/adt/pg_locale_icu.c:1235 utils/adt/pg_locale_icu.c:1255 #, c-format msgid "%s failed: %s" msgstr "%s fehlgeschlagen: %s" -#: utils/adt/pg_locale_icu.c:1131 +#: utils/adt/pg_locale_icu.c:1204 #, c-format msgid "encoding \"%s\" not supported by ICU" msgstr "Kodierung »%s« wird von ICU nicht unterstützt" -#: utils/adt/pg_locale_icu.c:1138 +#: utils/adt/pg_locale_icu.c:1211 #, c-format msgid "could not open ICU converter for encoding \"%s\": %s" msgstr "konnte ICU-Konverter für Kodierung »%s« nicht öffnen: %s" -#: utils/adt/pg_locale_libc.c:881 +#: utils/adt/pg_locale_libc.c:913 #, c-format msgid "collations with different collate and ctype values are not supported on this platform" msgstr "Sortierfolgen mit unterschiedlichen »collate«- und »ctype«-Werten werden auf dieser Plattform nicht unterstützt" -#: utils/adt/pg_locale_libc.c:1007 +#: utils/adt/pg_locale_libc.c:1036 #, c-format msgid "could not load locale \"%s\"" msgstr "konnte Locale »%s« nicht laden" -#: utils/adt/pg_locale_libc.c:1032 +#: utils/adt/pg_locale_libc.c:1061 #, c-format msgid "could not get collation version for locale \"%s\": error code %lu" msgstr "konnte Sortierfolgenversion für Locale »%s« nicht ermitteln: Fehlercode %lu" -#: utils/adt/pg_locale_libc.c:1094 utils/adt/pg_locale_libc.c:1107 +#: utils/adt/pg_locale_libc.c:1122 utils/adt/pg_locale_libc.c:1135 #, c-format msgid "could not convert string to UTF-16: error code %lu" msgstr "konnte Zeichenkette nicht in UTF-16 umwandeln: Fehlercode %lu" -#: utils/adt/pg_locale_libc.c:1116 +#: utils/adt/pg_locale_libc.c:1144 #, c-format msgid "could not compare Unicode strings: %m" msgstr "konnte Unicode-Zeichenketten nicht vergleichen: %m" -#: utils/adt/pg_locale_libc.c:1148 +#: utils/adt/pg_locale_libc.c:1186 #, c-format msgid "could not create locale \"%s\": %m" msgstr "konnte Locale »%s« nicht erzeugen: %m" -#: utils/adt/pg_locale_libc.c:1151 +#: utils/adt/pg_locale_libc.c:1189 #, c-format msgid "The operating system could not find any locale data for the locale name \"%s\"." msgstr "Das Betriebssystem konnte keine Locale-Daten für den Locale-Namen »%s« finden." -#: utils/adt/pg_locale_libc.c:1323 +#: utils/adt/pg_locale_libc.c:1361 #, c-format msgid "invalid multibyte character for locale" msgstr "ungültiges Mehrbytezeichen für Locale" -#: utils/adt/pg_locale_libc.c:1324 +#: utils/adt/pg_locale_libc.c:1362 #, c-format msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." msgstr "Die LC_CTYPE-Locale des Servers ist wahrscheinlich mit der Kodierung der Datenbank inkompatibel." @@ -33647,8 +33921,9 @@ msgid "unrecognized reset target: \"%s\"" msgstr "unbekanntes Reset-Ziel: »%s«" #: utils/adt/pgstatfuncs.c:1990 -#, c-format -msgid "Target must be \"archiver\", \"bgwriter\", \"checkpointer\", \"io\", \"recovery_prefetch\", \"slru\", or \"wal\"." +#, fuzzy, c-format +#| msgid "Target must be \"archiver\", \"bgwriter\", \"checkpointer\", \"io\", \"recovery_prefetch\", \"slru\", or \"wal\"." +msgid "Target must be \"archiver\", \"bgwriter\", \"checkpointer\", \"io\", \"lock\", \"recovery_prefetch\", \"slru\", or \"wal\"." msgstr "Das Reset-Ziel muss »archiver«, »bgwriter«, »checkpointer«, »io«, »recovery_prefetch«, »slru« oder »wal« sein." #: utils/adt/pgstatfuncs.c:2107 @@ -33741,7 +34016,7 @@ msgstr "Zu viele Kommas." msgid "Junk after right parenthesis or bracket." msgstr "Müll nach rechter runder oder eckiger Klammer." -#: utils/adt/regexp.c:304 utils/adt/regexp.c:2068 utils/adt/varlena.c:3411 +#: utils/adt/regexp.c:304 utils/adt/regexp.c:2068 utils/adt/varlena.c:3414 #, c-format msgid "regular expression failed: %s" msgstr "regulärer Ausdruck fehlgeschlagen: %s" @@ -33797,8 +34072,8 @@ msgstr "es gibt mehrere Funktionen namens »%s«" msgid "more than one operator named %s" msgstr "es gibt mehrere Operatoren namens %s" -#: utils/adt/regproc.c:683 utils/adt/regproc.c:2154 utils/adt/ruleutils.c:11424 -#: utils/adt/ruleutils.c:11637 +#: utils/adt/regproc.c:683 utils/adt/regproc.c:2154 utils/adt/ruleutils.c:11426 +#: utils/adt/ruleutils.c:11639 #, c-format msgid "too many arguments" msgstr "zu viele Argumente" @@ -33809,8 +34084,8 @@ msgid "Provide two argument types for operator." msgstr "Geben Sie zwei Argumente für den Operator an." #: utils/adt/regproc.c:1572 utils/adt/regproc.c:1689 utils/adt/regproc.c:1806 -#: utils/adt/regproc.c:1935 utils/adt/regproc.c:1940 utils/adt/varlena.c:2733 -#: utils/adt/varlena.c:2738 +#: utils/adt/regproc.c:1935 utils/adt/regproc.c:1940 utils/adt/varlena.c:2736 +#: utils/adt/varlena.c:2741 #, c-format msgid "invalid name syntax" msgstr "ungültige Namenssyntax" @@ -33835,93 +34110,93 @@ msgstr "Typname erwartet" msgid "improper type name" msgstr "falscher Typname" -#: utils/adt/ri_triggers.c:414 utils/adt/ri_triggers.c:1906 -#: utils/adt/ri_triggers.c:3653 +#: utils/adt/ri_triggers.c:421 utils/adt/ri_triggers.c:1929 +#: utils/adt/ri_triggers.c:3713 #, c-format msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" msgstr "Einfügen oder Aktualisieren in Tabelle »%s« verletzt Fremdschlüssel-Constraint »%s«" -#: utils/adt/ri_triggers.c:417 utils/adt/ri_triggers.c:1909 +#: utils/adt/ri_triggers.c:424 utils/adt/ri_triggers.c:1932 #, c-format msgid "MATCH FULL does not allow mixing of null and nonnull key values." msgstr "MATCH FULL erlaubt das Mischen von Schlüsseln, die NULL und nicht NULL sind, nicht." -#: utils/adt/ri_triggers.c:2323 +#: utils/adt/ri_triggers.c:2346 #, c-format msgid "function \"%s\" must be fired for INSERT" msgstr "Funktion »%s« muss von INSERT ausgelöst werden" -#: utils/adt/ri_triggers.c:2329 +#: utils/adt/ri_triggers.c:2352 #, c-format msgid "function \"%s\" must be fired for UPDATE" msgstr "Funktion »%s« muss von UPDATE ausgelöst werden" -#: utils/adt/ri_triggers.c:2335 +#: utils/adt/ri_triggers.c:2358 #, c-format msgid "function \"%s\" must be fired for DELETE" msgstr "Funktion »%s« muss von DELETE ausgelöst werden" -#: utils/adt/ri_triggers.c:2358 +#: utils/adt/ri_triggers.c:2381 #, c-format msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" msgstr "kein »pg_constraint«-Eintrag für Trigger »%s« für Tabelle »%s«" -#: utils/adt/ri_triggers.c:2360 +#: utils/adt/ri_triggers.c:2383 #, c-format msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." msgstr "Entfernen Sie diesen Referentielle-Integritäts-Trigger und seine Partner und führen Sie dann ALTER TABLE ADD CONSTRAINT aus." -#: utils/adt/ri_triggers.c:2749 +#: utils/adt/ri_triggers.c:2772 #, c-format msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" msgstr "RI-Anfrage in Tabelle »%s« für Constraint »%s« von Tabelle »%s« ergab unerwartetes Ergebnis" -#: utils/adt/ri_triggers.c:2753 +#: utils/adt/ri_triggers.c:2776 #, c-format msgid "This is most likely due to a rule having rewritten the query." msgstr "Das liegt höchstwahrscheinlich daran, dass eine Regel die Anfrage umgeschrieben hat." -#: utils/adt/ri_triggers.c:3643 +#: utils/adt/ri_triggers.c:3703 #, c-format msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" msgstr "Entfernen der Partition »%s« verletzt Fremdschlüssel-Constraint »%s«" -#: utils/adt/ri_triggers.c:3646 utils/adt/ri_triggers.c:3685 +#: utils/adt/ri_triggers.c:3706 utils/adt/ri_triggers.c:3745 #, c-format msgid "Key (%s)=(%s) is still referenced from table \"%s\"." msgstr "Auf Schlüssel (%s)=(%s) wird noch aus Tabelle »%s« verwiesen." -#: utils/adt/ri_triggers.c:3657 +#: utils/adt/ri_triggers.c:3717 #, c-format msgid "Key (%s)=(%s) is not present in table \"%s\"." msgstr "Schlüssel (%s)=(%s) ist nicht in Tabelle »%s« vorhanden." -#: utils/adt/ri_triggers.c:3660 +#: utils/adt/ri_triggers.c:3720 #, c-format msgid "Key is not present in table \"%s\"." msgstr "Der Schlüssel ist nicht in Tabelle »%s« vorhanden." -#: utils/adt/ri_triggers.c:3666 +#: utils/adt/ri_triggers.c:3726 #, c-format msgid "update or delete on table \"%s\" violates RESTRICT setting of foreign key constraint \"%s\" on table \"%s\"" msgstr "Aktualisieren oder Löschen in Tabelle »%s« verletzt die RESTRICT-Einstellung des Fremdschlüssel-Constraints »%s« von Tabelle »%s«" -#: utils/adt/ri_triggers.c:3671 +#: utils/adt/ri_triggers.c:3731 #, c-format msgid "Key (%s)=(%s) is referenced from table \"%s\"." msgstr "Auf Schlüssel (%s)=(%s) wird aus Tabelle »%s« verwiesen." -#: utils/adt/ri_triggers.c:3674 +#: utils/adt/ri_triggers.c:3734 #, c-format msgid "Key is referenced from table \"%s\"." msgstr "Auf den Schlüssel wird aus Tabelle »%s« verwiesen." -#: utils/adt/ri_triggers.c:3680 +#: utils/adt/ri_triggers.c:3740 #, c-format msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" msgstr "Aktualisieren oder Löschen in Tabelle »%s« verletzt Fremdschlüssel-Constraint »%s« von Tabelle »%s«" -#: utils/adt/ri_triggers.c:3688 +#: utils/adt/ri_triggers.c:3748 #, c-format msgid "Key is still referenced from table \"%s\"." msgstr "Auf den Schlüssel wird noch aus Tabelle »%s« verwiesen." @@ -33984,22 +34259,22 @@ msgstr "kann unterschiedliche Spaltentyp %s und %s in Record-Spalte %d nicht ver msgid "cannot compare record types with different numbers of columns" msgstr "kann Record-Typen mit unterschiedlicher Anzahl Spalten nicht vergleichen" -#: utils/adt/ruleutils.c:3098 +#: utils/adt/ruleutils.c:3100 #, c-format msgid "input is a query, not an expression" msgstr "Eingabe ist eine Anfrage, kein Ausdruck" -#: utils/adt/ruleutils.c:3110 +#: utils/adt/ruleutils.c:3112 #, c-format msgid "expression contains variables of more than one relation" msgstr "Ausdruck enthält Verweise auf Variablen von mehr als einer Relation" -#: utils/adt/ruleutils.c:3117 +#: utils/adt/ruleutils.c:3119 #, c-format msgid "expression contains variables" msgstr "Ausdruck enthält Variablen" -#: utils/adt/ruleutils.c:5795 +#: utils/adt/ruleutils.c:5797 #, c-format msgid "rule \"%s\" has unsupported event type %d" msgstr "Regel »%s« hat nicht unterstützten Ereignistyp %d" @@ -34039,108 +34314,108 @@ msgstr "Präzision von TIMESTAMP(%d)%s darf nicht negativ sein" msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" msgstr "Präzision von TIMESTAMP(%d)%s auf erlaubten Höchstwert %d reduziert" -#: utils/adt/timestamp.c:195 utils/adt/timestamp.c:449 +#: utils/adt/timestamp.c:196 utils/adt/timestamp.c:453 #, c-format msgid "timestamp out of range: \"%s\"" msgstr "timestamp ist außerhalb des gültigen Bereichs: »%s«" -#: utils/adt/timestamp.c:388 +#: utils/adt/timestamp.c:391 #, c-format msgid "timestamp(%d) precision must be between %d and %d" msgstr "Präzision von timestamp(%d) muss zwischen %d und %d sein" -#: utils/adt/timestamp.c:506 +#: utils/adt/timestamp.c:510 #, c-format msgid "Numeric time zones must have \"-\" or \"+\" as first character." msgstr "Numerische Zeitzonen müssen »-« oder »+« als erstes Zeichen haben." -#: utils/adt/timestamp.c:518 +#: utils/adt/timestamp.c:522 #, c-format msgid "numeric time zone \"%s\" out of range" msgstr "numerische Zeitzone »%s« ist außerhalb des gültigen Bereichs" -#: utils/adt/timestamp.c:618 utils/adt/timestamp.c:626 +#: utils/adt/timestamp.c:622 utils/adt/timestamp.c:630 #, c-format msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" msgstr "timestamp ist außerhalb des gültigen Bereichs: %d-%02d-%02d %d:%02d:%02g" -#: utils/adt/timestamp.c:727 +#: utils/adt/timestamp.c:731 #, c-format msgid "timestamp cannot be NaN" msgstr "timestamp kann nicht NaN sein" -#: utils/adt/timestamp.c:745 utils/adt/timestamp.c:757 +#: utils/adt/timestamp.c:749 utils/adt/timestamp.c:761 #, c-format msgid "timestamp out of range: \"%g\"" msgstr "timestamp ist außerhalb des gültigen Bereichs: »%g«" -#: utils/adt/timestamp.c:941 utils/adt/timestamp.c:1501 -#: utils/adt/timestamp.c:1511 utils/adt/timestamp.c:1572 -#: utils/adt/timestamp.c:2842 utils/adt/timestamp.c:2851 -#: utils/adt/timestamp.c:2866 utils/adt/timestamp.c:2940 -#: utils/adt/timestamp.c:2957 utils/adt/timestamp.c:3014 -#: utils/adt/timestamp.c:3057 utils/adt/timestamp.c:3435 -#: utils/adt/timestamp.c:3493 utils/adt/timestamp.c:3516 -#: utils/adt/timestamp.c:3525 utils/adt/timestamp.c:3549 -#: utils/adt/timestamp.c:3572 utils/adt/timestamp.c:3581 -#: utils/adt/timestamp.c:3716 utils/adt/timestamp.c:3817 -#: utils/adt/timestamp.c:4224 utils/adt/timestamp.c:4261 -#: utils/adt/timestamp.c:4309 utils/adt/timestamp.c:4318 -#: utils/adt/timestamp.c:4410 utils/adt/timestamp.c:4457 -#: utils/adt/timestamp.c:4466 utils/adt/timestamp.c:4562 -#: utils/adt/timestamp.c:4615 utils/adt/timestamp.c:4625 -#: utils/adt/timestamp.c:4850 utils/adt/timestamp.c:4860 -#: utils/adt/timestamp.c:5215 +#: utils/adt/timestamp.c:948 utils/adt/timestamp.c:1510 +#: utils/adt/timestamp.c:1520 utils/adt/timestamp.c:1581 +#: utils/adt/timestamp.c:2861 utils/adt/timestamp.c:2870 +#: utils/adt/timestamp.c:2885 utils/adt/timestamp.c:2959 +#: utils/adt/timestamp.c:2976 utils/adt/timestamp.c:3033 +#: utils/adt/timestamp.c:3076 utils/adt/timestamp.c:3460 +#: utils/adt/timestamp.c:3518 utils/adt/timestamp.c:3541 +#: utils/adt/timestamp.c:3550 utils/adt/timestamp.c:3574 +#: utils/adt/timestamp.c:3597 utils/adt/timestamp.c:3606 +#: utils/adt/timestamp.c:3741 utils/adt/timestamp.c:3842 +#: utils/adt/timestamp.c:4249 utils/adt/timestamp.c:4286 +#: utils/adt/timestamp.c:4335 utils/adt/timestamp.c:4344 +#: utils/adt/timestamp.c:4436 utils/adt/timestamp.c:4484 +#: utils/adt/timestamp.c:4493 utils/adt/timestamp.c:4589 +#: utils/adt/timestamp.c:4643 utils/adt/timestamp.c:4653 +#: utils/adt/timestamp.c:4880 utils/adt/timestamp.c:4890 +#: utils/adt/timestamp.c:5248 #, c-format msgid "interval out of range" msgstr "interval-Wert ist außerhalb des gültigen Bereichs" -#: utils/adt/timestamp.c:1078 utils/adt/timestamp.c:1111 +#: utils/adt/timestamp.c:1086 utils/adt/timestamp.c:1119 #, c-format msgid "invalid INTERVAL type modifier" msgstr "ungültiger Modifikator für Typ INTERVAL" -#: utils/adt/timestamp.c:1094 +#: utils/adt/timestamp.c:1102 #, c-format msgid "INTERVAL(%d) precision must not be negative" msgstr "INTERVAL(%d)-Präzision darf nicht negativ sein" -#: utils/adt/timestamp.c:1100 +#: utils/adt/timestamp.c:1108 #, c-format msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" msgstr "INTERVAL(%d)-Präzision auf erlaubtes Maximum %d reduziert" -#: utils/adt/timestamp.c:1491 +#: utils/adt/timestamp.c:1500 #, c-format msgid "interval(%d) precision must be between %d and %d" msgstr "Präzision von interval(%d) muss zwischen %d und %d sein" -#: utils/adt/timestamp.c:4599 utils/adt/timestamp.c:4834 +#: utils/adt/timestamp.c:4627 utils/adt/timestamp.c:4864 #, c-format msgid "origin out of range" msgstr "Anfangspunkt ist außerhalb des gültigen Bereichs" -#: utils/adt/timestamp.c:4604 utils/adt/timestamp.c:4839 +#: utils/adt/timestamp.c:4632 utils/adt/timestamp.c:4869 #, c-format msgid "timestamps cannot be binned into infinite intervals" msgstr "timestamp-Werte können nicht in unendliche Intervalle einsortiert werden" -#: utils/adt/timestamp.c:4609 utils/adt/timestamp.c:4844 +#: utils/adt/timestamp.c:4637 utils/adt/timestamp.c:4874 #, c-format msgid "timestamps cannot be binned into intervals containing months or years" msgstr "timestamp-Werte können nicht in Intervalle, die Monate oder Jahre enthalten, einsortiert werden" -#: utils/adt/timestamp.c:4620 utils/adt/timestamp.c:4855 +#: utils/adt/timestamp.c:4648 utils/adt/timestamp.c:4885 #, c-format msgid "stride must be greater than zero" msgstr "Schrittgröße muss größer als null sein" -#: utils/adt/timestamp.c:5157 utils/adt/timestamp.c:5209 +#: utils/adt/timestamp.c:5190 utils/adt/timestamp.c:5242 #, c-format msgid "Months usually have fractional weeks." msgstr "Monate haben gewöhnlich partielle Wochen." -#: utils/adt/timestamp.c:6715 utils/adt/timestamp.c:6800 +#: utils/adt/timestamp.c:6765 utils/adt/timestamp.c:6851 #, c-format msgid "step size cannot be infinite" msgstr "Schrittgröße kann nicht unendlich sein" @@ -34215,22 +34490,22 @@ msgstr "Textsucheanfrage enthält nur Stoppwörter oder enthält keine Lexeme, i msgid "ts_rewrite query must return two tsquery columns" msgstr "ts_rewrite-Anfrage muss zwei tsquery-Spalten zurückgeben" -#: utils/adt/tsrank.c:415 +#: utils/adt/tsrank.c:438 #, c-format msgid "array of weight must be one-dimensional" msgstr "Gewichtungs-Array muss eindimensional sein" -#: utils/adt/tsrank.c:420 +#: utils/adt/tsrank.c:443 #, c-format msgid "array of weight is too short" msgstr "Gewichtungs-Array ist zu kurz" -#: utils/adt/tsrank.c:425 +#: utils/adt/tsrank.c:448 #, c-format msgid "array of weight must not contain nulls" msgstr "Gewichtungs-Array darf keine NULL-Werte enthalten" -#: utils/adt/tsrank.c:434 utils/adt/tsrank.c:876 +#: utils/adt/tsrank.c:457 utils/adt/tsrank.c:899 #, c-format msgid "weight out of range" msgstr "Gewichtung ist außerhalb des gültigen Bereichs" @@ -34246,62 +34521,68 @@ msgstr "Wort ist zu lang (%ld Bytes, maximal %ld Bytes)" msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" msgstr "Zeichenkette ist zu lang für tsvector (%ld Bytes, maximal %ld Bytes)" -#: utils/adt/tsvector_op.c:772 +#: utils/adt/tsvector_op.c:238 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "unbekannte Gewichtung: »%c«" + +#: utils/adt/tsvector_op.c:242 +#, fuzzy, c-format +#| msgid "unrecognized weight: \"%c\"" +msgid "unrecognized weight: \"\\%03o\"" +msgstr "unbekannte Gewichtung: »%c«" + +#: utils/adt/tsvector_op.c:767 #, c-format msgid "lexeme array may not contain nulls" msgstr "Lexem-Array darf keine NULL-Werte enthalten" -#: utils/adt/tsvector_op.c:777 +#: utils/adt/tsvector_op.c:772 #, c-format msgid "lexeme array may not contain empty strings" msgstr "Lexem-Array darf keine leeren Zeichenketten enthalten" -#: utils/adt/tsvector_op.c:846 +#: utils/adt/tsvector_op.c:841 #, c-format msgid "weight array may not contain nulls" msgstr "Gewichtungs-Array darf keine NULL-Werte enthalten" -#: utils/adt/tsvector_op.c:870 -#, c-format -msgid "unrecognized weight: \"%c\"" -msgstr "unbekannte Gewichtung: »%c«" - -#: utils/adt/tsvector_op.c:2600 +#: utils/adt/tsvector_op.c:2573 #, c-format msgid "ts_stat query must return one tsvector column" msgstr "ts_stat-Anfrage muss eine tsvector-Spalte zurückgeben" -#: utils/adt/tsvector_op.c:2793 +#: utils/adt/tsvector_op.c:2766 #, c-format msgid "tsvector column \"%s\" does not exist" msgstr "tsvector-Spalte »%s« existiert nicht" -#: utils/adt/tsvector_op.c:2800 +#: utils/adt/tsvector_op.c:2773 #, c-format msgid "column \"%s\" is not of tsvector type" msgstr "Spalte »%s« hat nicht Typ tsvector" -#: utils/adt/tsvector_op.c:2812 +#: utils/adt/tsvector_op.c:2785 #, c-format msgid "configuration column \"%s\" does not exist" msgstr "Konfigurationsspalte »%s« existiert nicht" -#: utils/adt/tsvector_op.c:2818 +#: utils/adt/tsvector_op.c:2791 #, c-format msgid "column \"%s\" is not of regconfig type" msgstr "Spalte »%s« hat nicht Typ regconfig" -#: utils/adt/tsvector_op.c:2825 +#: utils/adt/tsvector_op.c:2798 #, c-format msgid "configuration column \"%s\" must not be null" msgstr "Konfigurationsspalte »%s« darf nicht NULL sein" -#: utils/adt/tsvector_op.c:2838 +#: utils/adt/tsvector_op.c:2811 #, c-format msgid "text search configuration name \"%s\" must be schema-qualified" msgstr "Textsuchekonfigurationsname »%s« muss Schemaqualifikation haben" -#: utils/adt/tsvector_op.c:2863 +#: utils/adt/tsvector_op.c:2836 #, c-format msgid "column \"%s\" is not of a character type" msgstr "Spalte »%s« hat keinen Zeichentyp" @@ -34397,93 +34678,93 @@ msgstr "Wert zu lang für Typ character(%d)" msgid "value too long for type character(%d)" msgstr "Wert zu lang für Typ character(%d)" -#: utils/adt/varchar.c:475 +#: utils/adt/varchar.c:478 #, fuzzy, c-format #| msgid "value too long for type character varying(%d)" msgid "value too long for type character varying(%zu)" msgstr "Wert zu lang für Typ character varying(%d)" -#: utils/adt/varchar.c:639 +#: utils/adt/varchar.c:642 #, c-format msgid "value too long for type character varying(%d)" msgstr "Wert zu lang für Typ character varying(%d)" -#: utils/adt/varchar.c:737 utils/adt/varlena.c:1336 +#: utils/adt/varchar.c:740 utils/adt/varlena.c:1336 #, c-format msgid "could not determine which collation to use for string comparison" msgstr "konnte die für den Zeichenkettenvergleich zu verwendende Sortierfolge nicht bestimmen" -#: utils/adt/varlena.c:1609 +#: utils/adt/varlena.c:1610 #, c-format msgid "nondeterministic collations are not supported for substring searches" msgstr "nichtdeterministische Sortierfolgen werden für Teilzeichenkettensuchen nicht unterstützt" -#: utils/adt/varlena.c:3523 +#: utils/adt/varlena.c:3526 #, c-format msgid "field position must not be zero" msgstr "Feldposition darf nicht null sein" -#: utils/adt/varlena.c:4773 +#: utils/adt/varlena.c:4776 #, c-format msgid "unterminated format() type specifier" msgstr "Typspezifikation in format() nicht abgeschlossen" -#: utils/adt/varlena.c:4774 utils/adt/varlena.c:4908 utils/adt/varlena.c:5029 +#: utils/adt/varlena.c:4777 utils/adt/varlena.c:4911 utils/adt/varlena.c:5032 #, c-format msgid "For a single \"%%\" use \"%%%%\"." msgstr "Für ein einzelnes »%%« geben Sie »%%%%« an." -#: utils/adt/varlena.c:4906 utils/adt/varlena.c:5027 +#: utils/adt/varlena.c:4909 utils/adt/varlena.c:5030 #, c-format msgid "unrecognized format() type specifier \"%.*s\"" msgstr "unbekannte Typspezifikation in format(): »%.*s«" -#: utils/adt/varlena.c:4919 utils/adt/varlena.c:4976 +#: utils/adt/varlena.c:4922 utils/adt/varlena.c:4979 #, c-format msgid "too few arguments for format()" msgstr "zu wenige Argumente für format()" -#: utils/adt/varlena.c:5072 utils/adt/varlena.c:5254 +#: utils/adt/varlena.c:5075 utils/adt/varlena.c:5257 #, c-format msgid "number is out of range" msgstr "Zahl ist außerhalb des gültigen Bereichs" -#: utils/adt/varlena.c:5135 utils/adt/varlena.c:5163 +#: utils/adt/varlena.c:5138 utils/adt/varlena.c:5166 #, c-format msgid "format specifies argument 0, but arguments are numbered from 1" msgstr "Format gibt Argument 0 an, aber die Argumente sind von 1 an nummeriert" -#: utils/adt/varlena.c:5156 +#: utils/adt/varlena.c:5159 #, c-format msgid "width argument position must be ended by \"$\"" msgstr "Argumentposition der Breitenangabe muss mit »$« enden" -#: utils/adt/varlena.c:5201 +#: utils/adt/varlena.c:5204 #, c-format msgid "null values cannot be formatted as an SQL identifier" msgstr "NULL-Werte können nicht als SQL-Bezeichner formatiert werden" -#: utils/adt/varlena.c:5409 +#: utils/adt/varlena.c:5412 #, c-format msgid "Unicode normalization can only be performed if server encoding is UTF8" msgstr "Unicode-Normalisierung kann nur durchgeführt werden, wenn die Serverkodierung UTF8 ist" -#: utils/adt/varlena.c:5422 +#: utils/adt/varlena.c:5425 #, c-format msgid "invalid normalization form: %s" msgstr "ungültige Normalisierungsform: %s" -#: utils/adt/varlena.c:5468 +#: utils/adt/varlena.c:5471 #, c-format msgid "Unicode categorization can only be performed if server encoding is UTF8" msgstr "Unicode-Kategorisierung kann nur durchgeführt werden, wenn die Serverkodierung UTF8 ist" -#: utils/adt/varlena.c:5685 utils/adt/varlena.c:5720 utils/adt/varlena.c:5755 +#: utils/adt/varlena.c:5688 utils/adt/varlena.c:5723 utils/adt/varlena.c:5758 #, c-format msgid "invalid Unicode code point: %04X" msgstr "ungültiger Unicode-Codepunkt: %04X" -#: utils/adt/varlena.c:5785 +#: utils/adt/varlena.c:5788 #, c-format msgid "Unicode escapes must be \\XXXX, \\+XXXXXX, \\uXXXX, or \\UXXXXXXXX." msgstr "Unicode-Escapes müssen \\XXXX, \\+XXXXXX, \\uXXXX oder \\UXXXXXXXX sein." @@ -34622,47 +34903,47 @@ msgstr "ungültige Anfrage" msgid "portal \"%s\" does not return tuples" msgstr "Portal »%s« gibt keine Tupel zurück" -#: utils/adt/xml.c:4413 +#: utils/adt/xml.c:4415 #, c-format msgid "invalid array for XML namespace mapping" msgstr "ungültiges Array for XML-Namensraumabbildung" -#: utils/adt/xml.c:4414 +#: utils/adt/xml.c:4416 #, c-format msgid "The array must be two-dimensional with length of the second axis equal to 2." msgstr "Das Array muss zweidimensional sein und die Länge der zweiten Achse muss gleich 2 sein." -#: utils/adt/xml.c:4438 +#: utils/adt/xml.c:4440 #, c-format msgid "empty XPath expression" msgstr "leerer XPath-Ausdruck" -#: utils/adt/xml.c:4490 +#: utils/adt/xml.c:4492 #, c-format msgid "neither namespace name nor URI may be null" msgstr "weder Namensraumname noch URI dürfen NULL sein" -#: utils/adt/xml.c:4497 +#: utils/adt/xml.c:4499 #, c-format msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" msgstr "konnte XML-Namensraum mit Namen »%s« und URI »%s« nicht registrieren" -#: utils/adt/xml.c:4846 +#: utils/adt/xml.c:4848 #, c-format msgid "DEFAULT namespace is not supported" msgstr "DEFAULT-Namensraum wird nicht unterstützt" -#: utils/adt/xml.c:4875 +#: utils/adt/xml.c:4877 #, c-format msgid "row path filter must not be empty string" msgstr "Zeilenpfadfilter darf nicht leer sein" -#: utils/adt/xml.c:4909 +#: utils/adt/xml.c:4911 #, c-format msgid "column path filter must not be empty string" msgstr "Spaltenpfadfilter darf nicht leer sein" -#: utils/adt/xml.c:5056 +#: utils/adt/xml.c:5058 #, c-format msgid "more than one value returned by column XPath expression" msgstr "XPath-Ausdruck für Spalte gab mehr als einen Wert zurück" @@ -34672,23 +34953,23 @@ msgstr "XPath-Ausdruck für Spalte gab mehr als einen Wert zurück" msgid "could not determine actual argument type for polymorphic function \"%s\"" msgstr "konnte den tatsächlichen Argumenttyp der polymorphischen Funktion »%s« nicht ermitteln" -#: utils/cache/lsyscache.c:1136 +#: utils/cache/lsyscache.c:1243 #, c-format msgid "cast from type %s to type %s does not exist" msgstr "Typumwandlung von Typ %s in Typ %s existiert nicht" -#: utils/cache/lsyscache.c:3082 utils/cache/lsyscache.c:3115 -#: utils/cache/lsyscache.c:3148 utils/cache/lsyscache.c:3181 +#: utils/cache/lsyscache.c:3203 utils/cache/lsyscache.c:3236 +#: utils/cache/lsyscache.c:3269 utils/cache/lsyscache.c:3302 #, c-format msgid "type %s is only a shell" msgstr "Typ %s ist nur eine Hülle" -#: utils/cache/lsyscache.c:3087 +#: utils/cache/lsyscache.c:3208 #, c-format msgid "no input function available for type %s" msgstr "keine Eingabefunktion verfügbar für Typ %s" -#: utils/cache/lsyscache.c:3120 +#: utils/cache/lsyscache.c:3241 #, c-format msgid "no output function available for type %s" msgstr "keine Ausgabefunktion verfügbar für Typ %s" @@ -34698,27 +34979,27 @@ msgstr "keine Ausgabefunktion verfügbar für Typ %s" msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" msgstr "in Operatorklasse »%s« für Zugriffsmethode %s fehlt Support-Funktion %d für Typ %s" -#: utils/cache/relcache.c:3797 +#: utils/cache/relcache.c:3809 #, c-format msgid "heap relfilenumber value not set when in binary upgrade mode" msgstr "Heap-Relfile-Nummer-Wert ist im Binary-Upgrade-Modus nicht gesetzt" -#: utils/cache/relcache.c:3805 +#: utils/cache/relcache.c:3817 #, c-format msgid "unexpected request for new relfilenumber in binary upgrade mode" msgstr "unerwartete Anforderung einer neuen Relfile-Nummer im Binary-Upgrade-Modus" -#: utils/cache/relcache.c:6649 +#: utils/cache/relcache.c:6668 #, c-format msgid "could not create relation-cache initialization file \"%s\": %m" msgstr "konnte Initialisierungsdatei für Relationscache »%s« nicht erzeugen: %m" -#: utils/cache/relcache.c:6651 +#: utils/cache/relcache.c:6670 #, c-format msgid "Continuing anyway, but there's something wrong." msgstr "Setze trotzdem fort, aber irgendwas stimmt nicht." -#: utils/cache/relcache.c:6981 +#: utils/cache/relcache.c:7000 #, c-format msgid "could not remove cache file \"%s\": %m" msgstr "konnte Cache-Datei »%s« nicht löschen: %m" @@ -34738,7 +35019,7 @@ msgstr "Relation-Mapping-Datei »%s« enthält ungültige Daten" msgid "relation mapping file \"%s\" contains incorrect checksum" msgstr "Relation-Mapping-Datei »%s« enthält falsche Prüfsumme" -#: utils/cache/typcache.c:1926 utils/fmgr/funcapi.c:576 +#: utils/cache/typcache.c:1928 utils/fmgr/funcapi.c:576 #, c-format msgid "record type has not been registered" msgstr "Record-Typ wurde nicht registriert" @@ -35192,174 +35473,174 @@ msgstr "Sie müssen möglicherweise initdb ausführen." msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." msgstr "Das Datenverzeichnis wurde von PostgreSQL Version %s initialisiert, welche nicht mit dieser Version %s kompatibel ist." -#: utils/init/postinit.c:278 +#: utils/init/postinit.c:284 #, c-format msgid "replication connection authorized: user=%s" msgstr "Replikationsverbindung autorisiert: Benutzer=%s" -#: utils/init/postinit.c:281 +#: utils/init/postinit.c:287 #, c-format msgid "connection authorized: user=%s" msgstr "Verbindung autorisiert: Benutzer=%s" -#: utils/init/postinit.c:284 +#: utils/init/postinit.c:290 #, c-format msgid " database=%s" msgstr " Datenbank=%s" -#: utils/init/postinit.c:287 +#: utils/init/postinit.c:293 #, c-format msgid " application_name=%s" msgstr " application_name=%s" -#: utils/init/postinit.c:292 +#: utils/init/postinit.c:298 #, c-format msgid " SSL enabled (protocol=%s, cipher=%s, bits=%d)" msgstr " SSL an (Protokoll=%s, Verschlüsselungsmethode=%s, Bits=%d)" -#: utils/init/postinit.c:304 +#: utils/init/postinit.c:310 #, c-format msgid " GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s, principal=%s)" msgstr " GSS (authentifiziert=%s, verschlüsselt=%s, delegated Credentials=%s, Principal=%s)" -#: utils/init/postinit.c:305 utils/init/postinit.c:306 -#: utils/init/postinit.c:307 utils/init/postinit.c:312 -#: utils/init/postinit.c:313 utils/init/postinit.c:314 +#: utils/init/postinit.c:311 utils/init/postinit.c:312 +#: utils/init/postinit.c:313 utils/init/postinit.c:318 +#: utils/init/postinit.c:319 utils/init/postinit.c:320 msgid "no" msgstr "nein" -#: utils/init/postinit.c:305 utils/init/postinit.c:306 -#: utils/init/postinit.c:307 utils/init/postinit.c:312 -#: utils/init/postinit.c:313 utils/init/postinit.c:314 +#: utils/init/postinit.c:311 utils/init/postinit.c:312 +#: utils/init/postinit.c:313 utils/init/postinit.c:318 +#: utils/init/postinit.c:319 utils/init/postinit.c:320 msgid "yes" msgstr "ja" -#: utils/init/postinit.c:311 +#: utils/init/postinit.c:317 #, c-format msgid " GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s)" msgstr " GSS (authentifiziert=%s, verschlüsselt=%s, delegated Credentials=%s)" -#: utils/init/postinit.c:351 +#: utils/init/postinit.c:357 #, c-format msgid "database \"%s\" has disappeared from pg_database" msgstr "Datenbank »%s« ist aus pg_database verschwunden" -#: utils/init/postinit.c:353 +#: utils/init/postinit.c:359 #, c-format msgid "Database OID %u now seems to belong to \"%s\"." msgstr "Datenbank-OID %u gehört jetzt anscheinend zu »%s«." -#: utils/init/postinit.c:373 +#: utils/init/postinit.c:379 #, c-format msgid "database \"%s\" is not currently accepting connections" msgstr "Datenbank »%s« akzeptiert gegenwärtig keine Verbindungen" -#: utils/init/postinit.c:386 +#: utils/init/postinit.c:392 #, c-format msgid "permission denied for database \"%s\"" msgstr "keine Berechtigung für Datenbank »%s«" -#: utils/init/postinit.c:387 +#: utils/init/postinit.c:393 #, c-format msgid "User does not have CONNECT privilege." msgstr "Benutzer hat das CONNECT-Privileg nicht." -#: utils/init/postinit.c:407 +#: utils/init/postinit.c:413 #, c-format msgid "too many connections for database \"%s\"" msgstr "zu viele Verbindungen für Datenbank »%s«" -#: utils/init/postinit.c:437 +#: utils/init/postinit.c:443 #, c-format msgid "database locale is incompatible with operating system" msgstr "Datenbank-Locale ist inkompatibel mit Betriebssystem" -#: utils/init/postinit.c:438 +#: utils/init/postinit.c:444 #, c-format msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." msgstr "Die Datenbank wurde mit LC_CTYPE »%s« initialisiert, was von setlocale() nicht erkannt wird." -#: utils/init/postinit.c:440 +#: utils/init/postinit.c:446 #, c-format msgid "Recreate the database with another locale or install the missing locale." msgstr "Erzeugen Sie die Datenbank neu mit einer anderen Locale oder installieren Sie die fehlende Locale." -#: utils/init/postinit.c:475 +#: utils/init/postinit.c:481 #, c-format msgid "database \"%s\" has a collation version mismatch" msgstr "Version von Sortierfolge für Datenbank »%s« stimmt nicht überein" -#: utils/init/postinit.c:477 +#: utils/init/postinit.c:483 #, c-format msgid "The database was created using collation version %s, but the operating system provides version %s." msgstr "Die Datenbank wurde mit Sortierfolgenversion %s erzeugt, aber das Betriebssystem hat Version %s." -#: utils/init/postinit.c:480 +#: utils/init/postinit.c:486 #, c-format msgid "Rebuild all objects in this database that use the default collation and run ALTER DATABASE %s REFRESH COLLATION VERSION, or build PostgreSQL with the right library version." msgstr "Bauen Sie alle Objekte in dieser Datenbank, die die Standardsortierfolge verwenden, neu und führen Sie ALTER DATABASE %s REFRESH COLLATION VERSION aus, oder bauen Sie PostgreSQL mit der richtigen Bibliotheksversion." -#: utils/init/postinit.c:570 +#: utils/init/postinit.c:576 #, c-format msgid "too many server processes configured" msgstr "zu viele Serverprozesse konfiguriert" -#: utils/init/postinit.c:571 +#: utils/init/postinit.c:577 #, c-format msgid "\"max_connections\" (%d) plus \"autovacuum_worker_slots\" (%d) plus \"max_worker_processes\" (%d) plus \"max_wal_senders\" (%d) must be less than %d." msgstr "»max_connections« (%d) plus »autovacuum_worker_slots« (%d) plus »max_worker_processes« (%d) plus »max_wal_senders« (%d) muss kleiner als %d sein." -#: utils/init/postinit.c:903 +#: utils/init/postinit.c:926 #, c-format msgid "no roles are defined in this database system" msgstr "in diesem Datenbanksystem sind keine Rollen definiert" -#: utils/init/postinit.c:904 +#: utils/init/postinit.c:927 #, c-format msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." msgstr "Sie sollten sofort CREATE USER \"%s\" SUPERUSER; ausführen." -#: utils/init/postinit.c:949 +#: utils/init/postinit.c:972 #, c-format msgid "must be superuser to connect in binary upgrade mode" msgstr "nur Superuser können im Binary-Upgrade-Modus verbinden" -#: utils/init/postinit.c:969 +#: utils/init/postinit.c:992 #, c-format msgid "remaining connection slots are reserved for roles with the %s attribute" msgstr "die verbleibenden Verbindungen sind für Rollen mit dem %s-Attribut reserviert" -#: utils/init/postinit.c:975 +#: utils/init/postinit.c:998 #, c-format msgid "remaining connection slots are reserved for roles with privileges of the \"%s\" role" msgstr "die verbleibenden Verbindungen sind für Rollen mit den Privilegien der Rolle »%s« reserviert" -#: utils/init/postinit.c:987 +#: utils/init/postinit.c:1010 #, c-format msgid "permission denied to start WAL sender" msgstr "keine Berechtigung, um WAL-Sender zu starten" -#: utils/init/postinit.c:988 +#: utils/init/postinit.c:1011 #, c-format msgid "Only roles with the %s attribute may start a WAL sender process." msgstr "Nur Rollen mit dem %s-Attribut können einen WAL-Sender-Prozess starten." -#: utils/init/postinit.c:1109 +#: utils/init/postinit.c:1132 #, c-format msgid "It seems to have just been dropped or renamed." msgstr "Sie wurde anscheinend gerade gelöscht oder umbenannt." -#: utils/init/postinit.c:1113 +#: utils/init/postinit.c:1136 #, c-format msgid "database %u does not exist" msgstr "Datenbank %u existiert nicht" -#: utils/init/postinit.c:1122 +#: utils/init/postinit.c:1145 #, c-format msgid "cannot connect to invalid database \"%s\"" msgstr "mit ungültiger Datenbank »%s« kann nicht verbunden werden" -#: utils/init/postinit.c:1183 +#: utils/init/postinit.c:1206 #, c-format msgid "The database subdirectory \"%s\" is missing." msgstr "Das Datenbankunterverzeichnis »%s« fehlt." @@ -35417,17 +35698,17 @@ msgstr "ungültiger Byte-Wert für Kodierung »%s«: 0x%02x" msgid "invalid Unicode code point" msgstr "ungültiger Unicode-Codepunkt" -#: utils/mb/mbutils.c:1328 +#: utils/mb/mbutils.c:1329 #, c-format msgid "bind_textdomain_codeset failed" msgstr "bind_textdomain_codeset fehlgeschlagen" -#: utils/mb/mbutils.c:1851 +#: utils/mb/mbutils.c:1852 #, c-format msgid "invalid byte sequence for encoding \"%s\": %s" msgstr "ungültige Byte-Sequenz für Kodierung »%s«: %s" -#: utils/mb/mbutils.c:1898 +#: utils/mb/mbutils.c:1899 #, c-format msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" msgstr "Zeichen mit Byte-Folge %s in Kodierung »%s« hat keine Entsprechung in Kodierung »%s«" @@ -35595,6 +35876,20 @@ msgstr "%g%s%s ist außerhalb des gültigen Bereichs für Parameter »%s« (%g%s msgid "Available values: " msgstr "Verfügbare Hilfe:\n" +#. translator: This is the terminator of a list of entity +#. names. +#. +#: utils/misc/guc.c:3176 +msgid "." +msgstr "" + +#. translator: This is a separator in a list of entity +#. names. +#. +#: utils/misc/guc.c:3182 +msgid ", " +msgstr ", " + #: utils/misc/guc.c:3374 #, c-format msgid "parameter \"%s\" cannot be set during a parallel operation" @@ -35951,22 +36246,22 @@ msgstr "Policy für Sicherheit auf Zeilenebene für Tabelle »%s« würde Auswir msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." msgstr "Um die Policy für den Tabelleneigentümer zu deaktivieren, verwenden Sie ALTER TABLE NO FORCE ROW LEVEL SECURITY." -#: utils/misc/stack_depth.c:101 +#: utils/misc/stack_depth.c:102 #, c-format msgid "stack depth limit exceeded" msgstr "Grenze für Stacktiefe überschritten" -#: utils/misc/stack_depth.c:102 +#: utils/misc/stack_depth.c:103 #, c-format msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." msgstr "Erhöhen Sie den Konfigurationsparameter »max_stack_depth« (aktuell %dkB), nachdem Sie sichergestellt haben, dass die Stacktiefenbegrenzung Ihrer Plattform ausreichend ist." -#: utils/misc/stack_depth.c:149 +#: utils/misc/stack_depth.c:165 #, c-format msgid "\"max_stack_depth\" must not exceed %zdkB." msgstr "»max_stack_depth« darf %zdkB nicht überschreiten." -#: utils/misc/stack_depth.c:151 +#: utils/misc/stack_depth.c:167 #, c-format msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." msgstr "Erhöhen Sie die Stacktiefenbegrenzung Ihrer Plattform mit »ulimit -s« oder der lokalen Entsprechung." @@ -36052,16 +36347,28 @@ msgstr "Fehler während der Erzeugung des Speicherkontexts »%s«." msgid "could not attach to dynamic shared area" msgstr "konnte nicht an dynamische Shared Area anbinden" -#: utils/mmgr/mcxt.c:1207 +#: utils/mmgr/mcxt.c:1210 #, c-format msgid "Failed on request of size %zu in memory context \"%s\"." msgstr "Fehler bei Anfrage mit Größe %zu im Speicherkontext »%s«." -#: utils/mmgr/mcxt.c:1363 +#: utils/mmgr/mcxt.c:1366 #, c-format msgid "logging memory contexts of PID %d" msgstr "logge Speicherkontexte von PID %d" +#: utils/mmgr/mcxt.c:1747 +#, fuzzy, c-format +#| msgid "invalid memory allocation request size %zu + %zu\n" +msgid "invalid memory allocation request size %zu + %zu" +msgstr "ungültige Speicheranforderungsgröße %zu + %zu\n" + +#: utils/mmgr/mcxt.c:1766 +#, fuzzy, c-format +#| msgid "invalid memory allocation request size %zu * %zu\n" +msgid "invalid memory allocation request size %zu * %zu" +msgstr "ungültige Speicheranforderungsgröße %zu * %zu\n" + #: utils/mmgr/portalmem.c:189 #, c-format msgid "cursor \"%s\" already exists" @@ -36196,10 +36503,30 @@ msgstr "eine serialisierbare Transaktion, die nicht im Read-Only-Modus ist, kann msgid "cannot import a snapshot from a different database" msgstr "kann keinen Snapshot aus einer anderen Datenbank importieren" +#, fuzzy, c-format +#~| msgid "This operation is not supported for partitioned tables." +#~ msgid "REPACK (CONCURRENTLY) is not supported for partitioned tables" +#~ msgstr "Diese Operation wird für partitionierte Tabellen nicht unterstützt." + +#, fuzzy, c-format +#~| msgid "column \"%s\" is in index used as replica identity" +#~ msgid "Relation \"%s\" has insufficient replication identity." +#~ msgstr "Spalte »%s« ist in einem Index, der als Replik-Identität verwendet wird" + #, c-format #~ msgid "The owner of a FOR ALL TABLES publication must be a superuser." #~ msgstr "Der Eigentümer einer FOR-ALL-TABLES-Publikation muss ein Superuser sein." +#, fuzzy, c-format +#~| msgid "cannot open relation \"%s\"" +#~ msgid "cannot process relation \"%s\"" +#~ msgstr "kann Relation »%s« nicht öffnen" + +#, fuzzy, c-format +#~| msgid "cannot lock relation \"%s\"" +#~ msgid "cannot repack relation \"%s\"" +#~ msgstr "kann Relation »%s« nicht sperren" + #, c-format #~ msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" #~ msgstr "Spalte »%s« kann nicht in Statistiken verwendet werden, weil ihr Typ %s keine Standardoperatorklasse für btree hat" @@ -36207,3 +36534,27 @@ msgstr "kann keinen Snapshot aus einer anderen Datenbank importieren" #, c-format #~ msgid "expression cannot be used in multivariate statistics because its type %s has no default btree operator class" #~ msgstr "Ausdruck kann nicht in multivariaten Statistiken verwendet werden, weil sein Typ %s keine Standardoperatorklasse für btree hat" + +#, fuzzy, c-format +#~| msgid "column \"%s\" specified more than once" +#~ msgid "option \"%s\" is specified more than once" +#~ msgstr "Spalte »%s« mehrmals angegeben" + +#, fuzzy, c-format +#~| msgid "name at variadic position %d is null" +#~ msgid "option name at variadic position %d is null" +#~ msgstr "Name auf variadischer Position %d ist NULL" + +#, c-format +#~ msgid "requested shared memory size overflows size_t" +#~ msgstr "angeforderte Shared-Memory-Größe übersteigt Kapazität von size_t" + +#, fuzzy, c-format +#~| msgid "unrecognized %s option \"%s\"" +#~ msgid "unrecognized option: \"%s\"" +#~ msgstr "unbekannte %s-Option »%s«" + +#, fuzzy, c-format +#~| msgid "argument \"%s\" must not be null" +#~ msgid "value for option \"%s\" must not be null" +#~ msgstr "Argument »%s« darf nicht NULL sein" diff --git a/src/backend/po/ja.po b/src/backend/po/ja.po index 15daee9569b..90ef1cf9f2b 100644 --- a/src/backend/po/ja.po +++ b/src/backend/po/ja.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: postgres (PostgreSQL 19)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-19 09:30+0900\n" -"PO-Revision-Date: 2026-05-19 16:12+0900\n" +"POT-Creation-Date: 2026-07-06 09:36+0900\n" +"PO-Revision-Date: 2026-07-06 15:36+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: jpug-doc \n" "Language: ja\n" @@ -82,24 +82,24 @@ msgstr "圧縮アルゴリズム\"%s\"は長距離モードをサポートしま msgid "not recorded" msgstr "記録されていません" -#: ../common/controldata_utils.c:94 ../common/controldata_utils.c:98 commands/copyfrom.c:1907 commands/extension.c:4023 utils/adt/genfile.c:123 utils/time/snapmgr.c:1450 +#: ../common/controldata_utils.c:94 ../common/controldata_utils.c:98 commands/copyfrom.c:1903 commands/extension.c:4025 utils/adt/genfile.c:123 utils/time/snapmgr.c:1450 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "ファイル\"%s\"を読み込み用にオープンできませんでした: %m" -#: ../common/controldata_utils.c:109 ../common/controldata_utils.c:111 access/transam/timeline.c:144 access/transam/timeline.c:363 access/transam/twophase.c:1367 access/transam/xlog.c:3533 access/transam/xlog.c:4431 access/transam/xlogrecovery.c:1197 access/transam/xlogrecovery.c:1295 access/transam/xlogrecovery.c:1332 access/transam/xlogrecovery.c:1399 backup/basebackup.c:2147 backup/walsummary.c:283 commands/extension.c:4033 libpq/hba.c:765 -#: replication/logical/origin.c:786 replication/logical/origin.c:814 replication/logical/reorderbuffer.c:5394 replication/logical/snapbuild.c:2011 replication/slot.c:2751 replication/slot.c:2792 replication/walsender.c:678 storage/file/buffile.c:471 storage/file/copydir.c:202 utils/adt/genfile.c:197 utils/adt/misc.c:1001 utils/cache/relmapper.c:830 +#: ../common/controldata_utils.c:109 ../common/controldata_utils.c:111 access/transam/timeline.c:144 access/transam/timeline.c:363 access/transam/twophase.c:1367 access/transam/xlog.c:3533 access/transam/xlog.c:4431 access/transam/xlogrecovery.c:1197 access/transam/xlogrecovery.c:1295 access/transam/xlogrecovery.c:1332 access/transam/xlogrecovery.c:1399 backup/basebackup.c:2145 backup/walsummary.c:283 commands/extension.c:4035 libpq/hba.c:765 +#: replication/logical/origin.c:786 replication/logical/origin.c:814 replication/logical/reorderbuffer.c:5392 replication/logical/snapbuild.c:1955 replication/slot.c:2747 replication/slot.c:2788 replication/walsender.c:678 storage/file/buffile.c:471 storage/file/copydir.c:202 utils/adt/genfile.c:197 utils/adt/misc.c:1001 utils/cache/relmapper.c:830 #, c-format msgid "could not read file \"%s\": %m" msgstr "ファイル\"%s\"の読み込みに失敗しました: %m" -#: ../common/controldata_utils.c:117 ../common/controldata_utils.c:120 access/transam/xlog.c:3538 access/transam/xlog.c:4436 replication/logical/origin.c:791 replication/logical/origin.c:829 replication/logical/snapbuild.c:2016 replication/slot.c:2755 replication/slot.c:2796 replication/walsender.c:683 utils/cache/relmapper.c:834 +#: ../common/controldata_utils.c:117 ../common/controldata_utils.c:120 access/transam/xlog.c:3538 access/transam/xlog.c:4436 replication/logical/origin.c:791 replication/logical/origin.c:829 replication/logical/snapbuild.c:1960 replication/slot.c:2751 replication/slot.c:2792 replication/walsender.c:683 utils/cache/relmapper.c:834 #, c-format msgid "could not read file \"%s\": read %d of %zu" msgstr "ファイル\"%1$s\"を読み込めませんでした: %3$zuバイトのうち%2$dバイトを読み込みました" #: ../common/controldata_utils.c:129 ../common/controldata_utils.c:133 ../common/controldata_utils.c:278 ../common/controldata_utils.c:281 access/heap/rewriteheap.c:1144 access/heap/rewriteheap.c:1249 access/transam/slru.c:1157 access/transam/timeline.c:393 access/transam/timeline.c:439 access/transam/timeline.c:513 access/transam/twophase.c:1379 access/transam/twophase.c:1805 access/transam/xlog.c:3379 access/transam/xlog.c:3573 access/transam/xlog.c:3578 -#: access/transam/xlog.c:3714 access/transam/xlog.c:4401 access/transam/xlog.c:5691 commands/copyfrom.c:1957 commands/copyto.c:740 libpq/be-fsstubs.c:475 libpq/be-fsstubs.c:545 replication/logical/origin.c:724 replication/logical/origin.c:862 replication/logical/reorderbuffer.c:5446 replication/logical/snapbuild.c:1756 replication/logical/snapbuild.c:1882 replication/slot.c:2637 replication/slot.c:2803 replication/walsender.c:693 storage/file/copydir.c:225 +#: access/transam/xlog.c:3714 access/transam/xlog.c:4401 access/transam/xlog.c:5690 commands/copyfrom.c:1953 commands/copyto.c:758 libpq/be-fsstubs.c:475 libpq/be-fsstubs.c:545 replication/logical/origin.c:724 replication/logical/origin.c:862 replication/logical/reorderbuffer.c:5444 replication/logical/snapbuild.c:1700 replication/logical/snapbuild.c:1826 replication/slot.c:2633 replication/slot.c:2799 replication/walsender.c:693 storage/file/copydir.c:225 #: storage/file/copydir.c:230 storage/file/copydir.c:285 storage/file/copydir.c:290 storage/file/fd.c:829 storage/file/fd.c:3803 storage/file/fd.c:3909 utils/cache/relmapper.c:842 utils/cache/relmapper.c:957 #, c-format msgid "could not close file \"%s\": %m" @@ -123,28 +123,28 @@ msgstr "" "PostgreSQLインストレーションはこのデータディレクトリと互換性がなくなります。" #: ../common/controldata_utils.c:226 ../common/controldata_utils.c:231 ../common/file_utils.c:69 ../common/file_utils.c:370 ../common/file_utils.c:428 ../common/file_utils.c:502 access/heap/rewriteheap.c:1232 access/transam/slru.c:1111 access/transam/timeline.c:112 access/transam/timeline.c:252 access/transam/timeline.c:349 access/transam/twophase.c:1323 access/transam/xlog.c:3269 access/transam/xlog.c:3449 access/transam/xlog.c:3488 access/transam/xlog.c:3681 -#: access/transam/xlog.c:4421 access/transam/xlogrecovery.c:4274 access/transam/xlogrecovery.c:4375 access/transam/xlogutils.c:825 backup/basebackup.c:553 backup/basebackup.c:1602 backup/walsummary.c:220 libpq/hba.c:622 postmaster/syslogger.c:1512 replication/logical/origin.c:776 replication/logical/reorderbuffer.c:4051 replication/logical/reorderbuffer.c:4605 replication/logical/reorderbuffer.c:5374 replication/logical/snapbuild.c:1711 -#: replication/logical/snapbuild.c:1823 replication/slot.c:2723 replication/walsender.c:651 replication/walsender.c:3307 storage/file/copydir.c:168 storage/file/copydir.c:256 storage/file/fd.c:804 storage/file/fd.c:3560 storage/file/fd.c:3790 storage/file/fd.c:3880 storage/smgr/md.c:697 utils/cache/relmapper.c:819 utils/cache/relmapper.c:936 utils/error/elog.c:2323 utils/init/miscinit.c:1536 utils/init/miscinit.c:1670 utils/init/miscinit.c:1747 utils/misc/guc.c:4680 +#: access/transam/xlog.c:4421 access/transam/xlogrecovery.c:4276 access/transam/xlogrecovery.c:4377 access/transam/xlogutils.c:849 backup/basebackup.c:553 backup/basebackup.c:1600 backup/walsummary.c:220 libpq/hba.c:622 postmaster/syslogger.c:1531 replication/logical/origin.c:776 replication/logical/reorderbuffer.c:4049 replication/logical/reorderbuffer.c:4603 replication/logical/reorderbuffer.c:5372 replication/logical/snapbuild.c:1655 +#: replication/logical/snapbuild.c:1767 replication/slot.c:2719 replication/walsender.c:651 replication/walsender.c:3329 storage/file/copydir.c:168 storage/file/copydir.c:256 storage/file/fd.c:804 storage/file/fd.c:3560 storage/file/fd.c:3790 storage/file/fd.c:3880 storage/smgr/md.c:697 utils/cache/relmapper.c:819 utils/cache/relmapper.c:936 utils/error/elog.c:2323 utils/init/miscinit.c:1536 utils/init/miscinit.c:1670 utils/init/miscinit.c:1747 utils/misc/guc.c:4680 #: utils/misc/guc.c:4730 #, c-format msgid "could not open file \"%s\": %m" msgstr "ファイル\"%s\"をオープンできませんでした: %m" -#: ../common/controldata_utils.c:247 ../common/controldata_utils.c:250 access/transam/twophase.c:1778 access/transam/twophase.c:1787 access/transam/xlog.c:9947 access/transam/xlogfuncs.c:718 backup/basebackup_server.c:173 backup/basebackup_server.c:266 backup/walsummary.c:304 postmaster/postmaster.c:4155 postmaster/syslogger.c:1523 postmaster/syslogger.c:1536 postmaster/syslogger.c:1549 utils/cache/relmapper.c:948 +#: ../common/controldata_utils.c:247 ../common/controldata_utils.c:250 access/transam/twophase.c:1778 access/transam/twophase.c:1787 access/transam/xlog.c:9951 access/transam/xlogfuncs.c:718 backup/basebackup_server.c:173 backup/basebackup_server.c:266 backup/walsummary.c:304 postmaster/postmaster.c:4155 postmaster/syslogger.c:1542 postmaster/syslogger.c:1555 postmaster/syslogger.c:1568 utils/cache/relmapper.c:948 #, c-format msgid "could not write file \"%s\": %m" msgstr "ファイル\"%s\"を書き出せませんでした: %m" -#: ../common/controldata_utils.c:264 ../common/controldata_utils.c:269 ../common/file_utils.c:440 ../common/file_utils.c:510 access/heap/rewriteheap.c:928 access/heap/rewriteheap.c:1138 access/heap/rewriteheap.c:1243 access/transam/slru.c:1150 access/transam/timeline.c:433 access/transam/timeline.c:507 access/transam/twophase.c:1799 access/transam/xlog.c:3369 access/transam/xlog.c:3567 access/transam/xlog.c:4394 access/transam/xlog.c:9340 access/transam/xlog.c:9384 -#: backup/basebackup_server.c:207 commands/dbcommands.c:518 replication/logical/snapbuild.c:1749 replication/slot.c:2621 replication/slot.c:2733 storage/file/fd.c:821 storage/file/fd.c:3901 storage/smgr/md.c:1480 storage/smgr/md.c:1540 storage/sync/sync.c:447 utils/misc/guc.c:4428 +#: ../common/controldata_utils.c:264 ../common/controldata_utils.c:269 ../common/file_utils.c:440 ../common/file_utils.c:510 access/heap/rewriteheap.c:928 access/heap/rewriteheap.c:1138 access/heap/rewriteheap.c:1243 access/transam/slru.c:1150 access/transam/timeline.c:433 access/transam/timeline.c:507 access/transam/twophase.c:1799 access/transam/xlog.c:3369 access/transam/xlog.c:3567 access/transam/xlog.c:4394 access/transam/xlog.c:9344 access/transam/xlog.c:9388 +#: backup/basebackup_server.c:207 commands/dbcommands.c:518 replication/logical/snapbuild.c:1693 replication/slot.c:2617 replication/slot.c:2729 storage/file/fd.c:821 storage/file/fd.c:3901 storage/smgr/md.c:1480 storage/smgr/md.c:1540 storage/sync/sync.c:447 utils/misc/guc.c:4428 #, c-format msgid "could not fsync file \"%s\": %m" msgstr "ファイル\"%s\"をfsyncできませんでした: %m" #: ../common/cryptohash.c:261 ../common/cryptohash_openssl.c:158 ../common/cryptohash_openssl.c:356 ../common/exec.c:544 ../common/exec.c:589 ../common/exec.c:681 ../common/hmac.c:309 ../common/hmac.c:325 ../common/hmac_openssl.c:151 ../common/hmac_openssl.c:339 ../common/jsonapi.c:2459 ../common/md5_common.c:156 ../common/parse_manifest.c:157 ../common/parse_manifest.c:852 ../common/psprintf.c:140 ../common/scram-common.c:268 ../port/path.c:846 ../port/path.c:883 -#: ../port/path.c:900 access/transam/twophase.c:1432 access/transam/xlogrecovery.c:509 lib/dshash.c:257 libpq/auth.c:1358 libpq/auth.c:1402 libpq/auth.c:1973 libpq/be-secure-gssapi.c:539 libpq/be-secure-gssapi.c:719 postmaster/bgworker.c:381 postmaster/bgworker.c:1045 postmaster/postmaster.c:3615 postmaster/walsummarizer.c:935 replication/libpqwalreceiver/libpqwalreceiver.c:367 replication/logical/logical.c:201 replication/walsender.c:860 -#: storage/buffer/localbuf.c:778 storage/file/fd.c:913 storage/file/fd.c:1431 storage/file/fd.c:1592 storage/file/fd.c:2576 storage/ipc/procarray.c:1456 storage/ipc/procarray.c:2156 storage/ipc/procarray.c:2163 storage/ipc/procarray.c:2668 storage/ipc/procarray.c:3408 utils/activity/pgstat_shmem.c:549 utils/adt/pg_locale.c:491 utils/adt/pg_locale.c:565 utils/adt/pg_locale_icu.c:580 utils/adt/pg_locale_libc.c:512 utils/adt/pg_locale_libc.c:617 -#: utils/adt/pg_locale_libc.c:710 utils/fmgr/dfmgr.c:234 utils/hash/dynahash.c:535 utils/hash/dynahash.c:615 utils/hash/dynahash.c:1031 utils/mb/mbutils.c:410 utils/mb/mbutils.c:438 utils/mb/mbutils.c:825 utils/mb/mbutils.c:852 utils/misc/guc.c:646 utils/misc/guc.c:671 utils/misc/guc.c:941 utils/misc/guc.c:4406 utils/misc/tzparser.c:479 utils/mmgr/aset.c:451 utils/mmgr/bump.c:185 utils/mmgr/dsa.c:722 utils/mmgr/dsa.c:744 utils/mmgr/dsa.c:825 +#: ../port/path.c:900 access/transam/twophase.c:1432 access/transam/xlogrecovery.c:509 lib/dshash.c:257 libpq/auth.c:1391 libpq/auth.c:1435 libpq/auth.c:2006 libpq/be-secure-gssapi.c:539 libpq/be-secure-gssapi.c:719 postmaster/bgworker.c:381 postmaster/bgworker.c:1045 postmaster/postmaster.c:3615 postmaster/walsummarizer.c:935 replication/libpqwalreceiver/libpqwalreceiver.c:367 replication/logical/logical.c:201 replication/walsender.c:860 +#: storage/buffer/localbuf.c:778 storage/file/fd.c:913 storage/file/fd.c:1431 storage/file/fd.c:1592 storage/file/fd.c:2576 storage/ipc/procarray.c:1456 storage/ipc/procarray.c:2156 storage/ipc/procarray.c:2170 storage/ipc/procarray.c:2674 storage/ipc/procarray.c:3395 utils/activity/pgstat_shmem.c:549 utils/adt/pg_locale.c:491 utils/adt/pg_locale.c:565 utils/adt/pg_locale_icu.c:595 utils/adt/pg_locale_libc.c:517 utils/adt/pg_locale_libc.c:616 +#: utils/adt/pg_locale_libc.c:703 utils/fmgr/dfmgr.c:234 utils/hash/dynahash.c:535 utils/hash/dynahash.c:615 utils/hash/dynahash.c:1031 utils/mb/mbutils.c:410 utils/mb/mbutils.c:438 utils/mb/mbutils.c:825 utils/mb/mbutils.c:852 utils/misc/guc.c:646 utils/misc/guc.c:671 utils/misc/guc.c:941 utils/misc/guc.c:4406 utils/misc/tzparser.c:479 utils/mmgr/aset.c:451 utils/mmgr/bump.c:185 utils/mmgr/dsa.c:722 utils/mmgr/dsa.c:744 utils/mmgr/dsa.c:825 #: utils/mmgr/generation.c:217 utils/mmgr/mcxt.c:1209 utils/mmgr/slab.c:370 #, c-format msgid "out of memory" @@ -182,7 +182,7 @@ msgstr "実行すべき\"%s\"がありませんでした" msgid "could not resolve path \"%s\" to absolute form: %m" msgstr "パス\"%s\"を絶対パス形式に変換できませんでした: %m" -#: ../common/exec.c:364 commands/collationcmds.c:877 commands/copyfrom.c:1891 commands/copyto.c:1148 libpq/be-secure-common.c:66 +#: ../common/exec.c:364 commands/collationcmds.c:877 commands/copyfrom.c:1887 commands/copyto.c:1170 libpq/be-secure-common.c:66 #, c-format msgid "could not execute command \"%s\": %m" msgstr "コマンド\"%s\"を実行できませんでした: %m" @@ -227,8 +227,8 @@ msgstr "メモリ割り当て要求サイズ %zu * %zu が不正です\n" msgid "could not synchronize file system for file \"%s\": %m" msgstr "ファイル\"%s\"に対してファイルシステムを同期できませんでした: %m" -#: ../common/file_utils.c:123 ../common/file_utils.c:588 ../common/file_utils.c:592 access/transam/twophase.c:1335 access/transam/xlogarchive.c:112 access/transam/xlogarchive.c:236 backup/basebackup.c:363 backup/basebackup.c:559 backup/basebackup.c:630 backup/walsummary.c:247 catalog/pg_tablespace.c:67 commands/copyfrom.c:1917 commands/copyto.c:1194 commands/extension.c:4012 commands/tablespace.c:812 commands/tablespace.c:901 postmaster/pgarch.c:685 -#: replication/logical/snapbuild.c:1606 replication/logical/snapbuild.c:2133 storage/file/fd.c:1956 storage/file/fd.c:2044 storage/file/fd.c:3614 utils/adt/dbsize.c:105 utils/adt/dbsize.c:266 utils/adt/dbsize.c:355 utils/adt/genfile.c:437 utils/adt/genfile.c:613 +#: ../common/file_utils.c:123 ../common/file_utils.c:588 ../common/file_utils.c:592 access/transam/twophase.c:1335 access/transam/xlogarchive.c:112 access/transam/xlogarchive.c:236 backup/basebackup.c:363 backup/basebackup.c:559 backup/basebackup.c:630 backup/walsummary.c:247 catalog/pg_tablespace.c:67 commands/copyfrom.c:1913 commands/copyto.c:1216 commands/extension.c:4014 commands/tablespace.c:812 commands/tablespace.c:901 postmaster/pgarch.c:685 +#: replication/logical/snapbuild.c:1550 replication/logical/snapbuild.c:2077 storage/file/fd.c:1956 storage/file/fd.c:2044 storage/file/fd.c:3614 utils/adt/dbsize.c:105 utils/adt/dbsize.c:266 utils/adt/dbsize.c:355 utils/adt/genfile.c:437 utils/adt/genfile.c:613 #, c-format msgid "could not stat file \"%s\": %m" msgstr "ファイル\"%s\"のstatに失敗しました: %m" @@ -248,7 +248,7 @@ msgstr "ディレクトリ\"%s\"をオープンできませんでした: %m" msgid "could not read directory \"%s\": %m" msgstr "ディレクトリ\"%s\"を読み取れませんでした: %m" -#: ../common/file_utils.c:520 access/transam/xlogarchive.c:390 postmaster/pgarch.c:839 postmaster/syslogger.c:1560 replication/logical/snapbuild.c:1768 replication/slot.c:1110 replication/slot.c:2504 replication/slot.c:2653 storage/file/fd.c:839 utils/time/snapmgr.c:1275 +#: ../common/file_utils.c:520 access/transam/xlogarchive.c:390 postmaster/pgarch.c:839 postmaster/syslogger.c:1579 replication/logical/snapbuild.c:1712 replication/slot.c:1106 replication/slot.c:2500 replication/slot.c:2649 storage/file/fd.c:839 utils/time/snapmgr.c:1275 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "ファイル\"%s\"の名前を\"%s\"に変更できませんでした: %m" @@ -470,7 +470,7 @@ msgstr "ファイル名をデコードできませんでした" msgid "file size is not an integer" msgstr "ファイルサイズが整数ではありません" -#: ../common/parse_manifest.c:699 backup/basebackup.c:874 +#: ../common/parse_manifest.c:699 backup/basebackup.c:872 #, c-format msgid "unrecognized checksum algorithm: \"%s\"" msgstr "認識できないチェックサムアルゴリズム: \"%s\"" @@ -537,7 +537,7 @@ msgstr "目録チェックサムの不一致" msgid "could not parse backup manifest: %s" msgstr "バックアップ目録をパースできませんでした: %s" -#: ../common/percentrepl.c:79 ../common/percentrepl.c:85 ../common/percentrepl.c:118 ../common/percentrepl.c:124 tcop/backend_startup.c:794 utils/misc/guc.c:3061 utils/misc/guc.c:3102 utils/misc/guc.c:3186 utils/misc/guc.c:4610 utils/misc/guc.c:6809 utils/misc/guc.c:6850 +#: ../common/percentrepl.c:79 ../common/percentrepl.c:85 ../common/percentrepl.c:118 ../common/percentrepl.c:124 tcop/backend_startup.c:801 utils/misc/guc.c:3061 utils/misc/guc.c:3102 utils/misc/guc.c:3186 utils/misc/guc.c:4610 utils/misc/guc.c:6809 utils/misc/guc.c:6850 #, c-format msgid "invalid value for parameter \"%s\": \"%s\"" msgstr "パラメータ\"%s\"の値が不正です: \"%s\"" @@ -597,7 +597,7 @@ msgstr "制限付きトークンで再実行できませんでした: %lu" msgid "could not get exit code from subprocess: error code %lu" msgstr "サブプロセスの終了コードを取得できませんでした: エラーコード %lu" -#: ../common/rmtree.c:97 access/heap/rewriteheap.c:1217 access/transam/twophase.c:1738 access/transam/xlogarchive.c:120 access/transam/xlogarchive.c:400 backup/walsummary.c:254 postmaster/postmaster.c:1084 postmaster/syslogger.c:1489 replication/logical/origin.c:632 replication/logical/reorderbuffer.c:4873 replication/logical/snapbuild.c:1649 replication/logical/snapbuild.c:2105 replication/slot.c:2707 storage/file/fd.c:879 storage/file/fd.c:3428 +#: ../common/rmtree.c:97 access/heap/rewriteheap.c:1217 access/transam/twophase.c:1738 access/transam/xlogarchive.c:120 access/transam/xlogarchive.c:400 backup/walsummary.c:254 postmaster/postmaster.c:1084 postmaster/syslogger.c:1508 replication/logical/origin.c:632 replication/logical/reorderbuffer.c:4871 replication/logical/snapbuild.c:1593 replication/logical/snapbuild.c:2049 replication/slot.c:2703 storage/file/fd.c:879 storage/file/fd.c:3428 #: storage/file/fd.c:3490 storage/file/reinit.c:261 storage/ipc/dsm.c:353 storage/smgr/md.c:412 storage/smgr/md.c:471 storage/sync/sync.c:244 utils/time/snapmgr.c:1611 #, c-format msgid "could not remove file \"%s\": %m" @@ -714,11 +714,11 @@ msgid "checkpointer" msgstr "チェックポインター" #: ../include/postmaster/proctypelist.h:41 -msgid "datachecksum launcher" +msgid "datachecksums launcher" msgstr "データチェックサム・ランチャー" #: ../include/postmaster/proctypelist.h:42 -msgid "datachecksum worker" +msgid "datachecksums worker" msgstr "データチェックサム・ワーカー" #: ../include/postmaster/proctypelist.h:43 @@ -842,7 +842,7 @@ msgstr "次のWALへの強制切り替え時間を設定します。" #. translator: GUC parameter "statement_timeout" long description #. translator: GUC parameter "transaction_timeout" long description #. translator: GUC parameter "wal_receiver_timeout" long description -#: ../include/utils/guc_tables.inc.c:147 ../include/utils/guc_tables.inc.c:2400 ../include/utils/guc_tables.inc.c:2434 ../include/utils/guc_tables.inc.c:2993 ../include/utils/guc_tables.inc.c:5356 ../include/utils/guc_tables.inc.c:6068 ../include/utils/guc_tables.inc.c:6563 utils/guc_tables.inc.c:147 utils/guc_tables.inc.c:2400 utils/guc_tables.inc.c:2434 utils/guc_tables.inc.c:2993 utils/guc_tables.inc.c:5356 utils/guc_tables.inc.c:6068 utils/guc_tables.inc.c:6563 +#: ../include/utils/guc_tables.inc.c:147 ../include/utils/guc_tables.inc.c:2400 ../include/utils/guc_tables.inc.c:2434 ../include/utils/guc_tables.inc.c:2993 ../include/utils/guc_tables.inc.c:5374 ../include/utils/guc_tables.inc.c:6086 ../include/utils/guc_tables.inc.c:6581 utils/guc_tables.inc.c:147 utils/guc_tables.inc.c:2400 utils/guc_tables.inc.c:2434 utils/guc_tables.inc.c:2993 utils/guc_tables.inc.c:5374 utils/guc_tables.inc.c:6086 utils/guc_tables.inc.c:6581 msgid "0 disables the timeout." msgstr "0でこのタイムアウトを無効にします。" @@ -1152,7 +1152,7 @@ msgstr "コミットタイムスタンプのキャッシュで専有するバッ #. translator: GUC parameter "commit_timestamp_buffers" long description #. translator: GUC parameter "subtransaction_buffers" long description #. translator: GUC parameter "transaction_buffers" long description -#: ../include/utils/guc_tables.inc.c:888 ../include/utils/guc_tables.inc.c:5389 ../include/utils/guc_tables.inc.c:6003 utils/guc_tables.inc.c:888 utils/guc_tables.inc.c:5389 utils/guc_tables.inc.c:6003 +#: ../include/utils/guc_tables.inc.c:888 ../include/utils/guc_tables.inc.c:5407 ../include/utils/guc_tables.inc.c:6021 utils/guc_tables.inc.c:888 utils/guc_tables.inc.c:5407 utils/guc_tables.inc.c:6021 msgid "0 means use a fraction of \"shared_buffers\"." msgstr "0で\"shared_buffers\"の一部を使用します。" @@ -1365,7 +1365,7 @@ msgstr "テーブルとインデックスの作成先となるデフォルトの #. translator: GUC parameter "temp_tablespaces" long description #. translator: GUC parameter "default_tablespace" long description #. translator: GUC parameter "temp_tablespaces" long description -#: ../include/utils/guc_tables.inc.c:1389 ../include/utils/guc_tables.inc.c:5680 utils/guc_tables.inc.c:1389 utils/guc_tables.inc.c:5680 +#: ../include/utils/guc_tables.inc.c:1389 ../include/utils/guc_tables.inc.c:5698 utils/guc_tables.inc.c:1389 utils/guc_tables.inc.c:5698 msgid "An empty string means use the database's default tablespace." msgstr "空文字列でデータベースのデフォルトのテーブル空間を使用します。" @@ -1433,7 +1433,7 @@ msgstr "ディスクサブシステムが効率的に処理可能な同時並行 #. translator: GUC parameter "maintenance_io_concurrency" long description #. translator: GUC parameter "effective_io_concurrency" long description #. translator: GUC parameter "maintenance_io_concurrency" long description -#: ../include/utils/guc_tables.inc.c:1539 ../include/utils/guc_tables.inc.c:3623 utils/guc_tables.inc.c:1539 utils/guc_tables.inc.c:3623 +#: ../include/utils/guc_tables.inc.c:1539 ../include/utils/guc_tables.inc.c:3641 utils/guc_tables.inc.c:1539 utils/guc_tables.inc.c:3641 msgid "0 disables simultaneous requests." msgstr "0で同時並列リクエストを無効にします。" @@ -1768,7 +1768,7 @@ msgstr "要求が見込まれるヒュージページのサイズ。" #. translator: GUC parameter "tcp_keepalives_idle" long description #. translator: GUC parameter "tcp_keepalives_interval" long description #. translator: GUC parameter "tcp_user_timeout" long description -#: ../include/utils/guc_tables.inc.c:2324 ../include/utils/guc_tables.inc.c:5585 ../include/utils/guc_tables.inc.c:5605 ../include/utils/guc_tables.inc.c:5625 utils/guc_tables.inc.c:2324 utils/guc_tables.inc.c:5585 utils/guc_tables.inc.c:5605 utils/guc_tables.inc.c:5625 +#: ../include/utils/guc_tables.inc.c:2324 ../include/utils/guc_tables.inc.c:5603 ../include/utils/guc_tables.inc.c:5623 ../include/utils/guc_tables.inc.c:5643 utils/guc_tables.inc.c:2324 utils/guc_tables.inc.c:5603 utils/guc_tables.inc.c:5623 utils/guc_tables.inc.c:5643 msgid "0 means use the system default." msgstr "0でシステムのデフォルト値を使用します。" @@ -2262,213 +2262,223 @@ msgstr "0で進捗情報の更新を無効にします。" msgid "Sets the type of statements logged." msgstr "ログ出力する文の種類を設定。" -#. translator: GUC parameter "log_statement_sample_rate" short description +#. translator: GUC parameter "log_statement_max_length" short description #: ../include/utils/guc_tables.inc.c:3495 utils/guc_tables.inc.c:3495 +msgid "Sets the maximum length in bytes of logged statements." +msgstr "記録する文の最大長をバイト単位で設定。" + +#. translator: GUC parameter "log_statement_max_length" long description +#: ../include/utils/guc_tables.inc.c:3497 utils/guc_tables.inc.c:3497 +msgid "-1 means log statement in full; 0 means log an empty statement body." +msgstr "-1 で文全体を記録します; 0 で空の文本体を記録します。" + +#. translator: GUC parameter "log_statement_sample_rate" short description +#: ../include/utils/guc_tables.inc.c:3513 utils/guc_tables.inc.c:3513 msgid "Fraction of statements exceeding \"log_min_duration_sample\" to be logged." msgstr "\"log_min_duration_sample\"を超過した文のうちログ出力を行う割合。" #. translator: GUC parameter "log_statement_sample_rate" long description -#: ../include/utils/guc_tables.inc.c:3497 utils/guc_tables.inc.c:3497 +#: ../include/utils/guc_tables.inc.c:3515 utils/guc_tables.inc.c:3515 msgid "Use a value between 0.0 (never log) and 1.0 (always log)." msgstr "0.0(ログ出力しない)から1.0(すべてログ出力する)の間の値を指定してください。" #. translator: GUC parameter "log_statement_stats" short description -#: ../include/utils/guc_tables.inc.c:3512 utils/guc_tables.inc.c:3512 +#: ../include/utils/guc_tables.inc.c:3530 utils/guc_tables.inc.c:3530 msgid "Writes cumulative performance statistics to the server log." msgstr "累積の性能統計情報をサーバーログに出力します。" #. translator: GUC parameter "log_temp_files" short description -#: ../include/utils/guc_tables.inc.c:3526 utils/guc_tables.inc.c:3526 +#: ../include/utils/guc_tables.inc.c:3544 utils/guc_tables.inc.c:3544 msgid "Log the use of temporary files larger than this number of kilobytes." msgstr "このキロバイト数よりも大きな一時ファイルの使用をログに記録します。" #. translator: GUC parameter "log_temp_files" long description -#: ../include/utils/guc_tables.inc.c:3528 utils/guc_tables.inc.c:3528 +#: ../include/utils/guc_tables.inc.c:3546 utils/guc_tables.inc.c:3546 msgid "-1 disables logging temporary files. 0 means log all temporary files." msgstr "-1で一時ファイルのログへの記録を無効にします。0ですべての一時ファイルをログに記録します。" #. translator: GUC parameter "log_timezone" short description -#: ../include/utils/guc_tables.inc.c:3544 utils/guc_tables.inc.c:3544 +#: ../include/utils/guc_tables.inc.c:3562 utils/guc_tables.inc.c:3562 msgid "Sets the time zone to use in log messages." msgstr "ログメッセージ使用するタイムゾーンを設定。" #. translator: GUC parameter "log_transaction_sample_rate" short description -#: ../include/utils/guc_tables.inc.c:3560 utils/guc_tables.inc.c:3560 +#: ../include/utils/guc_tables.inc.c:3578 utils/guc_tables.inc.c:3578 msgid "Sets the fraction of transactions from which to log all statements." msgstr "すべての文をログ出力するトランザクションの割合を設定します。" #. translator: GUC parameter "log_transaction_sample_rate" long description -#: ../include/utils/guc_tables.inc.c:3562 utils/guc_tables.inc.c:3562 +#: ../include/utils/guc_tables.inc.c:3580 utils/guc_tables.inc.c:3580 msgid "Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." msgstr "0.0 (ログ出力しない)から 1.0 (全てのトランザクションの全ての文をログ出力する)の間の値を指定してください。" #. translator: GUC parameter "log_truncate_on_rotation" short description -#: ../include/utils/guc_tables.inc.c:3577 utils/guc_tables.inc.c:3577 +#: ../include/utils/guc_tables.inc.c:3595 utils/guc_tables.inc.c:3595 msgid "Truncate existing log files of same name during log rotation." msgstr "ログローテーション時に既存の同一名称のログファイルを切り詰めます。" #. translator: GUC parameter "logging_collector" short description -#: ../include/utils/guc_tables.inc.c:3590 utils/guc_tables.inc.c:3590 +#: ../include/utils/guc_tables.inc.c:3608 utils/guc_tables.inc.c:3608 msgid "Start a subprocess to capture stderr, csvlog and/or jsonlog into log files." msgstr "標準エラー出力、CSVログ、および/またはJSONログをログファイルに記録するための子プロセスを開始します。" #. translator: GUC parameter "logical_decoding_work_mem" short description -#: ../include/utils/guc_tables.inc.c:3603 utils/guc_tables.inc.c:3603 +#: ../include/utils/guc_tables.inc.c:3621 utils/guc_tables.inc.c:3621 msgid "Sets the maximum memory to be used for logical decoding." msgstr "論理デコーディングで使用するメモリ量の上限を設定します。" #. translator: GUC parameter "logical_decoding_work_mem" long description -#: ../include/utils/guc_tables.inc.c:3605 utils/guc_tables.inc.c:3605 +#: ../include/utils/guc_tables.inc.c:3623 utils/guc_tables.inc.c:3623 msgid "This much memory can be used by each internal reorder buffer before spilling to disk." msgstr "個々の内部リオーダバッファはディスクに書き出す前にこれだけの量のメモリを使用することができます。" #. translator: GUC parameter "maintenance_io_concurrency" short description -#: ../include/utils/guc_tables.inc.c:3621 utils/guc_tables.inc.c:3621 +#: ../include/utils/guc_tables.inc.c:3639 utils/guc_tables.inc.c:3639 msgid "A variant of \"effective_io_concurrency\" that is used for maintenance work." msgstr "保守作業に使用される\"effective_io_concurrency\"の亜種。" #. translator: GUC parameter "maintenance_work_mem" short description -#: ../include/utils/guc_tables.inc.c:3640 utils/guc_tables.inc.c:3640 +#: ../include/utils/guc_tables.inc.c:3658 utils/guc_tables.inc.c:3658 msgid "Sets the maximum memory to be used for maintenance operations." msgstr "保守作業で使用される最大メモリ量を設定。" #. translator: GUC parameter "maintenance_work_mem" long description -#: ../include/utils/guc_tables.inc.c:3642 utils/guc_tables.inc.c:3642 +#: ../include/utils/guc_tables.inc.c:3660 utils/guc_tables.inc.c:3660 msgid "This includes operations such as VACUUM and CREATE INDEX." msgstr "VACUUMやCREATE INDEXなどの作業が含まれます。" #. translator: GUC parameter "max_active_replication_origins" short description -#: ../include/utils/guc_tables.inc.c:3658 utils/guc_tables.inc.c:3658 +#: ../include/utils/guc_tables.inc.c:3676 utils/guc_tables.inc.c:3676 msgid "Sets the maximum number of active replication origins." msgstr "有効なレプリケーション起源の最大数を設定します。" #. translator: GUC parameter "max_connections" short description -#: ../include/utils/guc_tables.inc.c:3673 utils/guc_tables.inc.c:3673 +#: ../include/utils/guc_tables.inc.c:3691 utils/guc_tables.inc.c:3691 msgid "Sets the maximum number of concurrent connections." msgstr "同時接続数の最大値を設定。" #. translator: GUC parameter "max_files_per_process" short description -#: ../include/utils/guc_tables.inc.c:3688 utils/guc_tables.inc.c:3688 +#: ../include/utils/guc_tables.inc.c:3706 utils/guc_tables.inc.c:3706 msgid "Sets the maximum number of files each server process is allowed to open simultaneously." msgstr "各サーバープロセスで同時にオープンできるファイルの最大数を設定。" #. translator: GUC parameter "max_function_args" short description -#: ../include/utils/guc_tables.inc.c:3703 utils/guc_tables.inc.c:3703 +#: ../include/utils/guc_tables.inc.c:3721 utils/guc_tables.inc.c:3721 msgid "Shows the maximum number of function arguments." msgstr "関数の引数の最大数を表示します。" #. translator: GUC parameter "max_identifier_length" short description -#: ../include/utils/guc_tables.inc.c:3719 utils/guc_tables.inc.c:3719 +#: ../include/utils/guc_tables.inc.c:3737 utils/guc_tables.inc.c:3737 msgid "Shows the maximum identifier length." msgstr "識別子の最大長を表示します。" #. translator: GUC parameter "max_index_keys" short description -#: ../include/utils/guc_tables.inc.c:3735 utils/guc_tables.inc.c:3735 +#: ../include/utils/guc_tables.inc.c:3753 utils/guc_tables.inc.c:3753 msgid "Shows the maximum number of index keys." msgstr "インデックスキーの最大数を表示します。" #. translator: GUC parameter "max_locks_per_transaction" short description -#: ../include/utils/guc_tables.inc.c:3751 utils/guc_tables.inc.c:3751 +#: ../include/utils/guc_tables.inc.c:3769 utils/guc_tables.inc.c:3769 msgid "Sets the maximum number of locks per transaction." msgstr "1トランザクション当たりのロック数の上限を設定。" #. translator: GUC parameter "max_locks_per_transaction" long description -#: ../include/utils/guc_tables.inc.c:3753 utils/guc_tables.inc.c:3753 +#: ../include/utils/guc_tables.inc.c:3771 utils/guc_tables.inc.c:3771 msgid "The shared lock table is sized on the assumption that at most \"max_locks_per_transaction\" objects per server process or prepared transaction will need to be locked at any one time." msgstr "共有ロックテーブルの大きさは、サーバープロセスまたは準備済みトランザクションごとに最大で\"max_locks_per_transaction\"個のオブジェクトが同時にロックされることを前提として決定されます。" #. translator: GUC parameter "max_logical_replication_workers" short description -#: ../include/utils/guc_tables.inc.c:3768 utils/guc_tables.inc.c:3768 +#: ../include/utils/guc_tables.inc.c:3786 utils/guc_tables.inc.c:3786 msgid "Maximum number of logical replication worker processes." msgstr "レプリケーションワーカープロセス数の最大値です。" #. translator: GUC parameter "max_notify_queue_pages" short description -#: ../include/utils/guc_tables.inc.c:3783 utils/guc_tables.inc.c:3783 +#: ../include/utils/guc_tables.inc.c:3801 utils/guc_tables.inc.c:3801 msgid "Sets the maximum number of allocated pages for NOTIFY / LISTEN queue." msgstr "LISTEN / NOTIFYキュー用に割り当てられるページ数の上限を設定。" #. translator: GUC parameter "max_parallel_apply_workers_per_subscription" short description -#: ../include/utils/guc_tables.inc.c:3798 utils/guc_tables.inc.c:3798 +#: ../include/utils/guc_tables.inc.c:3816 utils/guc_tables.inc.c:3816 msgid "Maximum number of parallel apply workers per subscription." msgstr "サブスクリプション毎のテーブル適用ワーカー数の最大値です。" #. translator: GUC parameter "max_parallel_maintenance_workers" short description -#: ../include/utils/guc_tables.inc.c:3813 utils/guc_tables.inc.c:3813 +#: ../include/utils/guc_tables.inc.c:3831 utils/guc_tables.inc.c:3831 msgid "Sets the maximum number of parallel processes per maintenance operation." msgstr "ひとつの保守作業に割り当てる並列処理プロセスの数の最大値を設定。" #. translator: GUC parameter "max_parallel_workers" short description -#: ../include/utils/guc_tables.inc.c:3828 utils/guc_tables.inc.c:3828 +#: ../include/utils/guc_tables.inc.c:3846 utils/guc_tables.inc.c:3846 msgid "Sets the maximum number of parallel workers that can be active at one time." msgstr "同時に活動可能な並列処理ワーカーの数の最大値を設定。" #. translator: GUC parameter "max_parallel_workers_per_gather" short description -#: ../include/utils/guc_tables.inc.c:3844 utils/guc_tables.inc.c:3844 +#: ../include/utils/guc_tables.inc.c:3862 utils/guc_tables.inc.c:3862 msgid "Sets the maximum number of parallel processes per executor node." msgstr "エグゼキュータノードあたりの並列処理プロセスの数の最大値を設定。" #. translator: GUC parameter "max_pred_locks_per_page" short description -#: ../include/utils/guc_tables.inc.c:3860 utils/guc_tables.inc.c:3860 +#: ../include/utils/guc_tables.inc.c:3878 utils/guc_tables.inc.c:3878 msgid "Sets the maximum number of predicate-locked tuples per page." msgstr "1ページあたりで述語ロックされるタプル数の上限値を設定。" #. translator: GUC parameter "max_pred_locks_per_page" long description -#: ../include/utils/guc_tables.inc.c:3862 utils/guc_tables.inc.c:3862 +#: ../include/utils/guc_tables.inc.c:3880 utils/guc_tables.inc.c:3880 msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." msgstr "あるコネクションで 、同じページ上でロックされるタプルの数がこの値を超えたときには、これらのロックはページレベルのロックに置き換えられます。" #. translator: GUC parameter "max_pred_locks_per_relation" short description -#: ../include/utils/guc_tables.inc.c:3877 utils/guc_tables.inc.c:3877 +#: ../include/utils/guc_tables.inc.c:3895 utils/guc_tables.inc.c:3895 msgid "Sets the maximum number of predicate-locked pages and tuples per relation." msgstr "1リレーション当たりで述語ロックされるページとタプルの数の上限値を設定。" #. translator: GUC parameter "max_pred_locks_per_relation" long description -#: ../include/utils/guc_tables.inc.c:3879 utils/guc_tables.inc.c:3879 +#: ../include/utils/guc_tables.inc.c:3897 utils/guc_tables.inc.c:3897 msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." msgstr "あるコネクションで、同じリレーション内でロックされるページ数とタプル数の合計がこの値を超えたときには、これらのロックはリレーションレベルのロックに置き換えられます。" #. translator: GUC parameter "max_pred_locks_per_transaction" short description -#: ../include/utils/guc_tables.inc.c:3894 utils/guc_tables.inc.c:3894 +#: ../include/utils/guc_tables.inc.c:3912 utils/guc_tables.inc.c:3912 msgid "Sets the maximum number of predicate locks per transaction." msgstr "1トランザクション当たりの述語ロック数の上限を設定。" #. translator: GUC parameter "max_pred_locks_per_transaction" long description -#: ../include/utils/guc_tables.inc.c:3896 utils/guc_tables.inc.c:3896 +#: ../include/utils/guc_tables.inc.c:3914 utils/guc_tables.inc.c:3914 msgid "The shared predicate lock table is sized on the assumption that at most \"max_pred_locks_per_transaction\" objects per server process or prepared transaction will need to be locked at any one time." msgstr "共有述語ロックテーブルの大きさは、サーバープロセスまたは準備済みトランザクションごとに最大で\"max_pred_locks_per_transaction\"個のオブジェクトが同時にロックされることを前提として決定されます。" #. translator: GUC parameter "max_prepared_transactions" short description -#: ../include/utils/guc_tables.inc.c:3911 utils/guc_tables.inc.c:3911 +#: ../include/utils/guc_tables.inc.c:3929 utils/guc_tables.inc.c:3929 msgid "Sets the maximum number of simultaneously prepared transactions." msgstr "同時に準備状態にできるトランザクションの最大数を設定。" #. translator: GUC parameter "max_repack_replication_slots" short description -#: ../include/utils/guc_tables.inc.c:3926 utils/guc_tables.inc.c:3926 +#: ../include/utils/guc_tables.inc.c:3944 utils/guc_tables.inc.c:3944 msgid "Sets the maximum number of replication slots for use by REPACK." msgstr "REPACKで使用するレプリケーションスロットの数の最大値を設定。" #. translator: GUC parameter "max_replication_slots" short description -#: ../include/utils/guc_tables.inc.c:3941 utils/guc_tables.inc.c:3941 +#: ../include/utils/guc_tables.inc.c:3959 utils/guc_tables.inc.c:3959 msgid "Sets the maximum number of simultaneously defined replication slots." msgstr "同時に定義できるレプリケーションスロットの数の最大値を設定。" #. translator: GUC parameter "max_slot_wal_keep_size" short description -#: ../include/utils/guc_tables.inc.c:3956 utils/guc_tables.inc.c:3956 +#: ../include/utils/guc_tables.inc.c:3974 utils/guc_tables.inc.c:3974 msgid "Sets the maximum WAL size that can be reserved by replication slots." msgstr "レプリケーションスロットで確保できるWALの量の最大値を設定します。" #. translator: GUC parameter "max_slot_wal_keep_size" long description -#: ../include/utils/guc_tables.inc.c:3958 utils/guc_tables.inc.c:3958 +#: ../include/utils/guc_tables.inc.c:3976 utils/guc_tables.inc.c:3976 msgid "Replication slots will be marked as failed, and segments released for deletion or recycling, if this much space is occupied by WAL on disk. -1 means no maximum." msgstr "ディスク内のWALがこの量に達すると、レプリケーションスロットは停止とマークされ、セグメントは削除あるいは再利用のために解放されます。-1で上限なしとなります。" #. translator: GUC parameter "max_stack_depth" short description -#: ../include/utils/guc_tables.inc.c:3974 utils/guc_tables.inc.c:3974 +#: ../include/utils/guc_tables.inc.c:3992 utils/guc_tables.inc.c:3992 msgid "Sets the maximum stack depth, in kilobytes." msgstr "スタック長の最大値をキロバイト単位で設定。" #. translator: GUC parameter "max_standby_archive_delay" short description -#: ../include/utils/guc_tables.inc.c:3992 utils/guc_tables.inc.c:3992 +#: ../include/utils/guc_tables.inc.c:4010 utils/guc_tables.inc.c:4010 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." msgstr "ホットスタンバイサーバーがアーカイブされた WAL データを処理している場合は、問い合わせをキャンセルする前に遅延秒数の最大値を設定。" @@ -2476,157 +2486,157 @@ msgstr "ホットスタンバイサーバーがアーカイブされた WAL デ #. translator: GUC parameter "max_standby_streaming_delay" long description #. translator: GUC parameter "max_standby_archive_delay" long description #. translator: GUC parameter "max_standby_streaming_delay" long description -#: ../include/utils/guc_tables.inc.c:3994 ../include/utils/guc_tables.inc.c:4012 utils/guc_tables.inc.c:3994 utils/guc_tables.inc.c:4012 +#: ../include/utils/guc_tables.inc.c:4012 ../include/utils/guc_tables.inc.c:4030 utils/guc_tables.inc.c:4012 utils/guc_tables.inc.c:4030 msgid "-1 means wait forever." msgstr "-1は無期限を意味します。" #. translator: GUC parameter "max_standby_streaming_delay" short description -#: ../include/utils/guc_tables.inc.c:4010 utils/guc_tables.inc.c:4010 +#: ../include/utils/guc_tables.inc.c:4028 utils/guc_tables.inc.c:4028 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." msgstr "ホットスタンバイサーバーがストリームの WAL データを処理している場合は、問い合わせをキャンセルする前に遅延秒数の最大値を設定。" #. translator: GUC parameter "max_sync_workers_per_subscription" short description -#: ../include/utils/guc_tables.inc.c:4028 utils/guc_tables.inc.c:4028 +#: ../include/utils/guc_tables.inc.c:4046 utils/guc_tables.inc.c:4046 msgid "Maximum number of workers per subscription for synchronizing tables and sequences." msgstr "テーブルとシーケンスの同期のためのワーカー数のサブスクリプション毎の最大値です。" #. translator: GUC parameter "max_wal_senders" short description -#: ../include/utils/guc_tables.inc.c:4043 utils/guc_tables.inc.c:4043 +#: ../include/utils/guc_tables.inc.c:4061 utils/guc_tables.inc.c:4061 msgid "Sets the maximum number of simultaneously running WAL sender processes." msgstr "WAL送信プロセスの最大同時実行数を設定。" #. translator: GUC parameter "max_wal_size" short description -#: ../include/utils/guc_tables.inc.c:4058 utils/guc_tables.inc.c:4058 +#: ../include/utils/guc_tables.inc.c:4076 utils/guc_tables.inc.c:4076 msgid "Sets the WAL size that triggers a checkpoint." msgstr "チェックポイントの契機となるWALのサイズを指定。" #. translator: GUC parameter "max_worker_processes" short description -#: ../include/utils/guc_tables.inc.c:4075 utils/guc_tables.inc.c:4075 +#: ../include/utils/guc_tables.inc.c:4093 utils/guc_tables.inc.c:4093 msgid "Maximum number of concurrent worker processes." msgstr "同時に実行されるワーカープロセス数の最大値です。" #. translator: GUC parameter "md5_password_warnings" short description -#: ../include/utils/guc_tables.inc.c:4090 utils/guc_tables.inc.c:4090 +#: ../include/utils/guc_tables.inc.c:4108 utils/guc_tables.inc.c:4108 msgid "Enables deprecation warnings for MD5 passwords." msgstr "MD5パスワードの非推奨警告を有効にする。" #. translator: GUC parameter "min_dynamic_shared_memory" short description -#: ../include/utils/guc_tables.inc.c:4103 utils/guc_tables.inc.c:4103 +#: ../include/utils/guc_tables.inc.c:4121 utils/guc_tables.inc.c:4121 msgid "Amount of dynamic shared memory reserved at startup." msgstr "起動時に予約される動的共有メモリの量。" #. translator: GUC parameter "min_eager_agg_group_size" short description -#: ../include/utils/guc_tables.inc.c:4119 utils/guc_tables.inc.c:4119 +#: ../include/utils/guc_tables.inc.c:4137 utils/guc_tables.inc.c:4137 msgid "Sets the minimum average group size required to consider applying eager aggregation." msgstr "貪欲集約の適用を検討する最小の平均グループサイズを設定。" #. translator: GUC parameter "min_parallel_index_scan_size" short description -#: ../include/utils/guc_tables.inc.c:4135 utils/guc_tables.inc.c:4135 +#: ../include/utils/guc_tables.inc.c:4153 utils/guc_tables.inc.c:4153 msgid "Sets the minimum amount of index data for a parallel scan." msgstr "並列スキャンを検討するインデックスデータの量の最小値を設定。" #. translator: GUC parameter "min_parallel_index_scan_size" long description -#: ../include/utils/guc_tables.inc.c:4137 utils/guc_tables.inc.c:4137 +#: ../include/utils/guc_tables.inc.c:4155 utils/guc_tables.inc.c:4155 msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." msgstr "この限度に到達できないような少ないページ数しか読み取らないとプランナが見積もった場合、並列スキャンは検討されません。" #. translator: GUC parameter "min_parallel_table_scan_size" short description -#: ../include/utils/guc_tables.inc.c:4153 utils/guc_tables.inc.c:4153 +#: ../include/utils/guc_tables.inc.c:4171 utils/guc_tables.inc.c:4171 msgid "Sets the minimum amount of table data for a parallel scan." msgstr "並列スキャンを検討するテーブルデータの量の最小値を設定。" #. translator: GUC parameter "min_parallel_table_scan_size" long description -#: ../include/utils/guc_tables.inc.c:4155 utils/guc_tables.inc.c:4155 +#: ../include/utils/guc_tables.inc.c:4173 utils/guc_tables.inc.c:4173 msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." msgstr "この限度に到達できないような少ないテーブルページ数しか読み取らないとプランナが見積もった場合、並列スキャンは検討されません。" #. translator: GUC parameter "min_wal_size" short description -#: ../include/utils/guc_tables.inc.c:4171 utils/guc_tables.inc.c:4171 +#: ../include/utils/guc_tables.inc.c:4189 utils/guc_tables.inc.c:4189 msgid "Sets the minimum size to shrink the WAL to." msgstr "WALを縮小させる際の最小のサイズを設定。" #. translator: GUC parameter "multixact_member_buffers" short description -#: ../include/utils/guc_tables.inc.c:4187 utils/guc_tables.inc.c:4187 +#: ../include/utils/guc_tables.inc.c:4205 utils/guc_tables.inc.c:4205 msgid "Sets the size of the dedicated buffer pool used for the MultiXact member cache." msgstr "マルチトランザクションメンバーのキャッシュで専有するバッファプールのサイズを設定する。" #. translator: GUC parameter "multixact_offset_buffers" short description -#: ../include/utils/guc_tables.inc.c:4204 utils/guc_tables.inc.c:4204 +#: ../include/utils/guc_tables.inc.c:4222 utils/guc_tables.inc.c:4222 msgid "Sets the size of the dedicated buffer pool used for the MultiXact offset cache." msgstr "マルチトランザクションオフセットのキャッシュで専有するバッファプールのサイズを設定する。" #. translator: GUC parameter "notify_buffers" short description -#: ../include/utils/guc_tables.inc.c:4221 utils/guc_tables.inc.c:4221 +#: ../include/utils/guc_tables.inc.c:4239 utils/guc_tables.inc.c:4239 msgid "Sets the size of the dedicated buffer pool used for the LISTEN/NOTIFY message cache." msgstr "LISTEN/NOTIFYのメッセージキャッシュで専有するバッファプールのサイズを設定する。" #. translator: GUC parameter "num_os_semaphores" short description -#: ../include/utils/guc_tables.inc.c:4238 utils/guc_tables.inc.c:4238 +#: ../include/utils/guc_tables.inc.c:4256 utils/guc_tables.inc.c:4256 msgid "Shows the number of semaphores required for the server." msgstr "サーバーで必要となるセマフォの数を表示します。" #. translator: GUC parameter "oauth_validator_libraries" short description -#: ../include/utils/guc_tables.inc.c:4254 utils/guc_tables.inc.c:4254 +#: ../include/utils/guc_tables.inc.c:4272 utils/guc_tables.inc.c:4272 msgid "Lists libraries that may be called to validate OAuth v2 bearer tokens." msgstr "OAuth v2 の Bearer トークンを検証するために使用できるライブラリの一覧。" #. translator: GUC parameter "optimize_bounded_sort" short description -#: ../include/utils/guc_tables.inc.c:4269 utils/guc_tables.inc.c:4269 +#: ../include/utils/guc_tables.inc.c:4287 utils/guc_tables.inc.c:4287 msgid "Enables bounded sorting using heap sort." msgstr "ヒープソートを使用した有界ソート処理を有効にします。" #. translator: GUC parameter "parallel_leader_participation" short description -#: ../include/utils/guc_tables.inc.c:4284 utils/guc_tables.inc.c:4284 +#: ../include/utils/guc_tables.inc.c:4302 utils/guc_tables.inc.c:4302 msgid "Controls whether Gather and Gather Merge also run subplans." msgstr "Gather および Gather Merge でも下位プランを実行するかどうかを制御します。" #. translator: GUC parameter "parallel_leader_participation" long description -#: ../include/utils/guc_tables.inc.c:4286 utils/guc_tables.inc.c:4286 +#: ../include/utils/guc_tables.inc.c:4304 utils/guc_tables.inc.c:4304 msgid "Should gather nodes also run subplans or just gather tuples?" msgstr "Gather ノードでも下位プランを実行するのか、もしくはただタプルの収集のみを行うのか?" #. translator: GUC parameter "parallel_setup_cost" short description -#: ../include/utils/guc_tables.inc.c:4300 utils/guc_tables.inc.c:4300 +#: ../include/utils/guc_tables.inc.c:4318 utils/guc_tables.inc.c:4318 msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." msgstr "並列問い合わせ実行のためのワーカープロセスの起動についてプランナで使用する見積もりコストを設定。" #. translator: GUC parameter "parallel_tuple_cost" short description -#: ../include/utils/guc_tables.inc.c:4316 utils/guc_tables.inc.c:4316 +#: ../include/utils/guc_tables.inc.c:4334 utils/guc_tables.inc.c:4334 msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to leader backend." msgstr "並列処理ワーカーからリーダーバックエンドへの一つのタプル(行)の受け渡しについてプランナが使用する見積もりコストを設定。" #. translator: GUC parameter "password_encryption" short description -#: ../include/utils/guc_tables.inc.c:4332 utils/guc_tables.inc.c:4332 +#: ../include/utils/guc_tables.inc.c:4350 utils/guc_tables.inc.c:4350 msgid "Chooses the algorithm for encrypting passwords." msgstr "パスワードの暗号化に使用するアルゴリズムを選択する。" #. translator: GUC parameter "password_expiration_warning_threshold" short description -#: ../include/utils/guc_tables.inc.c:4346 utils/guc_tables.inc.c:4346 +#: ../include/utils/guc_tables.inc.c:4364 utils/guc_tables.inc.c:4364 msgid "Threshold for password expiration warnings." msgstr "パスワード警告の閾値。" #. translator: GUC parameter "password_expiration_warning_threshold" long description -#: ../include/utils/guc_tables.inc.c:4348 utils/guc_tables.inc.c:4348 +#: ../include/utils/guc_tables.inc.c:4366 utils/guc_tables.inc.c:4366 msgid "0 means not to emit these warnings." msgstr "0でこれらの警告を出力しなくなります。" #. translator: GUC parameter "plan_cache_mode" short description -#: ../include/utils/guc_tables.inc.c:4364 utils/guc_tables.inc.c:4364 +#: ../include/utils/guc_tables.inc.c:4382 utils/guc_tables.inc.c:4382 msgid "Controls the planner's selection of custom or generic plan." msgstr "プランナでのカスタムプランと汎用プランの選択を制御。" #. translator: GUC parameter "plan_cache_mode" long description -#: ../include/utils/guc_tables.inc.c:4366 utils/guc_tables.inc.c:4366 +#: ../include/utils/guc_tables.inc.c:4384 utils/guc_tables.inc.c:4384 msgid "Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better. This can be set to override the default behavior." msgstr "プリペアド文は個別プランと一般プランを持ち、プランナはよりよいプランの選択を試みます。これを設定することでそのデフォルト動作を変更できます。" #. translator: GUC parameter "port" short description -#: ../include/utils/guc_tables.inc.c:4381 utils/guc_tables.inc.c:4381 +#: ../include/utils/guc_tables.inc.c:4399 utils/guc_tables.inc.c:4399 msgid "Sets the TCP port the server listens on." msgstr "サーバーが接続を監視するTCPポートを設定。" #. translator: GUC parameter "post_auth_delay" short description -#: ../include/utils/guc_tables.inc.c:4396 utils/guc_tables.inc.c:4396 +#: ../include/utils/guc_tables.inc.c:4414 utils/guc_tables.inc.c:4414 msgid "Sets the amount of time to wait after authentication on connection startup." msgstr "接続開始時の認証後の待ち時間を設定します。" @@ -2634,909 +2644,909 @@ msgstr "接続開始時の認証後の待ち時間を設定します。" #. translator: GUC parameter "pre_auth_delay" long description #. translator: GUC parameter "post_auth_delay" long description #. translator: GUC parameter "pre_auth_delay" long description -#: ../include/utils/guc_tables.inc.c:4398 ../include/utils/guc_tables.inc.c:4416 utils/guc_tables.inc.c:4398 utils/guc_tables.inc.c:4416 +#: ../include/utils/guc_tables.inc.c:4416 ../include/utils/guc_tables.inc.c:4434 utils/guc_tables.inc.c:4416 utils/guc_tables.inc.c:4434 msgid "This allows attaching a debugger to the process." msgstr "これによりデバッガがプロセスに接続できます。" #. translator: GUC parameter "pre_auth_delay" short description -#: ../include/utils/guc_tables.inc.c:4414 utils/guc_tables.inc.c:4414 +#: ../include/utils/guc_tables.inc.c:4432 utils/guc_tables.inc.c:4432 msgid "Sets the amount of time to wait before authentication on connection startup." msgstr "接続開始時の認証前の待ち時間を設定します。" #. translator: GUC parameter "primary_conninfo" short description -#: ../include/utils/guc_tables.inc.c:4432 utils/guc_tables.inc.c:4432 +#: ../include/utils/guc_tables.inc.c:4450 utils/guc_tables.inc.c:4450 msgid "Sets the connection string to be used to connect to the sending server." msgstr "送出側サーバーへの接続に使用する接続文字列をしています。" #. translator: GUC parameter "primary_slot_name" short description -#: ../include/utils/guc_tables.inc.c:4446 utils/guc_tables.inc.c:4446 +#: ../include/utils/guc_tables.inc.c:4464 utils/guc_tables.inc.c:4464 msgid "Sets the name of the replication slot to use on the sending server." msgstr "送出サーバーで使用するレプリケーションスロットの名前を設定。" #. translator: GUC parameter "quote_all_identifiers" short description -#: ../include/utils/guc_tables.inc.c:4460 utils/guc_tables.inc.c:4460 +#: ../include/utils/guc_tables.inc.c:4478 utils/guc_tables.inc.c:4478 msgid "When generating SQL fragments, quote all identifiers." msgstr "SQL文を生成する時に、すべての識別子を引用符で囲みます。" #. translator: GUC parameter "random_page_cost" short description -#: ../include/utils/guc_tables.inc.c:4473 utils/guc_tables.inc.c:4473 +#: ../include/utils/guc_tables.inc.c:4491 utils/guc_tables.inc.c:4491 msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." msgstr "ひと続きでは読み込めないディスクページについてプランナで使用する見積もりコストを設定。" # hoge #. translator: GUC parameter "recovery_end_command" short description -#: ../include/utils/guc_tables.inc.c:4489 utils/guc_tables.inc.c:4489 +#: ../include/utils/guc_tables.inc.c:4507 utils/guc_tables.inc.c:4507 msgid "Sets the shell command that will be executed once at the end of recovery." msgstr "リカバリ終了時に1度だけ実行されるシェルコマンドを設定。" #. translator: GUC parameter "recovery_init_sync_method" short description -#: ../include/utils/guc_tables.inc.c:4502 utils/guc_tables.inc.c:4502 +#: ../include/utils/guc_tables.inc.c:4520 utils/guc_tables.inc.c:4520 msgid "Sets the method for synchronizing the data directory before crash recovery." msgstr "クラシュリカバリ前に行うデータディレクトリの同期の方法を設定する。" #. translator: GUC parameter "recovery_min_apply_delay" short description -#: ../include/utils/guc_tables.inc.c:4516 utils/guc_tables.inc.c:4516 +#: ../include/utils/guc_tables.inc.c:4534 utils/guc_tables.inc.c:4534 msgid "Sets the minimum delay for applying changes during recovery." msgstr "リカバリ中の変更の適用の最小遅延時間を設定します。" #. translator: GUC parameter "recovery_prefetch" short description -#: ../include/utils/guc_tables.inc.c:4532 utils/guc_tables.inc.c:4532 +#: ../include/utils/guc_tables.inc.c:4550 utils/guc_tables.inc.c:4550 msgid "Prefetch referenced blocks during recovery." msgstr "リカバリ中に被参照ブロックの事前読み込みを行う。" #. translator: GUC parameter "recovery_prefetch" long description -#: ../include/utils/guc_tables.inc.c:4534 utils/guc_tables.inc.c:4534 +#: ../include/utils/guc_tables.inc.c:4552 utils/guc_tables.inc.c:4552 msgid "Look ahead in the WAL to find references to uncached data." msgstr "キャッシュされていないデータへの参照の検出のためにWALの先読みを行う。" #. translator: GUC parameter "recovery_target" short description -#: ../include/utils/guc_tables.inc.c:4550 utils/guc_tables.inc.c:4550 +#: ../include/utils/guc_tables.inc.c:4568 utils/guc_tables.inc.c:4568 msgid "Set to \"immediate\" to end recovery as soon as a consistent state is reached." msgstr "\"immediate\"を指定すると一貫性が確保できた時点でリカバリを終了します。" #. translator: GUC parameter "recovery_target_action" short description -#: ../include/utils/guc_tables.inc.c:4565 utils/guc_tables.inc.c:4565 +#: ../include/utils/guc_tables.inc.c:4583 utils/guc_tables.inc.c:4583 msgid "Sets the action to perform upon reaching the recovery target." msgstr "リカバリ目標に到達した際の動作を設定。" #. translator: GUC parameter "recovery_target_inclusive" short description -#: ../include/utils/guc_tables.inc.c:4579 utils/guc_tables.inc.c:4579 +#: ../include/utils/guc_tables.inc.c:4597 utils/guc_tables.inc.c:4597 msgid "Sets whether to include or exclude transaction with recovery target." msgstr "リカバリ目標のトランザクションを含めるか除外するかを設定。" #. translator: GUC parameter "recovery_target_lsn" short description -#: ../include/utils/guc_tables.inc.c:4592 utils/guc_tables.inc.c:4592 +#: ../include/utils/guc_tables.inc.c:4610 utils/guc_tables.inc.c:4610 msgid "Sets the LSN of the write-ahead log location up to which recovery will proceed." msgstr "リカバリを先行書き込みログの指定したLSNまで進めます。" #. translator: GUC parameter "recovery_target_name" short description -#: ../include/utils/guc_tables.inc.c:4607 utils/guc_tables.inc.c:4607 +#: ../include/utils/guc_tables.inc.c:4625 utils/guc_tables.inc.c:4625 msgid "Sets the named restore point up to which recovery will proceed." msgstr "リカバリを指定した名前のリストアポイントまで進めます。" #. translator: GUC parameter "recovery_target_time" short description -#: ../include/utils/guc_tables.inc.c:4622 utils/guc_tables.inc.c:4622 +#: ../include/utils/guc_tables.inc.c:4640 utils/guc_tables.inc.c:4640 msgid "Sets the time stamp up to which recovery will proceed." msgstr "リカバリを指定したタイムスタンプの時刻まで進めます。" #. translator: GUC parameter "recovery_target_timeline" short description -#: ../include/utils/guc_tables.inc.c:4637 utils/guc_tables.inc.c:4637 +#: ../include/utils/guc_tables.inc.c:4655 utils/guc_tables.inc.c:4655 msgid "Specifies the timeline to recover into." msgstr "リカバリの目標タイムラインを指定します。" #. translator: GUC parameter "recovery_target_xid" short description -#: ../include/utils/guc_tables.inc.c:4652 utils/guc_tables.inc.c:4652 +#: ../include/utils/guc_tables.inc.c:4670 utils/guc_tables.inc.c:4670 msgid "Sets the transaction ID up to which recovery will proceed." msgstr "リカバリを指定したトランザクションIDまで進めます。" #. translator: GUC parameter "recursive_worktable_factor" short description -#: ../include/utils/guc_tables.inc.c:4667 utils/guc_tables.inc.c:4667 +#: ../include/utils/guc_tables.inc.c:4685 utils/guc_tables.inc.c:4685 msgid "Sets the planner's estimate of the average size of a recursive query's working table." msgstr "再帰問い合わせでプランナが使用する中間テーブルの平均見積もりサイズを設定します。" #. translator: GUC parameter "remove_temp_files_after_crash" short description -#: ../include/utils/guc_tables.inc.c:4683 utils/guc_tables.inc.c:4683 +#: ../include/utils/guc_tables.inc.c:4701 utils/guc_tables.inc.c:4701 msgid "Remove temporary files after backend crash." msgstr "バックエンドのクラッシュ後に一時ファイルを削除します。" #. translator: GUC parameter "reserved_connections" short description -#: ../include/utils/guc_tables.inc.c:4697 utils/guc_tables.inc.c:4697 +#: ../include/utils/guc_tables.inc.c:4715 utils/guc_tables.inc.c:4715 msgid "Sets the number of connection slots reserved for roles with privileges of pg_use_reserved_connections." msgstr "pg_use_reserved_connections権限を持つロールのために予約する接続スロットの数を設定。" #. translator: GUC parameter "restart_after_crash" short description -#: ../include/utils/guc_tables.inc.c:4712 utils/guc_tables.inc.c:4712 +#: ../include/utils/guc_tables.inc.c:4730 utils/guc_tables.inc.c:4730 msgid "Reinitialize server after backend crash." msgstr "バックエンドがクラッシュした後サーバーを再初期化します" # hoge #. translator: GUC parameter "restore_command" short description -#: ../include/utils/guc_tables.inc.c:4725 utils/guc_tables.inc.c:4725 +#: ../include/utils/guc_tables.inc.c:4743 utils/guc_tables.inc.c:4743 msgid "Sets the shell command that will be called to retrieve an archived WAL file." msgstr "アーカイブされたWALファイルを取り出すために呼び出すシェルコマンドを設定します。" #. translator: GUC parameter "restrict_nonsystem_relation_kind" short description -#: ../include/utils/guc_tables.inc.c:4738 utils/guc_tables.inc.c:4738 +#: ../include/utils/guc_tables.inc.c:4756 utils/guc_tables.inc.c:4756 msgid "Prohibits access to non-system relations of specified kinds." msgstr "指定した種別の非システムリレーションへのアクセスを禁止します。" #. translator: GUC parameter "role" short description -#: ../include/utils/guc_tables.inc.c:4754 utils/guc_tables.inc.c:4754 +#: ../include/utils/guc_tables.inc.c:4772 utils/guc_tables.inc.c:4772 msgid "Sets the current role." msgstr "現在のロールを設定。" #. translator: GUC parameter "row_security" short description -#: ../include/utils/guc_tables.inc.c:4771 utils/guc_tables.inc.c:4771 +#: ../include/utils/guc_tables.inc.c:4789 utils/guc_tables.inc.c:4789 msgid "Enables row security." msgstr "行セキュリティを有効にします。" #. translator: GUC parameter "row_security" long description -#: ../include/utils/guc_tables.inc.c:4773 utils/guc_tables.inc.c:4773 +#: ../include/utils/guc_tables.inc.c:4791 utils/guc_tables.inc.c:4791 msgid "When enabled, row security will be applied to all users." msgstr "有効にすると、行セキュリティが全てのユーザーに適用されます。" #. translator: GUC parameter "scram_iterations" short description -#: ../include/utils/guc_tables.inc.c:4786 utils/guc_tables.inc.c:4786 +#: ../include/utils/guc_tables.inc.c:4804 utils/guc_tables.inc.c:4804 msgid "Sets the iteration count for SCRAM secret generation." msgstr "SCRAMシークレット生成の際の反復回数を設定。" #. translator: GUC parameter "search_path" short description -#: ../include/utils/guc_tables.inc.c:4802 utils/guc_tables.inc.c:4802 +#: ../include/utils/guc_tables.inc.c:4820 utils/guc_tables.inc.c:4820 msgid "Sets the schema search order for names that are not schema-qualified." msgstr "スキーマ部を含まない名前に対するスキーマの検索順を設定。" #. translator: GUC parameter "seed" short description -#: ../include/utils/guc_tables.inc.c:4818 utils/guc_tables.inc.c:4818 +#: ../include/utils/guc_tables.inc.c:4836 utils/guc_tables.inc.c:4836 msgid "Sets the seed for random-number generation." msgstr "乱数生成用のシードを設定。" #. translator: GUC parameter "segment_size" short description -#: ../include/utils/guc_tables.inc.c:4837 utils/guc_tables.inc.c:4837 +#: ../include/utils/guc_tables.inc.c:4855 utils/guc_tables.inc.c:4855 msgid "Shows the number of pages per disk file." msgstr "ディスクファイルごとのページ数を表示します。" #. translator: GUC parameter "send_abort_for_crash" short description -#: ../include/utils/guc_tables.inc.c:4853 utils/guc_tables.inc.c:4853 +#: ../include/utils/guc_tables.inc.c:4871 utils/guc_tables.inc.c:4871 msgid "Send SIGABRT not SIGQUIT to child processes after backend crash." msgstr "バックエンドのクラッシュ後にSIGQUITではなくSIGABRTを子プロセスに送信します。" #. translator: GUC parameter "send_abort_for_kill" short description -#: ../include/utils/guc_tables.inc.c:4867 utils/guc_tables.inc.c:4867 +#: ../include/utils/guc_tables.inc.c:4885 utils/guc_tables.inc.c:4885 msgid "Send SIGABRT not SIGKILL to stuck child processes." msgstr "固まっているプロセスにSIGKILLではなくSIGABRTを送信します。" #. translator: GUC parameter "seq_page_cost" short description -#: ../include/utils/guc_tables.inc.c:4881 utils/guc_tables.inc.c:4881 +#: ../include/utils/guc_tables.inc.c:4899 utils/guc_tables.inc.c:4899 msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." msgstr "ひと続きに読み込むディスクページについてプランナで使用する見積もりコストを設定。" #. translator: GUC parameter "serializable_buffers" short description -#: ../include/utils/guc_tables.inc.c:4897 utils/guc_tables.inc.c:4897 +#: ../include/utils/guc_tables.inc.c:4915 utils/guc_tables.inc.c:4915 msgid "Sets the size of the dedicated buffer pool used for the serializable transaction cache." msgstr "直列化可能トランザクションのキャッシュで専有するバッファプールのサイズを設定する。" #. translator: GUC parameter "server_encoding" short description -#: ../include/utils/guc_tables.inc.c:4914 utils/guc_tables.inc.c:4914 +#: ../include/utils/guc_tables.inc.c:4932 utils/guc_tables.inc.c:4932 msgid "Shows the server (database) character set encoding." msgstr "サーバー(データベース)文字セット符号化方式を表示します。" #. translator: GUC parameter "server_version" short description -#: ../include/utils/guc_tables.inc.c:4928 utils/guc_tables.inc.c:4928 +#: ../include/utils/guc_tables.inc.c:4946 utils/guc_tables.inc.c:4946 msgid "Shows the server version." msgstr "サーバーのバージョンを表示します。" #. translator: GUC parameter "server_version_num" short description -#: ../include/utils/guc_tables.inc.c:4942 utils/guc_tables.inc.c:4942 +#: ../include/utils/guc_tables.inc.c:4960 utils/guc_tables.inc.c:4960 msgid "Shows the server version as an integer." msgstr "サーバーのバージョンを整数値で表示します。" #. translator: GUC parameter "session_authorization" short description -#: ../include/utils/guc_tables.inc.c:4958 utils/guc_tables.inc.c:4958 +#: ../include/utils/guc_tables.inc.c:4976 utils/guc_tables.inc.c:4976 msgid "Sets the session user name." msgstr "セッションユーザー名を設定。" #. translator: GUC parameter "session_preload_libraries" short description -#: ../include/utils/guc_tables.inc.c:4974 utils/guc_tables.inc.c:4974 +#: ../include/utils/guc_tables.inc.c:4992 utils/guc_tables.inc.c:4992 msgid "Lists shared libraries to preload into each backend." msgstr "各バックエンドに事前ロードする共有ライブラリを列挙します。" #. translator: GUC parameter "session_replication_role" short description -#: ../include/utils/guc_tables.inc.c:4988 utils/guc_tables.inc.c:4988 +#: ../include/utils/guc_tables.inc.c:5006 utils/guc_tables.inc.c:5006 msgid "Sets the session's behavior for triggers and rewrite rules." msgstr "トリガーと書き換えルールに関するセッションの動作を設定。" #. translator: GUC parameter "shared_buffers" short description -#: ../include/utils/guc_tables.inc.c:5003 utils/guc_tables.inc.c:5003 +#: ../include/utils/guc_tables.inc.c:5021 utils/guc_tables.inc.c:5021 msgid "Sets the number of shared memory buffers used by the server." msgstr "サーバーで使用される共有メモリのバッファ数を設定。" #. translator: GUC parameter "shared_memory_size" short description -#: ../include/utils/guc_tables.inc.c:5019 utils/guc_tables.inc.c:5019 +#: ../include/utils/guc_tables.inc.c:5037 utils/guc_tables.inc.c:5037 msgid "Shows the size of the server's main shared memory area (rounded up to the nearest MB)." msgstr "サーバーの主共有メモリ領域のサイズを表示します(MB単位に切り上げられます)" #. translator: GUC parameter "shared_memory_size_in_huge_pages" short description -#: ../include/utils/guc_tables.inc.c:5035 utils/guc_tables.inc.c:5035 +#: ../include/utils/guc_tables.inc.c:5053 utils/guc_tables.inc.c:5053 msgid "Shows the number of huge pages needed for the main shared memory area." msgstr "主共有メモリ領域に必要となるヒュージページの数を表示します。" #. translator: GUC parameter "shared_memory_size_in_huge_pages" long description -#: ../include/utils/guc_tables.inc.c:5037 utils/guc_tables.inc.c:5037 +#: ../include/utils/guc_tables.inc.c:5055 utils/guc_tables.inc.c:5055 msgid "-1 means huge pages are not supported." msgstr "-1はヒュージページがサポートされていないことを示します。" #. translator: GUC parameter "shared_memory_type" short description -#: ../include/utils/guc_tables.inc.c:5053 utils/guc_tables.inc.c:5053 +#: ../include/utils/guc_tables.inc.c:5071 utils/guc_tables.inc.c:5071 msgid "Selects the shared memory implementation used for the main shared memory region." msgstr "主共有メモリ領域に使用する共有メモリ実装を選択します。" #. translator: GUC parameter "shared_preload_libraries" short description -#: ../include/utils/guc_tables.inc.c:5067 utils/guc_tables.inc.c:5067 +#: ../include/utils/guc_tables.inc.c:5085 utils/guc_tables.inc.c:5085 msgid "Lists shared libraries to preload into server." msgstr "サーバーに事前ロードする共有ライブラリを列挙します。" #. translator: GUC parameter "ssl" short description -#: ../include/utils/guc_tables.inc.c:5081 utils/guc_tables.inc.c:5081 +#: ../include/utils/guc_tables.inc.c:5099 utils/guc_tables.inc.c:5099 msgid "Enables SSL connections." msgstr "SSL接続を有効にします。" #. translator: GUC parameter "ssl_ca_file" short description -#: ../include/utils/guc_tables.inc.c:5095 utils/guc_tables.inc.c:5095 +#: ../include/utils/guc_tables.inc.c:5113 utils/guc_tables.inc.c:5113 msgid "Location of the SSL certificate authority file." msgstr "SSL認証局ファイルの場所です" #. translator: GUC parameter "ssl_cert_file" short description -#: ../include/utils/guc_tables.inc.c:5108 utils/guc_tables.inc.c:5108 +#: ../include/utils/guc_tables.inc.c:5126 utils/guc_tables.inc.c:5126 msgid "Location of the SSL server certificate file." msgstr "SSLサーバー証明書ファイルの場所です" #. translator: GUC parameter "ssl_ciphers" short description -#: ../include/utils/guc_tables.inc.c:5121 utils/guc_tables.inc.c:5121 +#: ../include/utils/guc_tables.inc.c:5139 utils/guc_tables.inc.c:5139 msgid "Sets the list of allowed TLSv1.2 (and lower) ciphers." msgstr "使用可能なTLSv1.2(およびそれ以前)の暗号方式のリストを設定。" #. translator: GUC parameter "ssl_crl_dir" short description -#: ../include/utils/guc_tables.inc.c:5135 utils/guc_tables.inc.c:5135 +#: ../include/utils/guc_tables.inc.c:5153 utils/guc_tables.inc.c:5153 msgid "Location of the SSL certificate revocation list directory." msgstr "SSL証明書失効リストディレクトリの場所です。" #. translator: GUC parameter "ssl_crl_file" short description -#: ../include/utils/guc_tables.inc.c:5148 utils/guc_tables.inc.c:5148 +#: ../include/utils/guc_tables.inc.c:5166 utils/guc_tables.inc.c:5166 msgid "Location of the SSL certificate revocation list file." msgstr "SSL証明書失効リストファイルの場所です。" #. translator: GUC parameter "ssl_dh_params_file" short description -#: ../include/utils/guc_tables.inc.c:5161 utils/guc_tables.inc.c:5161 +#: ../include/utils/guc_tables.inc.c:5179 utils/guc_tables.inc.c:5179 msgid "Location of the SSL DH parameters file." msgstr "SSLのDHパラメータファイルの場所です。" #. translator: GUC parameter "ssl_dh_params_file" long description -#: ../include/utils/guc_tables.inc.c:5163 utils/guc_tables.inc.c:5163 +#: ../include/utils/guc_tables.inc.c:5181 utils/guc_tables.inc.c:5181 msgid "An empty string means use compiled-in default parameters." msgstr "空文字列でコンパイル時設定のデフォルトのパラメーターを使用します。" #. translator: GUC parameter "ssl_groups" short description -#: ../include/utils/guc_tables.inc.c:5177 utils/guc_tables.inc.c:5177 +#: ../include/utils/guc_tables.inc.c:5195 utils/guc_tables.inc.c:5195 msgid "Sets the group(s) to use for Diffie-Hellman key exchange." msgstr "Diffie-Hellman鍵交換で使用するグループ(群)を設定。" #. translator: GUC parameter "ssl_groups" long description -#: ../include/utils/guc_tables.inc.c:5179 utils/guc_tables.inc.c:5179 +#: ../include/utils/guc_tables.inc.c:5197 utils/guc_tables.inc.c:5197 msgid "Multiple groups can be specified using a colon-separated list." msgstr "複数のグループはコロン区切りのリストとして指定できます。" #. translator: GUC parameter "ssl_key_file" short description -#: ../include/utils/guc_tables.inc.c:5193 utils/guc_tables.inc.c:5193 +#: ../include/utils/guc_tables.inc.c:5211 utils/guc_tables.inc.c:5211 msgid "Location of the SSL server private key file." msgstr "SSLサーバー秘密鍵ファイルの場所です。" #. translator: GUC parameter "ssl_library" short description -#: ../include/utils/guc_tables.inc.c:5206 utils/guc_tables.inc.c:5206 +#: ../include/utils/guc_tables.inc.c:5224 utils/guc_tables.inc.c:5224 msgid "Shows the name of the SSL library." msgstr "SSLライブラリの名前を表示します。" #. translator: GUC parameter "ssl_max_protocol_version" short description -#: ../include/utils/guc_tables.inc.c:5220 utils/guc_tables.inc.c:5220 +#: ../include/utils/guc_tables.inc.c:5238 utils/guc_tables.inc.c:5238 msgid "Sets the maximum SSL/TLS protocol version to use." msgstr "使用可能な最大の SSL/TLS プロトコルバージョンを指定します。" #. translator: GUC parameter "ssl_min_protocol_version" short description -#: ../include/utils/guc_tables.inc.c:5235 utils/guc_tables.inc.c:5235 +#: ../include/utils/guc_tables.inc.c:5253 utils/guc_tables.inc.c:5253 msgid "Sets the minimum SSL/TLS protocol version to use." msgstr "使用する SSL/TLSプロトコルの最小バージョンを設定。" #. translator: GUC parameter "ssl_passphrase_command" short description -#: ../include/utils/guc_tables.inc.c:5250 utils/guc_tables.inc.c:5250 +#: ../include/utils/guc_tables.inc.c:5268 utils/guc_tables.inc.c:5268 msgid "Command to obtain passphrases for SSL." msgstr "SSLのパスフレーズを取得するコマンド。" #. translator: GUC parameter "ssl_passphrase_command" long description -#: ../include/utils/guc_tables.inc.c:5252 utils/guc_tables.inc.c:5252 +#: ../include/utils/guc_tables.inc.c:5270 utils/guc_tables.inc.c:5270 msgid "An empty string means use the built-in prompting mechanism." msgstr "空文字列で内蔵のパスワード入力機構を使用します。" #. translator: GUC parameter "ssl_passphrase_command_supports_reload" short description -#: ../include/utils/guc_tables.inc.c:5266 utils/guc_tables.inc.c:5266 +#: ../include/utils/guc_tables.inc.c:5284 utils/guc_tables.inc.c:5284 msgid "Controls whether \"ssl_passphrase_command\" is called during server reload." msgstr "サーバーリロード時に\"ssl_passphrase_command\"を呼び出すかどうかを制御します。" #. translator: GUC parameter "ssl_prefer_server_ciphers" short description -#: ../include/utils/guc_tables.inc.c:5279 utils/guc_tables.inc.c:5279 +#: ../include/utils/guc_tables.inc.c:5297 utils/guc_tables.inc.c:5297 msgid "Give priority to server ciphersuite order." msgstr "サーバー側の暗号スイート順序を優先します。" #. translator: GUC parameter "ssl_renegotiation_limit" short description -#: ../include/utils/guc_tables.inc.c:5292 utils/guc_tables.inc.c:5292 +#: ../include/utils/guc_tables.inc.c:5310 utils/guc_tables.inc.c:5310 msgid "SSL renegotiation is no longer supported; this can only be 0." msgstr "SSLの再ネゴシエーションはすでにサポートされていません; 0のみに設定可能です。" #. translator: GUC parameter "ssl_sni" short description -#: ../include/utils/guc_tables.inc.c:5308 utils/guc_tables.inc.c:5308 +#: ../include/utils/guc_tables.inc.c:5326 utils/guc_tables.inc.c:5326 msgid "Sets whether to interpret SNI extensions in SSL connections." msgstr "SSL接続でSNI拡張を解釈するかどうかを設定。" #. translator: GUC parameter "ssl_tls13_ciphers" short description -#: ../include/utils/guc_tables.inc.c:5323 utils/guc_tables.inc.c:5323 +#: ../include/utils/guc_tables.inc.c:5341 utils/guc_tables.inc.c:5341 msgid "Sets the list of allowed TLSv1.3 cipher suites." msgstr "使用を許可するTLSv1.3の暗号スイートのリストを設定。" #. translator: GUC parameter "ssl_tls13_ciphers" long description -#: ../include/utils/guc_tables.inc.c:5325 utils/guc_tables.inc.c:5325 +#: ../include/utils/guc_tables.inc.c:5343 utils/guc_tables.inc.c:5343 msgid "An empty string means use the default cipher suites." msgstr "空文字列でデフォルトの暗号スイートを使用します。" #. translator: GUC parameter "standard_conforming_strings" short description -#: ../include/utils/guc_tables.inc.c:5339 utils/guc_tables.inc.c:5339 +#: ../include/utils/guc_tables.inc.c:5357 utils/guc_tables.inc.c:5357 msgid "Nonstandard strings are no longer supported; this can only be true." msgstr "非標準文字列はすでにサポートされていません。 true にしか設定できません。" #. translator: GUC parameter "statement_timeout" short description -#: ../include/utils/guc_tables.inc.c:5354 utils/guc_tables.inc.c:5354 +#: ../include/utils/guc_tables.inc.c:5372 utils/guc_tables.inc.c:5372 msgid "Sets the maximum allowed duration of any statement." msgstr "あらゆる文に対して実行時間として許容する上限値を設定。" #. translator: GUC parameter "stats_fetch_consistency" short description -#: ../include/utils/guc_tables.inc.c:5372 utils/guc_tables.inc.c:5372 +#: ../include/utils/guc_tables.inc.c:5390 utils/guc_tables.inc.c:5390 msgid "Sets the consistency of accesses to statistics data." msgstr "統計情報読み出し時の一貫性レベルを設定します。" #. translator: GUC parameter "subtransaction_buffers" short description -#: ../include/utils/guc_tables.inc.c:5387 utils/guc_tables.inc.c:5387 +#: ../include/utils/guc_tables.inc.c:5405 utils/guc_tables.inc.c:5405 msgid "Sets the size of the dedicated buffer pool used for the subtransaction cache." msgstr "サブトランザクションキャッシュ専用のバッファプールのサイズを設定する。" #. translator: GUC parameter "summarize_wal" short description -#: ../include/utils/guc_tables.inc.c:5406 utils/guc_tables.inc.c:5406 +#: ../include/utils/guc_tables.inc.c:5424 utils/guc_tables.inc.c:5424 msgid "Starts the WAL summarizer process to enable incremental backup." msgstr "差分バックアップを可能にするためのWAL集約プロセスを起動します。" #. translator: GUC parameter "superuser_reserved_connections" short description -#: ../include/utils/guc_tables.inc.c:5419 utils/guc_tables.inc.c:5419 +#: ../include/utils/guc_tables.inc.c:5437 utils/guc_tables.inc.c:5437 msgid "Sets the number of connection slots reserved for superusers." msgstr "スーパーユーザーによる接続用に予約される接続スロットの数を設定。" #. translator: GUC parameter "sync_replication_slots" short description -#: ../include/utils/guc_tables.inc.c:5434 utils/guc_tables.inc.c:5434 +#: ../include/utils/guc_tables.inc.c:5452 utils/guc_tables.inc.c:5452 msgid "Enables a physical standby to synchronize logical failover replication slots from the primary server." msgstr "物理スタンバイがプライマリサーバーから論理フェイルオーバーレプリケーションスロットを同期できるようにする。" #. translator: GUC parameter "synchronize_seqscans" short description -#: ../include/utils/guc_tables.inc.c:5447 utils/guc_tables.inc.c:5447 +#: ../include/utils/guc_tables.inc.c:5465 utils/guc_tables.inc.c:5465 msgid "Enables synchronized sequential scans." msgstr "同期シーケンシャルスキャンを有効にします。" #. translator: GUC parameter "synchronized_standby_slots" short description -#: ../include/utils/guc_tables.inc.c:5460 utils/guc_tables.inc.c:5460 +#: ../include/utils/guc_tables.inc.c:5478 utils/guc_tables.inc.c:5478 msgid "Lists streaming replication standby server replication slot names that logical WAL sender processes will wait for." msgstr "論理WAL senderプロセスが待ち受け対象とするストリーミングレプリケーションのスタンバイサーバーのレプリケーションスロット名を列挙します。" #. translator: GUC parameter "synchronized_standby_slots" long description -#: ../include/utils/guc_tables.inc.c:5462 utils/guc_tables.inc.c:5462 +#: ../include/utils/guc_tables.inc.c:5480 utils/guc_tables.inc.c:5480 msgid "Logical WAL sender processes will send decoded changes to output plugins only after the specified replication slots have confirmed receiving WAL." msgstr "論理WAL senderプロセスは指定されたレプリケーションスロットによるWALの受け取り確認後に初めてデコードされた変更を出力プラグインに送出します。" #. translator: GUC parameter "synchronous_commit" short description -#: ../include/utils/guc_tables.inc.c:5478 utils/guc_tables.inc.c:5478 +#: ../include/utils/guc_tables.inc.c:5496 utils/guc_tables.inc.c:5496 msgid "Sets the current transaction's synchronization level." msgstr "現在のトランザクションの同期レベルを設定。" #. translator: GUC parameter "synchronous_standby_names" short description -#: ../include/utils/guc_tables.inc.c:5493 utils/guc_tables.inc.c:5493 +#: ../include/utils/guc_tables.inc.c:5511 utils/guc_tables.inc.c:5511 msgid "Number of synchronous standbys and list of names of potential synchronous ones." msgstr "同期スタンバイの数と同期スタンバイ候補の名前の一覧。" #. translator: GUC parameter "syslog_facility" short description -#: ../include/utils/guc_tables.inc.c:5509 utils/guc_tables.inc.c:5509 +#: ../include/utils/guc_tables.inc.c:5527 utils/guc_tables.inc.c:5527 msgid "Sets the syslog \"facility\" to be used when syslog enabled." msgstr "syslogを有効にした場合に使用するsyslog \"facility\"を設定。" #. translator: GUC parameter "syslog_ident" short description -#: ../include/utils/guc_tables.inc.c:5524 utils/guc_tables.inc.c:5524 +#: ../include/utils/guc_tables.inc.c:5542 utils/guc_tables.inc.c:5542 msgid "Sets the program name used to identify PostgreSQL messages in syslog." msgstr "syslog内でPostgreSQLのメッセージを識別するために使用されるプログラム名を設定。" #. translator: GUC parameter "syslog_sequence_numbers" short description -#: ../include/utils/guc_tables.inc.c:5538 utils/guc_tables.inc.c:5538 +#: ../include/utils/guc_tables.inc.c:5556 utils/guc_tables.inc.c:5556 msgid "Add sequence number to syslog messages to avoid duplicate suppression." msgstr "シーケンス番号を付加することでsyslogメッセージの重複を防ぎます。" #. translator: GUC parameter "syslog_split_messages" short description -#: ../include/utils/guc_tables.inc.c:5551 utils/guc_tables.inc.c:5551 +#: ../include/utils/guc_tables.inc.c:5569 utils/guc_tables.inc.c:5569 msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." msgstr "syslogに送出するメッセージを行単位で分割して、1024バイトに収まるようにします。" #. translator: GUC parameter "tcp_keepalives_count" short description -#: ../include/utils/guc_tables.inc.c:5564 utils/guc_tables.inc.c:5564 +#: ../include/utils/guc_tables.inc.c:5582 utils/guc_tables.inc.c:5582 msgid "Maximum number of TCP keepalive retransmits." msgstr "TCPキープアライブの再送信回数の最大値です。" #. translator: GUC parameter "tcp_keepalives_count" long description -#: ../include/utils/guc_tables.inc.c:5566 utils/guc_tables.inc.c:5566 +#: ../include/utils/guc_tables.inc.c:5584 utils/guc_tables.inc.c:5584 msgid "Number of consecutive keepalive retransmits that can be lost before a connection is considered dead. 0 means use the system default." msgstr "接続が失われると判断するまでに再送信される、ひとつづきのキープアライブの数。0でシステムのデフォルト値を使用します。" #. translator: GUC parameter "tcp_keepalives_idle" short description -#: ../include/utils/guc_tables.inc.c:5583 utils/guc_tables.inc.c:5583 +#: ../include/utils/guc_tables.inc.c:5601 utils/guc_tables.inc.c:5601 msgid "Time between issuing TCP keepalives." msgstr "TCPキープアライブを発行する時間間隔。" #. translator: GUC parameter "tcp_keepalives_interval" short description -#: ../include/utils/guc_tables.inc.c:5603 utils/guc_tables.inc.c:5603 +#: ../include/utils/guc_tables.inc.c:5621 utils/guc_tables.inc.c:5621 msgid "Time between TCP keepalive retransmits." msgstr "TCPキープアライブの再送信の時間間隔。" #. translator: GUC parameter "tcp_user_timeout" short description -#: ../include/utils/guc_tables.inc.c:5623 utils/guc_tables.inc.c:5623 +#: ../include/utils/guc_tables.inc.c:5641 utils/guc_tables.inc.c:5641 msgid "TCP user timeout." msgstr "TCPユーザータイムアウト。" #. translator: GUC parameter "temp_buffers" short description -#: ../include/utils/guc_tables.inc.c:5643 utils/guc_tables.inc.c:5643 +#: ../include/utils/guc_tables.inc.c:5661 utils/guc_tables.inc.c:5661 msgid "Sets the maximum number of temporary buffers used by each session." msgstr "各セッションで使用される一時バッファの最大数を設定。" #. translator: GUC parameter "temp_file_limit" short description -#: ../include/utils/guc_tables.inc.c:5660 utils/guc_tables.inc.c:5660 +#: ../include/utils/guc_tables.inc.c:5678 utils/guc_tables.inc.c:5678 msgid "Limits the total size of all temporary files used by each process." msgstr "各プロセスで使用される全ての一時ファイルの合計サイズを制限します。" #. translator: GUC parameter "temp_file_limit" long description -#: ../include/utils/guc_tables.inc.c:5662 utils/guc_tables.inc.c:5662 +#: ../include/utils/guc_tables.inc.c:5680 utils/guc_tables.inc.c:5680 msgid "-1 means no limit." msgstr "-1は無制限を意味します。" #. translator: GUC parameter "temp_tablespaces" short description -#: ../include/utils/guc_tables.inc.c:5678 utils/guc_tables.inc.c:5678 +#: ../include/utils/guc_tables.inc.c:5696 utils/guc_tables.inc.c:5696 msgid "Sets the tablespace(s) to use for temporary tables and sort files." msgstr "一時テーブルとファイルのソートで使用されるテーブル空間を設定。" #. translator: GUC parameter "TimeZone" short description -#: ../include/utils/guc_tables.inc.c:5696 utils/guc_tables.inc.c:5696 +#: ../include/utils/guc_tables.inc.c:5714 utils/guc_tables.inc.c:5714 msgid "Sets the time zone for displaying and interpreting time stamps." msgstr "タイムスタンプの表示と解釈に使用するタイムゾーンを設定。" #. translator: GUC parameter "timezone_abbreviations" short description -#: ../include/utils/guc_tables.inc.c:5713 utils/guc_tables.inc.c:5713 +#: ../include/utils/guc_tables.inc.c:5731 utils/guc_tables.inc.c:5731 msgid "Selects a file of time zone abbreviations." msgstr "タイムゾーン省略形用のファイルを選択します。" #. translator: GUC parameter "timing_clock_source" short description -#: ../include/utils/guc_tables.inc.c:5728 utils/guc_tables.inc.c:5728 +#: ../include/utils/guc_tables.inc.c:5746 utils/guc_tables.inc.c:5746 msgid "Controls the clock source used for collecting timing measurements." msgstr "時間計測に使用するクロックソースを設定。" #. translator: GUC parameter "timing_clock_source" long description -#: ../include/utils/guc_tables.inc.c:5730 utils/guc_tables.inc.c:5730 +#: ../include/utils/guc_tables.inc.c:5748 utils/guc_tables.inc.c:5748 msgid "This enables the use of specialized clock sources, specifically the RDTSC clock source on x86-64 systems (if available), to support timing measurements with lower overhead during EXPLAIN and other instrumentation." msgstr "これにより、EXPLAIN やその他の計測処理において、より低オーバーヘッドな時間計測を行うために、専用のクロックソース、具体的には x86-64 システムで(利用可能な場合は) RDTSC クロックソースを使用できます。" #. translator: GUC parameter "trace_connection_negotiation" short description -#: ../include/utils/guc_tables.inc.c:5747 utils/guc_tables.inc.c:5747 +#: ../include/utils/guc_tables.inc.c:5765 utils/guc_tables.inc.c:5765 msgid "Logs details of pre-authentication connection handshake." msgstr "認証前接続ハンドシェークの詳細をログに記録します。" #. translator: GUC parameter "trace_lock_oidmin" short description -#: ../include/utils/guc_tables.inc.c:5762 utils/guc_tables.inc.c:5762 +#: ../include/utils/guc_tables.inc.c:5780 utils/guc_tables.inc.c:5780 msgid "Sets the minimum OID of tables for tracking locks." msgstr "ロックの追跡を行うテーブルの最小のOIDを設定。" #. translator: GUC parameter "trace_lock_oidmin" long description -#: ../include/utils/guc_tables.inc.c:5764 utils/guc_tables.inc.c:5764 +#: ../include/utils/guc_tables.inc.c:5782 utils/guc_tables.inc.c:5782 msgid "Is used to avoid output on system tables." msgstr "システムテーブルに関するの出力を避けるために使います。" #. translator: GUC parameter "trace_lock_table" short description -#: ../include/utils/guc_tables.inc.c:5782 utils/guc_tables.inc.c:5782 +#: ../include/utils/guc_tables.inc.c:5800 utils/guc_tables.inc.c:5800 msgid "Sets the OID of the table with unconditionally lock tracing." msgstr "無条件でロックの追跡を行うテーブルのOIDを設定。" #. translator: GUC parameter "trace_locks" short description -#: ../include/utils/guc_tables.inc.c:5800 utils/guc_tables.inc.c:5800 +#: ../include/utils/guc_tables.inc.c:5818 utils/guc_tables.inc.c:5818 msgid "Emits information about lock usage." msgstr "ロック使用状況に関する情報を出力します。" #. translator: GUC parameter "trace_lwlocks" short description -#: ../include/utils/guc_tables.inc.c:5816 utils/guc_tables.inc.c:5816 +#: ../include/utils/guc_tables.inc.c:5834 utils/guc_tables.inc.c:5834 msgid "Emits information about lightweight lock usage." msgstr "軽量ロックの使用状況に関する情報を出力します。" #. translator: GUC parameter "trace_notify" short description -#: ../include/utils/guc_tables.inc.c:5831 utils/guc_tables.inc.c:5831 +#: ../include/utils/guc_tables.inc.c:5849 utils/guc_tables.inc.c:5849 msgid "Generates debugging output for LISTEN and NOTIFY." msgstr "LISTENとNOTIFYコマンドのためのデバッグ出力を生成します。" #. translator: GUC parameter "trace_sort" short description -#: ../include/utils/guc_tables.inc.c:5845 utils/guc_tables.inc.c:5845 +#: ../include/utils/guc_tables.inc.c:5863 utils/guc_tables.inc.c:5863 msgid "Emit information about resource usage in sorting." msgstr "ソート中にリソース使用状況に関する情報を出力します。" #. translator: GUC parameter "trace_syncscan" short description -#: ../include/utils/guc_tables.inc.c:5860 utils/guc_tables.inc.c:5860 +#: ../include/utils/guc_tables.inc.c:5878 utils/guc_tables.inc.c:5878 msgid "Generate debugging output for synchronized scanning." msgstr "同期スキャン処理のデバッグ出力を生成します。" #. translator: GUC parameter "trace_userlocks" short description -#: ../include/utils/guc_tables.inc.c:5876 utils/guc_tables.inc.c:5876 +#: ../include/utils/guc_tables.inc.c:5894 utils/guc_tables.inc.c:5894 msgid "Emits information about user lock usage." msgstr "ユーザーロックの使用状況に関する情報を出力します。" #. translator: GUC parameter "track_activities" short description -#: ../include/utils/guc_tables.inc.c:5891 utils/guc_tables.inc.c:5891 +#: ../include/utils/guc_tables.inc.c:5909 utils/guc_tables.inc.c:5909 msgid "Collects information about executing commands." msgstr "実行中のコマンドに関する情報を収集します。" #. translator: GUC parameter "track_activities" long description -#: ../include/utils/guc_tables.inc.c:5893 utils/guc_tables.inc.c:5893 +#: ../include/utils/guc_tables.inc.c:5911 utils/guc_tables.inc.c:5911 msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." msgstr "そのコマンドが実行を開始した時刻を伴った、各セッションでの現時点で実行中のコマンドに関する情報の収集を有効にします。" #. translator: GUC parameter "track_activity_query_size" short description -#: ../include/utils/guc_tables.inc.c:5906 utils/guc_tables.inc.c:5906 +#: ../include/utils/guc_tables.inc.c:5924 utils/guc_tables.inc.c:5924 msgid "Sets the size reserved for pg_stat_activity.query, in bytes." msgstr "pg_stat_activity.queryのために予約するサイズをバイト単位で設定。" #. translator: GUC parameter "track_commit_timestamp" short description -#: ../include/utils/guc_tables.inc.c:5922 utils/guc_tables.inc.c:5922 +#: ../include/utils/guc_tables.inc.c:5940 utils/guc_tables.inc.c:5940 msgid "Collects transaction commit time." msgstr "トランザクションのコミット時刻を収集します。" #. translator: GUC parameter "track_cost_delay_timing" short description -#: ../include/utils/guc_tables.inc.c:5935 utils/guc_tables.inc.c:5935 +#: ../include/utils/guc_tables.inc.c:5953 utils/guc_tables.inc.c:5953 msgid "Collects timing statistics for cost-based vacuum delay." msgstr "コストベースのVACUUM遅延に関する時間統計を収集します。" #. translator: GUC parameter "track_counts" short description -#: ../include/utils/guc_tables.inc.c:5948 utils/guc_tables.inc.c:5948 +#: ../include/utils/guc_tables.inc.c:5966 utils/guc_tables.inc.c:5966 msgid "Collects statistics on database activity." msgstr "データベースの活動について統計情報を収集します。" #. translator: GUC parameter "track_functions" short description -#: ../include/utils/guc_tables.inc.c:5961 utils/guc_tables.inc.c:5961 +#: ../include/utils/guc_tables.inc.c:5979 utils/guc_tables.inc.c:5979 msgid "Collects function-level statistics on database activity." msgstr "データベースの動作に関して、関数レベルの統計情報を収集します。" #. translator: GUC parameter "track_io_timing" short description -#: ../include/utils/guc_tables.inc.c:5975 utils/guc_tables.inc.c:5975 +#: ../include/utils/guc_tables.inc.c:5993 utils/guc_tables.inc.c:5993 msgid "Collects timing statistics for database I/O activity." msgstr "データベースのI/O処理時間に関する統計情報を収集します。" #. translator: GUC parameter "track_wal_io_timing" short description -#: ../include/utils/guc_tables.inc.c:5988 utils/guc_tables.inc.c:5988 +#: ../include/utils/guc_tables.inc.c:6006 utils/guc_tables.inc.c:6006 msgid "Collects timing statistics for WAL I/O activity." msgstr "WALのI/O処理時間に関する統計情報を収集します。" #. translator: GUC parameter "transaction_buffers" short description -#: ../include/utils/guc_tables.inc.c:6001 utils/guc_tables.inc.c:6001 +#: ../include/utils/guc_tables.inc.c:6019 utils/guc_tables.inc.c:6019 msgid "Sets the size of the dedicated buffer pool used for the transaction status cache." msgstr "トランザクション状態のキャッシュで専有するバッファプールのサイズを設定する。" #. translator: GUC parameter "transaction_deferrable" short description -#: ../include/utils/guc_tables.inc.c:6020 utils/guc_tables.inc.c:6020 +#: ../include/utils/guc_tables.inc.c:6038 utils/guc_tables.inc.c:6038 msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." msgstr "リードオンリーのシリアライズ可能なトランザクションを、シリアライズに失敗することなく実行できるまで遅延させるかどうか" #. translator: GUC parameter "transaction_isolation" short description -#: ../include/utils/guc_tables.inc.c:6035 utils/guc_tables.inc.c:6035 +#: ../include/utils/guc_tables.inc.c:6053 utils/guc_tables.inc.c:6053 msgid "Sets the current transaction's isolation level." msgstr "現在のトランザクションの分離レベルを設定。" #. translator: GUC parameter "transaction_read_only" short description -#: ../include/utils/guc_tables.inc.c:6051 utils/guc_tables.inc.c:6051 +#: ../include/utils/guc_tables.inc.c:6069 utils/guc_tables.inc.c:6069 msgid "Sets the current transaction's read-only status." msgstr "現在のトランザクションのリードオンリー設定を設定。" #. translator: GUC parameter "transaction_timeout" short description -#: ../include/utils/guc_tables.inc.c:6066 utils/guc_tables.inc.c:6066 +#: ../include/utils/guc_tables.inc.c:6084 utils/guc_tables.inc.c:6084 msgid "Sets the maximum allowed duration of any transaction within a session (not a prepared transaction)." msgstr "(準備済みトランザクションではない)セッション内のトランザクションの最大許容時間を設定。" #. translator: GUC parameter "transform_null_equals" short description -#: ../include/utils/guc_tables.inc.c:6085 utils/guc_tables.inc.c:6085 +#: ../include/utils/guc_tables.inc.c:6103 utils/guc_tables.inc.c:6103 msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." msgstr "\"expr=NULL\"という形の式は\"expr IS NULL\"として扱います。" #. translator: GUC parameter "transform_null_equals" long description -#: ../include/utils/guc_tables.inc.c:6087 utils/guc_tables.inc.c:6087 +#: ../include/utils/guc_tables.inc.c:6105 utils/guc_tables.inc.c:6105 msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." msgstr "有効にした場合、expr = NULL(またはNULL = expr)という形の式はexpr IS NULLとして扱われます。つまり、exprの評価がNULL値の場合に真を、さもなくば偽を返します。expr = NULLのSQL仕様に基づいた正しい動作は常にNULL(未知)を返すことです。" #. translator: GUC parameter "unix_socket_directories" short description -#: ../include/utils/guc_tables.inc.c:6100 utils/guc_tables.inc.c:6100 +#: ../include/utils/guc_tables.inc.c:6118 utils/guc_tables.inc.c:6118 msgid "Sets the directories where Unix-domain sockets will be created." msgstr "Unixドメインソケットの作成先ディレクトリを設定。" #. translator: GUC parameter "unix_socket_group" short description -#: ../include/utils/guc_tables.inc.c:6114 utils/guc_tables.inc.c:6114 +#: ../include/utils/guc_tables.inc.c:6132 utils/guc_tables.inc.c:6132 msgid "Sets the owning group of the Unix-domain socket." msgstr "Unixドメインソケットを所有するグループを設定。" #. translator: GUC parameter "unix_socket_group" long description -#: ../include/utils/guc_tables.inc.c:6116 utils/guc_tables.inc.c:6116 +#: ../include/utils/guc_tables.inc.c:6134 utils/guc_tables.inc.c:6134 msgid "The owning user of the socket is always the user that starts the server. An empty string means use the user's default group." msgstr "ソケットを所有するユーザーは常にサーバーを開始したユーザーです。空文字列でユーザのデフォルトグループを使用します。" #. translator: GUC parameter "unix_socket_permissions" short description -#: ../include/utils/guc_tables.inc.c:6129 utils/guc_tables.inc.c:6129 +#: ../include/utils/guc_tables.inc.c:6147 utils/guc_tables.inc.c:6147 msgid "Sets the access permissions of the Unix-domain socket." msgstr "Unixドメインソケットのアクセス権限を設定。" #. translator: GUC parameter "unix_socket_permissions" long description -#: ../include/utils/guc_tables.inc.c:6131 utils/guc_tables.inc.c:6131 +#: ../include/utils/guc_tables.inc.c:6149 utils/guc_tables.inc.c:6149 msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "Unixドメインソケットは、通常のUnixファイルシステム権限の設定を使います。 このパラメータ値は chmod と umask システムコールが受け付ける数値のモード指定を想定しています(慣習的な8進数書式を使うためには、0(ゼロ)で始めなくてはなりません)。 " #. translator: GUC parameter "update_process_title" short description -#: ../include/utils/guc_tables.inc.c:6147 utils/guc_tables.inc.c:6147 +#: ../include/utils/guc_tables.inc.c:6165 utils/guc_tables.inc.c:6165 msgid "Updates the process title to show the active SQL command." msgstr "活動中のSQLコマンドを表示するようプロセスタイトルを更新します。" #. translator: GUC parameter "update_process_title" long description -#: ../include/utils/guc_tables.inc.c:6149 utils/guc_tables.inc.c:6149 +#: ../include/utils/guc_tables.inc.c:6167 utils/guc_tables.inc.c:6167 msgid "Enables updating of the process title every time a new SQL command is received by the server." msgstr "新しいSQLコマンドをサーバーが受信する度に行うプロセスタイトルの更新を有効にします。" #. translator: GUC parameter "vacuum_buffer_usage_limit" short description -#: ../include/utils/guc_tables.inc.c:6162 utils/guc_tables.inc.c:6162 +#: ../include/utils/guc_tables.inc.c:6180 utils/guc_tables.inc.c:6180 msgid "Sets the buffer pool size for VACUUM, ANALYZE, and autovacuum." msgstr "VACUUM, ANALYZE, および自動VACUUMで使用するバッファプールのサイズを設定します。" #. translator: GUC parameter "vacuum_cost_delay" short description -#: ../include/utils/guc_tables.inc.c:6179 utils/guc_tables.inc.c:6179 +#: ../include/utils/guc_tables.inc.c:6197 utils/guc_tables.inc.c:6197 msgid "Vacuum cost delay in milliseconds." msgstr "ミリ秒単位のコストベースのVACUUM処理の遅延時間です。" #. translator: GUC parameter "vacuum_cost_limit" short description -#: ../include/utils/guc_tables.inc.c:6195 utils/guc_tables.inc.c:6195 +#: ../include/utils/guc_tables.inc.c:6213 utils/guc_tables.inc.c:6213 msgid "Vacuum cost amount available before napping." msgstr "VACUUM処理を一時休止させるまでに使用できるコスト。" #. translator: GUC parameter "vacuum_cost_page_dirty" short description -#: ../include/utils/guc_tables.inc.c:6210 utils/guc_tables.inc.c:6210 +#: ../include/utils/guc_tables.inc.c:6228 utils/guc_tables.inc.c:6228 msgid "Vacuum cost for a page dirtied by vacuum." msgstr "VACUUM処理が1つのページをダーティにした際に課すコスト。" #. translator: GUC parameter "vacuum_cost_page_hit" short description -#: ../include/utils/guc_tables.inc.c:6225 utils/guc_tables.inc.c:6225 +#: ../include/utils/guc_tables.inc.c:6243 utils/guc_tables.inc.c:6243 msgid "Vacuum cost for a page found in the buffer cache." msgstr "バッファキャッシュにある1つのページをVACUUM処理する際のコスト。" #. translator: GUC parameter "vacuum_cost_page_miss" short description -#: ../include/utils/guc_tables.inc.c:6240 utils/guc_tables.inc.c:6240 +#: ../include/utils/guc_tables.inc.c:6258 utils/guc_tables.inc.c:6258 msgid "Vacuum cost for a page not found in the buffer cache." msgstr "バッファキャッシュにない1つのページをVACUUM処理する際のコスト。" #. translator: GUC parameter "vacuum_failsafe_age" short description -#: ../include/utils/guc_tables.inc.c:6255 utils/guc_tables.inc.c:6255 +#: ../include/utils/guc_tables.inc.c:6273 utils/guc_tables.inc.c:6273 msgid "Age at which VACUUM should trigger failsafe to avoid a wraparound outage." msgstr "VACUUMにおいて周回による停止を回避するためのフェイルセーフを実行されるまでの経過トランザクション数。" #. translator: GUC parameter "vacuum_freeze_min_age" short description -#: ../include/utils/guc_tables.inc.c:6270 utils/guc_tables.inc.c:6270 +#: ../include/utils/guc_tables.inc.c:6288 utils/guc_tables.inc.c:6288 msgid "Minimum age at which VACUUM should freeze a table row." msgstr "VACUUM にテーブル行の凍結をさせる最小のトランザクションID差分。" #. translator: GUC parameter "vacuum_freeze_table_age" short description -#: ../include/utils/guc_tables.inc.c:6285 utils/guc_tables.inc.c:6285 +#: ../include/utils/guc_tables.inc.c:6303 utils/guc_tables.inc.c:6303 msgid "Age at which VACUUM should scan whole table to freeze tuples." msgstr "行の凍結のためのテーブル全体スキャンを強制させる時のトランザクションID差分。" #. translator: GUC parameter "vacuum_max_eager_freeze_failure_rate" short description -#: ../include/utils/guc_tables.inc.c:6300 utils/guc_tables.inc.c:6300 +#: ../include/utils/guc_tables.inc.c:6318 utils/guc_tables.inc.c:6318 msgid "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning." msgstr "VACUUMが貪欲スキャンを無効にする前にスキャンできるページ数の、リレーション全体に対する割合" #. translator: GUC parameter "vacuum_max_eager_freeze_failure_rate" long description -#: ../include/utils/guc_tables.inc.c:6302 utils/guc_tables.inc.c:6302 +#: ../include/utils/guc_tables.inc.c:6320 utils/guc_tables.inc.c:6320 msgid "A value of 0.0 disables eager scanning and a value of 1.0 will eagerly scan up to 100 percent of the all-visible pages in the relation. If vacuum successfully freezes these pages, the cap is lower than 100 percent, because the goal is to amortize page freezing across multiple vacuums." msgstr "0.0で貪欲スキャンを無効にし、1.0ではリレーション内の全可視ページを最大100%まで貪欲にスキャンします。ページの凍結を複数回のVACUUMに分散させることを目的としているため、VACUUMがスキャンしたページの凍結に成功した場合には、この上限は100%を下回ることがあります。" #. translator: GUC parameter "vacuum_multixact_failsafe_age" short description -#: ../include/utils/guc_tables.inc.c:6317 utils/guc_tables.inc.c:6317 +#: ../include/utils/guc_tables.inc.c:6335 utils/guc_tables.inc.c:6335 msgid "Multixact age at which VACUUM should trigger failsafe to avoid a wraparound outage." msgstr "VACUUMにおいて周回による停止を回避するためのフェイルセーフが実行されるまでの経過マルチトランザクション数。" #. translator: GUC parameter "vacuum_multixact_freeze_min_age" short description -#: ../include/utils/guc_tables.inc.c:6332 utils/guc_tables.inc.c:6332 +#: ../include/utils/guc_tables.inc.c:6350 utils/guc_tables.inc.c:6350 msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." msgstr "テーブル行でのマルチトランザクションIDの凍結を強制する最小のマルチトランザクション差分。" #. translator: GUC parameter "vacuum_multixact_freeze_table_age" short description -#: ../include/utils/guc_tables.inc.c:6347 utils/guc_tables.inc.c:6347 +#: ../include/utils/guc_tables.inc.c:6365 utils/guc_tables.inc.c:6365 msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." msgstr "行の凍結のためにテーブル全体スキャンを強制する時点のマルチトランザクション差分。" #. translator: GUC parameter "vacuum_truncate" short description -#: ../include/utils/guc_tables.inc.c:6362 utils/guc_tables.inc.c:6362 +#: ../include/utils/guc_tables.inc.c:6380 utils/guc_tables.inc.c:6380 msgid "Enables vacuum to truncate empty pages at the end of the table." msgstr "VACUUMの際にテーブル末尾の空のページを切り詰めるようにします。" #. translator: GUC parameter "wal_block_size" short description -#: ../include/utils/guc_tables.inc.c:6375 utils/guc_tables.inc.c:6375 +#: ../include/utils/guc_tables.inc.c:6393 utils/guc_tables.inc.c:6393 msgid "Shows the block size in the write ahead log." msgstr "先行書き込みログ(WAL)におけるブロックサイズを表示します" #. translator: GUC parameter "wal_buffers" short description -#: ../include/utils/guc_tables.inc.c:6391 utils/guc_tables.inc.c:6391 +#: ../include/utils/guc_tables.inc.c:6409 utils/guc_tables.inc.c:6409 msgid "Sets the number of disk-page buffers in shared memory for WAL." msgstr "共有メモリ内に割り当てられた、WALデータ用のディスクページバッファ数を設定。" #. translator: GUC parameter "wal_buffers" long description -#: ../include/utils/guc_tables.inc.c:6393 utils/guc_tables.inc.c:6393 +#: ../include/utils/guc_tables.inc.c:6411 utils/guc_tables.inc.c:6411 msgid "-1 means use a fraction of \"shared_buffers\"." msgstr "-1で\"shared_buffers\"の一部を使用します。" #. translator: GUC parameter "wal_compression" short description -#: ../include/utils/guc_tables.inc.c:6410 utils/guc_tables.inc.c:6410 +#: ../include/utils/guc_tables.inc.c:6428 utils/guc_tables.inc.c:6428 msgid "Compresses full-page writes written in WAL file with specified method." msgstr "WALファイルに出力される全ページ出力を指定した方式で圧縮します。" #. translator: GUC parameter "wal_consistency_checking" short description -#: ../include/utils/guc_tables.inc.c:6424 utils/guc_tables.inc.c:6424 +#: ../include/utils/guc_tables.inc.c:6442 utils/guc_tables.inc.c:6442 msgid "Sets the WAL resource managers for which WAL consistency checks are done." msgstr "WALの整合性チェックを行う対象とするリソースマネージャを設定。" #. translator: GUC parameter "wal_consistency_checking" long description -#: ../include/utils/guc_tables.inc.c:6426 utils/guc_tables.inc.c:6426 +#: ../include/utils/guc_tables.inc.c:6444 utils/guc_tables.inc.c:6444 msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." msgstr "全ページイメージが全てのデータブロックに対して記録され、WAL再生の結果とクロスチェックされます。" #. translator: GUC parameter "wal_debug" short description -#: ../include/utils/guc_tables.inc.c:6443 utils/guc_tables.inc.c:6443 +#: ../include/utils/guc_tables.inc.c:6461 utils/guc_tables.inc.c:6461 msgid "Emit WAL-related debugging output." msgstr "WAL関連のデバッグ出力を出力します。" #. translator: GUC parameter "wal_decode_buffer_size" short description -#: ../include/utils/guc_tables.inc.c:6458 utils/guc_tables.inc.c:6458 +#: ../include/utils/guc_tables.inc.c:6476 utils/guc_tables.inc.c:6476 msgid "Buffer size for reading ahead in the WAL during recovery." msgstr "リカバリ中のWAL先読みバッファのサイズ。" #. translator: GUC parameter "wal_decode_buffer_size" long description -#: ../include/utils/guc_tables.inc.c:6460 utils/guc_tables.inc.c:6460 +#: ../include/utils/guc_tables.inc.c:6478 utils/guc_tables.inc.c:6478 msgid "Maximum distance to read ahead in the WAL to prefetch referenced data blocks." msgstr "参照先データブロックの先行読み込みのためのWAL先読みの最大量。" #. translator: GUC parameter "wal_init_zero" short description -#: ../include/utils/guc_tables.inc.c:6476 utils/guc_tables.inc.c:6476 +#: ../include/utils/guc_tables.inc.c:6494 utils/guc_tables.inc.c:6494 msgid "Writes zeroes to new WAL files before first use." msgstr "新しいWALファイルの使用前にゼロを書き込みます。" #. translator: GUC parameter "wal_keep_size" short description -#: ../include/utils/guc_tables.inc.c:6489 utils/guc_tables.inc.c:6489 +#: ../include/utils/guc_tables.inc.c:6507 utils/guc_tables.inc.c:6507 msgid "Sets the size of WAL files held for standby servers." msgstr "スタンバイサーバーのために確保するWALの量を設定します。" #. translator: GUC parameter "wal_level" short description -#: ../include/utils/guc_tables.inc.c:6505 utils/guc_tables.inc.c:6505 +#: ../include/utils/guc_tables.inc.c:6523 utils/guc_tables.inc.c:6523 msgid "Sets the level of information written to the WAL." msgstr "WALに書き出される情報のレベルを設定します。" #. translator: GUC parameter "wal_log_hints" short description -#: ../include/utils/guc_tables.inc.c:6519 utils/guc_tables.inc.c:6519 +#: ../include/utils/guc_tables.inc.c:6537 utils/guc_tables.inc.c:6537 msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modification." msgstr "チェックポイントの後最初に更新された時に、重要な更新ではなくてもページ全体をWALに書き出します。" #. translator: GUC parameter "wal_receiver_create_temp_slot" short description -#: ../include/utils/guc_tables.inc.c:6532 utils/guc_tables.inc.c:6532 +#: ../include/utils/guc_tables.inc.c:6550 utils/guc_tables.inc.c:6550 msgid "Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured." msgstr "永続レプリケーションスロットがない場合にWALレシーバが一時スロットを作成するかどうかを設定します。" #. translator: GUC parameter "wal_receiver_status_interval" short description -#: ../include/utils/guc_tables.inc.c:6545 utils/guc_tables.inc.c:6545 +#: ../include/utils/guc_tables.inc.c:6563 utils/guc_tables.inc.c:6563 msgid "Sets the maximum interval between WAL receiver status reports to the sending server." msgstr "WAL受信プロセスが送出側サーバーへ行う状況報告の最大間隔を設定。" #. translator: GUC parameter "wal_receiver_timeout" short description -#: ../include/utils/guc_tables.inc.c:6561 utils/guc_tables.inc.c:6561 +#: ../include/utils/guc_tables.inc.c:6579 utils/guc_tables.inc.c:6579 msgid "Sets the maximum wait time to receive data from the sending server." msgstr "送出側サーバーからのデータ受信を待機する最長時間を設定。" #. translator: GUC parameter "wal_recycle" short description -#: ../include/utils/guc_tables.inc.c:6579 utils/guc_tables.inc.c:6579 +#: ../include/utils/guc_tables.inc.c:6597 utils/guc_tables.inc.c:6597 msgid "Recycles WAL files by renaming them." msgstr "WALファイルを名前を変更して再利用します。" #. translator: GUC parameter "wal_retrieve_retry_interval" short description -#: ../include/utils/guc_tables.inc.c:6592 utils/guc_tables.inc.c:6592 +#: ../include/utils/guc_tables.inc.c:6610 utils/guc_tables.inc.c:6610 msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." msgstr "WALの取り出しの失敗後に再試行する回数を設定。" #. translator: GUC parameter "wal_segment_size" short description -#: ../include/utils/guc_tables.inc.c:6608 utils/guc_tables.inc.c:6608 +#: ../include/utils/guc_tables.inc.c:6626 utils/guc_tables.inc.c:6626 msgid "Shows the size of write ahead log segments." msgstr "先行書き込みログ(WAL)セグメントのサイズを表示します" #. translator: GUC parameter "wal_sender_shutdown_timeout" short description -#: ../include/utils/guc_tables.inc.c:6625 utils/guc_tables.inc.c:6625 +#: ../include/utils/guc_tables.inc.c:6643 utils/guc_tables.inc.c:6643 msgid "Sets the maximum time the server waits during shutdown for all WAL data to be replicated to the receiver." msgstr "サーバーがシャットダウン中に、すべてのWALデータが受信側にレプリケートされるのを待機する時間の最大値を設定。" #. translator: GUC parameter "wal_sender_shutdown_timeout" long description -#: ../include/utils/guc_tables.inc.c:6627 utils/guc_tables.inc.c:6627 +#: ../include/utils/guc_tables.inc.c:6645 utils/guc_tables.inc.c:6645 msgid "-1 disables the timeout" msgstr "-1でこのタイムアウトを無効にします" #. translator: GUC parameter "wal_sender_timeout" short description -#: ../include/utils/guc_tables.inc.c:6643 utils/guc_tables.inc.c:6643 +#: ../include/utils/guc_tables.inc.c:6661 utils/guc_tables.inc.c:6661 msgid "Sets the maximum time to wait for WAL replication." msgstr "WALレプリケーションを待つ時間の最大値を設定。" #. translator: GUC parameter "wal_skip_threshold" short description -#: ../include/utils/guc_tables.inc.c:6659 utils/guc_tables.inc.c:6659 +#: ../include/utils/guc_tables.inc.c:6677 utils/guc_tables.inc.c:6677 msgid "Minimum size of new file to fsync instead of writing WAL." msgstr "WALを出力する代わりにfsyncを使用する新規ファイルの最小サイズ。" #. translator: GUC parameter "wal_summary_keep_time" short description -#: ../include/utils/guc_tables.inc.c:6675 utils/guc_tables.inc.c:6675 +#: ../include/utils/guc_tables.inc.c:6693 utils/guc_tables.inc.c:6693 msgid "Time for which WAL summary files should be kept." msgstr "WAL集約ファイルを保持する時間。" #. translator: GUC parameter "wal_summary_keep_time" long description -#: ../include/utils/guc_tables.inc.c:6677 utils/guc_tables.inc.c:6677 +#: ../include/utils/guc_tables.inc.c:6695 utils/guc_tables.inc.c:6695 msgid "0 disables automatic summary file deletion." msgstr "0で集約ファイルの自動削除を無効にします。" #. translator: GUC parameter "wal_sync_method" short description -#: ../include/utils/guc_tables.inc.c:6693 utils/guc_tables.inc.c:6693 +#: ../include/utils/guc_tables.inc.c:6711 utils/guc_tables.inc.c:6711 msgid "Selects the method used for forcing WAL updates to disk." msgstr "WAL更新のディスクへの書き出しを強制するための方法を選択します。" #. translator: GUC parameter "wal_writer_delay" short description -#: ../include/utils/guc_tables.inc.c:6708 utils/guc_tables.inc.c:6708 +#: ../include/utils/guc_tables.inc.c:6726 utils/guc_tables.inc.c:6726 msgid "Time between WAL flushes performed in the WAL writer." msgstr "WALライタで実行する書き出しの時間間隔。" #. translator: GUC parameter "wal_writer_flush_after" short description -#: ../include/utils/guc_tables.inc.c:6724 utils/guc_tables.inc.c:6724 +#: ../include/utils/guc_tables.inc.c:6742 utils/guc_tables.inc.c:6742 msgid "Amount of WAL written out by WAL writer that triggers a flush." msgstr "書き出しが実行されるまでにWALライタで出力するWALの量。" #. translator: GUC parameter "work_mem" short description -#: ../include/utils/guc_tables.inc.c:6740 utils/guc_tables.inc.c:6740 +#: ../include/utils/guc_tables.inc.c:6758 utils/guc_tables.inc.c:6758 msgid "Sets the maximum memory to be used for query workspaces." msgstr "問い合わせの作業用空間として使用されるメモリの最大値を設定。" #. translator: GUC parameter "work_mem" long description -#: ../include/utils/guc_tables.inc.c:6742 utils/guc_tables.inc.c:6742 +#: ../include/utils/guc_tables.inc.c:6760 utils/guc_tables.inc.c:6760 msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." msgstr "内部ソート操作とハッシュテーブルで使われるメモリの量がこの量に達した時に一時ディスクファイルへの切替えを行います。" #. translator: GUC parameter "xmlbinary" short description -#: ../include/utils/guc_tables.inc.c:6758 utils/guc_tables.inc.c:6758 +#: ../include/utils/guc_tables.inc.c:6776 utils/guc_tables.inc.c:6776 msgid "Sets how binary values are to be encoded in XML." msgstr "XMLでどのようにバイナリ値を符号化するかを設定します。" #. translator: GUC parameter "xmloption" short description -#: ../include/utils/guc_tables.inc.c:6772 utils/guc_tables.inc.c:6772 +#: ../include/utils/guc_tables.inc.c:6790 utils/guc_tables.inc.c:6790 msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." msgstr "暗黙的なパースおよび直列化操作においてXMLデータを文書とみなすか断片とみなすかを設定します。" #. translator: GUC parameter "zero_damaged_pages" short description -#: ../include/utils/guc_tables.inc.c:6786 utils/guc_tables.inc.c:6786 +#: ../include/utils/guc_tables.inc.c:6804 utils/guc_tables.inc.c:6804 msgid "Continues processing past damaged page headers." msgstr "破損したページヘッダがあっても処理を継続します。" #. translator: GUC parameter "zero_damaged_pages" long description -#: ../include/utils/guc_tables.inc.c:6788 utils/guc_tables.inc.c:6788 +#: ../include/utils/guc_tables.inc.c:6806 utils/guc_tables.inc.c:6806 msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting \"zero_damaged_pages\" to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." msgstr "ページヘッダの障害が検出されると、通常PostgreSQLはエラーの報告を行ない、現在のトランザクションを中断させます。\"zero_damaged_pages\"をtrueに設定することにより、システムは代わりに警告を報告し、障害のあるページをゼロで埋め、処理を継続します。 この動作により、障害のあったページ上にある全ての行のデータが破壊されます。" @@ -3624,7 +3634,7 @@ msgid "request for BRIN range summarization for index \"%s\" page %u was not rec msgstr "インデックス\"%s\" ページ%uのBRIN範囲要約のリクエストは登録されていません" #: access/brin/brin.c:1402 access/brin/brin.c:1509 access/gin/ginfast.c:1040 access/transam/xlogfuncs.c:214 access/transam/xlogfuncs.c:239 access/transam/xlogfuncs.c:272 access/transam/xlogfuncs.c:311 access/transam/xlogfuncs.c:332 access/transam/xlogfuncs.c:353 access/transam/xlogfuncs.c:419 access/transam/xlogfuncs.c:478 commands/wait.c:192 statistics/attribute_stats.c:180 statistics/attribute_stats.c:619 statistics/extended_stats_funcs.c:370 -#: statistics/extended_stats_funcs.c:1773 statistics/relation_stats.c:97 +#: statistics/extended_stats_funcs.c:1778 statistics/relation_stats.c:97 #, c-format msgid "recovery is in progress" msgstr "リカバリは現在進行中です" @@ -3654,7 +3664,7 @@ msgstr "インデックス\"%s\"の親テーブルをオープンできません msgid "index \"%s\" is not valid" msgstr "インデックス\"%s\"は有効ではありません" -#: access/brin/brin_bloom.c:786 access/brin/brin_bloom.c:828 access/brin/brin_minmax_multi.c:2982 access/brin/brin_minmax_multi.c:3119 statistics/mcv.c:1478 statistics/mcv.c:1509 utils/adt/pg_dependencies.c:858 utils/adt/pg_ndistinct.c:836 utils/adt/pseudotypes.c:40 utils/adt/pseudotypes.c:74 utils/adt/tsgistidx.c:94 +#: access/brin/brin_bloom.c:786 access/brin/brin_bloom.c:828 access/brin/brin_minmax_multi.c:2982 access/brin/brin_minmax_multi.c:3119 statistics/mcv.c:1478 statistics/mcv.c:1509 utils/adt/pg_dependencies.c:857 utils/adt/pg_ndistinct.c:836 utils/adt/pseudotypes.c:40 utils/adt/pseudotypes.c:74 utils/adt/tsgistidx.c:94 #, c-format msgid "cannot accept a value of type %s" msgstr "%s型の値は受け付けられません" @@ -3759,7 +3769,7 @@ msgstr "インデックス列数(%d)が上限(%d)を超えています" msgid "index row requires %zu bytes, maximum size is %zu" msgstr "インデックス行が%zuバイトを必要としますが最大値は%zuです" -#: access/common/printtup.c:293 commands/explain_dr.c:95 tcop/fastpath.c:106 tcop/fastpath.c:453 tcop/postgres.c:1965 +#: access/common/printtup.c:293 commands/explain_dr.c:95 tcop/fastpath.c:106 tcop/fastpath.c:453 tcop/postgres.c:1996 #, c-format msgid "unsupported format code: %d" msgstr "非サポートの書式コード: %d" @@ -3807,12 +3817,12 @@ msgstr "認識できないラメータ \"%s\"" msgid "parameter \"%s\" specified more than once" msgstr "パラメータ\"%s\"が複数回指定されました" -#: access/common/reloptions.c:1715 access/common/reloptions.c:1729 utils/adt/ddlutils.c:195 +#: access/common/reloptions.c:1715 access/common/reloptions.c:1729 #, c-format msgid "invalid value for boolean option \"%s\": %s" msgstr "不正なブール型オプションの値 \"%s\": %s" -#: access/common/reloptions.c:1741 utils/adt/ddlutils.c:215 +#: access/common/reloptions.c:1741 #, c-format msgid "invalid value for integer option \"%s\": %s" msgstr "不正な整数型オプションの値 \"%s\": %s" @@ -3892,7 +3902,7 @@ msgstr "他のセッションの一時インデックスにはアクセスでき msgid "failed to re-find tuple within index \"%s\"" msgstr "インデックス\"%s\"内で行の再検索に失敗しました" -#: access/gin/gininsert.c:1324 access/gin/ginutil.c:155 executor/execExpr.c:2276 utils/adt/array_userfuncs.c:1972 utils/adt/arrayfuncs.c:4040 utils/adt/arrayfuncs.c:6752 utils/adt/rowtypes.c:974 utils/sort/tuplesortvariants.c:647 +#: access/gin/gininsert.c:1324 access/gin/ginutil.c:155 executor/execExpr.c:2243 utils/adt/array_userfuncs.c:1972 utils/adt/arrayfuncs.c:4040 utils/adt/arrayfuncs.c:6752 utils/adt/rowtypes.c:974 utils/sort/tuplesortvariants.c:647 #, c-format msgid "could not identify a comparison function for type %s" msgstr "%s型の比較関数が見つかりません" @@ -3977,7 +3987,7 @@ msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は演算子%3$s msgid "could not determine which collation to use for string hashing" msgstr "文字列のハッシュ値計算で使用する照合順序を特定できませんでした" -#: access/hash/hashfunc.c:281 access/hash/hashfunc.c:336 catalog/heap.c:703 catalog/heap.c:709 commands/createas.c:203 commands/createas.c:515 commands/indexcmds.c:2110 commands/tablecmds.c:20266 commands/view.c:79 regex/regc_pg_locale.c:48 utils/adt/formatting.c:1638 utils/adt/formatting.c:1702 utils/adt/formatting.c:1766 utils/adt/formatting.c:1830 utils/adt/like.c:151 utils/adt/like.c:182 utils/adt/like_support.c:1095 utils/adt/varchar.c:741 +#: access/hash/hashfunc.c:281 access/hash/hashfunc.c:336 catalog/heap.c:703 catalog/heap.c:709 commands/createas.c:203 commands/createas.c:515 commands/indexcmds.c:2120 commands/tablecmds.c:20553 commands/view.c:79 regex/regc_pg_locale.c:48 utils/adt/formatting.c:1638 utils/adt/formatting.c:1702 utils/adt/formatting.c:1766 utils/adt/formatting.c:1830 utils/adt/like.c:151 utils/adt/like.c:182 utils/adt/like_support.c:1095 utils/adt/varchar.c:741 #: utils/adt/varchar.c:1004 utils/adt/varchar.c:1060 utils/adt/varlena.c:1337 #, c-format msgid "Use the COLLATE clause to set the collation explicitly." @@ -4048,7 +4058,7 @@ msgstr "並列処理中はタプルの削除はできません" msgid "attempted to delete invisible tuple" msgstr "不可視のタプルを削除しようとしました" -#: access/heap/heapam.c:3264 access/index/genam.c:840 +#: access/heap/heapam.c:3264 access/index/genam.c:832 #, c-format msgid "cannot update tuples during a parallel operation" msgstr "並列処理中はタプルの更新はできません" @@ -4063,7 +4073,7 @@ msgstr "不可視のタプルを更新しようとしました" msgid "could not obtain lock on row in relation \"%s\"" msgstr "リレーション\"%s\"の行ロックを取得できませんでした" -#: access/heap/heapam.c:6392 commands/trigger.c:3402 executor/nodeModifyTable.c:2869 executor/nodeModifyTable.c:2959 +#: access/heap/heapam.c:6392 commands/trigger.c:3427 executor/nodeModifyTable.c:2856 executor/nodeModifyTable.c:2946 #, c-format msgid "tuple to be updated was already modified by an operation triggered by the current command" msgstr "更新対象のタプルはすでに現在のコマンドによって起動された操作によって変更されています" @@ -4108,8 +4118,8 @@ msgstr "リレーション \"%s\"、ページ %u" msgid "could not write to file \"%s\", wrote %d of %d: %m" msgstr "ファイル\"%1$s\"に書き込めませんでした、%3$dバイト中%2$dバイト書き込みました: %m" -#: access/heap/rewriteheap.c:980 access/heap/rewriteheap.c:1097 access/transam/timeline.c:330 access/transam/timeline.c:482 access/transam/xlog.c:3294 access/transam/xlog.c:3502 access/transam/xlog.c:4373 access/transam/xlog.c:9936 access/transam/xlogfuncs.c:712 backup/basebackup_server.c:149 backup/basebackup_server.c:242 commands/dbcommands.c:498 postmaster/launch_backend.c:332 postmaster/postmaster.c:4142 postmaster/walsummarizer.c:1218 -#: replication/logical/origin.c:644 replication/slot.c:2565 storage/file/copydir.c:174 storage/file/copydir.c:262 storage/smgr/md.c:263 utils/time/snapmgr.c:1254 +#: access/heap/rewriteheap.c:980 access/heap/rewriteheap.c:1097 access/transam/timeline.c:330 access/transam/timeline.c:482 access/transam/xlog.c:3294 access/transam/xlog.c:3502 access/transam/xlog.c:4373 access/transam/xlog.c:9940 access/transam/xlogfuncs.c:712 backup/basebackup_server.c:149 backup/basebackup_server.c:242 commands/dbcommands.c:498 postmaster/launch_backend.c:332 postmaster/postmaster.c:4142 postmaster/walsummarizer.c:1218 +#: replication/logical/origin.c:644 replication/slot.c:2561 storage/file/copydir.c:174 storage/file/copydir.c:262 storage/smgr/md.c:263 utils/time/snapmgr.c:1254 #, c-format msgid "could not create file \"%s\": %m" msgstr "ファイル\"%s\"を作成できませんでした: %m" @@ -4119,7 +4129,7 @@ msgstr "ファイル\"%s\"を作成できませんでした: %m" msgid "could not truncate file \"%s\" to %u: %m" msgstr "ファイル\"%s\"を%uバイトに切り詰められませんでした: %m" -#: access/heap/rewriteheap.c:1125 access/transam/timeline.c:385 access/transam/timeline.c:425 access/transam/timeline.c:499 access/transam/xlog.c:3355 access/transam/xlog.c:3558 access/transam/xlog.c:4385 commands/dbcommands.c:510 postmaster/launch_backend.c:343 postmaster/launch_backend.c:355 replication/logical/origin.c:656 replication/logical/origin.c:698 replication/logical/origin.c:717 replication/logical/snapbuild.c:1725 replication/slot.c:2601 +#: access/heap/rewriteheap.c:1125 access/transam/timeline.c:385 access/transam/timeline.c:425 access/transam/timeline.c:499 access/transam/xlog.c:3347 access/transam/xlog.c:3558 access/transam/xlog.c:4385 commands/dbcommands.c:510 postmaster/launch_backend.c:343 postmaster/launch_backend.c:355 replication/logical/origin.c:656 replication/logical/origin.c:698 replication/logical/origin.c:717 replication/logical/snapbuild.c:1669 replication/slot.c:2597 #: storage/file/buffile.c:546 storage/file/copydir.c:214 utils/init/miscinit.c:1611 utils/init/miscinit.c:1622 utils/init/miscinit.c:1630 utils/misc/guc.c:4389 utils/misc/guc.c:4420 utils/misc/guc.c:5579 utils/misc/guc.c:5597 utils/time/snapmgr.c:1259 utils/time/snapmgr.c:1266 #, c-format msgid "could not write to file \"%s\": %m" @@ -4383,17 +4393,17 @@ msgstr "アクセスメソッド\"%s\"のタイプが%sではありません" msgid "index access method \"%s\" does not have a handler" msgstr "インデックスアクセスメソッド\"%s\"はハンドラを持っていません" -#: access/index/genam.c:507 +#: access/index/genam.c:499 #, c-format msgid "transaction aborted during system catalog scan" msgstr "システムカタログのスキャン中にトランザクションがアボートしました" -#: access/index/genam.c:672 access/index/indexam.c:83 +#: access/index/genam.c:664 access/index/indexam.c:83 #, c-format msgid "cannot access index \"%s\" while it is being reindexed" msgstr "再作成中であるためインデックス\"%s\"にアクセスできません" -#: access/index/indexam.c:204 catalog/objectaddress.c:1449 commands/indexcmds.c:3039 commands/tablecmds.c:288 commands/tablecmds.c:312 commands/tablecmds.c:19945 commands/tablecmds.c:21896 +#: access/index/indexam.c:204 catalog/objectaddress.c:1455 commands/indexcmds.c:3164 commands/tablecmds.c:288 commands/tablecmds.c:312 commands/tablecmds.c:20232 commands/tablecmds.c:22176 #, c-format msgid "\"%s\" is not an index" msgstr "\"%s\"はインデックスではありません" @@ -4462,7 +4472,7 @@ msgstr "" msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は型%3$sと%4$sに対応するサポート関数を含んでいません" -#: access/sequence/sequence.c:75 catalog/aclchk.c:1842 catalog/objectaddress.c:1463 commands/tablecmds.c:270 commands/tablecmds.c:19913 utils/adt/acl.c:2150 utils/adt/acl.c:2180 utils/adt/acl.c:2213 utils/adt/acl.c:2249 utils/adt/acl.c:2280 utils/adt/acl.c:2311 +#: access/sequence/sequence.c:75 catalog/aclchk.c:1842 catalog/objectaddress.c:1469 commands/tablecmds.c:270 commands/tablecmds.c:20200 utils/adt/acl.c:2150 utils/adt/acl.c:2180 utils/adt/acl.c:2213 utils/adt/acl.c:2249 utils/adt/acl.c:2280 utils/adt/acl.c:2311 #, c-format msgid "\"%s\" is not a sequence" msgstr "\"%s\"はシーケンスではありません" @@ -4502,7 +4512,7 @@ msgstr "tid (%u, %u) はリレーション\"%s\"に対して妥当ではあり msgid "\"%s\" cannot be empty." msgstr "\"%s\"は空にはできません。" -#: access/table/tableamapi.c:112 access/transam/xlogrecovery.c:4879 +#: access/table/tableamapi.c:112 access/transam/xlogrecovery.c:4881 #, c-format msgid "\"%s\" is too long (maximum %d characters)." msgstr "\"%s\"が長過ぎます(最大%d文字)。" @@ -4557,14 +4567,14 @@ msgstr "トランザクション%uのコミット・タイムスタンプにア msgid "database is not accepting commands that assign new MultiXactIds to avoid wraparound data loss in database \"%s\"" msgstr "データベース\"%s\"はMultiXactIds周回によるデータ損失を防ぐために、新規のMultiXactIdsを割り当てるコマンドを受け付けていません" -#: access/transam/multixact.c:1042 access/transam/multixact.c:1049 access/transam/multixact.c:1075 access/transam/multixact.c:1086 access/transam/varsup.c:149 access/transam/varsup.c:156 +#: access/transam/multixact.c:1042 access/transam/multixact.c:1049 access/transam/multixact.c:1075 access/transam/multixact.c:1086 #, c-format msgid "" "Execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +"You might also need to commit or roll back old prepared transactions." msgstr "" "そのデータベース全体の VACUUM を実行してください。\n" -"古い準備済みトランザクションのコミットまたはロールバック、もしくは古いレプリケーションスロットの削除も必要かもしれません。" +"古い準備済みトランザクションのコミットまたはロールバックも必要かもしれません。" #: access/transam/multixact.c:1047 #, c-format @@ -4632,10 +4642,10 @@ msgstr "MultiXact %u のメンバが多すぎます(%)" #, c-format msgid "" "To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +"You might also need to commit or roll back old prepared transactions." msgstr "" "MultiXactIdの割り当て失敗を防ぐために、このデータベースでデータベース全体に対するVACUUMを実行してください。\n" -"古い準備済みトランザクションのコミットまたはロールバック、もしくは古いレプリケーションスロットの削除も必要かもしれません。" +"古い準備済みトランザクションのコミットまたはロールバックも必要かもしれません。" #: access/transam/multixact.c:2478 #, c-format @@ -4691,7 +4701,7 @@ msgstr "パラレルワーカーへの接続を失いました" msgid "parallel worker" msgstr "パラレルワーカー" -#: access/transam/parallel.c:1356 commands/repack_worker.c:83 replication/logical/applyparallelworker.c:909 +#: access/transam/parallel.c:1356 commands/repack_worker.c:78 replication/logical/applyparallelworker.c:909 #, c-format msgid "could not map dynamic shared memory segment" msgstr "動的共有メモリセグメントをマップできませんでした" @@ -5023,6 +5033,15 @@ msgstr "ファイル\"%s\"にアクセスできませんでした: %m" msgid "database is not accepting commands that assign new transaction IDs to avoid wraparound data loss in database \"%s\"" msgstr "データベース\"%s\"はXID周回によるデータ損失を防ぐために、新規のトランザクションIDを割り当てるコマンドを受け付けていません" +#: access/transam/varsup.c:149 access/transam/varsup.c:156 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"そのデータベース全体の VACUUM を実行してください。\n" +"古い準備済みトランザクションのコミットまたはロールバック、もしくは古いレプリケーションスロットの削除も必要かもしれません。" + #: access/transam/varsup.c:154 #, c-format msgid "database is not accepting commands that assign new transaction IDs to avoid wraparound data loss in database with OID %u" @@ -5086,86 +5105,86 @@ msgstr "1トランザクション内では 2^32-2 個より多くのコマンド msgid "maximum number of committed subtransactions (%d) exceeded" msgstr "コミットされたサブトランザクション数の最大値(%d)が制限を越えました" -#: access/transam/xact.c:2659 +#: access/transam/xact.c:2660 #, c-format msgid "cannot PREPARE a transaction that has operated on temporary objects" msgstr "一時オブジェクトに対する操作を行ったトランザクションをPREPAREすることはできません" -#: access/transam/xact.c:2669 +#: access/transam/xact.c:2670 #, c-format msgid "cannot PREPARE a transaction that has exported snapshots" msgstr "エクスポートされたスナップショットを持つトランザクションをPREPAREすることはできません" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3707 +#: access/transam/xact.c:3710 #, c-format msgid "%s cannot run inside a transaction block" msgstr "%sはトランザクションブロックの内側では実行できません" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3717 +#: access/transam/xact.c:3720 #, c-format msgid "%s cannot run inside a subtransaction" msgstr "%sはサブトランザクションブロックの内側では実行できません" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3727 +#: access/transam/xact.c:3730 #, c-format msgid "%s cannot be executed from a function or procedure" msgstr "%s は関数またはプロシージャ内での実行はできません" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3799 access/transam/xact.c:4121 access/transam/xact.c:4200 access/transam/xact.c:4323 access/transam/xact.c:4474 access/transam/xact.c:4543 access/transam/xact.c:4654 +#: access/transam/xact.c:3802 access/transam/xact.c:4124 access/transam/xact.c:4203 access/transam/xact.c:4326 access/transam/xact.c:4477 access/transam/xact.c:4546 access/transam/xact.c:4657 #, c-format msgid "%s can only be used in transaction blocks" msgstr "%sはトランザクションブロック内でのみ使用できます" -#: access/transam/xact.c:4007 +#: access/transam/xact.c:4010 #, c-format msgid "there is already a transaction in progress" msgstr "すでにトランザクションが実行中です" -#: access/transam/xact.c:4126 access/transam/xact.c:4205 access/transam/xact.c:4328 +#: access/transam/xact.c:4129 access/transam/xact.c:4208 access/transam/xact.c:4331 #, c-format msgid "there is no transaction in progress" msgstr "実行中のトランザクションがありません" -#: access/transam/xact.c:4216 +#: access/transam/xact.c:4219 #, c-format msgid "cannot commit during a parallel operation" msgstr "並列処理中にはコミットはできません" -#: access/transam/xact.c:4339 +#: access/transam/xact.c:4342 #, c-format msgid "cannot abort during a parallel operation" msgstr "パラレル処理中にロールバックはできません" -#: access/transam/xact.c:4438 +#: access/transam/xact.c:4441 #, c-format msgid "cannot define savepoints during a parallel operation" msgstr "パラレル処理中にセーブポイントは定義できません" -#: access/transam/xact.c:4525 +#: access/transam/xact.c:4528 #, c-format msgid "cannot release savepoints during a parallel operation" msgstr "並列処理中はセーブポイントの解放はできません" -#: access/transam/xact.c:4535 access/transam/xact.c:4586 access/transam/xact.c:4646 access/transam/xact.c:4695 +#: access/transam/xact.c:4538 access/transam/xact.c:4589 access/transam/xact.c:4649 access/transam/xact.c:4698 #, c-format msgid "savepoint \"%s\" does not exist" msgstr "セーブポイント\"%s\"は存在しません" -#: access/transam/xact.c:4592 access/transam/xact.c:4701 +#: access/transam/xact.c:4595 access/transam/xact.c:4704 #, c-format msgid "savepoint \"%s\" does not exist within current savepoint level" msgstr "セーブポイント\"%s\"は現在のセーブポイントレベルには存在しません" -#: access/transam/xact.c:4634 +#: access/transam/xact.c:4637 #, c-format msgid "cannot rollback to savepoints during a parallel operation" msgstr "パラレル処理中にセーブポイントのロールバックはできません" -#: access/transam/xact.c:5494 +#: access/transam/xact.c:5497 #, c-format msgid "cannot have more than 2^32-1 subtransactions in a transaction" msgstr "1トランザクション内には 2^32-1 個より多くのサブトランザクションを作成できません" @@ -5185,12 +5204,12 @@ msgstr "生成されたWALより先の位置までの読み込み要求; 要求 msgid "The WAL segment size must be a power of two between 1 MB and 1 GB." msgstr "WALセグメントサイズは1MBから1GBまでの間の2の累乗でなければなりません。" -#: access/transam/xlog.c:2475 +#: access/transam/xlog.c:2472 #, c-format msgid "could not write to log file \"%s\" at offset %u, length %zu: %m" msgstr "ログファイル \"%s\" のオフセット%uに長さ%zuの書き込みができませんでした: %m" -#: access/transam/xlog.c:3795 access/transam/xlogutils.c:820 replication/walsender.c:3301 +#: access/transam/xlog.c:3795 access/transam/xlogutils.c:844 replication/walsender.c:3323 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "要求された WAL セグメント %s はすでに削除されています" @@ -5278,284 +5297,284 @@ msgstr[0] "制御ファイル中の不正なWALセグメントサイズ (%dバ msgid "\"%s\" must be at least twice \"%s\"" msgstr "\"%s\"は\"%s\"の2倍以上でなければなりません" -#: access/transam/xlog.c:5093 catalog/namespace.c:4768 commands/tablespace.c:1224 commands/user.c:2544 commands/variable.c:72 replication/slot.c:2980 tcop/postgres.c:3708 utils/error/elog.c:2389 utils/error/elog.c:2693 +#: access/transam/xlog.c:5092 catalog/namespace.c:4768 commands/tablespace.c:1224 commands/user.c:2544 commands/variable.c:72 replication/slot.c:2976 tcop/postgres.c:3803 utils/error/elog.c:2389 utils/error/elog.c:2693 #, c-format msgid "List syntax is invalid." msgstr "リスト文法が無効です" -#: access/transam/xlog.c:5139 commands/user.c:2560 commands/variable.c:173 tcop/postgres.c:3724 utils/error/elog.c:2719 +#: access/transam/xlog.c:5138 commands/user.c:2560 commands/variable.c:173 tcop/postgres.c:3819 utils/error/elog.c:2719 #, c-format msgid "Unrecognized key word: \"%s\"." msgstr "不明なキーワードです: \"%s\"" -#: access/transam/xlog.c:5578 +#: access/transam/xlog.c:5577 #, c-format msgid "could not write bootstrap write-ahead log file: %m" msgstr "ブートストラップの先行書き込みログファイルに書き込めませんでした: %m" -#: access/transam/xlog.c:5586 +#: access/transam/xlog.c:5585 #, c-format msgid "could not fsync bootstrap write-ahead log file: %m" msgstr "ブートストラップの先行書き込みログファイルをfsyncできませんでした: %m" -#: access/transam/xlog.c:5592 +#: access/transam/xlog.c:5591 #, c-format msgid "could not close bootstrap write-ahead log file: %m" msgstr "ブートストラップの先行書き込みログファイルをクローズできませんでした: %m" -#: access/transam/xlog.c:5813 +#: access/transam/xlog.c:5812 #, c-format msgid "WAL was generated with \"wal_level=minimal\", cannot continue recovering" msgstr "\"wal_level=minimal\"でWALが生成されました、リカバリは続行不可です" -#: access/transam/xlog.c:5814 +#: access/transam/xlog.c:5813 #, c-format msgid "This happens if you temporarily set \"wal_level=minimal\" on the server." msgstr "これはこのサーバーで一時的に\"wal_level=minimal\"にした場合に起こります。" -#: access/transam/xlog.c:5815 +#: access/transam/xlog.c:5814 #, c-format msgid "Use a backup taken after setting \"wal_level\" to higher than \"minimal\"." msgstr "\"wal_level\"を\"minimal\"より上位に設定したあとに取得したバックアップを使用してください。" -#: access/transam/xlog.c:5881 +#: access/transam/xlog.c:5880 #, c-format msgid "control file contains invalid checkpoint location" msgstr "制御ファイル内のチェックポイント位置が不正です" -#: access/transam/xlog.c:5892 +#: access/transam/xlog.c:5891 #, c-format msgid "database system was shut down at %s" msgstr "データベースシステムは %s にシャットダウンしました" -#: access/transam/xlog.c:5899 +#: access/transam/xlog.c:5898 #, c-format msgid "database system was shut down in recovery at %s" msgstr "データベースシステムはリカバリ中 %s にシャットダウンしました" -#: access/transam/xlog.c:5906 +#: access/transam/xlog.c:5905 #, c-format msgid "database system shutdown was interrupted; last known up at %s" msgstr "データベースシステムはシャットダウン中に中断されました; %s まで動作していたことは確認できます" -#: access/transam/xlog.c:5913 +#: access/transam/xlog.c:5912 #, c-format msgid "database system was interrupted while in recovery at %s" msgstr "データベースシステムはリカバリ中 %s に中断されました" -#: access/transam/xlog.c:5916 +#: access/transam/xlog.c:5915 #, c-format msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." msgstr "これはおそらくデータ破損があり、リカバリのために直前のバックアップを使用しなければならないことを意味します。" -#: access/transam/xlog.c:5922 +#: access/transam/xlog.c:5921 #, c-format msgid "database system was interrupted while in recovery at log time %s" msgstr "データベースシステムはリカバリ中ログ時刻 %s に中断されました" -#: access/transam/xlog.c:5925 +#: access/transam/xlog.c:5924 #, c-format msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." msgstr "これが1回以上起きた場合はデータが破損している可能性があるため、より以前のリカバリ目標を選ぶ必要があるかもしれません。" -#: access/transam/xlog.c:5931 +#: access/transam/xlog.c:5930 #, c-format msgid "database system was interrupted; last known up at %s" msgstr "データベースシステムは中断されました: %s まで動作していたことは確認できます" -#: access/transam/xlog.c:5939 +#: access/transam/xlog.c:5938 #, c-format msgid "control file contains invalid database cluster state" msgstr "制御ファイル内のデータベース・クラスタ状態が不正です" -#: access/transam/xlog.c:6332 +#: access/transam/xlog.c:6331 #, c-format msgid "WAL ends before end of online backup" msgstr "オンラインバックアップの終了より前にWALが終了しました" -#: access/transam/xlog.c:6333 +#: access/transam/xlog.c:6332 #, c-format msgid "All WAL generated while online backup was taken must be available at recovery." msgstr "オンラインバックアップ中に生成されたすべてのWALがリカバリで利用可能である必要があります。" -#: access/transam/xlog.c:6337 +#: access/transam/xlog.c:6336 #, c-format msgid "WAL ends before consistent recovery point" msgstr "WALが一貫性があるリカバリポイントより前で終了しました" -#: access/transam/xlog.c:6383 +#: access/transam/xlog.c:6382 #, c-format msgid "selected new timeline ID: %u" msgstr "新しいタイムラインIDを選択: %u" -#: access/transam/xlog.c:6416 +#: access/transam/xlog.c:6415 #, c-format msgid "archive recovery complete" msgstr "アーカイブリカバリが完了しました" -#: access/transam/xlog.c:6614 +#: access/transam/xlog.c:6616 #, c-format msgid "enabling data checksums was interrupted" msgstr "チェックサムの有効化が中断されました" -#: access/transam/xlog.c:6615 +#: access/transam/xlog.c:6617 #, c-format -msgid "Data checksum processing must be manually restarted for checksums to be enabled" -msgstr "データチェックサムを有効化するには、この処理を手動で再実行する必要があります" +msgid "Data checksum processing must be manually restarted for checksums to be enabled." +msgstr "データチェックサムを有効化するには、データチェックサム処理を手動で再起動する必要があります。" -#: access/transam/xlog.c:7113 +#: access/transam/xlog.c:7117 #, c-format msgid "shutting down" msgstr "シャットダウンしています" #. translator: the placeholder shows checkpoint options -#: access/transam/xlog.c:7174 +#: access/transam/xlog.c:7178 #, c-format msgid "restartpoint starting:%s" msgstr "リスタートポイント開始:%s" #. translator: the placeholder shows checkpoint options -#: access/transam/xlog.c:7179 +#: access/transam/xlog.c:7183 #, c-format msgid "checkpoint starting:%s" msgstr "チェックポイント開始:%s" -#: access/transam/xlog.c:7237 +#: access/transam/xlog.c:7241 #, c-format msgid "restartpoint complete:%s: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB; lsn=%X/%08X, redo lsn=%X/%08X" msgstr "リスタートポイント完了:%s: %d個のバッファを出力 (%.1f%%), %d個のSLRUバッファを出力; %d個のWALファイルを追加、%d個を削除、%d個を再利用; 書き出し=%ld.%03d秒, 同期=%ld.%03d秒, 全体=%ld.%03d秒; 同期したファイル=%d, 最長=%ld.%03d秒, 平均=%ld.%03d秒; 距離=%d kB, 予測=%d kB; lsn=%X/%08X, 再生lsn=%X/%08X" -#: access/transam/xlog.c:7262 +#: access/transam/xlog.c:7266 #, c-format msgid "checkpoint complete:%s: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB; lsn=%X/%08X, redo lsn=%X/%08X" msgstr "チェックポイント完了:%s: %d個のバッファを出力 (%.1f%%), %d個のSLRUバッファを出力; %d個のWALファイルを追加、%d個を削除、%d個を再利用; 書き出し=%ld.%03d秒, 同期=%ld.%03d秒, 全体=%ld.%03d秒; 同期したファイル=%d, 最長=%ld.%03d秒, 平均=%ld.%03d秒; 距離=%d kB, 予測=%d kB; lsn=%X/%08X, 再生lsn=%X/%08X" -#: access/transam/xlog.c:7774 +#: access/transam/xlog.c:7778 #, c-format msgid "concurrent write-ahead log activity while database system is shutting down" msgstr "データベースのシャットダウンに並行して、先行書き込みログが発生しました" -#: access/transam/xlog.c:8370 +#: access/transam/xlog.c:8374 #, c-format msgid "recovery restart point at %X/%08X" msgstr "リカバリ再開ポイントは%X/%08Xです" -#: access/transam/xlog.c:8372 +#: access/transam/xlog.c:8376 #, c-format msgid "Last completed transaction was at log time %s." msgstr "最後に完了したトランザクションはログ時刻 %s のものです" -#: access/transam/xlog.c:8636 +#: access/transam/xlog.c:8640 #, c-format msgid "restore point \"%s\" created at %X/%08X" msgstr "復帰ポイント\"%s\"が%X/%08Xに作成されました" -#: access/transam/xlog.c:8885 +#: access/transam/xlog.c:8889 #, c-format msgid "online backup was canceled, recovery cannot continue" msgstr "オンラインバックアップはキャンセルされ、リカバリを継続できません" -#: access/transam/xlog.c:8941 +#: access/transam/xlog.c:8945 #, c-format msgid "unexpected timeline ID %u (should be %u) in shutdown checkpoint record" msgstr "シャットダウンチェックポイントレコードにおいて想定外のタイムラインID %u(%uのはず)がありました" -#: access/transam/xlog.c:9002 +#: access/transam/xlog.c:9006 #, c-format msgid "unexpected timeline ID %u (should be %u) in online checkpoint record" msgstr "オンラインチェックポイントレコードにおいて想定外のタイムラインID %u(%uのはず)がありました" -#: access/transam/xlog.c:9039 +#: access/transam/xlog.c:9043 #, c-format msgid "unexpected timeline ID %u (should be %u) in end-of-recovery record" msgstr "リカバリ終了チェックポイントレコードにおいて想定外のタイムラインID %u(%uのはず)がありました" -#: access/transam/xlog.c:9389 +#: access/transam/xlog.c:9393 #, c-format msgid "could not fsync write-through file \"%s\": %m" msgstr "ライトスルーファイル\"%s\"をfsyncできませんでした: %m" -#: access/transam/xlog.c:9394 +#: access/transam/xlog.c:9398 #, c-format msgid "could not fdatasync file \"%s\": %m" msgstr "ファイル\"%s\"をfdatasyncできませんでした: %m" -#: access/transam/xlog.c:9470 access/transam/xlog.c:9800 +#: access/transam/xlog.c:9474 access/transam/xlog.c:9804 #, c-format msgid "WAL level not sufficient for making an online backup" msgstr "オンラインバックアップを行うにはWALレベルが不十分です" -#: access/transam/xlog.c:9471 access/transam/xlog.c:9801 access/transam/xlogfuncs.c:279 commands/subscriptioncmds.c:3053 +#: access/transam/xlog.c:9475 access/transam/xlog.c:9805 access/transam/xlogfuncs.c:279 commands/subscriptioncmds.c:3371 #, c-format msgid "\"wal_level\" must be set to \"replica\" or \"logical\" at server start." msgstr "サーバーの開始時に\"wal_level\"を\"replica\"または \"logical\"にセットする必要があります。" -#: access/transam/xlog.c:9476 +#: access/transam/xlog.c:9480 #, c-format msgid "backup label too long (max %d bytes)" msgstr "バックアップラベルが長すぎます (最大%dバイト)" -#: access/transam/xlog.c:9591 +#: access/transam/xlog.c:9595 #, c-format msgid "WAL generated with \"full_page_writes=off\" was replayed since last restartpoint" msgstr "\"full_page_writes=off\"で生成されたWALが最終リスタートポイント以降に再生されました" -#: access/transam/xlog.c:9593 access/transam/xlog.c:9889 +#: access/transam/xlog.c:9597 access/transam/xlog.c:9893 #, c-format msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable \"full_page_writes\" and run CHECKPOINT on the primary, and then try an online backup again." msgstr "つまりこのスタンバイで取得されたバックアップは破損しており、使用すべきではありません。プライマリで\"full_page_writes\"を有効にしCHECKPOINTを実行したのち、再度オンラインバックアップを試行してください。" -#: access/transam/xlog.c:9673 backup/basebackup.c:1421 catalog/pg_tablespace.c:80 +#: access/transam/xlog.c:9677 backup/basebackup.c:1419 catalog/pg_tablespace.c:80 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "シンボリックリンク\"%s\"を読めませんでした: %m" -#: access/transam/xlog.c:9680 backup/basebackup.c:1426 catalog/pg_tablespace.c:85 +#: access/transam/xlog.c:9684 backup/basebackup.c:1424 catalog/pg_tablespace.c:85 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "シンボリックリンク\"%s\"の参照先が長すぎます" -#: access/transam/xlog.c:9839 backup/basebackup.c:1285 +#: access/transam/xlog.c:9843 backup/basebackup.c:1283 #, c-format msgid "the standby was promoted during online backup" msgstr "オンラインバックアップ中にスタンバイが昇格しました" -#: access/transam/xlog.c:9840 backup/basebackup.c:1286 +#: access/transam/xlog.c:9844 backup/basebackup.c:1284 #, c-format msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." msgstr "つまり取得中のバックアップは破損しているため使用してはいけません。再度オンラインバックアップを取得してください。" -#: access/transam/xlog.c:9887 +#: access/transam/xlog.c:9891 #, c-format msgid "WAL generated with \"full_page_writes=off\" was replayed during online backup" msgstr "\"full_page_writes=off\"で生成されたWALがオンラインバックアップ中に再生されました" -#: access/transam/xlog.c:10003 +#: access/transam/xlog.c:10007 #, c-format msgid "base backup done, waiting for required WAL segments to be archived" msgstr "ベースバックアップ完了、必要な WAL セグメントがアーカイブされるのを待っています" -#: access/transam/xlog.c:10017 +#: access/transam/xlog.c:10021 #, c-format msgid "still waiting for all required WAL segments to be archived (%d seconds elapsed)" msgstr "まだ必要なすべての WAL セグメントがアーカイブされるのを待っています(%d 秒経過)" -#: access/transam/xlog.c:10019 +#: access/transam/xlog.c:10023 #, c-format msgid "Check that your \"archive_command\" is executing properly. You can safely cancel this backup, but the database backup will not be usable without all the WAL segments." msgstr "\"archive_command\"が正しく実行されていることを確認してください。バックアップ処理は安全に取り消すことができますが、全てのWALセグメントがそろわなければこのバックアップは利用できません。" -#: access/transam/xlog.c:10026 +#: access/transam/xlog.c:10030 #, c-format msgid "all required WAL segments have been archived" msgstr "必要なすべての WAL セグメントがアーカイブされました" -#: access/transam/xlog.c:10030 +#: access/transam/xlog.c:10034 #, c-format msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" msgstr "WAL アーカイブが有効になっていません。バックアップを完了させるには、すべての必要なWALセグメントが他の方法でコピーされたことを確認してください。" -#: access/transam/xlog.c:10069 +#: access/transam/xlog.c:10073 #, c-format msgid "aborting backup due to backend exiting before pg_backup_stop was called" msgstr "バックエンドがpg_backup_stopの呼び出し前に終了したため、バックアップは異常終了しました" @@ -5598,7 +5617,7 @@ msgstr "アーカイブステータスファイル\"%s\"を作成できません msgid "could not write archive status file \"%s\": %m" msgstr "アーカイブステータスファイル\"%s\"に書き込めませんでした: %m" -#: access/transam/xlogfuncs.c:100 backup/basebackup.c:1001 +#: access/transam/xlogfuncs.c:100 backup/basebackup.c:999 #, c-format msgid "a backup is already in progress in this session" msgstr "このセッションではすでにバックアップが進行中です" @@ -5689,7 +5708,7 @@ msgid "server did not promote within %d second" msgid_plural "server did not promote within %d seconds" msgstr[0] "サーバーは%d秒以内に昇格しませんでした" -#: access/transam/xlogprefetcher.c:1091 +#: access/transam/xlogprefetcher.c:1092 #, c-format msgid "\"recovery_prefetch\" is not supported on platforms that lack support for issuing read-ahead advice." msgstr "\"recovery_prefetch\"は先読み指示の発行をサポートしないプラットフォームではサポートされません。" @@ -5769,82 +5788,82 @@ msgstr "WALセグメント%3$s、LSN %4$X/%5$08X、オフセット%6$uで想定 msgid "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%08X, offset %u" msgstr "WALセグメント%3$s、LSN %4$X/%5$08X、オフセット%6$uで異常な順序のタイムラインID %1$u(%2$uの後)" -#: access/transam/xlogreader.c:1788 +#: access/transam/xlogreader.c:1790 #, c-format msgid "out-of-order block_id %u at %X/%08X" msgstr "block_id %uが%X/%08Xで不正です" -#: access/transam/xlogreader.c:1812 +#: access/transam/xlogreader.c:1814 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%08X" msgstr "BKPBLOCK_HAS_DATAが設定されていますが、%X/%08Xにデータがありません" -#: access/transam/xlogreader.c:1819 +#: access/transam/xlogreader.c:1821 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %d at %X/%08X" msgstr "BKPBLOCK_HAS_DATAが設定されていませんが、%2$X/%3$08Xのデータ長は%1$dです" -#: access/transam/xlogreader.c:1855 +#: access/transam/xlogreader.c:1857 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %d length %d block image length %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLEが設定されていますが、%4$X/%5$08Xでホールオフセット%1$d、長さ%2$d、ブロックイメージ長%3$dです" -#: access/transam/xlogreader.c:1871 +#: access/transam/xlogreader.c:1873 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %d length %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLEが設定されていませんが、%3$X/%4$08Xにおけるホールオフセット%1$dの長さが%2$dです" -#: access/transam/xlogreader.c:1885 +#: access/transam/xlogreader.c:1887 #, c-format msgid "BKPIMAGE_COMPRESSED set, but block image length %d at %X/%08X" msgstr "BKPIMAGE_COMPRESSEDが設定されていますが、%2$X/%3$08Xにおいてブロックイメージ長が%1$dです" -#: access/transam/xlogreader.c:1900 +#: access/transam/xlogreader.c:1902 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image length is %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLEもBKPIMAGE_COMPRESSEDも設定されていませんが、%2$X/%3$08Xにおいてブロックイメージ長が%1$dです" -#: access/transam/xlogreader.c:1916 +#: access/transam/xlogreader.c:1918 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%08X" msgstr "BKPBLOCK_SAME_RELが設定されていますが、%X/%08Xにおいて以前のリレーションがありません" -#: access/transam/xlogreader.c:1928 +#: access/transam/xlogreader.c:1930 #, c-format msgid "invalid block_id %u at %X/%08X" msgstr "%2$X/%3$08Xにおけるblock_id %1$uが不正です" -#: access/transam/xlogreader.c:1995 +#: access/transam/xlogreader.c:1997 #, c-format msgid "record with invalid length at %X/%08X" msgstr "%X/%08Xのレコード長が不正です" -#: access/transam/xlogreader.c:2021 +#: access/transam/xlogreader.c:2023 #, c-format msgid "could not locate backup block with ID %d in WAL record" msgstr "WALレコード中ID %dのバックアップブロックを特定できませんでした" -#: access/transam/xlogreader.c:2105 +#: access/transam/xlogreader.c:2107 #, c-format msgid "could not restore image at %X/%08X with invalid block %d specified" msgstr "%X/%08Xで不正なブロック%dが指定されているためイメージが復元できませんでした" -#: access/transam/xlogreader.c:2112 +#: access/transam/xlogreader.c:2114 #, c-format msgid "could not restore image at %X/%08X with invalid state, block %d" msgstr "%X/%08Xでブロック%dのイメージが不正な状態であるため復元できませんでした" -#: access/transam/xlogreader.c:2139 access/transam/xlogreader.c:2156 +#: access/transam/xlogreader.c:2141 access/transam/xlogreader.c:2158 #, c-format msgid "could not restore image at %X/%08X compressed with %s not supported by build, block %d" msgstr "%1$X/%2$08Xで、ブロック%4$dがこのビルドでサポートされない圧縮方式%3$sで圧縮されているため復元できませんでした" -#: access/transam/xlogreader.c:2165 +#: access/transam/xlogreader.c:2167 #, c-format msgid "could not restore image at %X/%08X compressed with unknown method, block %d" msgstr "%X/%08Xでブロック%dのイメージが未知の方式で圧縮されているため復元できませんでした" -#: access/transam/xlogreader.c:2173 +#: access/transam/xlogreader.c:2175 #, c-format msgid "could not decompress image at %X/%08X, block %d" msgstr "%X/%08Xのブロック%dが伸張できませんでした" @@ -6183,7 +6202,7 @@ msgstr "リカバリ完了位置で一時停止しています" msgid "Execute pg_wal_replay_resume() to promote." msgstr "再開するには pg_wal_replay_resume() を実行してください" -#: access/transam/xlogrecovery.c:2918 access/transam/xlogrecovery.c:4687 +#: access/transam/xlogrecovery.c:2918 access/transam/xlogrecovery.c:4689 #, c-format msgid "recovery has paused" msgstr "リカバリは一時停止中です" @@ -6198,153 +6217,153 @@ msgstr "再開するには pg_xlog_replay_resume() を実行してください" msgid "unexpected timeline ID %u in WAL segment %s, LSN %X/%08X, offset %u" msgstr "WALセグメント%2$s、LSN %3$X/%4$08X、オフセット%5$uで想定外のタイムラインID%1$u" -#: access/transam/xlogrecovery.c:3402 +#: access/transam/xlogrecovery.c:3404 #, c-format msgid "could not read from WAL segment %s, LSN %X/%08X, offset %u: %m" msgstr "WALセグメント%s、LSN %X/%08X、オフセット%uを読み取れませんでした: %m" -#: access/transam/xlogrecovery.c:3409 +#: access/transam/xlogrecovery.c:3411 #, c-format msgid "could not read from WAL segment %s, LSN %X/%08X, offset %u: read %d of %zu" msgstr "WALセグメント%1$s、LSN %2$X/%3$08X、オフセット%4$uを読み取れませんでした: %6$zu 中 %5$d の読み込み" -#: access/transam/xlogrecovery.c:4071 +#: access/transam/xlogrecovery.c:4073 #, c-format msgid "invalid checkpoint location" msgstr "不正なチェックポイント位置" -#: access/transam/xlogrecovery.c:4081 +#: access/transam/xlogrecovery.c:4083 #, c-format msgid "invalid checkpoint record" msgstr "チェックポイントレコードが不正です" -#: access/transam/xlogrecovery.c:4087 +#: access/transam/xlogrecovery.c:4089 #, c-format msgid "invalid resource manager ID in checkpoint record" msgstr "チェックポイントレコード内のリソースマネージャIDがで不正です" -#: access/transam/xlogrecovery.c:4095 +#: access/transam/xlogrecovery.c:4097 #, c-format msgid "invalid xl_info in checkpoint record" msgstr "チェックポイントレコード内のxl_infoが不正です" -#: access/transam/xlogrecovery.c:4101 +#: access/transam/xlogrecovery.c:4103 #, c-format msgid "invalid length of checkpoint record" msgstr "チェックポイントレコード長が不正です" -#: access/transam/xlogrecovery.c:4155 +#: access/transam/xlogrecovery.c:4157 #, c-format msgid "new timeline %u is not a child of database system timeline %u" msgstr "新しいタイムライン%uはデータベースシステムのタイムライン%uの子ではありません" -#: access/transam/xlogrecovery.c:4169 +#: access/transam/xlogrecovery.c:4171 #, c-format msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%08X" msgstr "新しいタイムライン%uは現在のデータベースシステムのタイムライン%uから現在のリカバリポイント%X/%08Xより前に分岐しています" -#: access/transam/xlogrecovery.c:4188 +#: access/transam/xlogrecovery.c:4190 #, c-format msgid "new target timeline is %u" msgstr "新しい目標タイムラインは%uです" -#: access/transam/xlogrecovery.c:4389 +#: access/transam/xlogrecovery.c:4391 #, c-format msgid "WAL receiver process shutdown requested" msgstr "wal receiverプロセスのシャットダウンが要求されました" -#: access/transam/xlogrecovery.c:4449 +#: access/transam/xlogrecovery.c:4451 #, c-format msgid "received promote request" msgstr "昇格要求を受信しました" -#: access/transam/xlogrecovery.c:4678 +#: access/transam/xlogrecovery.c:4680 #, c-format msgid "hot standby is not possible because of insufficient parameter settings" msgstr "不十分なパラメータ設定のため、ホットスタンバイを使用できません" -#: access/transam/xlogrecovery.c:4679 access/transam/xlogrecovery.c:4706 access/transam/xlogrecovery.c:4736 +#: access/transam/xlogrecovery.c:4681 access/transam/xlogrecovery.c:4708 access/transam/xlogrecovery.c:4738 #, c-format msgid "%s = %d is a lower setting than on the primary server, where its value was %d." msgstr "%s = %d はプライマリサーバーの設定値より小さいです、プライマリサーバーではこの値は%dでした。" -#: access/transam/xlogrecovery.c:4688 +#: access/transam/xlogrecovery.c:4690 #, c-format msgid "If recovery is unpaused, the server will shut down." msgstr "リカバリの一時停止を解除すると、サーバーはシャットダウンします。" -#: access/transam/xlogrecovery.c:4689 +#: access/transam/xlogrecovery.c:4691 #, c-format msgid "You can then restart the server after making the necessary configuration changes." msgstr "その後、必要な設定変更を行った後にサーバーを再起動できます。" -#: access/transam/xlogrecovery.c:4700 +#: access/transam/xlogrecovery.c:4702 #, c-format msgid "promotion is not possible because of insufficient parameter settings" msgstr "不十分なパラメータ設定のため、昇格できません" -#: access/transam/xlogrecovery.c:4710 +#: access/transam/xlogrecovery.c:4712 #, c-format msgid "Restart the server after making the necessary configuration changes." msgstr "必要な設定変更を行ったのち、サーバーを再起動してください。" -#: access/transam/xlogrecovery.c:4734 +#: access/transam/xlogrecovery.c:4736 #, c-format msgid "recovery aborted because of insufficient parameter settings" msgstr "不十分なパラメータ設定値のためリカバリが停止しました" -#: access/transam/xlogrecovery.c:4740 +#: access/transam/xlogrecovery.c:4742 #, c-format msgid "You can restart the server after making the necessary configuration changes." msgstr "必要な設定変更を行うことでサーバーを再起動できます。" -#: access/transam/xlogrecovery.c:4760 access/transam/xlogrecovery.c:4762 catalog/dependency.c:1219 catalog/dependency.c:1226 catalog/dependency.c:1237 commands/tablecmds.c:1580 commands/tablecmds.c:17023 commands/tablespace.c:468 commands/user.c:1309 commands/view.c:441 commands/wait.c:108 executor/execExprInterp.c:5285 executor/execExprInterp.c:5293 libpq/auth-oauth.c:700 libpq/auth.c:314 replication/logical/applyparallelworker.c:1060 replication/slot.c:1853 -#: replication/slot.c:2995 replication/slot.c:2997 replication/syncrep.c:1088 storage/aio/method_io_uring.c:399 storage/lmgr/deadlock.c:1137 storage/lmgr/proc.c:1533 utils/init/postinit.c:1547 utils/init/postinit.c:1548 utils/misc/guc.c:3063 utils/misc/guc.c:3104 utils/misc/guc.c:3188 utils/misc/guc.c:6703 utils/misc/guc.c:6737 utils/misc/guc.c:6771 utils/misc/guc.c:6814 utils/misc/guc.c:6856 +#: access/transam/xlogrecovery.c:4762 access/transam/xlogrecovery.c:4764 catalog/dependency.c:1219 catalog/dependency.c:1226 catalog/dependency.c:1237 commands/tablecmds.c:1587 commands/tablecmds.c:17280 commands/tablespace.c:468 commands/user.c:1309 commands/view.c:441 commands/wait.c:108 executor/execExprInterp.c:5285 executor/execExprInterp.c:5293 libpq/auth-oauth.c:700 libpq/auth.c:316 replication/logical/applyparallelworker.c:1060 replication/slot.c:1849 +#: replication/slot.c:2991 replication/slot.c:2993 replication/syncrep.c:1088 storage/aio/method_io_uring.c:399 storage/lmgr/deadlock.c:1137 storage/lmgr/proc.c:1566 utils/init/postinit.c:1557 utils/init/postinit.c:1558 utils/misc/guc.c:3063 utils/misc/guc.c:3104 utils/misc/guc.c:3188 utils/misc/guc.c:6703 utils/misc/guc.c:6737 utils/misc/guc.c:6771 utils/misc/guc.c:6814 utils/misc/guc.c:6856 #, c-format msgid "%s" msgstr "%s" -#: access/transam/xlogrecovery.c:4792 +#: access/transam/xlogrecovery.c:4794 #, c-format msgid "multiple recovery targets specified" msgstr "複数のリカバリ目標が指定されています" -#: access/transam/xlogrecovery.c:4793 +#: access/transam/xlogrecovery.c:4795 #, c-format msgid "At most one of \"recovery_target\", \"recovery_target_lsn\", \"recovery_target_name\", \"recovery_target_time\", \"recovery_target_xid\" may be set." msgstr "\" recovery_target\", \"recovery_target_lsn\", \"recovery_target_name\", \"recovery_target_time, recovery_target_xid\" はこの中の1つまで設定可能です。" -#: access/transam/xlogrecovery.c:4804 +#: access/transam/xlogrecovery.c:4806 #, c-format msgid "The only allowed value is \"immediate\"." msgstr "\"immediate\"のみが指定可能です。" -#: access/transam/xlogrecovery.c:4958 +#: access/transam/xlogrecovery.c:4960 #, c-format msgid "Timestamp out of range: \"%s\"." msgstr "timestampが範囲外です: \"%s\"。" -#: access/transam/xlogrecovery.c:5007 access/transam/xlogrecovery.c:5072 +#: access/transam/xlogrecovery.c:5009 access/transam/xlogrecovery.c:5074 #, c-format msgid "\"%s\" is not a valid number." msgstr "\"%s\"は数値として正しくありません。" -#: access/transam/xlogrecovery.c:5014 +#: access/transam/xlogrecovery.c:5016 #, c-format msgid "\"%s\" must be between %u and %u." msgstr "\"%s\"は%uと%uとの間でなければなりません。" -#: access/transam/xlogrecovery.c:5079 +#: access/transam/xlogrecovery.c:5081 #, c-format msgid "\"%s\" without epoch must be greater than or equal to %u." msgstr "起源を伴わない\"%s\"は%u以上でなければなりません。" -#: access/transam/xlogutils.c:1023 +#: access/transam/xlogutils.c:1059 #, c-format msgid "could not read from WAL segment %s, offset %d: %m" msgstr "WALセグメント%s、オフセット%dを読み取れませんでした: %m" -#: access/transam/xlogutils.c:1030 +#: access/transam/xlogutils.c:1066 #, c-format msgid "could not read from WAL segment %s, offset %d: read %d of %d" msgstr "WALセグメント%1$s、オフセット%2$dを読み取れませんでした: %4$d 中 %3$d 読み込みました" @@ -6430,113 +6449,113 @@ msgstr[0] "合計%lld個のデータチェックサム検証エラー" msgid "checksum verification failure during base backup" msgstr "ベースバックアップ中にチェックサム確認が失敗しました" -#: backup/basebackup.c:737 backup/basebackup.c:746 backup/basebackup.c:757 backup/basebackup.c:774 backup/basebackup.c:783 backup/basebackup.c:792 backup/basebackup.c:807 backup/basebackup.c:824 backup/basebackup.c:833 backup/basebackup.c:845 backup/basebackup.c:869 backup/basebackup.c:883 backup/basebackup.c:894 backup/basebackup.c:905 backup/basebackup.c:918 +#: backup/basebackup.c:735 backup/basebackup.c:744 backup/basebackup.c:755 backup/basebackup.c:772 backup/basebackup.c:781 backup/basebackup.c:790 backup/basebackup.c:805 backup/basebackup.c:822 backup/basebackup.c:831 backup/basebackup.c:843 backup/basebackup.c:867 backup/basebackup.c:881 backup/basebackup.c:892 backup/basebackup.c:903 backup/basebackup.c:916 #, c-format msgid "duplicate option \"%s\"" msgstr "\"%s\"オプションは重複しています" -#: backup/basebackup.c:765 +#: backup/basebackup.c:763 #, c-format msgid "unrecognized checkpoint type: \"%s\"" msgstr "認識されないチェックポイントタイプ: \"%s\"" -#: backup/basebackup.c:797 +#: backup/basebackup.c:795 #, c-format msgid "incremental backups cannot be taken unless WAL summarization is enabled" msgstr "WAL集約が有効でなければ差分バックアップは取得できません" -#: backup/basebackup.c:813 +#: backup/basebackup.c:811 #, c-format msgid "% is outside the valid range for parameter \"%s\" (%d .. %d)" msgstr "%はパラメータ\"%s\"の有効範囲外です (%d .. %d)" -#: backup/basebackup.c:858 +#: backup/basebackup.c:856 #, c-format msgid "unrecognized manifest option: \"%s\"" msgstr "認識できない目録オプション: \"%s\"" -#: backup/basebackup.c:909 +#: backup/basebackup.c:907 #, c-format msgid "unrecognized compression algorithm: \"%s\"" msgstr "認識できない圧縮アルゴリズム: \"%s\"" -#: backup/basebackup.c:925 +#: backup/basebackup.c:923 #, c-format msgid "unrecognized base backup option: \"%s\"" msgstr "認識できないベースバックアップオプション: \"%s\"" -#: backup/basebackup.c:936 +#: backup/basebackup.c:934 #, c-format msgid "manifest checksums require a backup manifest" msgstr "目録のチェックサムにはバックアップ目録が必要です" -#: backup/basebackup.c:945 +#: backup/basebackup.c:943 #, c-format msgid "target detail cannot be used without target" msgstr "ターゲット詳細はターゲットの指定なしでは指定できません" -#: backup/basebackup.c:954 backup/basebackup_target.c:218 +#: backup/basebackup.c:952 backup/basebackup_target.c:218 #, c-format msgid "target \"%s\" does not accept a target detail" msgstr "ターゲット\"%s\"はターゲット詳細を受け付けません" -#: backup/basebackup.c:965 +#: backup/basebackup.c:963 #, c-format msgid "compression detail cannot be specified unless compression is enabled" msgstr "圧縮詳細は圧縮が有効でない場合は指定できません" -#: backup/basebackup.c:978 +#: backup/basebackup.c:976 #, c-format msgid "invalid compression specification: %s" msgstr "不正な圧縮指定: %s" -#: backup/basebackup.c:1028 +#: backup/basebackup.c:1026 #, c-format msgid "must UPLOAD_MANIFEST before performing an incremental BASE_BACKUP" msgstr "差分のBASE_BACKUPの実行前にUPLOAD_MANIFESTを実行する必要があります" -#: backup/basebackup.c:1161 backup/basebackup.c:1362 +#: backup/basebackup.c:1159 backup/basebackup.c:1360 #, c-format msgid "could not stat file or directory \"%s\": %m" msgstr "\"%s\"というファイルまたはディレクトリの情報を取得できませんでした。: %m" -#: backup/basebackup.c:1548 +#: backup/basebackup.c:1546 #, c-format msgid "skipping special file \"%s\"" msgstr "スペシャルファイル\"%s\"をスキップしています" -#: backup/basebackup.c:1756 +#: backup/basebackup.c:1754 #, c-format msgid "could not verify checksum in file \"%s\", block %u: read buffer size %d and page size %d differ" msgstr "ファイル\"%s\"、ブロック%uでチェックサム検証に失敗しました: 読み込みバッファサイズ%dとページサイズ%dが異なっています" -#: backup/basebackup.c:1818 +#: backup/basebackup.c:1816 #, c-format msgid "file \"%s\" has a total of %d checksum verification failure" msgid_plural "file \"%s\" has a total of %d checksum verification failures" msgstr[0] "ファイル\"%s\"では合計%d個のチェックサムエラーが発生しました" -#: backup/basebackup.c:1936 +#: backup/basebackup.c:1934 #, c-format msgid "checksum verification failed in file \"%s\", block %u: calculated %X but expected %X" msgstr "ファイル\"%s\"のブロック%uでチェックサム検証が失敗しました: 計算されたチェックサムは%Xですが想定は%Xです" -#: backup/basebackup.c:1943 +#: backup/basebackup.c:1941 #, c-format msgid "further checksum verification failures in file \"%s\" will not be reported" msgstr "ファイル\"%s\"における以降のチェックサムエラーは報告されません" -#: backup/basebackup.c:2071 +#: backup/basebackup.c:2069 #, c-format msgid "file name too long for tar format: \"%s\"" msgstr "ファイル名がtarフォーマットに対して長すぎます: \"%s\"" -#: backup/basebackup.c:2077 +#: backup/basebackup.c:2075 #, c-format msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" msgstr "シンボリックリンクのリンク先tarのフォーマットにとって長すぎます: ファイル名 \"%s\", リンク先 \"%s\"" -#: backup/basebackup.c:2151 +#: backup/basebackup.c:2149 #, c-format msgid "could not read file \"%s\": read %zd of %zu" msgstr "ファイル\"%1$s\"を読み込めませんでした: %3$zuバイトのうち%2$zdバイトを読み込みました" @@ -6631,7 +6650,7 @@ msgstr "\"%s\"ロールの権限を持つロールのみが、サーバー上に msgid "relative path not allowed for backup stored on server" msgstr "サーバー上に格納されるバックアップでは相対パスは指定できません" -#: backup/basebackup_server.c:102 commands/dbcommands.c:481 commands/tablespace.c:159 commands/tablespace.c:175 commands/tablespace.c:601 commands/tablespace.c:646 replication/slot.c:2492 storage/file/copydir.c:59 +#: backup/basebackup_server.c:102 commands/dbcommands.c:481 commands/tablespace.c:159 commands/tablespace.c:175 commands/tablespace.c:601 commands/tablespace.c:646 replication/slot.c:2488 storage/file/copydir.c:59 #, c-format msgid "could not create directory \"%s\": %m" msgstr "ディレクトリ\"%s\"を作成できませんでした: %m" @@ -6641,7 +6660,7 @@ msgstr "ディレクトリ\"%s\"を作成できませんでした: %m" msgid "directory \"%s\" exists but is not empty" msgstr "ディレクトリ\"%s\"は存在しますが、空ではありません" -#: backup/basebackup_server.c:123 utils/init/postinit.c:1205 +#: backup/basebackup_server.c:123 utils/init/postinit.c:1211 #, c-format msgid "could not access directory \"%s\": %m" msgstr "ディレクトリ\"%s\"にアクセスできませんでした: %m" @@ -6653,8 +6672,8 @@ msgstr "ディスクの空き容量をチェックしてください。" #: backup/basebackup_server.c:179 backup/basebackup_server.c:272 #, c-format -msgid "could not write file \"%s\": wrote only %d of %zu bytes at offset %u" -msgstr "ファイル\"%1$s\"に書き込みできませんでした: オフセット%4$uで%3$zuバイト中%2$dバイト分のみを書き出しました" +msgid "could not write file \"%s\": wrote only %d of %zu bytes at offset %lld" +msgstr "ファイル\"%1$s\"に書き込みできませんでした: オフセット%4$lldで%3$zuバイト中%2$dバイト分のみを書き出しました" #: backup/basebackup_target.c:146 #, c-format @@ -6691,17 +6710,17 @@ msgstr "ファイル\"%1$s\"に書き込みできませんでした: オフセ msgid "invalid timeline %" msgstr "不正なタイムライン%" -#: bootstrap/bootstrap.c:280 postmaster/postmaster.c:631 tcop/postgres.c:3943 +#: bootstrap/bootstrap.c:280 postmaster/postmaster.c:631 tcop/postgres.c:4038 #, c-format msgid "--%s must be first argument" msgstr "--%sは最初の引数でなければなりません" -#: bootstrap/bootstrap.c:294 postmaster/postmaster.c:645 tcop/postgres.c:3957 +#: bootstrap/bootstrap.c:294 postmaster/postmaster.c:645 tcop/postgres.c:4052 #, c-format msgid "--%s requires a value" msgstr "--%sには値が必要です" -#: bootstrap/bootstrap.c:299 postmaster/postmaster.c:650 tcop/postgres.c:3962 +#: bootstrap/bootstrap.c:299 postmaster/postmaster.c:650 tcop/postgres.c:4057 #, c-format msgid "-c %s requires a value" msgstr "-c %sは値が必要です" @@ -6861,9 +6880,9 @@ msgstr "デフォルト権限を変更する権限がありません" msgid "cannot use IN SCHEMA clause when using %s" msgstr "%s を使っている時には IN SCHEMA 句は指定できません" -#: catalog/aclchk.c:1582 catalog/catalog.c:684 catalog/heap.c:2638 catalog/heap.c:2960 catalog/objectaddress.c:1623 catalog/pg_publication.c:689 commands/analyze.c:1061 commands/copy.c:1123 commands/propgraphcmds.c:539 commands/sequence.c:1660 commands/tablecmds.c:7876 commands/tablecmds.c:8054 commands/tablecmds.c:8255 commands/tablecmds.c:8384 commands/tablecmds.c:8538 commands/tablecmds.c:8632 commands/tablecmds.c:8735 commands/tablecmds.c:8888 -#: commands/tablecmds.c:8918 commands/tablecmds.c:9073 commands/tablecmds.c:9176 commands/tablecmds.c:9310 commands/tablecmds.c:9423 commands/tablecmds.c:14679 commands/tablecmds.c:14882 commands/tablecmds.c:15043 commands/tablecmds.c:16271 commands/tablecmds.c:19030 commands/trigger.c:949 parser/analyze.c:1351 parser/analyze.c:2984 parser/parse_relation.c:745 parser/parse_target.c:1075 parser/parse_type.c:144 parser/parse_utilcmd.c:3956 parser/parse_utilcmd.c:3996 -#: parser/parse_utilcmd.c:4038 statistics/attribute_stats.c:201 statistics/attribute_stats.c:638 utils/adt/acl.c:2966 utils/adt/ruleutils.c:3216 +#: catalog/aclchk.c:1582 catalog/catalog.c:711 catalog/heap.c:2641 catalog/heap.c:2963 catalog/objectaddress.c:1629 catalog/pg_publication.c:699 commands/analyze.c:1061 commands/copy.c:1123 commands/propgraphcmds.c:539 commands/sequence.c:1660 commands/tablecmds.c:7901 commands/tablecmds.c:8079 commands/tablecmds.c:8280 commands/tablecmds.c:8409 commands/tablecmds.c:8563 commands/tablecmds.c:8657 commands/tablecmds.c:8760 commands/tablecmds.c:8913 +#: commands/tablecmds.c:8943 commands/tablecmds.c:9098 commands/tablecmds.c:9201 commands/tablecmds.c:9335 commands/tablecmds.c:9448 commands/tablecmds.c:14936 commands/tablecmds.c:15139 commands/tablecmds.c:15300 commands/tablecmds.c:16528 commands/tablecmds.c:19293 commands/trigger.c:961 parser/analyze.c:1354 parser/analyze.c:2981 parser/parse_relation.c:777 parser/parse_target.c:1075 parser/parse_type.c:144 parser/parse_utilcmd.c:3952 parser/parse_utilcmd.c:3992 +#: parser/parse_utilcmd.c:4034 statistics/attribute_stats.c:201 statistics/attribute_stats.c:638 utils/adt/acl.c:2966 utils/adt/ruleutils.c:3216 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" msgstr "リレーション\"%2$s\"の列\"%1$s\"は存在しません" @@ -6873,12 +6892,12 @@ msgstr "リレーション\"%2$s\"の列\"%1$s\"は存在しません" msgid "\"%s\" is an index" msgstr "\"%s\"はインデックスです" -#: catalog/aclchk.c:1834 commands/tablecmds.c:16429 commands/tablecmds.c:19954 +#: catalog/aclchk.c:1834 commands/tablecmds.c:16686 commands/tablecmds.c:20241 #, c-format msgid "\"%s\" is a composite type" msgstr "\"%s\"は複合型です" -#: catalog/aclchk.c:1849 catalog/objectaddress.c:1456 commands/tablecmds.c:318 commands/tablecmds.c:19938 parser/parse_clause.c:927 utils/adt/ruleutils.c:1639 +#: catalog/aclchk.c:1849 catalog/objectaddress.c:1462 commands/tablecmds.c:318 commands/tablecmds.c:20225 parser/parse_clause.c:927 utils/adt/ruleutils.c:1639 #, c-format msgid "\"%s\" is not a property graph" msgstr "\"%s\"はプロパティ・グラフではありません" @@ -7288,69 +7307,69 @@ msgstr "リレーション\"%2$s\"の列\"%1$s\"へのアクセスが拒否さ msgid "attribute %d of relation with OID %u does not exist" msgstr "OID %2$uのリレーションに属性%1$dは存在しません" -#: catalog/aclchk.c:3271 catalog/aclchk.c:3334 catalog/aclchk.c:3991 +#: catalog/aclchk.c:3271 catalog/aclchk.c:3334 catalog/aclchk.c:4013 #, c-format msgid "relation with OID %u does not exist" msgstr "OID %uのリレーションは存在しません" -#: catalog/aclchk.c:3519 +#: catalog/aclchk.c:3533 #, c-format msgid "parameter ACL with OID %u does not exist" msgstr "OID %uのパラメータACLは存在しません" -#: catalog/aclchk.c:3598 catalog/objectaddress.c:1143 catalog/pg_largeobject.c:127 libpq/be-fsstubs.c:323 storage/large_object/inv_api.c:247 +#: catalog/aclchk.c:3612 catalog/objectaddress.c:1149 catalog/pg_largeobject.c:127 libpq/be-fsstubs.c:323 storage/large_object/inv_api.c:247 #, c-format msgid "large object %u does not exist" msgstr "ラージオブジェクト%uは存在しません" -#: catalog/aclchk.c:3710 commands/collationcmds.c:854 commands/publicationcmds.c:2030 +#: catalog/aclchk.c:3732 commands/collationcmds.c:854 commands/publicationcmds.c:2030 #, c-format msgid "schema with OID %u does not exist" msgstr "OID %uのスキーマは存在しません" -#: catalog/aclchk.c:3784 catalog/aclchk.c:3811 catalog/aclchk.c:3840 utils/cache/typcache.c:476 utils/cache/typcache.c:531 +#: catalog/aclchk.c:3806 catalog/aclchk.c:3833 catalog/aclchk.c:3862 utils/cache/typcache.c:485 utils/cache/typcache.c:540 #, c-format msgid "type with OID %u does not exist" msgstr "OID %uの型は存在しません" -#: catalog/catalog.c:504 +#: catalog/catalog.c:531 #, c-format msgid "still searching for an unused OID in relation \"%s\"" msgstr "リレーション\"%s\"での未使用のOIDを探索を継続中" -#: catalog/catalog.c:506 +#: catalog/catalog.c:533 #, c-format msgid "OID candidates have been checked % time, but no unused OID has been found yet." msgid_plural "OID candidates have been checked % times, but no unused OID has been found yet." msgstr[0] "OID候補のチェックを%回行いましたが、使用されていないOIDはまだ見つかっていません。" -#: catalog/catalog.c:531 +#: catalog/catalog.c:558 #, c-format msgid "new OID has been assigned in relation \"%s\" after % retry" msgid_plural "new OID has been assigned in relation \"%s\" after % retries" msgstr[0] "リレーション\\\"%s\\\"で%回の試行後に新しいOIDが割り当てられました" -#: catalog/catalog.c:662 catalog/catalog.c:729 +#: catalog/catalog.c:689 catalog/catalog.c:756 #, c-format msgid "must be superuser to call %s()" msgstr "%s()を呼び出すにはスーパーユーザーである必要があります" -#: catalog/catalog.c:671 +#: catalog/catalog.c:698 #, c-format msgid "pg_nextoid() can only be used on system catalogs" msgstr "pg_nextoid() はシステムカタログでのみ使用できます" -#: catalog/catalog.c:676 parser/parse_utilcmd.c:2453 +#: catalog/catalog.c:703 parser/parse_utilcmd.c:2453 #, c-format msgid "index \"%s\" does not belong to table \"%s\"" msgstr "インデックス\"%s\"はテーブル\"%s\"には属していません" -#: catalog/catalog.c:693 +#: catalog/catalog.c:720 #, c-format msgid "column \"%s\" is not of type oid" msgstr "列\"%s\"はoid型ではありません" -#: catalog/catalog.c:700 +#: catalog/catalog.c:727 #, c-format msgid "index \"%s\" is not the index for column \"%s\"" msgstr "インデックス\"%s\"は列\"%s\"に対するインデックスではありません" @@ -7423,12 +7442,12 @@ msgstr[0] "削除は他の%d個のオブジェクトに対しても行われま msgid "constant of the type %s cannot be used here" msgstr "%s型の定数をここで使用することはできません" -#: catalog/dependency.c:2320 +#: catalog/dependency.c:2339 #, c-format msgid "transition table \"%s\" cannot be referenced in a persistent object" msgstr "遷移テーブル\"%s\"は永続オブジェクトからは参照できません" -#: catalog/dependency.c:2505 parser/parse_relation.c:3598 parser/parse_relation.c:3608 statistics/attribute_stats.c:213 statistics/stat_utils.c:457 statistics/stat_utils.c:465 +#: catalog/dependency.c:2524 parser/parse_relation.c:3630 parser/parse_relation.c:3640 statistics/attribute_stats.c:213 statistics/stat_utils.c:457 statistics/stat_utils.c:465 #, c-format msgid "column %d of relation \"%s\" does not exist" msgstr "リレーション\"%2$s\"の列\"%1$d\"は存在しません" @@ -7443,12 +7462,12 @@ msgstr "\"%s.%s\"を作成する権限がありません" msgid "System catalog modifications are currently disallowed." msgstr "システムカタログの更新は現在禁止されています" -#: catalog/heap.c:464 commands/tablecmds.c:2630 commands/tablecmds.c:3081 commands/tablecmds.c:7461 +#: catalog/heap.c:464 commands/tablecmds.c:2639 commands/tablecmds.c:3102 commands/tablecmds.c:7511 #, c-format msgid "tables can have at most %d columns" msgstr "テーブルは最大で%d列までしか持てません" -#: catalog/heap.c:482 commands/tablecmds.c:7788 +#: catalog/heap.c:482 commands/tablecmds.c:7813 #, c-format msgid "column name \"%s\" conflicts with a system column name" msgstr "列名\"%s\"はシステム用の列名に使われています" @@ -7484,7 +7503,7 @@ msgstr "複合型 %s がそれ自身のメンバーになることはできま msgid "virtual generated column \"%s\" cannot have a user-defined type" msgstr "仮想生成列\"%s\"ではユーザー定義関数は使用できません" -#: catalog/heap.c:689 catalog/heap.c:3314 +#: catalog/heap.c:689 catalog/heap.c:3317 #, c-format msgid "Virtual generated columns that make use of user-defined types are not yet supported." msgstr "ユーザー定義型を使用した仮想生成列は未サポートです。" @@ -7500,182 +7519,182 @@ msgstr "照合可能な型 %2$s のパーティションキー列%1$sのため msgid "no collation was derived for column \"%s\" with collatable type %s" msgstr "照合可能な型 %2$s を持つ列\"%1$s\"のための照合順序を決定できませんでした" -#: catalog/heap.c:1194 catalog/index.c:906 commands/createas.c:408 commands/tablecmds.c:4363 commands/tablecmds.c:22789 commands/tablecmds.c:23350 commands/tablecmds.c:23780 +#: catalog/heap.c:1197 catalog/index.c:906 commands/createas.c:408 commands/tablecmds.c:4397 commands/tablecmds.c:23070 commands/tablecmds.c:23668 commands/tablecmds.c:24098 #, c-format msgid "relation \"%s\" already exists" msgstr "リレーション\"%s\"はすでに存在します" -#: catalog/heap.c:1210 catalog/pg_type.c:432 catalog/pg_type.c:803 catalog/pg_type.c:975 commands/typecmds.c:255 commands/typecmds.c:267 commands/typecmds.c:760 commands/typecmds.c:1215 commands/typecmds.c:1446 commands/typecmds.c:1633 commands/typecmds.c:2626 +#: catalog/heap.c:1213 catalog/pg_type.c:432 catalog/pg_type.c:803 catalog/pg_type.c:975 commands/typecmds.c:255 commands/typecmds.c:267 commands/typecmds.c:760 commands/typecmds.c:1215 commands/typecmds.c:1446 commands/typecmds.c:1633 commands/typecmds.c:2626 #, c-format msgid "type \"%s\" already exists" msgstr "型\"%s\"はすでに存在します" -#: catalog/heap.c:1211 +#: catalog/heap.c:1214 #, c-format msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." msgstr "リレーションは同じ名前の関連する型を持ちます。このため既存の型と競合しない名前である必要があります。" -#: catalog/heap.c:1251 +#: catalog/heap.c:1254 #, c-format msgid "toast relfilenumber value not set when in binary upgrade mode" msgstr "バイナリアップグレードモード中にTOASTのrelfilenumberの値が設定されていません" -#: catalog/heap.c:1262 +#: catalog/heap.c:1265 #, c-format msgid "pg_class heap OID value not set when in binary upgrade mode" msgstr "バイナリアップグレードモード中にpg_classのヒープOIDが設定されていません" -#: catalog/heap.c:1272 +#: catalog/heap.c:1275 #, c-format msgid "relfilenumber value not set when in binary upgrade mode" msgstr "バイナリアップグレードモード中にrelfilenumberの値が設定されていません" -#: catalog/heap.c:2219 +#: catalog/heap.c:2222 #, c-format msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" msgstr "パーティション親テーブル\"%s\"に NO INHERIT 制約は追加できません" -#: catalog/heap.c:2542 +#: catalog/heap.c:2545 #, c-format msgid "check constraint \"%s\" already exists" msgstr "検査制約\"%s\"はすでに存在します" -#: catalog/heap.c:2643 catalog/heap.c:2966 +#: catalog/heap.c:2646 catalog/heap.c:2969 #, c-format msgid "cannot add not-null constraint on system column \"%s\"" msgstr "システム列\"%s\"に対して非NULL制約を追加することはできません" -#: catalog/heap.c:2671 catalog/heap.c:2797 catalog/heap.c:3050 catalog/index.c:920 catalog/pg_constraint.c:1027 commands/tablecmds.c:9934 +#: catalog/heap.c:2674 catalog/heap.c:2800 catalog/heap.c:3053 catalog/index.c:920 catalog/pg_constraint.c:1027 commands/tablecmds.c:9959 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" msgstr "すでに制約\"%s\"はリレーション\"%s\"に存在します" -#: catalog/heap.c:2804 +#: catalog/heap.c:2807 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" msgstr "制約\"%s\"は、リレーション\"%s\"上の継承されていない制約と競合します" -#: catalog/heap.c:2815 +#: catalog/heap.c:2818 #, c-format msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" msgstr "制約\"%s\"は、リレーション\"%s\"上の継承された制約と競合します" -#: catalog/heap.c:2825 +#: catalog/heap.c:2828 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" msgstr "制約\"%s\"は、リレーション\"%s\"上の NOT VALID 制約と競合します" -#: catalog/heap.c:2837 +#: catalog/heap.c:2840 #, c-format msgid "constraint \"%s\" conflicts with NOT ENFORCED constraint on relation \"%s\"" msgstr "制約\"%s\"は、リレーション\"%s\"上の \\NOT ENFORCED制約と競合します" -#: catalog/heap.c:2842 +#: catalog/heap.c:2845 #, c-format msgid "merging constraint \"%s\" with inherited definition" msgstr "継承された定義により制約\"%s\"をマージしています" -#: catalog/heap.c:2866 catalog/pg_constraint.c:803 catalog/pg_constraint.c:1156 commands/tablecmds.c:3246 commands/tablecmds.c:3566 commands/tablecmds.c:7386 commands/tablecmds.c:8092 commands/tablecmds.c:17862 commands/tablecmds.c:18044 +#: catalog/heap.c:2869 catalog/pg_constraint.c:803 catalog/pg_constraint.c:1156 commands/tablecmds.c:3267 commands/tablecmds.c:3587 commands/tablecmds.c:7436 commands/tablecmds.c:8117 commands/tablecmds.c:18125 commands/tablecmds.c:18307 #, c-format msgid "too many inheritance parents" msgstr "継承の親テーブルが多すぎます" -#: catalog/heap.c:2985 parser/parse_utilcmd.c:2661 +#: catalog/heap.c:2988 parser/parse_utilcmd.c:2661 #, c-format msgid "conflicting NO INHERIT declaration for not-null constraint on column \"%s\"" msgstr "列\"%s\"に対する非NULL制約にNO INHERIT宣言が競合しています" -#: catalog/heap.c:2999 +#: catalog/heap.c:3002 #, c-format msgid "conflicting not-null constraint names \"%s\" and \"%s\"" msgstr "非NULL制約の名前\"%s\"と\"%s\"が競合しています" -#: catalog/heap.c:3029 +#: catalog/heap.c:3032 #, c-format msgid "cannot define not-null constraint with NO INHERIT on column \"%s\"" msgstr "列\"%s\"に対して非NULL制約をNO INHERITと同時に定義することはできません" -#: catalog/heap.c:3031 +#: catalog/heap.c:3034 #, c-format msgid "The column has an inherited not-null constraint." msgstr "この列には継承された非NULL制約が存在します。" -#: catalog/heap.c:3221 +#: catalog/heap.c:3224 #, c-format msgid "cannot use generated column \"%s\" in column generation expression" msgstr "生成カラム\"%s\"はカラム生成式中では使用できません" -#: catalog/heap.c:3223 +#: catalog/heap.c:3226 #, c-format msgid "A generated column cannot reference another generated column." msgstr "生成カラムは他の生成カラムを参照できません。" -#: catalog/heap.c:3229 +#: catalog/heap.c:3232 #, c-format msgid "cannot use whole-row variable in column generation expression" msgstr "列生成式内では行全体参照は使用できません" -#: catalog/heap.c:3230 +#: catalog/heap.c:3233 #, c-format msgid "This would cause the generated column to depend on its own value." msgstr "これは生成列を自身の値に依存させることにつながります。" -#: catalog/heap.c:3297 +#: catalog/heap.c:3300 #, c-format msgid "generation expression uses user-defined function" msgstr "生成式でユーザー定義関数が使用されています" -#: catalog/heap.c:3298 +#: catalog/heap.c:3301 #, c-format msgid "Virtual generated columns that make use of user-defined functions are not yet supported." msgstr "ユーザー定義関数を使用した仮想生成列は未サポートです。" -#: catalog/heap.c:3313 +#: catalog/heap.c:3316 #, c-format msgid "generation expression uses user-defined type" msgstr "生成式でユーザー定義型が使用されています" -#: catalog/heap.c:3365 +#: catalog/heap.c:3368 #, c-format msgid "generation expression is not immutable" msgstr "生成式は不変ではありません" -#: catalog/heap.c:3397 rewrite/rewriteHandler.c:1337 +#: catalog/heap.c:3400 rewrite/rewriteHandler.c:1337 #, c-format msgid "column \"%s\" is of type %s but default expression is of type %s" msgstr "列\"%s\"の型は%sですが、デフォルト式の型は%sです" -#: catalog/heap.c:3402 commands/prepare.c:336 parser/analyze.c:3350 parser/parse_target.c:600 parser/parse_target.c:890 parser/parse_target.c:900 rewrite/rewriteHandler.c:1342 +#: catalog/heap.c:3405 commands/prepare.c:336 parser/analyze.c:3347 parser/parse_target.c:600 parser/parse_target.c:890 parser/parse_target.c:900 rewrite/rewriteHandler.c:1342 #, c-format msgid "You will need to rewrite or cast the expression." msgstr "式を書き換えるかキャストする必要があります。" -#: catalog/heap.c:3449 +#: catalog/heap.c:3452 #, c-format msgid "only table \"%s\" can be referenced in check constraint" msgstr "検査制約ではテーブル\"%s\"のみを参照することができます" -#: catalog/heap.c:3756 +#: catalog/heap.c:3759 #, c-format msgid "unsupported ON COMMIT and foreign key combination" msgstr "ON COMMITと外部キーの組み合わせはサポートされていません" -#: catalog/heap.c:3757 +#: catalog/heap.c:3760 #, c-format msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." msgstr "テーブル\"%s\"は\"%s\"を参照します。しかし、これらのON COMMIT設定は同一ではありません。" -#: catalog/heap.c:3762 +#: catalog/heap.c:3765 #, c-format msgid "cannot truncate a table referenced in a foreign key constraint" msgstr "外部キー制約で参照されているテーブルを削除できません" -#: catalog/heap.c:3763 +#: catalog/heap.c:3766 #, c-format msgid "Table \"%s\" references \"%s\"." msgstr "テーブル\"%s\"は\"%s\"を参照します。" -#: catalog/heap.c:3765 +#: catalog/heap.c:3768 #, c-format msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." msgstr "同時にテーブル\"%s\"がtruncateされました。TRUNCATE ... CASCADEを使用してください。" @@ -7735,7 +7754,7 @@ msgstr "リレーション\"%s\"はすでに存在します、スキップしま msgid "pg_class index OID value not set when in binary upgrade mode" msgstr "バイナリアップグレードモード中にpg_classのインデックスOIDが設定されていません" -#: catalog/index.c:958 utils/cache/relcache.c:3797 +#: catalog/index.c:958 utils/cache/relcache.c:3799 #, c-format msgid "index relfilenumber value not set when in binary upgrade mode" msgstr "バイナリアップグレードモード中にインデックスのrelfilenumberの値が設定されていません" @@ -7750,12 +7769,12 @@ msgstr "DROP INDEX CONCURRENTLYはトランザクション内で最初の操作 msgid "cannot reindex temporary tables of other sessions" msgstr "他のセッションの一時テーブルはインデクス再構築できません" -#: catalog/index.c:3761 commands/indexcmds.c:3819 +#: catalog/index.c:3761 commands/indexcmds.c:3944 #, c-format msgid "cannot reindex invalid index on TOAST table" msgstr "TOASTテーブルの無効なインデックスの再作成はできません" -#: catalog/index.c:3777 commands/indexcmds.c:3697 commands/indexcmds.c:3843 commands/tablecmds.c:3770 +#: catalog/index.c:3777 commands/indexcmds.c:3822 commands/indexcmds.c:3968 commands/tablecmds.c:3791 #, c-format msgid "cannot move system relation \"%s\"" msgstr "システムリレーション\"%s\"を移動できません" @@ -7770,7 +7789,7 @@ msgstr "インデックス\"%s\"のインデックス再構築が完了しまし msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" msgstr "TOASTテーブルの無効なインデックス \"%s.%s\"の再作成はできません、スキップします " -#: catalog/namespace.c:463 catalog/namespace.c:667 catalog/namespace.c:759 commands/trigger.c:5897 +#: catalog/namespace.c:463 catalog/namespace.c:667 catalog/namespace.c:759 commands/trigger.c:5922 #, c-format msgid "cross-database references are not implemented: \"%s.%s.%s\"" msgstr "データベース間の参照は実装されていません: \"%s.%s.%s\"" @@ -7785,22 +7804,22 @@ msgstr "一時テーブルにはスキーマ名を指定できません" msgid "could not obtain lock on relation \"%s.%s\"" msgstr "リレーション\"%s.%s\"のロックを取得できませんでした" -#: catalog/namespace.c:606 commands/lockcmds.c:143 commands/lockcmds.c:223 +#: catalog/namespace.c:606 commands/lockcmds.c:155 commands/lockcmds.c:245 #, c-format msgid "could not obtain lock on relation \"%s\"" msgstr "リレーション\"%s\"のロックを取得できませんでした" -#: catalog/namespace.c:634 parser/parse_relation.c:1439 +#: catalog/namespace.c:634 parser/parse_relation.c:1471 #, c-format msgid "relation \"%s.%s\" does not exist" msgstr "リレーション\"%s.%s\"は存在しません" -#: catalog/namespace.c:639 parser/parse_relation.c:1452 parser/parse_relation.c:1460 utils/adt/regproc.c:921 +#: catalog/namespace.c:639 parser/parse_relation.c:1484 parser/parse_relation.c:1492 utils/adt/regproc.c:921 #, c-format msgid "relation \"%s\" does not exist" msgstr "リレーション\"%s\"は存在しません" -#: catalog/namespace.c:705 catalog/namespace.c:3594 commands/extension.c:1986 commands/extension.c:1992 +#: catalog/namespace.c:705 catalog/namespace.c:3594 commands/extension.c:1988 commands/extension.c:1994 #, c-format msgid "no schema has been selected to create in" msgstr "作成先のスキーマが選択されていません" @@ -7810,7 +7829,7 @@ msgstr "作成先のスキーマが選択されていません" msgid "cannot create relations in temporary schemas of other sessions" msgstr "他のセッションの一時スキーマの中にリレーションを作成できません" -#: catalog/namespace.c:861 parser/parse_utilcmd.c:4598 +#: catalog/namespace.c:861 parser/parse_utilcmd.c:4594 #, c-format msgid "cannot create temporary relation in non-temporary schema" msgstr "非一時スキーマの中に一時リレーションを作成できません" @@ -7865,7 +7884,7 @@ msgstr "一時スキーマへ、または一時スキーマからオブジェク msgid "cannot move objects into or out of TOAST schema" msgstr "TOASTスキーマへ、またはTOASTスキーマからオブジェクトを移動できません" -#: catalog/namespace.c:3616 commands/schemacmds.c:265 commands/schemacmds.c:345 commands/tablecmds.c:1525 utils/adt/regproc.c:1696 +#: catalog/namespace.c:3616 commands/schemacmds.c:265 commands/schemacmds.c:345 commands/tablecmds.c:1532 utils/adt/regproc.c:1696 #, c-format msgid "schema \"%s\" does not exist" msgstr "スキーマ\"%s\"は存在しません" @@ -7900,235 +7919,235 @@ msgstr "リカバリ中は一時テーブルを作成できません" msgid "cannot create temporary tables during a parallel operation" msgstr "並行処理中は一時テーブルを作成できません" -#: catalog/objectaddress.c:1471 commands/policy.c:93 commands/policy.c:373 commands/tablecmds.c:264 commands/tablecmds.c:306 commands/tablecmds.c:2452 commands/tablecmds.c:14817 parser/parse_utilcmd.c:3541 +#: catalog/objectaddress.c:1477 commands/policy.c:105 commands/policy.c:385 commands/tablecmds.c:264 commands/tablecmds.c:306 commands/tablecmds.c:2459 commands/tablecmds.c:15074 parser/parse_utilcmd.c:3537 #, c-format msgid "\"%s\" is not a table" msgstr "\"%s\"はテーブルではありません" -#: catalog/objectaddress.c:1478 commands/tablecmds.c:276 commands/tablecmds.c:19918 commands/view.c:112 +#: catalog/objectaddress.c:1484 commands/tablecmds.c:276 commands/tablecmds.c:20205 commands/view.c:112 #, c-format msgid "\"%s\" is not a view" msgstr "\"%s\"はビューではありません" -#: catalog/objectaddress.c:1485 commands/matview.c:200 commands/tablecmds.c:282 commands/tablecmds.c:19923 +#: catalog/objectaddress.c:1491 commands/matview.c:200 commands/tablecmds.c:282 commands/tablecmds.c:20210 #, c-format msgid "\"%s\" is not a materialized view" msgstr "\"%s\"は実体化ビューではありません" -#: catalog/objectaddress.c:1492 commands/tablecmds.c:300 commands/tablecmds.c:19928 +#: catalog/objectaddress.c:1498 commands/tablecmds.c:300 commands/tablecmds.c:20215 #, c-format msgid "\"%s\" is not a foreign table" msgstr "\"%s\"は外部テーブルではありません" -#: catalog/objectaddress.c:1533 +#: catalog/objectaddress.c:1539 #, c-format msgid "must specify relation and object name" msgstr "リレーションとオブジェクトの名前の指定が必要です" -#: catalog/objectaddress.c:1609 catalog/objectaddress.c:1662 +#: catalog/objectaddress.c:1615 catalog/objectaddress.c:1668 #, c-format msgid "column name must be qualified" msgstr "列名を修飾する必要があります" -#: catalog/objectaddress.c:1681 +#: catalog/objectaddress.c:1687 #, c-format msgid "default value for column \"%s\" of relation \"%s\" does not exist" msgstr "リレーション\"%2$s\"の列\"%1$s\"に対するデフォルト値が存在しません" -#: catalog/objectaddress.c:1718 commands/functioncmds.c:133 commands/tablecmds.c:292 commands/typecmds.c:280 commands/typecmds.c:3893 parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:801 utils/adt/acl.c:4603 +#: catalog/objectaddress.c:1724 commands/functioncmds.c:133 commands/tablecmds.c:292 commands/typecmds.c:280 commands/typecmds.c:3883 parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:801 utils/adt/acl.c:4603 #, c-format msgid "type \"%s\" does not exist" msgstr "型\"%s\"は存在しません" -#: catalog/objectaddress.c:1729 +#: catalog/objectaddress.c:1735 #, c-format msgid "\"%s\" is not a domain" msgstr "\"%s\"はドメインではありません" -#: catalog/objectaddress.c:1837 +#: catalog/objectaddress.c:1843 #, c-format msgid "operator %d (%s, %s) of %s does not exist" msgstr "%4$sの演算子 %1$d (%2$s, %3$s) がありません" -#: catalog/objectaddress.c:1868 +#: catalog/objectaddress.c:1874 #, c-format msgid "function %d (%s, %s) of %s does not exist" msgstr "%4$s の関数 %1$d (%2$s, %3$s) がありません" -#: catalog/objectaddress.c:1919 catalog/objectaddress.c:1945 +#: catalog/objectaddress.c:1925 catalog/objectaddress.c:1951 #, c-format msgid "user mapping for user \"%s\" on server \"%s\" does not exist" msgstr "ユーザー\"%s\"に対するユーザーマッピングがサーバー\"%s\"には存在しません" -#: catalog/objectaddress.c:1934 commands/foreigncmds.c:441 commands/foreigncmds.c:1099 commands/foreigncmds.c:1462 foreign/foreign.c:745 +#: catalog/objectaddress.c:1940 commands/foreigncmds.c:441 commands/foreigncmds.c:1099 commands/foreigncmds.c:1462 foreign/foreign.c:745 #, c-format msgid "server \"%s\" does not exist" msgstr "サーバー\"%s\"は存在しません" -#: catalog/objectaddress.c:2001 +#: catalog/objectaddress.c:2007 #, c-format msgid "publication relation \"%s\" in publication \"%s\" does not exist" msgstr "パブリケーション\"%2$s\"にパブリケーションリレーション\"%1$s\"は存在しません" -#: catalog/objectaddress.c:2048 +#: catalog/objectaddress.c:2054 #, c-format msgid "publication schema \"%s\" in publication \"%s\" does not exist" msgstr "パブリケーション\"%2$s\"にパブリケーションスキーマ\"%1$s\"は存在しません" -#: catalog/objectaddress.c:2109 +#: catalog/objectaddress.c:2115 #, c-format msgid "unrecognized default ACL object type \"%c\"" msgstr "デフォルトのACLオブジェクトタイプ\"%c\"は認識できません" -#: catalog/objectaddress.c:2110 +#: catalog/objectaddress.c:2116 #, c-format msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." msgstr "有効なオブジェクトタイプは \"%c\"、\"%c\"、\"%c\"、\"%c\"、\"%c\"、\"%c\" です。" -#: catalog/objectaddress.c:2162 +#: catalog/objectaddress.c:2168 #, c-format msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" msgstr "ユーザー\"%s\"に対する、名前空間\"%s\"の%sへのデフォルトのACLはありません" -#: catalog/objectaddress.c:2167 +#: catalog/objectaddress.c:2173 #, c-format msgid "default ACL for user \"%s\" on %s does not exist" msgstr "ユーザー\"%s\"に対する%sへのデフォルトACLは存在しません" -#: catalog/objectaddress.c:2193 catalog/objectaddress.c:2250 catalog/objectaddress.c:2305 +#: catalog/objectaddress.c:2199 catalog/objectaddress.c:2256 catalog/objectaddress.c:2311 #, c-format msgid "name or argument lists may not contain nulls" msgstr "名前または引数のリストはnullを含むことができません" -#: catalog/objectaddress.c:2227 +#: catalog/objectaddress.c:2233 #, c-format msgid "unsupported object type \"%s\"" msgstr "サポートされないオブジェクトタイプ\"%s\"" -#: catalog/objectaddress.c:2246 catalog/objectaddress.c:2263 catalog/objectaddress.c:2328 catalog/objectaddress.c:2413 +#: catalog/objectaddress.c:2252 catalog/objectaddress.c:2269 catalog/objectaddress.c:2334 catalog/objectaddress.c:2419 #, c-format msgid "name list length must be exactly %d" msgstr "名前リストの長さは正確に%dでなくてはなりません" -#: catalog/objectaddress.c:2267 +#: catalog/objectaddress.c:2273 #, c-format msgid "large object OID may not be null" msgstr "ラージオブジェクトのOIDはnullにはなり得ません" -#: catalog/objectaddress.c:2276 catalog/objectaddress.c:2346 catalog/objectaddress.c:2353 +#: catalog/objectaddress.c:2282 catalog/objectaddress.c:2352 catalog/objectaddress.c:2359 #, c-format msgid "name list length must be at least %d" msgstr "名前リストの長さは%d以上でなくてはなりません" -#: catalog/objectaddress.c:2339 catalog/objectaddress.c:2360 +#: catalog/objectaddress.c:2345 catalog/objectaddress.c:2366 #, c-format msgid "argument list length must be exactly %d" msgstr "引数リストの長さはちょうど%dである必要があります" -#: catalog/objectaddress.c:2576 libpq/be-fsstubs.c:334 +#: catalog/objectaddress.c:2582 libpq/be-fsstubs.c:334 #, c-format msgid "must be owner of large object %u" msgstr "ラージオブジェクト %u の所有者である必要があります" -#: catalog/objectaddress.c:2591 commands/functioncmds.c:1581 +#: catalog/objectaddress.c:2597 commands/functioncmds.c:1581 #, c-format msgid "must be owner of type %s or type %s" msgstr "型%sまたは型%sの所有者である必要があります" -#: catalog/objectaddress.c:2618 catalog/objectaddress.c:2627 catalog/objectaddress.c:2633 +#: catalog/objectaddress.c:2624 catalog/objectaddress.c:2633 catalog/objectaddress.c:2639 #, c-format msgid "permission denied" msgstr "権限がありません" -#: catalog/objectaddress.c:2619 catalog/objectaddress.c:2628 +#: catalog/objectaddress.c:2625 catalog/objectaddress.c:2634 #, c-format msgid "The current user must have the %s attribute." msgstr "現在のユーザーは%s属性を持つ必要があります。" -#: catalog/objectaddress.c:2634 +#: catalog/objectaddress.c:2640 #, c-format msgid "The current user must have the %s option on role \"%s\"." msgstr "現在のユーザーはロール\"%2$s\"に対する%1$sオプションを持っている必要があります。" -#: catalog/objectaddress.c:2648 +#: catalog/objectaddress.c:2654 #, c-format msgid "must be superuser" msgstr "スーパーユーザーである必要があります" -#: catalog/objectaddress.c:2717 +#: catalog/objectaddress.c:2723 #, c-format msgid "unrecognized object type \"%s\"" msgstr "認識されないオブジェクトタイプ\"%s\"" #. translator: second %s is, e.g., "table %s" -#: catalog/objectaddress.c:3034 +#: catalog/objectaddress.c:3040 #, c-format msgid "column %s of %s" msgstr "%2$s の列 %1$s" -#: catalog/objectaddress.c:3049 +#: catalog/objectaddress.c:3055 #, c-format msgid "function %s" msgstr "関数%s" -#: catalog/objectaddress.c:3062 +#: catalog/objectaddress.c:3068 #, c-format msgid "type %s" msgstr "型%s" -#: catalog/objectaddress.c:3099 +#: catalog/objectaddress.c:3105 #, c-format msgid "cast from %s to %s" msgstr "%sから%sへの型変換" -#: catalog/objectaddress.c:3132 +#: catalog/objectaddress.c:3138 #, c-format msgid "collation %s" msgstr "照合順序%s" #. translator: second %s is, e.g., "table %s" -#: catalog/objectaddress.c:3163 +#: catalog/objectaddress.c:3169 #, c-format msgid "constraint %s on %s" msgstr "%2$sに対する制約%1$s" -#: catalog/objectaddress.c:3169 +#: catalog/objectaddress.c:3175 #, c-format msgid "constraint %s" msgstr "制約%s" -#: catalog/objectaddress.c:3201 +#: catalog/objectaddress.c:3207 #, c-format msgid "conversion %s" msgstr "変換%s" #. translator: %s is typically "column %s of table %s" -#: catalog/objectaddress.c:3223 +#: catalog/objectaddress.c:3229 #, c-format msgid "default value for %s" msgstr "%s のデフォルト値" -#: catalog/objectaddress.c:3234 +#: catalog/objectaddress.c:3240 #, c-format msgid "language %s" msgstr "言語%s" -#: catalog/objectaddress.c:3242 +#: catalog/objectaddress.c:3248 #, c-format msgid "large object %u" msgstr "ラージオブジェクト%u" -#: catalog/objectaddress.c:3255 +#: catalog/objectaddress.c:3261 #, c-format msgid "operator %s" msgstr "演算子%s" -#: catalog/objectaddress.c:3292 +#: catalog/objectaddress.c:3298 #, c-format msgid "operator class %s for access method %s" msgstr "アクセスメソッド%2$s用の演算子クラス%1$s" -#: catalog/objectaddress.c:3320 +#: catalog/objectaddress.c:3326 #, c-format msgid "access method %s" msgstr "アクセスメソッド%s" @@ -8137,7 +8156,7 @@ msgstr "アクセスメソッド%s" #. first two %s's are data type names, the third %s is the #. description of the operator family, and the last %s is the #. textual form of the operator with arguments. -#: catalog/objectaddress.c:3375 +#: catalog/objectaddress.c:3381 #, c-format msgid "operator %d (%s, %s) of %s: %s" msgstr "%4$sの演算子%1$d (%2$s, %3$s): %5$s" @@ -8146,270 +8165,266 @@ msgstr "%4$sの演算子%1$d (%2$s, %3$s): %5$s" #. are data type names, the third %s is the description of the #. operator family, and the last %s is the textual form of the #. function with arguments. -#: catalog/objectaddress.c:3440 +#: catalog/objectaddress.c:3446 #, c-format msgid "function %d (%s, %s) of %s: %s" msgstr "%4$s の関数 %1$d (%2$s, %3$s): %5$s" #. translator: second %s is, e.g., "table %s" -#: catalog/objectaddress.c:3494 +#: catalog/objectaddress.c:3500 #, c-format msgid "rule %s on %s" msgstr "%2$s のルール %1$s" #. translator: second %s is, e.g., "table %s" -#: catalog/objectaddress.c:3540 +#: catalog/objectaddress.c:3546 #, c-format msgid "trigger %s on %s" msgstr "%2$s のトリガー %1$s" -#: catalog/objectaddress.c:3560 +#: catalog/objectaddress.c:3566 #, c-format msgid "schema %s" msgstr "スキーマ%s" -#: catalog/objectaddress.c:3588 +#: catalog/objectaddress.c:3594 #, c-format msgid "statistics object %s" msgstr "統計オブジェクト%s" -#: catalog/objectaddress.c:3619 +#: catalog/objectaddress.c:3625 #, c-format msgid "text search parser %s" msgstr "テキスト検索パーサ%s" -#: catalog/objectaddress.c:3650 +#: catalog/objectaddress.c:3656 #, c-format msgid "text search dictionary %s" msgstr "テキスト検索辞書%s" -#: catalog/objectaddress.c:3681 +#: catalog/objectaddress.c:3687 #, c-format msgid "text search template %s" msgstr "テキスト検索テンプレート%s" -#: catalog/objectaddress.c:3712 +#: catalog/objectaddress.c:3718 #, c-format msgid "text search configuration %s" msgstr "テキスト検索設定%s" -#: catalog/objectaddress.c:3725 +#: catalog/objectaddress.c:3731 #, c-format msgid "role %s" msgstr "ロール%s" -#: catalog/objectaddress.c:3762 catalog/objectaddress.c:5839 +#: catalog/objectaddress.c:3768 #, c-format msgid "membership of role %s in role %s" msgstr "ロール%sのロール%sへの所属" -#: catalog/objectaddress.c:3783 +#: catalog/objectaddress.c:3789 #, c-format msgid "database %s" msgstr "データベース%s" -#: catalog/objectaddress.c:3799 +#: catalog/objectaddress.c:3805 #, c-format msgid "tablespace %s" msgstr "テーブル空間%s" -#: catalog/objectaddress.c:3810 +#: catalog/objectaddress.c:3816 #, c-format msgid "foreign-data wrapper %s" msgstr "外部データラッパー%s" -#: catalog/objectaddress.c:3820 +#: catalog/objectaddress.c:3826 #, c-format msgid "server %s" msgstr "サーバー%s" -#: catalog/objectaddress.c:3853 +#: catalog/objectaddress.c:3859 #, c-format msgid "user mapping for %s on server %s" msgstr "サーバー%2$s上のユーザーマッピング%1$s" -#: catalog/objectaddress.c:3905 +#: catalog/objectaddress.c:3911 #, c-format msgid "default privileges on new relations belonging to role %s in schema %s" msgstr "スキーマ %2$s のロール %1$s に属する新しいリレーションのデフォルト権限" -#: catalog/objectaddress.c:3909 +#: catalog/objectaddress.c:3915 #, c-format msgid "default privileges on new relations belonging to role %s" msgstr "ロール %s に属する新しいリレーションのデフォルト権限" -#: catalog/objectaddress.c:3915 +#: catalog/objectaddress.c:3921 #, c-format msgid "default privileges on new sequences belonging to role %s in schema %s" msgstr "スキーマ %2$s のロール %1$s に属する新しいシーケンスのデフォルト権限" -#: catalog/objectaddress.c:3919 +#: catalog/objectaddress.c:3925 #, c-format msgid "default privileges on new sequences belonging to role %s" msgstr "ロール %s に属する新しい新しいシーケンスのデフォルト権限" -#: catalog/objectaddress.c:3925 +#: catalog/objectaddress.c:3931 #, c-format msgid "default privileges on new functions belonging to role %s in schema %s" msgstr "スキーマ %2$s のロール %1$s に属する新しい関数のデフォルト権限" -#: catalog/objectaddress.c:3929 +#: catalog/objectaddress.c:3935 #, c-format msgid "default privileges on new functions belonging to role %s" msgstr "ロール %s に属する新しい関数のデフォルト権限" -#: catalog/objectaddress.c:3935 +#: catalog/objectaddress.c:3941 #, c-format msgid "default privileges on new types belonging to role %s in schema %s" msgstr "スキーマ %2$s のロール %1$s に属する新しい型のデフォルト権限" -#: catalog/objectaddress.c:3939 +#: catalog/objectaddress.c:3945 #, c-format msgid "default privileges on new types belonging to role %s" msgstr "ロール %s に属する新しい型のデフォルト権限" -#: catalog/objectaddress.c:3945 +#: catalog/objectaddress.c:3951 #, c-format msgid "default privileges on new schemas belonging to role %s" msgstr "ロール%sに属する新しいスキーマ上のデフォルト権限" -#: catalog/objectaddress.c:3951 +#: catalog/objectaddress.c:3957 #, c-format msgid "default privileges on new large objects belonging to role %s" msgstr "ロール %s に属する新しいラージオブジェクトのデフォルト権限" -#: catalog/objectaddress.c:3958 +#: catalog/objectaddress.c:3964 #, c-format msgid "default privileges belonging to role %s in schema %s" msgstr "スキーマ %2$s のロール %1$s に属するデフォルト権限" -#: catalog/objectaddress.c:3962 +#: catalog/objectaddress.c:3968 #, c-format msgid "default privileges belonging to role %s" msgstr "ロール %s に属するデフォルト権限" -#: catalog/objectaddress.c:3984 +#: catalog/objectaddress.c:3990 #, c-format msgid "extension %s" msgstr "機能拡張%s" -#: catalog/objectaddress.c:4001 +#: catalog/objectaddress.c:4007 #, c-format msgid "event trigger %s" msgstr "イベントトリガー %s" -#: catalog/objectaddress.c:4025 +#: catalog/objectaddress.c:4031 #, c-format msgid "parameter %s" msgstr "パラメータ %s" #. translator: second %s is, e.g., "table %s" -#: catalog/objectaddress.c:4068 +#: catalog/objectaddress.c:4074 #, c-format msgid "policy %s on %s" msgstr "%2$s のポリシ %1$s" -#. translator: followed by, e.g., "property graph %s" -#: catalog/objectaddress.c:4094 +#: catalog/objectaddress.c:4103 #, c-format -msgid "vertex %s of " -msgstr "の頂点 %s" +msgid "vertex %s of %s" +msgstr "%2$s の頂点 %1$s" -#. translator: followed by, e.g., "property graph %s" -#: catalog/objectaddress.c:4097 +#: catalog/objectaddress.c:4105 #, c-format -msgid "edge %s of " -msgstr "の辺 %s" +msgid "edge %s of %s" +msgstr "%2$s の辺 %1$s" -#. translator: followed by, e.g., "property graph %s" -#: catalog/objectaddress.c:4128 catalog/objectaddress.c:4152 +#: catalog/objectaddress.c:4137 catalog/objectaddress.c:4164 #, c-format -msgid "label %s of " -msgstr "の辺 %s" +msgid "label %s of %s" +msgstr "%2$s のラベル %1$ss" -#. translator: followed by, e.g., "property graph %s" -#: catalog/objectaddress.c:4180 catalog/objectaddress.c:4204 +#: catalog/objectaddress.c:4195 catalog/objectaddress.c:4222 #, c-format -msgid "property %s of " -msgstr "のプロパティ %s" +msgid "property %s of %s" +msgstr "%2$s のプロパティ %1$s" -#: catalog/objectaddress.c:4216 +#: catalog/objectaddress.c:4235 #, c-format msgid "publication %s" msgstr "パブリケーション%s" -#: catalog/objectaddress.c:4229 +#: catalog/objectaddress.c:4248 #, c-format msgid "publication of schema %s in publication %s" msgstr "パブリケーション%2$sでのスキーマ%1$sのパブリケーション" #. translator: first %s is, e.g., "table %s" -#: catalog/objectaddress.c:4260 +#: catalog/objectaddress.c:4279 #, c-format msgid "publication of %s in publication %s" msgstr "パブリケーション %2$s での %1$s のパブリケーション" -#: catalog/objectaddress.c:4273 +#: catalog/objectaddress.c:4292 #, c-format msgid "subscription %s" msgstr "サブスクリプション%s" -#: catalog/objectaddress.c:4294 +#: catalog/objectaddress.c:4313 #, c-format msgid "transform for %s language %s" msgstr "言語%2$sの%1$s型に対する変換" -#: catalog/objectaddress.c:4363 +#: catalog/objectaddress.c:4382 #, c-format msgid "table %s" msgstr "テーブル%s" -#: catalog/objectaddress.c:4368 +#: catalog/objectaddress.c:4387 #, c-format msgid "index %s" msgstr "インデックス%s" -#: catalog/objectaddress.c:4372 +#: catalog/objectaddress.c:4391 #, c-format msgid "sequence %s" msgstr "シーケンス%s" -#: catalog/objectaddress.c:4376 +#: catalog/objectaddress.c:4395 #, c-format msgid "toast table %s" msgstr "TOASTテーブル%s" -#: catalog/objectaddress.c:4380 +#: catalog/objectaddress.c:4399 #, c-format msgid "view %s" msgstr "ビュー%s" -#: catalog/objectaddress.c:4384 +#: catalog/objectaddress.c:4403 #, c-format msgid "materialized view %s" msgstr "実体化ビュー%s" -#: catalog/objectaddress.c:4388 +#: catalog/objectaddress.c:4407 #, c-format msgid "composite type %s" msgstr "複合型%s" -#: catalog/objectaddress.c:4392 +#: catalog/objectaddress.c:4411 #, c-format msgid "foreign table %s" msgstr "外部テーブル%s" -#: catalog/objectaddress.c:4396 +#: catalog/objectaddress.c:4415 #, c-format msgid "property graph %s" msgstr "プロパティ・グラフ %s" -#: catalog/objectaddress.c:4401 +#: catalog/objectaddress.c:4420 #, c-format msgid "relation %s" msgstr "リレーション%s" -#: catalog/objectaddress.c:4442 +#: catalog/objectaddress.c:4461 #, c-format msgid "operator family %s for access method %s" msgstr "アクセスメソッド%2$sの演算子族%1$s" @@ -8450,7 +8465,7 @@ msgstr "遷移関数がSTRICTかつ遷移用の型が入力型とバイナリ互 msgid "return type of inverse transition function %s is not %s" msgstr "逆遷移関数%sの戻り値の型が%sではありません" -#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:3179 +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:3180 #, c-format msgid "strictness of aggregate's forward and inverse transition functions must match" msgstr "集約の前進と反転の遷移関数のSTRICT属性は一致している必要があります" @@ -8525,8 +8540,8 @@ msgstr "\"%s\"は仮説集合集約です。" msgid "cannot change number of direct arguments of an aggregate function" msgstr "集約関数の直接引数の数は変更できません" -#: catalog/pg_aggregate.c:861 commands/functioncmds.c:704 commands/typecmds.c:2055 commands/typecmds.c:2101 commands/typecmds.c:2153 commands/typecmds.c:2190 commands/typecmds.c:2224 commands/typecmds.c:2258 commands/typecmds.c:2292 commands/typecmds.c:2321 commands/typecmds.c:2408 commands/typecmds.c:2450 parser/parse_func.c:422 parser/parse_func.c:453 parser/parse_func.c:480 parser/parse_func.c:494 parser/parse_func.c:625 parser/parse_func.c:645 -#: parser/parse_func.c:2300 parser/parse_func.c:2573 +#: catalog/pg_aggregate.c:861 commands/functioncmds.c:704 commands/typecmds.c:2055 commands/typecmds.c:2101 commands/typecmds.c:2153 commands/typecmds.c:2190 commands/typecmds.c:2224 commands/typecmds.c:2258 commands/typecmds.c:2292 commands/typecmds.c:2321 commands/typecmds.c:2408 commands/typecmds.c:2450 parser/parse_func.c:429 parser/parse_func.c:460 parser/parse_func.c:487 parser/parse_func.c:501 parser/parse_func.c:631 parser/parse_func.c:651 +#: parser/parse_func.c:2304 parser/parse_func.c:2577 #, c-format msgid "function %s does not exist" msgstr "関数%sは存在しません" @@ -8626,22 +8641,22 @@ msgstr "照合順序\"%s\"はすでに存在します" msgid "collation \"%s\" for encoding \"%s\" already exists" msgstr "エンコーディング\"%2$s\"の照合順序\"%1$s\"はすでに存在します" -#: catalog/pg_constraint.c:764 commands/tablecmds.c:8077 +#: catalog/pg_constraint.c:764 commands/tablecmds.c:8102 #, c-format msgid "cannot change NO INHERIT status of NOT NULL constraint \"%s\" on relation \"%s\"" msgstr "リレーション\"%2$s\"の非NULL制約\"%1$s\"のNO INHERIT設定は変更できません" -#: catalog/pg_constraint.c:766 commands/tablecmds.c:9696 +#: catalog/pg_constraint.c:766 commands/tablecmds.c:9721 #, c-format msgid "You might need to make the existing constraint inheritable using %s." msgstr "%s を用いて既存の制約を継承可能にする必要があるかもしれません。" -#: catalog/pg_constraint.c:776 commands/tablecmds.c:8426 +#: catalog/pg_constraint.c:776 commands/tablecmds.c:8451 #, c-format msgid "incompatible NOT VALID constraint \"%s\" on relation \"%s\"" msgstr "リレーション\"%2$s\"上の NOT VALID 制約\"%1$s\"は非互換です" -#: catalog/pg_constraint.c:778 commands/tablecmds.c:8428 commands/tablecmds.c:9708 +#: catalog/pg_constraint.c:778 commands/tablecmds.c:8453 commands/tablecmds.c:9733 #, c-format msgid "You might need to validate it using %s." msgstr "%s を用いてこの制約を検証する必要があるかもしれません。" @@ -8691,31 +8706,41 @@ msgstr "変換\"%s\"はすでに存在します" msgid "default conversion for %s to %s already exists" msgstr "%sから%sへのデフォルトの変換はすでに存在します" -#: catalog/pg_depend.c:225 commands/extension.c:3881 +#: catalog/pg_depend.c:236 commands/extension.c:3883 #, c-format msgid "%s is already a member of extension \"%s\"" msgstr "%sはすでに機能拡張\"%s\"のメンバです" -#: catalog/pg_depend.c:232 catalog/pg_depend.c:283 commands/extension.c:3921 +#: catalog/pg_depend.c:243 catalog/pg_depend.c:294 commands/extension.c:3923 #, c-format msgid "%s is not a member of extension \"%s\"" msgstr "%s は機能拡張\"%s\"のメンバではありません" -#: catalog/pg_depend.c:235 +#: catalog/pg_depend.c:246 #, c-format msgid "An extension is not allowed to replace an object that it does not own." msgstr "機能拡張は自身が所有していないオブジェクトを置き換えることができません。" -#: catalog/pg_depend.c:286 +#: catalog/pg_depend.c:297 #, c-format msgid "An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns." msgstr "機能拡張はCREATE ... IF NOT EXISTSを自身がすでに所有しているオブジェクトと競合するオブジェクトの生成をスキップするためにのみ使用することができます。" -#: catalog/pg_depend.c:649 +#: catalog/pg_depend.c:667 #, c-format msgid "cannot remove dependency on %s because it is a system object" msgstr "システムオブジェクトであるため、%sの依存関係を削除できません。" +#: catalog/pg_depend.c:812 +#, c-format +msgid "referenced %s was concurrently dropped" +msgstr "参照先の%sは並行して削除されました" + +#: catalog/pg_depend.c:844 +#, c-format +msgid "referenced relation was concurrently dropped" +msgstr "参照先のリレーションは並行して削除されました" + #: catalog/pg_enum.c:170 catalog/pg_enum.c:327 catalog/pg_enum.c:637 #, c-format msgid "invalid enum label \"%s\"" @@ -8766,7 +8791,7 @@ msgstr "パーティション\"%s\"を取り外せません" msgid "The partition is being detached concurrently or has an unfinished detach." msgstr "このパーティションは今現在取り外し中であるか取り外し処理が未完了の状態です。" -#: catalog/pg_inherits.c:596 commands/tablecmds.c:4988 commands/tablecmds.c:18165 +#: catalog/pg_inherits.c:596 commands/tablecmds.c:5022 commands/tablecmds.c:18428 #, c-format msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation." msgstr "ALTER TABLE ... DETACH PARTITION ... FINALIZE を実行して保留中の取り外し処理を完了させてください。" @@ -8871,7 +8896,7 @@ msgstr "否定演算子 %s はすでに演算子 %u の否定子です" msgid "parameter ACL \"%s\" does not exist" msgstr "パラメータACL \"%s\"は存在しません" -#: catalog/pg_proc.c:160 parser/parse_func.c:2362 +#: catalog/pg_proc.c:160 parser/parse_func.c:2366 #, c-format msgid "functions cannot have more than %d argument" msgid_plural "functions cannot have more than %d arguments" @@ -8993,50 +9018,55 @@ msgstr "この操作はシステムテーブルに対してはサポートされ #: catalog/pg_publication.c:100 #, c-format +msgid "This operation is not supported for conflict log tables." +msgstr "この操作は競合ログテーブルに対してはサポートされていません。" + +#: catalog/pg_publication.c:107 +#, c-format msgid "This operation is not supported for temporary tables." msgstr "この操作は一時テーブルに対してはサポートされていません。" -#: catalog/pg_publication.c:105 +#: catalog/pg_publication.c:112 #, c-format msgid "This operation is not supported for unlogged tables." msgstr "この操作はUNLOGGEDテーブルに対してはサポートされていません。" -#: catalog/pg_publication.c:119 catalog/pg_publication.c:127 +#: catalog/pg_publication.c:127 catalog/pg_publication.c:135 #, c-format msgid "cannot add schema \"%s\" to publication" msgstr "パブリケーションにスキーマ\"%s\"を追加できません" -#: catalog/pg_publication.c:121 +#: catalog/pg_publication.c:129 #, c-format msgid "This operation is not supported for system schemas." msgstr "この操作はシステムスキーマに対してはサポートされていません。" -#: catalog/pg_publication.c:129 +#: catalog/pg_publication.c:137 #, c-format msgid "Temporary schemas cannot be replicated." msgstr "一時スキーマは複製できません" -#: catalog/pg_publication.c:558 +#: catalog/pg_publication.c:568 #, c-format msgid "relation \"%s\" is already member of publication \"%s\"" msgstr "リレーション\"%s\"はすでにパブリケーション\"%s\"のメンバです" -#: catalog/pg_publication.c:695 +#: catalog/pg_publication.c:705 #, c-format msgid "cannot use system column \"%s\" in publication column list" msgstr "システム列\"%s\"はパブリケーション列リスト内では使用できません" -#: catalog/pg_publication.c:701 +#: catalog/pg_publication.c:711 #, c-format msgid "cannot use virtual generated column \"%s\" in publication column list" msgstr "仮想生成列\"%s\"はパブリケーションの列リストでは使用できません" -#: catalog/pg_publication.c:707 +#: catalog/pg_publication.c:717 #, c-format msgid "duplicate column \"%s\" in publication column list" msgstr "パブリケーション列リスト内に重複した列 \"%s\"" -#: catalog/pg_publication.c:819 +#: catalog/pg_publication.c:829 #, c-format msgid "schema \"%s\" is already member of publication \"%s\"" msgstr "スキーマ\"%s\"はすでにパブリケーション\"%s\"のメンバです" @@ -9110,17 +9140,27 @@ msgstr "データベースシステムが必要としているため%sが所有 msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" msgstr "データベースシステムが必要としているため%sが所有するオブジェクトの所有者を再割り当てできません" -#: catalog/pg_subscription.c:140 commands/subscriptioncmds.c:1842 commands/subscriptioncmds.c:2266 +#: catalog/pg_subscription.c:70 commands/tablecmds.c:20914 replication/logical/relation.c:252 +#, c-format +msgid "\"%s\"" +msgstr "\"%s\"" + +#: catalog/pg_subscription.c:72 commands/tablecmds.c:20916 replication/logical/relation.c:254 +#, c-format +msgid ", \"%s\"" +msgstr "、\"%s\"" + +#: catalog/pg_subscription.c:156 commands/subscriptioncmds.c:2088 commands/subscriptioncmds.c:2444 #, c-format msgid "subscription owner \"%s\" does not have permission on foreign server \"%s\"" msgstr "サブスクリプションのオーナー\"%s\"は外部サーバー\"%s\"に対して権限がありません" -#: catalog/pg_subscription.c:525 +#: catalog/pg_subscription.c:548 #, c-format msgid "could not drop relation mapping for subscription \"%s\"" msgstr "サブスクリプション\"%s\"に対するリレーションマッピングを削除できませんでした" -#: catalog/pg_subscription.c:527 +#: catalog/pg_subscription.c:550 #, c-format msgid "Table synchronization for relation \"%s\" is in progress and is in state \"%c\"." msgstr "リレーション\\\"%s\\\"のテーブル同期が進行中で、状態は\\\"%c\\\"です。" @@ -9128,7 +9168,7 @@ msgstr "リレーション\\\"%s\\\"のテーブル同期が進行中で、状 #. translator: first %s is a SQL ALTER command and second %s is a #. SQL DROP command #. -#: catalog/pg_subscription.c:534 +#: catalog/pg_subscription.c:557 #, c-format msgid "Use %s to enable subscription if not already enabled or use %s to drop the subscription." msgstr "サブスクリプションが有効にされていない場合は%sを実行して有効化するか、%sを実行してこのサブスクリプションを削除してください。" @@ -9158,7 +9198,7 @@ msgstr "値渡し型の場合、内部サイズ%dは不正です" msgid "alignment \"%c\" is invalid for variable-length type" msgstr "可変長型の場合、アラインメント\"%c\"は不正です" -#: catalog/pg_type.c:323 commands/typecmds.c:4413 +#: catalog/pg_type.c:323 commands/typecmds.c:4403 #, c-format msgid "fixed-size types must have storage PLAIN" msgstr "固定長型の場合はPLAIN格納方式でなければなりません" @@ -9173,7 +9213,7 @@ msgstr "\"%s\"の複範囲型の作成中に失敗しました。" msgid "You can manually specify a multirange type name using the \"multirange_type_name\" attribute." msgstr "\"multirange_type_name\"属性で複範囲型の型名を手動で指定することができます。" -#: catalog/storage.c:549 storage/buffer/bufmgr.c:8849 +#: catalog/storage.c:549 storage/buffer/bufmgr.c:8889 #, c-format msgid "invalid page in block %u of relation \"%s\"" msgstr "リレーション\"%2$s\"のブロック%1$uに不正なページ" @@ -9293,7 +9333,7 @@ msgstr "言語\"%s\"はすでに存在します" msgid "publication \"%s\" already exists" msgstr "パブリケーション\"%s\"はすでに存在します" -#: commands/alter.c:98 commands/subscriptioncmds.c:709 +#: commands/alter.c:98 commands/subscriptioncmds.c:765 #, c-format msgid "subscription \"%s\" already exists" msgstr "サブスクリプション\"%s\"はすでに存在します" @@ -9333,12 +9373,12 @@ msgstr "テキスト検索設定\"%s\"はすでにスキーマ\"%s\"存在しま msgid "must be superuser to rename %s" msgstr "%sの名前を変更するにはスーパーユーザーである必要があります" -#: commands/alter.c:250 commands/subscriptioncmds.c:688 commands/subscriptioncmds.c:1477 commands/subscriptioncmds.c:1566 commands/subscriptioncmds.c:2572 +#: commands/alter.c:250 commands/subscriptioncmds.c:744 commands/subscriptioncmds.c:1710 commands/subscriptioncmds.c:1785 commands/subscriptioncmds.c:2885 #, c-format msgid "password_required=false is superuser-only" msgstr "password_required=falseはスーパーユーザーのみ可能です" -#: commands/alter.c:251 commands/subscriptioncmds.c:689 commands/subscriptioncmds.c:1478 commands/subscriptioncmds.c:1567 commands/subscriptioncmds.c:2573 +#: commands/alter.c:251 commands/subscriptioncmds.c:745 commands/subscriptioncmds.c:1711 commands/subscriptioncmds.c:1786 commands/subscriptioncmds.c:2886 #, c-format msgid "Subscriptions with the password_required option set to false may only be created or modified by the superuser." msgstr "password_requiredオプションがfalseに設定されたサブスクリプションはスーパーユーザのみ作成と変更が可能です。" @@ -9363,7 +9403,7 @@ msgstr "アクセスメソッドを作成するにはスーパーユーザーで msgid "access method \"%s\" already exists" msgstr "アクセスメソッド\"%s\"は存在しません" -#: commands/amcmds.c:154 commands/indexcmds.c:227 commands/indexcmds.c:863 commands/opclasscmds.c:376 commands/opclasscmds.c:853 +#: commands/amcmds.c:154 commands/indexcmds.c:237 commands/indexcmds.c:873 commands/opclasscmds.c:376 commands/opclasscmds.c:853 #, c-format msgid "access method \"%s\" does not exist" msgstr "アクセスメソッド\"%s\"は存在しません" @@ -9373,7 +9413,7 @@ msgstr "アクセスメソッド\"%s\"は存在しません" msgid "handler function is not specified" msgstr "ハンドラ関数の指定がありません" -#: commands/amcmds.c:264 commands/event_trigger.c:206 commands/foreigncmds.c:500 commands/foreigncmds.c:548 commands/proclang.c:79 commands/trigger.c:707 parser/parse_clause.c:1073 +#: commands/amcmds.c:264 commands/event_trigger.c:206 commands/foreigncmds.c:500 commands/foreigncmds.c:548 commands/proclang.c:79 commands/trigger.c:719 parser/parse_clause.c:1077 #, c-format msgid "function %s must return type %s" msgstr "関数%sは型%sを返さなければなりません" @@ -9458,17 +9498,17 @@ msgstr "LISTEN / UNLISTEN / NOTIFY を実行しているトランザクション msgid "too many notifications in the NOTIFY queue" msgstr "NOTIFY キューで発生した通知イベントが多すぎます" -#: commands/async.c:2240 +#: commands/async.c:2237 #, c-format msgid "NOTIFY queue is %.0f%% full" msgstr "NOTYFY キューが %.0f%% まで一杯になっています" -#: commands/async.c:2242 +#: commands/async.c:2239 #, c-format msgid "The server process with PID %d is among those with the oldest transactions." msgstr "PID %d のサーバープロセスは、この中で最も古いトランザクションを実行中です。" -#: commands/async.c:2245 +#: commands/async.c:2242 #, c-format msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." msgstr "このプロセスが現在のトランザクションを終了するまで NOTYFY キューを空にすることはできません" @@ -9478,8 +9518,8 @@ msgstr "このプロセスが現在のトランザクションを終了するま msgid "collation attribute \"%s\" not recognized" msgstr "照合順序の属性\"%s\"が認識できません" -#: commands/collationcmds.c:128 commands/collationcmds.c:134 commands/define.c:374 commands/tablecmds.c:8519 replication/pgoutput/pgoutput.c:323 replication/pgoutput/pgoutput.c:346 replication/pgoutput/pgoutput.c:364 replication/pgoutput/pgoutput.c:374 replication/pgoutput/pgoutput.c:384 replication/pgoutput/pgoutput.c:394 replication/pgoutput/pgoutput.c:406 replication/walsender.c:1173 replication/walsender.c:1195 replication/walsender.c:1205 -#: replication/walsender.c:1214 replication/walsender.c:1465 replication/walsender.c:1474 +#: commands/collationcmds.c:128 commands/collationcmds.c:134 commands/define.c:374 commands/tablecmds.c:8544 replication/pgoutput/pgoutput.c:323 replication/pgoutput/pgoutput.c:346 replication/pgoutput/pgoutput.c:364 replication/pgoutput/pgoutput.c:374 replication/pgoutput/pgoutput.c:384 replication/pgoutput/pgoutput.c:394 replication/pgoutput/pgoutput.c:406 replication/walsender.c:1195 replication/walsender.c:1217 replication/walsender.c:1227 +#: replication/walsender.c:1236 replication/walsender.c:1487 replication/walsender.c:1496 #, c-format msgid "conflicting or redundant options" msgstr "競合するオプション、あるいは余計なオプションがあります" @@ -9548,7 +9588,7 @@ msgstr "デフォルト照合順序のバーションはリフレッシュでき #. translator: %s is an SQL command #. translator: %s is an SQL ALTER command -#: commands/collationcmds.c:448 commands/subscriptioncmds.c:1970 commands/tablecmds.c:8271 commands/tablecmds.c:8281 commands/tablecmds.c:8283 commands/tablecmds.c:16432 commands/tablecmds.c:19956 commands/tablecmds.c:19977 commands/typecmds.c:3837 commands/typecmds.c:3922 commands/typecmds.c:4276 +#: commands/collationcmds.c:448 commands/subscriptioncmds.c:2217 commands/tablecmds.c:8296 commands/tablecmds.c:8306 commands/tablecmds.c:8308 commands/tablecmds.c:16689 commands/tablecmds.c:20243 commands/tablecmds.c:20264 commands/typecmds.c:3827 commands/typecmds.c:3912 commands/typecmds.c:4266 #, c-format msgid "Use %s instead." msgstr "代わりに%sを使用してください" @@ -9563,7 +9603,7 @@ msgstr "バージョン%sから%sへの変更" msgid "version has not changed" msgstr "バージョンが変わっていません" -#: commands/collationcmds.c:529 commands/dbcommands.c:2811 utils/adt/dbsize.c:180 utils/adt/ddlutils.c:879 +#: commands/collationcmds.c:529 commands/dbcommands.c:2811 utils/adt/dbsize.c:180 utils/adt/ddlutils.c:677 #, c-format msgid "database with OID %u does not exist" msgstr "OID %uのデータベースは存在しません" @@ -9583,7 +9623,7 @@ msgstr "システム照合順序をインポートするにはスーパーユー msgid "no usable system locales were found" msgstr "使用できるシステムロケールが見つかりません" -#: commands/comment.c:62 commands/dbcommands.c:1720 commands/dbcommands.c:1944 commands/dbcommands.c:2056 commands/dbcommands.c:2254 commands/dbcommands.c:2495 commands/dbcommands.c:2588 commands/dbcommands.c:2712 commands/dbcommands.c:3223 utils/adt/regproc.c:1813 utils/init/postinit.c:1061 utils/init/postinit.c:1125 utils/init/postinit.c:1198 +#: commands/comment.c:62 commands/dbcommands.c:1720 commands/dbcommands.c:1944 commands/dbcommands.c:2056 commands/dbcommands.c:2254 commands/dbcommands.c:2495 commands/dbcommands.c:2588 commands/dbcommands.c:2712 commands/dbcommands.c:3223 utils/adt/regproc.c:1813 utils/init/postinit.c:1067 utils/init/postinit.c:1131 utils/init/postinit.c:1204 #, c-format msgid "database \"%s\" does not exist" msgstr "データベース\"%s\"は存在しません" @@ -9593,12 +9633,12 @@ msgstr "データベース\"%s\"は存在しません" msgid "cannot set comment on relation \"%s\"" msgstr "リレーション\"%s\"にはコメントを設定できません" -#: commands/constraint.c:61 utils/adt/ri_triggers.c:2306 +#: commands/constraint.c:61 utils/adt/ri_triggers.c:2329 #, c-format msgid "function \"%s\" was not called by trigger manager" msgstr "関数\"%s\"はトリガー関数として呼び出されていません" -#: commands/constraint.c:68 utils/adt/ri_triggers.c:2315 +#: commands/constraint.c:68 utils/adt/ri_triggers.c:2338 #, c-format msgid "function \"%s\" must be fired AFTER ROW" msgstr "関数\"%s\"はAFTER ROWトリガーで実行しなくてはなりません" @@ -9683,7 +9723,7 @@ msgstr "列\"%s\"はシステム列です。" msgid "generated columns are not supported in COPY FROM WHERE conditions" msgstr "生成列は COPY FROM の WHERE 条件では使用できません" -#: commands/copy.c:203 commands/tablecmds.c:14700 commands/tablecmds.c:20103 commands/tablecmds.c:20185 commands/trigger.c:661 rewrite/rewriteHandler.c:1001 rewrite/rewriteHandler.c:1036 +#: commands/copy.c:203 commands/tablecmds.c:14957 commands/tablecmds.c:20390 commands/tablecmds.c:20472 commands/trigger.c:673 rewrite/rewriteHandler.c:1001 rewrite/rewriteHandler.c:1036 #, c-format msgid "Column \"%s\" is a generated column." msgstr "列\"%s\"は生成カラムです。" @@ -9868,12 +9908,12 @@ msgstr "列\"%s\"は生成カラムです" msgid "Generated columns cannot be used in COPY." msgstr "生成カラムはCOPYでは使えません。" -#: commands/copy.c:1128 commands/indexcmds.c:1972 commands/statscmds.c:263 commands/tablecmds.c:2661 commands/tablecmds.c:3168 commands/tablecmds.c:3997 parser/parse_relation.c:3884 parser/parse_relation.c:3894 parser/parse_relation.c:3912 parser/parse_relation.c:3919 parser/parse_relation.c:3933 utils/adt/tsvector_op.c:2858 +#: commands/copy.c:1128 commands/indexcmds.c:1982 commands/statscmds.c:277 commands/tablecmds.c:2670 commands/tablecmds.c:3189 commands/tablecmds.c:4031 parser/parse_relation.c:3916 parser/parse_relation.c:3926 parser/parse_relation.c:3944 parser/parse_relation.c:3951 parser/parse_relation.c:3965 utils/adt/tsvector_op.c:2831 #, c-format msgid "column \"%s\" does not exist" msgstr "列\"%s\"は存在しません" -#: commands/copy.c:1135 commands/tablecmds.c:2687 commands/trigger.c:958 parser/parse_target.c:1091 parser/parse_target.c:1102 +#: commands/copy.c:1135 commands/tablecmds.c:2696 commands/trigger.c:970 parser/parse_target.c:1091 parser/parse_target.c:1102 #, c-format msgid "column \"%s\" specified more than once" msgstr "列\"%s\"が複数指定されました" @@ -9972,32 +10012,32 @@ msgstr[0] "データ型の不適合により、%行で一部の列が nu #. translator: first %s is the name of a COPY option, e.g. FORCE_NOT_NULL #. translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL -#: commands/copyfrom.c:1617 commands/copyfrom.c:1681 commands/copyto.c:1095 +#: commands/copyfrom.c:1617 commands/copyfrom.c:1677 commands/copyto.c:1117 #, c-format msgid "%s column \"%s\" not referenced by COPY" msgstr "%s指定された列\"%s\"はCOPYで参照されません" -#: commands/copyfrom.c:1734 utils/mb/mbutils.c:394 +#: commands/copyfrom.c:1730 utils/mb/mbutils.c:394 #, c-format msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" msgstr "符号化方式\"%s\"から\"%s\"用のデフォルト変換関数は存在しません" -#: commands/copyfrom.c:1910 +#: commands/copyfrom.c:1906 #, c-format msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." msgstr "COPY FROMによってPostgreSQLサーバープロセスはファイルを読み込みます。psqlの \\copy のようなクライアント側の仕組みが必要かもしれません" -#: commands/copyfrom.c:1923 commands/copyto.c:1200 +#: commands/copyfrom.c:1919 commands/copyto.c:1222 #, c-format msgid "\"%s\" is a directory" msgstr "\"%s\"はディレクトリです" -#: commands/copyfrom.c:1981 commands/copyto.c:714 libpq/be-secure-common.c:90 +#: commands/copyfrom.c:1977 commands/copyto.c:732 libpq/be-secure-common.c:90 #, c-format msgid "could not close pipe to external command: %m" msgstr "外部コマンドに対するパイプをクローズできませんでした: %m" -#: commands/copyfrom.c:1996 commands/copyto.c:719 +#: commands/copyfrom.c:1992 commands/copyto.c:737 #, c-format msgid "program \"%s\" failed" msgstr "プログラム\"%s\"の実行に失敗しました" @@ -10037,7 +10077,7 @@ msgstr "COPYファイルのヘッダが不正です(サイズが不正です)" msgid "could not read from COPY file: %m" msgstr "COPYファイルから読み込めませんでした: %m" -#: commands/copyfromparse.c:284 commands/copyfromparse.c:309 replication/walsender.c:781 replication/walsender.c:807 tcop/postgres.c:382 +#: commands/copyfromparse.c:284 commands/copyfromparse.c:309 replication/walsender.c:781 replication/walsender.c:807 tcop/postgres.c:383 #, c-format msgid "unexpected EOF on client connection with an open transaction" msgstr "トランザクションを実行中のクライアント接続で想定外のEOFがありました" @@ -10192,107 +10232,107 @@ msgstr "フィールドサイズが不正です" msgid "incorrect binary data format" msgstr "バイナリデータ書式が不正です" -#: commands/copyto.c:618 +#: commands/copyto.c:636 #, c-format msgid "could not write to COPY program: %m" msgstr "COPYプログラムに書き出せませんでした: %m" -#: commands/copyto.c:623 +#: commands/copyto.c:641 #, c-format msgid "could not write to COPY file: %m" msgstr "COPYファイルに書き出せませんでした: %m" -#: commands/copyto.c:799 +#: commands/copyto.c:817 #, c-format msgid "cannot copy from view \"%s\"" msgstr "ビュー\"%s\"からのコピーはできません" -#: commands/copyto.c:801 commands/copyto.c:816 commands/copyto.c:843 +#: commands/copyto.c:819 commands/copyto.c:834 commands/copyto.c:861 #, c-format msgid "Try the COPY (SELECT ...) TO variant." msgstr "COPY (SELECT ...) TO 形式を試してください" -#: commands/copyto.c:807 +#: commands/copyto.c:825 #, c-format msgid "cannot copy from unpopulated materialized view \"%s\"" msgstr "データ未投入の実体化ビュー\"%s\"からのコピーはできません" -#: commands/copyto.c:809 executor/execUtils.c:786 +#: commands/copyto.c:827 executor/execUtils.c:786 #, c-format msgid "Use the REFRESH MATERIALIZED VIEW command." msgstr "REFRESH MATERIALIZED VIEWコマンドを使用してください。" -#: commands/copyto.c:814 commands/copyto.c:840 +#: commands/copyto.c:832 commands/copyto.c:858 #, c-format msgid "cannot copy from foreign table \"%s\"" msgstr "外部テーブル \"%s\" からのコピーはできません" -#: commands/copyto.c:820 +#: commands/copyto.c:838 #, c-format msgid "cannot copy from sequence \"%s\"" msgstr "シーケンス\"%s\"からのコピーはできません" -#: commands/copyto.c:841 +#: commands/copyto.c:859 #, c-format msgid "Partition \"%s\" is a foreign table in partitioned table \"%s\"" msgstr "パーティション\"%s\"はパーティション親テーブル\"%s\"内の外部テーブルです" -#: commands/copyto.c:854 +#: commands/copyto.c:872 #, c-format msgid "cannot copy from non-table relation \"%s\"" msgstr "テーブル以外のリレーション\"%s\"からのコピーはできません" -#: commands/copyto.c:912 +#: commands/copyto.c:930 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for COPY" msgstr "DO INSTEAD NOTHING ルールは COPY ではサポートされていません" -#: commands/copyto.c:926 +#: commands/copyto.c:944 #, c-format msgid "conditional DO INSTEAD rules are not supported for COPY" msgstr "条件付き DO INSTEAD ルールは COPY ではサポートされていません" -#: commands/copyto.c:930 +#: commands/copyto.c:948 #, c-format msgid "DO ALSO rules are not supported for COPY" msgstr "DO ALSO ルールは COPY ではサポートされていません" -#: commands/copyto.c:935 +#: commands/copyto.c:953 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for COPY" msgstr "マルチステートメントの DO INSTEAD ルールは COPY ではサポートされていません" -#: commands/copyto.c:945 +#: commands/copyto.c:963 #, c-format msgid "COPY (SELECT INTO) is not supported" msgstr "COPY (SELECT INTO)はサポートされていません" -#: commands/copyto.c:951 +#: commands/copyto.c:969 #, c-format msgid "COPY query must not be a utility command" msgstr "COPY問い合わせはユーティリティコマンドであってはなりません" -#: commands/copyto.c:967 +#: commands/copyto.c:985 #, c-format msgid "COPY query must have a RETURNING clause" msgstr "COPY文中の問い合わせではRETURNING句が必須です" -#: commands/copyto.c:996 +#: commands/copyto.c:1014 #, c-format msgid "relation referenced by COPY statement has changed" msgstr "COPY文で参照されているリレーションが変更されました" -#: commands/copyto.c:1165 +#: commands/copyto.c:1187 #, c-format msgid "relative path not allowed for COPY to file" msgstr "ファイルへのCOPYでは相対パスは指定できません" -#: commands/copyto.c:1184 +#: commands/copyto.c:1206 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "ファイル\"%s\"を書き込み用にオープンできませんでした: %m" -#: commands/copyto.c:1187 +#: commands/copyto.c:1209 #, c-format msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." msgstr "COPY TOによってPostgreSQLサーバープロセスはファイルの書き込みを行います。psqlの \\copy のようなクライアント側の仕組みが必要かもしれません" @@ -10362,7 +10402,7 @@ msgstr "テンプレートデータベース\"%s\"は存在しません" msgid "cannot use invalid database \"%s\" as template" msgstr "無効なデータベース\"%s\"はテンプレートとして使用できません" -#: commands/dbcommands.c:1023 commands/dbcommands.c:2506 utils/init/postinit.c:1140 +#: commands/dbcommands.c:1023 commands/dbcommands.c:2506 utils/init/postinit.c:1146 #, c-format msgid "Use DROP DATABASE to drop invalid databases." msgstr "DROP DATABASEを使用して無効なデータベースを削除してください。" @@ -10639,7 +10679,7 @@ msgstr "このコマンドを使う前に、データベースのデフォルト msgid "some useless files may be left behind in old database directory \"%s\"" msgstr "元のデータベースのディレクトリ\"%s\"に不要なファイルが残っているかもしれません" -#: commands/dbcommands.c:2378 commands/explain_state.c:170 commands/indexcmds.c:2874 commands/repack.c:273 commands/vacuum.c:236 commands/vacuum.c:299 postmaster/checkpointer.c:1031 +#: commands/dbcommands.c:2378 commands/explain_state.c:170 commands/indexcmds.c:2999 commands/repack.c:281 commands/vacuum.c:236 commands/vacuum.c:299 postmaster/checkpointer.c:1031 #, c-format msgid "unrecognized %s option \"%s\"" msgstr "%s のオプション\"%s\"が認識できません" @@ -10675,7 +10715,7 @@ msgid "There is %d other session using the database." msgid_plural "There are %d other sessions using the database." msgstr[0] "他にこのデータベースを使っている %d 個のセッションがあります。" -#: commands/dbcommands.c:3175 storage/ipc/procarray.c:3880 +#: commands/dbcommands.c:3175 storage/ipc/procarray.c:3867 #, c-format msgid "There is %d prepared transaction using the database." msgid_plural "There are %d prepared transactions using the database." @@ -10731,12 +10771,12 @@ msgstr "\"%s\"は集約関数です" msgid "Use DROP AGGREGATE to drop aggregate functions." msgstr "集約関数を削除するにはDROP AGGREGATEを使用してください" -#: commands/dropcmds.c:153 commands/propgraphcmds.c:1305 commands/sequence.c:457 commands/tablecmds.c:4081 commands/tablecmds.c:4242 commands/tablecmds.c:4294 commands/tablecmds.c:19228 tcop/utility.c:1331 +#: commands/dropcmds.c:153 commands/propgraphcmds.c:1310 commands/sequence.c:457 commands/tablecmds.c:4115 commands/tablecmds.c:4276 commands/tablecmds.c:4328 commands/tablecmds.c:19491 tcop/utility.c:1331 #, c-format msgid "relation \"%s\" does not exist, skipping" msgstr "リレーション\"%s\"は存在しません、スキップします" -#: commands/dropcmds.c:183 commands/dropcmds.c:282 commands/tablecmds.c:1530 +#: commands/dropcmds.c:183 commands/dropcmds.c:282 commands/tablecmds.c:1537 #, c-format msgid "schema \"%s\" does not exist, skipping" msgstr "スキーマ\"%s\"は存在しません、スキップします" @@ -10761,7 +10801,7 @@ msgstr "照合順序\"%s\"は存在しません、スキップします" msgid "conversion \"%s\" does not exist, skipping" msgstr "変換\"%sは存在しません、スキップします" -#: commands/dropcmds.c:288 commands/statscmds.c:720 +#: commands/dropcmds.c:288 commands/statscmds.c:734 #, c-format msgid "statistics object \"%s\" does not exist, skipping" msgstr "統計情報オブジェクト\"%s\"は存在しません、スキップします" @@ -10937,22 +10977,22 @@ msgstr "イベントトリガー\"%s\"の所有者を変更する権限があり msgid "The owner of an event trigger must be a superuser." msgstr "イベントトリガーの所有者はスーパーユーザーでなければなりません" -#: commands/event_trigger.c:1538 +#: commands/event_trigger.c:1546 #, c-format msgid "%s can only be called in a sql_drop event trigger function" msgstr "%sはsql_dropイベントトリガー関数内でのみ呼び出すことができます" -#: commands/event_trigger.c:1631 commands/event_trigger.c:1652 +#: commands/event_trigger.c:1639 commands/event_trigger.c:1660 #, c-format msgid "%s can only be called in a table_rewrite event trigger function" msgstr "%sはtable_rewriteイベントトリガー関数でのみ呼び出すことができます" -#: commands/event_trigger.c:2068 +#: commands/event_trigger.c:2076 #, c-format msgid "%s can only be called in an event trigger function" msgstr "%sはイベントトリガー関数でのみ呼び出すことができます" -#: commands/explain_state.c:136 commands/explain_state.c:161 commands/wait.c:87 postmaster/checkpointer.c:1022 replication/walsender.c:1187 +#: commands/explain_state.c:136 commands/explain_state.c:161 commands/wait.c:87 postmaster/checkpointer.c:1022 replication/walsender.c:1209 #, c-format msgid "unrecognized value for %s option \"%s\": \"%s\"" msgstr "%s のオプション\"%s\"に対する認識できない値: \"%s\"" @@ -10977,7 +11017,7 @@ msgstr "EXPLAIN オプション\"%s\"が認識できません" msgid "EXPLAIN option \"%s\" requires a Boolean value" msgstr "EXPLAINオプション \"%s\" にはbooleanを指定します" -#: commands/extension.c:239 commands/extension.c:3515 +#: commands/extension.c:239 commands/extension.c:3517 #, c-format msgid "extension \"%s\" does not exist" msgstr "機能拡張\"%s\"は存在しません" @@ -11032,242 +11072,242 @@ msgstr "バージョン名が\"-\"で始まったり終わったりしてはな msgid "Version names must not contain directory separator characters." msgstr "バージョン名にディレクトリの区切り文字が含まれていてはなりません" -#: commands/extension.c:722 +#: commands/extension.c:724 #, c-format msgid "extension \"%s\" is not available" msgstr "機能拡張\"%s\" は利用できません" -#: commands/extension.c:723 +#: commands/extension.c:725 #, c-format msgid "The extension must first be installed on the system where PostgreSQL is running." msgstr "PostgreSQLが稼働しているシステムで、事前に機能拡張がインストールされている必要があります。" -#: commands/extension.c:745 +#: commands/extension.c:747 #, c-format msgid "could not open extension control file \"%s\": %m" msgstr "機能拡張の制御ファイル\"%s\"をオープンできませんでした: %m" -#: commands/extension.c:768 commands/extension.c:778 +#: commands/extension.c:770 commands/extension.c:780 #, c-format msgid "parameter \"%s\" cannot be set in a secondary extension control file" msgstr "セカンダリの機能拡張制御ファイルにパラメータ\"%s\"を設定できません" -#: commands/extension.c:800 commands/extension.c:808 commands/extension.c:816 utils/misc/guc.c:3041 +#: commands/extension.c:802 commands/extension.c:810 commands/extension.c:818 utils/misc/guc.c:3041 #, c-format msgid "parameter \"%s\" requires a Boolean value" msgstr "パラメータ\"%s\"にはbooleanを指定します" -#: commands/extension.c:825 +#: commands/extension.c:827 #, c-format msgid "\"%s\" is not a valid encoding name" msgstr "\"%s\"は有効な符号化方式名ではありません" -#: commands/extension.c:839 commands/extension.c:854 +#: commands/extension.c:841 commands/extension.c:856 #, c-format msgid "parameter \"%s\" must be a list of extension names" msgstr "パラメータ\"%s\"は機能拡張名のリストでなければなりません" -#: commands/extension.c:861 +#: commands/extension.c:863 #, c-format msgid "unrecognized parameter \"%s\" in file \"%s\"" msgstr "ファイル\"%2$s\"中に認識できないパラメータ\"%1$s\"があります" -#: commands/extension.c:870 +#: commands/extension.c:872 #, c-format msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" msgstr "\"relocatable\"が真の場合はパラメータ\"schema\"は指定できません" -#: commands/extension.c:1046 +#: commands/extension.c:1048 #, c-format msgid "SQL statement \"%.*s\"" msgstr "SQL文 \"%.*s\"" -#: commands/extension.c:1075 +#: commands/extension.c:1077 #, c-format msgid "extension script file \"%s\", near line %d" msgstr "機能拡張スクリプトファイル \"%s\"、%d 行目付近" -#: commands/extension.c:1079 +#: commands/extension.c:1081 #, c-format msgid "extension script file \"%s\"" msgstr "機能拡張スクリプトファイル \"%s\"" -#: commands/extension.c:1191 +#: commands/extension.c:1193 #, c-format msgid "transaction control statements are not allowed within an extension script" msgstr "トランザクション制御ステートメントを機能拡張スクリプトの中に書くことはできません" -#: commands/extension.c:1273 +#: commands/extension.c:1275 #, c-format msgid "permission denied to create extension \"%s\"" msgstr "機能拡張\"%s\"を作成する権限がありません" -#: commands/extension.c:1276 +#: commands/extension.c:1278 #, c-format msgid "Must have CREATE privilege on current database to create this extension." msgstr "この機能拡張を生成するには現在のデータベースのCREATE権限が必要です。" -#: commands/extension.c:1277 +#: commands/extension.c:1279 #, c-format msgid "Must be superuser to create this extension." msgstr "この機能拡張を生成するにはスーパーユーザーである必要があります。" -#: commands/extension.c:1281 +#: commands/extension.c:1283 #, c-format msgid "permission denied to update extension \"%s\"" msgstr "機能拡張\"%s\"を更新する権限がありません" -#: commands/extension.c:1284 +#: commands/extension.c:1286 #, c-format msgid "Must have CREATE privilege on current database to update this extension." msgstr "この機能拡張を更新するには現在のデータベースのCREATE権限が必要です。" -#: commands/extension.c:1285 +#: commands/extension.c:1287 #, c-format msgid "Must be superuser to update this extension." msgstr "この機能拡張を更新するにはスーパーユーザーである必要があります。" -#: commands/extension.c:1418 +#: commands/extension.c:1420 #, c-format msgid "invalid character in extension owner: must not contain any of \"%s\"" msgstr "機能拡張の所有者名に不正な文字: \"%s\"のいずれの文字も含むことはできません" -#: commands/extension.c:1442 commands/extension.c:1469 +#: commands/extension.c:1444 commands/extension.c:1471 #, c-format msgid "invalid character in extension \"%s\" schema: must not contain any of \"%s\"" msgstr "機能拡張\"%s\"のスキーマ名に不正な文字: \"%s\"のいずれの文字も含むことはできません" -#: commands/extension.c:1664 +#: commands/extension.c:1666 #, c-format msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" msgstr "機能拡張\"%s\"について、バージョン\"%s\"からバージョン\"%s\"へのアップデートパスがありません" -#: commands/extension.c:1872 commands/extension.c:3573 +#: commands/extension.c:1874 commands/extension.c:3575 #, c-format msgid "version to install must be specified" msgstr "インストールするバージョンを指定してください" -#: commands/extension.c:1909 +#: commands/extension.c:1911 #, c-format msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" msgstr "機能拡張\"%s\"にはバージョン\"%s\"のインストールスクリプトもアップデートパスもありません" -#: commands/extension.c:1943 +#: commands/extension.c:1945 #, c-format msgid "extension \"%s\" must be installed in schema \"%s\"" msgstr "機能拡張\"%s\"はスキーマ\"%s\"内にインストールされていなければなりません" -#: commands/extension.c:2106 +#: commands/extension.c:2108 #, c-format msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" msgstr "機能拡張\"%s\"と\"%s\"の間に循環依存関係が検出されました" -#: commands/extension.c:2111 +#: commands/extension.c:2113 #, c-format msgid "installing required extension \"%s\"" msgstr "必要な機能拡張をインストールします:\"%s\"" -#: commands/extension.c:2134 +#: commands/extension.c:2136 #, c-format msgid "required extension \"%s\" is not installed" msgstr "要求された機能拡張\"%s\"はインストールされていません" -#: commands/extension.c:2137 +#: commands/extension.c:2139 #, c-format msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." msgstr "必要な機能拡張を一緒にインストールするには CREATE EXTENSION ... CASCADE を使ってください。" -#: commands/extension.c:2172 +#: commands/extension.c:2174 #, c-format msgid "extension \"%s\" already exists, skipping" msgstr "機能拡張\"%s\"はすでに存在します、スキップします" -#: commands/extension.c:2179 +#: commands/extension.c:2181 #, c-format msgid "extension \"%s\" already exists" msgstr "機能拡張\"%s\"はすでに存在します" -#: commands/extension.c:2190 +#: commands/extension.c:2192 #, c-format msgid "nested CREATE EXTENSION is not supported" msgstr "入れ子の CREATE EXTENSION はサポートされません" -#: commands/extension.c:2354 +#: commands/extension.c:2356 #, c-format msgid "cannot drop extension \"%s\" because it is being modified" msgstr "変更されているため拡張\"%s\"を削除できません" -#: commands/extension.c:2881 +#: commands/extension.c:2883 #, c-format msgid "%s can only be called from an SQL script executed by CREATE EXTENSION" msgstr "%s はCREATE EXTENSIONにより実行されるSQLスクリプトからのみ呼び出すことができます" -#: commands/extension.c:2893 +#: commands/extension.c:2895 #, c-format msgid "OID %u does not refer to a table" msgstr "OID %u がテーブルを参照していません" -#: commands/extension.c:2898 +#: commands/extension.c:2900 #, c-format msgid "table \"%s\" is not a member of the extension being created" msgstr "テーブル\"%s\"は生成されようとしている機能拡張のメンバではありません" -#: commands/extension.c:3297 +#: commands/extension.c:3299 #, c-format msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" msgstr "機能拡張がそのスキーマを含んでいるため、機能拡張\"%s\"をスキーマ\"%s\"に移動できません" -#: commands/extension.c:3338 commands/extension.c:3432 +#: commands/extension.c:3340 commands/extension.c:3434 #, c-format msgid "extension \"%s\" does not support SET SCHEMA" msgstr "機能拡張\"%s\"は SET SCHEMA をサポートしていません" -#: commands/extension.c:3395 +#: commands/extension.c:3397 #, c-format msgid "cannot SET SCHEMA of extension \"%s\" because other extensions prevent it" msgstr "他の機能拡張によって禁止されているため、機能拡張\"%s\"の SET SCHEMAが実行できません" -#: commands/extension.c:3397 +#: commands/extension.c:3399 #, c-format msgid "Extension \"%s\" requests no relocation of extension \"%s\"." msgstr "機能拡張\"%s\"は機能拡張\"%s\"の再配置禁止を要求しています。" -#: commands/extension.c:3434 +#: commands/extension.c:3436 #, c-format msgid "%s is not in the extension's schema \"%s\"" msgstr "機能拡張のスキーマ\"%2$s\"に%1$sが見つかりません" -#: commands/extension.c:3495 +#: commands/extension.c:3497 #, c-format msgid "nested ALTER EXTENSION is not supported" msgstr "入れ子になった ALTER EXTENSION はサポートされていません" -#: commands/extension.c:3584 +#: commands/extension.c:3586 #, c-format msgid "version \"%s\" of extension \"%s\" is already installed" msgstr "機能拡張 \"%2$s\"のバージョン\"%1$s\"はすでにインストールされています" -#: commands/extension.c:3795 +#: commands/extension.c:3797 #, c-format msgid "cannot add an object of this type to an extension" msgstr "この型のオブジェクトは機能拡張に追加できません" -#: commands/extension.c:3893 +#: commands/extension.c:3895 #, c-format msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" msgstr "スキーマ\"%s\"を拡張\"%s\"に追加できません。そのスキーマにその拡張が含まれているためです" -#: commands/extension.c:3975 commands/typecmds.c:4092 utils/fmgr/funcapi.c:727 +#: commands/extension.c:3977 commands/typecmds.c:4082 utils/fmgr/funcapi.c:727 #, c-format msgid "could not find multirange type for data type %s" msgstr "データ型%sの複範囲型がありませんでした" -#: commands/extension.c:4017 +#: commands/extension.c:4019 #, c-format msgid "file \"%s\" is too large" msgstr "ファイル\"%s\"は大きすぎます" -#: commands/extension.c:4109 utils/fmgr/dfmgr.c:625 +#: commands/extension.c:4111 utils/fmgr/dfmgr.c:625 #, c-format msgid "component in parameter \"%s\" is not an absolute path" msgstr "パラメータ\"%s\"に絶対パスではない要素が含まれています" @@ -11758,344 +11798,344 @@ msgid "cannot pass more than %d argument to a procedure" msgid_plural "cannot pass more than %d arguments to a procedure" msgstr[0] "プロシージャには %d 個以上の引数を渡すことはできません" -#: commands/indexcmds.c:663 +#: commands/indexcmds.c:673 #, c-format msgid "must specify at least one column" msgstr "少なくとも1つの列を指定しなければなりません" -#: commands/indexcmds.c:667 +#: commands/indexcmds.c:677 #, c-format msgid "cannot use more than %d columns in an index" msgstr "インデックスには%dを超える列を使用できません" -#: commands/indexcmds.c:716 +#: commands/indexcmds.c:726 #, c-format msgid "cannot create index on relation \"%s\"" msgstr "リレーション\"%s\"のインデックスを作成できません" -#: commands/indexcmds.c:742 +#: commands/indexcmds.c:752 #, c-format msgid "cannot create index on partitioned table \"%s\" concurrently" msgstr "パーティション親テーブル\"%s\"には CREATE INDEX CONCURRENTLY は実行できません" -#: commands/indexcmds.c:752 +#: commands/indexcmds.c:762 #, c-format msgid "cannot create indexes on temporary tables of other sessions" msgstr "他のセッションの一時テーブルに対するインデックスを作成できません" -#: commands/indexcmds.c:790 commands/tablecmds.c:939 commands/tablespace.c:1192 +#: commands/indexcmds.c:800 commands/tablecmds.c:946 commands/tablespace.c:1192 #, c-format msgid "cannot specify default tablespace for partitioned relations" msgstr "パーティション親リレーションにはデフォルトテーブル空間は指定できません" -#: commands/indexcmds.c:822 commands/tablecmds.c:970 commands/tablecmds.c:3777 +#: commands/indexcmds.c:832 commands/tablecmds.c:977 commands/tablecmds.c:3798 commands/tablecmds.c:23119 #, c-format msgid "only shared relations can be placed in pg_global tablespace" msgstr "共有リレーションのみをpg_globalテーブル空間に格納することができます" -#: commands/indexcmds.c:855 +#: commands/indexcmds.c:865 #, c-format msgid "substituting access method \"gist\" for obsolete method \"rtree\"" msgstr "古いメソッド\"rtree\"をアクセスメソッド\"gist\"に置換しています" -#: commands/indexcmds.c:876 +#: commands/indexcmds.c:886 #, c-format msgid "access method \"%s\" does not support unique indexes" msgstr "アクセスメソッド\"%s\"ではユニークインデックスをサポートしていません" -#: commands/indexcmds.c:881 +#: commands/indexcmds.c:891 #, c-format msgid "access method \"%s\" does not support included columns" msgstr "アクセスメソッド\"%s\"では包含列をサポートしていません" -#: commands/indexcmds.c:886 +#: commands/indexcmds.c:896 #, c-format msgid "access method \"%s\" does not support multicolumn indexes" msgstr "アクセスメソッド\"%s\"は複数列インデックスをサポートしません" -#: commands/indexcmds.c:891 +#: commands/indexcmds.c:901 #, c-format msgid "access method \"%s\" does not support exclusion constraints" msgstr "アクセスメソッド\"%s\"は排除制約をサポートしていません" -#: commands/indexcmds.c:896 +#: commands/indexcmds.c:906 #, c-format msgid "access method \"%s\" does not support WITHOUT OVERLAPS constraints" msgstr "アクセスメソッド\"%s\"はWITHOUT OVERLAPS制約をサポートしていません" -#: commands/indexcmds.c:1023 +#: commands/indexcmds.c:1033 #, c-format msgid "unsupported %s constraint with partition key definition" msgstr "パーティションキー定義では %s 制約はサポートしていません" -#: commands/indexcmds.c:1025 +#: commands/indexcmds.c:1035 #, c-format msgid "%s constraints cannot be used when partition keys include expressions." msgstr "%s 制約はパーティションキーが式を含む場合は使用できません" -#: commands/indexcmds.c:1060 commands/indexcmds.c:2498 commands/indexcmds.c:2516 executor/execReplication.c:344 parser/parse_cte.c:303 parser/parse_oper.c:224 utils/adt/array_userfuncs.c:1419 utils/adt/array_userfuncs.c:1562 utils/adt/arrayfuncs.c:3878 utils/adt/arrayfuncs.c:4431 utils/adt/arrayfuncs.c:6465 utils/adt/rowtypes.c:1220 +#: commands/indexcmds.c:1070 commands/indexcmds.c:2508 commands/indexcmds.c:2526 executor/execReplication.c:344 parser/parse_cte.c:303 parser/parse_oper.c:224 utils/adt/array_userfuncs.c:1419 utils/adt/array_userfuncs.c:1562 utils/adt/arrayfuncs.c:3878 utils/adt/arrayfuncs.c:4431 utils/adt/arrayfuncs.c:6465 utils/adt/rowtypes.c:1220 #, c-format msgid "could not identify an equality operator for type %s" msgstr "型%sの等価演算子を特定できませんでした" -#: commands/indexcmds.c:1061 commands/indexcmds.c:2519 +#: commands/indexcmds.c:1071 commands/indexcmds.c:2529 #, c-format msgid "There is no suitable operator in operator family \"%s\" for access method \"%s\"." msgstr "アクセスメソッド\"%2$s\"に対する演算子族\"%1$s\"に適切な演算子がありません。" -#: commands/indexcmds.c:1081 +#: commands/indexcmds.c:1091 #, c-format msgid "cannot match partition key to index on column \"%s\" using non-equal operator \"%s\"" msgstr "パーティションキーの、列\"%s\"上のインデックスへの適合を非等価演算子\"%s\"を使って行うことはできません" #. translator: %s is UNIQUE, PRIMARY KEY, etc -#: commands/indexcmds.c:1098 +#: commands/indexcmds.c:1108 #, c-format msgid "%s constraint on partitioned table must include all partitioning columns" msgstr "パーティション親テーブル上の%s制約はすべてのパーティショニング列を含まなければなりません" #. translator: first %s is UNIQUE, PRIMARY KEY, etc -#: commands/indexcmds.c:1101 +#: commands/indexcmds.c:1111 #, c-format msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." msgstr "テーブル\"%2$s\"上の%1$s制約にパーティションキーの一部である列\"%3$s\"が含まれていません。" -#: commands/indexcmds.c:1123 commands/indexcmds.c:1155 +#: commands/indexcmds.c:1133 commands/indexcmds.c:1165 #, c-format msgid "index creation on system columns is not supported" msgstr "システム列へのインデックス作成はサポートされていません" -#: commands/indexcmds.c:1131 +#: commands/indexcmds.c:1141 #, c-format msgid "primary keys on virtual generated columns are not supported" msgstr "仮想生成列に対する主キーはサポートされていません" -#: commands/indexcmds.c:1133 commands/indexcmds.c:1173 +#: commands/indexcmds.c:1143 commands/indexcmds.c:1183 #, c-format msgid "unique constraints on virtual generated columns are not supported" msgstr "一意性制約は仮想生成列ではサポートされていません" -#: commands/indexcmds.c:1134 commands/indexcmds.c:1174 +#: commands/indexcmds.c:1144 commands/indexcmds.c:1184 #, c-format msgid "indexes on virtual generated columns are not supported" msgstr "仮想生成列に対するインデックスはサポートされていません" -#: commands/indexcmds.c:1406 tcop/utility.c:1521 +#: commands/indexcmds.c:1416 tcop/utility.c:1521 #, c-format msgid "cannot create unique index on partitioned table \"%s\"" msgstr "パーティション親テーブル\"%s\"にはユニークインデックスを構築できません" -#: commands/indexcmds.c:1408 tcop/utility.c:1523 +#: commands/indexcmds.c:1418 tcop/utility.c:1523 #, c-format msgid "Table \"%s\" contains partitions that are foreign tables." msgstr "テーブル\"%s\"は外部テーブルを子テーブルとして含んでいます" -#: commands/indexcmds.c:1868 +#: commands/indexcmds.c:1878 #, c-format msgid "functions in index predicate must be marked IMMUTABLE" msgstr "インデックスの述部の関数はIMMUTABLEマークが必要です" -#: commands/indexcmds.c:1966 parser/parse_utilcmd.c:2741 parser/parse_utilcmd.c:2930 +#: commands/indexcmds.c:1976 parser/parse_utilcmd.c:2741 parser/parse_utilcmd.c:2930 #, c-format msgid "column \"%s\" named in key does not exist" msgstr "キーとして指名された列\"%s\"は存在しません" -#: commands/indexcmds.c:1992 parser/parse_utilcmd.c:1988 +#: commands/indexcmds.c:2002 parser/parse_utilcmd.c:1988 #, c-format msgid "expressions are not supported in included columns" msgstr "包含列では式はサポートされません" -#: commands/indexcmds.c:2034 +#: commands/indexcmds.c:2044 #, c-format msgid "functions in index expression must be marked IMMUTABLE" msgstr "式インデックスの関数はIMMUTABLEマークが必要です" -#: commands/indexcmds.c:2050 +#: commands/indexcmds.c:2060 #, c-format msgid "including column does not support a collation" msgstr "包含列は照合順序をサポートしません" -#: commands/indexcmds.c:2055 +#: commands/indexcmds.c:2065 #, c-format msgid "including column does not support an operator class" msgstr "包含列は演算子クラスをサポートしません" -#: commands/indexcmds.c:2060 +#: commands/indexcmds.c:2070 #, c-format msgid "including column does not support ASC/DESC options" msgstr "包含列は ASC/DESC オプションをサポートしません" -#: commands/indexcmds.c:2065 +#: commands/indexcmds.c:2075 #, c-format msgid "including column does not support NULLS FIRST/LAST options" msgstr "包含列は NULLS FIRST/LAST オプションをサポートしません" -#: commands/indexcmds.c:2109 +#: commands/indexcmds.c:2119 #, c-format msgid "could not determine which collation to use for index expression" msgstr "インデックス式で使用する照合順序を特定できませんでした" -#: commands/indexcmds.c:2118 commands/tablecmds.c:20273 commands/typecmds.c:814 parser/parse_expr.c:2837 parser/parse_type.c:568 parser/parse_utilcmd.c:4389 utils/adt/misc.c:603 +#: commands/indexcmds.c:2128 commands/tablecmds.c:20560 commands/typecmds.c:814 parser/parse_expr.c:2837 parser/parse_type.c:568 parser/parse_utilcmd.c:4385 utils/adt/misc.c:603 #, c-format msgid "collations are not supported by type %s" msgstr "%s 型では照合順序はサポートされません" -#: commands/indexcmds.c:2186 +#: commands/indexcmds.c:2196 #, c-format msgid "operator %s is not commutative" msgstr "演算子 %s は可換ではありません" -#: commands/indexcmds.c:2188 +#: commands/indexcmds.c:2198 #, c-format msgid "Only commutative operators can be used in exclusion constraints." msgstr "排除制約で使えるのは可換演算子だけです" -#: commands/indexcmds.c:2199 +#: commands/indexcmds.c:2209 #, c-format msgid "operator %s is not a member of operator family \"%s\"" msgstr "演算子%sは演算子族\"%s\"のメンバーではありません" -#: commands/indexcmds.c:2202 +#: commands/indexcmds.c:2212 #, c-format msgid "The exclusion operator must be related to the index operator class for the constraint." msgstr "この排除に使用する演算子はこの制約に使用するインデックス演算子に関連付けられている必要があります。" -#: commands/indexcmds.c:2252 +#: commands/indexcmds.c:2262 #, c-format msgid "access method \"%s\" does not support ASC/DESC options" msgstr "アクセスメソッド\"%s\"はASC/DESCオプションをサポートしません" -#: commands/indexcmds.c:2258 +#: commands/indexcmds.c:2268 #, c-format msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "アクセスメソッド\"%s\"はNULLS FIRST/LASTオプションをサポートしません" -#: commands/indexcmds.c:2303 commands/tablecmds.c:20298 commands/tablecmds.c:20304 commands/typecmds.c:2381 parser/analyze.c:1505 +#: commands/indexcmds.c:2313 commands/tablecmds.c:20585 commands/tablecmds.c:20591 commands/typecmds.c:2381 parser/analyze.c:1505 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" msgstr "アクセスメソッド\"%2$s\"にはデータ型%1$s用のデフォルトの演算子クラスがありません" -#: commands/indexcmds.c:2305 +#: commands/indexcmds.c:2315 #, c-format msgid "You must specify an operator class for the index or define a default operator class for the data type." msgstr "このインデックスの演算子クラスを指定するか、あるいはこのデータ型のデフォルト演算子クラスを定義しなければなりません。" -#: commands/indexcmds.c:2334 commands/indexcmds.c:2342 commands/opclasscmds.c:205 +#: commands/indexcmds.c:2344 commands/indexcmds.c:2352 commands/opclasscmds.c:205 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\"" msgstr "アクセスメソッド\"%2$s\"用の演算子クラス\"%1$s\"は存在しません" -#: commands/indexcmds.c:2356 commands/typecmds.c:2369 +#: commands/indexcmds.c:2366 commands/typecmds.c:2369 #, c-format msgid "operator class \"%s\" does not accept data type %s" msgstr "演算子クラス\"%s\"はデータ型%sを受け付けません" -#: commands/indexcmds.c:2446 +#: commands/indexcmds.c:2456 #, c-format msgid "there are multiple default operator classes for data type %s" msgstr "データ型%sには複数のデフォルトの演算子クラスがあります" -#: commands/indexcmds.c:2499 commands/indexcmds.c:2517 +#: commands/indexcmds.c:2509 commands/indexcmds.c:2527 #, c-format msgid "could not identify an overlaps operator for type %s" msgstr "型%sの重複検出演算子を特定できませんでした" -#: commands/indexcmds.c:2500 commands/indexcmds.c:2518 +#: commands/indexcmds.c:2510 commands/indexcmds.c:2528 #, c-format msgid "could not identify a contained-by operator for type %s" msgstr "型%sの被包含演算子を特定できませんでした" -#: commands/indexcmds.c:2501 commands/tablecmds.c:10471 +#: commands/indexcmds.c:2511 commands/tablecmds.c:10508 #, c-format msgid "Could not translate compare type %d for operator family \"%s\" of access method \"%s\"." msgstr "アクセスメソッド\"%3$s\"の演算子ファミリー\"%2$s\"の比較方式%1$dを変換できませんでした。" -#: commands/indexcmds.c:3056 statistics/stat_utils.c:190 +#: commands/indexcmds.c:3181 statistics/stat_utils.c:190 #, c-format msgid "index \"%s\" was concurrently dropped" msgstr "インデックス \"%s\"の削除が並行して行われました" -#: commands/indexcmds.c:3106 +#: commands/indexcmds.c:3231 #, c-format msgid "table \"%s\" has no indexes that can be reindexed concurrently" msgstr "テーブル\"%s\"には並行インデックス再作成が可能なインデックスがありません" -#: commands/indexcmds.c:3120 +#: commands/indexcmds.c:3245 #, c-format msgid "table \"%s\" has no indexes to reindex" msgstr "テーブル\"%s\"には再構築すべきインデックスはありません" -#: commands/indexcmds.c:3167 commands/indexcmds.c:3678 commands/indexcmds.c:3808 +#: commands/indexcmds.c:3292 commands/indexcmds.c:3803 commands/indexcmds.c:3933 #, c-format msgid "cannot reindex system catalogs concurrently" msgstr "システムカタログではインデックスの並行再構築はできません" -#: commands/indexcmds.c:3191 +#: commands/indexcmds.c:3316 #, c-format msgid "can only reindex the currently open database" msgstr "現在オープンしているデータベースのみをインデックス再構築することができます" -#: commands/indexcmds.c:3283 +#: commands/indexcmds.c:3408 #, c-format msgid "cannot reindex system catalogs concurrently, skipping all" msgstr "システムカタログではインデックスの並行再構築はできません、全てスキップします" -#: commands/indexcmds.c:3316 +#: commands/indexcmds.c:3441 #, c-format msgid "cannot move system relations, skipping all" msgstr "システムリレーションは移動できません、すべてスキップします" -#: commands/indexcmds.c:3362 +#: commands/indexcmds.c:3487 #, c-format msgid "while reindexing partitioned table \"%s.%s\"" msgstr "パーティションテーブル\"%s.%s\"のインデックス再構築中" -#: commands/indexcmds.c:3365 +#: commands/indexcmds.c:3490 #, c-format msgid "while reindexing partitioned index \"%s.%s\"" msgstr "パーティションインデックス\"%s.%s\"のインデックス再構築中" -#: commands/indexcmds.c:3558 commands/indexcmds.c:4455 +#: commands/indexcmds.c:3683 commands/indexcmds.c:4580 #, c-format msgid "table \"%s.%s\" was reindexed" msgstr "テーブル\"%s.%s\"のインデックス再構築が完了しました" -#: commands/indexcmds.c:3710 commands/indexcmds.c:3763 +#: commands/indexcmds.c:3835 commands/indexcmds.c:3888 #, c-format msgid "skipping reindex of invalid index \"%s.%s\"" msgstr "無効なインデックス\"%s.%s\"の再構築をスキップします" -#: commands/indexcmds.c:3713 commands/indexcmds.c:3766 +#: commands/indexcmds.c:3838 commands/indexcmds.c:3891 #, c-format msgid "Use DROP INDEX or REINDEX INDEX." msgstr "DROP INDEXあるいはREINDEX INDEXを使用してください。" -#: commands/indexcmds.c:3717 +#: commands/indexcmds.c:3842 #, c-format msgid "cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping" msgstr "排他制約インデックス\"%s.%s\"を並行再構築することはできません、スキップします " -#: commands/indexcmds.c:3873 +#: commands/indexcmds.c:3998 #, c-format msgid "cannot reindex this type of relation concurrently" msgstr "このタイプのリレーションでインデックス並列再構築はできません" -#: commands/indexcmds.c:3891 +#: commands/indexcmds.c:4016 #, c-format msgid "cannot move non-shared relation to tablespace \"%s\"" msgstr "テーブルスペース\"%s\"への非共有リレーションの移動はできません" -#: commands/indexcmds.c:4436 commands/indexcmds.c:4448 +#: commands/indexcmds.c:4561 commands/indexcmds.c:4573 #, c-format msgid "index \"%s.%s\" was reindexed" msgstr " インデックス\"%s.%s\"の再構築が完了しました " -#: commands/indexcmds.c:4438 commands/indexcmds.c:4457 +#: commands/indexcmds.c:4563 commands/indexcmds.c:4582 #, c-format msgid "%s." msgstr "%s。" -#: commands/lockcmds.c:91 +#: commands/lockcmds.c:103 #, c-format msgid "cannot lock relation \"%s\"" msgstr "リレーション\"%s\"はロックできません" @@ -12440,42 +12480,52 @@ msgstr "演算子の属性\"%s\"は変更できません" msgid "operator attribute \"%s\" cannot be changed if it has already been set" msgstr "演算子の属性\"%s\"は、すでに設定されている場合には変更できません" -#: commands/policy.c:86 commands/policy.c:379 commands/repack.c:624 commands/statscmds.c:154 commands/tablecmds.c:1865 commands/tablecmds.c:2468 commands/tablecmds.c:3891 commands/tablecmds.c:6893 commands/tablecmds.c:10227 commands/tablecmds.c:19839 commands/tablecmds.c:19874 commands/trigger.c:320 commands/trigger.c:1339 commands/trigger.c:1449 rewrite/rewriteDefine.c:268 rewrite/rewriteDefine.c:778 rewrite/rewriteRemove.c:74 +#: commands/policy.c:90 +#, c-format +msgid "cannot create policy on conflict log table \"%s\"" +msgstr "競合ログテーブル\"%s\"ではポリシーを作成できません" + +#: commands/policy.c:92 commands/statscmds.c:162 commands/tablecmds.c:2770 commands/tablecmds.c:3920 commands/tablecmds.c:6938 commands/tablecmds.c:10259 commands/tablecmds.c:20108 commands/tablecmds.c:20155 commands/trigger.c:327 commands/trigger.c:1469 rewrite/rewriteDefine.c:275 rewrite/rewriteDefine.c:782 +#, c-format +msgid "Conflict log tables are system-managed tables for logical replication conflicts." +msgstr "競合ログテーブルは、論理レプリケーションの競合を記録するためのシステム管理テーブルです。" + +#: commands/policy.c:98 commands/policy.c:391 commands/repack.c:637 commands/statscmds.c:168 commands/tablecmds.c:1872 commands/tablecmds.c:2477 commands/tablecmds.c:3925 commands/tablecmds.c:6943 commands/tablecmds.c:10264 commands/tablecmds.c:20114 commands/tablecmds.c:20161 commands/trigger.c:332 commands/trigger.c:1351 commands/trigger.c:1474 rewrite/rewriteDefine.c:280 rewrite/rewriteDefine.c:787 rewrite/rewriteRemove.c:74 #, c-format msgid "permission denied: \"%s\" is a system catalog" msgstr "権限がありません: \"%s\"はシステムカタログです" -#: commands/policy.c:169 +#: commands/policy.c:181 #, c-format msgid "ignoring specified roles other than PUBLIC" msgstr "PUBLIC以外の指定されたロールを無視します" -#: commands/policy.c:170 +#: commands/policy.c:182 #, c-format msgid "All roles are members of the PUBLIC role." msgstr "全てのロールがPUBLICロールのメンバーです。" -#: commands/policy.c:603 +#: commands/policy.c:615 #, c-format msgid "WITH CHECK cannot be applied to SELECT or DELETE" msgstr "SELECTまたはDELETEには WITH CHECK を適用できません" -#: commands/policy.c:612 commands/policy.c:915 +#: commands/policy.c:624 commands/policy.c:927 #, c-format msgid "only WITH CHECK expression allowed for INSERT" msgstr "INSERTではWITH CHECK式のみが指定可能です" -#: commands/policy.c:686 commands/policy.c:1138 +#: commands/policy.c:698 commands/policy.c:1150 #, c-format msgid "policy \"%s\" for table \"%s\" already exists" msgstr "テーブル\"%2$s\"に対するポリシ\"%1$s\"はすでに存在します" -#: commands/policy.c:887 commands/policy.c:1166 commands/policy.c:1237 +#: commands/policy.c:899 commands/policy.c:1178 commands/policy.c:1249 #, c-format msgid "policy \"%s\" for table \"%s\" does not exist" msgstr "テーブル\"%2$s\"に対するポリシ\"%1$s\"は存在しません" -#: commands/policy.c:905 +#: commands/policy.c:917 #, c-format msgid "only USING expression allowed for SELECT, DELETE" msgstr "SELECT、DELETEにはUSING式のみが指定可能です" @@ -12640,42 +12690,52 @@ msgstr "ラベル\"%s\"の定義で、プロパティ数が一致していませ msgid "mismatching property names in definition of label \"%s\"" msgstr "ラベル\"%s\"の定義内に,プロパティ名の不一致があります" -#: commands/propgraphcmds.c:1329 commands/propgraphcmds.c:1379 +#: commands/propgraphcmds.c:1334 commands/propgraphcmds.c:1384 #, c-format msgid "cannot add temporary element table to non-temporary property graph" msgstr "一時要素テーブルを非一時プロパティ・グラフに追加することはできません" -#: commands/propgraphcmds.c:1330 commands/propgraphcmds.c:1380 +#: commands/propgraphcmds.c:1335 commands/propgraphcmds.c:1385 #, c-format msgid "Table \"%s\" is a temporary table." msgstr "テーブル\"%s\"は一時テーブルです。" -#: commands/propgraphcmds.c:1349 commands/propgraphcmds.c:1418 +#: commands/propgraphcmds.c:1354 commands/propgraphcmds.c:1423 #, c-format msgid "alias \"%s\" already exists in property graph \"%s\"" msgstr "別名\"%s\"はプロパティ・グラフ\"%s\"内にすでに存在します" -#: commands/propgraphcmds.c:1509 commands/propgraphcmds.c:1521 commands/propgraphcmds.c:1555 commands/propgraphcmds.c:1566 commands/propgraphcmds.c:1598 commands/propgraphcmds.c:1610 +#: commands/propgraphcmds.c:1519 commands/propgraphcmds.c:1555 commands/propgraphcmds.c:1605 commands/propgraphcmds.c:1643 #, c-format msgid "property graph \"%s\" element \"%s\" has no label \"%s\"" msgstr "プロパティグラフ\"%s\"の要素\"%s\"にラベル\"%s\"は存在しません" -#: commands/propgraphcmds.c:1627 +#: commands/propgraphcmds.c:1566 +#, c-format +msgid "cannot drop the last label from element \"%s\"" +msgstr "要素\"%s\"から最後のラベルの削除ができません" + +#: commands/propgraphcmds.c:1568 +#, c-format +msgid "Every element must have at least one label." +msgstr "各々の要素には指定ひとつのラベルが必要です。" + +#: commands/propgraphcmds.c:1665 #, c-format msgid "property graph \"%s\" element \"%s\" label \"%s\" has no property \"%s\"" msgstr "プロパティグラフ\"%s\"、要素\"%s\"のラベル\"%s\"にプロパティ\"%s\"は存在しません" -#: commands/propgraphcmds.c:1693 commands/propgraphcmds.c:1725 +#: commands/propgraphcmds.c:1729 commands/propgraphcmds.c:1761 #, c-format msgid "property graph \"%s\" has no element with alias \"%s\"" msgstr "プロパティ・グラフ\"%s\"に\"%s\"という別名の要素はありません" -#: commands/propgraphcmds.c:1700 +#: commands/propgraphcmds.c:1736 #, c-format msgid "element \"%s\" of property graph \"%s\" is not a vertex" msgstr "プロパティ・グラフ\"%2$s\"の要素\"%1$s\"は頂点ではありません" -#: commands/propgraphcmds.c:1732 +#: commands/propgraphcmds.c:1768 #, c-format msgid "element \"%s\" of property graph \"%s\" is not an edge" msgstr "プロパティ・グラフ\"%2$s\"の要素\"%1$s\"は辺ではありません" @@ -12879,7 +12939,7 @@ msgstr "パブリケーション\"%s\"は ALL SEQUENCES の操作をサポート msgid "This operation requires the publication to be defined as FOR ALL TABLES/SEQUENCES or to be empty." msgstr "この操作では、パブリケーションは FOR ALL TABLES/SEQUENCES として定義されているか、空である必要があります。" -#: commands/publicationcmds.c:1671 commands/publicationcmds.c:1711 commands/publicationcmds.c:2245 utils/cache/lsyscache.c:3912 +#: commands/publicationcmds.c:1671 commands/publicationcmds.c:1711 commands/publicationcmds.c:2245 utils/cache/lsyscache.c:3987 #, c-format msgid "publication \"%s\" does not exist" msgstr "パブリケーション\"%s\"は存在しません" @@ -12939,135 +12999,150 @@ msgstr "パブリケーションパラメータ\"%s\"の値が不正です: \"%s msgid "Valid values are \"%s\" and \"%s\"." msgstr "有効な値は\"%s\"と\"%s\"です。" -#: commands/repack.c:266 +#: commands/repack.c:274 #, c-format msgid "CONCURRENTLY option not supported for %s" msgstr "CONCURRENTLYオプションは、%s ではサポートされていません" -#: commands/repack.c:315 +#: commands/repack.c:328 #, c-format msgid "cannot execute %s on multiple tables" msgstr "複数テーブルに対して %s は実行できません" -#: commands/repack.c:331 +#: commands/repack.c:344 #, c-format msgid "%s is not supported for partitioned tables" msgstr "パーティション親テーブルに対して %s はサポートされていません" -#: commands/repack.c:333 +#: commands/repack.c:346 #, c-format msgid "Consider running the command on individual partitions." msgstr "このコマンドを子テーブルに対して個別に実行してください。" -#: commands/repack.c:338 +#: commands/repack.c:351 #, c-format msgid "%s requires an explicit table name" msgstr "%s ではテーブル名を明示的に指定する必要があります" -#: commands/repack.c:396 commands/repack.c:2454 +#: commands/repack.c:409 commands/repack.c:2500 #, c-format msgid "there is no previously clustered index for table \"%s\"" msgstr "テーブル\"%s\"には事前にクラスタ化されたインデックスはありません" #. translator: first %s is name of a SQL command, eg. REPACK -#: commands/repack.c:402 +#: commands/repack.c:415 #, c-format msgid "cannot execute %s on partitioned table \"%s\" USING INDEX with no index name" msgstr "パーティション親テーブル\"%2$s\"に対して、インデックス名なしの USING INDEX を指定した %1$s を実行することはできません" #. translator: first %s is name of a SQL command, eg. REPACK -#: commands/repack.c:574 +#: commands/repack.c:587 #, c-format msgid "cannot execute %s on a shared catalog" msgstr "共有カタログに対しては %s を実行できません" #. translator: first %s is name of a SQL command, eg. REPACK -#: commands/repack.c:591 commands/repack.c:2374 +#: commands/repack.c:604 commands/repack.c:2420 #, c-format msgid "cannot execute %s on temporary tables of other sessions" msgstr "ほかのセッションの一時テーブルに対しては %s を実行できません" -#: commands/repack.c:626 +#: commands/repack.c:639 #, c-format msgid "System catalogs can only be clustered by the index they're already clustered on, if any, unless \"%s\" is enabled." msgstr "\"%s\"が有効でない限り、既存のクラスタ化インデックスが存在する場合には、システムカタログはそのインデックスでのみクラスタ化可能です。" -#: commands/repack.c:773 commands/tablecmds.c:18797 +#: commands/repack.c:785 commands/tablecmds.c:19060 #, c-format msgid "\"%s\" is not an index for table \"%s\"" msgstr "\"%s\"はテーブル\"%s\"のインデックスではありません" -#: commands/repack.c:781 +#: commands/repack.c:793 #, c-format msgid "cannot cluster on index \"%s\" because access method does not support clustering" msgstr "インデックス\"%s\"でクラスタ化できません。アクセスメソッドがクラスタ化をサポートしないためです" -#: commands/repack.c:793 +#: commands/repack.c:805 #, c-format msgid "cannot cluster on partial index \"%s\"" msgstr "部分インデックス\"%s\"をクラスタ化できません" -#: commands/repack.c:807 +#: commands/repack.c:819 #, c-format msgid "cannot cluster on invalid index \"%s\"" msgstr "無効なインデックス\"%s\"ではクラスタ化できません" -#: commands/repack.c:896 commands/repack.c:908 commands/repack.c:917 commands/repack.c:927 +#: commands/repack.c:907 #, c-format -msgid "cannot repack relation \"%s\"" -msgstr "リレーション\"%s\"はREPACKできません" +msgid "cannot execute %s in this configuration" +msgstr "この構成では %s を実行できません" -#: commands/repack.c:898 +#: commands/repack.c:909 +#, c-format +msgid "%s requires \"wal_level\" to be set to \"replica\" or higher." +msgstr "%s では\"wal_level\"を\"replica\"またはそれより上位の設定にしてください。" + +#: commands/repack.c:916 commands/repack.c:928 commands/repack.c:937 commands/repack.c:951 commands/repack.c:972 commands/repack.c:981 +#, c-format +msgid "cannot execute %s on relation \"%s\"" +msgstr "リレーション\"%s\"に対して %s は実行できません" + +#: commands/repack.c:918 #, c-format msgid "%s is not supported for catalog relations." msgstr "%s はカタログリレーションに対してはサポートされません。" -#: commands/repack.c:910 +#: commands/repack.c:930 #, c-format msgid "%s is not supported for TOAST relations." msgstr "%s はカタログリレーションに対してはサポートされません。" -#: commands/repack.c:919 +#: commands/repack.c:939 #, c-format msgid "%s is only allowed for permanent relations." msgstr "%s は永続リレーションに対してのみ実行可能です。" -#: commands/repack.c:929 +#: commands/repack.c:953 #, c-format -msgid "Relation \"%s\" has insufficient replication identity." -msgstr "リレーション\"%s\"のレプリケーション識別の定義が不十分です。" +msgid "%s does not support tables with %s." +msgstr "%s は、%s が設定されたテーブルをサポートしていません。" -#: commands/repack.c:943 +#: commands/repack.c:975 #, c-format -msgid "cannot process relation \"%s\"" -msgstr "リレーション\"%s\"を処理できません" +msgid "%s does not support deferrable primary keys." +msgstr "%s は遅延可能な主キーをサポートしません。" -#: commands/repack.c:945 +#: commands/repack.c:977 +#, c-format +msgid "Use ALTER TABLE ... REPLICA IDENTITY USING INDEX to designate another index as replica identity." +msgstr "Use ALTER TABLE ... REPLICA IDENTITY USING INDEX を使用して、ほかのインデックスを複製識別として指定してください。" + +#: commands/repack.c:983 #, c-format msgid "Relation \"%s\" has no identity index." msgstr "リレーション\"%s\"には識別インデックスがありません。" -#: commands/repack.c:1386 +#: commands/repack.c:1432 #, c-format msgid "repacking \"%s.%s\" using index scan on \"%s\"" msgstr "\"%3$s\"に対するインデックススキャンを使って\"%1$s.%2$s\"をREPACKしています" -#: commands/repack.c:1392 +#: commands/repack.c:1438 #, c-format msgid "repacking \"%s.%s\" using sequential scan and sort" msgstr "シーケンシャルスキャンとソートを使って\"%s.%s\"をREPACKしています" -#: commands/repack.c:1397 +#: commands/repack.c:1443 #, c-format msgid "repacking \"%s.%s\" in physical order" msgstr "\"%s.%s\"を物理順でREPACKしています" -#: commands/repack.c:1429 +#: commands/repack.c:1475 #, c-format msgid "\"%s.%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" msgstr "\"%1$s.%2$s\": %5$u ページ中に見つかった行バージョン: 移動可能 %3$.0f 行、削除不可 %4$.0f 行" -#: commands/repack.c:1434 +#: commands/repack.c:1480 #, c-format msgid "" "%.0f dead row versions cannot be removed yet.\n" @@ -13076,67 +13151,57 @@ msgstr "" "%.0f 個の無効な行が今はまだ削除できません。\n" "%s." -#: commands/repack.c:2320 +#: commands/repack.c:2366 #, c-format msgid "permission denied to execute %s on \"%s\", skipping it" msgstr "\"%s\"に対して %s を実行する権限がありません、スキップします" -#: commands/repack.c:2356 commands/vacuum.c:351 +#: commands/repack.c:2402 commands/vacuum.c:351 #, c-format msgid "ANALYZE option must be specified when a column list is provided" msgstr "ANALYZE オプションは列リストが与えられているときのみ指定できます" -#: commands/repack.c:2464 commands/tablecmds.c:16730 commands/tablecmds.c:18787 +#: commands/repack.c:2510 commands/tablecmds.c:16987 commands/tablecmds.c:19050 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "テーブル\"%2$s\"にはインデックス\"%1$s\"は存在しません" -#: commands/repack.c:2660 -#, c-format -msgid "failed to apply concurrent UPDATE" -msgstr "同時実行されたUPDATEの適用に失敗しました" - -#: commands/repack.c:2696 +#: commands/repack.c:2707 commands/repack.c:2745 #, c-format -msgid "failed to apply concurrent DELETE" -msgstr "同時実行されたDELETEの適用に失敗しました" +msgid "could not apply concurrent %s on relation \"%s\"" +msgstr "リレーション\"%2$s\"に対する、並行実行された%1$sの適用に失敗しました。" -#: commands/repack.c:2771 -#, c-format -msgid "insufficient number of attributes stored separately" -msgstr "別途格納されていた属性の数が不足しています" - -#: commands/repack.c:3456 replication/logical/launcher.c:565 +#: commands/repack.c:3654 replication/logical/launcher.c:565 #, c-format msgid "out of background worker slots" msgstr "バックグラウンドワーカースロットが足りません" #. translator: %s is a GUC variable name -#: commands/repack.c:3457 replication/logical/launcher.c:468 replication/logical/launcher.c:566 replication/slot.c:1818 replication/slot.c:1838 storage/lmgr/lock.c:1051 storage/lmgr/lock.c:1089 storage/lmgr/lock.c:3009 storage/lmgr/lock.c:4386 storage/lmgr/lock.c:4451 storage/lmgr/lock.c:4801 storage/lmgr/predicate.c:2408 storage/lmgr/predicate.c:2423 storage/lmgr/predicate.c:3820 +#: commands/repack.c:3655 replication/logical/launcher.c:468 replication/logical/launcher.c:566 replication/slot.c:1814 replication/slot.c:1834 storage/lmgr/lock.c:1051 storage/lmgr/lock.c:1089 storage/lmgr/lock.c:3009 storage/lmgr/lock.c:4386 storage/lmgr/lock.c:4451 storage/lmgr/lock.c:4801 storage/lmgr/predicate.c:2408 storage/lmgr/predicate.c:2423 storage/lmgr/predicate.c:3820 #, c-format msgid "You might need to increase \"%s\"." msgstr "\"%s\"を大きくする必要があるかもしれません。" -#: commands/repack.c:3513 +#: commands/repack.c:3707 #, c-format msgid "postmaster exited during REPACK command" msgstr "REPACKコマンド実行中にpostmasterが終了しました" -#: commands/repack.c:3727 commands/repack.c:3729 +#: commands/repack.c:3934 commands/repack.c:3936 msgid "REPACK decoding worker" msgstr "REPACKデコードワーカー" -#: commands/repack_worker.c:419 postmaster/walsummarizer.c:1051 +#: commands/repack_worker.c:412 postmaster/walsummarizer.c:1051 #, c-format msgid "could not read WAL from timeline %u at %X/%08X: %s" msgstr "%X/%08Xでタイムライン%uのWALを読み取れませんでした: %s" -#: commands/repack_worker.c:435 +#: commands/repack_worker.c:429 #, c-format msgid "could not read WAL record" msgstr "WALレコードを読み取れませんでした" -#: commands/repack_worker.c:482 +#: commands/repack_worker.c:477 #, c-format msgid "waiting for WAL failed" msgstr "WALの待機に失敗しました" @@ -13297,7 +13362,7 @@ msgstr "シーケンスは関連するテーブルと同じスキーマでなけ msgid "cannot change ownership of identity sequence" msgstr "識別シーケンスの所有者は変更できません" -#: commands/sequence.c:1676 commands/tablecmds.c:16419 commands/tablecmds.c:19248 +#: commands/sequence.c:1676 commands/tablecmds.c:16676 commands/tablecmds.c:19511 #, c-format msgid "Sequence \"%s\" is linked to table \"%s\"." msgstr "シーケンス\"%s\"はテーブル\"%s\"にリンクされています" @@ -13312,409 +13377,424 @@ msgstr "CREATE STATISTICSで指定可能なリレーションは一つのみで msgid "cannot define statistics for relation \"%s\"" msgstr "リレーション\"%s\"に対して統計情報を定義できません" -#: commands/statscmds.c:210 +#: commands/statscmds.c:160 +#, c-format +msgid "cannot create statistics on conflict log table \"%s\"" +msgstr "競合ログテーブル\"%s\"では統計情報を作成できません" + +#: commands/statscmds.c:224 #, c-format msgid "statistics object \"%s\" already exists, skipping" msgstr "統計情報オブジェクト\"%s\"はすでに存在します、スキップします" -#: commands/statscmds.c:218 +#: commands/statscmds.c:232 #, c-format msgid "statistics object \"%s\" already exists" msgstr "統計情報オブジェクト\"%s\"はすでに存在します" -#: commands/statscmds.c:229 +#: commands/statscmds.c:243 #, c-format msgid "cannot have more than %d columns in statistics" msgstr "統計情報は%dを超える列を使用できません" -#: commands/statscmds.c:271 commands/statscmds.c:318 commands/statscmds.c:368 +#: commands/statscmds.c:285 commands/statscmds.c:332 commands/statscmds.c:382 #, c-format msgid "statistics creation on system columns is not supported" msgstr "システム列に対する統計情報の作成はサポートされていません" -#: commands/statscmds.c:283 commands/statscmds.c:330 +#: commands/statscmds.c:297 commands/statscmds.c:344 #, c-format msgid "cannot create multivariate statistics on column \"%s\"" msgstr "列\"%s\"の多変量統計情報は作成できません" -#: commands/statscmds.c:285 commands/statscmds.c:332 commands/statscmds.c:383 +#: commands/statscmds.c:299 commands/statscmds.c:346 commands/statscmds.c:397 #, c-format msgid "The type %s has no default btree operator class." msgstr "型\"%s\"にはデフォルトのbtree演算子クラスがありません。" -#: commands/statscmds.c:382 +#: commands/statscmds.c:396 #, c-format msgid "cannot create multivariate statistics on this expression" msgstr "この式に対する多変量統計情報は作成できません" -#: commands/statscmds.c:399 +#: commands/statscmds.c:413 #, c-format msgid "cannot create extended statistics on a single non-virtual column" msgstr "単一の非仮想列に対して拡張統計情報は作成できません" -#: commands/statscmds.c:400 +#: commands/statscmds.c:414 #, c-format msgid "Univariate statistics are already built for each individual non-virtual table column." msgstr "単変量統計情報は個々の非仮想列に対して構築済みです。" -#: commands/statscmds.c:409 +#: commands/statscmds.c:423 #, c-format msgid "cannot specify statistics kinds when building univariate statistics" msgstr "単変量統計を構築する際には、統計種別を指定できません" -#: commands/statscmds.c:436 +#: commands/statscmds.c:450 #, c-format msgid "unrecognized statistics kind \"%s\"" msgstr "認識できない統計情報種別\"%s\"" -#: commands/statscmds.c:474 +#: commands/statscmds.c:488 #, c-format msgid "duplicate column name in statistics definition" msgstr "定形情報定義中の列名が重複しています" -#: commands/statscmds.c:509 +#: commands/statscmds.c:523 #, c-format msgid "duplicate expression in statistics definition" msgstr "統計情報定義内に重複した式" -#: commands/statscmds.c:684 commands/tablecmds.c:9051 +#: commands/statscmds.c:698 commands/tablecmds.c:9076 #, c-format msgid "statistics target %d is too low" msgstr "統計情報目標%dは小さすぎます" -#: commands/statscmds.c:692 commands/tablecmds.c:9059 +#: commands/statscmds.c:706 commands/tablecmds.c:9084 #, c-format msgid "lowering statistics target to %d" msgstr "統計情報目標を%dに減らします" -#: commands/statscmds.c:716 +#: commands/statscmds.c:730 #, c-format msgid "statistics object \"%s.%s\" does not exist, skipping" msgstr "統計情報オブジェクト\"%s.%s\"は存在しません、スキップします" -#: commands/subscriptioncmds.c:381 replication/pgoutput/pgoutput.c:417 +#: commands/subscriptioncmds.c:374 +#, c-format +msgid "max_retention_duration cannot be negative" +msgstr "max_retention_duration は負数にできません" + +#: commands/subscriptioncmds.c:397 replication/pgoutput/pgoutput.c:417 #, c-format msgid "unrecognized origin value: \"%s\"" msgstr "識別できないoriginの値: \"%s\"" -#: commands/subscriptioncmds.c:404 +#: commands/subscriptioncmds.c:420 #, c-format msgid "invalid WAL location (LSN): %s" msgstr "不正なWAL位置(LSN): %s" -#: commands/subscriptioncmds.c:437 +#: commands/subscriptioncmds.c:465 #, c-format msgid "unrecognized subscription parameter: \"%s\"" msgstr "認識できないサブスクリプションパラメータ: \"%s\"" #. translator: both %s are strings of the form "option = value" -#: commands/subscriptioncmds.c:452 commands/subscriptioncmds.c:459 commands/subscriptioncmds.c:466 commands/subscriptioncmds.c:488 commands/subscriptioncmds.c:504 +#: commands/subscriptioncmds.c:480 commands/subscriptioncmds.c:487 commands/subscriptioncmds.c:494 commands/subscriptioncmds.c:516 commands/subscriptioncmds.c:532 #, c-format msgid "%s and %s are mutually exclusive options" msgstr "%s と %s は排他なオプションです" #. translator: both %s are strings of the form "option = value" -#: commands/subscriptioncmds.c:494 commands/subscriptioncmds.c:510 +#: commands/subscriptioncmds.c:522 commands/subscriptioncmds.c:538 #, c-format msgid "subscription with %s must also set %s" msgstr "%s としたサブスクリプションでは %s を設定する必要があります" -#: commands/subscriptioncmds.c:540 +#: commands/subscriptioncmds.c:594 #, c-format msgid "could not receive list of publications from the publisher: %s" msgstr "パブリケーション一覧をパブリッシャから受け取れませんでした: %s" -#: commands/subscriptioncmds.c:574 +#: commands/subscriptioncmds.c:628 #, c-format msgid "publication %s does not exist on the publisher" msgid_plural "publications %s do not exist on the publisher" msgstr[0] "パブリケーション%sはパブリッシャ上には存在しません" -#: commands/subscriptioncmds.c:666 +#: commands/subscriptioncmds.c:722 #, c-format msgid "permission denied to create subscription" msgstr "サブスクリプションを作成する権限がありません" -#: commands/subscriptioncmds.c:667 +#: commands/subscriptioncmds.c:723 #, c-format msgid "Only roles with privileges of the \"%s\" role may create subscriptions." msgstr "\"%s\"ロールの権限を持つロールのみがサブスクリプションを作成できます。" -#: commands/subscriptioncmds.c:870 commands/subscriptioncmds.c:1034 commands/subscriptioncmds.c:1286 commands/subscriptioncmds.c:2138 +#: commands/subscriptioncmds.c:960 commands/subscriptioncmds.c:1124 commands/subscriptioncmds.c:1376 commands/subscriptioncmds.c:2382 #, c-format msgid "subscription \"%s\" could not connect to the publisher: %s" msgstr "サブスクリプション\"%s\"はパブリッシャに接続できませんでした: %s" -#: commands/subscriptioncmds.c:961 +#: commands/subscriptioncmds.c:1051 #, c-format msgid "created replication slot \"%s\" on publisher" msgstr "パブリッシャ上でレプリケーションスロット\"%s\"を作成しました" -#: commands/subscriptioncmds.c:973 +#: commands/subscriptioncmds.c:1063 #, c-format msgid "subscription was created, but is not connected" msgstr "サブスクリプションは作成されましたが接続されていません" -#: commands/subscriptioncmds.c:974 +#: commands/subscriptioncmds.c:1064 #, c-format msgid "To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications." msgstr "レプリケーションを開始するには、レプリケーションスロットを手動で作成し、サブスクリプションを有効化したうえで、パブリケーションをリフレッシュするようにサブスクリプションを変更する必要があります。" -#: commands/subscriptioncmds.c:1383 +#: commands/subscriptioncmds.c:1473 #, c-format msgid "cannot set option \"%s\" for enabled subscription" msgstr "有効にされているサブスクリプションにはオプション”%s”を指定できません" -#: commands/subscriptioncmds.c:1397 +#: commands/subscriptioncmds.c:1487 #, c-format msgid "cannot set option \"%s\" for a subscription that does not have a slot name" msgstr "スロット名を指定されていないサブスクリプションのオプション\"%s\"を設定することはできません" -#: commands/subscriptioncmds.c:1445 commands/subscriptioncmds.c:2215 commands/subscriptioncmds.c:2648 utils/cache/lsyscache.c:3962 +#: commands/subscriptioncmds.c:1602 commands/subscriptioncmds.c:2544 commands/subscriptioncmds.c:2966 utils/cache/lsyscache.c:4037 #, c-format msgid "subscription \"%s\" does not exist" msgstr "サブスクリプション\"%s\"は存在しません" -#: commands/subscriptioncmds.c:1520 +#: commands/subscriptioncmds.c:1739 #, c-format msgid "cannot set %s for enabled subscription" msgstr "有効にされているサブスクリプションには %s を指定できません" -#: commands/subscriptioncmds.c:1605 +#: commands/subscriptioncmds.c:1824 #, c-format msgid "\"slot_name\" and \"two_phase\" cannot be altered at the same time" msgstr "\"slot_name\"と\"two_phase\"は同時に変更できません" -#: commands/subscriptioncmds.c:1621 +#: commands/subscriptioncmds.c:1840 #, c-format msgid "cannot alter \"two_phase\" when logical replication worker is still running" msgstr "論理レプリケーションワーカーがまだ実行中のため\"two_phase\"は変更できません" -#: commands/subscriptioncmds.c:1622 commands/subscriptioncmds.c:1706 +#: commands/subscriptioncmds.c:1841 commands/subscriptioncmds.c:1925 #, c-format msgid "Try again after some time." msgstr "少し待ってから再試行してください。" -#: commands/subscriptioncmds.c:1635 +#: commands/subscriptioncmds.c:1854 #, c-format msgid "cannot disable \"two_phase\" when prepared transactions exist" msgstr "準備済みトランザクションが存在するため\"two_phase\"を無効にできません" -#: commands/subscriptioncmds.c:1636 +#: commands/subscriptioncmds.c:1855 #, c-format msgid "Resolve these transactions and try again." msgstr "トランザクションの解決後に再試行してください。" -#: commands/subscriptioncmds.c:1705 +#: commands/subscriptioncmds.c:1924 #, c-format msgid "cannot alter retain_dead_tuples when logical replication worker is still running" msgstr "論理レプリケーションワーカーがまだ実行中のため、retain_dead_tuplesは変更できません" -#: commands/subscriptioncmds.c:1778 +#: commands/subscriptioncmds.c:2025 #, c-format msgid "cannot enable subscription that does not have a slot name" msgstr "スロット名を指定されていないサブスクリプションを有効にはできません" -#: commands/subscriptioncmds.c:1917 commands/subscriptioncmds.c:1968 +#: commands/subscriptioncmds.c:2168 commands/subscriptioncmds.c:2215 #, c-format msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" msgstr "refresh指定された ALTER SUBSCRIPTION は無効化されているサブスクリプションには実行できません" -#: commands/subscriptioncmds.c:1918 +#: commands/subscriptioncmds.c:2169 #, c-format msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." msgstr "ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false) を使ってください。" -#: commands/subscriptioncmds.c:1927 commands/subscriptioncmds.c:1982 +#: commands/subscriptioncmds.c:2178 commands/subscriptioncmds.c:2229 #, c-format msgid "ALTER SUBSCRIPTION with refresh and copy_data is not allowed when two_phase is enabled" msgstr "two_phaseが有効である場合、refreshおよびcopy_data指定された ALTER SUBSCRIPTIONは実行できません" -#: commands/subscriptioncmds.c:1928 +#: commands/subscriptioncmds.c:2179 #, c-format msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION with refresh = false, or with copy_data = false, or use DROP/CREATE SUBSCRIPTION." msgstr "refresh = false または copy_data = false を指定してALTER SUBSCRIPTION ... SET PUBLICATIONを実行するか、DROP/CREATE SUBSCRIPTIONを実行してください。" #. translator: %s is an SQL ALTER command -#: commands/subscriptioncmds.c:1984 +#: commands/subscriptioncmds.c:2231 #, c-format msgid "Use %s with refresh = false, or with copy_data = false, or use DROP/CREATE SUBSCRIPTION." msgstr "refresh = false または copy_data = false を指定して%sを実行するか、DROP/CREATE SUBSCRIPTIONを実行してください。" -#: commands/subscriptioncmds.c:2006 commands/subscriptioncmds.c:2047 +#: commands/subscriptioncmds.c:2253 commands/subscriptioncmds.c:2291 #, c-format msgid "%s is not allowed for disabled subscriptions" msgstr "%s は無効化されているサブスクリプションには実行できません" -#: commands/subscriptioncmds.c:2032 +#: commands/subscriptioncmds.c:2276 #, c-format msgid "ALTER SUBSCRIPTION ... REFRESH PUBLICATION with copy_data is not allowed when two_phase is enabled" msgstr "two_phaseが有効である場合、copy_data指定の ALTER SUBSCRIPTION ... REFRESH PUBLICATION は実行できません" -#: commands/subscriptioncmds.c:2033 +#: commands/subscriptioncmds.c:2277 #, c-format msgid "Use ALTER SUBSCRIPTION ... REFRESH PUBLICATION with copy_data = false, or use DROP/CREATE SUBSCRIPTION." msgstr "ALTER SUBSCRIPTION ... REFRESH PUBLICATION を copy_data = false を指定して実行するか、DROP/CREATE SUBSCRIPTIONを実行してください。" -#: commands/subscriptioncmds.c:2081 +#: commands/subscriptioncmds.c:2323 #, c-format msgid "skip WAL location (LSN %X/%08X) must be greater than origin LSN %X/%08X" msgstr "WAL読み飛ばし位置(LSN %X/%08X)は起源LSN %X/%08Xより大きくなければなりません" -#: commands/subscriptioncmds.c:2219 +#: commands/subscriptioncmds.c:2492 +#, c-format +msgid "dropped conflict log table \"%s\" for subscription \"%s\"" +msgstr "サブスクリプション\"%2$s\"の競合ログテーブル\"%1$s\"を削除しました" + +#: commands/subscriptioncmds.c:2548 #, c-format msgid "subscription \"%s\" does not exist, skipping" msgstr "サブスクリプション\"%s\"は存在しません、スキップします" -#: commands/subscriptioncmds.c:2517 +#: commands/subscriptioncmds.c:2830 #, c-format msgid "dropped replication slot \"%s\" on publisher" msgstr "パブリッシャ上でレプリケーションスロット\"%s\"を削除しました" -#: commands/subscriptioncmds.c:2526 commands/subscriptioncmds.c:2534 +#: commands/subscriptioncmds.c:2839 commands/subscriptioncmds.c:2847 #, c-format msgid "could not drop replication slot \"%s\" on publisher: %s" msgstr "パブリッシャ上でのレプリケーションスロット\"%s\"の削除に失敗しました: %s" -#: commands/subscriptioncmds.c:2604 +#: commands/subscriptioncmds.c:2917 #, c-format msgid "new subscription owner \"%s\" does not have permission on foreign server \"%s\"" msgstr "新しいサブスクリプションオーナー\"%s\"は外部サーバー\"%s\"に対して権限がありません" -#: commands/subscriptioncmds.c:2680 +#: commands/subscriptioncmds.c:2998 #, c-format msgid "subscription with OID %u does not exist" msgstr "OID %uのサブスクリプションは存在しません" -#: commands/subscriptioncmds.c:2795 commands/subscriptioncmds.c:3179 +#: commands/subscriptioncmds.c:3113 commands/subscriptioncmds.c:3497 #, c-format msgid "could not receive list of replicated tables from the publisher: %s" msgstr "パブリッシャから複製テーブルの一覧を受け取れませんでした: %s" -#: commands/subscriptioncmds.c:2834 commands/subscriptioncmds.c:2954 +#: commands/subscriptioncmds.c:3152 commands/subscriptioncmds.c:3272 #, c-format msgid "subscription \"%s\" requested copy_data with origin = NONE but might copy data that had a different origin" msgstr "サブスクリプション\"%s\"がcopy_dataをorigin = NONEで要求しましたが、異なる起源を持つデータをコピーする可能性があります" -#: commands/subscriptioncmds.c:2836 commands/subscriptioncmds.c:2845 +#: commands/subscriptioncmds.c:3154 commands/subscriptioncmds.c:3163 #, c-format msgid "The subscription subscribes to a publication (%s) that contains tables that are written to by other subscriptions." msgid_plural "The subscription subscribes to publications (%s) that contain tables that are written to by other subscriptions." msgstr[0] "このサブスクリプションは、他のサブスクリプションによって書き込まれるテーブルを含んだパブリケーション(%s)をサブスクライブします。" -#: commands/subscriptioncmds.c:2839 +#: commands/subscriptioncmds.c:3157 #, c-format msgid "Verify that initial data copied from the publisher tables did not come from other origins." msgstr "パブリッシャテーブルからコピーされた初期データが異なる起源からのものでないことを確認してください。" -#: commands/subscriptioncmds.c:2843 +#: commands/subscriptioncmds.c:3161 #, c-format msgid "subscription \"%s\" enabled retain_dead_tuples but might not reliably detect conflicts for changes from different origins" msgstr "サブスクリプション\"%s\"はretain_dead_tuplesを有効にしていますが、他の起源からの変更による衝突を確実に検出できない可能性があります" -#: commands/subscriptioncmds.c:2848 +#: commands/subscriptioncmds.c:3166 #, c-format msgid "Consider using origin = NONE or disabling retain_dead_tuples." msgstr "origin = NONE とするか、retain_dead_tuplesを無効にすることを検討してください。" -#: commands/subscriptioncmds.c:2922 +#: commands/subscriptioncmds.c:3240 #, c-format msgid "could not receive list of replicated sequences from the publisher: %s" msgstr "パブリッシャから複製シーケンスの一覧を受け取れませんでした: %s" -#: commands/subscriptioncmds.c:2956 +#: commands/subscriptioncmds.c:3274 #, c-format msgid "The subscription subscribes to a publication (%s) that contains sequences that are written to by other subscriptions." msgid_plural "The subscription subscribes to publications (%s) that contain sequences that are written to by other subscriptions." msgstr[0] "このサブスクリプションは、他のサブスクリプションによって書き込まれるシーケンスを含んだパブリケーション(%s)をサブスクライブします。" -#: commands/subscriptioncmds.c:2959 +#: commands/subscriptioncmds.c:3277 #, c-format msgid "Verify that initial data copied from the publisher sequences did not come from other origins." msgstr "パブリッシャシーケンスからコピーされた初期データが異なる起源からのものでないことを確認してください。" -#: commands/subscriptioncmds.c:2989 +#: commands/subscriptioncmds.c:3307 #, c-format msgid "cannot enable retain_dead_tuples if the publisher is running a version earlier than PostgreSQL 19" msgstr "パブリッシャのPostgreSQLのバージョンが19未満の場合、retain_dead_tuplesを有効にできません" -#: commands/subscriptioncmds.c:2996 +#: commands/subscriptioncmds.c:3314 #, c-format msgid "could not obtain recovery progress from the publisher: %s" msgstr "リカバリ進捗をパブリッシャから取得できませんでした: %s" -#: commands/subscriptioncmds.c:3008 +#: commands/subscriptioncmds.c:3326 #, c-format msgid "cannot enable retain_dead_tuples if the publisher is in recovery" msgstr "パブリッシャがリカバリ中の場合、retain_dead_tuplesを有効にできません" -#: commands/subscriptioncmds.c:3052 +#: commands/subscriptioncmds.c:3370 #, c-format msgid "\"wal_level\" is insufficient to create the replication slot required by retain_dead_tuples" msgstr "retain_dead_tuplesが要求するレプリケーションスロットを作成するには\"wal_level\"が不十分です" -#: commands/subscriptioncmds.c:3058 +#: commands/subscriptioncmds.c:3376 #, c-format msgid "commit timestamp and origin data required for detecting conflicts won't be retained" msgstr "競合を検出するために必要なコミットタイムスタンプおよび起源データは保持されません。" -#: commands/subscriptioncmds.c:3059 +#: commands/subscriptioncmds.c:3377 #, c-format msgid "Consider setting \"%s\" to true." msgstr "\"%s\"をtrueに設定することを検討してください。" -#: commands/subscriptioncmds.c:3065 +#: commands/subscriptioncmds.c:3383 #, c-format msgid "deleted rows to detect conflicts would not be removed until the subscription is enabled" msgstr "競合検出に必要な削除済みの行はサブスクリプションが有効になるまで削除されません" -#: commands/subscriptioncmds.c:3067 +#: commands/subscriptioncmds.c:3385 #, c-format msgid "Consider setting %s to false." msgstr "%s をfalseに設定することを検討してください。" -#: commands/subscriptioncmds.c:3074 +#: commands/subscriptioncmds.c:3392 #, c-format msgid "max_retention_duration is ineffective when retain_dead_tuples is disabled" msgstr "retain_dead_tuples が無効の場合、max_retention_duration は適用されません" -#: commands/subscriptioncmds.c:3207 replication/logical/tablesync.c:851 replication/pgoutput/pgoutput.c:1191 +#: commands/subscriptioncmds.c:3525 replication/logical/tablesync.c:851 replication/pgoutput/pgoutput.c:1191 #, c-format msgid "cannot use different column lists for table \"%s.%s\" in different publications" msgstr "テーブル\"%s.%s\"に対して、異なるパブリケーションで異なる列リストを使用することはできません" -#: commands/subscriptioncmds.c:3257 +#: commands/subscriptioncmds.c:3575 #, c-format msgid "could not connect to publisher when attempting to drop replication slot \"%s\": %s" msgstr "レプリケーションスロット\"%s\"を削除する際にパブリッシャへの接続に失敗しました: %s" #. translator: %s is an SQL ALTER command -#: commands/subscriptioncmds.c:3260 +#: commands/subscriptioncmds.c:3578 #, c-format msgid "Use %s to disable the subscription, and then use %s to disassociate it from the slot." msgstr "%s でサブスクリプションを無効化してから、%s でスロットとの関連付けを解除してください。" -#: commands/subscriptioncmds.c:3291 +#: commands/subscriptioncmds.c:3609 #, c-format msgid "publication name \"%s\" used more than once" msgstr "パブリケーション名\"%s\"が2回以上使われています" -#: commands/subscriptioncmds.c:3335 +#: commands/subscriptioncmds.c:3653 #, c-format msgid "publication \"%s\" is already in subscription \"%s\"" msgstr "パブリケーション\"%s\"はサブスクリプション\"%s\"にすでに存在します" -#: commands/subscriptioncmds.c:3349 +#: commands/subscriptioncmds.c:3667 #, c-format msgid "publication \"%s\" is not in subscription \"%s\"" msgstr "パブリケーション\"%s\"はサブスクリプション\"%s\"にはありません" -#: commands/subscriptioncmds.c:3360 +#: commands/subscriptioncmds.c:3678 #, c-format msgid "cannot drop all the publications from a subscription" msgstr "サブスクリプションからすべてのパブリケーションを削除することはできません" -#: commands/subscriptioncmds.c:3417 +#: commands/subscriptioncmds.c:3735 #, c-format msgid "%s requires a Boolean value or \"parallel\"" msgstr "パラメータ\"%s\"はBoolean値または\"parallel\"のみを取ります" @@ -13775,7 +13855,7 @@ msgstr "実体化ビュー\"%s\"は存在しません、スキップします" msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." msgstr "実体化ビューを削除するにはDROP MATERIALIZED VIEWを使用してください。" -#: commands/tablecmds.c:286 commands/tablecmds.c:310 commands/tablecmds.c:21939 parser/parse_utilcmd.c:2434 +#: commands/tablecmds.c:286 commands/tablecmds.c:310 commands/tablecmds.c:22219 parser/parse_utilcmd.c:2434 #, c-format msgid "index \"%s\" does not exist" msgstr "インデックス\"%s\"は存在しません" @@ -13798,7 +13878,7 @@ msgstr "\"%s\"は型ではありません" msgid "Use DROP TYPE to remove a type." msgstr "型を削除するにはDROP TYPEを使用してください" -#: commands/tablecmds.c:298 commands/tablecmds.c:16257 commands/tablecmds.c:18950 +#: commands/tablecmds.c:298 commands/tablecmds.c:16514 commands/tablecmds.c:19213 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "外部テーブル\"%s\"は存在しません" @@ -13826,1569 +13906,1593 @@ msgstr "プロパティ・グラフ\"%s\"は存在しません、スキップし msgid "Use DROP PROPERTY GRAPH to remove a property graph." msgstr "プロパティ・グラフを削除するには DROP PROPERTY GRAPH を使用してください。" -#: commands/tablecmds.c:849 +#: commands/tablecmds.c:856 #, c-format msgid "ON COMMIT can only be used on temporary tables" msgstr "ON COMMITは一時テーブルでのみ使用できます" -#: commands/tablecmds.c:866 +#: commands/tablecmds.c:873 #, c-format msgid "partitioned tables cannot be unlogged" msgstr "パーティションテーブルはログ非取得にはできません" -#: commands/tablecmds.c:886 +#: commands/tablecmds.c:893 #, c-format msgid "cannot create temporary table within security-restricted operation" msgstr "セキュリティー制限操作中は、一時テーブルを作成できません" -#: commands/tablecmds.c:922 commands/tablecmds.c:17679 +#: commands/tablecmds.c:929 commands/tablecmds.c:17942 #, c-format msgid "relation \"%s\" would be inherited from more than once" msgstr "リレーション\"%s\"が複数回継承されました" -#: commands/tablecmds.c:1182 +#: commands/tablecmds.c:1189 #, c-format msgid "\"%s\" is not partitioned" msgstr "\"%s\"はパーティションされていません" -#: commands/tablecmds.c:1276 +#: commands/tablecmds.c:1283 #, c-format msgid "cannot partition using more than %d columns" msgstr "%d以上の列を使ったパーティションはできません" -#: commands/tablecmds.c:1332 +#: commands/tablecmds.c:1339 #, c-format msgid "cannot create foreign partition of partitioned table \"%s\"" msgstr "パーティションテーブル\"%s\"では外部子テーブルを作成できません" -#: commands/tablecmds.c:1334 +#: commands/tablecmds.c:1341 #, c-format msgid "Table \"%s\" contains indexes that are unique." msgstr "テーブル\"%s\"はユニークインデックスを持っています" -#: commands/tablecmds.c:1474 commands/tablecmds.c:15234 +#: commands/tablecmds.c:1481 commands/tablecmds.c:15491 #, c-format msgid "too many array dimensions" msgstr "配列の次元多すぎます" -#: commands/tablecmds.c:1479 parser/parse_clause.c:778 parser/parse_relation.c:1918 +#: commands/tablecmds.c:1486 parser/parse_clause.c:778 parser/parse_relation.c:1950 #, c-format msgid "column \"%s\" cannot be declared SETOF" msgstr "列\"%s\"はSETOFとして宣言できません" -#: commands/tablecmds.c:1610 +#: commands/tablecmds.c:1617 #, c-format msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" msgstr "DROP INDEX CONCURRENTLYは複数オブジェクトの削除をサポートしていません" -#: commands/tablecmds.c:1614 +#: commands/tablecmds.c:1621 #, c-format msgid "DROP INDEX CONCURRENTLY does not support CASCADE" msgstr "DROP INDEX CONCURRENTLYはCASCADEをサポートしません" -#: commands/tablecmds.c:1722 +#: commands/tablecmds.c:1729 #, c-format msgid "cannot drop partitioned index \"%s\" concurrently" msgstr "パーティション親インデックス\"%s\"は並行的に削除することはできません" -#: commands/tablecmds.c:2010 +#: commands/tablecmds.c:2017 #, c-format msgid "cannot truncate only a partitioned table" msgstr "パーティションの親テーブルのみの切り詰めはできません" -#: commands/tablecmds.c:2011 +#: commands/tablecmds.c:2018 #, c-format msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." msgstr "ONLY キーワードを指定しないでください、もしくは子テーブルに対して直接 TRUNCATE ONLY を実行してください。" -#: commands/tablecmds.c:2084 +#: commands/tablecmds.c:2091 #, c-format msgid "truncate cascades to table \"%s\"" msgstr "テーブル\"%s\"へのカスケードを削除します" -#: commands/tablecmds.c:2445 +#: commands/tablecmds.c:2452 #, c-format msgid "cannot truncate foreign table \"%s\"" msgstr "外部テーブル\"%s\"の切り詰めはできません" -#: commands/tablecmds.c:2505 +#: commands/tablecmds.c:2514 #, c-format msgid "cannot truncate temporary tables of other sessions" msgstr "他のセッションの一時テーブルを削除できません" -#: commands/tablecmds.c:2743 commands/tablecmds.c:17573 +#: commands/tablecmds.c:2752 commands/tablecmds.c:17836 #, c-format msgid "cannot inherit from partitioned table \"%s\"" msgstr "パーティション親テーブル\"%s\"からの継承はできません" -#: commands/tablecmds.c:2748 +#: commands/tablecmds.c:2757 #, c-format msgid "cannot inherit from partition \"%s\"" msgstr "パーティション子テーブル\"%s\"からの継承はできません" -#: commands/tablecmds.c:2756 parser/parse_utilcmd.c:2705 parser/parse_utilcmd.c:2899 +#: commands/tablecmds.c:2768 +#, c-format +msgid "cannot inherit from conflict log table \"%s\"" +msgstr "競合ログテーブル\"%s\"からの継承はできません" + +#: commands/tablecmds.c:2777 parser/parse_utilcmd.c:2705 parser/parse_utilcmd.c:2899 #, c-format msgid "inherited relation \"%s\" is not a table or foreign table" msgstr "継承しようとしたリレーション\"%s\"はテーブルまたは外部テーブルではありません" -#: commands/tablecmds.c:2768 commands/tablecmds.c:22801 +#: commands/tablecmds.c:2789 commands/tablecmds.c:23082 #, c-format msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" msgstr "一時リレーションを永続リレーション\"%s\"のパーティション子テーブルとして作ることはできません" -#: commands/tablecmds.c:2777 commands/tablecmds.c:17554 +#: commands/tablecmds.c:2798 commands/tablecmds.c:17817 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "一時リレーション\"%s\"から継承することはできません" -#: commands/tablecmds.c:2786 commands/tablecmds.c:17561 +#: commands/tablecmds.c:2807 commands/tablecmds.c:17824 #, c-format msgid "cannot inherit from temporary relation of another session" msgstr "他のセッションの一時リレーションから継承することはできません" -#: commands/tablecmds.c:2941 commands/tablecmds.c:2995 commands/tablecmds.c:14917 parser/parse_utilcmd.c:1438 parser/parse_utilcmd.c:1482 parser/parse_utilcmd.c:1914 parser/parse_utilcmd.c:2026 +#: commands/tablecmds.c:2962 commands/tablecmds.c:3016 commands/tablecmds.c:15174 parser/parse_utilcmd.c:1438 parser/parse_utilcmd.c:1482 parser/parse_utilcmd.c:1914 parser/parse_utilcmd.c:2026 #, c-format msgid "cannot convert whole-row table reference" msgstr "行全体テーブル参照を変換できません" -#: commands/tablecmds.c:2942 parser/parse_utilcmd.c:1439 +#: commands/tablecmds.c:2963 parser/parse_utilcmd.c:1439 #, c-format msgid "Generation expression for column \"%s\" contains a whole-row reference to table \"%s\"." msgstr "制約\"%s\"はテーブル\"%s\"への行全体参照を含みます。" -#: commands/tablecmds.c:2996 parser/parse_utilcmd.c:1483 +#: commands/tablecmds.c:3017 parser/parse_utilcmd.c:1483 #, c-format msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." msgstr "制約\"%s\"はテーブル\"%s\"への行全体参照を含みます。" -#: commands/tablecmds.c:3118 commands/tablecmds.c:3412 +#: commands/tablecmds.c:3139 commands/tablecmds.c:3433 #, c-format msgid "column \"%s\" inherits from generated column but specifies default" msgstr "列\"%s\"は生成列を継承しますが、default 指定がされています" -#: commands/tablecmds.c:3123 commands/tablecmds.c:3417 +#: commands/tablecmds.c:3144 commands/tablecmds.c:3438 #, c-format msgid "column \"%s\" inherits from generated column but specifies identity" msgstr "列\"%s\"は生成列を継承しますが、識別列と指定されています" -#: commands/tablecmds.c:3131 commands/tablecmds.c:3425 +#: commands/tablecmds.c:3152 commands/tablecmds.c:3446 #, c-format msgid "child column \"%s\" specifies generation expression" msgstr "子テーブルの列\"%s\"は生成式を指定しています" -#: commands/tablecmds.c:3133 commands/tablecmds.c:3427 +#: commands/tablecmds.c:3154 commands/tablecmds.c:3448 #, c-format msgid "A child table column cannot be generated unless its parent column is." msgstr "子テーブルの列は、親となる列が生成列でなければ生成列にはできません。" -#: commands/tablecmds.c:3139 commands/tablecmds.c:3433 commands/tablecmds.c:17841 +#: commands/tablecmds.c:3160 commands/tablecmds.c:3454 commands/tablecmds.c:18104 #, c-format msgid "column \"%s\" inherits from generated column of different kind" msgstr "列\"%s\"は異なる種類の生成列を継承しています" -#: commands/tablecmds.c:3141 commands/tablecmds.c:3435 commands/tablecmds.c:17842 +#: commands/tablecmds.c:3162 commands/tablecmds.c:3456 commands/tablecmds.c:18105 #, c-format msgid "Parent column is %s, child column is %s." msgstr "親の列は %s、子の列は %s です。" -#: commands/tablecmds.c:3188 +#: commands/tablecmds.c:3209 #, c-format msgid "column \"%s\" inherits conflicting generation expressions" msgstr "列\"%s\"は競合する生成式を継承します" -#: commands/tablecmds.c:3190 +#: commands/tablecmds.c:3211 #, c-format msgid "To resolve the conflict, specify a generation expression explicitly." msgstr "この競合を解消するには明示的に生成式を指定してください。" -#: commands/tablecmds.c:3194 +#: commands/tablecmds.c:3215 #, c-format msgid "column \"%s\" inherits conflicting default values" msgstr "列\"%s\"は競合するデフォルト値を継承します" -#: commands/tablecmds.c:3196 +#: commands/tablecmds.c:3217 #, c-format msgid "To resolve the conflict, specify a default explicitly." msgstr "競合を解消するには明示的にデフォルトを指定してください" -#: commands/tablecmds.c:3263 +#: commands/tablecmds.c:3284 #, c-format msgid "check constraint name \"%s\" appears multiple times but with different expressions" msgstr "異なる式を持つ検査制約名\"%s\"が複数あります。" -#: commands/tablecmds.c:3316 +#: commands/tablecmds.c:3337 #, c-format msgid "merging column \"%s\" with inherited definition" msgstr "継承される定義で列\"%s\"をマージしています" -#: commands/tablecmds.c:3320 +#: commands/tablecmds.c:3341 #, c-format msgid "moving and merging column \"%s\" with inherited definition" msgstr "継承される定義で列\"%s\"を移動してマージします" -#: commands/tablecmds.c:3321 +#: commands/tablecmds.c:3342 #, c-format msgid "User-specified column moved to the position of the inherited column." msgstr "ユーザーが指定した列が継承した列の位置に移動されました。" -#: commands/tablecmds.c:3333 +#: commands/tablecmds.c:3354 #, c-format msgid "column \"%s\" has a type conflict" msgstr "列\"%s\"の型が競合しています" -#: commands/tablecmds.c:3335 commands/tablecmds.c:3369 commands/tablecmds.c:3385 commands/tablecmds.c:3501 commands/tablecmds.c:3529 commands/tablecmds.c:3545 parser/parse_coerce.c:2191 parser/parse_coerce.c:2211 parser/parse_coerce.c:2231 parser/parse_coerce.c:2252 parser/parse_coerce.c:2307 parser/parse_coerce.c:2341 parser/parse_coerce.c:2417 parser/parse_coerce.c:2448 parser/parse_coerce.c:2487 parser/parse_coerce.c:2554 parser/parse_param.c:224 +#: commands/tablecmds.c:3356 commands/tablecmds.c:3390 commands/tablecmds.c:3406 commands/tablecmds.c:3522 commands/tablecmds.c:3550 commands/tablecmds.c:3566 parser/parse_coerce.c:2190 parser/parse_coerce.c:2210 parser/parse_coerce.c:2230 parser/parse_coerce.c:2251 parser/parse_coerce.c:2306 parser/parse_coerce.c:2340 parser/parse_coerce.c:2416 parser/parse_coerce.c:2447 parser/parse_coerce.c:2486 parser/parse_coerce.c:2553 parser/parse_param.c:224 #, c-format msgid "%s versus %s" msgstr "%s対%s" -#: commands/tablecmds.c:3347 +#: commands/tablecmds.c:3368 #, c-format msgid "column \"%s\" has a collation conflict" msgstr "列\"%s\"の照合順序が競合しています" -#: commands/tablecmds.c:3349 commands/tablecmds.c:3515 commands/tablecmds.c:7377 parser/parse_expr.c:4904 +#: commands/tablecmds.c:3370 commands/tablecmds.c:3536 commands/tablecmds.c:7427 parser/parse_expr.c:4914 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "\"%s\"対\"%s\"" -#: commands/tablecmds.c:3367 +#: commands/tablecmds.c:3388 #, c-format msgid "column \"%s\" has a storage parameter conflict" msgstr "列\"%s\"でストレージパラメータが競合しています" -#: commands/tablecmds.c:3383 commands/tablecmds.c:3543 +#: commands/tablecmds.c:3404 commands/tablecmds.c:3564 #, c-format msgid "column \"%s\" has a compression method conflict" msgstr "列\"%s\"で圧縮方式が競合しています" -#: commands/tablecmds.c:3487 +#: commands/tablecmds.c:3508 #, c-format msgid "merging multiple inherited definitions of column \"%s\"" msgstr "複数の継承される列\"%s\"の定義をマージしています" -#: commands/tablecmds.c:3499 +#: commands/tablecmds.c:3520 #, c-format msgid "inherited column \"%s\" has a type conflict" msgstr "継承される列\"%s\"の型が競合しています" -#: commands/tablecmds.c:3513 +#: commands/tablecmds.c:3534 #, c-format msgid "inherited column \"%s\" has a collation conflict" msgstr "継承される列 \"%s\"の照合順序が競合しています" -#: commands/tablecmds.c:3527 +#: commands/tablecmds.c:3548 #, c-format msgid "inherited column \"%s\" has a storage parameter conflict" msgstr "継承される列\"%s\"でストレージパラメータが競合しています" -#: commands/tablecmds.c:3555 +#: commands/tablecmds.c:3576 #, c-format msgid "inherited column \"%s\" has a generation conflict" msgstr "継承された列 \"%s\"の生成が競合しています" -#: commands/tablecmds.c:3786 +#: commands/tablecmds.c:3807 #, c-format msgid "cannot move temporary tables of other sessions" msgstr "他のセッションの一時テーブルを移動できません" -#: commands/tablecmds.c:3859 +#: commands/tablecmds.c:3880 #, c-format msgid "cannot rename column of typed table" msgstr "型付けされたテーブルの列をリネームできません" -#: commands/tablecmds.c:3878 +#: commands/tablecmds.c:3899 #, c-format msgid "cannot rename columns of relation \"%s\"" msgstr "リレーション\"%s\"の列名は変更できません" -#: commands/tablecmds.c:3973 +#: commands/tablecmds.c:3918 +#, c-format +msgid "cannot rename columns of conflict log table \"%s\"" +msgstr "競合ログテーブル\"%s\"の列名は変更できません" + +#: commands/tablecmds.c:4007 #, c-format msgid "inherited column \"%s\" must be renamed in child tables too" msgstr "継承される列\"%s\"の名前を子テーブルでも変更する必要があります" -#: commands/tablecmds.c:4005 +#: commands/tablecmds.c:4039 #, c-format msgid "cannot rename system column \"%s\"" msgstr "システム列%s\"の名前を変更できません" -#: commands/tablecmds.c:4020 +#: commands/tablecmds.c:4054 #, c-format msgid "cannot rename inherited column \"%s\"" msgstr "継承される列\"%s\"の名前を変更できません" -#: commands/tablecmds.c:4175 +#: commands/tablecmds.c:4209 #, c-format msgid "inherited constraint \"%s\" must be renamed in child tables too" msgstr "継承される制約\"%s\"の名前を子テーブルでも変更する必要があります" -#: commands/tablecmds.c:4182 +#: commands/tablecmds.c:4216 #, c-format msgid "cannot rename inherited constraint \"%s\"" msgstr "継承される制約\"%s\"の名前を変更できません" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:4482 +#: commands/tablecmds.c:4516 #, c-format msgid "cannot %s \"%s\" because it is being used by active queries in this session" msgstr "このセッションで実行中の問い合わせで使用されているため\"%2$s\"を%1$sできません" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:4491 +#: commands/tablecmds.c:4525 #, c-format msgid "cannot %s \"%s\" because it has pending trigger events" msgstr "保留中のトリガーイベントがあるため\"%2$s\"を%1$sできません" -#: commands/tablecmds.c:4517 +#: commands/tablecmds.c:4551 #, c-format msgid "cannot alter temporary tables of other sessions" msgstr "他のセッションの一時テーブルは変更できません" -#: commands/tablecmds.c:4986 +#: commands/tablecmds.c:5020 #, c-format msgid "cannot alter partition \"%s\" with an incomplete detach" msgstr "パーティション子テーブル\"%s\"は不完全な取り外し状態であるため変更できません" -#: commands/tablecmds.c:5215 +#: commands/tablecmds.c:5249 #, c-format msgid "cannot change persistence setting twice" msgstr "永続性設定の変更は2度はできません" -#: commands/tablecmds.c:5232 +#: commands/tablecmds.c:5266 #, c-format msgid "cannot have multiple SET ACCESS METHOD subcommands" msgstr "SET ACCESS METHODサブコマンドを複数指定できません" -#: commands/tablecmds.c:5988 +#: commands/tablecmds.c:6022 #, c-format msgid "cannot rewrite system relation \"%s\"" msgstr "システムリレーション\"%sを書き換えられません" -#: commands/tablecmds.c:5994 +#: commands/tablecmds.c:6028 #, c-format msgid "cannot rewrite table \"%s\" used as a catalog table" msgstr "カタログテーブルとして使用されているテーブル\"%s\"は書き換えられません" -#: commands/tablecmds.c:6006 +#: commands/tablecmds.c:6040 #, c-format msgid "cannot rewrite temporary tables of other sessions" msgstr "他のセッションの一時テーブルを書き換えられません" -#: commands/tablecmds.c:6544 commands/tablecmds.c:6564 +#: commands/tablecmds.c:6578 commands/tablecmds.c:6598 #, c-format msgid "column \"%s\" of relation \"%s\" contains null values" msgstr "リレーション\"%2$s\"の列\"%1$s\"にNULL値があります" -#: commands/tablecmds.c:6581 commands/tablecmds.c:22476 +#: commands/tablecmds.c:6615 commands/tablecmds.c:22756 #, c-format msgid "check constraint \"%s\" of relation \"%s\" is violated by some row" msgstr "一部の行がリレーション\"%2$s\"の検査制約\"%1$s\"に違反してます" -#: commands/tablecmds.c:6601 partitioning/partbounds.c:3381 +#: commands/tablecmds.c:6635 partitioning/partbounds.c:3381 #, c-format msgid "updated partition constraint for default partition \"%s\" would be violated by some row" msgstr "デフォルトパーティション\"%s\"の一部の行が更新後のパーティション制約に違反しています" -#: commands/tablecmds.c:6607 +#: commands/tablecmds.c:6641 #, c-format msgid "partition constraint of relation \"%s\" is violated by some row" msgstr "一部の行がリレーション\"%s\"のパーティション制約に違反しています" #. translator: %s is a group of some SQL keywords -#: commands/tablecmds.c:6876 +#: commands/tablecmds.c:6910 #, c-format msgid "ALTER action %s cannot be performed on relation \"%s\"" msgstr "ALTERのアクション%sはリレーション\"%s\"では実行できません" -#: commands/tablecmds.c:7131 commands/tablecmds.c:7138 +#: commands/tablecmds.c:6936 commands/tablecmds.c:20153 +#, c-format +msgid "cannot alter conflict log table \"%s\"" +msgstr "競合ログテーブル\"%s\"は変更できません" + +#: commands/tablecmds.c:7181 commands/tablecmds.c:7188 #, c-format msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" msgstr "型\"%s\"を変更できません。列\"%s\".\"%s\"でその型を使用しているためです" -#: commands/tablecmds.c:7145 +#: commands/tablecmds.c:7195 #, c-format msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" msgstr "列%2$s\".\"%3$s\"がその行型を使用しているため、外部テーブル\"%1$s\"を変更できません。" -#: commands/tablecmds.c:7152 +#: commands/tablecmds.c:7202 #, c-format msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" msgstr "テーブル\"%s\"を変更できません。その行型を列\"%s\".\"%s\"で使用しているためです" -#: commands/tablecmds.c:7208 +#: commands/tablecmds.c:7258 #, c-format msgid "cannot alter type \"%s\" because it is the type of a typed table" msgstr "型付けされたテーブルの型であるため、外部テーブル\"%s\"を変更できません。" -#: commands/tablecmds.c:7210 +#: commands/tablecmds.c:7260 #, c-format msgid "Use ALTER ... CASCADE to alter the typed tables too." msgstr "型付けされたテーブルを変更する場合も ALTER .. CASCADE を使用してください" -#: commands/tablecmds.c:7256 +#: commands/tablecmds.c:7306 #, c-format msgid "type %s is the row type of another table" msgstr "型\"%s\"は他のテーブルの行型です" -#: commands/tablecmds.c:7258 +#: commands/tablecmds.c:7308 #, c-format msgid "A typed table must use a stand-alone composite type created with CREATE TYPE." msgstr "型付きテーブルは、CREATE TYPEで作成された独立した複合型を使用する必要があります。" -#: commands/tablecmds.c:7263 +#: commands/tablecmds.c:7313 #, c-format msgid "type %s is not a composite type" msgstr "型 %s は複合型ではありません" -#: commands/tablecmds.c:7290 +#: commands/tablecmds.c:7340 #, c-format msgid "cannot add column to typed table" msgstr "型付けされたテーブルに列を追加できません" -#: commands/tablecmds.c:7340 +#: commands/tablecmds.c:7390 #, c-format msgid "cannot add column to a partition" msgstr "パーティションに列は追加できません" -#: commands/tablecmds.c:7369 commands/tablecmds.c:17797 +#: commands/tablecmds.c:7419 commands/tablecmds.c:18060 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" msgstr "子テーブル\"%s\"に異なる型の列\"%s\"があります" -#: commands/tablecmds.c:7375 commands/tablecmds.c:17803 +#: commands/tablecmds.c:7425 commands/tablecmds.c:18066 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" msgstr "子テーブル\"%s\"に異なる照合順序の列\"%s\"があります" -#: commands/tablecmds.c:7393 +#: commands/tablecmds.c:7443 #, c-format msgid "merging definition of column \"%s\" for child \"%s\"" msgstr "子\"%2$s\"の列\"%1$s\"の定義をマージしています" -#: commands/tablecmds.c:7446 +#: commands/tablecmds.c:7496 #, c-format msgid "cannot recursively add identity column to table that has child tables" msgstr "子テーブルを持つテーブルに識別列を再帰的に追加することはできません" -#: commands/tablecmds.c:7718 +#: commands/tablecmds.c:7743 #, c-format msgid "column must be added to child tables too" msgstr "列は子テーブルでも追加する必要があります" -#: commands/tablecmds.c:7796 +#: commands/tablecmds.c:7821 #, c-format msgid "column \"%s\" of relation \"%s\" already exists, skipping" msgstr "リレーション\"%2$s\"の列\"%1$s\"はすでに存在します、スキップします" -#: commands/tablecmds.c:7803 +#: commands/tablecmds.c:7828 #, c-format msgid "column \"%s\" of relation \"%s\" already exists" msgstr "リレーション\"%2$s\"の列\"%1$s\"はすでに存在します" -#: commands/tablecmds.c:7894 commands/tablecmds.c:8061 commands/tablecmds.c:8262 commands/tablecmds.c:8393 commands/tablecmds.c:8547 commands/tablecmds.c:8641 commands/tablecmds.c:8744 commands/tablecmds.c:8927 commands/tablecmds.c:9093 commands/tablecmds.c:9184 commands/tablecmds.c:9318 commands/tablecmds.c:14689 commands/tablecmds.c:16280 commands/tablecmds.c:19039 +#: commands/tablecmds.c:7919 commands/tablecmds.c:8086 commands/tablecmds.c:8287 commands/tablecmds.c:8418 commands/tablecmds.c:8572 commands/tablecmds.c:8666 commands/tablecmds.c:8769 commands/tablecmds.c:8952 commands/tablecmds.c:9118 commands/tablecmds.c:9209 commands/tablecmds.c:9343 commands/tablecmds.c:14946 commands/tablecmds.c:16537 commands/tablecmds.c:19302 #, c-format msgid "cannot alter system column \"%s\"" msgstr "システム列\"%s\"を変更できません" -#: commands/tablecmds.c:7900 commands/tablecmds.c:8268 commands/tablecmds.c:14450 +#: commands/tablecmds.c:7925 commands/tablecmds.c:8293 commands/tablecmds.c:14707 #, c-format msgid "column \"%s\" of relation \"%s\" is an identity column" msgstr "リレーション\"%2$s\"の列\"%1$s\"は識別列です" -#: commands/tablecmds.c:7917 +#: commands/tablecmds.c:7942 #, c-format msgid "column \"%s\" is marked NOT NULL in parent table" msgstr "列\"%s\"は親テーブルでNOT NULL指定されています" -#: commands/tablecmds.c:8139 commands/tablecmds.c:10126 +#: commands/tablecmds.c:8164 commands/tablecmds.c:10151 #, c-format msgid "constraint must be added to child tables too" msgstr "制約は子テーブルにも追加する必要があります" -#: commands/tablecmds.c:8140 commands/tablecmds.c:8371 commands/tablecmds.c:8503 commands/tablecmds.c:8620 commands/tablecmds.c:9491 commands/tablecmds.c:12320 commands/tablecmds.c:12730 +#: commands/tablecmds.c:8165 commands/tablecmds.c:8396 commands/tablecmds.c:8528 commands/tablecmds.c:8645 commands/tablecmds.c:9516 commands/tablecmds.c:12357 commands/tablecmds.c:12830 #, c-format msgid "Do not specify the ONLY keyword." msgstr "ONLYキーワードを指定しないでください。" -#: commands/tablecmds.c:8277 +#: commands/tablecmds.c:8302 #, c-format msgid "column \"%s\" of relation \"%s\" is a generated column" msgstr "リレーション\"%2$s\"の列\"%1$s\"は生成カラムです" -#: commands/tablecmds.c:8370 +#: commands/tablecmds.c:8395 #, c-format msgid "cannot add identity to a column of only the partitioned table" msgstr "パーティション親テーブルのみで列を識別列とすることはできません" -#: commands/tablecmds.c:8376 +#: commands/tablecmds.c:8401 #, c-format msgid "cannot add identity to a column of a partition" msgstr "パーティション子テーブルの列を識別列とすることはできません" -#: commands/tablecmds.c:8404 +#: commands/tablecmds.c:8429 #, c-format msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" msgstr "識別列を追加するにはリレーション\"%s\"の列\"%s\"はNOT NULLと宣言されている必要があります" -#: commands/tablecmds.c:8435 +#: commands/tablecmds.c:8460 #, c-format msgid "column \"%s\" of relation \"%s\" is already an identity column" msgstr "リレーション\"%2$s\"の列\"%1$s\"はすでに識別列です" -#: commands/tablecmds.c:8441 +#: commands/tablecmds.c:8466 #, c-format msgid "column \"%s\" of relation \"%s\" already has a default value" msgstr "リレーション\"%2$s\"の列\"%1$s\"はすでにデフォルト値が指定されています" -#: commands/tablecmds.c:8502 +#: commands/tablecmds.c:8527 #, c-format msgid "cannot change identity column of only the partitioned table" msgstr "パーティション親テーブルのみで列の識別列属性を変更することはできません" -#: commands/tablecmds.c:8508 +#: commands/tablecmds.c:8533 #, c-format msgid "cannot change identity column of a partition" msgstr "パーティション子テーブルの列の識別列属性を変更することはできません" -#: commands/tablecmds.c:8553 commands/tablecmds.c:8649 +#: commands/tablecmds.c:8578 commands/tablecmds.c:8674 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column" msgstr "リレーション\"%2$s\"の列\"%1$s\"は識別列ではありません" -#: commands/tablecmds.c:8619 +#: commands/tablecmds.c:8644 #, c-format msgid "cannot drop identity from a column of only the partitioned table" msgstr "パーティション親テーブルのみで列の識別列属性を削除することはできません" -#: commands/tablecmds.c:8625 +#: commands/tablecmds.c:8650 #, c-format msgid "cannot drop identity from a column of a partition" msgstr "パーティション子テーブルの列の識別列属性を削除することはできません" -#: commands/tablecmds.c:8654 +#: commands/tablecmds.c:8679 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" msgstr "リレーション\"%2$s\"の列\"%1$s\"は識別列ではありません、スキップします" -#: commands/tablecmds.c:8751 commands/tablecmds.c:8948 +#: commands/tablecmds.c:8776 commands/tablecmds.c:8973 #, c-format msgid "column \"%s\" of relation \"%s\" is not a generated column" msgstr "リレーション\"%2$s\"の列\"%1$s\"は生成列ではありません" -#: commands/tablecmds.c:8768 +#: commands/tablecmds.c:8793 #, c-format msgid "ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns in tables that are part of a publication" msgstr "ALTER TABLE / SET EXPRESSION は、パブリケーションに含まれるテーブルの仮想生成列ではサポートされていません" -#: commands/tablecmds.c:8769 commands/tablecmds.c:8940 +#: commands/tablecmds.c:8794 commands/tablecmds.c:8965 #, c-format msgid "Column \"%s\" of relation \"%s\" is a virtual generated column." msgstr "リレーション\"%2$s\"の列\"%1$s\"は仮想生成列です。" -#: commands/tablecmds.c:8874 +#: commands/tablecmds.c:8899 #, c-format msgid "ALTER TABLE / DROP EXPRESSION must be applied to child tables too" msgstr "ALTER TABLE / DROP EXPRESSIONは子テーブルに対しても適用されなくてはなりません" -#: commands/tablecmds.c:8896 +#: commands/tablecmds.c:8921 #, c-format msgid "cannot drop generation expression from inherited column" msgstr "継承列から生成式を削除することはできません" -#: commands/tablecmds.c:8939 +#: commands/tablecmds.c:8964 #, c-format msgid "ALTER TABLE / DROP EXPRESSION is not supported for virtual generated columns" msgstr "ALTER TABLE / DROP EXPRESSIONは仮想生成列ではサポートされていません" -#: commands/tablecmds.c:8953 +#: commands/tablecmds.c:8978 #, c-format msgid "column \"%s\" of relation \"%s\" is not a generated column, skipping" msgstr "リレーション\"%2$s\"の列\"%1$s\"は生成列ではありません、スキップします" -#: commands/tablecmds.c:9031 +#: commands/tablecmds.c:9056 #, c-format msgid "cannot refer to non-index column by number" msgstr "非インデックス列を番号で参照することはできません" -#: commands/tablecmds.c:9083 +#: commands/tablecmds.c:9108 #, c-format msgid "column number %d of relation \"%s\" does not exist" msgstr "リレーション \"%2$s\"の列 %1$d は存在しません" -#: commands/tablecmds.c:9103 +#: commands/tablecmds.c:9128 #, c-format msgid "cannot alter statistics on virtual generated column \"%s\"" msgstr "仮想生成列\"%s\"の統計情報は変更できません" -#: commands/tablecmds.c:9112 +#: commands/tablecmds.c:9137 #, c-format msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" msgstr "インデックス\"%2$s\"の包含列\"%1$s\"への統計情報の変更はできません" -#: commands/tablecmds.c:9117 +#: commands/tablecmds.c:9142 #, c-format msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" msgstr "インデックス \"%2$s\"の非式列\"%1$s\"の統計情報の変更はできません" -#: commands/tablecmds.c:9119 +#: commands/tablecmds.c:9144 #, c-format msgid "Alter statistics on table column instead." msgstr "代わりにテーブルカラムの統計情報を変更してください。" -#: commands/tablecmds.c:9365 +#: commands/tablecmds.c:9390 #, c-format msgid "cannot drop column from typed table" msgstr "型付けされたテーブルから列を削除できません" -#: commands/tablecmds.c:9429 +#: commands/tablecmds.c:9454 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" msgstr "リレーション\"%2$s\"の列\"%1$s\"は存在しません、スキップします" -#: commands/tablecmds.c:9442 +#: commands/tablecmds.c:9467 #, c-format msgid "cannot drop system column \"%s\"" msgstr "システム列\"%s\"を削除できません" -#: commands/tablecmds.c:9452 +#: commands/tablecmds.c:9477 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "継承される列\"%s\"を削除できません" -#: commands/tablecmds.c:9465 +#: commands/tablecmds.c:9490 #, c-format msgid "cannot drop column \"%s\" because it is part of the partition key of relation \"%s\"" msgstr "列\"%s\"はリレーション\"%s\"のパーティションキーの一部であるため、削除できません" -#: commands/tablecmds.c:9490 +#: commands/tablecmds.c:9515 #, c-format msgid "cannot drop column from only the partitioned table when partitions exist" msgstr "子テーブルが存在する場合にはパーティション親テーブルのみから列を削除することはできません" -#: commands/tablecmds.c:9655 +#: commands/tablecmds.c:9680 #, c-format msgid "column \"%s\" of table \"%s\" is not marked NOT NULL" msgstr "テーブル\"%2$s\"の列\"%1$s\"は非NULLに設定されていません" -#: commands/tablecmds.c:9691 commands/tablecmds.c:9703 +#: commands/tablecmds.c:9716 commands/tablecmds.c:9728 #, c-format msgid "cannot create primary key on column \"%s\"" msgstr "列%s\"に主キーを作成することはできません" #. translator: fourth %s is a constraint characteristic such as NOT VALID -#: commands/tablecmds.c:9693 commands/tablecmds.c:9705 +#: commands/tablecmds.c:9718 commands/tablecmds.c:9730 #, c-format msgid "The constraint \"%s\" on column \"%s\" of table \"%s\", marked %s, is incompatible with a primary key." msgstr " %4$s とマークされているテーブル \"%3$s\"の列 \"%2$s\" への制約 \"%1$s\" は、主キーの要件を満たしていません。" -#: commands/tablecmds.c:9830 +#: commands/tablecmds.c:9855 #, c-format msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX はパーティションテーブルではサポートされていません" -#: commands/tablecmds.c:9855 +#: commands/tablecmds.c:9880 #, c-format msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX はインデックス\"%s\"を\"%s\"にリネームします" -#: commands/tablecmds.c:10213 +#: commands/tablecmds.c:10238 #, c-format msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" msgstr "パーティションテーブル\"%s\"上のリレーション\"%s\"を参照する外部キー定義ではONLY指定はできません " -#: commands/tablecmds.c:10221 commands/tablecmds.c:10848 +#: commands/tablecmds.c:10246 commands/tablecmds.c:10885 #, c-format msgid "referenced relation \"%s\" is not a table" msgstr "参照先のリレーション\"%s\"はテーブルではありません" -#: commands/tablecmds.c:10244 +#: commands/tablecmds.c:10257 +#, c-format +msgid "cannot reference conflict log table \"%s\"" +msgstr "競合ログテーブル\"%s\"を参照先にはできません" + +#: commands/tablecmds.c:10281 #, c-format msgid "constraints on permanent tables may reference only permanent tables" msgstr "永続テーブルの制約は永続テーブルだけを参照できます" -#: commands/tablecmds.c:10251 +#: commands/tablecmds.c:10288 #, c-format msgid "constraints on unlogged tables may reference only permanent or unlogged tables" msgstr "UNLOGGEDテーブルに対する制約は、永続テーブルまたはUNLOGGEDテーブルだけを参照する場合があります" -#: commands/tablecmds.c:10257 +#: commands/tablecmds.c:10294 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "一時テーブルに対する制約は一時テーブルだけを参照する場合があります" -#: commands/tablecmds.c:10261 +#: commands/tablecmds.c:10298 #, c-format msgid "constraints on temporary tables must involve temporary tables of this session" msgstr "一時テーブルに対する制約にはこのセッションの一時テーブルを加える必要があります" -#: commands/tablecmds.c:10276 commands/tablecmds.c:10304 +#: commands/tablecmds.c:10313 commands/tablecmds.c:10341 #, c-format msgid "foreign key uses PERIOD on the referenced table but not the referencing table" msgstr "外部キーが参照先テーブル上ではPERIODを使用していますが、参照元テーブルでは使用していません" -#: commands/tablecmds.c:10316 +#: commands/tablecmds.c:10353 #, c-format msgid "foreign key uses PERIOD on the referencing table but not the referenced table" msgstr "外部キーが参照元テーブル上ではPERIODを使用していますが、参照先テーブルでは使用していません" -#: commands/tablecmds.c:10330 +#: commands/tablecmds.c:10367 #, c-format msgid "foreign key must use PERIOD when referencing a primary key using WITHOUT OVERLAPS" msgstr "主キーがWITHOUT OVERLAPSを使用している場合は外部キーはPERIODを使用する必要があります" -#: commands/tablecmds.c:10354 commands/tablecmds.c:10360 +#: commands/tablecmds.c:10391 commands/tablecmds.c:10397 #, c-format msgid "invalid %s action for foreign key constraint containing generated column" msgstr "生成カラムを含む外部キー制約に対する不正な %s 処理" -#: commands/tablecmds.c:10375 +#: commands/tablecmds.c:10412 #, c-format msgid "foreign key constraints on virtual generated columns are not supported" msgstr "外部キー制約は仮想生成列ではサポートされていません" -#: commands/tablecmds.c:10389 commands/tablecmds.c:10398 +#: commands/tablecmds.c:10426 commands/tablecmds.c:10435 #, c-format msgid "unsupported %s action for foreign key constraint using PERIOD" msgstr "PERIODを使用する外部キー制約に対するサポートされない %s 処理" -#: commands/tablecmds.c:10413 +#: commands/tablecmds.c:10450 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "外部キーの参照列数と被参照列数が合いません" -#: commands/tablecmds.c:10469 +#: commands/tablecmds.c:10506 #, c-format msgid "could not identify an overlaps operator for foreign key" msgstr "外部キーに使用する重複検出演算子を特定できませんでした" -#: commands/tablecmds.c:10470 +#: commands/tablecmds.c:10507 #, c-format msgid "could not identify an equality operator for foreign key" msgstr "外部キーに使用する等価演算子を特定できませんでした" -#: commands/tablecmds.c:10535 commands/tablecmds.c:10569 +#: commands/tablecmds.c:10572 commands/tablecmds.c:10606 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "外部キー制約\"%sは実装されていません" -#: commands/tablecmds.c:10537 +#: commands/tablecmds.c:10574 #, c-format msgid "Key columns \"%s\" of the referencing table and \"%s\" of the referenced table are of incompatible types: %s and %s." msgstr "キー列である参照元テーブルの\"%1$s\"と参照先テーブルの\"%2$s\"の型に互換性がありません: %3$sと%4$s。" -#: commands/tablecmds.c:10570 +#: commands/tablecmds.c:10607 #, c-format msgid "Key columns \"%s\" of the referencing table and \"%s\" of the referenced table have incompatible collations: \"%s\" and \"%s\". If either collation is nondeterministic, then both collations have to be the same." msgstr "キー列である参照元テーブルの\"%1$s\"と参照先テーブルの\"%2$s\"の照合順序に互換性がありません: %3$sと%4$s。いずれかの照合順序が非決定的である場合は両方の照合順序が同一である必要があります。" -#: commands/tablecmds.c:10776 +#: commands/tablecmds.c:10813 #, c-format msgid "column \"%s\" referenced in ON DELETE SET action must be part of foreign key" msgstr "ON DELETE SETアクションで参照されている列\"%s\"は外部キーの一部である必要があります" -#: commands/tablecmds.c:11160 commands/tablecmds.c:11593 parser/parse_utilcmd.c:939 parser/parse_utilcmd.c:1084 +#: commands/tablecmds.c:11197 commands/tablecmds.c:11630 parser/parse_utilcmd.c:939 parser/parse_utilcmd.c:1084 #, c-format msgid "foreign key constraints are not supported on foreign tables" msgstr "外部テーブルでは外部キー制約はサポートされていません" -#: commands/tablecmds.c:11576 +#: commands/tablecmds.c:11613 #, c-format msgid "cannot attach table \"%s\" as a partition because it is referenced by foreign key \"%s\"" msgstr "外部キー\"%2$s\"で参照されているため、テーブル\"%1$s\"を子テーブルとしてアタッチすることはできません" -#: commands/tablecmds.c:11857 +#: commands/tablecmds.c:11894 #, c-format msgid "constraint \"%s\" enforceability conflicts with constraint \"%s\" on relation \"%s\"" msgstr "制約\"%1$s\"の強制性が、リレーション\"%3$s\"上の制約\"%2$s\"と競合しています" -#: commands/tablecmds.c:12319 +#: commands/tablecmds.c:12356 #, c-format msgid "constraint must be altered in child tables too" msgstr "制約は子テーブルでも変更される必要があります" -#: commands/tablecmds.c:12348 commands/tablecmds.c:12810 commands/tablecmds.c:13214 commands/tablecmds.c:14329 commands/tablecmds.c:14558 +#: commands/tablecmds.c:12385 commands/tablecmds.c:12937 commands/tablecmds.c:13468 commands/tablecmds.c:14586 commands/tablecmds.c:14815 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "リレーション\"%2$s\"の制約\"%1$s\"は存在しません" -#: commands/tablecmds.c:12355 +#: commands/tablecmds.c:12392 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "リレーション\"%2$s\"の制約\"%1$s\"は外部キー制約ではありません" -#: commands/tablecmds.c:12361 +#: commands/tablecmds.c:12398 #, c-format msgid "cannot alter enforceability of constraint \"%s\" of relation \"%s\"" msgstr "リレーション\"%2$s\"の制約\"%1$s\"の強制性を変更できません" -#: commands/tablecmds.c:12363 +#: commands/tablecmds.c:12400 #, c-format msgid "Only foreign key and check constraints can change enforceability." msgstr "強制性の変更は外部キーと検査制約でのみ可能です。" -#: commands/tablecmds.c:12368 +#: commands/tablecmds.c:12405 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a not-null constraint" msgstr "リレーション\"%2$s\"の制約\"%1$s\"は非NULL制約ではありません" -#: commands/tablecmds.c:12376 +#: commands/tablecmds.c:12411 +#, c-format +msgid "not-null constraint \"%s\" on partitioned table \"%s\" cannot be NO INHERIT" +msgstr "パーティション親テーブル\"%2$s\"に対する非NULL制約\"%1$s\"はNO INHERIT指定できません" + +#: commands/tablecmds.c:12419 #, c-format msgid "cannot alter inherited constraint \"%s\" on relation \"%s\"" msgstr "リレーション\"%2$s\"の継承された制約\"%1$s\"を変更できません" -#: commands/tablecmds.c:12416 +#: commands/tablecmds.c:12459 #, c-format msgid "cannot alter constraint \"%s\" on relation \"%s\"" msgstr "リレーション\"%2$s\"の制約\"%1$s\"を変更できません" -#: commands/tablecmds.c:12419 +#: commands/tablecmds.c:12462 #, c-format msgid "Constraint \"%s\" is derived from constraint \"%s\" of relation \"%s\"." msgstr "制約\"%1$s\"は、リレーション\"%3$s\"上の制約\"%2$s\"から派生しています。" -#: commands/tablecmds.c:12421 +#: commands/tablecmds.c:12464 #, c-format msgid "You may alter the constraint it derives from instead." msgstr "この制約の代わりに派生元の制約を変更することは可能です。" -#: commands/tablecmds.c:12729 +#: commands/tablecmds.c:12760 +#, c-format +msgid "cannot mark inherited constraint \"%s\" as %s" +msgstr "継承された制約\"%s\"を %s と指定することはできません" + +#: commands/tablecmds.c:12763 +#, c-format +msgid "The matching constraint on parent table \"%s\" is %s." +msgstr "親テーブル\"%s\"での対応する制約が %s です。" + +#: commands/tablecmds.c:12829 #, c-format msgid "constraint must be altered on child tables too" msgstr "制約は子テーブルでも変更される必要があります" -#: commands/tablecmds.c:13223 +#: commands/tablecmds.c:13477 #, c-format msgid "cannot validate constraint \"%s\" of relation \"%s\"" msgstr "リレーション\"%2$s\"の制約\"%1$s\"を検証できません" -#: commands/tablecmds.c:13225 +#: commands/tablecmds.c:13479 #, c-format msgid "This operation is not supported for this type of constraint." msgstr "この操作はこのタイプの制約に対してはサポートされていません。" -#: commands/tablecmds.c:13230 +#: commands/tablecmds.c:13484 #, c-format msgid "cannot validate NOT ENFORCED constraint" msgstr "NOT ENFORCED制約は検証できません" -#: commands/tablecmds.c:13439 commands/tablecmds.c:13539 +#: commands/tablecmds.c:13696 commands/tablecmds.c:13796 #, c-format msgid "constraint must be validated on child tables too" msgstr "制約は子テーブルでも検証される必要があります" -#: commands/tablecmds.c:13616 +#: commands/tablecmds.c:13873 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" msgstr "外部キー制約で参照される列\"%s\"が存在しません" -#: commands/tablecmds.c:13622 +#: commands/tablecmds.c:13879 #, c-format msgid "system columns cannot be used in foreign keys" msgstr "システム列は外部キーに使用できません" -#: commands/tablecmds.c:13626 +#: commands/tablecmds.c:13883 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "外部キーでは%dを超えるキーを持つことができません" -#: commands/tablecmds.c:13694 +#: commands/tablecmds.c:13951 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "被参照テーブル\"%s\"には遅延可能プライマリキーは使用できません" -#: commands/tablecmds.c:13711 +#: commands/tablecmds.c:13968 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "被参照テーブル\"%s\"にはプライマリキーがありません" -#: commands/tablecmds.c:13784 +#: commands/tablecmds.c:14041 #, c-format msgid "foreign key referenced-columns list must not contain duplicates" msgstr "外部キーの被参照列リストには重複があってはなりません" -#: commands/tablecmds.c:13887 +#: commands/tablecmds.c:14144 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "被参照テーブル\"%s\"に対しては、遅延可能な一意性制約は使用できません" -#: commands/tablecmds.c:13892 +#: commands/tablecmds.c:14149 #, c-format msgid "there is no unique constraint matching given keys for referenced table \"%s\"" msgstr "被参照テーブル\"%s\"に、指定したキーに一致する一意性制約がありません" -#: commands/tablecmds.c:14333 +#: commands/tablecmds.c:14590 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" msgstr "リレーション\"%2$s\"の制約\"%1$s\"は存在しません、スキップします" -#: commands/tablecmds.c:14378 +#: commands/tablecmds.c:14635 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "リレーション\"%2$s\"の継承された制約\"%1$s\"を削除できません" -#: commands/tablecmds.c:14430 +#: commands/tablecmds.c:14687 #, c-format msgid "column \"%s\" is in a primary key" msgstr "列\"%s\"はプライマリキーで使用しています" -#: commands/tablecmds.c:14438 +#: commands/tablecmds.c:14695 #, c-format msgid "column \"%s\" is in index used as replica identity" msgstr "列\"%s\"は複製識別として使用中のインデックスに含まれています" -#: commands/tablecmds.c:14671 +#: commands/tablecmds.c:14928 #, c-format msgid "cannot alter column type of typed table" msgstr "型付けされたテーブルの列の型を変更できません" -#: commands/tablecmds.c:14699 +#: commands/tablecmds.c:14956 #, c-format msgid "cannot specify USING when altering type of generated column" msgstr "生成列の型変更の際にはUSINGを指定することはできません" -#: commands/tablecmds.c:14711 +#: commands/tablecmds.c:14968 #, c-format msgid "cannot alter inherited column \"%s\"" msgstr "継承される列\"%s\"を変更できません" -#: commands/tablecmds.c:14720 +#: commands/tablecmds.c:14977 #, c-format msgid "cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"" msgstr "列\"%s\"はリレーション\"%s\"のパーティションキーの一部であるため、変更できません" -#: commands/tablecmds.c:14775 +#: commands/tablecmds.c:15032 #, c-format msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" msgstr "列\"%s\"に対するUSING句の結果は自動的に%s型に型変換できません" -#: commands/tablecmds.c:14778 +#: commands/tablecmds.c:15035 #, c-format msgid "You might need to add an explicit cast." msgstr "必要に応じて明示的な型変換を追加してください。" -#: commands/tablecmds.c:14782 +#: commands/tablecmds.c:15039 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" msgstr "列\"%s\"は型%sには自動的に型変換できません" #. translator: USING is SQL, don't translate it -#: commands/tablecmds.c:14786 +#: commands/tablecmds.c:15043 #, c-format msgid "You might need to specify \"USING %s::%s\"." msgstr "必要に応じて\"USING %s::%s\"を追加してください。" -#: commands/tablecmds.c:14889 +#: commands/tablecmds.c:15146 #, c-format msgid "cannot alter inherited column \"%s\" of relation \"%s\"" msgstr "リレーション\"%2$s\"の継承列\"%1$s\"は変更できません" -#: commands/tablecmds.c:14918 +#: commands/tablecmds.c:15175 #, c-format msgid "USING expression contains a whole-row table reference." msgstr "USING式が行全体テーブル参照を含んでいます。" -#: commands/tablecmds.c:14929 +#: commands/tablecmds.c:15186 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" msgstr "継承される列\"%s\"の型を子テーブルで変更しなければなりません" -#: commands/tablecmds.c:15054 +#: commands/tablecmds.c:15311 #, c-format msgid "cannot alter type of column \"%s\" twice" msgstr "列\"%s\"の型を2回変更することはできません" -#: commands/tablecmds.c:15092 +#: commands/tablecmds.c:15349 #, c-format msgid "generation expression for column \"%s\" cannot be cast automatically to type %s" msgstr "カラム\"%s\"に対する生成式は自動的に%s型にキャストできません" -#: commands/tablecmds.c:15097 +#: commands/tablecmds.c:15354 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "列\"%s\"のデフォルト値を自動的に%s型にキャストできません" -#: commands/tablecmds.c:15401 +#: commands/tablecmds.c:15658 #, c-format msgid "cannot alter type of a column used by a function or procedure" msgstr "関数またはプロシージャで使用される列の型は変更できません" -#: commands/tablecmds.c:15402 commands/tablecmds.c:15417 commands/tablecmds.c:15437 commands/tablecmds.c:15456 commands/tablecmds.c:15515 +#: commands/tablecmds.c:15659 commands/tablecmds.c:15674 commands/tablecmds.c:15694 commands/tablecmds.c:15713 commands/tablecmds.c:15772 #, c-format msgid "%s depends on column \"%s\"" msgstr "%sは列\"%s\"に依存しています" -#: commands/tablecmds.c:15416 +#: commands/tablecmds.c:15673 #, c-format msgid "cannot alter type of a column used by a view or rule" msgstr "ビューまたはルールで使用される列の型は変更できません" -#: commands/tablecmds.c:15436 +#: commands/tablecmds.c:15693 #, c-format msgid "cannot alter type of a column used in a trigger definition" msgstr "トリガー定義で使用される列の型は変更できません" -#: commands/tablecmds.c:15455 +#: commands/tablecmds.c:15712 #, c-format msgid "cannot alter type of a column used in a policy definition" msgstr "ポリシ定義で使用されている列の型は変更できません" -#: commands/tablecmds.c:15486 +#: commands/tablecmds.c:15743 #, c-format msgid "cannot alter type of a column used by a generated column" msgstr "生成カラムで使用される列の型は変更できません" -#: commands/tablecmds.c:15487 +#: commands/tablecmds.c:15744 #, c-format msgid "Column \"%s\" is used by generated column \"%s\"." msgstr "カラム\"%s\"は生成カラム\"%s\"で使われています。" -#: commands/tablecmds.c:15514 +#: commands/tablecmds.c:15771 #, c-format msgid "cannot alter type of a column used by a publication WHERE clause" msgstr "パブリケーションのWHERE句で使用される列の型は変更できません" -#: commands/tablecmds.c:16389 commands/tablecmds.c:16401 +#: commands/tablecmds.c:16646 commands/tablecmds.c:16658 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "インデックス\"%s\"の所有者を変更できません" -#: commands/tablecmds.c:16391 commands/tablecmds.c:16403 +#: commands/tablecmds.c:16648 commands/tablecmds.c:16660 #, c-format msgid "Change the ownership of the index's table instead." msgstr "代わりにインデックスのテーブルの所有者を変更してください。" -#: commands/tablecmds.c:16417 +#: commands/tablecmds.c:16674 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "シーケンス\"%s\"の所有者を変更できません" -#: commands/tablecmds.c:16442 +#: commands/tablecmds.c:16699 #, c-format msgid "cannot change owner of relation \"%s\"" msgstr "リレーション\"%s\"の所有者を変更できません" -#: commands/tablecmds.c:16909 +#: commands/tablecmds.c:17166 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "SET TABLESPACEサブコマンドを複数指定できません" -#: commands/tablecmds.c:16988 +#: commands/tablecmds.c:17245 #, c-format msgid "cannot set options for relation \"%s\"" msgstr "リレーション\"%s\"のオプションは設定できません" -#: commands/tablecmds.c:17022 commands/view.c:440 +#: commands/tablecmds.c:17279 commands/view.c:440 #, c-format msgid "WITH CHECK OPTION is supported only on automatically updatable views" msgstr "WITH CHECK OPTIONは自動更新可能ビューでのみサポートされます" -#: commands/tablecmds.c:17275 +#: commands/tablecmds.c:17532 #, c-format msgid "only tables, indexes, and materialized views exist in tablespaces" msgstr "テーブルスペースにはテーブル、インデックスおよび実体化ビューしかありません" -#: commands/tablecmds.c:17287 +#: commands/tablecmds.c:17544 #, c-format msgid "cannot move relations in to or out of pg_global tablespace" msgstr "pg_globalテーブルスペースとの間のリレーションの移動はできません" -#: commands/tablecmds.c:17379 +#: commands/tablecmds.c:17642 #, c-format msgid "aborting because lock on relation \"%s.%s\" is not available" msgstr "リレーション\"%s.%s\"のロックが獲得できなかったため中断します" -#: commands/tablecmds.c:17395 +#: commands/tablecmds.c:17658 #, c-format msgid "no matching relations in tablespace \"%s\" found" msgstr "テーブルスペース\"%s\"には合致するリレーションはありませんでした" -#: commands/tablecmds.c:17515 +#: commands/tablecmds.c:17778 #, c-format msgid "cannot change inheritance of typed table" msgstr "型付けされたテーブルの継承を変更できません" -#: commands/tablecmds.c:17520 +#: commands/tablecmds.c:17783 #, c-format msgid "cannot change inheritance of a partition" msgstr "パーティションの継承は変更できません" -#: commands/tablecmds.c:17567 +#: commands/tablecmds.c:17830 #, c-format msgid "cannot inherit to temporary relation of another session" msgstr "他のセッションの一時テーブルを継承できません" -#: commands/tablecmds.c:17580 +#: commands/tablecmds.c:17843 #, c-format msgid "cannot inherit from a partition" msgstr "パーティションからの継承はできません" -#: commands/tablecmds.c:17602 commands/tablecmds.c:20705 +#: commands/tablecmds.c:17865 commands/tablecmds.c:20985 #, c-format msgid "circular inheritance not allowed" msgstr "循環継承を行うことはできません" -#: commands/tablecmds.c:17603 commands/tablecmds.c:20706 +#: commands/tablecmds.c:17866 commands/tablecmds.c:20986 #, c-format msgid "\"%s\" is already a child of \"%s\"." msgstr "\"%s\"はすでに\"%s\"の子です" -#: commands/tablecmds.c:17616 +#: commands/tablecmds.c:17879 #, c-format msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" msgstr "トリガー\"%s\"によってテーブル\"%s\"が継承子テーブルになることができません" -#: commands/tablecmds.c:17618 +#: commands/tablecmds.c:17881 #, c-format msgid "ROW triggers with transition tables are not supported in inheritance hierarchies." msgstr "遷移テーブルを使用したROWトリガーは継承関係ではサポートされていません。" -#: commands/tablecmds.c:17822 commands/tablecmds.c:18071 +#: commands/tablecmds.c:18085 commands/tablecmds.c:18334 #, c-format msgid "column \"%s\" in child table \"%s\" must be marked NOT NULL" msgstr "子テーブル\"%2$s\"の列\"%1$s\"は非NULLに設定されていません" -#: commands/tablecmds.c:17832 +#: commands/tablecmds.c:18095 #, c-format msgid "column \"%s\" in child table must be a generated column" msgstr "子テーブルの列\"%s\"は生成列である必要があります" -#: commands/tablecmds.c:17836 +#: commands/tablecmds.c:18099 #, c-format msgid "column \"%s\" in child table must not be a generated column" msgstr "子テーブルの列\"%s\"は生成列であってはなりません" -#: commands/tablecmds.c:17882 +#: commands/tablecmds.c:18145 #, c-format msgid "child table is missing column \"%s\"" msgstr "子テーブルには列\"%s\"がありません" -#: commands/tablecmds.c:17999 +#: commands/tablecmds.c:18262 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" msgstr "子テーブル\"%s\"では検査制約\"%s\"に異なった定義がされています" -#: commands/tablecmds.c:18008 +#: commands/tablecmds.c:18271 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" msgstr "制約\"%s\"は子テーブル\"%s\"上の継承されない制約と競合します" -#: commands/tablecmds.c:18019 +#: commands/tablecmds.c:18282 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" msgstr "制約\"%s\"は子テーブル\"%s\"のNOT VALID制約と衝突しています" -#: commands/tablecmds.c:18030 +#: commands/tablecmds.c:18293 #, c-format msgid "constraint \"%s\" conflicts with NOT ENFORCED constraint on child table \"%s\"" msgstr "制約\"%s\"は子テーブル\"%s\"のNOT ENFORCED制約と衝突しています" -#: commands/tablecmds.c:18079 +#: commands/tablecmds.c:18342 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "子テーブルには制約\"%s\"がありません" -#: commands/tablecmds.c:18161 +#: commands/tablecmds.c:18424 #, c-format msgid "partition \"%s\" already pending detach in partitioned table \"%s.%s\"" msgstr "パーティション\"%s\"はすでにパーティションテーブル\"%s.%s\"からの取り外し保留中です" -#: commands/tablecmds.c:18190 commands/tablecmds.c:18238 parser/parse_utilcmd.c:3558 +#: commands/tablecmds.c:18453 commands/tablecmds.c:18501 parser/parse_utilcmd.c:3554 #, c-format msgid "relation \"%s\" is not a partition of relation \"%s\"" msgstr "リレーション\"%s\"はリレーション\"%s\"のパーティション子テーブルではありません" -#: commands/tablecmds.c:18244 +#: commands/tablecmds.c:18507 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "リレーション\"%s\"はリレーション\"%s\"の親ではありません" -#: commands/tablecmds.c:18515 +#: commands/tablecmds.c:18778 #, c-format msgid "typed tables cannot inherit" msgstr "型付けされたテーブルは継承できません" -#: commands/tablecmds.c:18545 +#: commands/tablecmds.c:18808 #, c-format msgid "table is missing column \"%s\"" msgstr "テーブルには列\"%s\"がありません" -#: commands/tablecmds.c:18556 +#: commands/tablecmds.c:18819 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" msgstr "テーブルには列\"%s\"がありますが型は\"%s\"を必要としています" -#: commands/tablecmds.c:18565 +#: commands/tablecmds.c:18828 #, c-format msgid "table \"%s\" has different type for column \"%s\"" msgstr "テーブル\"%s\"では列\"%s\"の型が異なっています" -#: commands/tablecmds.c:18579 +#: commands/tablecmds.c:18842 #, c-format msgid "table has extra column \"%s\"" msgstr "テーブルに余分な列\"%s\"があります" -#: commands/tablecmds.c:18631 +#: commands/tablecmds.c:18894 #, c-format msgid "\"%s\" is not a typed table" msgstr "\"%s\"は型付けされたテーブルではありません" -#: commands/tablecmds.c:18811 +#: commands/tablecmds.c:19074 #, c-format msgid "cannot use non-unique index \"%s\" as replica identity" msgstr "非ユニークインデックス\"%s\"は複製識別としては使用できません" -#: commands/tablecmds.c:18817 +#: commands/tablecmds.c:19080 #, c-format msgid "cannot use non-immediate index \"%s\" as replica identity" msgstr "一意性を即時検査しないインデックス\"%s\"は複製識別には使用できません" -#: commands/tablecmds.c:18823 +#: commands/tablecmds.c:19086 #, c-format msgid "cannot use expression index \"%s\" as replica identity" msgstr "式インデックス\"%s\"は複製識別としては使用できません" -#: commands/tablecmds.c:18829 +#: commands/tablecmds.c:19092 #, c-format msgid "cannot use partial index \"%s\" as replica identity" msgstr "部分インデックス\"%s\"を複製識別としては使用できません" -#: commands/tablecmds.c:18846 +#: commands/tablecmds.c:19109 #, c-format msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" msgstr "列%2$dはシステム列であるためインデックス\"%1$s\"は複製識別には使えません" -#: commands/tablecmds.c:18853 +#: commands/tablecmds.c:19116 #, c-format msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" msgstr "列\"%2$s\"はnull可であるためインデックス\"%1$s\"は複製識別には使えません" -#: commands/tablecmds.c:19102 +#: commands/tablecmds.c:19365 #, c-format msgid "cannot change logged status of table \"%s\" because it is temporary" msgstr "テーブル\"%s\"は一時テーブルであるため、ログ出力設定を変更できません" -#: commands/tablecmds.c:19126 +#: commands/tablecmds.c:19389 #, c-format msgid "cannot change table \"%s\" to unlogged because it is part of a publication" msgstr "テーブル\"%s\"はパブリケーションの一部であるため、UNLOGGEDに変更できません" -#: commands/tablecmds.c:19128 +#: commands/tablecmds.c:19391 #, c-format msgid "Unlogged relations cannot be replicated." msgstr "UNLOGGEDリレーションはレプリケーションできません。" -#: commands/tablecmds.c:19173 +#: commands/tablecmds.c:19436 #, c-format msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" msgstr "テーブル\"%s\"はUNLOGGEDテーブル\"%s\"を参照しているためLOGGEDには設定できません" -#: commands/tablecmds.c:19183 +#: commands/tablecmds.c:19446 #, c-format msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" msgstr "テーブル\"%s\"はLOGGEDテーブル\"%s\"を参照しているためUNLOGGEDには設定できません" -#: commands/tablecmds.c:19247 +#: commands/tablecmds.c:19510 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "所有するシーケンスを他のスキーマに移動することができません" -#: commands/tablecmds.c:19355 +#: commands/tablecmds.c:19618 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "リレーション\"%s\"はスキーマ\"%s\"内にすでに存在します" -#: commands/tablecmds.c:19780 +#: commands/tablecmds.c:20043 #, c-format msgid "\"%s\" is not a table or materialized view" msgstr "\"%s\"はテーブルや実体化ビューではありません" -#: commands/tablecmds.c:19933 +#: commands/tablecmds.c:20106 +#, c-format +msgid "cannot change conflict log table \"%s\"" +msgstr "競合ログテーブル\"%s\"は更新できません" + +#: commands/tablecmds.c:20220 #, c-format msgid "\"%s\" is not a composite type" msgstr "\"%s\"は複合型ではありません" -#: commands/tablecmds.c:19968 +#: commands/tablecmds.c:20255 #, c-format msgid "cannot change schema of index \"%s\"" msgstr "インデックス\"%s\"のスキーマを変更できません" -#: commands/tablecmds.c:19970 commands/tablecmds.c:19984 +#: commands/tablecmds.c:20257 commands/tablecmds.c:20271 #, c-format msgid "Change the schema of the table instead." msgstr "代わりにこのテーブルのスキーマを変更してください。" -#: commands/tablecmds.c:19974 +#: commands/tablecmds.c:20261 #, c-format msgid "cannot change schema of composite type \"%s\"" msgstr "複合型%sのスキーマは変更できません" -#: commands/tablecmds.c:19982 +#: commands/tablecmds.c:20269 #, c-format msgid "cannot change schema of TOAST table \"%s\"" msgstr "TOASTテーブル\"%s\"のスキーマは変更できません" -#: commands/tablecmds.c:20014 +#: commands/tablecmds.c:20301 #, c-format msgid "cannot use \"list\" partition strategy with more than one column" msgstr "\"list\"パーティションストラテジは2つ以上の列に対しては使えません" -#: commands/tablecmds.c:20080 +#: commands/tablecmds.c:20367 #, c-format msgid "column \"%s\" named in partition key does not exist" msgstr "パーティションキーに指定されている列\"%s\"は存在しません" -#: commands/tablecmds.c:20088 +#: commands/tablecmds.c:20375 #, c-format msgid "cannot use system column \"%s\" in partition key" msgstr "パーティションキーでシステム列\"%s\"は使用できません" -#: commands/tablecmds.c:20102 commands/tablecmds.c:20184 +#: commands/tablecmds.c:20389 commands/tablecmds.c:20471 #, c-format msgid "cannot use generated column in partition key" msgstr "パーティションキーで生成カラムは使用できません" -#: commands/tablecmds.c:20171 +#: commands/tablecmds.c:20458 #, c-format msgid "partition key expressions cannot contain system column references" msgstr "パーティションキー式はシステム列への参照を含むことができません" -#: commands/tablecmds.c:20235 +#: commands/tablecmds.c:20522 #, c-format msgid "functions in partition key expression must be marked IMMUTABLE" msgstr "パーティションキー式で使われる関数はIMMUTABLE指定されている必要があります" -#: commands/tablecmds.c:20244 +#: commands/tablecmds.c:20531 #, c-format msgid "cannot use constant expression as partition key" msgstr "定数式をパーティションキーとして使うことはできません" -#: commands/tablecmds.c:20265 +#: commands/tablecmds.c:20552 #, c-format msgid "could not determine which collation to use for partition expression" msgstr "パーティション式で使用する照合順序を特定できませんでした" -#: commands/tablecmds.c:20300 +#: commands/tablecmds.c:20587 #, c-format msgid "You must specify a hash operator class or define a default hash operator class for the data type." msgstr "ハッシュ演算子クラスを指定するか、もしくはこのデータ型にデフォルトのハッシュ演算子クラスを定義する必要があります。" -#: commands/tablecmds.c:20306 +#: commands/tablecmds.c:20593 #, c-format msgid "You must specify a btree operator class or define a default btree operator class for the data type." msgstr "btree演算子クラスを指定するか、もしくはこのデータ型にデフォルトのbtree演算子クラスを定義するかする必要があります。" -#: commands/tablecmds.c:20601 +#: commands/tablecmds.c:20888 #, c-format msgid "\"%s\" is already a partition" msgstr "\"%s\"はすでパーティションです" -#: commands/tablecmds.c:20607 +#: commands/tablecmds.c:20894 #, c-format msgid "cannot attach a typed table as partition" msgstr "型付けされたテーブルをパーティションにアタッチすることはできません" -#. translator: This is a separator in a list of publication -#. names. -#. -#. translator: This is a separator in a list of entity names. -#. translator: This is a separator in a list of entity -#. names. -#. -#: commands/tablecmds.c:20632 replication/logical/relation.c:254 utils/misc/guc.c:3182 -msgid ", " -msgstr ", " - -#: commands/tablecmds.c:20637 replication/logical/relation.c:256 -#, c-format -msgid "\"%s\"" -msgstr "\"%s\"" - -#: commands/tablecmds.c:20642 +#: commands/tablecmds.c:20922 #, c-format msgid "cannot attach table \"%s\" as partition because it is referenced in publication %s EXCEPT clause" msgid_plural "cannot attach table \"%s\" as partition because it is referenced in publications %s EXCEPT clause" msgstr[0] "パブリケーション %2$s のEXCEPT句で参照されているため、テーブル\"%1$s\"を子テーブルとしてアタッチすることはできません" -#: commands/tablecmds.c:20647 +#: commands/tablecmds.c:20927 #, c-format msgid "The publication EXCEPT clause cannot contain tables that are partitions." msgstr "このパブリケーションのEXCEPT句はパーティション子テーブルを含むことはできません。" -#: commands/tablecmds.c:20648 +#: commands/tablecmds.c:20928 #, c-format msgid "Change the publication's EXCEPT clause using ALTER PUBLICATION ... SET ALL TABLES." msgstr "パブリケーションのEXCEPT句を ALTER PUBLICATION ... SET ALL TABLES を使って変更してください。" -#: commands/tablecmds.c:20667 +#: commands/tablecmds.c:20947 #, c-format msgid "cannot attach inheritance child as partition" msgstr "継承子テーブルをパーティションにアタッチすることはできません" -#: commands/tablecmds.c:20681 +#: commands/tablecmds.c:20961 #, c-format msgid "cannot attach inheritance parent as partition" msgstr "継承親テーブルをパーティションにアタッチすることはできません" -#: commands/tablecmds.c:20715 +#: commands/tablecmds.c:20995 #, c-format msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" msgstr "一時リレーションを永続リレーション \"%s\" のパーティション子テーブルとしてアタッチすることはできません" -#: commands/tablecmds.c:20723 +#: commands/tablecmds.c:21003 #, c-format msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" msgstr "永続リレーションを一時リレーション\"%s\"のパーティション子テーブルとしてアタッチすることはできません" -#: commands/tablecmds.c:20730 +#: commands/tablecmds.c:21010 #, c-format msgid "cannot attach as partition of temporary relation of another session" msgstr "他セッションの一時リレーションのパーティション子テーブルとしてアタッチすることはできません" -#: commands/tablecmds.c:20736 +#: commands/tablecmds.c:21016 #, c-format msgid "cannot attach temporary relation of another session as partition" msgstr "他セッションの一時リレーションにパーティション子テーブルとしてアタッチすることはできません" -#: commands/tablecmds.c:20756 +#: commands/tablecmds.c:21036 #, c-format msgid "table \"%s\" being attached contains an identity column \"%s\"" msgstr "アタッチ対象のテーブル\"%s\"には識別列\"%s\"が含まれています" -#: commands/tablecmds.c:20758 +#: commands/tablecmds.c:21038 #, c-format msgid "The new partition may not contain an identity column." msgstr "新しいパーティションは識別列を含むことはできません" -#: commands/tablecmds.c:20766 +#: commands/tablecmds.c:21046 #, c-format msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" msgstr "テーブル\"%1$s\"は親テーブル\"%3$s\"にない列\"%2$s\"を含んでいます" -#: commands/tablecmds.c:20769 +#: commands/tablecmds.c:21049 #, c-format msgid "The new partition may contain only the columns present in parent." msgstr "新しいパーティションは親に存在する列のみを含むことができます。" -#: commands/tablecmds.c:20781 +#: commands/tablecmds.c:21061 #, c-format msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" msgstr "トリガー\"%s\"のため、テーブル\"%s\"はパーティション子テーブルにはなれません" -#: commands/tablecmds.c:20783 +#: commands/tablecmds.c:21063 #, c-format msgid "ROW triggers with transition tables are not supported on partitions." msgstr "遷移テーブルを使用するROWトリガーはパーティション子テーブルではサポートされません。" -#: commands/tablecmds.c:20949 +#: commands/tablecmds.c:21229 #, c-format msgid "cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"" msgstr "外部テーブル\"%s\"はパーティションテーブル\"%s\"の子テーブルとしてアタッチすることはできません" -#: commands/tablecmds.c:20952 +#: commands/tablecmds.c:21232 #, c-format msgid "Partitioned table \"%s\" contains unique indexes." msgstr "パーティション親テーブル\"%s\"はユニークインデックスを持っています。" -#: commands/tablecmds.c:21276 +#: commands/tablecmds.c:21556 #, c-format msgid "cannot detach partitions concurrently when a default partition exists" msgstr "デフォルトパーティションを持つパーティションは並列的に取り外しはできません" -#: commands/tablecmds.c:21379 +#: commands/tablecmds.c:21659 #, c-format msgid "partitioned table \"%s\" was removed concurrently" msgstr "パーティション親テーブル\"%s\"には CREATE INDEX CONCURRENTLY は実行できません" -#: commands/tablecmds.c:21385 +#: commands/tablecmds.c:21665 #, c-format msgid "partition \"%s\" was removed concurrently" msgstr "パーティション子テーブル\\\"%s\\\"は同時に削除されました" -#: commands/tablecmds.c:21976 commands/tablecmds.c:21996 commands/tablecmds.c:22017 commands/tablecmds.c:22036 commands/tablecmds.c:22093 +#: commands/tablecmds.c:22256 commands/tablecmds.c:22276 commands/tablecmds.c:22297 commands/tablecmds.c:22316 commands/tablecmds.c:22373 #, c-format msgid "cannot attach index \"%s\" as a partition of index \"%s\"" msgstr "インデックス\"%s\"をインデックス\"%s\"の子インデックスとしてアタッチすることはできません" -#: commands/tablecmds.c:21979 +#: commands/tablecmds.c:22259 #, c-format msgid "Index \"%s\" is already attached to another index." msgstr "インデックス\"%s\"はすでに別のインデックスにアタッチされています。" -#: commands/tablecmds.c:21999 +#: commands/tablecmds.c:22279 #, c-format msgid "Index \"%s\" is not an index on any partition of table \"%s\"." msgstr "インデックス\"%s\"はテーブル\"%s\"のどの子テーブルのインデックスでもありません。" -#: commands/tablecmds.c:22020 +#: commands/tablecmds.c:22300 #, c-format msgid "The index definitions do not match." msgstr "インデックス定義が合致しません。" -#: commands/tablecmds.c:22039 +#: commands/tablecmds.c:22319 #, c-format msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." msgstr "インデックス\"%s\"はテーブル\"%s\"の制約に属していますが、インデックス\"%s\"には制約がありません。" -#: commands/tablecmds.c:22096 +#: commands/tablecmds.c:22376 #, c-format msgid "Another index \"%s\" is already attached for partition \"%s\"." msgstr "子テーブル\"%2$s\"にはすでに他のインデックス\"%1$s\"がアタッチされています。" -#: commands/tablecmds.c:22220 +#: commands/tablecmds.c:22500 #, c-format msgid "invalid primary key definition" msgstr "不正な主キー定義" -#: commands/tablecmds.c:22221 +#: commands/tablecmds.c:22501 #, c-format msgid "Column \"%s\" of relation \"%s\" is not marked NOT NULL." msgstr "リレーション\"%2$s\"の列\"%1$s\"は非NULLに設定されていません。" -#: commands/tablecmds.c:22356 +#: commands/tablecmds.c:22636 #, c-format msgid "column data type %s does not support compression" msgstr "列データ型%sは圧縮をサポートしていません" -#: commands/tablecmds.c:22363 +#: commands/tablecmds.c:22643 #, c-format msgid "invalid compression method \"%s\"" msgstr "無効な圧縮方式\"%s\"" -#: commands/tablecmds.c:22389 +#: commands/tablecmds.c:22669 #, c-format msgid "invalid storage type \"%s\"" msgstr "不正な格納タイプ\"%s\"" -#: commands/tablecmds.c:22399 +#: commands/tablecmds.c:22679 #, c-format msgid "column data type %s can only have storage PLAIN" msgstr "列のデータ型%sは格納タイプPLAINしか取ることができません" -#: commands/tablecmds.c:22772 +#: commands/tablecmds.c:23053 #, c-format msgid "cannot create as partition of temporary relation of another session" msgstr "他セッションの一時リレーションのパーティション子テーブルとして作成することはできません" -#: commands/tablecmds.c:22809 +#: commands/tablecmds.c:23090 #, c-format msgid "cannot create a permanent relation as partition of temporary relation \"%s\"" msgstr "永続リレーションを一時リレーション\"%s\"のパーティション子テーブルとして作成することはできません" -#: commands/tablecmds.c:23161 +#: commands/tablecmds.c:23479 #, c-format msgid "cannot merge partitions with conflicting extension dependencies" msgstr "異なる機能拡張に依存するパーティション子テーブル同士のマージはできません" -#: commands/tablecmds.c:23162 +#: commands/tablecmds.c:23480 #, c-format msgid "Partition indexes \"%s\" and \"%s\" depend on different extensions." msgstr "パーティションインデックス\"%s\"と\"%s\"が異なる拡張機能に依存しています。" -#: commands/tablecmds.c:23298 +#: commands/tablecmds.c:23616 #, c-format msgid "partitions being merged have different owners" msgstr "マージ対象のパーティションのオーナーが異なっています" -#: commands/tablecmds.c:23664 +#: commands/tablecmds.c:23982 #, c-format msgid "cannot find partition for split partition row" msgstr "パーティションの分割対象行に対応するパーティションが見つかりません" @@ -15538,7 +15642,7 @@ msgstr "\"%s\"はパーティション親テーブルです" msgid "ROW triggers with transition tables are not supported on partitioned tables." msgstr "遷移テーブルを使用するROWトリガーはパーティション親テーブルではサポートされません。" -#: commands/trigger.c:277 commands/trigger.c:284 commands/trigger.c:448 +#: commands/trigger.c:277 commands/trigger.c:284 commands/trigger.c:460 #, c-format msgid "\"%s\" is a view" msgstr "\"%s\"はビューです" @@ -15553,7 +15657,7 @@ msgstr "ビューは行レベルの BEFORE / AFTER トリガーを持つこと msgid "Views cannot have TRUNCATE triggers." msgstr "ビューは TRUNCATE トリガーを持つことができません" -#: commands/trigger.c:294 commands/trigger.c:306 commands/trigger.c:441 +#: commands/trigger.c:294 commands/trigger.c:306 commands/trigger.c:453 #, c-format msgid "\"%s\" is a foreign table" msgstr "\"%s\"は外部テーブルです" @@ -15568,227 +15672,237 @@ msgstr "外部テーブルは INSTEAD OF トリガーを持つことができま msgid "Foreign tables cannot have constraint triggers." msgstr "外部テーブルは制約トリガーを持つことができません。" -#: commands/trigger.c:313 commands/trigger.c:1332 commands/trigger.c:1439 +#: commands/trigger.c:313 commands/trigger.c:1344 commands/trigger.c:1451 #, c-format msgid "relation \"%s\" cannot have triggers" msgstr "リレーション\"%s\"にはトリガーを設定できません" -#: commands/trigger.c:384 +#: commands/trigger.c:325 +#, c-format +msgid "cannot create trigger on conflict log table \"%s\"" +msgstr "競合ログテーブル\"%s\"にトリガーは設定できません" + +#: commands/trigger.c:396 #, c-format msgid "TRUNCATE FOR EACH ROW triggers are not supported" msgstr "TRUNCATE FOR EACH ROW トリガーはサポートされていません" -#: commands/trigger.c:392 +#: commands/trigger.c:404 #, c-format msgid "INSTEAD OF triggers must be FOR EACH ROW" msgstr "INSTEAD OF トリガーは FOR EACH ROW でなければなりません" -#: commands/trigger.c:396 +#: commands/trigger.c:408 #, c-format msgid "INSTEAD OF triggers cannot have WHEN conditions" msgstr "INSTEAD OF トリガーは WHEN 条件を持つことができません" -#: commands/trigger.c:400 +#: commands/trigger.c:412 #, c-format msgid "INSTEAD OF triggers cannot have column lists" msgstr "INSTEAD OF トリガーは列リストを持つことができません" -#: commands/trigger.c:429 +#: commands/trigger.c:441 #, c-format msgid "ROW variable naming in the REFERENCING clause is not supported" msgstr "REFERENCING句でのROW変数の命名はサポートされていません" -#: commands/trigger.c:430 +#: commands/trigger.c:442 #, c-format msgid "Use OLD TABLE or NEW TABLE for naming transition tables." msgstr "遷移テーブルを指定するには OLD TABLE または NEW TABLE を使ってください" -#: commands/trigger.c:443 +#: commands/trigger.c:455 #, c-format msgid "Triggers on foreign tables cannot have transition tables." msgstr "外部テーブルに対するトリガーは遷移テーブルを持てません。" -#: commands/trigger.c:450 +#: commands/trigger.c:462 #, c-format msgid "Triggers on views cannot have transition tables." msgstr "ビューに対するトリガーは遷移テーブルを持てません。" -#: commands/trigger.c:466 +#: commands/trigger.c:478 #, c-format msgid "ROW triggers with transition tables are not supported on partitions" msgstr "遷移テーブルを使用するROWトリガーはパーティションではサポートされません" -#: commands/trigger.c:470 +#: commands/trigger.c:482 #, c-format msgid "ROW triggers with transition tables are not supported on inheritance children" msgstr "遷移テーブルをもったROWトリガーは継承子テーブルではサポートされません" -#: commands/trigger.c:476 +#: commands/trigger.c:488 #, c-format msgid "transition table name can only be specified for an AFTER trigger" msgstr "遷移テーブル名はAFTERトリガーでのみ指定可能です" -#: commands/trigger.c:481 +#: commands/trigger.c:493 #, c-format msgid "TRUNCATE triggers with transition tables are not supported" msgstr "遷移テーブルを使用するTRUNCATEトリガーはサポートされていません" -#: commands/trigger.c:498 +#: commands/trigger.c:510 #, c-format msgid "transition tables cannot be specified for triggers with more than one event" msgstr "2つ以上のイベントに対するトリガーには遷移テーブルは指定できません" -#: commands/trigger.c:509 +#: commands/trigger.c:521 #, c-format msgid "transition tables cannot be specified for triggers with column lists" msgstr "列リストを指定したトリガーに対しては遷移テーブルは指定できません" -#: commands/trigger.c:526 +#: commands/trigger.c:538 #, c-format msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" msgstr "NEW TABLE はINSERTまたはUPDATEトリガーに対してのみ指定可能です" -#: commands/trigger.c:531 +#: commands/trigger.c:543 #, c-format msgid "NEW TABLE cannot be specified multiple times" msgstr "NEW TABLE は複数回指定できません" -#: commands/trigger.c:541 +#: commands/trigger.c:553 #, c-format msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" msgstr "OLD TABLE はDELETEまたはUPDATEトリガーに対してのみ指定可能です" -#: commands/trigger.c:546 +#: commands/trigger.c:558 #, c-format msgid "OLD TABLE cannot be specified multiple times" msgstr "OLD TABLE は複数回指定できません" -#: commands/trigger.c:556 +#: commands/trigger.c:568 #, c-format msgid "OLD TABLE name and NEW TABLE name cannot be the same" msgstr "OLD TABLE の名前と NEW TABLE の名前は同じにはできません" -#: commands/trigger.c:620 commands/trigger.c:633 +#: commands/trigger.c:632 commands/trigger.c:645 #, c-format msgid "statement trigger's WHEN condition cannot reference column values" msgstr "ステートメントトリガーの WHEN 条件では列の値を参照できません" -#: commands/trigger.c:625 +#: commands/trigger.c:637 #, c-format msgid "INSERT trigger's WHEN condition cannot reference OLD values" msgstr "INSERT トリガーの WHEN 条件では OLD 値を参照できません" -#: commands/trigger.c:638 +#: commands/trigger.c:650 #, c-format msgid "DELETE trigger's WHEN condition cannot reference NEW values" msgstr "DELETE トリガーの WHEN 条件では NEW 値を参照できません" -#: commands/trigger.c:643 +#: commands/trigger.c:655 #, c-format msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" msgstr "BEFORE トリガーの WHEN 条件では NEW システム列を参照できません" -#: commands/trigger.c:652 commands/trigger.c:660 +#: commands/trigger.c:664 commands/trigger.c:672 #, c-format msgid "BEFORE trigger's WHEN condition cannot reference NEW generated columns" msgstr "BEFORE トリガーの WHEN 条件では NEW の生成列を参照できません" -#: commands/trigger.c:653 +#: commands/trigger.c:665 #, c-format msgid "A whole-row reference is used and the table contains generated columns." msgstr "行全体参照が使われていてかつ、このテーブルは生成カラムを含んでいます。" -#: commands/trigger.c:768 commands/trigger.c:1615 +#: commands/trigger.c:780 commands/trigger.c:1640 #, c-format msgid "trigger \"%s\" for relation \"%s\" already exists" msgstr "リレーション\"%2$s\"用のトリガー\"%1$s\"はすでに存在します" -#: commands/trigger.c:781 +#: commands/trigger.c:793 #, c-format msgid "trigger \"%s\" for relation \"%s\" is an internal or a child trigger" msgstr "リレーション\"%2$s\"のトリガー\"%1$s\"は内部トリガーまたは子トリガーです" -#: commands/trigger.c:800 +#: commands/trigger.c:812 #, c-format msgid "trigger \"%s\" for relation \"%s\" is a constraint trigger" msgstr "リレーション\"%2$s\"のトリガー\"%1$s\"は制約トリガーです" -#: commands/trigger.c:1404 commands/trigger.c:1558 commands/trigger.c:1839 +#: commands/trigger.c:1416 commands/trigger.c:1583 commands/trigger.c:1864 #, c-format msgid "trigger \"%s\" for table \"%s\" does not exist" msgstr "テーブル\"%2$s\"のトリガー\"%1$s\"は存在しません" -#: commands/trigger.c:1530 +#: commands/trigger.c:1467 +#, c-format +msgid "cannot rename trigger on conflict log table \"%s\"" +msgstr "競合ログテーブル\"%s\"のトリガーの名前は変更できません" + +#: commands/trigger.c:1555 #, c-format msgid "cannot rename trigger \"%s\" on table \"%s\"" msgstr "テーブル\"%2$s\"のトリガー\"%1$s\"の名前は変更できません" -#: commands/trigger.c:1532 +#: commands/trigger.c:1557 #, c-format msgid "Rename the trigger on the partitioned table \"%s\" instead." msgstr "代わりにパーティション親テーブル\"%s\"でこのトリガーの名前を変更してください。" -#: commands/trigger.c:1632 +#: commands/trigger.c:1657 #, c-format msgid "renamed trigger \"%s\" on relation \"%s\"" msgstr "リレーション\"%2$s\"のトリガー\"%1$s\"の名前を変更しました" -#: commands/trigger.c:1778 +#: commands/trigger.c:1803 #, c-format msgid "permission denied: \"%s\" is a system trigger" msgstr "権限がありません: \"%s\"はシステムトリガーです" -#: commands/trigger.c:2389 +#: commands/trigger.c:2414 #, c-format msgid "trigger function %u returned null value" msgstr "トリガー関数%uがNULL値を返しました" -#: commands/trigger.c:2449 commands/trigger.c:2678 commands/trigger.c:2950 commands/trigger.c:3324 +#: commands/trigger.c:2474 commands/trigger.c:2703 commands/trigger.c:2975 commands/trigger.c:3349 #, c-format msgid "BEFORE STATEMENT trigger cannot return a value" msgstr "BEFORE STATEMENTトリガーは値を返すことができません" -#: commands/trigger.c:2527 +#: commands/trigger.c:2552 #, c-format msgid "moving row to another partition during a BEFORE FOR EACH ROW trigger is not supported" msgstr "BEFORE FOR EACH ROWトリガーの実行では、他のパーティション子テーブルへの行の移動はサポートされていません" -#: commands/trigger.c:2528 +#: commands/trigger.c:2553 #, c-format msgid "Before executing trigger \"%s\", the row was to be in partition \"%s.%s\"." msgstr "トリガー\"%s\"の実行前には、この行はパーティション子テーブル\"%s.%s\"に置かれるはずでした。" -#: commands/trigger.c:2557 commands/trigger.c:2818 commands/trigger.c:3165 +#: commands/trigger.c:2582 commands/trigger.c:2843 commands/trigger.c:3190 #, c-format msgid "cannot collect transition tuples from child foreign tables" msgstr "外部子テーブルからは遷移タプルを収集できません" -#: commands/trigger.c:3403 executor/nodeModifyTable.c:1975 executor/nodeModifyTable.c:2049 executor/nodeModifyTable.c:2870 executor/nodeModifyTable.c:2960 executor/nodeModifyTable.c:3785 executor/nodeModifyTable.c:3982 +#: commands/trigger.c:3428 executor/nodeModifyTable.c:1962 executor/nodeModifyTable.c:2036 executor/nodeModifyTable.c:2857 executor/nodeModifyTable.c:2947 executor/nodeModifyTable.c:3772 executor/nodeModifyTable.c:3969 #, c-format msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." msgstr "他の行への変更を伝搬させるためにはBEFOREトリガーではなくAFTERトリガーの使用を検討してください" -#: commands/trigger.c:3445 executor/nodeLockRows.c:228 executor/nodeModifyTable.c:411 executor/nodeModifyTable.c:1991 executor/nodeModifyTable.c:2886 executor/nodeModifyTable.c:3092 executor/nodeModifyTable.c:3823 utils/adt/ri_triggers.c:3254 +#: commands/trigger.c:3470 executor/nodeLockRows.c:228 executor/nodeModifyTable.c:413 executor/nodeModifyTable.c:1978 executor/nodeModifyTable.c:2873 executor/nodeModifyTable.c:3079 executor/nodeModifyTable.c:3810 utils/adt/ri_triggers.c:3314 #, c-format msgid "could not serialize access due to concurrent update" msgstr "更新が同時に行われたためアクセスの直列化ができませんでした" -#: commands/trigger.c:3453 executor/nodeLockRows.c:237 executor/nodeModifyTable.c:2081 executor/nodeModifyTable.c:2977 executor/nodeModifyTable.c:3108 executor/nodeModifyTable.c:3803 utils/adt/ri_triggers.c:3247 +#: commands/trigger.c:3478 executor/nodeLockRows.c:237 executor/nodeModifyTable.c:2068 executor/nodeModifyTable.c:2964 executor/nodeModifyTable.c:3095 executor/nodeModifyTable.c:3790 utils/adt/ri_triggers.c:3307 #, c-format msgid "could not serialize access due to concurrent delete" msgstr "削除が同時に行われたためアクセスの直列化ができませんでした" -#: commands/trigger.c:4693 +#: commands/trigger.c:4718 #, c-format msgid "cannot fire deferred trigger within security-restricted operation" msgstr "セキュリティー制限操作中は、遅延トリガーは発火させられません" -#: commands/trigger.c:5948 +#: commands/trigger.c:5973 #, c-format msgid "constraint \"%s\" is not deferrable" msgstr "制約\"%s\"は遅延可能ではありません" -#: commands/trigger.c:5971 +#: commands/trigger.c:5996 #, c-format msgid "constraint \"%s\" does not exist" msgstr "制約\"%s\"は存在しません" @@ -15898,7 +16012,7 @@ msgstr "基本型を作成するにはスーパーユーザーである必要が msgid "Create the type as a shell type, then create its I/O functions, then do a full CREATE TYPE." msgstr "最初に型をシェル型として生成して、続いてI/O関数を生成した後に完全な CREATE TYPE を実行してください。" -#: commands/typecmds.c:333 commands/typecmds.c:1508 commands/typecmds.c:4530 +#: commands/typecmds.c:333 commands/typecmds.c:1508 commands/typecmds.c:4520 #, c-format msgid "type attribute \"%s\" not recognized" msgstr "型の属性\"%s\"は不明です" @@ -15918,7 +16032,7 @@ msgstr "%sを配列要素の型にすることはできません" msgid "alignment \"%s\" not recognized" msgstr "アライメント\"%s\"は不明です" -#: commands/typecmds.c:456 commands/typecmds.c:4404 +#: commands/typecmds.c:456 commands/typecmds.c:4394 #, c-format msgid "storage \"%s\" not recognized" msgstr "格納方式\"%s\"は不明です" @@ -16008,7 +16122,7 @@ msgstr "ドメインではGENERATEDの指定はサポートしていません" msgid "specifying constraint enforceability not supported for domains" msgstr "ドメインでは制約の強制性指定はサポートしていません" -#: commands/typecmds.c:1363 utils/cache/typcache.c:2782 +#: commands/typecmds.c:1363 utils/cache/typcache.c:2784 #, c-format msgid "%s is not an enum" msgstr "%s は数値ではありません" @@ -16178,77 +16292,77 @@ msgstr "ドメイン\"%2$s\"の制約\"%1$s\"は存在しません、スキッ msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" msgstr "ドメイン\"%2$s\"の制約\"%1$s\"は検査制約ではありません" -#: commands/typecmds.c:3219 +#: commands/typecmds.c:3214 #, c-format msgid "column \"%s\" of table \"%s\" contains null values" msgstr "テーブル\"%2$s\"の列\"%1$s\"にNULL値があります" -#: commands/typecmds.c:3315 +#: commands/typecmds.c:3305 #, c-format msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" msgstr "テーブル\"%2$s\"の列\"%1$s\"に新しい制約に違反する値があります" -#: commands/typecmds.c:3544 commands/typecmds.c:3822 commands/typecmds.c:3907 commands/typecmds.c:4123 +#: commands/typecmds.c:3534 commands/typecmds.c:3812 commands/typecmds.c:3897 commands/typecmds.c:4113 #, c-format msgid "%s is not a domain" msgstr "%s はドメインではありません" -#: commands/typecmds.c:3578 commands/typecmds.c:3734 +#: commands/typecmds.c:3568 commands/typecmds.c:3724 #, c-format msgid "constraint \"%s\" for domain \"%s\" already exists" msgstr "ドメイン\"%2$s\"の制約\"%1$s\"はすでに存在します" -#: commands/typecmds.c:3629 +#: commands/typecmds.c:3619 #, c-format msgid "cannot use table references in domain check constraint" msgstr "ドメインの検査制約ではテーブル参照を使用できません" -#: commands/typecmds.c:3834 commands/typecmds.c:3919 commands/typecmds.c:4273 +#: commands/typecmds.c:3824 commands/typecmds.c:3909 commands/typecmds.c:4263 #, c-format msgid "%s is a table's row type" msgstr "%sはテーブルの行型です" -#: commands/typecmds.c:3844 commands/typecmds.c:3929 commands/typecmds.c:4171 +#: commands/typecmds.c:3834 commands/typecmds.c:3919 commands/typecmds.c:4161 #, c-format msgid "cannot alter array type %s" msgstr "配列型%sを変更できません" -#: commands/typecmds.c:3846 commands/typecmds.c:3931 commands/typecmds.c:4173 +#: commands/typecmds.c:3836 commands/typecmds.c:3921 commands/typecmds.c:4163 #, c-format msgid "You can alter type %s, which will alter the array type as well." msgstr "型%sを変更することができます。これは同時にその配列型も変更します。" -#: commands/typecmds.c:3942 +#: commands/typecmds.c:3932 #, c-format msgid "cannot alter multirange type %s" msgstr "複範囲型%sを変更できません" -#: commands/typecmds.c:3945 +#: commands/typecmds.c:3935 #, c-format msgid "You can alter type %s, which will alter the multirange type as well." msgstr "型%sを変更することができます。これは同時にその複範囲型も変更します。" -#: commands/typecmds.c:4252 +#: commands/typecmds.c:4242 #, c-format msgid "type \"%s\" already exists in schema \"%s\"" msgstr "型\"%s\"はスキーマ\"%s\"内にすでに存在します" -#: commands/typecmds.c:4432 +#: commands/typecmds.c:4422 #, c-format msgid "cannot change type's storage to PLAIN" msgstr "型の格納方式をPLAINには変更できません" -#: commands/typecmds.c:4525 +#: commands/typecmds.c:4515 #, c-format msgid "type attribute \"%s\" cannot be changed" msgstr "型の属性\"%s\"は変更できません" -#: commands/typecmds.c:4543 +#: commands/typecmds.c:4533 #, c-format msgid "must be superuser to alter a type" msgstr "型の変更を行うにはスーパーユーザーである必要があります" -#: commands/typecmds.c:4564 commands/typecmds.c:4573 +#: commands/typecmds.c:4554 commands/typecmds.c:4563 #, c-format msgid "%s is not a base type" msgstr "\"%s\"は基本型ではありません" @@ -16278,7 +16392,7 @@ msgstr "%s属性を持つロールのみがロールを作成できます。" msgid "Only roles with the %s attribute may create roles with the %s attribute." msgstr "%s属性を持つロールのみが%s属性を持つロールを作成できます。" -#: commands/user.c:361 commands/user.c:1399 commands/user.c:1406 gram.y:18610 gram.y:18656 utils/adt/acl.c:5759 utils/adt/acl.c:5765 utils/adt/ddlutils.c:356 +#: commands/user.c:361 commands/user.c:1399 commands/user.c:1406 gram.y:18610 gram.y:18656 utils/adt/acl.c:5759 utils/adt/acl.c:5765 utils/adt/ddlutils.c:187 #, c-format msgid "role name \"%s\" is reserved" msgstr "ロール名\"%s\"は予約されています" @@ -16657,20 +16771,29 @@ msgstr "パーティション親テーブル\"%s\"に対する VACUUM ONLY は msgid "cutoff for removing and freezing tuples is far in the past" msgstr "タプルの削除およびフリーズのカットオフ値が古すぎます" -#: commands/vacuum.c:1174 commands/vacuum.c:1179 +#: commands/vacuum.c:1174 #, c-format msgid "" "Close open transactions soon to avoid wraparound problems.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "周回問題を回避するためにすぐに実行中のトランザクションを終了してください。\n" -"古い準備済みトランザクションのコミットまたはロールバック、もしくは古いレプリケーションスロットの削除が必要な場合もあります。" +"古い準備済みトランザクションのコミットまたはロールバック、もしくは古いレプリケーションスロットの削除も必要かもしれません。" #: commands/vacuum.c:1178 #, c-format msgid "cutoff for freezing multixacts is far in the past" msgstr "マルチトランザクションのフリーズのカットオフ値が古すぎます" +#: commands/vacuum.c:1179 +#, c-format +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions." +msgstr "" +"周回問題を回避するためにすぐに実行中のトランザクションを終了してください。\n" +"古い準備済みトランザクションのコミットまたはロールバックも必要かもしれません。" + #: commands/vacuum.c:1944 #, c-format msgid "some databases have not been vacuumed in over 2 billion transactions" @@ -17034,58 +17157,58 @@ msgstr "パラメータの型%d(%s)が実行計画(%s)を準備する時点と msgid "no value found for parameter %d" msgstr "パラメータ%dの値がありません" -#: executor/execExpr.c:688 executor/execExpr.c:695 executor/execExpr.c:701 executor/execExprInterp.c:5513 executor/execExprInterp.c:5530 executor/execExprInterp.c:5629 executor/nodeModifyTable.c:236 executor/nodeModifyTable.c:255 executor/nodeModifyTable.c:272 executor/nodeModifyTable.c:282 executor/nodeModifyTable.c:292 +#: executor/execExpr.c:667 executor/execExpr.c:674 executor/execExpr.c:680 executor/execExprInterp.c:5513 executor/execExprInterp.c:5530 executor/execExprInterp.c:5629 executor/nodeModifyTable.c:238 executor/nodeModifyTable.c:257 executor/nodeModifyTable.c:274 executor/nodeModifyTable.c:284 executor/nodeModifyTable.c:294 #, c-format msgid "table row type and query-specified row type do not match" msgstr "テーブルの行型と問い合わせで指定した行型が一致しません" -#: executor/execExpr.c:689 executor/nodeModifyTable.c:237 +#: executor/execExpr.c:668 executor/nodeModifyTable.c:239 #, c-format msgid "Query has too many columns." msgstr "問い合わせの列が多すぎます" -#: executor/execExpr.c:696 executor/nodeModifyTable.c:256 +#: executor/execExpr.c:675 executor/nodeModifyTable.c:258 #, c-format msgid "Query provides a value for a dropped column at ordinal position %d." msgstr "問い合わせで %d 番目に削除される列の値を指定しています。" -#: executor/execExpr.c:702 executor/execExprInterp.c:5531 executor/nodeModifyTable.c:283 +#: executor/execExpr.c:681 executor/execExprInterp.c:5531 executor/nodeModifyTable.c:285 #, c-format msgid "Table has type %s at ordinal position %d, but query expects %s." msgstr "テーブルでは %2$d 番目の型は %1$s ですが、問い合わせでは %3$s を想定しています。" -#: executor/execExpr.c:1190 parser/parse_agg.c:912 +#: executor/execExpr.c:1157 parser/parse_agg.c:912 #, c-format msgid "window function calls cannot be nested" msgstr "ウィンドウ関数の呼び出しを入れ子にすることはできません" -#: executor/execExpr.c:1722 +#: executor/execExpr.c:1689 #, c-format msgid "target type is not an array" msgstr "対象型は配列ではありません" -#: executor/execExpr.c:2065 +#: executor/execExpr.c:2032 #, c-format msgid "ROW() column has type %s instead of type %s" msgstr "ROW()列の型が%2$sではなく%1$sです" -#: executor/execExpr.c:2755 executor/execSRF.c:720 parser/parse_func.c:142 parser/parse_func.c:669 parser/parse_func.c:1148 +#: executor/execExpr.c:2722 executor/execSRF.c:720 parser/parse_func.c:142 parser/parse_func.c:675 parser/parse_func.c:1154 #, c-format msgid "cannot pass more than %d argument to a function" msgid_plural "cannot pass more than %d arguments to a function" msgstr[0] "関数に%dを超える引数を渡せません" -#: executor/execExpr.c:2782 executor/execSRF.c:740 executor/functions.c:1605 utils/adt/jsonfuncs.c:4056 utils/fmgr/funcapi.c:89 utils/fmgr/funcapi.c:143 +#: executor/execExpr.c:2749 executor/execSRF.c:740 executor/functions.c:1605 utils/adt/jsonfuncs.c:4056 utils/fmgr/funcapi.c:89 utils/fmgr/funcapi.c:143 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "このコンテキストで集合値の関数は集合を受け付けられません" -#: executor/execExpr.c:3290 parser/parse_node.c:272 parser/parse_node.c:322 +#: executor/execExpr.c:3257 parser/parse_node.c:272 parser/parse_node.c:322 #, c-format msgid "cannot subscript type %s because it does not support subscripting" msgstr "添字をサポートしないため、型%sには添字をつけられません" -#: executor/execExpr.c:3418 executor/execExpr.c:3440 +#: executor/execExpr.c:3385 executor/execExpr.c:3407 #, c-format msgid "type %s does not support subscripted assignment" msgstr "型%sは添字を使った代入をサポートしません" @@ -17105,7 +17228,7 @@ msgstr "型%2$sの属性%1$dの型が間違っています" msgid "Table has type %s, but query expects %s." msgstr "テーブルの型は%sですが、問い合わせでは%sを想定しています。" -#: executor/execExprInterp.c:2513 utils/adt/expandedrecord.c:99 utils/adt/expandedrecord.c:231 utils/cache/typcache.c:1866 utils/cache/typcache.c:2025 utils/cache/typcache.c:2172 utils/fmgr/funcapi.c:571 +#: executor/execExprInterp.c:2513 utils/adt/expandedrecord.c:99 utils/adt/expandedrecord.c:231 utils/cache/typcache.c:1868 utils/cache/typcache.c:2027 utils/cache/typcache.c:2174 utils/fmgr/funcapi.c:571 #, c-format msgid "type %s is not composite" msgstr "型%sは複合型ではありません" @@ -17217,142 +17340,167 @@ msgstr "キーが既存のキーと衝突しています" msgid "empty WITHOUT OVERLAPS value found in column \"%s\" in relation \"%s\"" msgstr "リレーション\"%2$s\"の列\"%1$s\"に空のWITHOUT OVERLAPS値が見つかりました" -#: executor/execMain.c:1100 +#: executor/execMain.c:1101 #, c-format msgid "cannot change sequence \"%s\"" msgstr "シーケンス\"%s\"を変更できません" -#: executor/execMain.c:1106 +#: executor/execMain.c:1107 #, c-format msgid "cannot change TOAST relation \"%s\"" msgstr "TOASTリレーション\"%s\"を変更できません" -#: executor/execMain.c:1125 +#: executor/execMain.c:1126 #, c-format msgid "cannot change materialized view \"%s\"" msgstr "実体化ビュー\"%s\"を変更できません" -#: executor/execMain.c:1137 +#: executor/execMain.c:1134 +#, c-format +msgid "foreign tables don't support FOR PORTION OF" +msgstr "外部テーブルでは FOR PORTION OF はサポートされません" + +#: executor/execMain.c:1135 +#, c-format +msgid "\"%s\" is a foreign table." +msgstr "\"%s\"は外部テーブルです。" + +#: executor/execMain.c:1146 #, c-format msgid "cannot insert into foreign table \"%s\"" msgstr "外部テーブル\"%s\"への挿入ができません" -#: executor/execMain.c:1143 +#: executor/execMain.c:1152 #, c-format msgid "foreign table \"%s\" does not allow inserts" msgstr "外部テーブル\"%s\"は挿入を許しません" -#: executor/execMain.c:1150 +#: executor/execMain.c:1159 #, c-format msgid "cannot update foreign table \"%s\"" msgstr "外部テーブル \"%s\"の更新ができません" -#: executor/execMain.c:1156 +#: executor/execMain.c:1165 #, c-format msgid "foreign table \"%s\" does not allow updates" msgstr "外部テーブル\"%s\"は更新を許しません" -#: executor/execMain.c:1163 +#: executor/execMain.c:1172 #, c-format msgid "cannot delete from foreign table \"%s\"" msgstr "外部テーブル\"%s\"からの削除ができません" -#: executor/execMain.c:1169 +#: executor/execMain.c:1178 #, c-format msgid "foreign table \"%s\" does not allow deletes" msgstr "外部テーブル\"%s\"は削除を許しません" -#: executor/execMain.c:1180 +#: executor/execMain.c:1189 #, c-format msgid "cannot change property graph \"%s\"" msgstr "プロパティ・グラフ\"%s\"を変更できません" -#: executor/execMain.c:1186 +#: executor/execMain.c:1195 #, c-format msgid "cannot change relation \"%s\"" msgstr "リレーション\"%s\"を変更できません" -#: executor/execMain.c:1213 +#: executor/execMain.c:1214 +#, c-format +msgid "cannot modify or insert data into conflict log table \"%s\"" +msgstr "競合ログテーブル\"%s\"のデータの更新や挿入はできません" + +#: executor/execMain.c:1216 +#, c-format +msgid "Conflict log tables are system-managed and only support cleanup using DELETE or TRUNCATE." +msgstr "競合ログテーブルはシステム管理であり、DELETEおよびTRUNCATEを使用したクリーンアップのみをサポートしています。" + +#: executor/execMain.c:1240 #, c-format msgid "cannot lock rows in sequence \"%s\"" msgstr "シーケンス\"%s\"では行のロックはできません" -#: executor/execMain.c:1220 +#: executor/execMain.c:1247 #, c-format msgid "cannot lock rows in TOAST relation \"%s\"" msgstr "TOAST リレーション\"%s\"では行のロックはできません" -#: executor/execMain.c:1227 +#: executor/execMain.c:1254 #, c-format msgid "cannot lock rows in view \"%s\"" msgstr "ビュー\"%s\"では行のロックはできません" -#: executor/execMain.c:1235 +#: executor/execMain.c:1262 #, c-format msgid "cannot lock rows in materialized view \"%s\"" msgstr "実体化ビュー\"%s\"では行のロックはできません" -#: executor/execMain.c:1244 executor/execMain.c:2893 executor/nodeLockRows.c:135 +#: executor/execMain.c:1271 executor/execMain.c:2930 executor/nodeLockRows.c:135 #, c-format msgid "cannot lock rows in foreign table \"%s\"" msgstr "外部テーブル\"%s\"では行のロックはできません" -#: executor/execMain.c:1257 +#: executor/execMain.c:1284 #, c-format msgid "cannot lock rows in relation \"%s\"" msgstr "リレーション\"%s\"では行のロックはできません" -#: executor/execMain.c:1991 +#: executor/execMain.c:1296 +#, c-format +msgid "cannot lock rows in the conflict log table \"%s\"" +msgstr "競合ログテーブル\"%s\"では行のロックはできません" + +#: executor/execMain.c:2028 #, c-format msgid "new row for relation \"%s\" violates partition constraint" msgstr "リレーション\"%s\"の新しい行はパーティション制約に違反しています" -#: executor/execMain.c:1993 executor/execMain.c:2105 executor/execMain.c:2243 executor/execMain.c:2351 +#: executor/execMain.c:2030 executor/execMain.c:2142 executor/execMain.c:2280 executor/execMain.c:2388 #, c-format msgid "Failing row contains %s." msgstr "失敗した行は%sを含みます" -#: executor/execMain.c:2103 +#: executor/execMain.c:2140 #, c-format msgid "new row for relation \"%s\" violates check constraint \"%s\"" msgstr "リレーション\"%s\"の新しい行は検査制約\"%s\"に違反しています" -#: executor/execMain.c:2240 +#: executor/execMain.c:2277 #, c-format msgid "null value in column \"%s\" of relation \"%s\" violates not-null constraint" msgstr "リレーション\"%2$s\"の列\"%1$s\"のNULL値が非NULL制約に違反しています" -#: executor/execMain.c:2349 +#: executor/execMain.c:2386 #, c-format msgid "new row violates check option for view \"%s\"" msgstr "新しい行はビュー\"%s\"のチェックオプションに違反しています" -#: executor/execMain.c:2359 +#: executor/execMain.c:2396 #, c-format msgid "new row violates row-level security policy \"%s\" for table \"%s\"" msgstr "新しい行はテーブル\"%2$s\"行レベルセキュリティポリシ\"%1$s\"に違反しています" -#: executor/execMain.c:2364 +#: executor/execMain.c:2401 #, c-format msgid "new row violates row-level security policy for table \"%s\"" msgstr "新しい行はテーブル\"%s\"の行レベルセキュリティポリシに違反しています" -#: executor/execMain.c:2372 +#: executor/execMain.c:2409 #, c-format msgid "target row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" msgstr "ターゲットの行はテーブル\"%s\"の行レベルセキュリティポリシ\"%s\"(USING式)に違反しています" -#: executor/execMain.c:2377 +#: executor/execMain.c:2414 #, c-format msgid "target row violates row-level security policy (USING expression) for table \"%s\"" msgstr "ターゲットの行はテーブル\"%s\"の行レベルセキュリティポリシ(USING式)に違反しています" -#: executor/execMain.c:2384 +#: executor/execMain.c:2421 #, c-format msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" msgstr "新しい行はテーブル\"%1$s\"の行レベルセキュリティポリシ\"%2$s\"(USING式)に違反しています" -#: executor/execMain.c:2389 +#: executor/execMain.c:2426 #, c-format msgid "new row violates row-level security policy (USING expression) for table \"%s\"" msgstr "新しい行はテーブル\"%s\"の行レベルセキュリティポリシ(USING式)に違反しています" @@ -17586,7 +17734,7 @@ msgstr "戻り値型%sはSQL関数でサポートされていません" msgid "TSC is not supported as timing clock source" msgstr "TSCは時間計測のクロックソースとしてはサポートされていません" -#: executor/nodeAgg.c:4036 executor/nodeWindowAgg.c:3163 +#: executor/nodeAgg.c:4036 executor/nodeWindowAgg.c:3164 #, c-format msgid "aggregate %u needs to have compatible input type and transition type" msgstr "集約%uは入力データ型と遷移用の型間で互換性が必要です" @@ -17631,73 +17779,73 @@ msgstr "RIGHT JOINはマージ結合可能な結合条件でのみサポート msgid "FULL JOIN is only supported with merge-joinable join conditions" msgstr "FULL JOINはマージ結合可能な結合条件でのみサポートされています" -#: executor/nodeModifyTable.c:273 +#: executor/nodeModifyTable.c:275 #, c-format msgid "Query provides a value for a generated column at ordinal position %d." msgstr "問い合わせで %d 番目に生成列の値を指定しています。" -#: executor/nodeModifyTable.c:293 +#: executor/nodeModifyTable.c:295 #, c-format msgid "Query has too few columns." msgstr "問い合わせの列が少なすぎます。" -#: executor/nodeModifyTable.c:1974 executor/nodeModifyTable.c:2048 +#: executor/nodeModifyTable.c:1961 executor/nodeModifyTable.c:2035 #, c-format msgid "tuple to be deleted was already modified by an operation triggered by the current command" msgstr "削除対象のタプルはすでに現在のコマンドによって引き起こされた操作によって変更されています" -#: executor/nodeModifyTable.c:2247 +#: executor/nodeModifyTable.c:2234 #, c-format msgid "invalid ON UPDATE specification" msgstr "不正な ON UPDATE 指定です" -#: executor/nodeModifyTable.c:2248 +#: executor/nodeModifyTable.c:2235 #, c-format msgid "The result tuple would appear in a different partition than the original tuple." msgstr "結果タプルをもとのパーティションではなく異なるパーティションに追加しようとしました。" -#: executor/nodeModifyTable.c:2718 +#: executor/nodeModifyTable.c:2705 #, c-format msgid "cannot move tuple across partitions when a non-root ancestor of the source partition is directly referenced in a foreign key" msgstr "ソースパーティションのルート以外の上位パーティションが外部キーで直接参照されている場合はパーティション間でタプルを移動させることができません" -#: executor/nodeModifyTable.c:2719 +#: executor/nodeModifyTable.c:2706 #, c-format msgid "A foreign key points to ancestor \"%s\" but not the root ancestor \"%s\"." msgstr "外部キーがパーティションルートテーブル\"%2$s\"ではなくパーティション親テーブル\"%1$s\"を指しています。" -#: executor/nodeModifyTable.c:2722 +#: executor/nodeModifyTable.c:2709 #, c-format msgid "Consider defining the foreign key on table \"%s\"." msgstr "テーブル\"%s\"上に外部キー制約を定義することを検討してください。" #. translator: %s is a SQL command name -#: executor/nodeModifyTable.c:3070 executor/nodeModifyTable.c:3791 executor/nodeModifyTable.c:3988 +#: executor/nodeModifyTable.c:3057 executor/nodeModifyTable.c:3778 executor/nodeModifyTable.c:3975 #, c-format msgid "%s command cannot affect row a second time" msgstr "%sコマンドは単一の行に2度は適用できません" -#: executor/nodeModifyTable.c:3072 +#: executor/nodeModifyTable.c:3059 #, c-format msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." msgstr "同じコマンドでの挿入候補の行が同じ制約値を持つことがないようにしてください" -#: executor/nodeModifyTable.c:3784 executor/nodeModifyTable.c:3981 +#: executor/nodeModifyTable.c:3771 executor/nodeModifyTable.c:3968 #, c-format msgid "tuple to be updated or deleted was already modified by an operation triggered by the current command" msgstr "更新または削除対象のタプルは、現在のコマンドによって発火した操作トリガーによってすでに更新されています" -#: executor/nodeModifyTable.c:3793 executor/nodeModifyTable.c:3990 +#: executor/nodeModifyTable.c:3780 executor/nodeModifyTable.c:3977 #, c-format msgid "Ensure that not more than one source row matches any one target row." msgstr "ソース行が2行以上ターゲット行に合致しないようにしてください。" -#: executor/nodeModifyTable.c:3867 +#: executor/nodeModifyTable.c:3854 #, c-format msgid "tuple to be merged was already moved to another partition due to concurrent update" msgstr "マージ対象のタプルは同時に行われた更新によってすでに他の子テーブルに移動されています" -#: executor/nodeModifyTable.c:5604 +#: executor/nodeModifyTable.c:5619 #, c-format msgid "FOR PORTION OF target was null" msgstr "FOR PORTION OF の対象が null でした" @@ -17742,37 +17890,37 @@ msgstr "列\"%s\"のフィルタがnullです。" msgid "null is not allowed in column \"%s\"" msgstr "列\"%s\"でnullは許可されません" -#: executor/nodeWindowAgg.c:402 +#: executor/nodeWindowAgg.c:403 #, c-format msgid "moving-aggregate transition function must not return null" msgstr "移動集約の推移関数はnullを返却してはなりません" -#: executor/nodeWindowAgg.c:2223 +#: executor/nodeWindowAgg.c:2224 #, c-format msgid "frame starting offset must not be null" msgstr "フレームの開始オフセットは NULL であってはなりません" -#: executor/nodeWindowAgg.c:2237 +#: executor/nodeWindowAgg.c:2238 #, c-format msgid "frame starting offset must not be negative" msgstr "フレームの開始オフセットは負数であってはなりません" -#: executor/nodeWindowAgg.c:2250 +#: executor/nodeWindowAgg.c:2251 #, c-format msgid "frame ending offset must not be null" msgstr "フレームの終了オフセットは NULL であってはなりません" -#: executor/nodeWindowAgg.c:2264 +#: executor/nodeWindowAgg.c:2265 #, c-format msgid "frame ending offset must not be negative" msgstr "フレームの終了オフセットは負数であってはなりません" -#: executor/nodeWindowAgg.c:3079 +#: executor/nodeWindowAgg.c:3080 #, c-format msgid "aggregate function %s does not support use as a window function" msgstr "集約関数 %s はウィンドウ関数としての使用をサポートしていません" -#: executor/nodeWindowAgg.c:3642 +#: executor/nodeWindowAgg.c:3664 #, c-format msgid "function %s does not allow RESPECT/IGNORE NULLS" msgstr "関数 %s は RESPECT/IGNORE NULLS を受け付けません" @@ -17823,7 +17971,7 @@ msgstr "カーソルで%s問い合わせを開くことができません" msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHAREはサポートされていません" -#: executor/spi.c:1720 parser/analyze.c:3431 +#: executor/spi.c:1720 parser/analyze.c:3428 #, c-format msgid "Scrollable cursors must be READ ONLY." msgstr "スクロール可能カーソルは読み取り専用である必要があります。" @@ -17984,7 +18132,7 @@ msgstr "一時テーブル作成におけるGLOBALは廃止予定です" msgid "for a generated column, GENERATED ALWAYS must be specified" msgstr "生成カラムに対しては GENERATED ALWAYS の指定が必須です" -#: gram.y:4628 utils/adt/ri_triggers.c:2390 +#: gram.y:4628 utils/adt/ri_triggers.c:2413 #, c-format msgid "MATCH PARTIAL not yet implemented" msgstr "MMATCH PARTIAL はまだ実装されていません" @@ -18023,7 +18171,7 @@ msgstr "CREATE OR REPLACE CONSTRAINT TRIGGERはサポートされません" msgid "duplicate trigger events specified" msgstr "重複したトリガーイベントが指定されました" -#: gram.y:6425 parser/parse_utilcmd.c:4271 parser/parse_utilcmd.c:4297 +#: gram.y:6425 parser/parse_utilcmd.c:4267 parser/parse_utilcmd.c:4293 #, c-format msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" msgstr "INITIALLY DEFERREDと宣言された制約はDEFERRABLEでなければなりません" @@ -18394,7 +18542,7 @@ msgstr "不正な16進文字列" msgid "unexpected end after backslash" msgstr "バックスラッシュの後の想定外の終了" -#: jsonpath_scan.l:201 repl_scanner.l:217 scan.l:719 +#: jsonpath_scan.l:201 repl_scanner.l:221 scan.l:719 msgid "unterminated quoted string" msgstr "文字列の引用符が閉じていません" @@ -18620,10 +18768,10 @@ msgstr "OAuth検証モジュール\"%s\"は\"%s\"コールバックを実装す #: libpq/auth-oauth.c:870 #, c-format -msgid "parameter %s\" must be set for authentication method \"%s\"" +msgid "parameter \"%s\" must be set for authentication method \"%s\"" msgstr "認証方式\"%2$s\"では、パラメータ\"%1$s\"を設定しなければなりません" -#: libpq/auth-oauth.c:872 libpq/auth-oauth.c:906 libpq/auth-oauth.c:923 libpq/auth-oauth.c:1076 libpq/be-secure-common.c:223 libpq/be-secure-common.c:238 libpq/be-secure-common.c:248 libpq/be-secure-common.c:262 libpq/be-secure-common.c:272 libpq/be-secure-common.c:289 libpq/be-secure-common.c:306 libpq/be-secure-common.c:334 libpq/be-secure-common.c:344 libpq/be-secure-openssl.c:272 libpq/be-secure-openssl.c:286 libpq/be-secure-openssl.c:311 libpq/hba.c:327 +#: libpq/auth-oauth.c:872 libpq/auth-oauth.c:906 libpq/auth-oauth.c:923 libpq/auth-oauth.c:1076 libpq/be-secure-common.c:223 libpq/be-secure-common.c:238 libpq/be-secure-common.c:248 libpq/be-secure-common.c:262 libpq/be-secure-common.c:272 libpq/be-secure-common.c:289 libpq/be-secure-common.c:306 libpq/be-secure-common.c:334 libpq/be-secure-common.c:344 libpq/be-secure-openssl.c:270 libpq/be-secure-openssl.c:284 libpq/be-secure-openssl.c:309 libpq/hba.c:327 #: libpq/hba.c:662 libpq/hba.c:1247 libpq/hba.c:1267 libpq/hba.c:1290 libpq/hba.c:1303 libpq/hba.c:1356 libpq/hba.c:1384 libpq/hba.c:1392 libpq/hba.c:1404 libpq/hba.c:1425 libpq/hba.c:1438 libpq/hba.c:1463 libpq/hba.c:1490 libpq/hba.c:1502 libpq/hba.c:1561 libpq/hba.c:1581 libpq/hba.c:1595 libpq/hba.c:1615 libpq/hba.c:1626 libpq/hba.c:1641 libpq/hba.c:1660 libpq/hba.c:1676 libpq/hba.c:1688 libpq/hba.c:1754 libpq/hba.c:1767 libpq/hba.c:1789 libpq/hba.c:1801 #: libpq/hba.c:1819 libpq/hba.c:1869 libpq/hba.c:1913 libpq/hba.c:1924 libpq/hba.c:1940 libpq/hba.c:1982 libpq/hba.c:2028 libpq/hba.c:2045 libpq/hba.c:2058 libpq/hba.c:2070 libpq/hba.c:2089 libpq/hba.c:2175 libpq/hba.c:2193 libpq/hba.c:2302 libpq/hba.c:2324 tsearch/ts_locale.c:192 #, c-format @@ -18787,454 +18935,463 @@ msgstr "client-final-message 中の proof の形式が不正です" msgid "Garbage found at the end of client-final-message." msgstr "client-final-message の終端に不要なデータがあります。" -#: libpq/auth.c:259 +#: libpq/auth.c:261 #, c-format msgid "authentication failed for user \"%s\": host rejected" msgstr "ユーザー\"%s\"の認証に失敗しました: ホストを拒絶しました" -#: libpq/auth.c:262 +#: libpq/auth.c:264 #, c-format msgid "\"trust\" authentication failed for user \"%s\"" msgstr "ユーザー\"%s\"の\"trust\"認証に失敗しました" -#: libpq/auth.c:265 +#: libpq/auth.c:267 #, c-format msgid "Ident authentication failed for user \"%s\"" msgstr "ユーザー\"%s\"のIdent認証に失敗しました" -#: libpq/auth.c:268 +#: libpq/auth.c:270 #, c-format msgid "Peer authentication failed for user \"%s\"" msgstr "ユーザー\"%s\"で対向(peer)認証に失敗しました" -#: libpq/auth.c:273 +#: libpq/auth.c:275 #, c-format msgid "password authentication failed for user \"%s\"" msgstr "ユーザー\"%s\"のパスワード認証に失敗しました" -#: libpq/auth.c:278 +#: libpq/auth.c:280 #, c-format msgid "GSSAPI authentication failed for user \"%s\"" msgstr "ユーザー\"%s\"のGSSAPI認証に失敗しました" -#: libpq/auth.c:281 +#: libpq/auth.c:283 #, c-format msgid "SSPI authentication failed for user \"%s\"" msgstr "ユーザー\"%s\"のSSPI認証に失敗しました" -#: libpq/auth.c:284 +#: libpq/auth.c:286 #, c-format msgid "PAM authentication failed for user \"%s\"" msgstr "ユーザー\"%s\"のPAM認証に失敗しました" -#: libpq/auth.c:287 +#: libpq/auth.c:289 #, c-format msgid "BSD authentication failed for user \"%s\"" msgstr "ユーザー\"%s\"のBSD認証に失敗しました" -#: libpq/auth.c:290 +#: libpq/auth.c:292 #, c-format msgid "LDAP authentication failed for user \"%s\"" msgstr "ユーザー\"%s\"のLDAP認証に失敗しました" -#: libpq/auth.c:293 +#: libpq/auth.c:295 #, c-format msgid "certificate authentication failed for user \"%s\"" msgstr "ユーザー\"%s\"の証明書認証に失敗しました" -#: libpq/auth.c:296 +#: libpq/auth.c:298 #, c-format msgid "OAuth bearer authentication failed for user \"%s\"" msgstr "ユーザー \"%s\" の OAuth Bearer 認証に失敗しました" -#: libpq/auth.c:299 +#: libpq/auth.c:301 #, c-format msgid "authentication failed for user \"%s\": invalid authentication method" msgstr "ユーザー\"%s\"の認証に失敗しました: 認証方式が不正です" -#: libpq/auth.c:303 +#: libpq/auth.c:305 #, c-format msgid "Connection matched file \"%s\" line %d: \"%s\"" msgstr "接続はファイル%sの行%dに一致しました: \"%s\"" -#: libpq/auth.c:349 +#: libpq/auth.c:351 #, c-format msgid "authentication identifier set more than once" msgstr "認証識別子が2度以上設定されました" -#: libpq/auth.c:350 +#: libpq/auth.c:352 #, c-format msgid "previous identifier: \"%s\"; new identifier: \"%s\"" msgstr "以前の識別子: \"%s\"; 新しい識別子: \"%s\"" -#: libpq/auth.c:360 +#: libpq/auth.c:362 #, c-format msgid "connection authenticated: identity=\"%s\" method=%s (%s:%d)" msgstr "接続認証完了: 識別名=\"%s\" 方式=%s (%s:%d)" -#: libpq/auth.c:409 +#: libpq/auth.c:411 #, c-format msgid "client certificates can only be checked if a root certificate store is available" msgstr "クライアント証明書はルート証明書ストアが利用できる場合にのみ検証されます" -#: libpq/auth.c:420 +#: libpq/auth.c:422 #, c-format msgid "connection requires a valid client certificate" msgstr "この接続には有効なクライアント証明が必要です" -#: libpq/auth.c:451 libpq/auth.c:497 +#: libpq/auth.c:453 libpq/auth.c:499 msgid "GSS encryption" msgstr "GSS暗号化" -#: libpq/auth.c:454 libpq/auth.c:500 +#: libpq/auth.c:456 libpq/auth.c:502 msgid "SSL encryption" msgstr "SSL暗号化" -#: libpq/auth.c:456 libpq/auth.c:502 +#: libpq/auth.c:458 libpq/auth.c:504 msgid "no encryption" msgstr "暗号化なし" #. translator: last %s describes encryption state -#: libpq/auth.c:462 +#: libpq/auth.c:464 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" msgstr "pg_hba.conf の設定でホスト \"%s\"、ユーザー \"%s\", %s 用のレプリケーション接続を拒否しました" #. translator: last %s describes encryption state -#: libpq/auth.c:469 +#: libpq/auth.c:471 #, c-format msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "pg_hba.conf の設定でホスト \"%s\"、ユーザー \"%s\"、データベース \"%s\", %sの接続を拒否しました" -#: libpq/auth.c:507 +#: libpq/auth.c:509 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup matches." msgstr "クライアントIPアドレスは\"%s\"に解決され、前方検索と一致しました。" -#: libpq/auth.c:510 +#: libpq/auth.c:512 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup not checked." msgstr "クライアントIPアドレスは\"%s\"に解決されました。前方検索は検査されません。" -#: libpq/auth.c:513 +#: libpq/auth.c:515 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup does not match." msgstr "クライアントIPアドレスは\"%s\"に解決され、前方検索と一致しませんでした。" -#: libpq/auth.c:516 +#: libpq/auth.c:518 #, c-format msgid "Could not translate client host name \"%s\" to IP address: %s." msgstr "クライアントのホスト名\"%s\"をIPアドレスに変換できませんでした: %s。" -#: libpq/auth.c:521 +#: libpq/auth.c:523 #, c-format msgid "Could not resolve client IP address to a host name: %s." msgstr "クライアントのIPアドレスをホスト名に解決できませんでした: %s。" #. translator: last %s describes encryption state -#: libpq/auth.c:529 +#: libpq/auth.c:531 #, c-format msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" msgstr "pg_hba.conf にホスト\"%s\"、ユーザー\"%s\", %s用のエントリがありません" #. translator: last %s describes encryption state -#: libpq/auth.c:537 +#: libpq/auth.c:539 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "pg_hba.conf にホスト\"%s\"、ユーザー\"%s\"、データベース\"%s, %s用のエントリがありません" -#: libpq/auth.c:659 +#: libpq/auth.c:661 #, c-format msgid "connection authenticated: user=\"%s\" method=%s (%s:%d)" msgstr "接続認証完了: ユーザー=\"%s\" 方式=%s (%s:%d)" -#: libpq/auth.c:731 +#: libpq/auth.c:733 #, c-format msgid "expected password response, got message type %d" msgstr "パスワード応答を想定しましたが、メッセージタイプ%dを受け取りました" -#: libpq/auth.c:752 +#: libpq/auth.c:754 #, c-format msgid "invalid password packet size" msgstr "パスワードパケットのサイズが不正です" -#: libpq/auth.c:770 +#: libpq/auth.c:772 #, c-format msgid "empty password returned by client" msgstr "クライアントから空のパスワードが返されました" -#: libpq/auth.c:898 +#: libpq/auth.c:906 #, c-format msgid "could not generate random MD5 salt" msgstr "ランダムなMD5ソルトの生成に失敗しました" -#: libpq/auth.c:949 libpq/be-secure-gssapi.c:555 +#: libpq/auth.c:945 +msgid "authenticated with an MD5-encrypted password" +msgstr "MD5暗号化パスワードで認証されました" + +#: libpq/auth.c:946 libpq/crypt.c:247 +#, c-format +msgid "MD5 password support is deprecated and will be removed in a future release of PostgreSQL." +msgstr "MD5パスワードは非推奨であり、PostgreSQLの将来のリリースでは廃止される予定です。" + +#: libpq/auth.c:982 libpq/be-secure-gssapi.c:555 #, c-format msgid "could not set environment: %m" msgstr "環境を設定できません: %m" -#: libpq/auth.c:988 +#: libpq/auth.c:1021 #, c-format msgid "expected GSS response, got message type %d" msgstr "GSS応答を想定しましたが、メッセージタイプ %d を受け取りました" -#: libpq/auth.c:1054 +#: libpq/auth.c:1087 msgid "accepting GSS security context failed" msgstr "GSSセキュリティコンテキストの受け付けに失敗しました" -#: libpq/auth.c:1095 +#: libpq/auth.c:1128 msgid "retrieving GSS user name failed" msgstr "GSSユーザー名の受信に失敗しました" -#: libpq/auth.c:1241 +#: libpq/auth.c:1274 msgid "could not acquire SSPI credentials" msgstr "SSPIの資格ハンドルを入手できませんでした" -#: libpq/auth.c:1266 +#: libpq/auth.c:1299 #, c-format msgid "expected SSPI response, got message type %d" msgstr "SSPI応答を想定しましたが、メッセージタイプ%dを受け取りました" -#: libpq/auth.c:1344 +#: libpq/auth.c:1377 msgid "could not accept SSPI security context" msgstr "SSPIセキュリティコンテキストを受け付けられませんでした" -#: libpq/auth.c:1385 +#: libpq/auth.c:1418 msgid "could not get token from SSPI security context" msgstr "SSPIセキュリティコンテキストからトークンを入手できませんでした" -#: libpq/auth.c:1521 libpq/auth.c:1540 +#: libpq/auth.c:1554 libpq/auth.c:1573 #, c-format msgid "could not translate name" msgstr "名前の変換ができませんでした" -#: libpq/auth.c:1553 +#: libpq/auth.c:1586 #, c-format msgid "realm name too long" msgstr "realm名が長すぎます" -#: libpq/auth.c:1568 +#: libpq/auth.c:1601 #, c-format msgid "translated account name too long" msgstr "変換後のアカウント名が長すぎます" -#: libpq/auth.c:1756 +#: libpq/auth.c:1789 #, c-format msgid "could not create socket for Ident connection: %m" msgstr "Ident接続用のソケットを作成できませんでした: %m" -#: libpq/auth.c:1771 +#: libpq/auth.c:1804 #, c-format msgid "could not bind to local address \"%s\": %m" msgstr "ローカルアドレス\"%s\"にバインドできませんでした: %m" -#: libpq/auth.c:1783 +#: libpq/auth.c:1816 #, c-format msgid "could not connect to Ident server at address \"%s\", port %s: %m" msgstr "アドレス\"%s\"、ポート%sのIdentサーバーに接続できませんでした: %m" -#: libpq/auth.c:1805 +#: libpq/auth.c:1838 #, c-format msgid "could not send query to Ident server at address \"%s\", port %s: %m" msgstr "アドレス\"%s\"、ポート%sのIdentサーバーに問い合わせを送信できませんでした: %m" -#: libpq/auth.c:1822 +#: libpq/auth.c:1855 #, c-format msgid "could not receive response from Ident server at address \"%s\", port %s: %m" msgstr "アドレス\"%s\"、ポート%sのIdentサーバーからの応答を受信できませんでした: %m" -#: libpq/auth.c:1832 +#: libpq/auth.c:1865 #, c-format msgid "invalidly formatted response from Ident server: \"%s\"" msgstr "Identサーバーからの応答の書式が不正です: \"%s\"" -#: libpq/auth.c:1888 +#: libpq/auth.c:1921 #, c-format msgid "peer authentication is not supported on this platform" msgstr "このプラットフォームでは対向(peer)認証はサポートされていません" -#: libpq/auth.c:1892 +#: libpq/auth.c:1925 #, c-format msgid "could not get peer credentials: %m" msgstr "ピアの資格証明を入手できませんでした: %m" -#: libpq/auth.c:1902 +#: libpq/auth.c:1935 #, c-format msgid "could not look up local user ID %ld: %m" msgstr "ローカルユーザーID %ldの参照に失敗しました: %m" -#: libpq/auth.c:1908 +#: libpq/auth.c:1941 #, c-format msgid "local user with ID %ld does not exist" msgstr "ID %ld を持つローカルユーザーは存在しません" -#: libpq/auth.c:2008 +#: libpq/auth.c:2041 #, c-format msgid "error from underlying PAM layer: %s" msgstr "背後のPAM層でエラーがありました: %s" -#: libpq/auth.c:2019 +#: libpq/auth.c:2052 #, c-format msgid "unsupported PAM conversation %d/\"%s\"" msgstr "非サポートのPAM変換%d/\"%s\"" -#: libpq/auth.c:2076 +#: libpq/auth.c:2109 #, c-format msgid "could not create PAM authenticator: %s" msgstr "PAM authenticatorを作成できませんでした: %s" -#: libpq/auth.c:2087 +#: libpq/auth.c:2120 #, c-format msgid "pam_set_item(PAM_USER) failed: %s" msgstr "pam_set_item(PAM_USER)が失敗しました: %s" -#: libpq/auth.c:2119 +#: libpq/auth.c:2152 #, c-format msgid "pam_set_item(PAM_RHOST) failed: %s" msgstr "pam_set_item(PAM_RHOST)が失敗しました: %s" -#: libpq/auth.c:2131 +#: libpq/auth.c:2164 #, c-format msgid "pam_set_item(PAM_CONV) failed: %s" msgstr "\"pam_set_item(PAM_CONV)が失敗しました: %s" -#: libpq/auth.c:2144 +#: libpq/auth.c:2177 #, c-format msgid "pam_authenticate failed: %s" msgstr "\"pam_authenticateが失敗しました: %s" -#: libpq/auth.c:2157 +#: libpq/auth.c:2190 #, c-format msgid "pam_acct_mgmt failed: %s" msgstr "pam_acct_mgmtが失敗しました: %s" -#: libpq/auth.c:2168 +#: libpq/auth.c:2201 #, c-format msgid "could not release PAM authenticator: %s" msgstr "PAM authenticatorを解放できませんでした: %s" -#: libpq/auth.c:2248 +#: libpq/auth.c:2281 #, c-format msgid "could not initialize LDAP: error code %lu" msgstr "LDAPを初期化できませんでした: エラーコード %lu" -#: libpq/auth.c:2285 +#: libpq/auth.c:2318 #, c-format msgid "could not extract domain name from ldapbasedn" msgstr "ldapbasedn からドメイン名を抽出できませんでした" -#: libpq/auth.c:2293 +#: libpq/auth.c:2326 #, c-format msgid "LDAP authentication could not find DNS SRV records for \"%s\"" msgstr "LDAP認証で\"%s\"に対する DNS SRV レコードが見つかりませんでした" -#: libpq/auth.c:2295 +#: libpq/auth.c:2328 #, c-format msgid "Set an LDAP server name explicitly." msgstr "LDAPサーバー名を明示的に指定してください。" -#: libpq/auth.c:2347 +#: libpq/auth.c:2380 #, c-format msgid "could not initialize LDAP: %s" msgstr "LDAPを初期化できませんでした: %s" -#: libpq/auth.c:2357 +#: libpq/auth.c:2390 #, c-format msgid "ldaps not supported with this LDAP library" msgstr "この LDAP ライブラリでは ldaps はサポートされていません" -#: libpq/auth.c:2365 +#: libpq/auth.c:2398 #, c-format msgid "could not initialize LDAP: %m" msgstr "LDAPを初期化できませんでした: %m" -#: libpq/auth.c:2375 +#: libpq/auth.c:2408 #, c-format msgid "could not set LDAP protocol version: %s" msgstr "LDAPプロトコルバージョンを設定できませんでした: %s" -#: libpq/auth.c:2391 +#: libpq/auth.c:2424 #, c-format msgid "could not start LDAP TLS session: %s" msgstr "LDAP TLSセッションを開始できませんでした: %s" -#: libpq/auth.c:2468 +#: libpq/auth.c:2501 #, c-format msgid "LDAP server not specified, and no ldapbasedn" msgstr "LDAP サーバーも ldapbasedn も指定されていません" -#: libpq/auth.c:2475 +#: libpq/auth.c:2508 #, c-format msgid "LDAP server not specified" msgstr "LDAP サーバーの指定がありません" -#: libpq/auth.c:2537 +#: libpq/auth.c:2570 #, c-format msgid "invalid character in user name for LDAP authentication" msgstr "LDAP 認証でユーザー名の中に不正な文字があります" -#: libpq/auth.c:2554 +#: libpq/auth.c:2587 #, c-format msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" msgstr "サーバー\"%2$s\"で、ldapbinddn \"%1$s\"によるLDAPバインドを実行できませんでした: %3$s" -#: libpq/auth.c:2584 +#: libpq/auth.c:2617 #, c-format msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" msgstr "サーバー\"%2$s\"で、フィルタ\"%1$s\"によるLDAP検索ができませんでした: %3$s" -#: libpq/auth.c:2600 +#: libpq/auth.c:2633 #, c-format msgid "LDAP user \"%s\" does not exist" msgstr "LDAPサーバー\"%s\"は存在しません" -#: libpq/auth.c:2601 +#: libpq/auth.c:2634 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." msgstr "サーバー\"%2$s\"で、フィルタ\"%1$s\"によるLDAP検索が何も返しませんでした。" -#: libpq/auth.c:2605 +#: libpq/auth.c:2638 #, c-format msgid "LDAP user \"%s\" is not unique" msgstr "LDAPユーザー\"%s\"は一意ではありません" -#: libpq/auth.c:2606 +#: libpq/auth.c:2639 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." msgstr[0] "サーバー\"%2$s\"で、フィルタ\"%1$s\"によるLDAP検索が%3$d項目返しました。" -#: libpq/auth.c:2626 +#: libpq/auth.c:2659 #, c-format msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" msgstr "サーバー\"%2$s\"で\"%1$s\"にマッチする最初のエントリの dn を取得できません: %3$s" -#: libpq/auth.c:2653 +#: libpq/auth.c:2686 #, c-format msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" msgstr "サーバー\"%2$s\"でユーザー\"%1$s\"のLDAPログインが失敗しました: %3$s" -#: libpq/auth.c:2685 +#: libpq/auth.c:2718 #, c-format msgid "LDAP diagnostics: %s" msgstr "LDAP診断: %s" -#: libpq/auth.c:2723 +#: libpq/auth.c:2756 #, c-format msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" msgstr "ユーザー \"%s\" の証明書認証に失敗しました: クライアント証明書にユーザー名が含まれていません" -#: libpq/auth.c:2744 +#: libpq/auth.c:2777 #, c-format msgid "certificate authentication failed for user \"%s\": unable to retrieve subject DN" msgstr "ユーザー\"%s\"の証明書認証に失敗しました: サブジェクト識別名(DN)が取得できません" -#: libpq/auth.c:2767 +#: libpq/auth.c:2800 #, c-format msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": DN mismatch" msgstr "ユーザー\"%s\"に対する証明書の検証(clientcert=verify-full) に失敗しました: DN 不一致" -#: libpq/auth.c:2772 +#: libpq/auth.c:2805 #, c-format msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch" msgstr "ユーザー\"%s\"に対する証明書の検証(clientcert=verify-full) に失敗しました: CN 不一致" @@ -19400,287 +19557,287 @@ msgstr "GSSAPIセキュリティコンテキストを受け入れられません msgid "GSSAPI size check error" msgstr "GSSAPIサイズチェックエラー" -#: libpq/be-secure-openssl.c:216 +#: libpq/be-secure-openssl.c:214 #, c-format msgid "ssl_sni is not supported with LibreSSL" msgstr "LibreSSLでは ssl_sni はサポートされていません" -#: libpq/be-secure-openssl.c:233 +#: libpq/be-secure-openssl.c:231 #, c-format msgid "could not load \"%s\": %s" msgstr "\"%s\"をロードできませんでした: %s" -#: libpq/be-secure-openssl.c:271 +#: libpq/be-secure-openssl.c:269 #, c-format msgid "multiple default hosts specified" msgstr "複数のデフォルトホストが指定されています" -#: libpq/be-secure-openssl.c:285 +#: libpq/be-secure-openssl.c:283 #, c-format msgid "multiple no_sni hosts specified" msgstr "複数のno_sniホストが指定されています" -#: libpq/be-secure-openssl.c:309 +#: libpq/be-secure-openssl.c:307 #, c-format msgid "multiple entries for host \"%s\" specified" msgstr "ホスト\"%s\"のエントリが複数指定されています" -#: libpq/be-secure-openssl.c:367 +#: libpq/be-secure-openssl.c:365 #, c-format msgid "no SSL configurations loaded" msgstr "SSL設定が読み込まれていません" #. translator: The two %s contain filenames -#: libpq/be-secure-openssl.c:369 +#: libpq/be-secure-openssl.c:367 #, c-format msgid "If ssl_sni is enabled then add configuration to \"%s\", else \"%s\"" msgstr "ssl_sniが有効な場合は\"%s\"、そうでなければ\"%s\"の設定を追加してください。" -#: libpq/be-secure-openssl.c:390 libpq/be-secure-openssl.c:622 +#: libpq/be-secure-openssl.c:388 libpq/be-secure-openssl.c:620 #, c-format msgid "could not create SSL context: %s" msgstr "SSLコンテキストを作成できませんでした: %s" #. translator: first %s is a GUC option name, second %s is its value -#: libpq/be-secure-openssl.c:425 libpq/be-secure-openssl.c:448 +#: libpq/be-secure-openssl.c:423 libpq/be-secure-openssl.c:446 #, c-format msgid "\"%s\" setting \"%s\" not supported by this build" msgstr "このビルドでは\"%s\"の\"%s\"への設定はサポートされていません" -#: libpq/be-secure-openssl.c:435 +#: libpq/be-secure-openssl.c:433 #, c-format msgid "could not set minimum SSL protocol version" msgstr "最小SSLプロトコルバージョンを設定できませんでした" -#: libpq/be-secure-openssl.c:458 +#: libpq/be-secure-openssl.c:456 #, c-format msgid "could not set maximum SSL protocol version" msgstr "最大SSLプロトコルバージョンを設定できませんでした" -#: libpq/be-secure-openssl.c:475 +#: libpq/be-secure-openssl.c:473 #, c-format msgid "could not set SSL protocol version range" msgstr "SSLプロトコルバージョンの範囲を設定できませんでした" -#: libpq/be-secure-openssl.c:476 +#: libpq/be-secure-openssl.c:474 #, c-format msgid "\"%s\" cannot be higher than \"%s\"" msgstr "\"%s\"は\"%s\"より大きくできません" -#: libpq/be-secure-openssl.c:529 +#: libpq/be-secure-openssl.c:527 #, c-format msgid "could not set the TLSv1.2 cipher list (no valid ciphers available)" msgstr " TLSv1.2 の暗号方式リストが設定できませんでした (有効な暗号方式がありません)" -#: libpq/be-secure-openssl.c:544 +#: libpq/be-secure-openssl.c:542 #, c-format msgid "could not set the TLSv1.3 cipher suites (no valid ciphers available)" msgstr " TLSv1.3 の暗号スイートが設定できませんでした (有効な暗号方式がありません)" -#: libpq/be-secure-openssl.c:643 +#: libpq/be-secure-openssl.c:641 #, c-format msgid "SNI is enabled; installed TLS init hook will be ignored" msgstr "SNIが有効です; 設定されている TLS init hook は無視されます" #. translator: first %s is a GUC, second %s contains a filename -#: libpq/be-secure-openssl.c:645 +#: libpq/be-secure-openssl.c:643 #, c-format msgid "TLS init hooks are incompatible with SNI. Set \"%s\" to \"off\" to make use of the hook that is currently installed, or remove the hook and use per-host passphrase commands in \"%s\"." msgstr "TLS init hook はSNIと共存不可です。\"%s\"を\"off\"に設定して、現在設定されているフックを使用可能にするか、このフックを削除して、\"%s\"内のホストごとのパスフレーズ・コマンドを使用するようにしてください。" -#: libpq/be-secure-openssl.c:697 +#: libpq/be-secure-openssl.c:695 #, c-format msgid "could not load server certificate file \"%s\": %s" msgstr "サーバー証明書ファイル\"%s\"をロードできませんでした: %s" -#: libpq/be-secure-openssl.c:721 +#: libpq/be-secure-openssl.c:719 #, c-format msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" msgstr "パスフレーズが要求されたため秘密鍵ファイル\"%s\"をリロードできませんでした" -#: libpq/be-secure-openssl.c:726 +#: libpq/be-secure-openssl.c:724 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "秘密鍵ファイル\"%s\"をロードできませんでした: %s" -#: libpq/be-secure-openssl.c:735 +#: libpq/be-secure-openssl.c:733 #, c-format msgid "check of private key failed: %s" msgstr "秘密鍵の検査に失敗しました: %s" -#: libpq/be-secure-openssl.c:752 +#: libpq/be-secure-openssl.c:750 #, c-format msgid "could not load root certificate file \"%s\": %s" msgstr "ルート証明書ファイル\"%s\"をロードできませんでした: %s" -#: libpq/be-secure-openssl.c:791 +#: libpq/be-secure-openssl.c:789 #, c-format msgid "could not load SSL certificate revocation list file \"%s\": %s" msgstr "SSL証明失効リストファイル\"%s\"をロードできませんでした: %s" -#: libpq/be-secure-openssl.c:799 +#: libpq/be-secure-openssl.c:797 #, c-format msgid "could not load SSL certificate revocation list directory \"%s\": %s" msgstr "SSL証明失効リストディレクトリ\"%s\"をロードできませんでした: %s" -#: libpq/be-secure-openssl.c:807 +#: libpq/be-secure-openssl.c:805 #, c-format msgid "could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s" msgstr "SSL証明失効リストファイル\"%s\"またはディレクトリ\"%s\"をロードできませんでした: %s" -#: libpq/be-secure-openssl.c:850 +#: libpq/be-secure-openssl.c:848 #, c-format msgid "could not initialize SSL connection: SSL context not set up" msgstr "SSL接続を初期化できませんでした: SSLコンテクストが準備できていません" -#: libpq/be-secure-openssl.c:864 +#: libpq/be-secure-openssl.c:862 #, c-format msgid "could not initialize SSL connection: %s" msgstr "SSL接続を初期化できませんでした: %s" -#: libpq/be-secure-openssl.c:872 +#: libpq/be-secure-openssl.c:870 #, c-format msgid "could not set SSL socket: %s" msgstr "SSLソケットを設定できませんでした: %s" -#: libpq/be-secure-openssl.c:964 +#: libpq/be-secure-openssl.c:962 #, c-format msgid "could not accept SSL connection: %m" msgstr "SSL接続を受け付けられませんでした: %m" -#: libpq/be-secure-openssl.c:968 libpq/be-secure-openssl.c:1026 +#: libpq/be-secure-openssl.c:966 libpq/be-secure-openssl.c:1024 #, c-format msgid "could not accept SSL connection: EOF detected" msgstr "SSL接続を受け付けられませんでした: EOFを検出しました" -#: libpq/be-secure-openssl.c:1009 +#: libpq/be-secure-openssl.c:1007 #, c-format msgid "could not accept SSL connection: %s" msgstr "SSL接続を受け付けられませんでした: %s" -#: libpq/be-secure-openssl.c:1013 +#: libpq/be-secure-openssl.c:1011 #, c-format msgid "This may indicate that the client does not support any SSL protocol version between %s and %s." msgstr "このことは、クライアントがSSLプロトコルのバージョン%sから%sのいずれもサポートしていないことを示唆しているかもしれません。" -#: libpq/be-secure-openssl.c:1031 libpq/be-secure-openssl.c:1246 libpq/be-secure-openssl.c:1316 +#: libpq/be-secure-openssl.c:1029 libpq/be-secure-openssl.c:1244 libpq/be-secure-openssl.c:1314 #, c-format msgid "unrecognized SSL error code: %d" msgstr "認識できないSSLエラーコード: %d" -#: libpq/be-secure-openssl.c:1059 +#: libpq/be-secure-openssl.c:1057 #, c-format msgid "received SSL connection request with unexpected ALPN protocol" msgstr "想定外のALPNプロトコルによるSSL接続要求を受信しました" -#: libpq/be-secure-openssl.c:1103 +#: libpq/be-secure-openssl.c:1101 #, c-format msgid "SSL certificate's common name contains embedded null" msgstr "SSL 証明書のコモンネームに null が含まれています" -#: libpq/be-secure-openssl.c:1149 +#: libpq/be-secure-openssl.c:1147 #, c-format msgid "SSL certificate's distinguished name contains embedded null" msgstr "SSL証明書の識別名の途中にnullが含まれています" -#: libpq/be-secure-openssl.c:1235 libpq/be-secure-openssl.c:1300 +#: libpq/be-secure-openssl.c:1233 libpq/be-secure-openssl.c:1298 #, c-format msgid "SSL error: %s" msgstr "SSLエラー: %s" -#: libpq/be-secure-openssl.c:1483 +#: libpq/be-secure-openssl.c:1481 #, c-format msgid "could not open DH parameters file \"%s\": %m" msgstr "DHパラメータファイル\"%s\"をオープンできませんでした: %m" -#: libpq/be-secure-openssl.c:1495 +#: libpq/be-secure-openssl.c:1493 #, c-format msgid "could not load DH parameters file: %s" msgstr "DHパラメータをロードできませんでした: %s" -#: libpq/be-secure-openssl.c:1505 +#: libpq/be-secure-openssl.c:1503 #, c-format msgid "invalid DH parameters: %s" msgstr "不正なDHパラメータです: %s" -#: libpq/be-secure-openssl.c:1514 +#: libpq/be-secure-openssl.c:1512 #, c-format msgid "invalid DH parameters: p is not prime" msgstr "不正なDHパラメータ: pは素数ではありません" -#: libpq/be-secure-openssl.c:1523 +#: libpq/be-secure-openssl.c:1521 #, c-format msgid "invalid DH parameters: neither suitable generator or safe prime" msgstr "不正なDHパラメータ: 適切な生成器も安全な素数もありません" -#: libpq/be-secure-openssl.c:1669 +#: libpq/be-secure-openssl.c:1667 #, c-format msgid "Client certificate verification failed at depth %d: %s." msgstr "クライアント証明書の検証に深さ%dで失敗しました: %s。" -#: libpq/be-secure-openssl.c:1706 +#: libpq/be-secure-openssl.c:1704 #, c-format msgid "Failed certificate data (unverified): subject \"%s\", serial number %s, issuer \"%s\"." msgstr "失敗した証明書の情報(未検証): サブジェクト \"%s\", シリアル番号 %s, 発行者 \"%s\"。" -#: libpq/be-secure-openssl.c:1707 +#: libpq/be-secure-openssl.c:1705 msgid "unknown" msgstr "不明" -#: libpq/be-secure-openssl.c:2032 +#: libpq/be-secure-openssl.c:2030 #, c-format msgid "no hostname provided in callback, and no fallback configured" msgstr "コールバックでホスト名が設定されず、フォールバックの設定もありません" -#: libpq/be-secure-openssl.c:2056 +#: libpq/be-secure-openssl.c:2054 #, c-format msgid "failed to switch to SSL configuration for host, terminating connection" msgstr "ホストごとのSSL設定への切り替えに失敗しました、切断します" -#: libpq/be-secure-openssl.c:2092 +#: libpq/be-secure-openssl.c:2090 #, c-format msgid "DH: could not load DH parameters" msgstr "DH: DHパラメータをロードできませんでした" -#: libpq/be-secure-openssl.c:2100 +#: libpq/be-secure-openssl.c:2098 #, c-format msgid "DH: could not set DH parameters: %s" msgstr "DH: DHパラメータを設定できませんでした: %s" -#: libpq/be-secure-openssl.c:2130 +#: libpq/be-secure-openssl.c:2127 #, c-format msgid "could not set group names specified in ssl_groups: %s" msgstr "ssl_groupsで指定されたグループ名の設定に失敗しました: %s" -#: libpq/be-secure-openssl.c:2132 +#: libpq/be-secure-openssl.c:2129 msgid "No valid groups found" msgstr "有効なグループが見つかりませんでした" -#: libpq/be-secure-openssl.c:2133 +#: libpq/be-secure-openssl.c:2130 #, c-format msgid "Ensure that each group name is spelled correctly and supported by the installed version of OpenSSL." msgstr "すべてのグループ名が正しく記述されおり、インストールされているバージョンのOpenSSLでサポートされていることを確認してください。" -#: libpq/be-secure-openssl.c:2179 +#: libpq/be-secure-openssl.c:2175 msgid "no SSL error reported" msgstr "SSLエラーはありませんでした" -#: libpq/be-secure-openssl.c:2197 +#: libpq/be-secure-openssl.c:2193 #, c-format msgid "SSL error code %lu" msgstr "SSLエラーコード: %lu" -#: libpq/be-secure-openssl.c:2354 +#: libpq/be-secure-openssl.c:2350 #, c-format msgid "could not create BIO" msgstr "BIOを作成できませんでした" -#: libpq/be-secure-openssl.c:2364 +#: libpq/be-secure-openssl.c:2360 #, c-format msgid "could not get NID for ASN1_OBJECT object" msgstr "ASN1_OBJECTオブジェクトのNIDを取得できませんでした" -#: libpq/be-secure-openssl.c:2372 +#: libpq/be-secure-openssl.c:2368 #, c-format msgid "could not convert NID %d to an ASN1_OBJECT structure" msgstr "NID %dをASN1_OBJECT構造体へ変換できませんでした" @@ -19742,11 +19899,6 @@ msgstr "暗号化されたパスワードは%dバイト以下でなければな msgid "setting an MD5-encrypted password" msgstr "MD5暗号化パスワードを設定しています" -#: libpq/crypt.c:247 libpq/crypt.c:310 -#, c-format -msgid "MD5 password support is deprecated and will be removed in a future release of PostgreSQL." -msgstr "MD5パスワードは非推奨であり、PostgreSQLの将来のリリースでは廃止される予定です。" - #: libpq/crypt.c:248 #, c-format msgid "Refer to the PostgreSQL documentation for details about migrating to another password type." @@ -19757,16 +19909,12 @@ msgstr "他のパスワードタイプへの移行の詳細についてはPostgr msgid "User \"%s\" has a password that cannot be used with MD5 authentication." msgstr "ユーザー\"%s\"のパスワードはMD5認証で使用不能です。" -#: libpq/crypt.c:309 -msgid "authenticated with an MD5-encrypted password" -msgstr "MD5暗号化パスワードで認証されました" - -#: libpq/crypt.c:318 libpq/crypt.c:360 libpq/crypt.c:381 +#: libpq/crypt.c:301 libpq/crypt.c:343 libpq/crypt.c:364 #, c-format msgid "Password does not match for user \"%s\"." msgstr "ユーザー\"%s\"のパスワードが合致しません。" -#: libpq/crypt.c:400 +#: libpq/crypt.c:383 #, c-format msgid "Password of user \"%s\" is in unrecognized format." msgstr "ユーザー\"%s\"のパスワードは識別不能な形式です。" @@ -20190,7 +20338,7 @@ msgstr "クライアント接続がありません" msgid "could not receive data from client: %m" msgstr "クライアントからデータを受信できませんでした: %m" -#: libpq/pqcomm.c:1151 tcop/postgres.c:4590 +#: libpq/pqcomm.c:1151 tcop/postgres.c:4685 #, c-format msgid "terminating connection because protocol synchronization was lost" msgstr "プロトコルの同期が失われたためコネクションを終了します" @@ -20549,7 +20697,7 @@ msgstr "ExtensibleNodeMethods \"%s\"は登録されていません" msgid "relation \"%s\" does not have a composite type" msgstr "リレーション\"%s\"は複合型を持っていません" -#: nodes/nodeFuncs.c:118 nodes/nodeFuncs.c:149 parser/parse_coerce.c:2603 parser/parse_coerce.c:2741 parser/parse_coerce.c:2788 parser/parse_expr.c:2152 parser/parse_func.c:724 parser/parse_oper.c:920 utils/adt/array_userfuncs.c:1959 utils/fmgr/funcapi.c:671 +#: nodes/nodeFuncs.c:118 nodes/nodeFuncs.c:149 parser/parse_coerce.c:2602 parser/parse_coerce.c:2740 parser/parse_coerce.c:2787 parser/parse_expr.c:2152 parser/parse_func.c:730 parser/parse_oper.c:920 utils/adt/array_userfuncs.c:1959 utils/fmgr/funcapi.c:671 #, c-format msgid "could not find array type for data type %s" msgstr "データ型%sの配列型がありませんでした" @@ -20580,43 +20728,48 @@ msgstr "リレーション\"%s\"に対してMERGEは実行できません" msgid "%s cannot be applied to the nullable side of an outer join" msgstr "外部結合のNULL可な側では%sを適用できません" +#: optimizer/plan/planner.c:1093 +#, c-format +msgid "FOR PORTION OF bounds cannot contain volatile functions" +msgstr "FOR PORTION OF の範囲境界にvolatile関数を含めることはできません" + #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1853 parser/analyze.c:2192 parser/analyze.c:2451 parser/analyze.c:3754 +#: optimizer/plan/planner.c:1865 parser/analyze.c:2188 parser/analyze.c:2447 parser/analyze.c:3751 #, c-format msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" msgstr "UNION/INTERSECT/EXCEPTでは%sを使用できません" -#: optimizer/plan/planner.c:2599 optimizer/plan/planner.c:4478 +#: optimizer/plan/planner.c:2611 optimizer/plan/planner.c:4490 #, c-format msgid "could not implement GROUP BY" msgstr "GROUP BY を実行できませんでした" -#: optimizer/plan/planner.c:2600 optimizer/plan/planner.c:4479 optimizer/plan/planner.c:5160 optimizer/prep/prepunion.c:1127 +#: optimizer/plan/planner.c:2612 optimizer/plan/planner.c:4491 optimizer/plan/planner.c:5172 optimizer/prep/prepunion.c:1119 #, c-format msgid "Some of the datatypes only support hashing, while others only support sorting." msgstr "一部のデータ型がハッシュのみをサポートする一方で、別の型はソートのみをサポートしています。" -#: optimizer/plan/planner.c:5159 +#: optimizer/plan/planner.c:5171 #, c-format msgid "could not implement DISTINCT" msgstr "DISTINCTを実行できませんでした" -#: optimizer/plan/planner.c:6624 +#: optimizer/plan/planner.c:6636 #, c-format msgid "could not implement window PARTITION BY" msgstr "ウィンドウの PARTITION BY を実行できませんでした" -#: optimizer/plan/planner.c:6625 +#: optimizer/plan/planner.c:6637 #, c-format msgid "Window partitioning columns must be of sortable datatypes." msgstr "ウィンドウ分割に使用する列は、ソート可能なデータ型でなければなりません。" -#: optimizer/plan/planner.c:6629 +#: optimizer/plan/planner.c:6641 #, c-format msgid "could not implement window ORDER BY" msgstr "ウィンドウの ORDER BY を実行できませんでした" -#: optimizer/plan/planner.c:6630 +#: optimizer/plan/planner.c:6642 #, c-format msgid "Window ordering columns must be of sortable datatypes." msgstr "ウィンドウの順序付けをする列は、ソート可能なデータ型でなければなりません。" @@ -20632,7 +20785,7 @@ msgid "All column datatypes must be hashable." msgstr "すべての列のデータ型はハッシュ可能でなければなりません。" #. translator: %s is INTERSECT or EXCEPT -#: optimizer/prep/prepunion.c:1125 +#: optimizer/prep/prepunion.c:1117 #, c-format msgid "could not implement %s" msgstr "%sを実行できませんでした" @@ -20647,7 +20800,7 @@ msgstr "リレーション\"%2$s\"の属性\"%1$s\"は親での型と一致し msgid "attribute \"%s\" of relation \"%s\" does not match parent's collation" msgstr "リレーション\"%2$s\"の属性\"%1$s\"は親での照合順序と一致していません" -#: optimizer/util/clauses.c:5714 +#: optimizer/util/clauses.c:5717 #, c-format msgid "SQL function \"%s\" during inlining" msgstr "SQL関数\"%s\"のインライン化処理中" @@ -20677,292 +20830,287 @@ msgstr "ON CONFLICT DO %s での排除制約の使用はサポートされてい msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" msgstr "ON CONFLICT 指定に合致するユニーク制約または排除制約がありません" -#: parser/analyze.c:604 parser/analyze.c:2885 +#: parser/analyze.c:605 parser/analyze.c:2881 #, c-format msgid "WHERE CURRENT OF on a view is not implemented" msgstr "ビューに対するWHERE CURRENT OFは実装されていません" -#: parser/analyze.c:910 parser/analyze.c:1971 +#: parser/analyze.c:912 parser/analyze.c:1967 #, c-format msgid "VALUES lists must all be the same length" msgstr "VALUESリストはすべて同じ長さでなければなりません" -#: parser/analyze.c:1065 rewrite/rewriteHandler.c:706 +#: parser/analyze.c:1067 rewrite/rewriteHandler.c:706 #, c-format msgid "ON CONFLICT DO SELECT requires a RETURNING clause" msgstr "ON CONFLICT DO SELECT にはRETURNING句が必須です" -#: parser/analyze.c:1121 +#: parser/analyze.c:1123 #, c-format msgid "INSERT has more expressions than target columns" msgstr "INSERTに対象列よりも多くの式があります" -#: parser/analyze.c:1139 +#: parser/analyze.c:1141 #, c-format msgid "INSERT has more target columns than expressions" msgstr "INSERTに式よりも多くの対象列があります" -#: parser/analyze.c:1143 +#: parser/analyze.c:1145 #, c-format msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" msgstr "挿入ソースがINSERTが期待するのと同じ列数を含む行表現になっています。うっかり余計なカッコをつけたりしませんでしたか?" -#: parser/analyze.c:1342 +#: parser/analyze.c:1345 #, c-format -msgid "foreign tables don't support FOR PORTION OF" -msgstr "外部テーブルでは FOR PORTION OF はサポートされません" +msgid "WHERE CURRENT OF with FOR PORTION OF is not implemented" +msgstr "FOR PORTION OFを伴うWHERE CURRENT OFは実装されていません" -#: parser/analyze.c:1398 +#: parser/analyze.c:1401 #, c-format msgid "could not coerce FOR PORTION OF target from %s to %s" msgstr "FOR PORTION OF の対象を %s から %s に型強制できませんでした" -#: parser/analyze.c:1419 +#: parser/analyze.c:1422 #, c-format msgid "column \"%s\" of relation \"%s\" is not a range or multirange type" msgstr "リレーション\"%2$s\"の列\"%1$s\"は範囲型でも複範囲型でもありません" -#: parser/analyze.c:1440 +#: parser/analyze.c:1443 #, c-format msgid "column \"%s\" of relation \"%s\" is not a range type" msgstr "リレーション\"%2$s\"の列\"%1$s\"は範囲型ではありません" -#: parser/analyze.c:1472 parser/analyze.c:1480 +#: parser/analyze.c:1475 parser/analyze.c:1483 #, c-format msgid "could not coerce FOR PORTION OF %s bound from %s to %s" msgstr "FOR PORTION OF の %s 指定の値を %s から %s に型強制できませんでした" -#: parser/analyze.c:1494 -#, c-format -msgid "FOR PORTION OF bounds cannot contain volatile functions" -msgstr "FOR PORTION OF の範囲境界にvolatile関数を含めることはできません" - #: parser/analyze.c:1507 #, c-format msgid "You must define a default operator class for the data type." msgstr "このデータ型に対してデフォルト演算子クラスを定義する必要があります。" -#: parser/analyze.c:1573 +#: parser/analyze.c:1574 #, c-format msgid "could not identify an intersect function for type %s" msgstr "型 %s の積集合関数を特定できません" -#: parser/analyze.c:1768 parser/analyze.c:2165 +#: parser/analyze.c:1764 parser/analyze.c:2161 #, c-format msgid "SELECT ... INTO is not allowed here" msgstr "ここではSELECT ... INTOは許可されません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2094 parser/analyze.c:3986 +#: parser/analyze.c:2090 parser/analyze.c:3983 #, c-format msgid "%s cannot be applied to VALUES" msgstr "%sをVALUESに使用できません" -#: parser/analyze.c:2332 +#: parser/analyze.c:2328 #, c-format msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" msgstr "不正なUNION/INTERSECT/EXCEPT ORDER BY句です" -#: parser/analyze.c:2333 +#: parser/analyze.c:2329 #, c-format msgid "Only result column names can be used, not expressions or functions." msgstr "式や関数ではなく、結果列の名前のみが使用できます。" -#: parser/analyze.c:2334 +#: parser/analyze.c:2330 #, c-format msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." msgstr "式/関数をすべてのSELECTにつけてください。またはこのUNIONをFROM句に移動してください。" -#: parser/analyze.c:2441 +#: parser/analyze.c:2437 #, c-format msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" msgstr "INTOはUNION/INTERSECT/EXCEPTの最初のSELECTでのみ使用できます" -#: parser/analyze.c:2511 +#: parser/analyze.c:2507 #, c-format msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" msgstr "UNION/INTERSECT/EXCEPTの要素となる文では同一問い合わせレベルの他のリレーションを参照できません" -#: parser/analyze.c:2623 +#: parser/analyze.c:2619 #, c-format msgid "each %s query must have the same number of columns" msgstr "すべての%s問い合わせは同じ列数を返す必要があります" -#: parser/analyze.c:2989 +#: parser/analyze.c:2986 #, c-format msgid "SET target columns cannot be qualified with the relation name." msgstr "SETの対象列はリレーション名で修飾することはできません。" -#: parser/analyze.c:3001 +#: parser/analyze.c:2998 #, c-format msgid "cannot update column \"%s\" because it is used in FOR PORTION OF" msgstr "列\"%s\"は FOR PORTION OF で使用されているため、更新できません" #. translator: %s is OLD or NEW -#: parser/analyze.c:3090 parser/analyze.c:3100 +#: parser/analyze.c:3087 parser/analyze.c:3097 #, c-format msgid "%s cannot be specified multiple times" msgstr "%s は複数回指定できません" -#: parser/analyze.c:3112 parser/parse_relation.c:469 +#: parser/analyze.c:3109 parser/parse_relation.c:469 #, c-format msgid "table name \"%s\" specified more than once" msgstr "テーブル名\"%s\"が複数指定されました" -#: parser/analyze.c:3160 +#: parser/analyze.c:3157 #, c-format msgid "RETURNING must have at least one column" msgstr "RETURNINGには少なくとも1つの列が必要です" -#: parser/analyze.c:3284 +#: parser/analyze.c:3281 #, c-format msgid "assignment source returned %d column" msgid_plural "assignment source returned %d columns" msgstr[0] "代入元が%d個の列を返しました" -#: parser/analyze.c:3345 +#: parser/analyze.c:3342 #, c-format msgid "variable \"%s\" is of type %s but expression is of type %s" msgstr "変数\"%s\"は型%sですが、式は型%sでした" #. translator: %s is a SQL keyword -#: parser/analyze.c:3381 parser/analyze.c:3389 +#: parser/analyze.c:3378 parser/analyze.c:3386 #, c-format msgid "cannot specify both %s and %s" msgstr "%sと%sの両方を同時には指定できません" -#: parser/analyze.c:3409 +#: parser/analyze.c:3406 #, c-format msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" msgstr "DECLARE CURSOR では WITH にデータを変更する文を含んではなりません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3417 +#: parser/analyze.c:3414 #, c-format msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" msgstr "DECLARE CURSOR WITH HOLD ... %sはサポートされていません" -#: parser/analyze.c:3420 +#: parser/analyze.c:3417 #, c-format msgid "Holdable cursors must be READ ONLY." msgstr "保持可能カーソルは読み取り専用である必要があります。" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3428 +#: parser/analyze.c:3425 #, c-format msgid "DECLARE SCROLL CURSOR ... %s is not supported" msgstr "DECLARE SCROLL CURSOR ... %sはサポートされていません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3439 +#: parser/analyze.c:3436 #, c-format msgid "DECLARE INSENSITIVE CURSOR ... %s is not valid" msgstr "DECLARE INSENSITIVE CURSOR ... %sはが不正です" -#: parser/analyze.c:3442 +#: parser/analyze.c:3439 #, c-format msgid "Insensitive cursors must be READ ONLY." msgstr "INSENSITIVEカーソルは読み取り専用である必要があります。" -#: parser/analyze.c:3538 +#: parser/analyze.c:3535 #, c-format msgid "materialized views must not use data-modifying statements in WITH" msgstr "実体化ビューではWITH句にデータを変更する文を含んではなりません" -#: parser/analyze.c:3548 +#: parser/analyze.c:3545 #, c-format msgid "materialized views must not use temporary objects" msgstr "実体化ビューでは一時オブジェクトを使用してはいけません" -#: parser/analyze.c:3549 +#: parser/analyze.c:3546 #, c-format msgid "This view depends on temporary %s." msgstr "このビューは一時%sに依存しています。" -#: parser/analyze.c:3560 +#: parser/analyze.c:3557 #, c-format msgid "materialized views may not be defined using bound parameters" msgstr "実体化ビューは境界パラメータを用いて定義してはなりません" -#: parser/analyze.c:3572 +#: parser/analyze.c:3569 #, c-format msgid "materialized views cannot be unlogged" msgstr "実体化ビューをログ非取得にはできません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3761 +#: parser/analyze.c:3758 #, c-format msgid "%s is not allowed with DISTINCT clause" msgstr "DISTINCT句では%sを使用できません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3768 +#: parser/analyze.c:3765 #, c-format msgid "%s is not allowed with GROUP BY clause" msgstr "GROUP BY句で%sを使用できません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3775 +#: parser/analyze.c:3772 #, c-format msgid "%s is not allowed with HAVING clause" msgstr "HAVING 句では%sを使用できません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3782 +#: parser/analyze.c:3779 #, c-format msgid "%s is not allowed with aggregate functions" msgstr "集約関数では%sは使用できません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3789 +#: parser/analyze.c:3786 #, c-format msgid "%s is not allowed with window functions" msgstr "ウィンドウ関数では%sは使用できません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3796 +#: parser/analyze.c:3793 #, c-format msgid "%s is not allowed with set-returning functions in the target list" msgstr "ターゲットリストの中では%sを集合返却関数と一緒に使うことはできません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3895 +#: parser/analyze.c:3892 #, c-format msgid "%s must specify unqualified relation names" msgstr "%sでは非修飾のリレーション名を指定してください" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3959 +#: parser/analyze.c:3956 #, c-format msgid "%s cannot be applied to a join" msgstr "%sを結合に使用できません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3968 +#: parser/analyze.c:3965 #, c-format msgid "%s cannot be applied to a function" msgstr "%sを関数に使用できません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3977 +#: parser/analyze.c:3974 #, c-format msgid "%s cannot be applied to a table function" msgstr "%sはテーブル関数には適用できません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3995 +#: parser/analyze.c:3992 #, c-format msgid "%s cannot be applied to a WITH query" msgstr "%sはWITH問い合わせには適用できません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:4004 +#: parser/analyze.c:4001 #, c-format msgid "%s cannot be applied to a named tuplestore" msgstr "%sは名前付きタプルストアには適用できません" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:4024 +#: parser/analyze.c:4021 #, c-format msgid "relation \"%s\" in %s clause not found in FROM clause" msgstr "%2$s句のリレーション\"%1$s\"はFROM句にありません" @@ -21167,7 +21315,7 @@ msgid "grouping operations are not allowed in property definition expressions" msgstr "プロパティ定義内の式ではグルーピング演算を使用できません" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:622 parser/parse_clause.c:2106 +#: parser/parse_agg.c:622 parser/parse_clause.c:2110 #, c-format msgid "aggregate functions are not allowed in %s" msgstr "%sでは集約関数を使用できません" @@ -21198,7 +21346,7 @@ msgstr "アウタレベルの集約は直接引数に低位の変数を含むこ msgid "aggregate function calls cannot contain set-returning function calls" msgstr "集合返却関数の呼び出しに集約関数の呼び出しを含むことはできません" -#: parser/parse_agg.c:830 parser/parse_expr.c:1788 parser/parse_expr.c:2287 parser/parse_func.c:900 +#: parser/parse_agg.c:830 parser/parse_expr.c:1788 parser/parse_expr.c:2287 parser/parse_func.c:906 #, c-format msgid "You might be able to move the set-returning function into a LATERAL FROM item." msgstr "この集合返却関数をLATERAL FROM項目に移動できるかもしれません。" @@ -21289,12 +21437,12 @@ msgid "window functions are not allowed in FOR PORTION OF expressions" msgstr "FOR PORTION OF 内の式ではウィンドウ関数を使用できません" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:1066 parser/parse_clause.c:2115 +#: parser/parse_agg.c:1066 parser/parse_clause.c:2119 #, c-format msgid "window functions are not allowed in %s" msgstr "%sの中ではウィンドウ関数を使用できません" -#: parser/parse_agg.c:1100 parser/parse_clause.c:3010 +#: parser/parse_agg.c:1100 parser/parse_clause.c:3014 #, c-format msgid "window \"%s\" does not exist" msgstr "ウィンドウ\"%s\"は存在しません" @@ -21334,7 +21482,7 @@ msgstr "GROUPINGの引数は関連するクエリレベルのグルーピング msgid "relation \"%s\" cannot be the target of a modifying statement" msgstr "リレーション\"%s\"は更新文の対象にはなれません" -#: parser/parse_clause.c:573 parser/parse_clause.c:601 parser/parse_func.c:2681 +#: parser/parse_clause.c:573 parser/parse_clause.c:601 parser/parse_func.c:2685 #, c-format msgid "set-returning functions must appear at top level of FROM" msgstr "集合返却関数はFROMの最上位レベルにある必要があります" @@ -21399,358 +21547,358 @@ msgstr "デフォルト名前空間は一つのみ指定可能です" msgid "complex graph table column must specify an explicit column name" msgstr "単純でないグラフテーブル列には明示的な列名の指定が必要です" -#: parser/parse_clause.c:1027 +#: parser/parse_clause.c:1031 #, c-format msgid "subqueries within GRAPH_TABLE reference are not supported" msgstr "GRAPH_TABLE参照内の副問合せはサポートされていません" -#: parser/parse_clause.c:1065 +#: parser/parse_clause.c:1069 #, c-format msgid "tablesample method %s does not exist" msgstr "テーブルサンプルメソッド%sは存在しません" -#: parser/parse_clause.c:1087 +#: parser/parse_clause.c:1091 #, c-format msgid "tablesample method %s requires %d argument, not %d" msgid_plural "tablesample method %s requires %d arguments, not %d" msgstr[0] "テーブルサンプルメソッド%sは%d個の引数を必要とします、%d個ではありません" -#: parser/parse_clause.c:1121 +#: parser/parse_clause.c:1125 #, c-format msgid "tablesample method %s does not support REPEATABLE" msgstr "テーブルサンプルメソッド%sはREPEATABLEをサポートしていません" -#: parser/parse_clause.c:1286 +#: parser/parse_clause.c:1290 #, c-format msgid "TABLESAMPLE clause can only be applied to tables and materialized views" msgstr "TABLESAMPLE句はテーブルおよび実体化ビューのみに適用可能です" -#: parser/parse_clause.c:1473 +#: parser/parse_clause.c:1477 #, c-format msgid "column name \"%s\" appears more than once in USING clause" msgstr "USING句に列名\"%s\"が複数あります" -#: parser/parse_clause.c:1488 +#: parser/parse_clause.c:1492 #, c-format msgid "common column name \"%s\" appears more than once in left table" msgstr "左テーブルに列名\"%s\"が複数あります" -#: parser/parse_clause.c:1497 +#: parser/parse_clause.c:1501 #, c-format msgid "column \"%s\" specified in USING clause does not exist in left table" msgstr "USING句で指定した列\"%sが左テーブルに存在しません" -#: parser/parse_clause.c:1512 +#: parser/parse_clause.c:1516 #, c-format msgid "common column name \"%s\" appears more than once in right table" msgstr "右テーブルに列名\"%s\"が複数あります" -#: parser/parse_clause.c:1521 +#: parser/parse_clause.c:1525 #, c-format msgid "column \"%s\" specified in USING clause does not exist in right table" msgstr "USING句で指定した列\"%sが右テーブルに存在しません" -#: parser/parse_clause.c:2051 +#: parser/parse_clause.c:2055 #, c-format msgid "row count cannot be null in FETCH FIRST ... WITH TIES clause" msgstr "FETCH FIRST ... WITH TIES句で行数にNULLは指定できません" #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_clause.c:2076 +#: parser/parse_clause.c:2080 #, c-format msgid "argument of %s must not contain variables" msgstr "%sの引数には変数を使用できません" #. translator: first %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:2241 +#: parser/parse_clause.c:2245 #, c-format msgid "%s \"%s\" is ambiguous" msgstr "%s \"%s\"は曖昧です" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:2269 +#: parser/parse_clause.c:2273 #, c-format msgid "non-integer constant in %s" msgstr "%sに整数以外の定数があります" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:2291 +#: parser/parse_clause.c:2295 #, c-format msgid "%s position %d is not in select list" msgstr "%sの位置%dはSELECTリストにありません" -#: parser/parse_clause.c:2730 +#: parser/parse_clause.c:2734 #, c-format msgid "CUBE is limited to 12 elements" msgstr "CUBEは12要素に制限されています" -#: parser/parse_clause.c:2998 +#: parser/parse_clause.c:3002 #, c-format msgid "window \"%s\" is already defined" msgstr "ウィンドウ\"%s\"はすでに定義済みです" -#: parser/parse_clause.c:3060 +#: parser/parse_clause.c:3064 #, c-format msgid "cannot override PARTITION BY clause of window \"%s\"" msgstr "ウィンドウ\"%s\"のPARTITION BY句をオーバーライドできません" -#: parser/parse_clause.c:3072 +#: parser/parse_clause.c:3076 #, c-format msgid "cannot override ORDER BY clause of window \"%s\"" msgstr "ウィンドウ\"%s\"のORDER BY句をオーバーライドできません" -#: parser/parse_clause.c:3102 parser/parse_clause.c:3108 +#: parser/parse_clause.c:3106 parser/parse_clause.c:3112 #, c-format msgid "cannot copy window \"%s\" because it has a frame clause" msgstr "フレーム句をもっているため、ウィンドウ\"%s\"はコピーできません" -#: parser/parse_clause.c:3110 +#: parser/parse_clause.c:3114 #, c-format msgid "Omit the parentheses in this OVER clause." msgstr "このOVER句中の括弧を無視しました" -#: parser/parse_clause.c:3130 +#: parser/parse_clause.c:3134 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" msgstr "offset PRECEDING/FOLLOWING を伴った RANGE はただ一つの ORDER BY 列を必要とします" -#: parser/parse_clause.c:3153 +#: parser/parse_clause.c:3157 #, c-format msgid "GROUPS mode requires an ORDER BY clause" msgstr "GROUPSフレーム指定はORDER BY句を必要とします" -#: parser/parse_clause.c:3223 +#: parser/parse_clause.c:3227 #, c-format msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" msgstr "DISTINCT や ORDER BY 表現を伴なう集約は引数リストの中に現れなければなりません" -#: parser/parse_clause.c:3224 +#: parser/parse_clause.c:3228 #, c-format msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" msgstr "SELECT DISTINCTではORDER BYの式はSELECTリスト内になければなりません" -#: parser/parse_clause.c:3256 +#: parser/parse_clause.c:3260 #, c-format msgid "an aggregate with DISTINCT must have at least one argument" msgstr "DISTINCTを伴った集約は、最低でも一つの引数を取る必要があります" -#: parser/parse_clause.c:3257 +#: parser/parse_clause.c:3261 #, c-format msgid "SELECT DISTINCT must have at least one column" msgstr "SELECT DISTINCTには少なくとも1つの列が必要です" -#: parser/parse_clause.c:3323 parser/parse_clause.c:3355 +#: parser/parse_clause.c:3327 parser/parse_clause.c:3359 #, c-format msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" msgstr "SELECT DISTINCT ONの式はORDER BY式の先頭に一致しなければなりません" -#: parser/parse_clause.c:3433 parser/parse_clause.c:3439 +#: parser/parse_clause.c:3437 parser/parse_clause.c:3443 #, c-format msgid "%s is not allowed in ON CONFLICT clause" msgstr "%sはON CONFLICT句では指定できません" -#: parser/parse_clause.c:3445 +#: parser/parse_clause.c:3449 #, c-format msgid "operator class options are not allowed in ON CONFLICT clause" msgstr "演算子クラスオプションはON CONFLICT句では指定できません" -#: parser/parse_clause.c:3524 +#: parser/parse_clause.c:3528 #, c-format msgid "ON CONFLICT DO %s requires inference specification or constraint name" msgstr "ON CONFLICT DO %s は推定指定または制約名を必要とします" -#: parser/parse_clause.c:3526 +#: parser/parse_clause.c:3530 #, c-format msgid "For example, ON CONFLICT (column_name)." msgstr "例えば、 ON CONFLICT (column_name)。" -#: parser/parse_clause.c:3537 +#: parser/parse_clause.c:3541 #, c-format msgid "ON CONFLICT is not supported with system catalog tables" msgstr "システムカタログテーブルではON CONFLICTはサポートしていません" -#: parser/parse_clause.c:3545 +#: parser/parse_clause.c:3549 #, c-format msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" msgstr "ON CONFLICT はカタログテーブルとして使用中のテーブル\"%s\"ではサポートされません" -#: parser/parse_clause.c:3676 +#: parser/parse_clause.c:3680 #, c-format msgid "operator %s is not a valid ordering operator" msgstr "演算子\"%s\"は有効な順序付け演算子名ではありません" -#: parser/parse_clause.c:3678 +#: parser/parse_clause.c:3682 #, c-format msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." msgstr "順序付け演算子はB-Tree演算子族の\"<\"または\">\"要素でなければなりません。" -#: parser/parse_clause.c:3992 +#: parser/parse_clause.c:3996 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" msgstr "offset PRECEDING/FOLLOWING を伴った RANGE は列型 %s に対してはサポートされません" -#: parser/parse_clause.c:3998 +#: parser/parse_clause.c:4002 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" msgstr "offset PRECEDING/FOLLOWING を伴った RANGE は列型 %s とオフセット型 %s に対してはサポートされません" -#: parser/parse_clause.c:4001 +#: parser/parse_clause.c:4005 #, c-format msgid "Cast the offset value to an appropriate type." msgstr "オフセット値を適切な型にキャストしてください。" -#: parser/parse_clause.c:4006 +#: parser/parse_clause.c:4010 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" msgstr "offset PRECEDING/FOLLOWING を伴った RANGE は列型 %s とオフセット型 %s に対して複数の解釈が可能になっています" -#: parser/parse_clause.c:4009 +#: parser/parse_clause.c:4013 #, c-format msgid "Cast the offset value to the exact intended type." msgstr "オフセット値を意図した型そのものにキャストしてください。" -#: parser/parse_coerce.c:1049 parser/parse_coerce.c:1087 parser/parse_coerce.c:1105 parser/parse_coerce.c:1120 parser/parse_expr.c:2186 parser/parse_expr.c:2806 parser/parse_expr.c:3461 parser/parse_expr.c:3690 parser/parse_target.c:1006 +#: parser/parse_coerce.c:1048 parser/parse_coerce.c:1086 parser/parse_coerce.c:1104 parser/parse_coerce.c:1119 parser/parse_expr.c:2186 parser/parse_expr.c:2806 parser/parse_expr.c:3461 parser/parse_expr.c:3690 parser/parse_expr.c:4211 parser/parse_target.c:1006 #, c-format msgid "cannot cast type %s to %s" msgstr "型%sから%sへの型変換ができません" -#: parser/parse_coerce.c:1090 +#: parser/parse_coerce.c:1089 #, c-format msgid "Input has too few columns." msgstr "入力列が少なすぎます。" -#: parser/parse_coerce.c:1108 +#: parser/parse_coerce.c:1107 #, c-format msgid "Cannot cast type %s to %s in column %d." msgstr "列%3$dで型%1$sから%2$sへの型変換ができません。" -#: parser/parse_coerce.c:1123 +#: parser/parse_coerce.c:1122 #, c-format msgid "Input has too many columns." msgstr "入力列が多すぎます。" #. translator: first %s is name of a SQL construct, eg WHERE #. translator: first %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1178 parser/parse_coerce.c:1226 +#: parser/parse_coerce.c:1177 parser/parse_coerce.c:1225 #, c-format msgid "argument of %s must be type %s, not type %s" msgstr "%1$sの引数は型%3$sではなく%2$s型でなければなりません" #. translator: %s is name of a SQL construct, eg WHERE #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1189 parser/parse_coerce.c:1238 +#: parser/parse_coerce.c:1188 parser/parse_coerce.c:1237 #, c-format msgid "argument of %s must not return a set" msgstr "%sの引数は集合を返してはなりません" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1419 +#: parser/parse_coerce.c:1418 #, c-format msgid "%s types %s and %s cannot be matched" msgstr "%sの型%sと%sを一致させることができません" -#: parser/parse_coerce.c:1535 +#: parser/parse_coerce.c:1534 #, c-format msgid "argument types %s and %s cannot be matched" msgstr "引数の型%sと%sは合致させられません" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1587 +#: parser/parse_coerce.c:1586 #, c-format msgid "%s could not convert type %s to %s" msgstr "%sで型%sから%sへ変換できませんでした" -#: parser/parse_coerce.c:2190 parser/parse_coerce.c:2210 parser/parse_coerce.c:2230 parser/parse_coerce.c:2251 parser/parse_coerce.c:2306 parser/parse_coerce.c:2340 +#: parser/parse_coerce.c:2189 parser/parse_coerce.c:2209 parser/parse_coerce.c:2229 parser/parse_coerce.c:2250 parser/parse_coerce.c:2305 parser/parse_coerce.c:2339 #, c-format msgid "arguments declared \"%s\" are not all alike" msgstr "\"%s\"と宣言された引数が全て同じでありません" -#: parser/parse_coerce.c:2285 parser/parse_coerce.c:2398 utils/fmgr/funcapi.c:602 +#: parser/parse_coerce.c:2284 parser/parse_coerce.c:2397 utils/fmgr/funcapi.c:602 #, c-format msgid "argument declared %s is not an array but type %s" msgstr "%sと宣言された引数が配列ではなく%s型です" -#: parser/parse_coerce.c:2318 parser/parse_coerce.c:2468 utils/fmgr/funcapi.c:616 +#: parser/parse_coerce.c:2317 parser/parse_coerce.c:2467 utils/fmgr/funcapi.c:616 #, c-format msgid "argument declared %s is not a range type but type %s" msgstr "%sと宣言された引数が範囲型ではなく型%sです" -#: parser/parse_coerce.c:2352 parser/parse_coerce.c:2432 parser/parse_coerce.c:2565 utils/fmgr/funcapi.c:634 utils/fmgr/funcapi.c:699 +#: parser/parse_coerce.c:2351 parser/parse_coerce.c:2431 parser/parse_coerce.c:2564 utils/fmgr/funcapi.c:634 utils/fmgr/funcapi.c:699 #, c-format msgid "argument declared %s is not a multirange type but type %s" msgstr "%sと宣言された引数が複範囲型ではなく型%sです" -#: parser/parse_coerce.c:2389 +#: parser/parse_coerce.c:2388 #, c-format msgid "cannot determine element type of \"anyarray\" argument" msgstr "\"anyarray\"型の引数の要素型を決定できません" -#: parser/parse_coerce.c:2415 parser/parse_coerce.c:2446 parser/parse_coerce.c:2485 parser/parse_coerce.c:2551 +#: parser/parse_coerce.c:2414 parser/parse_coerce.c:2445 parser/parse_coerce.c:2484 parser/parse_coerce.c:2550 #, c-format msgid "argument declared %s is not consistent with argument declared %s" msgstr "%sと宣言された引数と%sと宣言された引数とで整合性がありません" -#: parser/parse_coerce.c:2510 +#: parser/parse_coerce.c:2509 #, c-format msgid "could not determine polymorphic type because input has type %s" msgstr "入力型が%sであったため多様型が特定できませんでした" -#: parser/parse_coerce.c:2524 +#: parser/parse_coerce.c:2523 #, c-format msgid "type matched to anynonarray is an array type: %s" msgstr "anynonarrayと照合されたは配列型です: %s" -#: parser/parse_coerce.c:2534 +#: parser/parse_coerce.c:2533 #, c-format msgid "type matched to anyenum is not an enum type: %s" msgstr "anyenumと照合された型は列挙型ではありません: %s" -#: parser/parse_coerce.c:2595 +#: parser/parse_coerce.c:2594 #, c-format msgid "arguments of anycompatible family cannot be cast to a common type" msgstr "anycompatible系の引数を共通の型にキャストできません" -#: parser/parse_coerce.c:2613 parser/parse_coerce.c:2634 parser/parse_coerce.c:2684 parser/parse_coerce.c:2689 parser/parse_coerce.c:2753 parser/parse_coerce.c:2765 +#: parser/parse_coerce.c:2612 parser/parse_coerce.c:2633 parser/parse_coerce.c:2683 parser/parse_coerce.c:2688 parser/parse_coerce.c:2752 parser/parse_coerce.c:2764 #, c-format msgid "could not determine polymorphic type %s because input has type %s" msgstr "入力型が%2$sであるため多様型%1$sが特定できませんでした" -#: parser/parse_coerce.c:2623 +#: parser/parse_coerce.c:2622 #, c-format msgid "anycompatiblerange type %s does not match anycompatible type %s" msgstr "anycompatiblerange型%sはanycompatiblerange型%sと合致しません" -#: parser/parse_coerce.c:2644 +#: parser/parse_coerce.c:2643 #, c-format msgid "anycompatiblemultirange type %s does not match anycompatible type %s" msgstr "anycompatiblemultirange型%sはanycompatible型%sと合致しません" -#: parser/parse_coerce.c:2658 +#: parser/parse_coerce.c:2657 #, c-format msgid "type matched to anycompatiblenonarray is an array type: %s" msgstr "anycompatiblenonarrayに対応する型が配列型です: %s" -#: parser/parse_coerce.c:2893 +#: parser/parse_coerce.c:2892 #, c-format msgid "A result of type %s requires at least one input of type anyrange or anymultirange." msgstr "%s型の返却値にはanyrangeまたはanymultirange型の入力が最低でも一つ必要です。" -#: parser/parse_coerce.c:2910 +#: parser/parse_coerce.c:2909 #, c-format msgid "A result of type %s requires at least one input of type anycompatiblerange or anycompatiblemultirange." msgstr "%s型の返却値には少なくとも一つのanycompatiblerangeまたはanycompatiblemultirange型の入力が必要です。" -#: parser/parse_coerce.c:2922 +#: parser/parse_coerce.c:2921 #, c-format msgid "A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange." msgstr "%s型の返却値には少なくとも一つのanyelement、anyarray、anynonarray、anyenum、anyrange またはanymultirange型の入力が必要です。" -#: parser/parse_coerce.c:2934 +#: parser/parse_coerce.c:2933 #, c-format msgid "A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, anycompatiblerange, or anycompatiblemultirange." msgstr "%s型の返却値には少なくとも一つのanycompatible、anycompatiblearray、anycompatiblenonarray、anycompatiblerangeまたはanycompatiblemultirange型の入力が必要です。" -#: parser/parse_coerce.c:2964 +#: parser/parse_coerce.c:2963 msgid "A result of type internal requires at least one input of type internal." msgstr "internal型の返却値には少なくとも1つのinternal型の入力が必要です。" @@ -21944,7 +22092,7 @@ msgstr "問い合わせ\"%s\"への再帰参照が2回以上現れてはなり msgid "DEFAULT is not allowed in this context" msgstr "この文脈ではDEFAULTは使えません" -#: parser/parse_expr.c:407 parser/parse_relation.c:3883 parser/parse_relation.c:3893 parser/parse_relation.c:3911 parser/parse_relation.c:3918 parser/parse_relation.c:3932 +#: parser/parse_expr.c:407 parser/parse_relation.c:3915 parser/parse_relation.c:3925 parser/parse_relation.c:3943 parser/parse_relation.c:3950 parser/parse_relation.c:3964 #, c-format msgid "column %s.%s does not exist" msgstr "列%s.%sは存在しません" @@ -21981,7 +22129,7 @@ msgstr "列参照はパーティション境界式では使用できません" msgid "cannot use column reference in FOR PORTION OF expression" msgstr "FOR PORTION OF 内の式では列参照を使用できません" -#: parser/parse_expr.c:861 parser/parse_relation.c:844 parser/parse_relation.c:926 parser/parse_target.c:1246 +#: parser/parse_expr.c:861 parser/parse_relation.c:876 parser/parse_relation.c:958 parser/parse_target.c:1246 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "列参照\"%s\"は曖昧です" @@ -22019,7 +22167,7 @@ msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() ex msgstr "複数列のUPDATE項目のソースは副問合せまたはROW()式でなければなりません" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_expr.c:1786 parser/parse_expr.c:2285 parser/parse_func.c:2813 +#: parser/parse_expr.c:1786 parser/parse_expr.c:2285 parser/parse_func.c:2814 #, c-format msgid "set-returning functions are not allowed in %s" msgstr "集合返却関数は%sでは使用できません" @@ -22219,60 +22367,60 @@ msgstr "SQL/JSON関数ではSETOF型の返却はサポートされていませ msgid "returning pseudo-types is not supported in SQL/JSON functions" msgstr "SQL/JSON関数では疑似型の返却はサポートされていません" -#: parser/parse_expr.c:3990 parser/parse_func.c:881 +#: parser/parse_expr.c:3990 parser/parse_func.c:887 #, c-format msgid "aggregate ORDER BY is not implemented for window functions" msgstr "ウィンドウ関数に対する集約の ORDER BY は実装されていません" -#: parser/parse_expr.c:4213 +#: parser/parse_expr.c:4223 #, c-format msgid "cannot use JSON FORMAT ENCODING clause for non-bytea input types" msgstr "bytrea以外の入力型に対しては JSON FORMAT ENCODING句は使用できません" -#: parser/parse_expr.c:4233 +#: parser/parse_expr.c:4243 #, c-format msgid "cannot use type %s in IS JSON predicate" msgstr "JSON述語では型%sを使用できません" -#: parser/parse_expr.c:4260 parser/parse_expr.c:4381 +#: parser/parse_expr.c:4270 parser/parse_expr.c:4391 #, c-format msgid "cannot use type %s in RETURNING clause of %s" msgstr "%s()のRETURNING節では型%sは指定できません" -#: parser/parse_expr.c:4262 +#: parser/parse_expr.c:4272 #, c-format msgid "Try returning json or jsonb." msgstr "jsonまたはjsonbでの返却を試してください。" -#: parser/parse_expr.c:4310 +#: parser/parse_expr.c:4320 #, c-format msgid "cannot use non-string types with WITH UNIQUE KEYS clause" msgstr "非文字列型はWITH UNIQUE KEYS句とともには使用できません" -#: parser/parse_expr.c:4384 +#: parser/parse_expr.c:4394 #, c-format msgid "Try returning a string type or bytea." msgstr "文字列型またはBYTEA型での返却を試してください。" -#: parser/parse_expr.c:4452 +#: parser/parse_expr.c:4462 #, c-format msgid "cannot specify FORMAT JSON in RETURNING clause of %s()" msgstr "%s()のRETURNING節ではFORMAT JSONは指定できません" -#: parser/parse_expr.c:4465 +#: parser/parse_expr.c:4475 #, c-format msgid "SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is used" msgstr "WITH WRAPPERが使われてるときにはSQL/JSONのQUOTESの挙動は指定できまえん" #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4479 parser/parse_expr.c:4508 parser/parse_expr.c:4539 parser/parse_expr.c:4565 parser/parse_expr.c:4591 parser/parse_jsontable.c:92 +#: parser/parse_expr.c:4489 parser/parse_expr.c:4518 parser/parse_expr.c:4549 parser/parse_expr.c:4575 parser/parse_expr.c:4601 parser/parse_jsontable.c:92 #, c-format msgid "invalid %s behavior" msgstr "不正な%s挙動指定" #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY), #. second %s is a SQL/JSON function name (e.g. JSON_QUERY) -#: parser/parse_expr.c:4482 parser/parse_expr.c:4511 +#: parser/parse_expr.c:4492 parser/parse_expr.c:4521 #, c-format msgid "Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for %s." msgstr "%2$sに対する%1$s句ではERROR, NULL, EMPTY ARRAY, EMPTY OBJECTまたはDEFAULT式のみが使用可能です。" @@ -22280,72 +22428,72 @@ msgstr "%2$sに対する%1$s句ではERROR, NULL, EMPTY ARRAY, EMPTY OBJECTま #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) #. translator: first %s is name a SQL/JSON clause (eg. ON EMPTY) #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4489 parser/parse_expr.c:4518 parser/parse_expr.c:4547 parser/parse_expr.c:4575 parser/parse_expr.c:4601 +#: parser/parse_expr.c:4499 parser/parse_expr.c:4528 parser/parse_expr.c:4557 parser/parse_expr.c:4585 parser/parse_expr.c:4611 #, c-format msgid "invalid %s behavior for column \"%s\"" msgstr "列\"%s\"に対する不正な%s挙動指定" #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4492 parser/parse_expr.c:4521 +#: parser/parse_expr.c:4502 parser/parse_expr.c:4531 #, c-format msgid "Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for formatted columns." msgstr "フォーマット化対象列に対する%s句ではERROR, NULL, EMPTY ARRAY, EMPTY OBJECTまたはDEFAULT式のみが使用可能です。" -#: parser/parse_expr.c:4540 +#: parser/parse_expr.c:4550 #, c-format msgid "Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for %s." msgstr "%2$sに対する%1$s句ではERROR, TRUE, FALSEまたはUNKNOWNのみが使用可能です。" #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4550 +#: parser/parse_expr.c:4560 #, c-format msgid "Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for EXISTS columns." msgstr "EXIST列に対する%s句ではERROR, TRUE, FALSEまたはUNKNOWNのみが使用可能です。" #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY), #. second %s is a SQL/JSON function name (e.g. JSON_QUERY) -#: parser/parse_expr.c:4568 parser/parse_expr.c:4594 +#: parser/parse_expr.c:4578 parser/parse_expr.c:4604 #, c-format msgid "Only ERROR, NULL, or DEFAULT expression is allowed in %s for %s." msgstr "%2$sに対する%1$s句ではERROR, NULLまたはDEFAULT式のみが使用可能です。" #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4578 parser/parse_expr.c:4604 +#: parser/parse_expr.c:4588 parser/parse_expr.c:4614 #, c-format msgid "Only ERROR, NULL, or DEFAULT expression is allowed in %s for scalar columns." msgstr "スカラー列に対する%s句ではERROR, NULLまたはDEFAULT式のみが使用可能です。" -#: parser/parse_expr.c:4638 +#: parser/parse_expr.c:4648 #, c-format msgid "JSON path expression must be of type %s, not of type %s" msgstr "JSONパス式は型%2$sではなく%1$s型でなければなりません" -#: parser/parse_expr.c:4878 +#: parser/parse_expr.c:4888 #, c-format msgid "can only specify a constant, non-aggregate function, or operator expression for DEFAULT" msgstr "DEFAULTには定数、非集約関数、および演算子式のみ指定可能です" -#: parser/parse_expr.c:4883 +#: parser/parse_expr.c:4893 #, c-format msgid "DEFAULT expression must not contain column references" msgstr "DEFAULT式は列参照を含むことができません" -#: parser/parse_expr.c:4888 +#: parser/parse_expr.c:4898 #, c-format msgid "DEFAULT expression must not return a set" msgstr "DEFAULT式は集合を返してはなりません" -#: parser/parse_expr.c:4903 +#: parser/parse_expr.c:4913 #, c-format msgid "collation of DEFAULT expression conflicts with RETURNING clause" msgstr "DEFAULT式の照合順序がRETURNING句と競合しています" -#: parser/parse_expr.c:4982 parser/parse_expr.c:4991 +#: parser/parse_expr.c:4992 parser/parse_expr.c:5001 #, c-format msgid "cannot cast behavior expression of type %s to %s" msgstr "型%sの挙動式の%sへの型変換はできません" -#: parser/parse_expr.c:4985 +#: parser/parse_expr.c:4995 #, c-format msgid "You will need to explicitly cast the expression to type %s." msgstr "式を%s型に明示的にキャストする必要があります。" @@ -22360,7 +22508,7 @@ msgstr "引数名\"%s\"が複数回指定されました" msgid "positional argument cannot follow named argument" msgstr "位置パラメーターの次には名前付きの引数を指定できません。" -#: parser/parse_func.c:292 parser/parse_func.c:2496 +#: parser/parse_func.c:292 parser/parse_func.c:2500 #, c-format msgid "%s is not a procedure" msgstr "%sはプロシージャではありません" @@ -22410,357 +22558,363 @@ msgstr "FILTERが指定されましたが、%sは集約関数ではありませ msgid "OVER specified, but %s is not a window function nor an aggregate function" msgstr "OVERが指定されましたが、%sはウィンドウ関数と集約関数のいずれでもありません" -#: parser/parse_func.c:389 +#. translator: first %s is a null treatment option, eg IGNORE NULLS +#: parser/parse_func.c:358 +#, c-format +msgid "%s specified, but %s is not a window function" +msgstr "%s が指定されましたが、%s はウィンドウ関数ではありません" + +#: parser/parse_func.c:396 #, c-format msgid "WITHIN GROUP is required for ordered-set aggregate %s" msgstr "順序集合集約%sには WITHIN GROUP が必要です" -#: parser/parse_func.c:395 +#: parser/parse_func.c:402 #, c-format msgid "OVER is not supported for ordered-set aggregate %s" msgstr "OVERは順序集合集約%sではサポートされていません" -#: parser/parse_func.c:426 parser/parse_func.c:457 +#: parser/parse_func.c:433 parser/parse_func.c:464 #, c-format msgid "There is an ordered-set aggregate %s, but it requires %d direct argument, not %d." msgid_plural "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." msgstr[0] "順序集合集約%1$sはありますが、それは%3$d個ではなく%2$d個の直接引数を必要とします。" -#: parser/parse_func.c:484 +#: parser/parse_func.c:491 #, c-format msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." msgstr "仮説集合集約%sを使うには、仮説直接引数(今は%d)がソート列の数(今は%d)と一致する必要があります" -#: parser/parse_func.c:498 +#: parser/parse_func.c:505 #, c-format msgid "There is an ordered-set aggregate %s, but it requires at least %d direct argument." msgid_plural "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." msgstr[0] "順序集合集約%sはありますが、それは少なくとも%d個の直接引数を必要とします。" -#: parser/parse_func.c:519 +#: parser/parse_func.c:526 #, c-format msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" msgstr "%sは順序集合集約ではないため、WITHIN GROUP を持つことができません" -#: parser/parse_func.c:527 +#: parser/parse_func.c:534 #, c-format msgid "aggregate functions do not accept RESPECT/IGNORE NULLS" msgstr "集約関数は RESPECT/IGNORE NULLS を受け付けません" -#: parser/parse_func.c:539 +#: parser/parse_func.c:545 #, c-format msgid "window function %s requires an OVER clause" msgstr "ウィンドウ関数%sにはOVER句が必要です" -#: parser/parse_func.c:546 +#: parser/parse_func.c:552 #, c-format msgid "window function %s cannot have WITHIN GROUP" msgstr "ウィンドウ関数%sはWITHIN GROUPを持つことができません" -#: parser/parse_func.c:575 +#: parser/parse_func.c:581 #, c-format msgid "procedure %s is not unique" msgstr "プロシージャ %s は一意ではありません" -#: parser/parse_func.c:578 +#: parser/parse_func.c:584 #, c-format msgid "Could not choose a best candidate procedure." msgstr "最善の候補プロシージャを選択できませんでした。" -#: parser/parse_func.c:579 parser/parse_func.c:588 parser/parse_func.c:1018 parser/parse_oper.c:645 parser/parse_oper.c:694 +#: parser/parse_func.c:585 parser/parse_func.c:594 parser/parse_func.c:1024 parser/parse_oper.c:645 parser/parse_oper.c:694 #, c-format msgid "You might need to add explicit type casts." msgstr "必要に応じて明示的な型変換を追加してください。" -#: parser/parse_func.c:584 +#: parser/parse_func.c:590 #, c-format msgid "function %s is not unique" msgstr "関数 %s は一意ではありません" -#: parser/parse_func.c:587 +#: parser/parse_func.c:593 #, c-format msgid "Could not choose a best candidate function." msgstr "最善の候補関数を選択できませんでした。" -#: parser/parse_func.c:628 +#: parser/parse_func.c:634 #, c-format msgid "No aggregate function matches the given name and argument types." msgstr "指定した名前と引数型に合致する集約関数がありません。" -#: parser/parse_func.c:629 +#: parser/parse_func.c:635 #, c-format msgid "Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." msgstr "おそらく ORDER BY の位置に誤りがあります。ORDER BY は集約関数のすべての通常の引数の後になければなりません。" -#: parser/parse_func.c:636 parser/parse_func.c:2539 +#: parser/parse_func.c:642 parser/parse_func.c:2543 #, c-format msgid "procedure %s does not exist" msgstr "プロシージャ %s は存在しません" -#: parser/parse_func.c:750 +#: parser/parse_func.c:756 #, c-format msgid "VARIADIC argument must be an array" msgstr "VARIADIC引数は配列でなければなりません" -#: parser/parse_func.c:805 parser/parse_func.c:871 +#: parser/parse_func.c:811 parser/parse_func.c:877 #, c-format msgid "%s(*) must be used to call a parameterless aggregate function" msgstr "%s(*)はパラメータがない集約関数の呼び出しに使用しなければなりません" -#: parser/parse_func.c:812 +#: parser/parse_func.c:818 #, c-format msgid "aggregates cannot return sets" msgstr "集約は集合を返せません" -#: parser/parse_func.c:827 +#: parser/parse_func.c:833 #, c-format msgid "aggregates cannot use named arguments" msgstr "集約では名前付き引数は使えません" -#: parser/parse_func.c:861 +#: parser/parse_func.c:867 #, c-format msgid "DISTINCT is not implemented for window functions" msgstr "ウィンドウ関数に対するDISTINCTは実装されていません" -#: parser/parse_func.c:890 +#: parser/parse_func.c:896 #, c-format msgid "FILTER is not implemented for non-aggregate window functions" msgstr "非集約のウィンドウ関数に対するFILTERは実装されていません" -#: parser/parse_func.c:899 +#: parser/parse_func.c:905 #, c-format msgid "window function calls cannot contain set-returning function calls" msgstr "集約関数の呼び出しに集合返却関数の呼び出しを含むことはできません" -#: parser/parse_func.c:907 +#: parser/parse_func.c:913 #, c-format msgid "window functions cannot return sets" msgstr "ウィンドウ関数は集合を返すことができません" -#: parser/parse_func.c:950 +#: parser/parse_func.c:956 #, c-format msgid "There is no procedure of that name." msgstr "その名前のプロシージャは存在しません。" -#: parser/parse_func.c:952 +#: parser/parse_func.c:958 #, c-format msgid "There is no function of that name." msgstr "その名前の関数は存在しません。" -#: parser/parse_func.c:957 +#: parser/parse_func.c:963 #, c-format msgid "A procedure of that name exists, but it is not in the search_path." msgstr "その名前のプロシージャは存在しますが、サーチパス中にはありません。" -#: parser/parse_func.c:959 +#: parser/parse_func.c:965 #, c-format msgid "A function of that name exists, but it is not in the search_path." msgstr "その名前の関数は存在しますが、サーチパス中にはありません。" -#: parser/parse_func.c:971 +#: parser/parse_func.c:977 #, c-format msgid "No procedure of that name accepts the given number of arguments." msgstr "その名前のプロシージャには、指定された数の引数を受け付けるものがありません。" -#: parser/parse_func.c:973 +#: parser/parse_func.c:979 #, c-format msgid "No function of that name accepts the given number of arguments." msgstr "その名前の関数には、指定された数の引数を受け付けるものがありません。" -#: parser/parse_func.c:983 +#: parser/parse_func.c:989 #, c-format msgid "No procedure of that name accepts the given argument names." msgstr "その名前のプロシージャには、指定された名前の引数を受け付けるものがありません。" -#: parser/parse_func.c:985 +#: parser/parse_func.c:991 #, c-format msgid "No function of that name accepts the given argument names." msgstr "その名前の関数には、指定された名前の引数を受け付けるものがありません。" -#: parser/parse_func.c:998 +#: parser/parse_func.c:1004 #, c-format msgid "In the closest available match, an argument was specified both positionally and by name." msgstr "利用可能な最も近い候補では、同一の引数が位置指定と名前指定の双方で指定されています。" -#: parser/parse_func.c:1002 +#: parser/parse_func.c:1008 #, c-format msgid "In the closest available match, not all required arguments were supplied." msgstr "利用可能な最も近い候補では、必須引数の一部が指定されていません。" -#: parser/parse_func.c:1006 +#: parser/parse_func.c:1012 #, c-format msgid "This call would be correct if the variadic array were labeled VARIADIC and placed last." msgstr "この呼び出しは、可変長引数用の配列が VARIADIC と指定され、かつ末尾に置かれていれば正しい呼び出しです。" -#: parser/parse_func.c:1009 +#: parser/parse_func.c:1015 #, c-format msgid "The VARIADIC parameter must be placed last, even when using argument names." msgstr "VARIADIC 引数は、引数名を使う場合でも最後に指定する必要があります。" -#: parser/parse_func.c:1015 +#: parser/parse_func.c:1021 #, c-format msgid "No procedure of that name accepts the given argument types." msgstr "その名前のプロシージャには、指定された引数型を受け付けるものはありません。" -#: parser/parse_func.c:1017 +#: parser/parse_func.c:1023 #, c-format msgid "No function of that name accepts the given argument types." msgstr "その名前の関数には、指定された引数型を受け付けるものはありません。" -#: parser/parse_func.c:2295 parser/parse_func.c:2568 +#: parser/parse_func.c:2299 parser/parse_func.c:2572 #, c-format msgid "could not find a function named \"%s\"" msgstr "\"%s\"という名前の関数は見つかりませんでした" -#: parser/parse_func.c:2309 parser/parse_func.c:2586 +#: parser/parse_func.c:2313 parser/parse_func.c:2590 #, c-format msgid "function name \"%s\" is not unique" msgstr "関数名\"%s\"は一意ではありません" -#: parser/parse_func.c:2311 parser/parse_func.c:2589 +#: parser/parse_func.c:2315 parser/parse_func.c:2593 #, c-format msgid "Specify the argument list to select the function unambiguously." msgstr "関数を曖昧さなく選択するには引数リストを指定してください。" -#: parser/parse_func.c:2355 +#: parser/parse_func.c:2359 #, c-format msgid "procedures cannot have more than %d argument" msgid_plural "procedures cannot have more than %d arguments" msgstr[0] "プロシージャは%d個以上の引数を取ることはできません" -#: parser/parse_func.c:2486 +#: parser/parse_func.c:2490 #, c-format msgid "%s is not a function" msgstr "%s は関数ではありません" -#: parser/parse_func.c:2506 +#: parser/parse_func.c:2510 #, c-format msgid "function %s is not an aggregate" msgstr "関数%sは集約ではありません" -#: parser/parse_func.c:2534 +#: parser/parse_func.c:2538 #, c-format msgid "could not find a procedure named \"%s\"" msgstr "\"%s\"という名前のプロシージャは見つかりませんでした" -#: parser/parse_func.c:2548 +#: parser/parse_func.c:2552 #, c-format msgid "could not find an aggregate named \"%s\"" msgstr "\"%s\"という名前の集約は見つかりませんでした" -#: parser/parse_func.c:2553 +#: parser/parse_func.c:2557 #, c-format msgid "aggregate %s(*) does not exist" msgstr "集約%s(*)は存在しません" -#: parser/parse_func.c:2558 +#: parser/parse_func.c:2562 #, c-format msgid "aggregate %s does not exist" msgstr "集約%sは存在しません" -#: parser/parse_func.c:2594 +#: parser/parse_func.c:2598 #, c-format msgid "procedure name \"%s\" is not unique" msgstr "プロシージャ名\"%s\"は一意ではありません" -#: parser/parse_func.c:2597 +#: parser/parse_func.c:2601 #, c-format msgid "Specify the argument list to select the procedure unambiguously." msgstr "プロシージャを曖昧さなく選択するには引数リストを指定してください。" -#: parser/parse_func.c:2602 +#: parser/parse_func.c:2606 #, c-format msgid "aggregate name \"%s\" is not unique" msgstr "集約名\"%s\"は一意ではありません" -#: parser/parse_func.c:2605 +#: parser/parse_func.c:2609 #, c-format msgid "Specify the argument list to select the aggregate unambiguously." msgstr "集約を曖昧さなく選択するには引数リストを指定してください。" -#: parser/parse_func.c:2610 +#: parser/parse_func.c:2614 #, c-format msgid "routine name \"%s\" is not unique" msgstr "ルーチン名\"%s\"は一意ではありません" -#: parser/parse_func.c:2613 +#: parser/parse_func.c:2617 #, c-format msgid "Specify the argument list to select the routine unambiguously." msgstr "ルーチンを曖昧さなく選択するには引数リストを指定してください。" -#: parser/parse_func.c:2668 +#: parser/parse_func.c:2672 msgid "set-returning functions are not allowed in JOIN conditions" msgstr "集合返却関数はJOIN条件では使用できません" -#: parser/parse_func.c:2689 +#: parser/parse_func.c:2693 msgid "set-returning functions are not allowed in policy expressions" msgstr "集合返却関数はポリシ式では使用できません" -#: parser/parse_func.c:2705 +#: parser/parse_func.c:2706 msgid "set-returning functions are not allowed in window definitions" msgstr "ウィンドウ定義では集合返却関数は使用できません" -#: parser/parse_func.c:2743 +#: parser/parse_func.c:2744 msgid "set-returning functions are not allowed in MERGE WHEN conditions" msgstr "集合返却関数はMERGE WHEN条件では使用できません" -#: parser/parse_func.c:2747 +#: parser/parse_func.c:2748 msgid "set-returning functions are not allowed in check constraints" msgstr "集合返却関数は検査制約の中では使用できません" -#: parser/parse_func.c:2751 +#: parser/parse_func.c:2752 msgid "set-returning functions are not allowed in DEFAULT expressions" msgstr "集合返却関数はDEFAULT式の中では使用できません" -#: parser/parse_func.c:2754 +#: parser/parse_func.c:2755 msgid "set-returning functions are not allowed in index expressions" msgstr "集合返却関数はインデックス式では使用できません" -#: parser/parse_func.c:2757 +#: parser/parse_func.c:2758 msgid "set-returning functions are not allowed in index predicates" msgstr "集合返却関数はインデックス述語では使用できません" -#: parser/parse_func.c:2760 +#: parser/parse_func.c:2761 msgid "set-returning functions are not allowed in statistics expressions" msgstr "集合返却関数は統計情報式では使用できません" -#: parser/parse_func.c:2763 +#: parser/parse_func.c:2764 msgid "set-returning functions are not allowed in transform expressions" msgstr "集合返却関数は変換式では使用できません" -#: parser/parse_func.c:2766 +#: parser/parse_func.c:2767 msgid "set-returning functions are not allowed in EXECUTE parameters" msgstr "集合返却関数はEXECUTEパラメータでは使用できません" -#: parser/parse_func.c:2769 +#: parser/parse_func.c:2770 msgid "set-returning functions are not allowed in trigger WHEN conditions" msgstr "集合返却関数はトリガーのWHEN条件では使用できません" -#: parser/parse_func.c:2772 +#: parser/parse_func.c:2773 msgid "set-returning functions are not allowed in partition bound" msgstr "集合返却関数はパーティション境界では使用できません" -#: parser/parse_func.c:2775 +#: parser/parse_func.c:2776 msgid "set-returning functions are not allowed in partition key expressions" msgstr "集合返却関数はパーティションキー式では使用できません" -#: parser/parse_func.c:2778 +#: parser/parse_func.c:2779 msgid "set-returning functions are not allowed in CALL arguments" msgstr "CALLの引数に集合返却関数は使用できません" -#: parser/parse_func.c:2781 +#: parser/parse_func.c:2782 msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" msgstr "集合返却関数は COPY FROM の WHERE条件では使用できません" -#: parser/parse_func.c:2784 +#: parser/parse_func.c:2785 msgid "set-returning functions are not allowed in column generation expressions" msgstr "集合返却関数はカラム生成式では使用できません" -#: parser/parse_func.c:2790 +#: parser/parse_func.c:2791 msgid "set-returning functions are not allowed in property definition expressions" msgstr "集合返却関数はプロパティ定義内の式では使用できません" -#: parser/parse_func.c:2793 +#: parser/parse_func.c:2794 msgid "set-returning functions are not allowed in FOR PORTION OF expressions" msgstr "集合返却関数はFOR PORTION OF 内の式では使用できません" @@ -22929,7 +23083,7 @@ msgstr "演算子 ANY/ALL (配列) 集合を返してはなりません" msgid "inconsistent types deduced for parameter $%d" msgstr "パラメータ$%dについて推定された型が不整合です" -#: parser/parse_param.c:310 tcop/postgres.c:751 +#: parser/parse_param.c:310 tcop/postgres.c:752 #, c-format msgid "could not determine data type of parameter $%d" msgstr "パラメータ$%dのデータ型が特定できませんでした" @@ -22944,12 +23098,12 @@ msgstr "テーブル参照\"%s\"は曖昧です" msgid "table reference %u is ambiguous" msgstr "テーブル参照%uは曖昧です" -#: parser/parse_relation.c:498 parser/parse_relation.c:3825 parser/parse_relation.c:3834 +#: parser/parse_relation.c:498 parser/parse_relation.c:3857 parser/parse_relation.c:3866 #, c-format msgid "invalid reference to FROM-clause entry for table \"%s\"" msgstr "テーブル\"%s\"用のFROM句に対する不正な参照" -#: parser/parse_relation.c:502 parser/parse_relation.c:3836 +#: parser/parse_relation.c:502 parser/parse_relation.c:3868 #, c-format msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." msgstr "テーブル\"%s\"の項目がありますが、問い合わせのこの部分からは参照できません。\"" @@ -22959,147 +23113,147 @@ msgstr "テーブル\"%s\"の項目がありますが、問い合わせのこの msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." msgstr "LATERAL参照では組み合わせる結合のタイプはINNERまたはLEFTでなければなりません" -#: parser/parse_relation.c:707 +#: parser/parse_relation.c:739 #, c-format msgid "system column \"%s\" reference in check constraint is invalid" msgstr "検査制約で参照されるシステム列\"%s\"は不正です" -#: parser/parse_relation.c:720 +#: parser/parse_relation.c:752 #, c-format msgid "cannot use system column \"%s\" in column generation expression" msgstr "カラム生成式ではシステム列\"%s\"は使用できません" -#: parser/parse_relation.c:731 +#: parser/parse_relation.c:763 #, c-format msgid "cannot use system column \"%s\" in MERGE WHEN condition" msgstr "MERGE WHEN条件ではシステム列\"%s\"は使用できません" -#: parser/parse_relation.c:1247 parser/parse_relation.c:1696 parser/parse_relation.c:2485 +#: parser/parse_relation.c:1279 parser/parse_relation.c:1728 parser/parse_relation.c:2517 #, c-format msgid "table \"%s\" has %d columns available but %d columns specified" msgstr "テーブル\"%s\"では%d列使用できますが、%d列指定されました" -#: parser/parse_relation.c:1454 +#: parser/parse_relation.c:1486 #, c-format msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." msgstr "\"%s\"というWITH項目はありますが、これは問い合わせのこの部分からは参照できません。" -#: parser/parse_relation.c:1456 +#: parser/parse_relation.c:1488 #, c-format msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." msgstr "WITH RECURSIVE を使うか、もしくは WITH 項目の場所を変えて前方参照をなくしてください" -#: parser/parse_relation.c:1838 +#: parser/parse_relation.c:1870 #, c-format msgid "a column definition list is redundant for a function with OUT parameters" msgstr "OUTパラメータを持つ関数に対しては列定義リストは不要です" -#: parser/parse_relation.c:1844 +#: parser/parse_relation.c:1876 #, c-format msgid "a column definition list is redundant for a function returning a named composite type" msgstr "名前付き複合型w返す関数に対しては列定義リストは不要です" -#: parser/parse_relation.c:1851 +#: parser/parse_relation.c:1883 #, c-format msgid "a column definition list is only allowed for functions returning \"record\"" msgstr "列定義リストは\"record\"を返す関数でのみ使用できます" -#: parser/parse_relation.c:1862 +#: parser/parse_relation.c:1894 #, c-format msgid "a column definition list is required for functions returning \"record\"" msgstr "\"record\"を返す関数では列定義リストが必要です" -#: parser/parse_relation.c:1900 +#: parser/parse_relation.c:1932 #, c-format msgid "column definition lists can have at most %d entries" msgstr "列定義リストは最大でも%dエントリまでしか持てません" -#: parser/parse_relation.c:1961 +#: parser/parse_relation.c:1993 #, c-format msgid "function \"%s\" in FROM has unsupported return type %s" msgstr "FROM句の関数\"%s\"の戻り値型%sはサポートされていません" -#: parser/parse_relation.c:1988 parser/parse_relation.c:2073 +#: parser/parse_relation.c:2020 parser/parse_relation.c:2105 #, c-format msgid "functions in FROM can return at most %d columns" msgstr "FROM内の関数は最大%d列までしか返却できません" -#: parser/parse_relation.c:2103 +#: parser/parse_relation.c:2135 #, c-format msgid "%s function has %d columns available but %d columns specified" msgstr "%s関数では%d列使用できますが、%d列指定されました" -#: parser/parse_relation.c:2184 +#: parser/parse_relation.c:2216 #, c-format msgid "GRAPH_TABLE \"%s\" has %d columns available but %d columns specified" msgstr "GRAPH_TABLE \"%s\"では%d列使用できますが、%d列指定されています" -#: parser/parse_relation.c:2277 +#: parser/parse_relation.c:2309 #, c-format msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" msgstr "VALUESリスト\"%s\"は%d列使用可能ですが、%d列が指定されました" -#: parser/parse_relation.c:2342 +#: parser/parse_relation.c:2374 #, c-format msgid "joins can have at most %d columns" msgstr "JOIN で指定できるのは、最大 %d 列です" -#: parser/parse_relation.c:2367 +#: parser/parse_relation.c:2399 #, c-format msgid "join expression \"%s\" has %d columns available but %d columns specified" msgstr "結合式\"%s\"では%d列使用できますが、%d列指定されました" -#: parser/parse_relation.c:2458 +#: parser/parse_relation.c:2490 #, c-format msgid "WITH query \"%s\" does not have a RETURNING clause" msgstr "WITH 問い合わせ\"%s\"にRETURNING句がありません" -#: parser/parse_relation.c:3827 +#: parser/parse_relation.c:3859 #, c-format msgid "Perhaps you meant to reference the table alias \"%s\"." msgstr "テーブル別名\"%s\"を参照しようとしていたようです。" -#: parser/parse_relation.c:3839 +#: parser/parse_relation.c:3871 #, c-format msgid "To reference that table, you must mark this subquery with LATERAL." msgstr "そのテーブルを参照するためには、この副問合せをLATERALとマークする必要があります。" -#: parser/parse_relation.c:3845 +#: parser/parse_relation.c:3877 #, c-format msgid "missing FROM-clause entry for table \"%s\"" msgstr "テーブル\"%s\"用のFROM句エントリがありません" -#: parser/parse_relation.c:3885 +#: parser/parse_relation.c:3917 #, c-format msgid "There are columns named \"%s\", but they are in tables that cannot be referenced from this part of the query." msgstr "\"%s\"という名前の列はありますが、問い合わせのこの部分からは参照できないテーブルに属しています。" -#: parser/parse_relation.c:3887 +#: parser/parse_relation.c:3919 #, c-format msgid "Try using a table-qualified name." msgstr "テーブル名で修飾した名前を試してください。" -#: parser/parse_relation.c:3895 +#: parser/parse_relation.c:3927 #, c-format msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." msgstr "テーブル\"%2$s\"には\"%1$s\"という名前の列がありますが、問い合わせのこの部分からは参照できません。" -#: parser/parse_relation.c:3898 +#: parser/parse_relation.c:3930 #, c-format msgid "To reference that column, you must mark this subquery with LATERAL." msgstr "その列を参照するには、この副問合せをLATERALとマークする必要があります。" -#: parser/parse_relation.c:3900 +#: parser/parse_relation.c:3932 #, c-format msgid "To reference that column, you must use a table-qualified name." msgstr "その列を参照するには、テーブル名で修飾した名前を使う必要があります。" -#: parser/parse_relation.c:3920 +#: parser/parse_relation.c:3952 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\"." msgstr "列\"%s.%s\"を参照しようとしていたようです。" -#: parser/parse_relation.c:3934 +#: parser/parse_relation.c:3966 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." msgstr "列\"%s.%s\"または列\"%s.%s\"を参照しようとしていたようです。" @@ -23164,7 +23318,7 @@ msgstr "%%TYPE参照が不適切です(ドット区切りの名前が多すぎ msgid "type reference %s converted to %s" msgstr "型参照%sは%sに変換されました" -#: parser/parse_type.c:278 parser/parse_type.c:813 utils/cache/typcache.c:481 utils/cache/typcache.c:536 +#: parser/parse_type.c:278 parser/parse_type.c:813 utils/cache/typcache.c:490 utils/cache/typcache.c:545 #, c-format msgid "type \"%s\" is only a shell" msgstr "型\"%s\"は単なるシェルです" @@ -23349,252 +23503,252 @@ msgstr "WITHOUT OVERLAPS中の列\"%s\"は範囲型でも副範囲型でもあ msgid "constraint using WITHOUT OVERLAPS needs at least two columns" msgstr "WITHOUT OVERLAPSを使用する制約では少なくとも2つの列が必要です" -#: parser/parse_utilcmd.c:3136 +#: parser/parse_utilcmd.c:3132 #, c-format msgid "index expressions and predicates can refer only to the table being indexed" msgstr "インデックス式と述語はインデックス付けされるテーブルのみを参照できます" -#: parser/parse_utilcmd.c:3208 +#: parser/parse_utilcmd.c:3204 #, c-format msgid "statistics expressions can refer only to the table being referenced" msgstr "統計情報式は参照されているテーブルのみを参照できます" -#: parser/parse_utilcmd.c:3251 +#: parser/parse_utilcmd.c:3247 #, c-format msgid "rules on materialized views are not supported" msgstr "実体化ビューに対するルールはサポートされません" -#: parser/parse_utilcmd.c:3311 +#: parser/parse_utilcmd.c:3307 #, c-format msgid "rule WHERE condition cannot contain references to other relations" msgstr "ルールのWHERE条件に他のリレーションへの参照を持たせられません" -#: parser/parse_utilcmd.c:3383 +#: parser/parse_utilcmd.c:3379 #, c-format msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" msgstr "ルールのWHERE条件はSELECT、INSERT、UPDATE、DELETE動作のみを持つことができます" -#: parser/parse_utilcmd.c:3401 parser/parse_utilcmd.c:3502 rewrite/rewriteHandler.c:547 rewrite/rewriteManip.c:1199 +#: parser/parse_utilcmd.c:3397 parser/parse_utilcmd.c:3498 rewrite/rewriteHandler.c:547 rewrite/rewriteManip.c:1199 #, c-format msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" msgstr "条件付きのUNION/INTERSECT/EXCEPT文は実装されていません" -#: parser/parse_utilcmd.c:3419 +#: parser/parse_utilcmd.c:3415 #, c-format msgid "ON SELECT rule cannot use OLD" msgstr "ON SELECTルールではOLDを使用できません" -#: parser/parse_utilcmd.c:3423 +#: parser/parse_utilcmd.c:3419 #, c-format msgid "ON SELECT rule cannot use NEW" msgstr "ON SELECTルールではNEWを使用できません" -#: parser/parse_utilcmd.c:3432 +#: parser/parse_utilcmd.c:3428 #, c-format msgid "ON INSERT rule cannot use OLD" msgstr "ON INSERTルールではOLDを使用できません" -#: parser/parse_utilcmd.c:3438 +#: parser/parse_utilcmd.c:3434 #, c-format msgid "ON DELETE rule cannot use NEW" msgstr "ON DELETEルールではNEWを使用できません" -#: parser/parse_utilcmd.c:3466 +#: parser/parse_utilcmd.c:3462 #, c-format msgid "cannot refer to OLD within WITH query" msgstr "WITH 問い合わせ内では OLD は参照できません" -#: parser/parse_utilcmd.c:3473 +#: parser/parse_utilcmd.c:3469 #, c-format msgid "cannot refer to NEW within WITH query" msgstr "WITH 問い合わせ内では NEW は参照できません" -#: parser/parse_utilcmd.c:3543 parser/parse_utilcmd.c:3552 parser/parse_utilcmd.c:3561 +#: parser/parse_utilcmd.c:3539 parser/parse_utilcmd.c:3548 parser/parse_utilcmd.c:3557 #, c-format msgid "ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions." msgstr "ALTER TABLE ... MERGE PARTITIONS は子パーティションを持たないパーティションのみマージできます" -#: parser/parse_utilcmd.c:3544 parser/parse_utilcmd.c:3553 parser/parse_utilcmd.c:3562 +#: parser/parse_utilcmd.c:3540 parser/parse_utilcmd.c:3549 parser/parse_utilcmd.c:3558 #, c-format msgid "ALTER TABLE ... SPLIT PARTITION can only split partitions that don't have sub-partitions." msgstr "ALTER TABLE ... SPLIT PARTITION は子パーティションを持たないパーティションのみ分割できます" -#: parser/parse_utilcmd.c:3549 +#: parser/parse_utilcmd.c:3545 #, c-format msgid "\"%s\" is not a partition of partitioned table \"%s\"" msgstr "\"%s\"はパーティション親テーブル \"%s\"の子テーブルではありません" -#: parser/parse_utilcmd.c:3625 +#: parser/parse_utilcmd.c:3621 #, c-format msgid "cannot specify more than one DEFAULT partition" msgstr "2個以上のDEFAULTパーティションを指定できません" -#: parser/parse_utilcmd.c:3637 +#: parser/parse_utilcmd.c:3633 #, c-format msgid "partition of hash-partitioned table cannot be split" msgstr "ハッシュパーティションテーブルの子テーブルは分割できません" -#: parser/parse_utilcmd.c:3652 +#: parser/parse_utilcmd.c:3648 #, c-format msgid "cannot split DEFAULT partition \"%s\"" msgstr "DEFAULTパーティション\"%s\"は分割できません" -#: parser/parse_utilcmd.c:3654 +#: parser/parse_utilcmd.c:3650 #, c-format msgid "To split a DEFAULT partition, one of the new partitions must be DEFAULT." msgstr "DEFAULT パーティションを分割するには、新しいパーティションの一方がDEFAULTである必要があります。" -#: parser/parse_utilcmd.c:3668 +#: parser/parse_utilcmd.c:3664 #, c-format msgid "cannot split non-DEFAULT partition \"%s\"" msgstr "非DEFAULTパーティション\"%s\"は分割できません" -#: parser/parse_utilcmd.c:3670 +#: parser/parse_utilcmd.c:3666 #, c-format msgid "New partition cannot be DEFAULT because DEFAULT partition \"%s\" already exists." msgstr "DEFAULT パーティション \"%s\" がすでに存在するため、新しいパーティションは DEFAULT にできません。" -#: parser/parse_utilcmd.c:3693 parser/parse_utilcmd.c:3701 parser/parse_utilcmd.c:3754 parser/parse_utilcmd.c:3783 +#: parser/parse_utilcmd.c:3689 parser/parse_utilcmd.c:3697 parser/parse_utilcmd.c:3750 parser/parse_utilcmd.c:3779 #, c-format msgid "partition with name \"%s\" is already used" msgstr "\"%s\"という名前のパーティション子テーブルはすでに使用されています" -#: parser/parse_utilcmd.c:3737 +#: parser/parse_utilcmd.c:3733 #, c-format msgid "partition of hash-partitioned table cannot be merged" msgstr "ハッシュパーティションテーブルの子テーブルはマージできません" -#: parser/parse_utilcmd.c:4090 +#: parser/parse_utilcmd.c:4086 #, c-format msgid "list of partitions to be merged should include at least two partitions" msgstr "マージ対象パーティションのリストは少なくとも2つのパーティションを含んでいる必要があります" -#: parser/parse_utilcmd.c:4104 +#: parser/parse_utilcmd.c:4100 #, c-format msgid "list of new partitions should contain at least two partitions" msgstr "新しいパーティションのリストには少なくとも2つのパーティションが含まれていなければなりません" -#: parser/parse_utilcmd.c:4243 +#: parser/parse_utilcmd.c:4239 #, c-format msgid "misplaced DEFERRABLE clause" msgstr "DEFERRABLE句の場所が間違っています" -#: parser/parse_utilcmd.c:4248 parser/parse_utilcmd.c:4263 +#: parser/parse_utilcmd.c:4244 parser/parse_utilcmd.c:4259 #, c-format msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" msgstr "複数のDEFERRABLE/NOT DEFERRABLE句を使用できません" -#: parser/parse_utilcmd.c:4258 +#: parser/parse_utilcmd.c:4254 #, c-format msgid "misplaced NOT DEFERRABLE clause" msgstr "NOT DEFERRABLE句の場所が間違っています" -#: parser/parse_utilcmd.c:4279 +#: parser/parse_utilcmd.c:4275 #, c-format msgid "misplaced INITIALLY DEFERRED clause" msgstr "INITIALLY DEFERRED句の場所が間違っています<" -#: parser/parse_utilcmd.c:4284 parser/parse_utilcmd.c:4310 +#: parser/parse_utilcmd.c:4280 parser/parse_utilcmd.c:4306 #, c-format msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" msgstr "複数のINITIALLY IMMEDIATE/DEFERRED句を使用できません" -#: parser/parse_utilcmd.c:4305 +#: parser/parse_utilcmd.c:4301 #, c-format msgid "misplaced INITIALLY IMMEDIATE clause" msgstr "INITIALLY IMMEDIATE句の場所が間違っています<" -#: parser/parse_utilcmd.c:4322 +#: parser/parse_utilcmd.c:4318 #, c-format msgid "misplaced ENFORCED clause" msgstr "ENFORCED句の場所が間違っています" -#: parser/parse_utilcmd.c:4327 parser/parse_utilcmd.c:4344 +#: parser/parse_utilcmd.c:4323 parser/parse_utilcmd.c:4340 #, c-format msgid "multiple ENFORCED/NOT ENFORCED clauses not allowed" msgstr "複数のENFORCED/NOT ENFORCED句は指定できません" -#: parser/parse_utilcmd.c:4339 +#: parser/parse_utilcmd.c:4335 #, c-format msgid "misplaced NOT ENFORCED clause" msgstr "NOT ENFORCED句の場所が間違っています" -#: parser/parse_utilcmd.c:4588 parser/parse_utilcmd.c:4622 +#: parser/parse_utilcmd.c:4584 parser/parse_utilcmd.c:4618 #, c-format msgid "CREATE specifies a schema (%s) different from the one being created (%s)" msgstr "CREATEで指定したスキーマ(%s)が作成先のスキーマ(%s)と異なります" -#: parser/parse_utilcmd.c:4812 +#: parser/parse_utilcmd.c:4808 #, c-format msgid "\"%s\" is not a partitioned table" msgstr "\"%s\"はパーティションテーブルではありません" -#: parser/parse_utilcmd.c:4819 +#: parser/parse_utilcmd.c:4815 #, c-format msgid "table \"%s\" is not partitioned" msgstr "テーブル\"%s\"はパーティションされていません" -#: parser/parse_utilcmd.c:4826 +#: parser/parse_utilcmd.c:4822 #, c-format msgid "index \"%s\" is not partitioned" msgstr "インデックス\"%s\"はパーティションされていません" -#: parser/parse_utilcmd.c:4866 +#: parser/parse_utilcmd.c:4862 #, c-format msgid "a hash-partitioned table may not have a default partition" msgstr "ハッシュパーティションテーブルはデフォルトパーティションを持つことができません" -#: parser/parse_utilcmd.c:4883 +#: parser/parse_utilcmd.c:4879 #, c-format msgid "invalid bound specification for a hash partition" msgstr "ハッシュパーティションに対する不正な境界指定" -#: parser/parse_utilcmd.c:4889 partitioning/partbounds.c:4795 +#: parser/parse_utilcmd.c:4885 partitioning/partbounds.c:4795 #, c-format msgid "modulus for hash partition must be an integer value greater than zero" msgstr "ハッシュパーティションの法は0より大きい整数にする必要があります" -#: parser/parse_utilcmd.c:4896 partitioning/partbounds.c:4803 +#: parser/parse_utilcmd.c:4892 partitioning/partbounds.c:4803 #, c-format msgid "remainder for hash partition must be less than modulus" msgstr "ハッシュパーティションの剰余は法よりも小さくなければなりません" -#: parser/parse_utilcmd.c:4909 +#: parser/parse_utilcmd.c:4905 #, c-format msgid "invalid bound specification for a list partition" msgstr "リストパーティションに対する不正な境界指定" -#: parser/parse_utilcmd.c:4962 +#: parser/parse_utilcmd.c:4958 #, c-format msgid "invalid bound specification for a range partition" msgstr "範囲パーティションに対する不正な境界指定" -#: parser/parse_utilcmd.c:4968 +#: parser/parse_utilcmd.c:4964 #, c-format msgid "FROM must specify exactly one value per partitioning column" msgstr "FROMは全てのパーティション列ごとに一つの値を指定しなければなりません" -#: parser/parse_utilcmd.c:4972 +#: parser/parse_utilcmd.c:4968 #, c-format msgid "TO must specify exactly one value per partitioning column" msgstr "TOは全てのパーティション列ごとに一つの値を指定しなければなりません" -#: parser/parse_utilcmd.c:5088 +#: parser/parse_utilcmd.c:5084 #, c-format msgid "cannot specify NULL in range bound" msgstr "範囲境界でNULLは使用できません" -#: parser/parse_utilcmd.c:5136 +#: parser/parse_utilcmd.c:5132 #, c-format msgid "every bound following MAXVALUE must also be MAXVALUE" msgstr "MAXVALUEに続く境界値はMAXVALUEでなければなりません" -#: parser/parse_utilcmd.c:5143 +#: parser/parse_utilcmd.c:5139 #, c-format msgid "every bound following MINVALUE must also be MINVALUE" msgstr "MINVALUEに続く境界値はMINVALUEでなければなりません" -#: parser/parse_utilcmd.c:5186 +#: parser/parse_utilcmd.c:5182 #, c-format msgid "specified value cannot be cast to type %s for column \"%s\"" msgstr "指定した値は列\"%s\"の%s型に変換できません" @@ -23732,9 +23886,9 @@ msgstr "新しいパーティション \"%s\" は、他の新しいパーティ msgid "lower bound of partition \"%s\" is not equal to lower bound of split partition \"%s\"" msgstr "パーティション\"%s\"の下限が、分割対象パーティション\"%s\"の下限と一致していません" -#: partitioning/partbounds.c:5408 partitioning/partbounds.c:5418 partitioning/partbounds.c:5450 partitioning/partbounds.c:5460 partitioning/partbounds.c:5656 partitioning/partbounds.c:5699 +#: partitioning/partbounds.c:5408 partitioning/partbounds.c:5450 partitioning/partbounds.c:5655 partitioning/partbounds.c:5698 #, c-format -msgid "%s require combined bounds of new partitions must exactly match the bound of the split partition." +msgid "%s requires the combined bounds of the new partitions to exactly match the bound of the split partition." msgstr "%s では、新しいパーティションの範囲を結合した結果が、分割対象の範囲と正確に一致している必要があります。" #: partitioning/partbounds.c:5415 @@ -23742,6 +23896,11 @@ msgstr "%s では、新しいパーティションの範囲を結合した結果 msgid "lower bound of partition \"%s\" is less than lower bound of split partition \"%s\"" msgstr "パーティション\"%s\"の下限が、分割対象パーティション\"%s\"の下限よりも小さいです" +#: partitioning/partbounds.c:5418 partitioning/partbounds.c:5460 +#, c-format +msgid "Explicit partition bounds must be contained within the bounds of the split partition when a DEFAULT partition is specified." +msgstr "DEFAULTパーティションを指定する際は、明示的パーティション境界は分割対象パーティションの境界内である必要があります。" + #: partitioning/partbounds.c:5447 #, c-format msgid "upper bound of partition \"%s\" is not equal to upper bound of split partition \"%s\"" @@ -23752,26 +23911,41 @@ msgstr "パーティション\"%s\"の上限が、分割対象パーティショ msgid "upper bound of partition \"%s\" is greater than upper bound of split partition \"%s\"" msgstr "パーティション \"%s\" の上限が分割対象のパーティション \"%s\" の上限よりも大きいです" -#: partitioning/partbounds.c:5528 +#: partitioning/partbounds.c:5527 #, c-format msgid "new partition \"%s\" cannot have this value because split partition \"%s\" does not have it" msgstr "分割対象のパーティション \"%2$s\" がこの値を含まないため、新しいパーティション \"%1$s\" にこの値を含めることはできません" -#: partitioning/partbounds.c:5545 +#: partitioning/partbounds.c:5544 #, c-format msgid "new partition \"%s\" cannot have NULL value because split partition \"%s\" does not have it" msgstr "分割対象のパーティション \"%s\" にはNULLが含まれていないため、新しいパーティション \"%s\" はNULLを含められません" -#: partitioning/partbounds.c:5556 +#: partitioning/partbounds.c:5555 #, c-format msgid "new partition \"%s\" would overlap with another (not split) partition \"%s\"" msgstr "新しいパーティション\"%s\"は、(分割対象ではない)他のパーティション\"%s\"と重複することになります" -#: partitioning/partbounds.c:5653 partitioning/partbounds.c:5696 +#: partitioning/partbounds.c:5652 partitioning/partbounds.c:5695 #, c-format msgid "new partitions' combined partition bounds do not contain value (%s) but split partition \"%s\" does" msgstr "新しいパーティションの結合範囲は値(%s)を含んでいませんが、分割対象パーティション \"%s\" には含まれています" +#: partitioning/partbounds.c:5836 +#, c-format +msgid "cannot split partition \"%s\" only to add a DEFAULT partition" +msgstr "DEFAULT パーティションの追加のみを目的として、パーティション\"%s\"を分割することはできません" + +#: partitioning/partbounds.c:5838 +#, c-format +msgid "The non-DEFAULT partition would keep the same partition bound." +msgstr "非DEFAULTパーティションは同じパーティション境界のままとなります。" + +#: partitioning/partbounds.c:5839 +#, c-format +msgid "Use CREATE TABLE ... PARTITION OF ... DEFAULT to add a DEFAULT partition." +msgstr "CREATE TABLE ... PARTITION OF ... DEFAULT を使用して DEFAULT パーティションを追加してください。" + #: port/pg_sema.c:211 port/pg_shmem.c:719 port/posix_sema.c:211 port/sysv_sema.c:347 port/sysv_shmem.c:719 #, c-format msgid "could not stat data directory \"%s\": %m" @@ -24017,25 +24191,25 @@ msgstr "テーブル\"%s.%s.%s\"に対する自動ANALYZE" msgid "processing work entry for relation \"%s.%s.%s\"" msgstr "リレーション\"%s.%s.%s\"の作業エントリを処理しています" -#: postmaster/autovacuum.c:3519 +#: postmaster/autovacuum.c:3524 #, c-format msgid "autovacuum not started because of misconfiguration" msgstr "誤設定のため自動VACUUMが起動できません" -#: postmaster/autovacuum.c:3520 +#: postmaster/autovacuum.c:3525 #, c-format msgid "Enable the \"track_counts\" option." msgstr "\"track_counts\"オプションを有効にしてください。" -#: postmaster/autovacuum.c:3630 +#: postmaster/autovacuum.c:3635 #, c-format -msgid "\"autovacuum_max_workers\" (%d) should be less than or equal to \"autovacuum_worker_slots\" (%d)" -msgstr "\"autovacuum_max_workers\" (%d) は \"autovacuum_worker_slots\" (%d) 以下でなければなりません" +msgid "\"%s\" (%d) should be less than or equal to \"%s\" (%d)" +msgstr "\"%s\" (%d) は \"%s\" (%d) 以下でなければなりません" -#: postmaster/autovacuum.c:3632 +#: postmaster/autovacuum.c:3638 #, c-format -msgid "The server will only start up to \"autovacuum_worker_slots\" (%d) autovacuum workers at a given time." -msgstr "このサーバーは、同時に最大 \"autovacuum_worker_slots\" (%d) プロセスの自動バキュームワーカーを起動します。" +msgid "The server will only start up to \"%s\" (%d) autovacuum workers at a given time." +msgstr "このサーバーは、同時に最大 \"%s\" (%d) プロセスまでの自動VACUUMワーカーしか起動しません。" #: postmaster/bgworker.c:286 #, c-format @@ -24130,142 +24304,142 @@ msgstr "チェックポイント要求が失敗しました" msgid "Consult recent messages in the server log for details." msgstr "詳細はサーバーログの最近のメッセージを調査してください" -#: postmaster/datachecksum_state.c:497 +#: postmaster/datachecksum_state.c:531 #, c-format msgid "incorrect data checksum state %i for target state %i" msgstr "目標状態 %2$i に対してデータチェックサム状態 %1$i は不正です" -#: postmaster/datachecksum_state.c:517 postmaster/datachecksum_state.c:539 +#: postmaster/datachecksum_state.c:551 postmaster/datachecksum_state.c:573 #, c-format msgid "must be superuser to change data checksum state" msgstr "データチェックサムの状態を変更するにはスーパーユーザーである必要があります" -#: postmaster/datachecksum_state.c:544 +#: postmaster/datachecksum_state.c:578 #, c-format msgid "cost delay cannot be a negative value" msgstr "コストディレイに負の値は指定できません" -#: postmaster/datachecksum_state.c:549 +#: postmaster/datachecksum_state.c:583 #, c-format msgid "cost limit must be greater than zero" msgstr "コストディレイには0より大きい値を指定する必要があります" -#: postmaster/datachecksum_state.c:617 +#: postmaster/datachecksum_state.c:651 #, c-format msgid "data checksums already in desired state, exiting" msgstr "データチェックサムはすでに目標の状態です、終了します" -#: postmaster/datachecksum_state.c:638 +#: postmaster/datachecksum_state.c:672 #, c-format msgid "failed to start background worker to process data checksums" msgstr "データチェックサム処理を行うバックグラウンドワーカーを起動できませんでした" -#: postmaster/datachecksum_state.c:643 +#: postmaster/datachecksum_state.c:677 #, c-format msgid "data checksum processing already running" msgstr "データチェックサム処理はすでに実行中です" -#: postmaster/datachecksum_state.c:830 postmaster/datachecksum_state.c:856 +#: postmaster/datachecksum_state.c:871 postmaster/datachecksum_state.c:895 #, c-format msgid "could not start background worker for enabling data checksums in database \"%s\"" msgstr "データベース\"%s\"で、データチェックサムを有効化するバックグランドワーカーを起動できませんでした" -#: postmaster/datachecksum_state.c:832 +#: postmaster/datachecksum_state.c:873 #, c-format msgid "The \"%s\" setting might be too low." msgstr "\"%s\"の設定値が低すぎる可能性があります" -#: postmaster/datachecksum_state.c:858 +#: postmaster/datachecksum_state.c:897 #, c-format msgid "More details on the error might be found in the server log." msgstr "このエラーのより詳細な情報がサーバーログにあるかもしれません。" -#: postmaster/datachecksum_state.c:880 +#: postmaster/datachecksum_state.c:919 #, c-format msgid "cannot enable data checksums without the postmaster process" msgstr "postmasterプロセスなしではデータチェックサムの有効化はできません" -#: postmaster/datachecksum_state.c:881 postmaster/datachecksum_state.c:903 +#: postmaster/datachecksum_state.c:920 postmaster/datachecksum_state.c:943 #, c-format msgid "Restart the database and restart data checksum processing by calling pg_enable_data_checksums()." msgstr "データベースを再起動したのち、pg_enable_data_checksums()を呼び出してデータチェックサム処理を再実行してください。" -#: postmaster/datachecksum_state.c:885 +#: postmaster/datachecksum_state.c:924 #, c-format msgid "initiating data checksum processing in database \"%s\"" msgstr "データベース\"%s\"で、データチェックサム処理を開始します" -#: postmaster/datachecksum_state.c:901 +#: postmaster/datachecksum_state.c:941 #, c-format msgid "postmaster exited during data checksum processing in \"%s\"" msgstr "\"%s\"でデータチェックサム処理中に、postmasterが終了しました" -#: postmaster/datachecksum_state.c:908 +#: postmaster/datachecksum_state.c:953 #, c-format msgid "data checksums processing was aborted in database \"%s\"" msgstr "\"%s\"でデータチェックサム処理中に、postmasterが終了しました" -#: postmaster/datachecksum_state.c:941 +#: postmaster/datachecksum_state.c:980 #, c-format msgid "data checksums launcher exiting while worker is still running, signalling worker" msgstr "ワーカーの実行中にデータチェックサムランチャーが終了しました、ワーカーにシグナルを送ります" -#: postmaster/datachecksum_state.c:1032 +#: postmaster/datachecksum_state.c:1070 #, c-format msgid "postmaster exited during data checksums processing" msgstr "データチェックサム処理中に、postmasterが終了しました" -#: postmaster/datachecksum_state.c:1033 +#: postmaster/datachecksum_state.c:1071 #, c-format msgid "Data checksums processing must be restarted manually after cluster restart." msgstr "データチェックサム処理はクラスタの再起動後に手動で再実行する必要があります。" -#: postmaster/datachecksum_state.c:1059 +#: postmaster/datachecksum_state.c:1097 #, c-format msgid "background worker \"datachecksums launcher\" started" msgstr "バックグラウンドワーカー \"datachecksums launcher\" が起動しました" -#: postmaster/datachecksum_state.c:1078 +#: postmaster/datachecksum_state.c:1116 #, c-format msgid "background worker \"datachecksums launcher\" already running, exiting" msgstr "バックグラウンドワーカー \"datachecksums launcher\" はすでに実行中です、終了します" -#: postmaster/datachecksum_state.c:1118 +#: postmaster/datachecksum_state.c:1156 #, c-format msgid "enabling data checksums requested, starting data checksum calculation" msgstr "データチェックサム有効化が要求されました、データチェックサムの計算を開始します" -#: postmaster/datachecksum_state.c:1146 +#: postmaster/datachecksum_state.c:1180 #, c-format msgid "unable to enable data checksums in cluster" msgstr "クラスタでデータチェックサムを有効化できませんでした" -#: postmaster/datachecksum_state.c:1156 +#: postmaster/datachecksum_state.c:1190 #, c-format msgid "data checksums are now enabled" msgstr "データチェックサムが有効になりました" -#: postmaster/datachecksum_state.c:1161 +#: postmaster/datachecksum_state.c:1195 #, c-format msgid "disabling data checksums requested" msgstr "データチェックサムの無効化が要求されました" -#: postmaster/datachecksum_state.c:1167 +#: postmaster/datachecksum_state.c:1201 #, c-format msgid "data checksums are now disabled" msgstr "データチェックサムが無効になりました" -#: postmaster/datachecksum_state.c:1285 +#: postmaster/datachecksum_state.c:1319 #, c-format msgid "data checksums failed to get enabled in all databases, aborting" msgstr "一部のデータベースでデータチェックサムを有効にできませんでした、中断します" -#: postmaster/datachecksum_state.c:1286 +#: postmaster/datachecksum_state.c:1320 #, c-format msgid "The server log might have more information on the cause of the error." msgstr "サーバーログにこのエラーの原因についての詳細な情報があるかもしれません。" -#: postmaster/datachecksum_state.c:1641 postmaster/datachecksum_state.c:1713 +#: postmaster/datachecksum_state.c:1701 postmaster/datachecksum_state.c:1774 #, c-format msgid "data checksum processing aborted in database OID %u" msgstr "データベース OID %u で、データチェックサム処理が中断されました" @@ -24511,7 +24685,7 @@ msgid "%s: could not write external PID file \"%s\": %m\n" msgstr "%s: 外部PIDファイル\"%s\"に書き込めませんでした: %m\n" #. translator: %s is a configuration file -#: postmaster/postmaster.c:1351 utils/init/postinit.c:234 +#: postmaster/postmaster.c:1351 utils/init/postinit.c:240 #, c-format msgid "could not load %s" msgstr "%s\"をロードできませんでした" @@ -24770,52 +24944,52 @@ msgstr "子プロセスの終了コードの読み込みができませんでし msgid "could not post child completion status\n" msgstr "個プロセスの終了コードを投稿できませんでした\n" -#: postmaster/syslogger.c:527 postmaster/syslogger.c:1172 +#: postmaster/syslogger.c:546 postmaster/syslogger.c:1191 #, c-format msgid "could not read from logger pipe: %m" msgstr "ロガーパイプから読み取れませんでした: %m" -#: postmaster/syslogger.c:626 postmaster/syslogger.c:640 +#: postmaster/syslogger.c:645 postmaster/syslogger.c:659 #, c-format msgid "could not create pipe for syslog: %m" msgstr "syslog用のパイプを作成できませんでした: %m" -#: postmaster/syslogger.c:711 +#: postmaster/syslogger.c:730 #, c-format msgid "could not fork system logger: %m" msgstr "システムロガーをforkできませんでした: %m" -#: postmaster/syslogger.c:730 +#: postmaster/syslogger.c:749 #, c-format msgid "redirecting log output to logging collector process" msgstr "ログ出力をログ収集プロセスにリダイレクトしています" -#: postmaster/syslogger.c:731 +#: postmaster/syslogger.c:750 #, c-format msgid "Future log output will appear in directory \"%s\"." msgstr "ここからのログ出力はディレクトリ\"%s\"に現れます。" -#: postmaster/syslogger.c:739 +#: postmaster/syslogger.c:758 #, c-format msgid "could not redirect stdout: %m" msgstr "標準出力にリダイレクトできませんでした: %m" -#: postmaster/syslogger.c:744 postmaster/syslogger.c:761 +#: postmaster/syslogger.c:763 postmaster/syslogger.c:780 #, c-format msgid "could not redirect stderr: %m" msgstr "標準エラー出力にリダイレクトできませんでした: %m" -#: postmaster/syslogger.c:1127 +#: postmaster/syslogger.c:1146 #, c-format msgid "could not write to log file: %m\n" msgstr "ログファイルに書き込めませんでした: %m\n" -#: postmaster/syslogger.c:1247 +#: postmaster/syslogger.c:1266 #, c-format msgid "could not open log file \"%s\": %m" msgstr "ロックファイル\"%s\"をオープンできませんでした: %m" -#: postmaster/syslogger.c:1337 +#: postmaster/syslogger.c:1356 #, c-format msgid "disabling automatic rotation (use SIGHUP to re-enable)" msgstr "自動ローテーションを無効にしています(再度有効にするにはSIGHUPを使用してください)" @@ -24875,17 +25049,17 @@ msgstr "タイムライン%uは不正です" msgid "invalid streaming start location" msgstr "不正なストリーミング開始位置" -#: replication/libpqwalreceiver/libpqwalreceiver.c:243 replication/libpqwalreceiver/libpqwalreceiver.c:338 +#: replication/libpqwalreceiver/libpqwalreceiver.c:246 replication/libpqwalreceiver/libpqwalreceiver.c:338 #, c-format msgid "password is required" msgstr "パスワードが必要です" -#: replication/libpqwalreceiver/libpqwalreceiver.c:244 +#: replication/libpqwalreceiver/libpqwalreceiver.c:247 #, c-format msgid "Non-superuser cannot connect if the server does not request a password." msgstr "非スーパーユーザーはサーバーがパスワードを要求してこない場合は接続できません。" -#: replication/libpqwalreceiver/libpqwalreceiver.c:245 +#: replication/libpqwalreceiver/libpqwalreceiver.c:248 #, c-format msgid "Target server's authentication method must be changed, or set password_required=false in the subscription parameters." msgstr "接続先サーバーの認証方式を変更するか、サブスクリプション属性でpassword_requiredをfalseに設定する必要があります。" @@ -24915,7 +25089,7 @@ msgstr "接続文字列をパースできませんでした: %s" msgid "could not receive database system identifier and timeline ID from the primary server: %s" msgstr "プライマリサーバーからデータベースシステムの識別子とタイムライン ID を受信できませんでした: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:450 replication/libpqwalreceiver/libpqwalreceiver.c:745 +#: replication/libpqwalreceiver/libpqwalreceiver.c:450 replication/libpqwalreceiver/libpqwalreceiver.c:764 #, c-format msgid "invalid response from primary server" msgstr "プライマリサーバーからの応答が不正です" @@ -24925,86 +25099,86 @@ msgstr "プライマリサーバーからの応答が不正です" msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." msgstr "システムを識別できませんでした: 受信したのは%d行で%d列、期待していたのは%d行で%d以上の列でした。" -#: replication/libpqwalreceiver/libpqwalreceiver.c:591 replication/libpqwalreceiver/libpqwalreceiver.c:598 replication/libpqwalreceiver/libpqwalreceiver.c:628 +#: replication/libpqwalreceiver/libpqwalreceiver.c:647 #, c-format msgid "could not start WAL streaming: %s" msgstr "WAL ストリーミングを開始できませんでした: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:651 +#: replication/libpqwalreceiver/libpqwalreceiver.c:670 #, c-format msgid "could not send end-of-streaming message to primary: %s" msgstr "プライマリにストリーミングの終了メッセージを送信できませんでした: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:675 +#: replication/libpqwalreceiver/libpqwalreceiver.c:694 #, c-format msgid "unexpected result set after end-of-streaming" msgstr "ストリーミングの終了後の想定外の結果セット" -#: replication/libpqwalreceiver/libpqwalreceiver.c:691 +#: replication/libpqwalreceiver/libpqwalreceiver.c:710 #, c-format msgid "error while shutting down streaming COPY: %s" msgstr "ストリーミングCOPY終了中のエラー: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:702 +#: replication/libpqwalreceiver/libpqwalreceiver.c:721 #, c-format msgid "error reading result of streaming command: %s" msgstr "ストリーミングコマンドの結果読み取り中のエラー: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:712 replication/libpqwalreceiver/libpqwalreceiver.c:839 +#: replication/libpqwalreceiver/libpqwalreceiver.c:731 replication/libpqwalreceiver/libpqwalreceiver.c:858 #, c-format msgid "unexpected result after CommandComplete: %s" msgstr "CommandComplete後の想定外の結果: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:739 +#: replication/libpqwalreceiver/libpqwalreceiver.c:758 #, c-format msgid "could not receive timeline history file from the primary server: %s" msgstr "プライマリサーバーからタイムライン履歴ファイルを受信できませんでした: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:746 +#: replication/libpqwalreceiver/libpqwalreceiver.c:765 #, c-format msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." msgstr "2個のフィールドを持つ1個のタプルを期待していましたが、%2$d 個のフィールドを持つ %1$d 個のタプルを受信しました。" -#: replication/libpqwalreceiver/libpqwalreceiver.c:800 replication/libpqwalreceiver/libpqwalreceiver.c:853 replication/libpqwalreceiver/libpqwalreceiver.c:859 +#: replication/libpqwalreceiver/libpqwalreceiver.c:819 replication/libpqwalreceiver/libpqwalreceiver.c:872 replication/libpqwalreceiver/libpqwalreceiver.c:878 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "WAL ストリームからデータを受信できませんでした: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:879 +#: replication/libpqwalreceiver/libpqwalreceiver.c:898 #, c-format msgid "could not send data to WAL stream: %s" msgstr "WAL ストリームにデータを送信できませんでした: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:980 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1000 #, c-format msgid "could not create replication slot \"%s\": %s" msgstr "レプリケーションスロット\"%s\"を作成できませんでした: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1031 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1052 #, c-format msgid "could not alter replication slot \"%s\": %s" msgstr "レプリケーションスロット\"%s\"を変更できませんでした: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1065 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1086 #, c-format msgid "invalid query response" msgstr "不正な問い合わせ応答" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1066 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1087 #, c-format msgid "Expected %d fields, got %d fields." msgstr "%d個の列を期待していましたが、%d列を受信しました。" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1137 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1158 #, c-format msgid "the query interface requires a database connection" msgstr "クエリインタフェースの動作にはデータベースコネクションが必要です" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1171 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1192 msgid "empty query" msgstr "空の問い合わせ" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1177 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1198 msgid "unexpected pipeline mode" msgstr "想定されていないパイプラインモード" @@ -25042,187 +25216,202 @@ msgstr "共有メモリキューにデータを送出できませんでした" msgid "logical replication apply worker will serialize the remaining changes of remote transaction %u to a file" msgstr "論理レプリケーションt起用ワーカーはリモートトランザクション%uの残りの変更をシリアライズしてファイルに格納します" -#: replication/logical/conflict.c:128 +#: replication/logical/conflict.c:198 +#, c-format +msgid "created conflict log table \"%s\" for subscription \"%s\"" +msgstr "サブスクリプション\"%2$s\"に対する競合ログテーブル\"%1$s\"を作成しました" + +#: replication/logical/conflict.c:225 +#, c-format +msgid "unrecognized conflict_log_destination value: \"%s\"" +msgstr "識別できない conflict_log_destination の値: \"%s\"" + +#: replication/logical/conflict.c:226 +#, c-format +msgid "Valid values are \"log\", \"table\", and \"all\"." +msgstr "有効な値の範囲は\"log\"、\"table\"または\"all\"です。" + +#: replication/logical/conflict.c:300 #, c-format msgid "conflict detected on relation \"%s.%s\": conflict=%s" msgstr "リレーション\"%s.%s\"で衝突が検出されました: conflict=%s" -#: replication/logical/conflict.c:271 +#: replication/logical/conflict.c:443 #, c-format msgid "Could not apply remote change: %s.\n" msgstr "リモートの更新が適用できませんでした: %s。\n" -#: replication/logical/conflict.c:274 +#: replication/logical/conflict.c:446 msgid "Could not apply remote change.\n" msgstr "リモートの更新が適用できませんでした。\n" -#: replication/logical/conflict.c:288 +#: replication/logical/conflict.c:460 #, c-format msgid "Key already exists in unique index \"%s\", modified locally in transaction %u at %s: %s." msgstr "ユニークインデックス\"%1$s\"にすでにキーが存在しており、%3$sにトランザクション%2$uでローカル更新されています: %4$s。" -#: replication/logical/conflict.c:293 +#: replication/logical/conflict.c:465 #, c-format msgid "Key already exists in unique index \"%s\", modified locally in transaction %u at %s." msgstr "ユニークインデックス\"%1$s\"にすでにキーが存在しており、%3$sにトランザクション%2$uでローカルで更新されています。" -#: replication/logical/conflict.c:300 +#: replication/logical/conflict.c:472 #, c-format msgid "Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s: %s." msgstr "ユニークインデックス\"%1$s\"にすでにキーが存在しており、%4$sに起源\"%2$s\"によってトランザクション%3$uで更新されています: %5$s。" -#: replication/logical/conflict.c:305 +#: replication/logical/conflict.c:477 #, c-format msgid "Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s." msgstr "ユニークインデックス\"%1$s\"にすでにキーが存在しており、%4$sに起源\"%2$s\"によってトランザクション%3$uで更新されています。" -#: replication/logical/conflict.c:320 +#: replication/logical/conflict.c:492 #, c-format msgid "Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s: %s." msgstr "ユニークインデックス\"%1$s\"にすでにキーが存在しており、%3$sに存在しない起源によってトランザクション%2$uで更新されています: %4$s。" -#: replication/logical/conflict.c:325 +#: replication/logical/conflict.c:497 #, c-format msgid "Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s." msgstr "ユニークインデックス\"%1$s\"にすでにキーが存在しており、%3$sに存在しない起源によってトランザクション%2$uで更新されています。" -#: replication/logical/conflict.c:333 +#: replication/logical/conflict.c:505 #, c-format msgid "Key already exists in unique index \"%s\", modified in transaction %u: %s." msgstr "ユニークインデックス\"%s\"にすでにキーが存在しており、トランザクション%uで更新されています: %s。" -#: replication/logical/conflict.c:337 +#: replication/logical/conflict.c:509 #, c-format msgid "Key already exists in unique index \"%s\", modified in transaction %u." msgstr "ユニークインデックス\"%s\"にすでにキーが存在しており、トランザクション%uで更新されています。" -#: replication/logical/conflict.c:351 +#: replication/logical/conflict.c:523 #, c-format msgid "Updating the row that was modified locally in transaction %u at %s: %s." msgstr "%2$sに、トランザクション%1$uでローカル更新された行を更新中: %3$s。" -#: replication/logical/conflict.c:355 +#: replication/logical/conflict.c:527 #, c-format msgid "Updating the row that was modified locally in transaction %u at %s." msgstr "%2$sに、トランザクション%1$uでローカル更新された行を更新中。" -#: replication/logical/conflict.c:361 +#: replication/logical/conflict.c:533 #, c-format msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s: %s." msgstr "%3$sに、異なる起源”%1$s\"によってトランザクション%2$uで更新された行を更新中: %4$s。" -#: replication/logical/conflict.c:366 +#: replication/logical/conflict.c:538 #, c-format msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s." msgstr "%3$sに、異なる起源”%1$s\"によってトランザクション%2$uで更新された行を更新中。" -#: replication/logical/conflict.c:375 +#: replication/logical/conflict.c:547 #, c-format msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s: %s." msgstr "%2$sに、存在しない起源によってトランザクション%1$uで更新された行を更新中: %3$s。" -#: replication/logical/conflict.c:379 +#: replication/logical/conflict.c:551 #, c-format msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s." msgstr "%2$sに、存在しない起源によってトランザクション%1$uで更新された行の更新中。" -#: replication/logical/conflict.c:390 +#: replication/logical/conflict.c:562 #, c-format msgid "Could not find the row to be updated: %s.\n" msgstr "更新すべき行が見つかりませんでした: %s。\n" -#: replication/logical/conflict.c:393 +#: replication/logical/conflict.c:565 msgid "Could not find the row to be updated.\n" msgstr "更新すべき行が見つかりませんでした。\n" -#: replication/logical/conflict.c:398 +#: replication/logical/conflict.c:570 #, c-format msgid "The row to be updated was deleted locally in transaction %u at %s" msgstr "更新しようとした行は %2$s に、このノード自身によってトランザクション %1$u 内で削除されています" -#: replication/logical/conflict.c:401 +#: replication/logical/conflict.c:573 #, c-format msgid "The row to be updated was deleted by a different origin \"%s\" in transaction %u at %s" msgstr "更新しようとした行は %3$s に、異なる起源\"%1$s\"によってトランザクション %2$u 内で削除されています" -#: replication/logical/conflict.c:406 +#: replication/logical/conflict.c:578 #, c-format msgid "The row to be updated was deleted by a non-existent origin in transaction %u at %s" msgstr "更新しようとした行は %2$s に、存在しない起源によってトランザクション %1$u 内で削除されています" -#: replication/logical/conflict.c:410 +#: replication/logical/conflict.c:582 msgid "The row to be updated was deleted" msgstr "更新しようとした行は削除されています" -#: replication/logical/conflict.c:419 +#: replication/logical/conflict.c:591 #, c-format msgid "Could not find the row to be updated: %s." msgstr "更新すべき行が見つかりませんでした: %s。" -#: replication/logical/conflict.c:422 +#: replication/logical/conflict.c:594 msgid "Could not find the row to be updated." msgstr "更新すべき行が見つかりませんでした。" -#: replication/logical/conflict.c:434 +#: replication/logical/conflict.c:606 #, c-format msgid "Deleting the row that was modified locally in transaction %u at %s: %s." msgstr "%2$sに、トランザクション%1$uでローカル更新された行を削除中: %3$s。" -#: replication/logical/conflict.c:438 +#: replication/logical/conflict.c:610 #, c-format msgid "Deleting the row that was modified locally in transaction %u at %s." msgstr "%2$sに、トランザクション%1$uでローカルに更新された行を削除中。" -#: replication/logical/conflict.c:444 +#: replication/logical/conflict.c:616 #, c-format msgid "Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s: %s." msgstr "%3$sに、異なる起源\"%1$s\"によってトランザクション%2$uで更新された行を削除中: %4$s。" -#: replication/logical/conflict.c:449 +#: replication/logical/conflict.c:621 #, c-format msgid "Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s." msgstr "%3$sに、異なる起源\"%1$s\"によってトランザクション%2$uで更新された行を削除中。" -#: replication/logical/conflict.c:458 +#: replication/logical/conflict.c:630 #, c-format msgid "Deleting the row that was modified by a non-existent origin in transaction %u at %s: %s." msgstr "%2$sに、存在しない起源によってトランザクション%1$uで更新された行の削除中: %3$s。" -#: replication/logical/conflict.c:462 +#: replication/logical/conflict.c:634 #, c-format msgid "Deleting the row that was modified by a non-existent origin in transaction %u at %s." msgstr "%2$sに、存在しない起源によってトランザクション%1$uで更新された行の削除中。" -#: replication/logical/conflict.c:473 +#: replication/logical/conflict.c:645 #, c-format msgid "Could not find the row to be deleted: %s." msgstr "削除すべき行が見つかりませんでした: %s。" -#: replication/logical/conflict.c:476 +#: replication/logical/conflict.c:648 msgid "Could not find the row to be deleted." msgstr "削除すべき行が見つかりませんでした。" -#: replication/logical/conflict.c:529 +#: replication/logical/conflict.c:701 #, c-format msgid "key %s" msgstr "キー %s" -#: replication/logical/conflict.c:542 +#: replication/logical/conflict.c:714 #, c-format msgid "local row %s" msgstr "ローカル行 %s" -#: replication/logical/conflict.c:563 +#: replication/logical/conflict.c:735 #, c-format msgid "remote row %s" msgstr "リモート行 %s" -#: replication/logical/conflict.c:592 +#: replication/logical/conflict.c:764 #, c-format msgid "replica identity %s" msgstr "複製識別 %s" -#: replication/logical/conflict.c:594 +#: replication/logical/conflict.c:766 #, c-format msgid "replica identity full %s" msgstr "全列複製識別 %s" @@ -25247,7 +25436,7 @@ msgstr "論理レプリケーションワーカースロット%dが空いてい msgid "logical replication worker slot %d is already used by another worker, cannot attach" msgstr "論理レプリケーションワーカースロット%dが既に他のワーカーに使用されているため接続できません" -#: replication/logical/launcher.c:1575 +#: replication/logical/launcher.c:1576 #, c-format msgid "creating replication conflict detection slot" msgstr "レプリケーション衝突検出用スロットを作成しています" @@ -25267,77 +25456,77 @@ msgstr "スタンバイ上で論理デコードを行うためにはプライマ msgid "Set \"wal_level\" >= \"logical\" or create at least one logical slot when \"wal_level\" = \"replica\"." msgstr "\"wal_level\" >= \"logical\" と設定するか、\"wal_level\" = \"replica\"の際は少なくとも一つの論理スロットを作成してください。" -#: replication/logical/logical.c:361 replication/logical/logical.c:517 +#: replication/logical/logical.c:358 replication/logical/logical.c:514 #, c-format msgid "cannot use physical replication slot for logical decoding" msgstr "物理レプリケーションスロットを論理デコードに使用するとはできません" -#: replication/logical/logical.c:366 replication/logical/logical.c:527 +#: replication/logical/logical.c:363 replication/logical/logical.c:524 #, c-format msgid "replication slot \"%s\" was not created in this database" msgstr "レプリケーションスロット\"%s\"はこのデータベースでは作成されていません" -#: replication/logical/logical.c:373 +#: replication/logical/logical.c:370 #, c-format msgid "cannot create logical replication slot in transaction that has performed writes" msgstr "論理レプリケーションスロットは書き込みを行ったトランザクションの中で生成することはできません" -#: replication/logical/logical.c:538 +#: replication/logical/logical.c:535 #, c-format msgid "cannot use replication slot \"%s\" for logical decoding" msgstr "レプリケーションスロット\"%s\"は論理デコードには使用できません" -#: replication/logical/logical.c:540 replication/slot.c:936 replication/slot.c:986 +#: replication/logical/logical.c:537 replication/slot.c:927 replication/slot.c:972 #, c-format msgid "This replication slot is being synchronized from the primary server." msgstr "このレプリケーションスロットはプライマリサーバーからの同期中です。" -#: replication/logical/logical.c:541 +#: replication/logical/logical.c:538 #, c-format msgid "Specify another replication slot." msgstr "他のレプリケーションスロットを指定してください。" -#: replication/logical/logical.c:607 +#: replication/logical/logical.c:604 #, c-format msgid "starting logical decoding for slot \"%s\"" msgstr "スロット\"%s\"の論理デコードを開始します" -#: replication/logical/logical.c:609 +#: replication/logical/logical.c:606 #, c-format msgid "Streaming transactions committing after %X/%08X, reading WAL from %X/%08X." msgstr "%3$X/%4$08XからWALを読み取って、%1$X/%2$08X以降にコミットされるトランザクションをストリーミングします。" -#: replication/logical/logical.c:757 +#: replication/logical/logical.c:754 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%08X" msgstr "スロット\"%s\", 出力プラグイン\"%s\", %sコールバックの処理中, 関連LSN %X/%08X" -#: replication/logical/logical.c:763 +#: replication/logical/logical.c:760 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback" msgstr "スロット\"%s\", 出力プラグイン\"%s\", %sコールバックの処理中" -#: replication/logical/logical.c:934 replication/logical/logical.c:979 replication/logical/logical.c:1024 replication/logical/logical.c:1070 +#: replication/logical/logical.c:931 replication/logical/logical.c:976 replication/logical/logical.c:1021 replication/logical/logical.c:1067 #, c-format msgid "logical replication at prepare time requires a %s callback" msgstr "プリペア時の論理レプリケーションを行うには%sコールバックが必要です" -#: replication/logical/logical.c:1302 replication/logical/logical.c:1351 replication/logical/logical.c:1392 replication/logical/logical.c:1478 replication/logical/logical.c:1527 +#: replication/logical/logical.c:1299 replication/logical/logical.c:1348 replication/logical/logical.c:1389 replication/logical/logical.c:1475 replication/logical/logical.c:1524 #, c-format msgid "logical streaming requires a %s callback" msgstr "論理ストリーミングを行うには%sコールバックが必要です" -#: replication/logical/logical.c:1437 +#: replication/logical/logical.c:1434 #, c-format msgid "logical streaming at prepare time requires a %s callback" msgstr "プリペア時の論理ストリーミングを行うには%sコールバックが必要です" -#: replication/logical/logicalctl.c:421 +#: replication/logical/logicalctl.c:413 #, c-format msgid "logical decoding is enabled upon creating a new logical replication slot" msgstr "論理デコードは新しいレプリケーションスロットの作成時に有効化されます" -#: replication/logical/logicalctl.c:530 +#: replication/logical/logicalctl.c:537 #, c-format msgid "logical decoding is disabled because there are no valid logical replication slots" msgstr "有効な論理レプリケーションスロットが存在しないため、論理デコードが無効化されます" @@ -25502,87 +25691,93 @@ msgstr "レプリケーション起源名\"%s\"は予約されています" msgid "Origin names \"%s\", \"%s\", and names starting with \"pg_\" are reserved." msgstr "\"%s\"、\"%s\"、および\"pg_\"で始まる起源名は予約されています。" -#: replication/logical/relation.c:275 +#: replication/logical/relation.c:274 #, c-format msgid "logical replication target relation \"%s.%s\" is missing replicated column: %s" msgid_plural "logical replication target relation \"%s.%s\" is missing replicated columns: %s" msgstr[0] "論理レプリケーション先のリレーション\"%s.%s\"は複製された列を失っています: %s" -#: replication/logical/relation.c:286 +#: replication/logical/relation.c:285 #, c-format msgid "logical replication target relation \"%s.%s\" has incompatible generated column: %s" msgid_plural "logical replication target relation \"%s.%s\" has incompatible generated columns: %s" msgstr[0] "論理レプリケーション先のリレーション\"%s.%s\"に非互換の生成列が存在します: %s" -#: replication/logical/relation.c:341 +#: replication/logical/relation.c:340 #, c-format msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" msgstr "論理レプリケーションのターゲットリレーション\"%s.%s\"がREPLICA IDENTITYインデックスでシステム列を使用しています" -#: replication/logical/relation.c:434 +#: replication/logical/relation.c:433 #, c-format msgid "logical replication target relation \"%s.%s\" does not exist" msgstr "論理レプリケーション先のリレーション\"%s.%s\"は存在しません" -#: replication/logical/reorderbuffer.c:4284 +#: replication/logical/reorderbuffer.c:4282 #, c-format msgid "could not write to data file for XID %u: %m" msgstr "XID%uのためのデータファイルの書き出しに失敗しました: %m" -#: replication/logical/reorderbuffer.c:4630 replication/logical/reorderbuffer.c:4655 +#: replication/logical/reorderbuffer.c:4628 replication/logical/reorderbuffer.c:4653 #, c-format msgid "could not read from reorderbuffer spill file: %m" msgstr "並べ替えバッファのあふれファイルの読み込みに失敗しました: %m" -#: replication/logical/reorderbuffer.c:4634 replication/logical/reorderbuffer.c:4659 +#: replication/logical/reorderbuffer.c:4632 replication/logical/reorderbuffer.c:4657 #, c-format msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" msgstr "並べ替えバッファのあふれファイルの読み込みに失敗しました: %2$uバイトのはずが%1$dバイトでした" -#: replication/logical/reorderbuffer.c:4908 +#: replication/logical/reorderbuffer.c:4906 #, c-format msgid "could not remove file \"%s\" during removal of %s/%s/xid*: %m" msgstr "%2$s/%3$s/xid* の削除中にファイル\"%1$s\"が削除できませんでした: %4$m" -#: replication/logical/reorderbuffer.c:5401 +#: replication/logical/reorderbuffer.c:5399 #, c-format msgid "could not read from file \"%s\": read %d instead of %d bytes" msgstr "ファイル\"%1$s\"の読み込みに失敗しました: %3$dバイトのはずが%2$dバイトでした" -#: replication/logical/sequencesync.c:190 +#: replication/logical/sequencesync.c:195 #, c-format msgid "mismatched or renamed sequence on subscriber (%s)" msgid_plural "mismatched or renamed sequences on subscriber (%s)" msgstr[0] "サブスクライバ (%s) 上の、定義が一致しない、または名前が変更されたシーケンス" -#: replication/logical/sequencesync.c:201 +#: replication/logical/sequencesync.c:206 +#, c-format +msgid "insufficient privileges on subscriber sequence (%s)" +msgid_plural "insufficient privileges on subscriber sequences (%s)" +msgstr[0] "購読側のシーケンス(%s)に対する権限不足" + +#: replication/logical/sequencesync.c:217 #, c-format -msgid "insufficient privileges on sequence (%s)" -msgid_plural "insufficient privileges on sequences (%s)" -msgstr[0] "シーケンス(%s)に対する権限不足" +msgid "insufficient privileges on publisher sequence (%s)" +msgid_plural "insufficient privileges on publisher sequences (%s)" +msgstr[0] "発行側のシーケンス(%s)に対する権限不足" -#: replication/logical/sequencesync.c:212 +#: replication/logical/sequencesync.c:228 #, c-format msgid "missing sequence on publisher (%s)" msgid_plural "missing sequences on publisher (%s)" msgstr[0] "パブリッシャ上に存在しないシーケンス (%s)" -#: replication/logical/sequencesync.c:220 +#: replication/logical/sequencesync.c:236 #, c-format msgid "logical replication sequence synchronization failed for subscription \"%s\"" msgstr "論理レプリケーションにおいて、サブスクリプション\"%s\"に対するシーケンス同期が失敗しました" -#: replication/logical/sequencesync.c:488 +#: replication/logical/sequencesync.c:514 #, c-format msgid "could not fetch sequence information from the publisher: %s" msgstr "シーケンス情報をパブリッシャから取得できませんでした: %s" -#: replication/logical/sequencesync.c:559 +#: replication/logical/sequencesync.c:597 #, c-format msgid "skip synchronization of sequence \"%s.%s\" because it has been dropped concurrently" msgstr "並行して削除されたため,シーケンス \"%s.%s\" の同期はスキップします" -#: replication/logical/sequencesync.c:720 +#: replication/logical/sequencesync.c:759 #, c-format msgid "sequencesync worker for subscription \"%s\" could not connect to the publisher: %s" msgstr "サブスクリプション\"%s\"のシーケンス同期ワーカーが、パブリッシャに接続できませんでした: %s" @@ -25607,43 +25802,43 @@ msgstr "リモートスロットでは LSN %X/%08X のWALとカタログxmin %u msgid "Synchronization could lead to data loss, because the standby could not build a consistent snapshot to decode WALs at LSN %X/%08X." msgstr "スタンバイがLSN %X/%08XのWALをデコードするために必要な一貫性のあるスナップショットを作成できないため、同期によってデータが失われる可能性があります。" -#: replication/logical/slotsync.c:577 +#: replication/logical/slotsync.c:591 #, c-format msgid "dropped replication slot \"%s\" of database with OID %u" msgstr "OID %2$uのデータベースのレプリケーションスロット\"%1$s\"を削除しました" -#: replication/logical/slotsync.c:705 +#: replication/logical/slotsync.c:723 #, c-format msgid "newly created replication slot \"%s\" is sync-ready now" msgstr "新規に作成したレプリケーションスロット\"%s\"が同期可能になりました" -#: replication/logical/slotsync.c:747 +#: replication/logical/slotsync.c:765 #, c-format msgid "exiting from slot synchronization because same name slot \"%s\" already exists on the standby" msgstr "スタンバイに同名のスロット\"%s\"がすでに存在するため、スロット同期を終了しました" -#: replication/logical/slotsync.c:940 +#: replication/logical/slotsync.c:958 #, c-format msgid "could not fetch failover logical slots info from the primary server: %s" msgstr "プライマリサーバーからフェイルオーバー属性を持つ論理スロットを取得できませんでした: %s" -#: replication/logical/slotsync.c:1104 +#: replication/logical/slotsync.c:1123 #, c-format msgid "could not fetch primary slot name \"%s\" info from the primary server: %s" msgstr "プライマリサーバーからプライマリのスロット名\"%s\"の情報を取得できませんでした: %s" -#: replication/logical/slotsync.c:1106 +#: replication/logical/slotsync.c:1125 #, c-format msgid "Check if \"primary_slot_name\" is configured correctly." msgstr "\"primary_slot_name\"が正しく設定されているか確認してください。" -#: replication/logical/slotsync.c:1126 +#: replication/logical/slotsync.c:1145 #, c-format msgid "cannot synchronize replication slots from a standby server" msgstr "スタンバイサーバーからのリプリケーションスロットの同期ができませんでした" #. translator: second %s is a GUC variable name -#: replication/logical/slotsync.c:1135 +#: replication/logical/slotsync.c:1154 #, c-format msgid "replication slot \"%s\" specified by \"%s\" does not exist on primary server" msgstr "%2$sで指定されたレプリケーションスロット\"%1$s\"はプライマリサーバーに存在しません" @@ -25651,146 +25846,146 @@ msgstr "%2$sで指定されたレプリケーションスロット\"%1$s\"はプ #. translator: first %s is a connection option; second %s is a GUC #. variable name #. -#: replication/logical/slotsync.c:1168 +#: replication/logical/slotsync.c:1187 #, c-format msgid "replication slot synchronization requires \"%s\" to be specified in \"%s\"" msgstr "レプリケーションスロットの同期を行う際は\"%2$s\"で\"%1$s\"が指定されている必要があります" -#: replication/logical/slotsync.c:1187 +#: replication/logical/slotsync.c:1206 #, c-format msgid "replication slot synchronization requires \"effective_wal_level\" >= \"logical\" on the primary" msgstr "レプリケーションスロットの同期を行う際は、プライマリ上で\"effective_wal_level\" >= \"logical\" である必要があります" -#: replication/logical/slotsync.c:1188 +#: replication/logical/slotsync.c:1207 #, c-format msgid "To enable logical decoding on primary, set \"wal_level\" >= \"logical\" or create at least one logical slot when \"wal_level\" = \"replica\"." msgstr "プライマリで論理デコードを有効にするには、\"wal_level\" >= \"logical\" と設定するか、\"wal_level\" = \"replica\" の場合は少なくとも一つの論理スロットを作成してください。" #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1204 replication/logical/slotsync.c:1232 +#: replication/logical/slotsync.c:1223 replication/logical/slotsync.c:1251 #, c-format msgid "replication slot synchronization requires \"%s\" to be set" msgstr "レプリケーションスロットの同期を行う際は\"%s\"が設定されている必要があります" #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1218 +#: replication/logical/slotsync.c:1237 #, c-format msgid "replication slot synchronization requires \"%s\" to be enabled" msgstr "レプリケーションスロットの同期を行う際は\"%s\"が有効になっている必要があります" #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1275 +#: replication/logical/slotsync.c:1294 #, c-format msgid "replication slot synchronization worker will stop because \"%s\" is disabled" msgstr "\"%s\"が無効にされたため、レプリケーションスロット同期ワーカーが停止します" -#: replication/logical/slotsync.c:1293 +#: replication/logical/slotsync.c:1312 #, c-format msgid "replication slot synchronization worker will restart because of a parameter change" msgstr "パラメータの変更があったため、レプリケーションスロット同期ワーカーが再起動します" -#: replication/logical/slotsync.c:1318 +#: replication/logical/slotsync.c:1337 #, c-format msgid "replication slot synchronization will stop because of a parameter change" msgstr "パラメータの変更があったため、レプリケーションスロット同期が停止します" -#: replication/logical/slotsync.c:1354 +#: replication/logical/slotsync.c:1373 #, c-format msgid "replication slot synchronization worker will stop because promotion is triggered" msgstr "昇格が開始されたため、レプリケーションスロット同期ワーカーが停止します" -#: replication/logical/slotsync.c:1368 +#: replication/logical/slotsync.c:1387 #, c-format msgid "replication slot synchronization will stop because promotion is triggered" msgstr "昇格が開始されたため、レプリケーションスロット同期が停止します" -#: replication/logical/slotsync.c:1488 +#: replication/logical/slotsync.c:1507 #, c-format msgid "replication slot synchronization worker will not start because promotion was triggered" msgstr "昇格が開始されたため、レプリケーションスロット同期ワーカーは起動しません" -#: replication/logical/slotsync.c:1500 +#: replication/logical/slotsync.c:1519 #, c-format msgid "replication slot synchronization will not start because promotion was triggered" msgstr "昇格が開始されたため、レプリケーションスロット同期は開始されません" -#: replication/logical/slotsync.c:1509 +#: replication/logical/slotsync.c:1528 #, c-format msgid "cannot synchronize replication slots concurrently" msgstr "複数のレプリケーションスロットの並行同期はできません" -#: replication/logical/slotsync.c:1629 +#: replication/logical/slotsync.c:1648 #, c-format msgid "slot sync worker started" msgstr "スロット同期ワーカーが起動しました" -#: replication/logical/slotsync.c:1691 replication/slotfuncs.c:953 +#: replication/logical/slotsync.c:1710 replication/slotfuncs.c:953 #, c-format msgid "synchronization worker \"%s\" could not connect to the primary server: %s" msgstr "同期ワーカー\"%s\"はプライマリ・サーバーに接続できませんでした: %s" -#: replication/logical/snapbuild.c:531 +#: replication/logical/snapbuild.c:517 #, c-format msgid "initial slot snapshot too large" msgstr "初期スロットスナップショットが大きすぎます" -#: replication/logical/snapbuild.c:585 +#: replication/logical/snapbuild.c:571 #, c-format msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" msgstr[0] "エクスポートされた論理デコードスナップショット: \"%s\" (%u個のトランザクションID を含む)" -#: replication/logical/snapbuild.c:1369 replication/logical/snapbuild.c:1466 replication/logical/snapbuild.c:1976 +#: replication/logical/snapbuild.c:1317 replication/logical/snapbuild.c:1414 replication/logical/snapbuild.c:1920 #, c-format msgid "logical decoding found consistent point at %X/%08X" msgstr "論理デコードは一貫性ポイントを%X/%08Xで発見しました" -#: replication/logical/snapbuild.c:1371 +#: replication/logical/snapbuild.c:1319 #, c-format msgid "There are no running transactions." msgstr "実行中のトランザクションはありません。" -#: replication/logical/snapbuild.c:1418 +#: replication/logical/snapbuild.c:1366 #, c-format msgid "logical decoding found initial starting point at %X/%08X" msgstr "論理デコードは初期開始点を%X/%08Xで発見しました" -#: replication/logical/snapbuild.c:1420 replication/logical/snapbuild.c:1444 +#: replication/logical/snapbuild.c:1368 replication/logical/snapbuild.c:1392 #, c-format msgid "Waiting for transactions (approximately %d) older than %u to end." msgstr "%2$uより古いトランザクション(おおよそ%1$d個)の完了を待っています" -#: replication/logical/snapbuild.c:1442 +#: replication/logical/snapbuild.c:1390 #, c-format msgid "logical decoding found initial consistent point at %X/%08X" msgstr "論理デコードは初期の一貫性ポイントを%X/%08Xで発見しました" -#: replication/logical/snapbuild.c:1468 +#: replication/logical/snapbuild.c:1416 #, c-format msgid "There are no old transactions anymore." msgstr "古いトランザクションはこれ以上はありません" -#: replication/logical/snapbuild.c:1843 +#: replication/logical/snapbuild.c:1787 #, c-format msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" msgstr "スナップショット構築状態ファイル\"%1$s\"のマジックナンバーが不正です: %3$uのはずが%2$uでした" -#: replication/logical/snapbuild.c:1849 +#: replication/logical/snapbuild.c:1793 #, c-format msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" msgstr "スナップショット状態ファイル\"%1$s\"のバージョン%2$uはサポート外です: %3$uのはずが%2$uでした" -#: replication/logical/snapbuild.c:1890 +#: replication/logical/snapbuild.c:1834 #, c-format msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" msgstr "スナップショット生成状態ファイル\"%s\"のチェックサムが一致しません: %uですが、%uであるべきです" -#: replication/logical/snapbuild.c:1978 +#: replication/logical/snapbuild.c:1922 #, c-format msgid "Logical decoding will begin using saved snapshot." msgstr "論理デコードは保存されたスナップショットを使って開始します。" -#: replication/logical/snapbuild.c:2085 +#: replication/logical/snapbuild.c:2029 #, c-format msgid "could not parse file name \"%s\"" msgstr "ファイル名\"%s\"をパースできませんでした" @@ -25845,7 +26040,7 @@ msgstr "サブスクリプション\"%s\"のテーブル同期ワーカーがパ msgid "table copy could not start transaction on publisher: %s" msgstr "テーブルコピー中にパブリッシャ上でのトランザクション開始に失敗しました: %s" -#: replication/logical/tablesync.c:1474 replication/logical/worker.c:2630 +#: replication/logical/tablesync.c:1474 replication/logical/worker.c:2640 #, c-format msgid "user \"%s\" cannot replicate into relation with row-level security enabled: \"%s\"" msgstr "ユーザー\"%s\"は行レベルセキュリティが有効なリレーションへのレプリケーションはできません: \"%s\"" @@ -25865,192 +26060,197 @@ msgstr "サブスクリプション\"%s\"に対応する論理レプリケーシ msgid "Cannot handle streamed replication transactions using parallel apply workers until all tables have been synchronized." msgstr "すべてのテーブルの同期が完了するまでは、ストリームされたトランザクションを適用ワーカーで扱うことはできません。" -#: replication/logical/worker.c:1079 replication/logical/worker.c:1194 +#: replication/logical/worker.c:1046 replication/logical/worker.c:1163 replication/logical/worker.c:2886 +#, c-format +msgid "logical replication column %d not found in tuple: only %d column(s) received" +msgstr "論理レプリケーション列 %d がタプル内にありません: %d 列しか受信していません" + +#: replication/logical/worker.c:1085 replication/logical/worker.c:1204 #, c-format msgid "incorrect binary data format in logical replication column %d" msgstr "論理レプリケーション列%dのバイナリデータ書式が不正です" -#: replication/logical/worker.c:2777 +#: replication/logical/worker.c:2787 #, c-format msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" msgstr "論理レプリケーション先のリレーション\"%s.%s\"は複製の識別列を期待していましたが、パブリッシャは送信しませんでした" -#: replication/logical/worker.c:2784 +#: replication/logical/worker.c:2794 #, c-format msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" msgstr "論理レプリケーション先のリレーション\"%s.%s\"が識別列インデックスも主キーをもっておらず、かつパブリッシュされたリレーションがREPLICA IDENTITY FULLとなっていません" -#: replication/logical/worker.c:3325 +#: replication/logical/worker.c:3340 #, c-format msgid "could not detect conflict as the leader apply worker has exited" msgstr "リーダー適用ワーカーが終了したため、衝突検出ができません" -#: replication/logical/worker.c:3881 +#: replication/logical/worker.c:3896 #, c-format msgid "invalid logical replication message type \"??? (%d)\"" msgstr "不正な論理レプリケーションのメッセージタイプ \"??? (%d)\"" -#: replication/logical/worker.c:4054 +#: replication/logical/worker.c:4069 #, c-format msgid "data stream from publisher has ended" msgstr "パブリッシャからのデータストリームが終了しました" -#: replication/logical/worker.c:4257 +#: replication/logical/worker.c:4272 #, c-format msgid "terminating logical replication worker due to timeout" msgstr "タイムアウトにより論理レプリケーションワーカーを終了しています" -#: replication/logical/worker.c:4829 +#: replication/logical/worker.c:4844 #, c-format msgid "logical replication worker for subscription \"%s\" has stopped retaining the information for detecting conflicts" msgstr "サブスクリプション\"%s\"の論理レプリケーションワーカーが、衝突検出のための情報の保持を停止しました" -#: replication/logical/worker.c:4831 +#: replication/logical/worker.c:4846 #, c-format msgid "Retention is stopped because the apply process has not caught up with the publisher within the configured max_retention_duration." msgstr "適用プロセスがmax_retention_durationの設定値の範囲内でパブリッシャに追いついていないため、保持を停止します。" -#: replication/logical/worker.c:4856 +#: replication/logical/worker.c:4871 #, c-format msgid "logical replication worker for subscription \"%s\" will resume retaining the information for detecting conflicts" msgstr "サブスクリプション\"%s\"の論理レプリケーションワーカーが、衝突検出のための情報の保持を再開します" -#: replication/logical/worker.c:4859 +#: replication/logical/worker.c:4874 #, c-format msgid "Retention is re-enabled because the apply process has caught up with the publisher within the configured max_retention_duration." msgstr "適用プロセスがmax_retention_durationの設定値の範囲内でパブリッシャに追いついたため、保持を再開します。" -#: replication/logical/worker.c:4860 +#: replication/logical/worker.c:4875 #, c-format msgid "Retention is re-enabled because max_retention_duration has been set to unlimited." msgstr "最大保持時間が無制限に設定されているため、保持が再有効化されます。" -#: replication/logical/worker.c:5075 +#: replication/logical/worker.c:5090 #, c-format msgid "logical replication worker for subscription \"%s\" will stop because the subscription was removed" msgstr "サブスクリプション\"%s\"が削除されたため、このサブスクリプションに対応する論理レプリケーションワーカーが停止します" -#: replication/logical/worker.c:5089 +#: replication/logical/worker.c:5104 #, c-format msgid "logical replication worker for subscription \"%s\" will stop because the subscription was disabled" msgstr "サブスクリプション\"%s\"が無効化されたため、このサブスクリプションに対応する論理レプリケーションワーカーが停止します" -#: replication/logical/worker.c:5120 +#: replication/logical/worker.c:5135 #, c-format msgid "logical replication parallel apply worker for subscription \"%s\" will stop because of a parameter change" msgstr "パラメータの変更があったため、サブスクリプション\"%s\"に対応する論理レプリケーション並列適用ワーカーが停止します" -#: replication/logical/worker.c:5124 +#: replication/logical/worker.c:5139 #, c-format msgid "logical replication worker for subscription \"%s\" will restart because of a parameter change" msgstr "パラメータの変更があったため、サブスクリプション\"%s\"に対応する論理レプリケーションワーカーが再起動します" -#: replication/logical/worker.c:5138 +#: replication/logical/worker.c:5153 #, c-format msgid "logical replication parallel apply worker for subscription \"%s\" will stop because the subscription owner's superuser privileges have been revoked" msgstr "サブスクリプション\"%s\"の所有者のスーパーユーザー権限が剥奪されたため、このサブスクリプションに対応する論理レプリケーション並列適用ワーカーが停止します" -#: replication/logical/worker.c:5142 +#: replication/logical/worker.c:5157 #, c-format msgid "logical replication worker for subscription \"%s\" will restart because the subscription owner's superuser privileges have been revoked" msgstr "サブスクリプション\"%s\"の所有者のスーパーユーザー権限が剥奪されたため、このサブスクリプションに対応する論理レプリケーションワーカーが再起動します" -#: replication/logical/worker.c:5688 +#: replication/logical/worker.c:5703 #, c-format msgid "subscription has no replication slot set" msgstr "サブスクリプションにレプリケーションスロットが設定されていません" -#: replication/logical/worker.c:5713 +#: replication/logical/worker.c:5728 #, c-format msgid "apply worker for subscription \"%s\" could not connect to the publisher: %s" msgstr "サブスクリプション\"%s\"の適用ワーカーがパブリッシャに接続できませんでした: %s" -#: replication/logical/worker.c:5820 +#: replication/logical/worker.c:5835 #, c-format msgid "logical replication worker for subscription %u will not start because the subscription was removed during startup" msgstr "サブスクリプション%uが起動中に削除されたため、このサブスクリプションに対応する論理レプリケーションワーカーは起動しません" -#: replication/logical/worker.c:5835 +#: replication/logical/worker.c:5850 #, c-format msgid "logical replication worker for subscription \"%s\" will not start because the subscription was disabled during startup" msgstr "サブスクリプション\"%s\"が起動中に無効化されたため、このサブスクリプションに対応する論理レプリケーションワーカーは起動しません" -#: replication/logical/worker.c:5860 +#: replication/logical/worker.c:5875 #, c-format msgid "logical replication worker for subscription \"%s\" will restart because the option %s was enabled during startup" msgstr "オプション%sが起動処理中に有効化されたため、サブスクリプション\"%s\"に対応する論理レプリケーションワーカーは再起動されます" -#: replication/logical/worker.c:5903 +#: replication/logical/worker.c:5918 #, c-format msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" msgstr "サブスクリプション\"%s\"、テーブル\"%s\"に対応する論理レプリケーションテーブル同期ワーカーが起動しました" -#: replication/logical/worker.c:5908 +#: replication/logical/worker.c:5923 #, c-format msgid "logical replication sequence synchronization worker for subscription \"%s\" has started" msgstr "サブスクリプション\"%s\"に対応する、論理レプリケーションのシーケンス同期ワーカーが起動しました" -#: replication/logical/worker.c:5912 +#: replication/logical/worker.c:5927 #, c-format msgid "logical replication apply worker for subscription \"%s\" has started" msgstr "サブスクリプション\"%s\"に対応する論理レプリケーション適用ワーカーが起動しました" -#: replication/logical/worker.c:6047 +#: replication/logical/worker.c:6062 #, c-format msgid "subscription \"%s\" has been disabled because of an error" msgstr "サブスクリプション\"%s\"はエラーのため無効化されました" -#: replication/logical/worker.c:6104 +#: replication/logical/worker.c:6119 #, c-format msgid "logical replication starts skipping transaction at LSN %X/%08X" msgstr "論理レプリケーションは%X/%08Xででトランザクションのスキップを開始します" -#: replication/logical/worker.c:6118 +#: replication/logical/worker.c:6133 #, c-format msgid "logical replication completed skipping transaction at LSN %X/%08X" msgstr "論理レプリケーションは%X/%08Xでトランザクションのスキップを完了しました" -#: replication/logical/worker.c:6206 +#: replication/logical/worker.c:6221 #, c-format msgid "skip-LSN of subscription \"%s\" cleared" msgstr "サブスクリプションの\"%s\"スキップLSNをクリアしました" -#: replication/logical/worker.c:6207 +#: replication/logical/worker.c:6222 #, c-format msgid "Remote transaction's finish WAL location (LSN) %X/%08X did not match skip-LSN %X/%08X." msgstr "リモートトランザクションの完了WAL位置(LSN) %X/%08XがスキップLSN %X/%08X と一致しません。" -#: replication/logical/worker.c:6235 +#: replication/logical/worker.c:6250 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\"" msgstr "メッセージタイプ \"%2$s\"でレプリケーション起源\"%1$s\"のリモートからのデータを処理中" -#: replication/logical/worker.c:6239 +#: replication/logical/worker.c:6254 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" in transaction %u" msgstr "トランザクション%3$u中、メッセージタイプ\"%2$s\"でレプリケーション起源\"%1$s\"のリモートからのデータを処理中" -#: replication/logical/worker.c:6244 +#: replication/logical/worker.c:6259 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" in transaction %u, finished at %X/%08X" msgstr "%4$X/%5$08Xで終了したトランザクション%3$u中、メッセージタイプ\"%2$s\"でレプリケーション起源\"%1$s\"のリモートからのデータを処理中" -#: replication/logical/worker.c:6255 +#: replication/logical/worker.c:6270 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" in transaction %u" msgstr "レプリケーション起点\"%1$s\"のリモートデータ処理中、トランザクション%5$uのレプリケーション対象リレーション\"%3$s.%4$s\"に対するメッセージタイプ\"%2$s\"内" -#: replication/logical/worker.c:6262 +#: replication/logical/worker.c:6277 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" in transaction %u, finished at %X/%08X" msgstr "%6$X/%7$08Xで終了したトランザクション%5$u中、レプリケーション先リレーション\"%3$s.%4$s\"に対するメッセージタイプ\"%2$s\"でレプリケーション起源\"%1$s\"のリモートからのデータを処理中" -#: replication/logical/worker.c:6273 +#: replication/logical/worker.c:6288 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" column \"%s\" in transaction %u" msgstr "レプリケーション起点\"%1$s\"のリモートデータ処理中、トランザクション%6$uのレプリケーション対象リレーション\"%3$s.%4$s\"、列\"%5$s\"に対するメッセージタイプ\"%2$s\"内" -#: replication/logical/worker.c:6281 +#: replication/logical/worker.c:6296 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" column \"%s\" in transaction %u, finished at %X/%08X" msgstr "%7$X/%8$08Xで終了したトランザクション%6$u中、レプリケーション先リレーション\"%3$s.%4$s\"、列\"%5$s\"に対するメッセージタイプ\"%2$s\"でレプリケーション起源\"%1$s\"のリモートからのデータを処理中" @@ -26130,7 +26330,17 @@ msgstr "このパブリケーションはWALのこの時点では存在しませ msgid "Create the publication if it does not exist." msgstr "パブリケーションが存在しない場合は作成してください。" -#: replication/pgrepack/pgrepack.c:66 +#: replication/pgrepack/pgrepack.c:56 +#, c-format +msgid "unsupported use of logical decoding plugin \"%s\"" +msgstr "論理デコードプラグイン\"%s\"はこの使用形態をサポートしていません" + +#: replication/pgrepack/pgrepack.c:58 +#, c-format +msgid "This plugin can only be used by %s." +msgstr "このプラグインは %s でのみ使用可能です。" + +#: replication/pgrepack/pgrepack.c:77 #, c-format msgid "this plugin does not expect any options" msgstr "このプラグインで使用可能なオプションはありません" @@ -26169,7 +26379,7 @@ msgstr "この名前\"%s\"は衝突検出用スロットのために予約され msgid "cannot enable failover for a replication slot created on the standby" msgstr "スタンバイ上で作成したレプリケーションスロットのフェイルオーバーを有効にすることはできません" -#: replication/slot.c:420 replication/slot.c:1008 +#: replication/slot.c:420 replication/slot.c:994 #, c-format msgid "cannot enable failover for a temporary replication slot" msgstr "一時レプリケーションスロットのフェイルオーバーを有効にすることはできません" @@ -26204,7 +26414,7 @@ msgstr "レプリケーションスロット\"%s\"を取得できません" msgid "The slot is reserved for conflict detection and can only be acquired by logical replication launcher." msgstr "このスロットは競合検出のため保持されており、論理レプリケーションランチャーのみが取得可能です。" -#: replication/slot.c:717 replication/slot.c:1596 +#: replication/slot.c:717 replication/slot.c:1592 #, c-format msgid "replication slot \"%s\" is active for PID %d" msgstr "レプリケーションスロット\"%s\"はPID%dで使用中です" @@ -26229,198 +26439,198 @@ msgstr "論理レプリケーションスロット\"%s\"を取得しました" msgid "acquired physical replication slot \"%s\"" msgstr "物理レプリケーションスロット\"%s\"を取得しました" -#: replication/slot.c:849 +#: replication/slot.c:842 #, c-format msgid "released logical replication slot \"%s\"" msgstr "論理レプリケーションスロット\"%s\"を解放しました" -#: replication/slot.c:851 +#: replication/slot.c:844 #, c-format msgid "released physical replication slot \"%s\"" msgstr "物理レプリケーションスロット\"%s\"を解放しました" -#: replication/slot.c:935 +#: replication/slot.c:926 #, c-format msgid "cannot drop replication slot \"%s\"" msgstr "レプリケーションスロット\"%s\"を削除できませんでした" -#: replication/slot.c:973 +#: replication/slot.c:959 #, c-format msgid "cannot use %s with a physical replication slot" msgstr "%sは物理レプリケーションスロットでは使用できません" -#: replication/slot.c:985 +#: replication/slot.c:971 #, c-format msgid "cannot alter replication slot \"%s\"" msgstr "レプリケーションスロット\"%s\"を変更できませんでした" -#: replication/slot.c:995 +#: replication/slot.c:981 #, c-format msgid "cannot enable failover for a replication slot on the standby" msgstr "スタンバイ上ではレプリケーションスロットのフェイルオーバーを有効にすることはできません" -#: replication/slot.c:1143 replication/slot.c:2433 replication/slot.c:2826 +#: replication/slot.c:1139 replication/slot.c:2429 replication/slot.c:2822 #, c-format msgid "could not remove directory \"%s\"" msgstr "ディレクトリ\"%s\"を削除できませんでした" -#: replication/slot.c:1675 +#: replication/slot.c:1671 #, c-format msgid "replication slots can only be used if \"%s\" > 0" msgstr "レプリケーションスロットは\"%s\" > 0 のときだけ使用できます" -#: replication/slot.c:1681 +#: replication/slot.c:1677 #, c-format msgid "REPACK can only be used if \"%s\" > 0" msgstr "REPACKは \"%s\" > 0 のときにのみ使用できます" -#: replication/slot.c:1687 +#: replication/slot.c:1683 #, c-format msgid "replication slots can only be used if \"wal_level\" >= \"replica\"" msgstr "レプリケーションスロットは\"wal_level\" >= \"replica\" のときだけ使用できます" -#: replication/slot.c:1699 +#: replication/slot.c:1695 #, c-format msgid "permission denied to use replication slots" msgstr "レプリケーションスロットを使用する権限がありません" -#: replication/slot.c:1700 +#: replication/slot.c:1696 #, c-format msgid "Only roles with the %s attribute may use replication slots." msgstr "%s属性を持つロールのみがレプリケーションスロットを使用できます。" -#: replication/slot.c:1812 +#: replication/slot.c:1808 #, c-format msgid "The slot's restart_lsn %X/%08X exceeds the limit by % byte." msgid_plural "The slot's restart_lsn %X/%08X exceeds the limit by % bytes." msgstr[0] "このスロットのrestart_lsn %X/%08Xは制限を%バイト超過しています。" -#: replication/slot.c:1823 +#: replication/slot.c:1819 #, c-format msgid "The slot conflicted with xid horizon %u." msgstr "このスロットはXID地平線%uと競合しました。" -#: replication/slot.c:1828 +#: replication/slot.c:1824 msgid "Logical decoding on standby requires the primary server to either set \"wal_level\" >= \"logical\" or have at least one logical slot when \"wal_level\" = \"replica\"." msgstr "スタンバイ上で論理デコードを行うためには、プライマリサーバー上で\"wal_level\" >= \"logical\" であるか、または\"wal_level\" = \"replica\"の場合に少なくとも 1 つの論理レプリケーションスロットが存在する必要があります。" #. translator: %s is a GUC variable name -#: replication/slot.c:1834 +#: replication/slot.c:1830 #, c-format msgid "The slot's idle time of %lds exceeds the configured \"%s\" duration of %ds." msgstr "このスロットのアイドル時間 %ld秒が、\"%s\"で設定された %d秒を超えています。" -#: replication/slot.c:1848 +#: replication/slot.c:1844 #, c-format msgid "terminating process %d to release replication slot \"%s\"" msgstr "プロセス%dを終了してレプリケーションスロット\"%s\"を解放します" -#: replication/slot.c:1850 +#: replication/slot.c:1846 #, c-format msgid "invalidating obsolete replication slot \"%s\"" msgstr "使用不能のレプリケーションスロット\"%s\"を無効化します" -#: replication/slot.c:2764 +#: replication/slot.c:2760 #, c-format msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" msgstr "レプリケーションスロットファイル\"%1$s\"のマジックナンバーが不正です: %3$uのはずが%2$uでした" -#: replication/slot.c:2771 +#: replication/slot.c:2767 #, c-format msgid "replication slot file \"%s\" has unsupported version %u" msgstr "レプリケーションスロットファイル\"%s\"はサポート外のバージョン%uです" -#: replication/slot.c:2778 +#: replication/slot.c:2774 #, c-format msgid "replication slot file \"%s\" has corrupted length %u" msgstr "レプリケーションスロットファイル\"%s\"のサイズ%uは異常です" -#: replication/slot.c:2814 +#: replication/slot.c:2810 #, c-format msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" msgstr "レプリケーションスロットファイル\"%s\"のチェックサムが一致しません: %uですが、%uであるべきです" -#: replication/slot.c:2850 +#: replication/slot.c:2846 #, c-format msgid "logical replication slot \"%s\" exists, but \"wal_level\" < \"replica\"" msgstr "論理レプリケーションスロット\"%s\"がありますが、\"wal_level\" < \"replica\" です" -#: replication/slot.c:2852 replication/slot.c:2874 +#: replication/slot.c:2848 replication/slot.c:2870 #, c-format msgid "Change \"wal_level\" to be \"replica\" or higher." msgstr "\"wal_level\"を\"replica\"もしくはそれより上位の設定にしてください。" -#: replication/slot.c:2865 +#: replication/slot.c:2861 #, c-format msgid "logical replication slot \"%s\" exists on the standby, but \"hot_standby\" = \"off\"" msgstr "論理レプリケーションスロット\"%s\"がありますが、\"hot_standby\" = \"off\" です" -#: replication/slot.c:2867 +#: replication/slot.c:2863 #, c-format msgid "Change \"hot_standby\" to be \"on\"." msgstr "\"hot_standby\" を \"on\" に変更してください。" -#: replication/slot.c:2872 +#: replication/slot.c:2868 #, c-format msgid "physical replication slot \"%s\" exists, but \"wal_level\" < \"replica\"" msgstr "物理レプリケーションスロット\"%s\"がありますが、\"wal_level\" < \"replica\" です" -#: replication/slot.c:2927 +#: replication/slot.c:2923 #, c-format msgid "too many replication slots active before shutdown" msgstr "シャットダウン前のアクティブなレプリケーションスロットの数が多すぎます" -#: replication/slot.c:2928 +#: replication/slot.c:2924 #, c-format msgid "Increase \"max_replication_slots\" and try again." msgstr "\"max_replication_slots\"を増やして再度試してください" -#: replication/slot.c:3165 +#: replication/slot.c:3161 #, c-format msgid "replication slot \"%s\" specified in parameter \"%s\" does not exist" msgstr "パラメータ\"%2$s\"で指定されているレプリケーションスロット\"%1$s\"は存在しません" -#: replication/slot.c:3167 replication/slot.c:3201 replication/slot.c:3216 +#: replication/slot.c:3163 replication/slot.c:3197 replication/slot.c:3212 #, c-format msgid "Logical replication is waiting on the standby associated with replication slot \"%s\"." msgstr "論理レプリケーションはレプリケーションスロット”%s\"に対応するスタンバイを待っています。 " -#: replication/slot.c:3169 +#: replication/slot.c:3165 #, c-format msgid "Create the replication slot \"%s\" or amend parameter \"%s\"." msgstr "レプリケーションスロット\"%s\"を作成するか、パラメータ\"%s\"を修正してください。" -#: replication/slot.c:3179 +#: replication/slot.c:3175 #, c-format msgid "cannot specify logical replication slot \"%s\" in parameter \"%s\"" msgstr "パラメータ\"%2$s\"では論理レプリケーションスロット\"%1$s\"は指定できません" -#: replication/slot.c:3181 +#: replication/slot.c:3177 #, c-format msgid "Logical replication is waiting for correction on replication slot \"%s\"." msgstr "論理レプリケーションはレプリケーションスロット\"%s\"が修正されるのを待っています。" -#: replication/slot.c:3183 +#: replication/slot.c:3179 #, c-format msgid "Remove the logical replication slot \"%s\" from parameter \"%s\"." msgstr "論理レプリケーションスロット\"%s\"をパラメータ\"%s\"から削除してください。" -#: replication/slot.c:3199 +#: replication/slot.c:3195 #, c-format msgid "physical replication slot \"%s\" specified in parameter \"%s\" has been invalidated" msgstr "パラメータ\"%2$s\"で指定された物理レプリケーションスロット\"%1$s\"は無効化されています" -#: replication/slot.c:3203 +#: replication/slot.c:3199 #, c-format msgid "Drop and recreate the replication slot \"%s\", or amend parameter \"%s\"." msgstr "レプリケーションスロット\"%s\"を削除して再作成するか、パラメータ\"%s\"を修正してください。" -#: replication/slot.c:3214 +#: replication/slot.c:3210 #, c-format msgid "replication slot \"%s\" specified in parameter \"%s\" does not have active_pid" msgstr "\"%2$s\"で指定されたレプリケーションスロット\"%1$s\"にはactive_pidがありません" -#: replication/slot.c:3218 +#: replication/slot.c:3214 #, c-format msgid "Start the standby associated with the replication slot \"%s\", or amend parameter \"%s\"." msgstr "レプリケーションスロット\"%s\"に関連付けられているスタンバイを起動するか、パラメータ%sを修正してください。" @@ -26542,72 +26752,72 @@ msgstr "\"%s\"のパーサーが失敗しました。" msgid "number of synchronous standbys (%d) must be greater than zero" msgstr "同期スタンバイの数(%d)は1以上である必要があります" -#: replication/walreceiver.c:276 +#: replication/walreceiver.c:290 #, c-format msgid "streaming replication receiver \"%s\" could not connect to the primary server: %s" msgstr "ストリーミングレプリケーション・レシーバー\"%s\"はプライマリ・サーバーに接続できませんでした: %s" -#: replication/walreceiver.c:327 +#: replication/walreceiver.c:335 #, c-format msgid "database system identifier differs between the primary and standby" msgstr "データベースシステムの識別子がプライマリサーバーとスタンバイサーバー間で異なります" -#: replication/walreceiver.c:328 +#: replication/walreceiver.c:336 #, c-format msgid "The primary's identifier is %s, the standby's identifier is %s." msgstr "プライマリ側の識別子は %s ですが、スタンバイ側の識別子は %s です。" -#: replication/walreceiver.c:340 +#: replication/walreceiver.c:348 #, c-format msgid "highest timeline %u of the primary is behind recovery timeline %u" msgstr "プライマリの最大のタイムライン%uが、リカバリのタイムライン %uより遅れています" -#: replication/walreceiver.c:393 +#: replication/walreceiver.c:401 #, c-format msgid "started streaming WAL from primary at %X/%08X on timeline %u" msgstr "プライマリのタイムライン%3$uの %1$X/%2$08XからでWALストリーミングを開始します" -#: replication/walreceiver.c:397 +#: replication/walreceiver.c:405 #, c-format msgid "restarted WAL streaming at %X/%08X on timeline %u" msgstr "タイムライン%3$uの %1$X/%2$08XからでWALストリーミングを再開します" -#: replication/walreceiver.c:442 +#: replication/walreceiver.c:450 #, c-format msgid "cannot continue WAL streaming, recovery has already ended" msgstr "WAL ストリーミングを継続できません。リカバリはすでに終わっています。" -#: replication/walreceiver.c:486 +#: replication/walreceiver.c:494 #, c-format msgid "replication terminated by primary server" msgstr "プライマリサーバーによりレプリケーションが打ち切られました" -#: replication/walreceiver.c:487 +#: replication/walreceiver.c:495 #, c-format msgid "End of WAL reached on timeline %u at %X/%08X." msgstr "タイムライン%uの%X/%08XでWALの終点に到達しました" -#: replication/walreceiver.c:587 +#: replication/walreceiver.c:595 #, c-format msgid "terminating walreceiver due to timeout" msgstr "レプリケーションタイムアウトによりwalreceiverを終了しています" -#: replication/walreceiver.c:619 +#: replication/walreceiver.c:627 #, c-format msgid "primary server contains no more WAL on requested timeline %u" msgstr "プライマリサーバーには要求されたタイムライン%u上にこれ以上WALがありません" -#: replication/walreceiver.c:635 replication/walreceiver.c:1090 +#: replication/walreceiver.c:643 replication/walreceiver.c:1098 #, c-format msgid "could not close WAL segment %s: %m" msgstr "WALセグメント%sをクローズできませんでした: %m" -#: replication/walreceiver.c:754 +#: replication/walreceiver.c:762 #, c-format msgid "fetching timeline history file for timeline %u from primary server" msgstr "プライマリサーバーからライムライン%u用のタイムライン履歴ファイルを取り込みしています" -#: replication/walreceiver.c:966 +#: replication/walreceiver.c:971 #, c-format msgid "could not write to WAL segment %s at offset %d, length %d: %m" msgstr "WALファイルセグメント%sのオフセット%d、長さ%dの書き込みが失敗しました: %m" @@ -26648,267 +26858,272 @@ msgid "requested starting point %X/%08X is ahead of the WAL flush position of th msgstr "要求された開始ポイント%X/%08XはサーバーのWALフラッシュ位置%X/%08Xより進んでいます" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1293 +#: replication/walsender.c:1315 #, c-format msgid "%s must not be called inside a transaction" msgstr "%sはトランザクション内では呼び出せません" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1303 +#: replication/walsender.c:1325 #, c-format msgid "%s must be called inside a transaction" msgstr "%sはトランザクション内で呼び出さなければなりません" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1309 +#: replication/walsender.c:1331 #, c-format msgid "%s must be called in REPEATABLE READ isolation mode transaction" msgstr "%s は REPEATABLE READ 分離レベルのトランザクションで呼び出されなければなりません" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1314 +#: replication/walsender.c:1336 #, c-format msgid "%s must be called in a read-only transaction" msgstr "%sは読み取り専用トランザクションの中で呼び出さなければなりません" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1320 +#: replication/walsender.c:1342 #, c-format msgid "%s must be called before any query" msgstr "%s は問い合わせの実行前に呼び出されなければなりません" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1326 +#: replication/walsender.c:1348 #, c-format msgid "%s must not be called in a subtransaction" msgstr "%s はサブトランザクション内では呼び出せません" -#: replication/walsender.c:1512 +#: replication/walsender.c:1534 #, c-format msgid "terminating walsender process after promotion" msgstr "昇格後にWAL送信プロセスを終了します" -#: replication/walsender.c:2091 +#: replication/walsender.c:2113 #, c-format msgid "cannot execute new commands while WAL sender is in stopping mode" msgstr "WAL送信プロセスが停止モードの間は新しいコマンドを実行できません" -#: replication/walsender.c:2145 +#: replication/walsender.c:2167 #, c-format msgid "cannot execute SQL commands in WAL sender for physical replication" msgstr "物理レプリケーション用のWAL送信プロセスでSQLコマンドは実行できません" -#: replication/walsender.c:2176 +#: replication/walsender.c:2198 #, c-format msgid "received replication command: %s" msgstr "レプリケーションコマンドを受信しました: %s" -#: replication/walsender.c:2184 tcop/fastpath.c:208 tcop/postgres.c:1155 tcop/postgres.c:1511 tcop/postgres.c:1762 tcop/postgres.c:2266 tcop/postgres.c:2688 tcop/postgres.c:2764 +#: replication/walsender.c:2206 tcop/fastpath.c:208 tcop/postgres.c:1165 tcop/postgres.c:1532 tcop/postgres.c:1793 tcop/postgres.c:2315 tcop/postgres.c:2783 tcop/postgres.c:2859 #, c-format msgid "current transaction is aborted, commands ignored until end of transaction block" msgstr "現在のトランザクションがアボートしました。トランザクションブロックが終わるまでコマンドは無視されます" -#: replication/walsender.c:2344 replication/walsender.c:2379 +#: replication/walsender.c:2366 replication/walsender.c:2401 #, c-format msgid "unexpected EOF on standby connection" msgstr "スタンバイ接続で想定外のEOFがありました" -#: replication/walsender.c:2367 +#: replication/walsender.c:2389 #, c-format msgid "invalid standby message type \"%c\"" msgstr "スタンバイのメッセージタイプ\"%c\"は不正です" -#: replication/walsender.c:2463 +#: replication/walsender.c:2485 #, c-format msgid "unexpected message type \"%c\"" msgstr "想定しないメッセージタイプ\"%c\"" -#: replication/walsender.c:2961 +#: replication/walsender.c:2983 #, c-format msgid "terminating walsender process due to replication timeout" msgstr "レプリケーションタイムアウトにより WAL 送信プロセスを終了しています" -#: replication/walsender.c:3754 +#: replication/walsender.c:3776 #, c-format msgid "terminating walsender process due to replication shutdown timeout" msgstr "レプリケーション終了タイムアウトによりWAL送信プロセスを終了しています" -#: replication/walsender.c:3755 +#: replication/walsender.c:3777 #, c-format msgid "Walsender process might have been terminated before all WAL data was replicated to the receiver." msgstr "Walsenderプロセスが、すべてのWALデータが受診側にレプリケートされる前に終了した可能性があります。" -#: rewrite/rewriteDefine.c:104 rewrite/rewriteDefine.c:834 +#: rewrite/rewriteDefine.c:104 rewrite/rewriteDefine.c:843 #, c-format msgid "rule \"%s\" for relation \"%s\" already exists" msgstr "リレーション\"%2$s\"のルール\"%1$s\"はすでに存在します" -#: rewrite/rewriteDefine.c:261 rewrite/rewriteDefine.c:772 +#: rewrite/rewriteDefine.c:261 rewrite/rewriteDefine.c:769 #, c-format msgid "relation \"%s\" cannot have rules" msgstr "リレーション \"%s\"にはルールを定義できません" -#: rewrite/rewriteDefine.c:292 +#: rewrite/rewriteDefine.c:273 rewrite/rewriteDefine.c:780 +#, c-format +msgid "conflict log table \"%s\" cannot have rules" +msgstr "競合ログテーブル\"%s\"にはルールを定義できません" + +#: rewrite/rewriteDefine.c:304 #, c-format msgid "rule actions on OLD are not implemented" msgstr "OLDに対するルールアクションは実装されていません" -#: rewrite/rewriteDefine.c:293 +#: rewrite/rewriteDefine.c:305 #, c-format msgid "Use views or triggers instead." msgstr "代わりにビューかトリガーを使用してください。" -#: rewrite/rewriteDefine.c:297 +#: rewrite/rewriteDefine.c:309 #, c-format msgid "rule actions on NEW are not implemented" msgstr "NEWに対するルールアクションは実装されていません" -#: rewrite/rewriteDefine.c:298 +#: rewrite/rewriteDefine.c:310 #, c-format msgid "Use triggers instead." msgstr "代わりにトリガーを使用してください。" -#: rewrite/rewriteDefine.c:312 +#: rewrite/rewriteDefine.c:324 #, c-format msgid "relation \"%s\" cannot have ON SELECT rules" msgstr "リレーション \"%s\"にはON SELECTルールを定義できません" -#: rewrite/rewriteDefine.c:322 +#: rewrite/rewriteDefine.c:334 #, c-format msgid "INSTEAD NOTHING rules on SELECT are not implemented" msgstr "SELECTに対するINSTEAD NOTHINGルールは実装されていません" -#: rewrite/rewriteDefine.c:323 +#: rewrite/rewriteDefine.c:335 #, c-format msgid "Use views instead." msgstr "代わりにビューを使用してください" -#: rewrite/rewriteDefine.c:331 +#: rewrite/rewriteDefine.c:343 #, c-format msgid "multiple actions for rules on SELECT are not implemented" msgstr "SELECTに対するルールにおける複数のアクションは実装されていません" -#: rewrite/rewriteDefine.c:341 +#: rewrite/rewriteDefine.c:353 #, c-format msgid "rules on SELECT must have action INSTEAD SELECT" msgstr "SELECTに対するルールはINSTEAD SELECTアクションを持たなければなりません" -#: rewrite/rewriteDefine.c:349 +#: rewrite/rewriteDefine.c:361 #, c-format msgid "rules on SELECT must not contain data-modifying statements in WITH" msgstr "SELECT のルールでは WITH にデータを変更するステートメントを含むことはできません" -#: rewrite/rewriteDefine.c:357 +#: rewrite/rewriteDefine.c:369 #, c-format msgid "event qualifications are not implemented for rules on SELECT" msgstr "SELECTに対するルールではイベント条件は実装されていません" -#: rewrite/rewriteDefine.c:384 +#: rewrite/rewriteDefine.c:396 #, c-format msgid "\"%s\" is already a view" msgstr "\"%s\"はすでにビューです" -#: rewrite/rewriteDefine.c:408 +#: rewrite/rewriteDefine.c:407 #, c-format msgid "view rule for \"%s\" must be named \"%s\"" msgstr "\"%s\"に対するビューのルールの名前は\"%s\"でなければなりません" -#: rewrite/rewriteDefine.c:435 +#: rewrite/rewriteDefine.c:432 #, c-format msgid "cannot have multiple RETURNING lists in a rule" msgstr "ルールは複数のRETURNINGリストを持つことができません" -#: rewrite/rewriteDefine.c:440 +#: rewrite/rewriteDefine.c:437 #, c-format msgid "RETURNING lists are not supported in conditional rules" msgstr "条件付のルールではRETURNINGリストはサポートされません" -#: rewrite/rewriteDefine.c:444 +#: rewrite/rewriteDefine.c:441 #, c-format msgid "RETURNING lists are not supported in non-INSTEAD rules" msgstr "INSTEAD以外のルールではRETURNINGリストはサポートされません" -#: rewrite/rewriteDefine.c:458 +#: rewrite/rewriteDefine.c:455 rewrite/rewriteDefine.c:862 #, c-format msgid "non-view rule for \"%s\" must not be named \"%s\"" msgstr "\"%s\"に対するビュー以外のルールの名前は\"%s\"にはできません" -#: rewrite/rewriteDefine.c:532 +#: rewrite/rewriteDefine.c:529 #, c-format msgid "SELECT rule's target list has too many entries" msgstr "SELECTルールのターゲットリストの要素が多すぎます" -#: rewrite/rewriteDefine.c:533 +#: rewrite/rewriteDefine.c:530 #, c-format msgid "RETURNING list has too many entries" msgstr "RETURNINGリストの要素が多すぎます" -#: rewrite/rewriteDefine.c:560 +#: rewrite/rewriteDefine.c:557 #, c-format msgid "cannot convert relation containing dropped columns to view" msgstr "削除された列を持つリレーションをビューに変換できませんでした" -#: rewrite/rewriteDefine.c:561 +#: rewrite/rewriteDefine.c:558 #, c-format msgid "cannot create a RETURNING list for a relation containing dropped columns" msgstr "削除された列を持つリレーションにRETURNINGリストを生成することはできませんでした" -#: rewrite/rewriteDefine.c:567 +#: rewrite/rewriteDefine.c:564 #, c-format msgid "SELECT rule's target entry %d has different column name from column \"%s\"" msgstr "SELECTルールのターゲットエントリ%dは列\"%s\"とは異なる列名を持っています" -#: rewrite/rewriteDefine.c:569 +#: rewrite/rewriteDefine.c:566 #, c-format msgid "SELECT target entry is named \"%s\"." msgstr "SELECTのターゲットエントリは\"%s\"と名付けられています。" -#: rewrite/rewriteDefine.c:578 +#: rewrite/rewriteDefine.c:575 #, c-format msgid "SELECT rule's target entry %d has different type from column \"%s\"" msgstr "SELECTルールの対象項目%dは\"%s\"と異なる列型を持っています" -#: rewrite/rewriteDefine.c:580 +#: rewrite/rewriteDefine.c:577 #, c-format msgid "RETURNING list's entry %d has different type from column \"%s\"" msgstr "RETURNINGリスト項目%dは\"%s\"と異なる列型を持っています" -#: rewrite/rewriteDefine.c:583 rewrite/rewriteDefine.c:607 +#: rewrite/rewriteDefine.c:580 rewrite/rewriteDefine.c:604 #, c-format msgid "SELECT target entry has type %s, but column has type %s." msgstr "SELECTのターゲットエントリの型は%sですが、列の型は%sです。" -#: rewrite/rewriteDefine.c:586 rewrite/rewriteDefine.c:611 +#: rewrite/rewriteDefine.c:583 rewrite/rewriteDefine.c:608 #, c-format msgid "RETURNING list entry has type %s, but column has type %s." msgstr "RETURNINGリストの要素の型は%sですが、列の型は%sです。" -#: rewrite/rewriteDefine.c:602 +#: rewrite/rewriteDefine.c:599 #, c-format msgid "SELECT rule's target entry %d has different size from column \"%s\"" msgstr "SELECTルールの対象項目%dは\"%s\"と異なる列のサイズを持っています" -#: rewrite/rewriteDefine.c:604 +#: rewrite/rewriteDefine.c:601 #, c-format msgid "RETURNING list's entry %d has different size from column \"%s\"" msgstr "RETURNINGリスト項目%dは\"%s\"と異なる列のサイズを持っています" -#: rewrite/rewriteDefine.c:621 +#: rewrite/rewriteDefine.c:618 #, c-format msgid "SELECT rule's target list has too few entries" msgstr "SELECTルールのターゲットリストの項目が少なすぎます" -#: rewrite/rewriteDefine.c:622 +#: rewrite/rewriteDefine.c:619 #, c-format msgid "RETURNING list has too few entries" msgstr "RETURNINGリストの項目が少なすぎます" -#: rewrite/rewriteDefine.c:711 rewrite/rewriteDefine.c:825 rewrite/rewriteSupport.c:108 +#: rewrite/rewriteDefine.c:708 rewrite/rewriteDefine.c:834 rewrite/rewriteSupport.c:108 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist" msgstr "リレーション\"%2$s\"のルール\"%1$s\"は存在しません" -#: rewrite/rewriteDefine.c:844 +#: rewrite/rewriteDefine.c:853 #, c-format msgid "renaming an ON SELECT rule is not allowed" msgstr "ON SELECTルールの名前を変更することはできません" @@ -26928,12 +27143,12 @@ msgstr "同じ変数名\"%s\"を持つが,ラベル式が異なる要素パタ msgid "an edge cannot connect more than two vertices even in a cyclic pattern" msgstr "ひとつの辺は、循環パターン内であっても3つ以上の頂点に接続することはできません" -#: rewrite/rewriteGraphTable.c:983 +#: rewrite/rewriteGraphTable.c:990 #, c-format msgid "no property graph element of type \"%s\" has label \"%s\" associated with it in property graph \"%s\"" msgstr "プロパティグラフ\"%3$s\"には、ラベル\"%2$s\"が関連付けられた型\"%1$s\"の要素が存在しません" -#: rewrite/rewriteGraphTable.c:1138 +#: rewrite/rewriteGraphTable.c:1145 #, c-format msgid "property \"%s\" for element variable \"%s\" not found" msgstr "要素変数\"%2$s\"に対するプロパティ\"%1$s\"がみつかりません" @@ -27335,7 +27550,7 @@ msgstr "認識できないSnowballパラメータ: \"%s\"" msgid "missing Language parameter" msgstr "Languageパラメータがありません" -#: statistics/attribute_stats.c:181 statistics/attribute_stats.c:620 statistics/extended_stats_funcs.c:371 statistics/extended_stats_funcs.c:1774 statistics/relation_stats.c:98 +#: statistics/attribute_stats.c:181 statistics/attribute_stats.c:620 statistics/extended_stats_funcs.c:371 statistics/extended_stats_funcs.c:1779 statistics/relation_stats.c:98 #, c-format msgid "Statistics cannot be modified during recovery." msgstr "リカバリ中は統計情報の更新はできません。" @@ -27375,7 +27590,7 @@ msgstr "列\"%s\"に対する小なり演算子(<)を特定できませんでし msgid "column \"%s\" is not a range type" msgstr "列\"%s\"は範囲型ではありません" -#: statistics/attribute_stats.c:385 statistics/extended_stats_funcs.c:1354 +#: statistics/attribute_stats.c:385 statistics/extended_stats_funcs.c:1359 #, c-format msgid "could not parse \"%s\": incorrect number of elements (same as \"%s\" required)" msgstr "\"%s\" をパースできません: 要素数が間違っています (\"%s\" と同数が必要です)" @@ -27395,12 +27610,12 @@ msgstr "\"%s\"オブジェクトを検証できませんでした: 不正な属 msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" msgstr "統計オブジェクト\"%s.%s\"がリレーション\"%s.%s\"に対して計算できませんでした" -#: statistics/extended_stats_funcs.c:404 statistics/extended_stats_funcs.c:1794 +#: statistics/extended_stats_funcs.c:404 statistics/extended_stats_funcs.c:1799 #, c-format msgid "could not find schema \"%s\"" msgstr "スキーマ\"%s\"が見つかりませんでした" -#: statistics/extended_stats_funcs.c:416 statistics/extended_stats_funcs.c:1806 +#: statistics/extended_stats_funcs.c:416 statistics/extended_stats_funcs.c:1811 #, c-format msgid "could not find extended statistics object \"%s.%s\"" msgstr "拡張統計オブジェクト \"%s.%s\"が見つかりませんでした" @@ -27450,67 +27665,72 @@ msgstr "配列 \"%s\" をパースできません: 要素数が間違ってい msgid "could not parse array \"%s\": found %d attributes but expected %d" msgstr "配列\"%s\"のパースに失敗しました: %d個の属性がありましたが、%d個を期待していました" -#: statistics/extended_stats_funcs.c:951 +#: statistics/extended_stats_funcs.c:863 +#, c-format +msgid "could not parse array \"%s\": number of items (%d) exceeds maximum (%d)" +msgstr "配列\"%s\"のパースに失敗しました: 要素(%d)が最大値(%d)を超えています" + +#: statistics/extended_stats_funcs.c:967 #, c-format msgid "could not import element in expression %d: invalid key name" msgstr "式 %d 中の要素をインポートできませんでした: 不正なキー名" -#: statistics/extended_stats_funcs.c:1077 +#: statistics/extended_stats_funcs.c:1082 #, c-format msgid "could not import element \"%s\" in expression %d: must be a one-dimensional array" msgstr "式 %2$d 中の要素 \"%1$s\" をインポートできませんでした: 1次元の配列でなければなりません" -#: statistics/extended_stats_funcs.c:1086 +#: statistics/extended_stats_funcs.c:1091 #, c-format msgid "could not import element \"%s\" in expression %d: null value found" msgstr "式 %2$d 中の要素 \"%1$s\" をインポートできませんでした: null値がありました" -#: statistics/extended_stats_funcs.c:1131 statistics/extended_stats_funcs.c:1161 statistics/extended_stats_funcs.c:1181 statistics/extended_stats_funcs.c:1192 statistics/extended_stats_funcs.c:1209 statistics/extended_stats_funcs.c:1654 +#: statistics/extended_stats_funcs.c:1136 statistics/extended_stats_funcs.c:1166 statistics/extended_stats_funcs.c:1186 statistics/extended_stats_funcs.c:1197 statistics/extended_stats_funcs.c:1214 statistics/extended_stats_funcs.c:1659 #, c-format msgid "could not parse \"%s\": invalid element in expression %d" msgstr "\"%s\"のパースに失敗しました: 式%d中に不正な要素" -#: statistics/extended_stats_funcs.c:1162 +#: statistics/extended_stats_funcs.c:1167 #, c-format -msgid "Value of element \"%s\" must be type a null or a string." -msgstr "\"%s\" の値はnullまたは文字列でなければなりません。" +msgid "Value of element \"%s\" must be a null or a string." +msgstr "要素\"%s\"の値はnullまたは文字列でなければなりません。" -#: statistics/extended_stats_funcs.c:1183 statistics/extended_stats_funcs.c:1194 +#: statistics/extended_stats_funcs.c:1188 statistics/extended_stats_funcs.c:1199 #, c-format msgid "\"%s\" and \"%s\" must be both either strings or nulls." msgstr "\"%s\" と \"%s\" は、両方とも文字列か、または両方とも null でなければなりません。" -#: statistics/extended_stats_funcs.c:1211 +#: statistics/extended_stats_funcs.c:1216 #, c-format msgid "\"%s\", \"%s\", and \"%s\" must be all either strings or all nulls." msgstr "\"%s\"、\"%s\"および\"%s\" は、すべてが文字列か、またはすべてが null でなければなりません。" -#: statistics/extended_stats_funcs.c:1243 +#: statistics/extended_stats_funcs.c:1248 #, c-format msgid "could not parse \"%s\": invalid element type in expression %d" msgstr "\"%s\"のパースに失敗しました: 式%d中に不正な要素型" -#: statistics/extended_stats_funcs.c:1262 +#: statistics/extended_stats_funcs.c:1267 #, c-format msgid "could not parse \"%s\": invalid data in expression %d" msgstr "\"%s\"のパースに失敗しました: 式%d中に不正なデータ" -#: statistics/extended_stats_funcs.c:1264 +#: statistics/extended_stats_funcs.c:1269 #, c-format msgid "\"%s\", \"%s\", and \"%s\" can only be set for a range type." msgstr "\"%s\"、\"%s\" および \"%s\"は範囲型に対してのみ設定可能です。" -#: statistics/extended_stats_funcs.c:1579 +#: statistics/extended_stats_funcs.c:1584 #, c-format msgid "could not parse \"%s\": root-level array required" msgstr "\"%s\"のパースに失敗しました: 最上位レベルは配列である必要があります" -#: statistics/extended_stats_funcs.c:1594 +#: statistics/extended_stats_funcs.c:1599 #, c-format msgid "could not parse \"%s\": incorrect number of elements (%d required)" msgstr "\"%s\"のパースに失敗しました: 要素数が不正です (%d要素必要です)" -#: statistics/extended_stats_funcs.c:1822 +#: statistics/extended_stats_funcs.c:1828 #, c-format msgid "could not clear extended statistics object \"%s.%s\": incorrect relation \"%s.%s\" specified" msgstr "拡張統計オブジェクト\"%s.%s\"のクリアに失敗しました: 不正なリレーション\"%s.%s\"が指定されました" @@ -27580,12 +27800,12 @@ msgstr "識別できない引数名: \"%s\"" msgid "argument \"%s\" has type %s, expected type %s" msgstr "引数\"%s\"の型は %s ですが、期待される型は %s です" -#: statistics/stat_utils.c:372 utils/adt/ddlutils.c:141 +#: statistics/stat_utils.c:372 #, c-format msgid "variadic arguments must be name/value pairs" msgstr "可変長引数は名前/値のペアである必要があります" -#: statistics/stat_utils.c:373 utils/adt/ddlutils.c:142 +#: statistics/stat_utils.c:373 #, c-format msgid "Provide an even number of variadic arguments that can be divided into pairs." msgstr "2つ組に分割できるよう、偶数個の可変長引数を指定してください。" @@ -27600,17 +27820,17 @@ msgstr "可変長引数の位置%dの名前がnullです" msgid "name at variadic position %d has type %s, expected type %s" msgstr "可変長引数の位置%dの名前の型が %s ですが、期待される型は %s です" -#: statistics/stat_utils.c:607 +#: statistics/stat_utils.c:596 #, c-format msgid "\"%s\" must be a one-dimensional array" msgstr "\"%s\"は1次元の配列でなければなりません" -#: statistics/stat_utils.c:616 +#: statistics/stat_utils.c:605 #, c-format msgid "\"%s\" array must not contain null values" msgstr "\"%s\"配列にはNULL値を含められません" -#: statistics/stat_utils.c:674 +#: statistics/stat_utils.c:663 #, c-format msgid "maximum number of statistics slots exceeded: %d" msgstr "統計情報スロットの最大数を超過しました: %d" @@ -27648,98 +27868,98 @@ msgstr "プロセス %d に代わってI/O完了させています" msgid "I/O worker executing I/O on behalf of process %d" msgstr "I/Oワーカーがプロセス %d に代わってI/Oを実行中" -#: storage/aio/read_stream.c:787 storage/buffer/bufmgr.c:798 storage/buffer/bufmgr.c:1296 storage/buffer/bufmgr.c:1392 +#: storage/aio/read_stream.c:787 storage/buffer/bufmgr.c:798 storage/buffer/bufmgr.c:1296 storage/buffer/bufmgr.c:1392 storage/buffer/bufmgr.c:2781 #, c-format msgid "cannot access temporary tables of other sessions" msgstr "他のセッションの一時テーブルにはアクセスできません" -#: storage/buffer/bufmgr.c:2888 storage/buffer/localbuf.c:403 +#: storage/buffer/bufmgr.c:2902 storage/buffer/localbuf.c:403 #, c-format msgid "cannot extend relation %s beyond %u blocks" msgstr "リレーション\"%s\"を%uブロックを超えて拡張できません" -#: storage/buffer/bufmgr.c:2952 +#: storage/buffer/bufmgr.c:2966 #, c-format msgid "unexpected data beyond EOF in block %u of relation \"%s\"" msgstr "リレーション\"%2$s\"の%1$uブロック目で、EOF の先に想定外のデータを検出しました" -#: storage/buffer/bufmgr.c:7453 +#: storage/buffer/bufmgr.c:7493 #, c-format msgid "could not write block %u of %s" msgstr "%u ブロックを %s に書き出せませんでした" -#: storage/buffer/bufmgr.c:7457 +#: storage/buffer/bufmgr.c:7497 #, c-format msgid "Multiple failures --- write error might be permanent." msgstr "複数回失敗しました ---ずっと書き込みエラーが続くかもしれません。" -#: storage/buffer/bufmgr.c:7474 storage/buffer/bufmgr.c:7489 +#: storage/buffer/bufmgr.c:7514 storage/buffer/bufmgr.c:7529 #, c-format msgid "writing block %u of relation \"%s\"" msgstr "リレーション\"%2$s\"のブロック%1$uの書き込み中" -#: storage/buffer/bufmgr.c:8828 +#: storage/buffer/bufmgr.c:8868 #, c-format msgid "zeroing %u page(s) and ignoring %u checksum failure(s) among blocks %u..%u of relation \"%s\"" msgstr "リレーション\"%5$s\"のブロック%3$u..%4$uの間の%1$uページをゼロクリアし、%2$u件のチェックサムエラーを無視します" -#: storage/buffer/bufmgr.c:8831 storage/buffer/bufmgr.c:8859 +#: storage/buffer/bufmgr.c:8871 storage/buffer/bufmgr.c:8899 #, c-format msgid "Block %u held the first zeroed page." msgstr "ゼロクリアした最初のページはブロック%uにありました。" -#: storage/buffer/bufmgr.c:8833 +#: storage/buffer/bufmgr.c:8873 #, c-format msgid "See server log for details about the other %d invalid block." msgid_plural "See server log for details about the other %d invalid blocks." msgstr[0] "他の%d個の不正なブロックの詳細については、サーバーログを参照してください。" -#: storage/buffer/bufmgr.c:8850 +#: storage/buffer/bufmgr.c:8890 #, c-format msgid "%u invalid pages among blocks %u..%u of relation \"%s\"" msgstr "リレーション\"%4$s\"のブロック%2$u..%3$uで%1$uの不正なページ" -#: storage/buffer/bufmgr.c:8851 +#: storage/buffer/bufmgr.c:8891 #, c-format msgid "Block %u held the first invalid page." msgstr "最初の不正なページはブロック%uにありました。" -#: storage/buffer/bufmgr.c:8852 +#: storage/buffer/bufmgr.c:8892 #, c-format msgid "See server log for the other %u invalid block(s)." msgstr "他の%u個の不正なブロックについてはサーバーログを参照してください。" -#: storage/buffer/bufmgr.c:8857 +#: storage/buffer/bufmgr.c:8897 #, c-format msgid "invalid page in block %u of relation \"%s\"; zeroing out page" msgstr "リレーション\"%2$s\"の%1$uブロック目のページが不正です: ページをゼロクリアします" -#: storage/buffer/bufmgr.c:8858 +#: storage/buffer/bufmgr.c:8898 #, c-format msgid "zeroing out %u invalid pages among blocks %u..%u of relation \"%s\"" msgstr "リレーション\"%4$s\"のブロック%2$u..%3$u間の%1$u個の不正なページをゼロクリアします" -#: storage/buffer/bufmgr.c:8860 +#: storage/buffer/bufmgr.c:8900 #, c-format msgid "See server log for the other %u zeroed block(s)." msgstr "他の%u個の0クリアしたブロックについてはサーバーログを参照してください。" -#: storage/buffer/bufmgr.c:8865 +#: storage/buffer/bufmgr.c:8905 #, c-format msgid "ignoring checksum failure in block %u of relation \"%s\"" msgstr "リレーション\"%2$s\"のブロック%1$uでのチェックサムエラーを無視します" -#: storage/buffer/bufmgr.c:8866 +#: storage/buffer/bufmgr.c:8906 #, c-format msgid "ignoring %u checksum failures among blocks %u..%u of relation \"%s\"" msgstr "リレーション\"%4$s\"のブロック%2$u..%3$uでの%1$u件のチェックサムエラーを無視します" -#: storage/buffer/bufmgr.c:8867 +#: storage/buffer/bufmgr.c:8907 #, c-format msgid "Block %u held the first ignored page." msgstr "無視した最初のページはブロック%uにありました。" -#: storage/buffer/bufmgr.c:8868 +#: storage/buffer/bufmgr.c:8908 #, c-format msgid "See server log for the other %u ignored block(s)." msgstr "他の%u個のエラーを無視したブロックについてはサーバーログを参照してください。" @@ -27909,12 +28129,12 @@ msgstr "データディレクトリを同期しています(fsync)、経過時 msgid "\"%s\" is not supported on this platform." msgstr "このプラットフォームでは\"%s\"をサポートしていません。" -#: storage/file/fd.c:4015 tcop/backend_startup.c:1115 +#: storage/file/fd.c:4015 tcop/backend_startup.c:1122 #, c-format msgid "Invalid list syntax in parameter \"%s\"." msgstr "パラメータ\"%s\"のリスト構文が不正です。" -#: storage/file/fd.c:4035 tcop/backend_startup.c:1089 +#: storage/file/fd.c:4035 tcop/backend_startup.c:1096 #, c-format msgid "Invalid option \"%s\"." msgstr "不正なオプション\"%s\"。" @@ -28079,42 +28299,42 @@ msgstr "要求されたDSHashはすでに現在のプロセスにアタッチさ msgid "sorry, too many clients already" msgstr "現在クライアント数が多すぎます" -#: storage/ipc/procarray.c:3878 +#: storage/ipc/procarray.c:3865 #, c-format msgid "database \"%s\" is being used by prepared transactions" msgstr "データベース\"%s\"は準備済みトランザクションで使用中です" -#: storage/ipc/procarray.c:3914 storage/ipc/procarray.c:3922 storage/ipc/signalfuncs.c:254 storage/ipc/signalfuncs.c:261 storage/ipc/signalfuncs.c:268 +#: storage/ipc/procarray.c:3901 storage/ipc/procarray.c:3909 storage/ipc/signalfuncs.c:254 storage/ipc/signalfuncs.c:261 storage/ipc/signalfuncs.c:268 #, c-format msgid "permission denied to terminate process" msgstr "プロセスを終了させる権限がありません" -#: storage/ipc/procarray.c:3915 storage/ipc/signalfuncs.c:255 +#: storage/ipc/procarray.c:3902 storage/ipc/signalfuncs.c:255 #, c-format msgid "Only roles with the %s attribute may terminate processes of roles with the %s attribute." msgstr "%s属性を持つロールのみが%s属性を持つロールが接続中のプロセスを終了できます。" -#: storage/ipc/procarray.c:3923 storage/ipc/signalfuncs.c:269 +#: storage/ipc/procarray.c:3910 storage/ipc/signalfuncs.c:269 #, c-format msgid "Only roles with privileges of the role whose process is being terminated or with privileges of the \"%s\" role may terminate this process." msgstr "終了させようとしているプロセスに接続しているロールの権限を持つロール、または\"%sロール権限を持つロールのみがこのプロセスを終了できます。" -#: storage/ipc/procsignal.c:455 +#: storage/ipc/procsignal.c:463 #, c-format msgid "still waiting for backend with PID %d to accept ProcSignalBarrier" msgstr "PID %dのバックエンドがProcSignalBarrierを受け付けるのを待っています" -#: storage/ipc/procsignal.c:735 +#: storage/ipc/procsignal.c:743 #, c-format msgid "invalid cancel request with PID 0" msgstr "PID 0の不正なキャンセル要求" -#: storage/ipc/procsignal.c:790 +#: storage/ipc/procsignal.c:798 #, c-format msgid "wrong key in cancel request for process %d" msgstr "プロセス%dに対するキャンセル要求においてキーが間違っています" -#: storage/ipc/procsignal.c:799 +#: storage/ipc/procsignal.c:807 #, c-format msgid "PID %d in cancel request did not match any process" msgstr "キャンセル要求内のPID %dがどのプロセスにも一致しません" @@ -28169,7 +28389,7 @@ msgstr "共有メモリが足りません (%zu バイト要求しました)" msgid "PID %d is not a PostgreSQL backend process" msgstr "PID %dはPostgreSQLバックエンドプロセスではありません" -#: storage/ipc/signalfuncs.c:121 storage/lmgr/proc.c:1554 utils/adt/mcxtfuncs.c:305 +#: storage/ipc/signalfuncs.c:121 storage/lmgr/proc.c:1587 utils/adt/mcxtfuncs.c:305 #, c-format msgid "could not send signal to process %d: %m" msgstr "プロセス%dにシグナルを送信できませんでした: %m" @@ -28230,49 +28450,49 @@ msgstr "リカバリは%ld.%03dミリ秒経過後待機継続中: %s" msgid "recovery finished waiting after %ld.%03d ms: %s" msgstr "リカバリは%ld.%03dミリ秒で待機終了: %s" -#: storage/ipc/standby.c:923 tcop/postgres.c:3289 +#: storage/ipc/standby.c:923 tcop/postgres.c:3384 #, c-format msgid "canceling statement due to conflict with recovery" msgstr "リカバリで競合が発生したためステートメントをキャンセルしています" -#: storage/ipc/standby.c:924 tcop/postgres.c:2576 +#: storage/ipc/standby.c:924 tcop/postgres.c:2671 #, c-format msgid "User transaction caused buffer deadlock with recovery." msgstr "リカバリ時にユーザーのトランザクションがバッファのデッドロックを引き起こしました。" -#: storage/ipc/standby.c:1517 +#: storage/ipc/standby.c:1497 msgid "unknown reason" msgstr "不明な理由" -#: storage/ipc/standby.c:1522 +#: storage/ipc/standby.c:1502 msgid "recovery conflict on buffer pin" msgstr "バッファピン上のリカバリ競合" -#: storage/ipc/standby.c:1525 +#: storage/ipc/standby.c:1505 msgid "recovery conflict on lock" msgstr "ロック上のリカバリ衝突" -#: storage/ipc/standby.c:1528 +#: storage/ipc/standby.c:1508 msgid "recovery conflict on tablespace" msgstr "テーブル空間上のリカバリ衝突" -#: storage/ipc/standby.c:1531 +#: storage/ipc/standby.c:1511 msgid "recovery conflict on snapshot" msgstr "スナップショット上のリカバリ競合" -#: storage/ipc/standby.c:1534 +#: storage/ipc/standby.c:1514 msgid "recovery conflict on replication slot" msgstr "レプリケーションスロット上のリカバリ競合" -#: storage/ipc/standby.c:1537 +#: storage/ipc/standby.c:1517 msgid "recovery conflict on deadlock" msgstr "デッドロック上のリカバリ衝突" -#: storage/ipc/standby.c:1540 +#: storage/ipc/standby.c:1520 msgid "recovery conflict on buffer deadlock" msgstr "バッファのデッドロック上のリカバリ競合" -#: storage/ipc/standby.c:1543 +#: storage/ipc/standby.c:1523 msgid "recovery conflict on database" msgstr "データベース上のリカバリ衝突" @@ -28536,27 +28756,27 @@ msgstr "リトライが行われた場合、このトランザクションは成 msgid "number of requested standby connections exceeds \"max_wal_senders\" (currently %d)" msgstr "要求されたスタンバイ接続が\"max_wal_senders を超えています\" (現在は %d)" -#: storage/lmgr/proc.c:1609 +#: storage/lmgr/proc.c:1643 #, c-format msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" msgstr "プロセス%1$dは、%4$ld.%5$03d ms後にキューの順番を再調整することで、%3$s上の%2$sに対するデッドロックを防ぎました。" -#: storage/lmgr/proc.c:1624 +#: storage/lmgr/proc.c:1658 #, c-format msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" msgstr "プロセス%1$dは、%3$s上の%2$sに対し%4$ld.%5$03d ms待機するデッドロックを検知しました" -#: storage/lmgr/proc.c:1648 +#: storage/lmgr/proc.c:1682 #, c-format msgid "process %d still waiting for %s on %s after %ld.%03d ms" msgstr "プロセス%dは%sを%sで待機しています。%ld.%03dミリ秒後" -#: storage/lmgr/proc.c:1658 +#: storage/lmgr/proc.c:1692 #, c-format msgid "process %d acquired %s on %s after %ld.%03d ms" msgstr "プロセス%1$dは%4$ld.%5$03d ms後に%3$s上の%2$sを獲得しました" -#: storage/lmgr/proc.c:1675 +#: storage/lmgr/proc.c:1709 #, c-format msgid "process %d failed to acquire %s on %s after %ld.%03d ms" msgstr "プロセス%1$dは%4$ld.%5$03d ms後に%3$s上で%2$sを獲得することに失敗しました" @@ -28741,92 +28961,92 @@ msgstr "直接SSL接続を受け付けられました" msgid "direct SSL connection rejected" msgstr "直接SSL接続が拒否されました" -#: tcop/backend_startup.c:529 tcop/backend_startup.c:557 +#: tcop/backend_startup.c:536 tcop/backend_startup.c:564 #, c-format msgid "incomplete startup packet" msgstr "開始パケットが不完全です" -#: tcop/backend_startup.c:541 +#: tcop/backend_startup.c:548 #, c-format msgid "invalid length of startup packet" msgstr "不正な開始パケット長" -#: tcop/backend_startup.c:598 +#: tcop/backend_startup.c:605 #, c-format msgid "SSLRequest accepted" msgstr "SSLRequestを受け付けました" -#: tcop/backend_startup.c:601 +#: tcop/backend_startup.c:608 #, c-format msgid "SSLRequest rejected" msgstr "SSLRequestを拒否しました" -#: tcop/backend_startup.c:610 +#: tcop/backend_startup.c:617 #, c-format msgid "failed to send SSL negotiation response: %m" msgstr "SSLネゴシエーション応答の送信に失敗しました: %m" -#: tcop/backend_startup.c:631 +#: tcop/backend_startup.c:638 #, c-format msgid "received unencrypted data after SSL request" msgstr "SSL要求の後に非暗号化データを受信しました" -#: tcop/backend_startup.c:632 tcop/backend_startup.c:698 +#: tcop/backend_startup.c:639 tcop/backend_startup.c:705 #, c-format msgid "This could be either a client-software bug or evidence of an attempted man-in-the-middle attack." msgstr "これはクライアントソフトウェアのバグであるか、man-in-the-middle攻撃の証左である可能性があります。" -#: tcop/backend_startup.c:664 +#: tcop/backend_startup.c:671 #, c-format msgid "GSSENCRequest accepted" msgstr "GSSENCRequestを受け付けました" -#: tcop/backend_startup.c:667 +#: tcop/backend_startup.c:674 #, c-format msgid "GSSENCRequest rejected" msgstr "GSSENCRequestを拒否しました" -#: tcop/backend_startup.c:676 +#: tcop/backend_startup.c:683 #, c-format msgid "failed to send GSSAPI negotiation response: %m" msgstr "GSSAPIネゴシエーション応答の送信に失敗しました: %m" -#: tcop/backend_startup.c:697 +#: tcop/backend_startup.c:704 #, c-format msgid "received unencrypted data after GSSAPI encryption request" msgstr "GSSAPI暗号化リクエストの後に非暗号化データを受信" -#: tcop/backend_startup.c:734 +#: tcop/backend_startup.c:741 #, c-format msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" msgstr "フロントエンドプロトコル%u.%uをサポートしていません: サーバーは%u.0から %u.%uまでをサポートします" -#: tcop/backend_startup.c:797 +#: tcop/backend_startup.c:804 #, c-format msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." msgstr "有効な値: \"false\", 0, \"true\", 1, \"database\"。" -#: tcop/backend_startup.c:838 +#: tcop/backend_startup.c:845 #, c-format msgid "invalid startup packet layout: expected terminator as last byte" msgstr "開始パケットの配置が不正です: 最終バイトはターミネータであるはずです" -#: tcop/backend_startup.c:857 +#: tcop/backend_startup.c:864 #, c-format msgid "no PostgreSQL user name specified in startup packet" msgstr "開始パケットで指定されたPostgreSQLユーザー名は存在しません" -#: tcop/backend_startup.c:919 +#: tcop/backend_startup.c:926 #, c-format msgid "invalid length of cancel request packet" msgstr "不正なキャンセル要求パケット長" -#: tcop/backend_startup.c:927 +#: tcop/backend_startup.c:934 #, c-format msgid "invalid length of cancel key in cancel request packet" msgstr "キャンセル要求パケット中の不正なキャンセルキー長" -#: tcop/backend_startup.c:1057 +#: tcop/backend_startup.c:1064 #, c-format msgid "Cannot specify log_connections option \"%s\" in a list with other options." msgstr "log_connectionsオプション\"%s\"は、リスト内で他のオプションと同時に指定できません。" @@ -28846,7 +29066,7 @@ msgstr "関数\"%s\"は高速呼び出しインタフェースでの呼び出し msgid "fastpath function call: \"%s\" (OID %u)" msgstr "近道関数呼び出し: \"%s\"(OID %u))" -#: tcop/fastpath.c:312 tcop/postgres.c:1380 tcop/postgres.c:1615 tcop/postgres.c:2092 tcop/postgres.c:2363 +#: tcop/fastpath.c:312 tcop/postgres.c:1390 tcop/postgres.c:1636 tcop/postgres.c:2123 tcop/postgres.c:2412 #, c-format msgid "duration: %s ms" msgstr "期間: %s ミリ秒" @@ -28881,155 +29101,155 @@ msgstr "関数引数%dのバイナリデータ書式が不正です" msgid "Signal sent by PID %d, UID %d." msgstr "シグナルが PID %d、UID %d から送信されました。" -#: tcop/postgres.c:468 tcop/postgres.c:5108 +#: tcop/postgres.c:469 tcop/postgres.c:5203 #, c-format msgid "invalid frontend message type %d" msgstr "フロントエンドメッセージタイプ%dが不正です" -#: tcop/postgres.c:1088 +#: tcop/postgres.c:1094 #, c-format msgid "statement: %s" msgstr "文: %s" -#: tcop/postgres.c:1385 +#: tcop/postgres.c:1401 #, c-format msgid "duration: %s ms statement: %s" msgstr "期間: %s ミリ秒 文: %s" -#: tcop/postgres.c:1491 +#: tcop/postgres.c:1512 #, c-format msgid "cannot insert multiple commands into a prepared statement" msgstr "準備された文に複数のコマンドを挿入できません" -#: tcop/postgres.c:1620 +#: tcop/postgres.c:1647 #, c-format msgid "duration: %s ms parse %s: %s" msgstr "期間: %s ミリ秒 パース%s : %s" -#: tcop/postgres.c:1687 tcop/postgres.c:2669 +#: tcop/postgres.c:1718 tcop/postgres.c:2764 #, c-format msgid "unnamed prepared statement does not exist" msgstr "無名の準備された文が存在しません" -#: tcop/postgres.c:1739 +#: tcop/postgres.c:1770 #, c-format msgid "bind message has %d parameter formats but %d parameters" msgstr "バインドメッセージは%dパラメータ書式ありましたがパラメータは%dでした" -#: tcop/postgres.c:1745 +#: tcop/postgres.c:1776 #, c-format msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" msgstr "バインドメッセージは%dパラメータを提供しましたが、準備された文\"%s\"では%d必要でした" -#: tcop/postgres.c:1958 +#: tcop/postgres.c:1989 #, c-format msgid "incorrect binary data format in bind parameter %d" msgstr "バインドパラメータ%dにおいてバイナリデータ書式が不正です" -#: tcop/postgres.c:2097 +#: tcop/postgres.c:2134 #, c-format msgid "duration: %s ms bind %s%s%s: %s" msgstr "期間: %s ミリ秒 バインド %s%s%s: %s" -#: tcop/postgres.c:2152 tcop/postgres.c:2750 +#: tcop/postgres.c:2193 tcop/postgres.c:2845 #, c-format msgid "portal \"%s\" does not exist" msgstr "ポータル\"%s\"は存在しません" -#: tcop/postgres.c:2245 +#: tcop/postgres.c:2291 #, c-format msgid "%s %s%s%s: %s" msgstr "%s %s%s%s: %s" -#: tcop/postgres.c:2247 tcop/postgres.c:2371 +#: tcop/postgres.c:2293 tcop/postgres.c:2426 msgid "execute fetch from" msgstr "取り出し実行" -#: tcop/postgres.c:2248 tcop/postgres.c:2372 +#: tcop/postgres.c:2294 tcop/postgres.c:2427 msgid "execute" msgstr "実行" -#: tcop/postgres.c:2368 +#: tcop/postgres.c:2423 #, c-format msgid "duration: %s ms %s %s%s%s: %s" msgstr "期間: %s ミリ秒 %s %s%s%s: %s" -#: tcop/postgres.c:2516 +#: tcop/postgres.c:2611 #, c-format msgid "prepare: %s" msgstr "準備: %s" -#: tcop/postgres.c:2541 +#: tcop/postgres.c:2636 #, c-format msgid "Parameters: %s" msgstr "パラメータ: %s" -#: tcop/postgres.c:2558 +#: tcop/postgres.c:2653 #, c-format msgid "User was holding shared buffer pin for too long." msgstr "ユーザーが共有バッファ・ピンを長く保持し過ぎていました" -#: tcop/postgres.c:2561 +#: tcop/postgres.c:2656 #, c-format msgid "User was holding a relation lock for too long." msgstr "ユーザーリレーションのロックを長く保持し過ぎていました" -#: tcop/postgres.c:2564 +#: tcop/postgres.c:2659 #, c-format msgid "User was or might have been using tablespace that must be dropped." msgstr "削除されるべきテーブルスペースをユーザーが使っていました(もしくはその可能性がありました)。" -#: tcop/postgres.c:2567 +#: tcop/postgres.c:2662 #, c-format msgid "User query might have needed to see row versions that must be removed." msgstr "削除されるべきバージョンの行をユーザー問い合わせが参照しなければならなかった可能性がありました。" -#: tcop/postgres.c:2570 +#: tcop/postgres.c:2665 #, c-format msgid "User was using a logical replication slot that must be invalidated." msgstr "無効化されるべき論理レプリケーションスロットをユーザーが使用していました。" -#: tcop/postgres.c:2573 +#: tcop/postgres.c:2668 #, c-format msgid "User transaction caused deadlock with recovery." msgstr "ユーザーのトランザクションがリカバリとの間でデッドロックを引き起こしました。" -#: tcop/postgres.c:2579 +#: tcop/postgres.c:2674 #, c-format msgid "User was connected to a database that must be dropped." msgstr "削除されるべきデータベースにユーザーが接続していました。" -#: tcop/postgres.c:2615 +#: tcop/postgres.c:2710 #, c-format msgid "portal \"%s\" parameter $%d = %s" msgstr "ポータル\"%s\" パラメータ$%d = %s" -#: tcop/postgres.c:2618 +#: tcop/postgres.c:2713 #, c-format msgid "portal \"%s\" parameter $%d" msgstr "ポータル\"%s\" パラメータ $%d" -#: tcop/postgres.c:2624 +#: tcop/postgres.c:2719 #, c-format msgid "unnamed portal parameter $%d = %s" msgstr "無名ポータルパラメータ $%d = %s" -#: tcop/postgres.c:2627 +#: tcop/postgres.c:2722 #, c-format msgid "unnamed portal parameter $%d" msgstr "無名ポータルパラメータ $%d" -#: tcop/postgres.c:2980 +#: tcop/postgres.c:3075 #, c-format msgid "terminating connection because of unexpected SIGQUIT signal" msgstr "予期しないSIGQUITシグナルによりコネクションを終了します" -#: tcop/postgres.c:2986 +#: tcop/postgres.c:3081 #, c-format msgid "terminating connection because of crash of another server process" msgstr "他のサーバープロセスがクラッシュしたため接続を終了します" -#: tcop/postgres.c:2987 +#: tcop/postgres.c:3082 #, c-format msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." msgstr "" @@ -29037,167 +29257,167 @@ msgstr "" "postmasterはこのサーバープロセスに対し、現在のトランザクションをロールバック\n" "し終了するよう指示しました。" -#: tcop/postgres.c:2991 tcop/postgres.c:3303 +#: tcop/postgres.c:3086 tcop/postgres.c:3398 #, c-format msgid "In a moment you should be able to reconnect to the database and repeat your command." msgstr "この後、データベースに再接続し、コマンドを繰り返さなければなりません。" -#: tcop/postgres.c:2998 +#: tcop/postgres.c:3093 #, c-format msgid "terminating connection due to immediate shutdown command" msgstr "即時シャットダウンコマンドによりコネクションを終了します" -#: tcop/postgres.c:3087 +#: tcop/postgres.c:3182 #, c-format msgid "floating-point exception" msgstr "浮動小数点例外" -#: tcop/postgres.c:3088 +#: tcop/postgres.c:3183 #, c-format msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." msgstr "不正な浮動小数点演算がシグナルされました。おそらくこれは、範囲外の結果もしくは0除算のような不正な演算によるものです。" -#: tcop/postgres.c:3215 tcop/postgres.c:3301 +#: tcop/postgres.c:3310 tcop/postgres.c:3396 #, c-format msgid "terminating connection due to conflict with recovery" msgstr "リカバリで競合が発生したため、接続を終了しています" -#: tcop/postgres.c:3385 +#: tcop/postgres.c:3480 #, c-format msgid "canceling authentication due to timeout" msgstr "タイムアウトにより認証処理をキャンセルしています" -#: tcop/postgres.c:3389 +#: tcop/postgres.c:3484 #, c-format msgid "terminating autovacuum process due to administrator command" msgstr "管理者コマンドにより自動VACUUM処理を終了しています" -#: tcop/postgres.c:3394 +#: tcop/postgres.c:3489 #, c-format msgid "terminating logical replication worker due to administrator command" msgstr "管理者コマンドにより、論理レプリケーションワーカーを終了します" -#: tcop/postgres.c:3411 +#: tcop/postgres.c:3506 #, c-format msgid "terminating walreceiver process due to administrator command" msgstr "管理者コマンドにより WAL 受信プロセスを終了しています" -#: tcop/postgres.c:3416 +#: tcop/postgres.c:3511 #, c-format msgid "terminating background worker \"%s\" due to administrator command" msgstr "管理者コマンドによりバックグラウンドワーカー\"%s\"を終了しています" -#: tcop/postgres.c:3430 +#: tcop/postgres.c:3525 #, c-format msgid "terminating connection due to administrator command" msgstr "管理者コマンドにより接続を終了しています" -#: tcop/postgres.c:3462 +#: tcop/postgres.c:3557 #, c-format msgid "connection to client lost" msgstr "クライアントへの接続が切れました。" -#: tcop/postgres.c:3514 +#: tcop/postgres.c:3609 #, c-format msgid "canceling statement due to lock timeout" msgstr "ロックのタイムアウトのためステートメントをキャンセルしています" -#: tcop/postgres.c:3521 +#: tcop/postgres.c:3616 #, c-format msgid "canceling statement due to statement timeout" msgstr "ステートメントのタイムアウトのためステートメントをキャンセルしています" -#: tcop/postgres.c:3528 +#: tcop/postgres.c:3623 #, c-format msgid "canceling autovacuum task" msgstr "自動VACUUM処理をキャンセルしています" -#: tcop/postgres.c:3541 +#: tcop/postgres.c:3636 #, c-format msgid "canceling statement due to user request" msgstr "ユーザーからの要求により文をキャンセルしています" -#: tcop/postgres.c:3562 +#: tcop/postgres.c:3657 #, c-format msgid "terminating connection due to idle-in-transaction timeout" msgstr "トランザクション中アイドルタイムアウトのため接続を終了します" -#: tcop/postgres.c:3575 +#: tcop/postgres.c:3670 #, c-format msgid "terminating connection due to transaction timeout" msgstr "トランザクションタイムアウトのため接続を終了します" -#: tcop/postgres.c:3588 +#: tcop/postgres.c:3683 #, c-format msgid "terminating connection due to idle-session timeout" msgstr "アイドルセッションタイムアウトにより接続を終了します" -#: tcop/postgres.c:3630 +#: tcop/postgres.c:3725 #, c-format msgid "\"client_connection_check_interval\" must be set to 0 on this platform." msgstr "このプラットフォームでは\"client_connection_check_interval\"を0に設定する必要があります。" -#: tcop/postgres.c:3651 +#: tcop/postgres.c:3746 #, c-format msgid "Cannot enable parameter when \"log_statement_stats\" is true." msgstr "\"log_statement_stats\"が真の場合、パラメータを有効にできません" -#: tcop/postgres.c:3666 +#: tcop/postgres.c:3761 #, c-format msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." msgstr "\"log_parser_stats\"、\"log_planner_stats\"、または\"log_executor_stats\"のいずれかがtrueの場合は\"log_statement_stats\"を有効にできません。" -#: tcop/postgres.c:4109 +#: tcop/postgres.c:4204 #, c-format msgid "invalid command-line argument for server process: %s" msgstr "サーバープロセスに対する不正なコマンドライン引数: %s" -#: tcop/postgres.c:4110 tcop/postgres.c:4116 +#: tcop/postgres.c:4205 tcop/postgres.c:4211 #, c-format msgid "Try \"%s --help\" for more information." msgstr "詳細は\"%s --help\"を実行してください。" -#: tcop/postgres.c:4114 +#: tcop/postgres.c:4209 #, c-format msgid "%s: invalid command-line argument: %s" msgstr "%s: 不正なコマンドライン引数: %s" -#: tcop/postgres.c:4158 +#: tcop/postgres.c:4253 #, c-format msgid "%s: no database nor user name specified" msgstr "%s: データベース名もユーザー名も指定されていません" -#: tcop/postgres.c:4365 +#: tcop/postgres.c:4460 #, c-format msgid "could not generate random cancel key" msgstr "ランダムなキャンセルキーを生成できませんでした" -#: tcop/postgres.c:4767 +#: tcop/postgres.c:4862 #, c-format msgid "connection ready: setup total=%.3f ms, fork=%.3f ms, authentication=%.3f ms" msgstr "接続完了: 所要時間=%.3fミリ秒、fork=%.3fミリ秒、認証処理=%.3fミリ秒" -#: tcop/postgres.c:4998 +#: tcop/postgres.c:5093 #, c-format msgid "invalid CLOSE message subtype %d" msgstr "不正なCLOSEメッセージのサブタイプ%d" -#: tcop/postgres.c:5035 +#: tcop/postgres.c:5130 #, c-format msgid "invalid DESCRIBE message subtype %d" msgstr "不正なDESCRIBEメッセージのサブタイプ%d" -#: tcop/postgres.c:5129 +#: tcop/postgres.c:5224 #, c-format msgid "fastpath function calls not supported in a replication connection" msgstr "レプリケーション接続では高速関数呼び出しはサポートされていません" -#: tcop/postgres.c:5133 +#: tcop/postgres.c:5228 #, c-format msgid "extended query protocol not supported in a replication connection" msgstr "レプリケーション接続では拡張問い合わせプロトコルはサポートされていません" -#: tcop/postgres.c:5279 +#: tcop/postgres.c:5374 #, c-format msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" msgstr "接続を切断: セッション時間: %d:%02d:%02d.%03d ユーザー=%s データベース=%s ホスト=%s%s%s" @@ -29287,17 +29507,17 @@ msgstr "重複するAcceptパラメータ" msgid "unrecognized simple dictionary parameter: \"%s\"" msgstr "認識できない単純辞書パラメータ: \"%s\"" -#: tsearch/dict_synonym.c:120 +#: tsearch/dict_synonym.c:119 #, c-format msgid "unrecognized synonym parameter: \"%s\"" msgstr "認識できない類義語パラメータ: \"%s\"" -#: tsearch/dict_synonym.c:127 +#: tsearch/dict_synonym.c:126 #, c-format msgid "missing Synonyms parameter" msgstr "類義語パラメータがありません" -#: tsearch/dict_synonym.c:134 +#: tsearch/dict_synonym.c:133 #, c-format msgid "could not open synonym file \"%s\": %m" msgstr "類義語ファイル\"%s\"をオープンできませんでした: %m" @@ -29427,7 +29647,7 @@ msgstr "別名の数が指定された数 %d を超えています" msgid "affix file contains both old-style and new-style commands" msgstr "接辞ファイルが新旧両方の形式のコマンドを含んでいます" -#: tsearch/to_tsany.c:194 utils/adt/tsvector.c:274 utils/adt/tsvector_op.c:1127 +#: tsearch/to_tsany.c:194 utils/adt/tsvector.c:274 utils/adt/tsvector_op.c:1100 #, c-format msgid "string is too long for tsvector (%d bytes, max %d bytes)" msgstr "TSベクターのための文字列が長すぎます(%dバイト、最大は%dバイト)" @@ -29728,8 +29948,8 @@ msgstr "入力データ型を特定できませんでした" msgid "input data type is not an array" msgstr "入力データ型は配列ではありません" -#: utils/adt/array_userfuncs.c:168 utils/adt/array_userfuncs.c:250 utils/adt/bytea.c:177 utils/adt/bytea.c:1284 utils/adt/float.c:1270 utils/adt/float.c:1344 utils/adt/float.c:4259 utils/adt/float.c:4299 utils/adt/int.c:807 utils/adt/int.c:829 utils/adt/int.c:843 utils/adt/int.c:857 utils/adt/int.c:888 utils/adt/int.c:909 utils/adt/int.c:1026 utils/adt/int.c:1040 utils/adt/int.c:1054 utils/adt/int.c:1087 utils/adt/int.c:1101 utils/adt/int.c:1115 utils/adt/int.c:1146 -#: utils/adt/int.c:1229 utils/adt/int.c:1293 utils/adt/int.c:1361 utils/adt/int.c:1367 utils/adt/int8.c:1266 utils/adt/numeric.c:2021 utils/adt/numeric.c:4392 utils/adt/rangetypes.c:1722 utils/adt/rangetypes.c:1735 utils/adt/varbit.c:1195 utils/adt/varbit.c:1596 utils/adt/varlena.c:875 +#: utils/adt/array_userfuncs.c:168 utils/adt/array_userfuncs.c:250 utils/adt/bytea.c:177 utils/adt/bytea.c:1284 utils/adt/float.c:1270 utils/adt/float.c:1344 utils/adt/float.c:4327 utils/adt/float.c:4367 utils/adt/int.c:807 utils/adt/int.c:829 utils/adt/int.c:843 utils/adt/int.c:857 utils/adt/int.c:888 utils/adt/int.c:909 utils/adt/int.c:1026 utils/adt/int.c:1040 utils/adt/int.c:1054 utils/adt/int.c:1087 utils/adt/int.c:1101 utils/adt/int.c:1115 utils/adt/int.c:1146 +#: utils/adt/int.c:1229 utils/adt/int.c:1293 utils/adt/int.c:1361 utils/adt/int.c:1367 utils/adt/int8.c:1266 utils/adt/numeric.c:2027 utils/adt/numeric.c:4398 utils/adt/rangetypes.c:1722 utils/adt/rangetypes.c:1735 utils/adt/varbit.c:1195 utils/adt/varbit.c:1596 utils/adt/varlena.c:875 #, c-format msgid "integer out of range" msgstr "integerの範囲外です" @@ -29884,7 +30104,7 @@ msgstr "不正な配列フラグ" msgid "binary data has array element type %u (%s) instead of expected %u (%s)" msgstr "バイナリデータ中に期待される型%3$u(%4$s)の代わりに%1$u(%2$s)がありました" -#: utils/adt/arrayfuncs.c:1382 utils/adt/multirangetypes.c:453 utils/adt/rangetypes.c:357 utils/cache/lsyscache.c:3191 +#: utils/adt/arrayfuncs.c:1382 utils/adt/multirangetypes.c:453 utils/adt/rangetypes.c:357 utils/cache/lsyscache.c:3266 #, c-format msgid "no binary input function available for type %s" msgstr "型%sにはバイナリ入力関数がありません" @@ -29894,7 +30114,7 @@ msgstr "型%sにはバイナリ入力関数がありません" msgid "improper binary format in array element %d" msgstr "配列要素%dのバイナリ書式が不適切です" -#: utils/adt/arrayfuncs.c:1593 utils/adt/multirangetypes.c:458 utils/adt/rangetypes.c:362 utils/cache/lsyscache.c:3224 +#: utils/adt/arrayfuncs.c:1593 utils/adt/multirangetypes.c:458 utils/adt/rangetypes.c:362 utils/cache/lsyscache.c:3299 #, c-format msgid "no binary output function available for type %s" msgstr "型%sにはバイナリ出力関数がありません" @@ -30051,7 +30271,7 @@ msgstr "%s符号化方式からASCIIへの変換はサポートされていま #. translator: first %s is inet or cidr #: utils/adt/bool.c:150 utils/adt/cash.c:356 utils/adt/datetime.c:4291 utils/adt/float.c:248 utils/adt/float.c:335 utils/adt/float.c:349 utils/adt/float.c:454 utils/adt/float.c:537 utils/adt/float.c:551 utils/adt/geo_ops.c:251 utils/adt/geo_ops.c:336 utils/adt/geo_ops.c:1020 utils/adt/geo_ops.c:1466 utils/adt/geo_ops.c:1503 utils/adt/geo_ops.c:1511 utils/adt/geo_ops.c:3512 utils/adt/geo_ops.c:4751 utils/adt/geo_ops.c:4766 utils/adt/geo_ops.c:4773 utils/adt/int.c:198 -#: utils/adt/int.c:210 utils/adt/jsonpath.c:185 utils/adt/mac.c:83 utils/adt/mac8.c:226 utils/adt/network.c:97 utils/adt/numeric.c:788 utils/adt/numeric.c:6966 utils/adt/numeric.c:7169 utils/adt/numeric.c:8016 utils/adt/numutils.c:355 utils/adt/numutils.c:616 utils/adt/numutils.c:877 utils/adt/numutils.c:916 utils/adt/numutils.c:938 utils/adt/numutils.c:1002 utils/adt/numutils.c:1024 utils/adt/pg_lsn.c:59 utils/adt/tid.c:71 utils/adt/tid.c:79 utils/adt/tid.c:93 +#: utils/adt/int.c:210 utils/adt/jsonpath.c:185 utils/adt/mac.c:83 utils/adt/mac8.c:226 utils/adt/network.c:97 utils/adt/numeric.c:788 utils/adt/numeric.c:6972 utils/adt/numeric.c:7175 utils/adt/numeric.c:8022 utils/adt/numutils.c:355 utils/adt/numutils.c:616 utils/adt/numutils.c:877 utils/adt/numutils.c:916 utils/adt/numutils.c:938 utils/adt/numutils.c:1002 utils/adt/numutils.c:1024 utils/adt/pg_lsn.c:59 utils/adt/tid.c:71 utils/adt/tid.c:79 utils/adt/tid.c:93 #: utils/adt/tid.c:102 utils/adt/timestamp.c:508 utils/adt/uuid.c:176 utils/adt/xid8funcs.c:324 #, c-format msgid "invalid input syntax for type %s: \"%s\"" @@ -30077,13 +30297,13 @@ msgstr "インデックス%は有効範囲0..%の間にありま msgid "new bit must be 0 or 1" msgstr "新しいビットは0か1でなければなりません" -#: utils/adt/bytea.c:1259 utils/adt/float.c:1295 utils/adt/float.c:1369 utils/adt/int.c:384 utils/adt/int.c:922 utils/adt/int.c:944 utils/adt/int.c:958 utils/adt/int.c:972 utils/adt/int.c:1004 utils/adt/int.c:1243 utils/adt/int8.c:1287 utils/adt/numeric.c:4523 utils/adt/numeric.c:4528 +#: utils/adt/bytea.c:1259 utils/adt/float.c:1295 utils/adt/float.c:1369 utils/adt/int.c:384 utils/adt/int.c:922 utils/adt/int.c:944 utils/adt/int.c:958 utils/adt/int.c:972 utils/adt/int.c:1004 utils/adt/int.c:1243 utils/adt/int8.c:1287 utils/adt/numeric.c:4529 utils/adt/numeric.c:4534 #, c-format msgid "smallint out of range" msgstr "smallintの範囲外です" #: utils/adt/bytea.c:1309 utils/adt/cash.c:1196 utils/adt/cash.c:1229 utils/adt/int8.c:455 utils/adt/int8.c:478 utils/adt/int8.c:492 utils/adt/int8.c:506 utils/adt/int8.c:537 utils/adt/int8.c:562 utils/adt/int8.c:645 utils/adt/int8.c:713 utils/adt/int8.c:719 utils/adt/int8.c:736 utils/adt/int8.c:750 utils/adt/int8.c:908 utils/adt/int8.c:922 utils/adt/int8.c:936 utils/adt/int8.c:967 utils/adt/int8.c:989 utils/adt/int8.c:1003 utils/adt/int8.c:1017 utils/adt/int8.c:1050 -#: utils/adt/int8.c:1064 utils/adt/int8.c:1078 utils/adt/int8.c:1109 utils/adt/int8.c:1131 utils/adt/int8.c:1145 utils/adt/int8.c:1159 utils/adt/int8.c:1323 utils/adt/int8.c:1359 utils/adt/numeric.c:4468 utils/adt/rangetypes.c:1769 utils/adt/rangetypes.c:1782 utils/adt/varbit.c:1676 +#: utils/adt/int8.c:1064 utils/adt/int8.c:1078 utils/adt/int8.c:1109 utils/adt/int8.c:1131 utils/adt/int8.c:1145 utils/adt/int8.c:1159 utils/adt/int8.c:1323 utils/adt/int8.c:1359 utils/adt/numeric.c:4474 utils/adt/rangetypes.c:1769 utils/adt/rangetypes.c:1782 utils/adt/varbit.c:1676 #, c-format msgid "bigint out of range" msgstr "bigintの範囲外です" @@ -30103,8 +30323,8 @@ msgstr "%dバイトを期待していましたが、%dバイトを受信しま msgid "money out of range" msgstr "マネー型の値が範囲外です" -#: utils/adt/cash.c:162 utils/adt/cash.c:731 utils/adt/float.c:123 utils/adt/float.c:147 utils/adt/int.c:872 utils/adt/int.c:988 utils/adt/int.c:1068 utils/adt/int.c:1130 utils/adt/int.c:1168 utils/adt/int.c:1196 utils/adt/int8.c:521 utils/adt/int8.c:581 utils/adt/int8.c:951 utils/adt/int8.c:1031 utils/adt/int8.c:1093 utils/adt/int8.c:1173 utils/adt/numeric.c:3243 utils/adt/numeric.c:3278 utils/adt/numeric.c:3296 utils/adt/numeric.c:3408 utils/adt/numeric.c:8941 -#: utils/adt/numeric.c:9465 utils/adt/numeric.c:9581 utils/adt/numeric.c:11092 utils/adt/timestamp.c:3773 +#: utils/adt/cash.c:162 utils/adt/cash.c:731 utils/adt/float.c:123 utils/adt/float.c:147 utils/adt/int.c:872 utils/adt/int.c:988 utils/adt/int.c:1068 utils/adt/int.c:1130 utils/adt/int.c:1168 utils/adt/int.c:1196 utils/adt/int8.c:521 utils/adt/int8.c:581 utils/adt/int8.c:951 utils/adt/int8.c:1031 utils/adt/int8.c:1093 utils/adt/int8.c:1173 utils/adt/numeric.c:3249 utils/adt/numeric.c:3284 utils/adt/numeric.c:3302 utils/adt/numeric.c:3414 utils/adt/numeric.c:8947 +#: utils/adt/numeric.c:9471 utils/adt/numeric.c:9587 utils/adt/numeric.c:11098 utils/adt/timestamp.c:3773 #, c-format msgid "division by zero" msgstr "0 による除算が行われました" @@ -30179,7 +30399,7 @@ msgstr "単位\"%s\"は型%sに対してはサポートされていません" msgid "unit \"%s\" not recognized for type %s" msgstr "単位\"%s\"は型%sに対しては認識できません" -#: utils/adt/date.c:1378 utils/adt/date.c:1460 utils/adt/date.c:2029 utils/adt/date.c:2061 utils/adt/date.c:2091 utils/adt/date.c:2994 utils/adt/date.c:3229 utils/adt/datetime.c:433 utils/adt/datetime.c:1833 utils/adt/ddlutils.c:416 utils/adt/formatting.c:3976 utils/adt/formatting.c:4012 utils/adt/formatting.c:4097 utils/adt/formatting.c:4216 utils/adt/json.c:374 utils/adt/json.c:413 utils/adt/timestamp.c:243 utils/adt/timestamp.c:275 utils/adt/timestamp.c:703 +#: utils/adt/date.c:1378 utils/adt/date.c:1460 utils/adt/date.c:2029 utils/adt/date.c:2061 utils/adt/date.c:2091 utils/adt/date.c:2994 utils/adt/date.c:3229 utils/adt/datetime.c:433 utils/adt/datetime.c:1833 utils/adt/ddlutils.c:247 utils/adt/formatting.c:3976 utils/adt/formatting.c:4012 utils/adt/formatting.c:4097 utils/adt/formatting.c:4216 utils/adt/json.c:374 utils/adt/json.c:413 utils/adt/timestamp.c:243 utils/adt/timestamp.c:275 utils/adt/timestamp.c:703 #: utils/adt/timestamp.c:712 utils/adt/timestamp.c:791 utils/adt/timestamp.c:824 utils/adt/timestamp.c:3121 utils/adt/timestamp.c:3130 utils/adt/timestamp.c:3147 utils/adt/timestamp.c:3152 utils/adt/timestamp.c:3171 utils/adt/timestamp.c:3184 utils/adt/timestamp.c:3195 utils/adt/timestamp.c:3201 utils/adt/timestamp.c:3207 utils/adt/timestamp.c:3212 utils/adt/timestamp.c:3266 utils/adt/timestamp.c:3275 utils/adt/timestamp.c:3296 utils/adt/timestamp.c:3301 #: utils/adt/timestamp.c:3322 utils/adt/timestamp.c:3335 utils/adt/timestamp.c:3349 utils/adt/timestamp.c:3357 utils/adt/timestamp.c:3363 utils/adt/timestamp.c:3368 utils/adt/timestamp.c:4441 utils/adt/timestamp.c:4594 utils/adt/timestamp.c:4671 utils/adt/timestamp.c:4738 utils/adt/timestamp.c:4828 utils/adt/timestamp.c:4908 utils/adt/timestamp.c:4978 utils/adt/timestamp.c:5081 utils/adt/timestamp.c:5569 utils/adt/timestamp.c:5844 utils/adt/timestamp.c:6380 #: utils/adt/timestamp.c:6390 utils/adt/timestamp.c:6395 utils/adt/timestamp.c:6401 utils/adt/timestamp.c:6442 utils/adt/timestamp.c:6522 utils/adt/timestamp.c:6592 utils/adt/timestamp.c:6603 utils/adt/timestamp.c:6659 utils/adt/timestamp.c:6663 utils/adt/timestamp.c:6669 utils/adt/timestamp.c:6711 utils/adt/xml.c:2618 utils/adt/xml.c:2625 utils/adt/xml.c:2645 utils/adt/xml.c:2652 @@ -30212,7 +30432,7 @@ msgstr "無限大のintervalのtimeへの加算はできません" msgid "cannot subtract infinite interval from time" msgstr "無限大のintervalのtimeからの減算できません" -#: utils/adt/date.c:2232 utils/adt/date.c:2790 utils/adt/float.c:1084 utils/adt/float.c:1160 utils/adt/int.c:664 utils/adt/int.c:711 utils/adt/int.c:746 utils/adt/int8.c:420 utils/adt/numeric.c:2598 utils/adt/timestamp.c:3870 utils/adt/timestamp.c:3907 utils/adt/timestamp.c:3948 +#: utils/adt/date.c:2232 utils/adt/date.c:2790 utils/adt/float.c:1084 utils/adt/float.c:1160 utils/adt/int.c:664 utils/adt/int.c:711 utils/adt/int.c:746 utils/adt/int8.c:420 utils/adt/numeric.c:2604 utils/adt/timestamp.c:3870 utils/adt/timestamp.c:3907 utils/adt/timestamp.c:3948 #, c-format msgid "invalid preceding or following size in window function" msgstr "ウィンドウ関数での不正なサイズの PRECEDING または FOLLOWING 指定" @@ -30267,7 +30487,7 @@ msgstr "このタイムゾーンはタイムゾーン省略名\"%s\"の構成フ msgid "invalid Datum pointer" msgstr "不正なDatumポインタ" -#: utils/adt/dbsize.c:293 utils/adt/ddlutils.c:674 utils/adt/ddlutils.c:992 utils/adt/genfile.c:657 +#: utils/adt/dbsize.c:293 utils/adt/ddlutils.c:495 utils/adt/ddlutils.c:790 utils/adt/genfile.c:657 #, c-format msgid "tablespace with OID %u does not exist" msgstr "OID %uのテーブル空間は存在しません" @@ -30287,72 +30507,52 @@ msgstr "不正なサイズの単位: \"%s\"" msgid "Valid units are \"bytes\", \"B\", \"kB\", \"MB\", \"GB\", \"TB\", and \"PB\"." msgstr "有効な単位は \"bytes\"、\"B\"、\"kB\"、\"MB\"、\"GB\"、\"TB\"そして\"PB\"です。" -#: utils/adt/ddlutils.c:157 -#, c-format -msgid "option name at variadic position %d is null" -msgstr "可変長引数の位置%dのオプション名がnullです" - -#: utils/adt/ddlutils.c:164 -#, c-format -msgid "value for option \"%s\" must not be null" -msgstr "オプション\"%s\"の値はnullであってはなりません" - -#: utils/adt/ddlutils.c:179 -#, c-format -msgid "unrecognized option: \"%s\"" -msgstr "認識できないオプション: \"%s\"" - -#: utils/adt/ddlutils.c:184 -#, c-format -msgid "option \"%s\" is specified more than once" -msgstr "オプション\"%s\"が複数指定されました" - -#: utils/adt/ddlutils.c:335 utils/init/miscinit.c:762 +#: utils/adt/ddlutils.c:166 utils/init/miscinit.c:762 #, c-format msgid "role with OID %u does not exist" msgstr "OID が %u であるロールは存在しません" -#: utils/adt/ddlutils.c:346 +#: utils/adt/ddlutils.c:177 #, c-format msgid "permission denied for role %s" msgstr "ロール %s には権限がありません" -#: utils/adt/ddlutils.c:357 +#: utils/adt/ddlutils.c:188 #, c-format msgid "Role names starting with \"pg_\" are reserved for system roles." msgstr "\"pg_\"で始まるロール名はシステムロールとして予約されています。" -#: utils/adt/ddlutils.c:694 +#: utils/adt/ddlutils.c:515 #, c-format msgid "tablespace name \"%s\" is reserved" msgstr "テーブル空間名\"%s\"は予約されています" -#: utils/adt/ddlutils.c:695 +#: utils/adt/ddlutils.c:516 #, c-format msgid "Tablespace names starting with \"pg_\" are reserved for system tablespaces." msgstr "\"pg_\"で始まるテーブル空間名はシステムテーブル空間用に予約されています。" -#: utils/adt/ddlutils.c:897 +#: utils/adt/ddlutils.c:695 #, c-format msgid "cannot generate DDL for invalid database \"%s\"" msgstr "無効なデータベース\"%s\"に対するDDLは生成できません" -#: utils/adt/ddlutils.c:907 +#: utils/adt/ddlutils.c:705 #, c-format msgid "database \"%s\" is a system database" msgstr "データベース\"%s\"はシステムデータベースです" -#: utils/adt/ddlutils.c:908 +#: utils/adt/ddlutils.c:706 #, c-format msgid "DDL generation is not supported for template0 and template1." msgstr "DDL生成は template0 と template1 に対してはサポートされていません。" -#: utils/adt/ddlutils.c:937 +#: utils/adt/ddlutils.c:735 #, c-format msgid "unrecognized locale provider: %c" msgstr "認識できないロケールプロバイダ: %c" -#: utils/adt/ddlutils.c:994 +#: utils/adt/ddlutils.c:792 #, c-format msgid "It may have been concurrently dropped." msgstr "並行して削除されたかも知れません。" @@ -30472,27 +30672,27 @@ msgstr "型realでは\"%s\"は範囲外です" msgid "\"%s\" is out of range for type double precision" msgstr "型double precisionでは\"%s\"は範囲外です" -#: utils/adt/float.c:1495 utils/adt/numeric.c:3675 utils/adt/numeric.c:9996 +#: utils/adt/float.c:1495 utils/adt/numeric.c:3681 utils/adt/numeric.c:10002 #, c-format msgid "cannot take square root of a negative number" msgstr "負の値の平方根を取ることができません" -#: utils/adt/float.c:1563 utils/adt/numeric.c:3963 utils/adt/numeric.c:4075 +#: utils/adt/float.c:1563 utils/adt/numeric.c:3969 utils/adt/numeric.c:4081 #, c-format msgid "zero raised to a negative power is undefined" msgstr "0 の負数乗は定義されていません" -#: utils/adt/float.c:1567 utils/adt/numeric.c:3967 utils/adt/numeric.c:10887 +#: utils/adt/float.c:1567 utils/adt/numeric.c:3973 utils/adt/numeric.c:10893 #, c-format msgid "a negative number raised to a non-integer power yields a complex result" msgstr "負数を整数でない数でべき乗すると、結果が複雑になります" -#: utils/adt/float.c:1743 utils/adt/float.c:1776 utils/adt/numeric.c:3875 utils/adt/numeric.c:10667 +#: utils/adt/float.c:1743 utils/adt/float.c:1776 utils/adt/numeric.c:3881 utils/adt/numeric.c:10673 #, c-format msgid "cannot take logarithm of zero" msgstr "ゼロの対数を取ることができません" -#: utils/adt/float.c:1747 utils/adt/float.c:1780 utils/adt/numeric.c:3813 utils/adt/numeric.c:3870 utils/adt/numeric.c:10671 +#: utils/adt/float.c:1747 utils/adt/float.c:1780 utils/adt/numeric.c:3819 utils/adt/numeric.c:3876 utils/adt/numeric.c:10677 #, c-format msgid "cannot take logarithm of a negative number" msgstr "負の値の対数を取ることができません" @@ -30502,22 +30702,22 @@ msgstr "負の値の対数を取ることができません" msgid "input is out of range" msgstr "入力が範囲外です" -#: utils/adt/float.c:4240 utils/adt/numeric.c:1965 +#: utils/adt/float.c:4308 utils/adt/numeric.c:1971 #, c-format msgid "count must be greater than zero" msgstr "カウントは0より大きくなければなりません" -#: utils/adt/float.c:4245 utils/adt/numeric.c:1972 +#: utils/adt/float.c:4313 utils/adt/numeric.c:1978 #, c-format msgid "lower and upper bounds cannot be NaN" msgstr "下限および上限をNaNにすることはできません" -#: utils/adt/float.c:4250 utils/adt/numeric.c:1977 utils/adt/pseudorandomfuncs.c:214 utils/adt/pseudorandomfuncs.c:240 utils/adt/pseudorandomfuncs.c:266 +#: utils/adt/float.c:4318 utils/adt/numeric.c:1983 utils/adt/pseudorandomfuncs.c:214 utils/adt/pseudorandomfuncs.c:240 utils/adt/pseudorandomfuncs.c:266 #, c-format msgid "lower and upper bounds must be finite" msgstr "下限および上限は有限でなければなりません" -#: utils/adt/float.c:4316 utils/adt/numeric.c:1991 +#: utils/adt/float.c:4384 utils/adt/numeric.c:1997 #, c-format msgid "lower bound cannot equal upper bound" msgstr "下限を上限と同じにはできません" @@ -30867,7 +31067,7 @@ msgstr "配列は有効な int2vector ではありません" msgid "invalid int2vector data" msgstr "不正なint2vectorデータ" -#: utils/adt/int.c:1559 utils/adt/int8.c:1423 utils/adt/numeric.c:1752 utils/adt/timestamp.c:6760 utils/adt/timestamp.c:6846 +#: utils/adt/int.c:1559 utils/adt/int8.c:1423 utils/adt/numeric.c:1758 utils/adt/timestamp.c:6760 utils/adt/timestamp.c:6846 #, c-format msgid "step size cannot equal zero" msgstr "ステップ数をゼロにすることはできません" @@ -31280,7 +31480,7 @@ msgstr "jsonpathメンバアクセサはオブジェクトに対してのみ適 msgid "jsonpath item method .%s() can only be applied to an array" msgstr "jsonpath 項目メソッド .%s() は配列にのみ適用可能です" -#: utils/adt/jsonpath_exec.c:1195 utils/adt/jsonpath_exec.c:1221 utils/adt/jsonpath_exec.c:1307 utils/adt/jsonpath_exec.c:1332 utils/adt/jsonpath_exec.c:1383 utils/adt/jsonpath_exec.c:1403 utils/adt/jsonpath_exec.c:1464 utils/adt/jsonpath_exec.c:1552 utils/adt/jsonpath_exec.c:1585 utils/adt/jsonpath_exec.c:1609 +#: utils/adt/jsonpath_exec.c:1195 utils/adt/jsonpath_exec.c:1221 utils/adt/jsonpath_exec.c:1307 utils/adt/jsonpath_exec.c:1332 utils/adt/jsonpath_exec.c:1383 utils/adt/jsonpath_exec.c:1403 utils/adt/jsonpath_exec.c:1464 utils/adt/jsonpath_exec.c:1541 utils/adt/jsonpath_exec.c:1573 utils/adt/jsonpath_exec.c:1597 #, c-format msgid "argument \"%s\" of jsonpath item method .%s() is invalid for type %s" msgstr "jsonpath項目メソッド .%2$s() の引数\"%1$s\"が型%3$sに適合しません" @@ -31290,7 +31490,7 @@ msgstr "jsonpath項目メソッド .%2$s() の引数\"%1$s\"が型%3$sに適合 msgid "NaN or Infinity is not allowed for jsonpath item method .%s()" msgstr "NaNとInifinityはjsonpath項目メソッド .%s() では使用できません" -#: utils/adt/jsonpath_exec.c:1239 utils/adt/jsonpath_exec.c:1340 utils/adt/jsonpath_exec.c:1480 utils/adt/jsonpath_exec.c:1617 +#: utils/adt/jsonpath_exec.c:1239 utils/adt/jsonpath_exec.c:1340 utils/adt/jsonpath_exec.c:1480 utils/adt/jsonpath_exec.c:1605 #, c-format msgid "jsonpath item method .%s() can only be applied to a string or numeric value" msgstr "jsonpath 項目メソッド .%s() は文字列または数値にのみ適用可能です" @@ -31300,142 +31500,142 @@ msgstr "jsonpath 項目メソッド .%s() は文字列または数値にのみ msgid "jsonpath item method .%s() can only be applied to a boolean, string, or numeric value" msgstr "jsonpath 項目メソッド .%s() は真偽値、文字列または数値にのみ適用可能です" -#: utils/adt/jsonpath_exec.c:1511 +#: utils/adt/jsonpath_exec.c:1507 #, c-format msgid "precision of jsonpath item method .%s() is out of range for type integer" msgstr "JSONパス項目メソッド .%s() の精度がinteger型の範囲外です" -#: utils/adt/jsonpath_exec.c:1525 +#: utils/adt/jsonpath_exec.c:1521 #, c-format msgid "scale of jsonpath item method .%s() is out of range for type integer" msgstr "JSONパス項目メソッド .%s() のスケールがinteger型の範囲外です" -#: utils/adt/jsonpath_exec.c:1671 +#: utils/adt/jsonpath_exec.c:1659 #, c-format msgid "jsonpath item method .%s() can only be applied to a boolean, string, numeric, or datetime value" msgstr "jsonpath 項目メソッド .%s() は真偽値、文字列、数値、または日時値にのみ適用可能です" -#: utils/adt/jsonpath_exec.c:2220 +#: utils/adt/jsonpath_exec.c:2208 #, c-format msgid "left operand of jsonpath operator %s is not a single numeric value" msgstr "jsonpath演算子 %s の左辺値が単一の数値ではありません" -#: utils/adt/jsonpath_exec.c:2231 +#: utils/adt/jsonpath_exec.c:2219 #, c-format msgid "right operand of jsonpath operator %s is not a single numeric value" msgstr "jsonpath演算子 %s の右辺値が単一の数値ではありません" -#: utils/adt/jsonpath_exec.c:2312 +#: utils/adt/jsonpath_exec.c:2300 #, c-format msgid "operand of unary jsonpath operator %s is not a numeric value" msgstr "単項jsonpath演算子 %s のオペランドが数値ではありません" -#: utils/adt/jsonpath_exec.c:2418 +#: utils/adt/jsonpath_exec.c:2406 #, c-format msgid "jsonpath item method .%s() can only be applied to a numeric value" msgstr "jsonpath 項目メソッド .%s() は数値にのみ適用可能です" -#: utils/adt/jsonpath_exec.c:2463 utils/adt/jsonpath_exec.c:2929 +#: utils/adt/jsonpath_exec.c:2451 utils/adt/jsonpath_exec.c:2917 #, c-format msgid "jsonpath item method .%s() can only be applied to a string" msgstr "jsonpath 項目メソッド .%s() は文字列にのみ適用可能です" -#: utils/adt/jsonpath_exec.c:2556 +#: utils/adt/jsonpath_exec.c:2544 #, c-format msgid "time precision of jsonpath item method .%s() is out of range for type integer" msgstr "JSONパス項目メソッド .%s() の日付時刻精度がinteger型の範囲外です" -#: utils/adt/jsonpath_exec.c:2590 utils/adt/jsonpath_exec.c:2596 utils/adt/jsonpath_exec.c:2623 utils/adt/jsonpath_exec.c:2651 utils/adt/jsonpath_exec.c:2704 utils/adt/jsonpath_exec.c:2755 utils/adt/jsonpath_exec.c:2826 +#: utils/adt/jsonpath_exec.c:2578 utils/adt/jsonpath_exec.c:2584 utils/adt/jsonpath_exec.c:2611 utils/adt/jsonpath_exec.c:2639 utils/adt/jsonpath_exec.c:2692 utils/adt/jsonpath_exec.c:2743 utils/adt/jsonpath_exec.c:2814 #, c-format msgid "%s format is not recognized: \"%s\"" msgstr "%sの書式を認識できません: \"%s\"" -#: utils/adt/jsonpath_exec.c:2592 +#: utils/adt/jsonpath_exec.c:2580 #, c-format msgid "Use a datetime template argument to specify the input data format." msgstr "datetimeテンプレート引数を使って入力データフォーマットを指定してください。" -#: utils/adt/jsonpath_exec.c:2785 utils/adt/jsonpath_exec.c:2866 +#: utils/adt/jsonpath_exec.c:2773 utils/adt/jsonpath_exec.c:2854 #, c-format msgid "time precision of jsonpath item method .%s() is invalid" msgstr "jsonpath項目メソッド .%s() の日付時刻精度が不正です" -#: utils/adt/jsonpath_exec.c:3038 +#: utils/adt/jsonpath_exec.c:3026 #, c-format msgid "field position of jsonpath item method .%s() is out of range for type integer" msgstr "JSONパス項目メソッド .%s() のフィールド位置がinteger型の範囲外です" -#: utils/adt/jsonpath_exec.c:3044 +#: utils/adt/jsonpath_exec.c:3032 #, c-format msgid "field position of jsonpath item method .%s() must not be zero" msgstr "jsonpath項目メソッド .%s() のフィールド位置はゼロであってはなりません" -#: utils/adt/jsonpath_exec.c:3117 +#: utils/adt/jsonpath_exec.c:3105 #, c-format msgid "jsonpath item method .%s() can only be applied to an object" msgstr "jsonpath項目メソッド .%s() はオブジェクトに対してのみ適用可能です" -#: utils/adt/jsonpath_exec.c:3401 +#: utils/adt/jsonpath_exec.c:3389 #, c-format msgid "could not convert value of type %s to jsonpath" msgstr "型%sの値のjsonpathへ変換ができませんでした" -#: utils/adt/jsonpath_exec.c:3435 +#: utils/adt/jsonpath_exec.c:3423 #, c-format msgid "could not find jsonpath variable \"%s\"" msgstr "jsonpath変数\"%s\"が見つかりませんでした" -#: utils/adt/jsonpath_exec.c:3488 +#: utils/adt/jsonpath_exec.c:3476 #, c-format msgid "\"vars\" argument is not an object" msgstr "引数\"vars\"がオブジェクトではありません" -#: utils/adt/jsonpath_exec.c:3489 +#: utils/adt/jsonpath_exec.c:3477 #, c-format msgid "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." msgstr "Jsonpath パラメータは \"vars\"オブジェクトの key-value ペアの形にエンコードされていなければなりません。" -#: utils/adt/jsonpath_exec.c:3761 +#: utils/adt/jsonpath_exec.c:3749 #, c-format msgid "jsonpath array subscript is not a single numeric value" msgstr "jsonpath配列添え字が単一の数値ではありません" -#: utils/adt/jsonpath_exec.c:3776 +#: utils/adt/jsonpath_exec.c:3764 #, c-format msgid "jsonpath array subscript is out of integer range" msgstr "jsonpath配列の添え字が整数の範囲外です" -#: utils/adt/jsonpath_exec.c:3998 +#: utils/adt/jsonpath_exec.c:3986 #, c-format msgid "cannot convert value from %s to %s without time zone usage" msgstr "時間帯を使用せずに%sから%sへの値の変換はできません" -#: utils/adt/jsonpath_exec.c:4000 +#: utils/adt/jsonpath_exec.c:3988 #, c-format msgid "Use *_tz() function for time zone support." msgstr "*_tz() 関数を使用することで時間帯がサポートされます。" -#: utils/adt/jsonpath_exec.c:4304 +#: utils/adt/jsonpath_exec.c:4292 #, c-format msgid "JSON path expression for column \"%s\" must return single item when no wrapper is requested" msgstr "ラッパーが要求されていない場合は、列\"%s\"に対するJSONパス式は単一要素を返却する必要があります" -#: utils/adt/jsonpath_exec.c:4306 utils/adt/jsonpath_exec.c:4311 +#: utils/adt/jsonpath_exec.c:4294 utils/adt/jsonpath_exec.c:4299 #, c-format msgid "Use the WITH WRAPPER clause to wrap SQL/JSON items into an array." msgstr "SQL/JSON要素列を配列にまとめるにはWITH WRAPPER句を使用してください。" -#: utils/adt/jsonpath_exec.c:4310 +#: utils/adt/jsonpath_exec.c:4298 #, c-format msgid "JSON path expression in JSON_QUERY must return single item when no wrapper is requested" msgstr "ラッパーが要求されていない場合は、JSON_QUERY中のJSONパス式は単一要素を返却する必要があります" -#: utils/adt/jsonpath_exec.c:4367 utils/adt/jsonpath_exec.c:4391 +#: utils/adt/jsonpath_exec.c:4355 utils/adt/jsonpath_exec.c:4379 #, c-format msgid "JSON path expression for column \"%s\" must return single scalar item" msgstr "列\"%s\"に対するJSONパス式は単一のスカラー要素を返却する必要があります" -#: utils/adt/jsonpath_exec.c:4372 utils/adt/jsonpath_exec.c:4396 +#: utils/adt/jsonpath_exec.c:4360 utils/adt/jsonpath_exec.c:4384 #, c-format msgid "JSON path expression in JSON_VALUE must return single scalar item" msgstr "JSON_VALUE中のJSONパス式は単一のスカラー要素を返却する必要があります" @@ -31614,7 +31814,7 @@ msgstr "複範囲値はnullの要素を持てません" msgid "invalid MultiXactId: %u" msgstr "不正なMultiXactId: %u" -#: utils/adt/multixactfuncs.c:115 +#: utils/adt/multixactfuncs.c:109 #, c-format msgid "return type must be a row type" msgstr "返り値は行型でなければなりません" @@ -31707,112 +31907,112 @@ msgstr "外部\"numeric\"の値の位取りが不正です" msgid "invalid digit in external \"numeric\" value" msgstr "外部\"numeric\"の値の桁が不正です" -#: utils/adt/numeric.c:1323 utils/adt/numeric.c:1337 +#: utils/adt/numeric.c:1320 #, c-format msgid "NUMERIC precision %d must be between 1 and %d" msgstr "NUMERICの精度%dは1から%dまででなければなりません" -#: utils/adt/numeric.c:1328 +#: utils/adt/numeric.c:1325 #, c-format msgid "NUMERIC scale %d must be between %d and %d" msgstr "NUMERICの位取り%dは%dから%dまでの間でなければなりません" -#: utils/adt/numeric.c:1346 +#: utils/adt/numeric.c:1352 #, c-format msgid "invalid NUMERIC type modifier" msgstr "不正なNUMERIC型の修正子" -#: utils/adt/numeric.c:1712 +#: utils/adt/numeric.c:1718 #, c-format msgid "start value cannot be NaN" msgstr "開始値はNaNにはできません" -#: utils/adt/numeric.c:1716 +#: utils/adt/numeric.c:1722 #, c-format msgid "start value cannot be infinity" msgstr "開始値は無限大にはできません" -#: utils/adt/numeric.c:1723 +#: utils/adt/numeric.c:1729 #, c-format msgid "stop value cannot be NaN" msgstr "終了値はNaNにはできません" -#: utils/adt/numeric.c:1727 +#: utils/adt/numeric.c:1733 #, c-format msgid "stop value cannot be infinity" msgstr "終了値は無限大にはできません" -#: utils/adt/numeric.c:1740 +#: utils/adt/numeric.c:1746 #, c-format msgid "step size cannot be NaN" msgstr "加算量はNaNにはできません" -#: utils/adt/numeric.c:1744 +#: utils/adt/numeric.c:1750 #, c-format msgid "step size cannot be infinity" msgstr "加算量は無限大にはできません" -#: utils/adt/numeric.c:3615 +#: utils/adt/numeric.c:3621 #, c-format msgid "factorial of a negative number is undefined" msgstr "負数の階乗は定義されていません" -#: utils/adt/numeric.c:3625 utils/adt/numeric.c:6961 utils/adt/numeric.c:7164 utils/adt/numeric.c:7622 utils/adt/numeric.c:10470 utils/adt/numeric.c:10945 utils/adt/numeric.c:11039 utils/adt/numeric.c:11174 +#: utils/adt/numeric.c:3631 utils/adt/numeric.c:6967 utils/adt/numeric.c:7170 utils/adt/numeric.c:7628 utils/adt/numeric.c:10476 utils/adt/numeric.c:10951 utils/adt/numeric.c:11045 utils/adt/numeric.c:11180 #, c-format msgid "value overflows numeric format" msgstr "値がnumericの形式でオーバフローします" -#: utils/adt/numeric.c:4222 +#: utils/adt/numeric.c:4228 #, c-format msgid "lower bound cannot be NaN" msgstr "下限をNaNにすることはできません" -#: utils/adt/numeric.c:4226 +#: utils/adt/numeric.c:4232 #, c-format msgid "lower bound cannot be infinity" msgstr "下限を無限値にすることはできません" -#: utils/adt/numeric.c:4233 +#: utils/adt/numeric.c:4239 #, c-format msgid "upper bound cannot be NaN" msgstr "上限をNaNにすることはできません" -#: utils/adt/numeric.c:4237 +#: utils/adt/numeric.c:4243 #, c-format msgid "upper bound cannot be infinity" msgstr "上限を無限値にすることはできません" -#: utils/adt/numeric.c:4379 utils/adt/numeric.c:4455 utils/adt/numeric.c:4510 utils/adt/numeric.c:4719 +#: utils/adt/numeric.c:4385 utils/adt/numeric.c:4461 utils/adt/numeric.c:4516 utils/adt/numeric.c:4725 #, c-format msgid "cannot convert NaN to %s" msgstr "NaNを%sには変換できません" -#: utils/adt/numeric.c:4383 utils/adt/numeric.c:4459 utils/adt/numeric.c:4514 utils/adt/numeric.c:4723 +#: utils/adt/numeric.c:4389 utils/adt/numeric.c:4465 utils/adt/numeric.c:4520 utils/adt/numeric.c:4729 #, c-format msgid "cannot convert infinity to %s" msgstr "無限大を%sに変換できません" -#: utils/adt/numeric.c:4732 +#: utils/adt/numeric.c:4738 #, c-format msgid "pg_lsn out of range" msgstr "pg_lsnの範囲外です" -#: utils/adt/numeric.c:7710 utils/adt/numeric.c:7761 +#: utils/adt/numeric.c:7716 utils/adt/numeric.c:7767 #, c-format msgid "numeric field overflow" msgstr "numericフィールドのオーバーフロー" -#: utils/adt/numeric.c:7711 +#: utils/adt/numeric.c:7717 #, c-format msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." msgstr "精度%d、位取り%dを持つフィールドは、%s%dより小さな絶対値に丸められます。" -#: utils/adt/numeric.c:7762 +#: utils/adt/numeric.c:7768 #, c-format msgid "A field with precision %d, scale %d cannot hold an infinite value." msgstr "精度%d、位取り%dを持つフィールドは、無限大値を格納できません。" -#: utils/adt/numeric.c:11243 utils/adt/pseudorandomfuncs.c:38 +#: utils/adt/numeric.c:11249 utils/adt/pseudorandomfuncs.c:38 #, c-format msgid "lower bound must be less than or equal to upper bound" msgstr "下限は上限と同じあるいはより小さい必要があります" @@ -31857,9 +32057,9 @@ msgstr "要求された文字は符号化方式に対して不正です: %u" msgid "percentile value %g is not between 0 and 1" msgstr "百分位数の値%gが0と1の間ではありません" -#: utils/adt/pg_dependencies.c:79 utils/adt/pg_dependencies.c:87 utils/adt/pg_dependencies.c:95 utils/adt/pg_dependencies.c:104 utils/adt/pg_dependencies.c:112 utils/adt/pg_dependencies.c:121 utils/adt/pg_dependencies.c:159 utils/adt/pg_dependencies.c:169 utils/adt/pg_dependencies.c:179 utils/adt/pg_dependencies.c:194 utils/adt/pg_dependencies.c:223 utils/adt/pg_dependencies.c:271 utils/adt/pg_dependencies.c:300 utils/adt/pg_dependencies.c:314 -#: utils/adt/pg_dependencies.c:351 utils/adt/pg_dependencies.c:368 utils/adt/pg_dependencies.c:385 utils/adt/pg_dependencies.c:398 utils/adt/pg_dependencies.c:425 utils/adt/pg_dependencies.c:435 utils/adt/pg_dependencies.c:494 utils/adt/pg_dependencies.c:507 utils/adt/pg_dependencies.c:521 utils/adt/pg_dependencies.c:539 utils/adt/pg_dependencies.c:552 utils/adt/pg_dependencies.c:569 utils/adt/pg_dependencies.c:580 utils/adt/pg_dependencies.c:673 -#: utils/adt/pg_dependencies.c:681 utils/adt/pg_dependencies.c:716 utils/adt/pg_dependencies.c:803 +#: utils/adt/pg_dependencies.c:79 utils/adt/pg_dependencies.c:87 utils/adt/pg_dependencies.c:95 utils/adt/pg_dependencies.c:104 utils/adt/pg_dependencies.c:112 utils/adt/pg_dependencies.c:121 utils/adt/pg_dependencies.c:159 utils/adt/pg_dependencies.c:169 utils/adt/pg_dependencies.c:179 utils/adt/pg_dependencies.c:194 utils/adt/pg_dependencies.c:222 utils/adt/pg_dependencies.c:270 utils/adt/pg_dependencies.c:299 utils/adt/pg_dependencies.c:313 +#: utils/adt/pg_dependencies.c:350 utils/adt/pg_dependencies.c:367 utils/adt/pg_dependencies.c:384 utils/adt/pg_dependencies.c:397 utils/adt/pg_dependencies.c:424 utils/adt/pg_dependencies.c:434 utils/adt/pg_dependencies.c:493 utils/adt/pg_dependencies.c:506 utils/adt/pg_dependencies.c:520 utils/adt/pg_dependencies.c:538 utils/adt/pg_dependencies.c:551 utils/adt/pg_dependencies.c:568 utils/adt/pg_dependencies.c:579 utils/adt/pg_dependencies.c:672 +#: utils/adt/pg_dependencies.c:680 utils/adt/pg_dependencies.c:715 utils/adt/pg_dependencies.c:802 #, c-format msgid "malformed pg_dependencies: \"%s\"" msgstr "pg_dependenciesのフォーマット異常: \"%s\"" @@ -31899,87 +32099,87 @@ msgstr "項目は \"%s\"キーを含む必要があります。" msgid "The \"%s\" key must contain an array of at least %d and no more than %d elements." msgstr "\"%s\"キーには、要素数が%d以上%d以下の配列を指定する必要があります。" -#: utils/adt/pg_dependencies.c:224 +#: utils/adt/pg_dependencies.c:223 #, c-format msgid "Item \"%s\" with value %d has been found in the \"%s\" list." msgstr "値 %2$d を持つ項目 \"%1$s\" が \"%3$s\" リストで見つかりました。" -#: utils/adt/pg_dependencies.c:272 utils/adt/pg_ndistinct.c:226 +#: utils/adt/pg_dependencies.c:271 utils/adt/pg_ndistinct.c:226 #, c-format msgid "Array has been found at an unexpected location." msgstr "配列が予期しない場所で検出されました。" -#: utils/adt/pg_dependencies.c:301 utils/adt/pg_ndistinct.c:260 +#: utils/adt/pg_dependencies.c:300 utils/adt/pg_ndistinct.c:260 #, c-format msgid "The \"%s\" key must be a non-empty array." msgstr "\"%s\"キーは空ではない配列でなければなりません。" -#: utils/adt/pg_dependencies.c:315 utils/adt/pg_ndistinct.c:275 +#: utils/adt/pg_dependencies.c:314 utils/adt/pg_ndistinct.c:275 #, c-format msgid "Item array cannot be empty." msgstr "項目配列は空にはできません。" -#: utils/adt/pg_dependencies.c:352 utils/adt/pg_dependencies.c:369 utils/adt/pg_dependencies.c:386 utils/adt/pg_ndistinct.c:312 utils/adt/pg_ndistinct.c:328 +#: utils/adt/pg_dependencies.c:351 utils/adt/pg_dependencies.c:368 utils/adt/pg_dependencies.c:385 utils/adt/pg_ndistinct.c:312 utils/adt/pg_ndistinct.c:328 #, c-format msgid "Multiple \"%s\" keys are not allowed." msgstr "複数の\"%s\"キーは使用できません" -#: utils/adt/pg_dependencies.c:399 +#: utils/adt/pg_dependencies.c:398 #, c-format msgid "Only allowed keys are \"%s\", \"%s\", and \"%s\"." msgstr "使用可能なキーは\"%s\"、\"%s\"と\"%s\"のみです。" -#: utils/adt/pg_dependencies.c:426 utils/adt/pg_ndistinct.c:366 +#: utils/adt/pg_dependencies.c:425 utils/adt/pg_ndistinct.c:366 #, c-format msgid "Attribute number array cannot be null." msgstr "属性番号配列はnullにはできません。" -#: utils/adt/pg_dependencies.c:436 utils/adt/pg_ndistinct.c:376 +#: utils/adt/pg_dependencies.c:435 utils/adt/pg_ndistinct.c:376 #, c-format msgid "Item list elements cannot be null." msgstr "項目リストの要素はnullにはできません。" -#: utils/adt/pg_dependencies.c:495 utils/adt/pg_dependencies.c:540 utils/adt/pg_dependencies.c:570 utils/adt/pg_ndistinct.c:436 utils/adt/pg_ndistinct.c:490 +#: utils/adt/pg_dependencies.c:494 utils/adt/pg_dependencies.c:539 utils/adt/pg_dependencies.c:569 utils/adt/pg_ndistinct.c:436 utils/adt/pg_ndistinct.c:490 #, c-format msgid "Key \"%s\" has an incorrect value." msgstr "キー\"%s\"の値が不正です。" -#: utils/adt/pg_dependencies.c:508 utils/adt/pg_ndistinct.c:449 +#: utils/adt/pg_dependencies.c:507 utils/adt/pg_ndistinct.c:449 #, c-format msgid "Invalid \"%s\" element has been found: %d." msgstr "不正な\"%s\"要素が見つかりました: %d。" -#: utils/adt/pg_dependencies.c:522 utils/adt/pg_ndistinct.c:463 +#: utils/adt/pg_dependencies.c:521 utils/adt/pg_ndistinct.c:463 #, c-format msgid "Invalid \"%s\" element has been found: %d cannot follow %d." msgstr "不正な\"%s\"要素が見つかりました: %d は %d の後に続けることはできません。" -#: utils/adt/pg_dependencies.c:553 +#: utils/adt/pg_dependencies.c:552 #, c-format msgid "Key \"%s\" has an incorrect value: %d." msgstr "キー\"%s\"の値が不正です: %d。" -#: utils/adt/pg_dependencies.c:581 utils/adt/pg_ndistinct.c:498 +#: utils/adt/pg_dependencies.c:580 utils/adt/pg_ndistinct.c:498 #, c-format msgid "Unexpected scalar has been found." msgstr "想定外のスカラー値が見つかりました。" -#: utils/adt/pg_dependencies.c:674 utils/adt/pg_ndistinct.c:615 +#: utils/adt/pg_dependencies.c:673 utils/adt/pg_ndistinct.c:615 #, c-format msgid "Value cannot be empty." msgstr "値は空にはできません。" -#: utils/adt/pg_dependencies.c:682 utils/adt/pg_ndistinct.c:623 +#: utils/adt/pg_dependencies.c:681 utils/adt/pg_ndistinct.c:623 #, c-format msgid "Unexpected end state has been found: %d." msgstr "想定外の終了状態を検出しました: %d。" -#: utils/adt/pg_dependencies.c:717 +#: utils/adt/pg_dependencies.c:716 #, c-format msgid "Duplicated \"%s\" array has been found: [%s] for key \"%s\" and value %d." msgstr "重複した\"%1$s\"配列が見つかりました: キー \"%3$s\"、値 %4$d に対する[%2$s]。" -#: utils/adt/pg_dependencies.c:804 utils/adt/pg_ndistinct.c:780 +#: utils/adt/pg_dependencies.c:803 utils/adt/pg_ndistinct.c:780 #, c-format msgid "Input data must be valid JSON." msgstr "入力データは妥当なJSONでなければなりません。" @@ -32009,7 +32209,7 @@ msgstr "データベース中の照合順序はバージョン%sで作成され msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." msgstr "この照合順序の影響を受ける全てのオブジェクトを再構築して、ALTER COLLATION %s REFRESH VERSIONを実行するか、正しいバージョンのライブラリを用いてPostgreSQLをビルドしてください。" -#: utils/adt/pg_locale.c:1679 utils/adt/pg_locale.c:1706 utils/adt/pg_locale_builtin.c:295 +#: utils/adt/pg_locale.c:1679 utils/adt/pg_locale.c:1706 utils/adt/pg_locale_builtin.c:294 #, c-format msgid "invalid locale name \"%s\" for builtin provider" msgstr "ロケール名\"%s\"は組み込みプロバイダでは不正です" @@ -32019,7 +32219,7 @@ msgstr "ロケール名\"%s\"は組み込みプロバイダでは不正です" msgid "could not convert locale name \"%s\" to language tag: %s" msgstr "ロケール名\"%s\"を、言語タグに変換できませんでした: %s" -#: utils/adt/pg_locale.c:1780 utils/adt/pg_locale.c:1855 utils/adt/pg_locale_icu.c:400 +#: utils/adt/pg_locale.c:1780 utils/adt/pg_locale.c:1855 utils/adt/pg_locale_icu.c:415 #, c-format msgid "ICU is not supported in this build" msgstr "このビルドではICUはサポートされていません" @@ -32039,97 +32239,97 @@ msgstr "ICUロケールを無効にするには、パラメータ\"%s\"を\"%s\" msgid "ICU locale \"%s\" has unknown language \"%s\"" msgstr "ICUロケール\"%s\"には未知の言語\"%s\"が含まれています" -#: utils/adt/pg_locale_icu.c:440 +#: utils/adt/pg_locale_icu.c:455 #, c-format msgid "could not get language from locale \"%s\": %s" msgstr "ロケール\"%s\"から言語を取得できませんでした: %s" -#: utils/adt/pg_locale_icu.c:481 utils/adt/pg_locale_icu.c:498 +#: utils/adt/pg_locale_icu.c:496 utils/adt/pg_locale_icu.c:513 #, c-format msgid "could not open collator for locale \"%s\": %s" msgstr "ロケール\"%s\"の照合器をオープンできませんでした: %s" -#: utils/adt/pg_locale_icu.c:528 +#: utils/adt/pg_locale_icu.c:543 #, c-format msgid "could not open casemap for locale \"%s\": %s" msgstr "ロケール\"%s\"の文字ケース変換テーブル(casemap)をオープンできませんでした: %s" -#: utils/adt/pg_locale_icu.c:596 +#: utils/adt/pg_locale_icu.c:611 #, c-format msgid "could not open collator for locale \"%s\" with rules \"%s\": %s" msgstr "ルール\"%2$s\"を持つロケール\"%1$s\"の照合器をオープンできませんでした: %3$s" -#: utils/adt/pg_locale_icu.c:644 utils/adt/pg_locale_icu.c:658 utils/adt/pg_locale_icu.c:672 utils/adt/pg_locale_icu.c:686 utils/adt/pg_locale_icu.c:931 +#: utils/adt/pg_locale_icu.c:659 utils/adt/pg_locale_icu.c:673 utils/adt/pg_locale_icu.c:687 utils/adt/pg_locale_icu.c:701 utils/adt/pg_locale_icu.c:992 #, c-format msgid "case conversion failed: %s" msgstr "文字ケースの変換に失敗しました: %s" -#: utils/adt/pg_locale_icu.c:747 +#: utils/adt/pg_locale_icu.c:761 utils/adt/pg_locale_icu.c:781 #, c-format msgid "collation failed: %s" msgstr "照合順序による比較に失敗しました: %s" -#: utils/adt/pg_locale_icu.c:816 utils/adt/pg_locale_icu.c:1094 +#: utils/adt/pg_locale_icu.c:862 utils/adt/pg_locale_icu.c:1167 #, c-format msgid "sort key generation failed: %s" msgstr "ソートキーの生成に失敗しました: %s" -#: utils/adt/pg_locale_icu.c:890 utils/adt/pg_locale_icu.c:902 utils/adt/pg_locale_icu.c:1148 utils/adt/pg_locale_icu.c:1168 +#: utils/adt/pg_locale_icu.c:951 utils/adt/pg_locale_icu.c:963 utils/adt/pg_locale_icu.c:1235 utils/adt/pg_locale_icu.c:1255 #, c-format msgid "%s failed: %s" msgstr "%s が失敗しました: %s" -#: utils/adt/pg_locale_icu.c:1117 +#: utils/adt/pg_locale_icu.c:1204 #, c-format msgid "encoding \"%s\" not supported by ICU" msgstr "エンコーディング\"%s\"はICUではサポートされていません" -#: utils/adt/pg_locale_icu.c:1124 +#: utils/adt/pg_locale_icu.c:1211 #, c-format msgid "could not open ICU converter for encoding \"%s\": %s" msgstr "エンコーディング\"%s\"のICU変換器をオープンできませんでした: %s" -#: utils/adt/pg_locale_libc.c:881 +#: utils/adt/pg_locale_libc.c:874 #, c-format msgid "collations with different collate and ctype values are not supported on this platform" msgstr "このプラットフォームでは値が異なるcollateとctypeによる照合順序をサポートしていません" -#: utils/adt/pg_locale_libc.c:1007 +#: utils/adt/pg_locale_libc.c:997 #, c-format msgid "could not load locale \"%s\"" msgstr "ロケール\"%s\"をロードできませんでした" -#: utils/adt/pg_locale_libc.c:1032 +#: utils/adt/pg_locale_libc.c:1022 #, c-format msgid "could not get collation version for locale \"%s\": error code %lu" msgstr "ロケール\"%s\"に対応する照合順序バージョンを取得できませんでした: エラーコード %lu" -#: utils/adt/pg_locale_libc.c:1100 utils/adt/pg_locale_libc.c:1113 +#: utils/adt/pg_locale_libc.c:1083 utils/adt/pg_locale_libc.c:1096 #, c-format msgid "could not convert string to UTF-16: error code %lu" msgstr "文字列をUTF-16に変換できませんでした: エラーコード %lu" -#: utils/adt/pg_locale_libc.c:1122 +#: utils/adt/pg_locale_libc.c:1105 #, c-format msgid "could not compare Unicode strings: %m" msgstr "Unicode文字列を比較できませんでした: %m" -#: utils/adt/pg_locale_libc.c:1154 +#: utils/adt/pg_locale_libc.c:1147 #, c-format msgid "could not create locale \"%s\": %m" msgstr "ロケール\"%s\"を作成できませんでした: %m" -#: utils/adt/pg_locale_libc.c:1157 +#: utils/adt/pg_locale_libc.c:1150 #, c-format msgid "The operating system could not find any locale data for the locale name \"%s\"." msgstr "オペレーティングシステムはロケール名\"%s\"のロケールデータを見つけられませんでした。" -#: utils/adt/pg_locale_libc.c:1329 +#: utils/adt/pg_locale_libc.c:1322 #, c-format msgid "invalid multibyte character for locale" msgstr "ロケールに対する不正なマルチバイト文字" -#: utils/adt/pg_locale_libc.c:1330 +#: utils/adt/pg_locale_libc.c:1323 #, c-format msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." msgstr "おそらくサーバーのLC_CTYPEロケールはデータベースの符号化方式と互換性がありません" @@ -32180,17 +32380,17 @@ msgstr "関数はサーバーがバイナリアップグレードモードであ msgid "invalid command name: \"%s\"" msgstr "不正なコマンド名: \"%s\"" -#: utils/adt/pgstatfuncs.c:1989 +#: utils/adt/pgstatfuncs.c:2029 #, c-format msgid "unrecognized reset target: \"%s\"" msgstr "認識できないリセットターゲット: \"%s\"" -#: utils/adt/pgstatfuncs.c:1990 +#: utils/adt/pgstatfuncs.c:2030 #, c-format msgid "Target must be \"archiver\", \"bgwriter\", \"checkpointer\", \"io\", \"lock\", \"recovery_prefetch\", \"slru\", or \"wal\"." msgstr "対象は\"archiver\"、\"bgwriter\"、\"checkpointer\"、\"io\"、\"lock\"、\"recovery_prefetch\"、\"slru\"または\"wal\"でなければなりません。" -#: utils/adt/pgstatfuncs.c:2107 +#: utils/adt/pgstatfuncs.c:2147 #, c-format msgid "invalid subscription OID %u" msgstr "不正なサブスクリプションOID %u" @@ -32361,92 +32561,92 @@ msgstr "型の名前を想定していました" msgid "improper type name" msgstr "型の名前が不適切です" -#: utils/adt/ri_triggers.c:414 utils/adt/ri_triggers.c:1906 utils/adt/ri_triggers.c:3653 +#: utils/adt/ri_triggers.c:421 utils/adt/ri_triggers.c:1929 utils/adt/ri_triggers.c:3713 #, c-format msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" msgstr "テーブル\"%s\"への挿入、更新は外部キー制約\"%s\"に違反しています" -#: utils/adt/ri_triggers.c:417 utils/adt/ri_triggers.c:1909 +#: utils/adt/ri_triggers.c:424 utils/adt/ri_triggers.c:1932 #, c-format msgid "MATCH FULL does not allow mixing of null and nonnull key values." msgstr "MACTH FULLではNULLキー値と非NULLキー値を混在できません" -#: utils/adt/ri_triggers.c:2323 +#: utils/adt/ri_triggers.c:2346 #, c-format msgid "function \"%s\" must be fired for INSERT" msgstr "関数\"%s\"はINSERTで発火しなければなりません" -#: utils/adt/ri_triggers.c:2329 +#: utils/adt/ri_triggers.c:2352 #, c-format msgid "function \"%s\" must be fired for UPDATE" msgstr "関数\"%s\"はUPDATEで発火しなければなりません" -#: utils/adt/ri_triggers.c:2335 +#: utils/adt/ri_triggers.c:2358 #, c-format msgid "function \"%s\" must be fired for DELETE" msgstr "関数\"%s\"はDELETEで発火しなければなりません" -#: utils/adt/ri_triggers.c:2358 +#: utils/adt/ri_triggers.c:2381 #, c-format msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" msgstr "テーブル\"%2$s\"のトリガMERGEは\"%1$s\"用のpg_constraintエントリがありません" -#: utils/adt/ri_triggers.c:2360 +#: utils/adt/ri_triggers.c:2383 #, c-format msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." msgstr "この参照整合性トリガーと、それに関連するトリガーをすべて削除し、ALTER TABLE ADD CONSTRAINTを実行してください。" -#: utils/adt/ri_triggers.c:2749 +#: utils/adt/ri_triggers.c:2772 #, c-format msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" msgstr "\"%3$s\"の制約\"%2$s\"から\"%1$s\"に行われた参照整合性問い合わせが想定外の結果になりました" -#: utils/adt/ri_triggers.c:2753 +#: utils/adt/ri_triggers.c:2776 #, c-format msgid "This is most likely due to a rule having rewritten the query." msgstr "これは概ねこの問い合わせを書き換えるルールが原因です" -#: utils/adt/ri_triggers.c:3643 +#: utils/adt/ri_triggers.c:3703 #, c-format msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" msgstr "子テーブル \"%s\"の削除は外部キー制約\"%s\"違反となります" -#: utils/adt/ri_triggers.c:3646 utils/adt/ri_triggers.c:3685 +#: utils/adt/ri_triggers.c:3706 utils/adt/ri_triggers.c:3745 #, c-format msgid "Key (%s)=(%s) is still referenced from table \"%s\"." msgstr "キー(%s)=(%s)はまだテーブル\"%s\"から参照されています" -#: utils/adt/ri_triggers.c:3657 +#: utils/adt/ri_triggers.c:3717 #, c-format msgid "Key (%s)=(%s) is not present in table \"%s\"." msgstr "テーブル\"%3$s\"にキー(%1$s)=(%2$s)がありません" -#: utils/adt/ri_triggers.c:3660 +#: utils/adt/ri_triggers.c:3720 #, c-format msgid "Key is not present in table \"%s\"." msgstr "テーブル\"%s\"にキーがありません。" -#: utils/adt/ri_triggers.c:3666 +#: utils/adt/ri_triggers.c:3726 #, c-format msgid "update or delete on table \"%s\" violates RESTRICT setting of foreign key constraint \"%s\" on table \"%s\"" msgstr "テーブル\"%1$s\"の更新または削除は、テーブル\"%3$s\"の外部キー制約\"%2$s\"のRESTRICT設定に違反しています" -#: utils/adt/ri_triggers.c:3671 +#: utils/adt/ri_triggers.c:3731 #, c-format msgid "Key (%s)=(%s) is referenced from table \"%s\"." msgstr "キー(%s)=(%s)はテーブル\"%s\"から参照されています。" -#: utils/adt/ri_triggers.c:3674 +#: utils/adt/ri_triggers.c:3734 #, c-format msgid "Key is referenced from table \"%s\"." msgstr "キーがテーブル\"%s\"から参照されています。" -#: utils/adt/ri_triggers.c:3680 +#: utils/adt/ri_triggers.c:3740 #, c-format msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" msgstr "テーブル\"%1$s\"の更新または削除は、テーブル\"%3$s\"の外部キー制約\"%2$s\"に違反します" -#: utils/adt/ri_triggers.c:3688 +#: utils/adt/ri_triggers.c:3748 #, c-format msgid "Key is still referenced from table \"%s\"." msgstr "テーブル\"%s\"からキーがまだ参照されています。" @@ -32752,62 +32952,67 @@ msgstr "単語が長すぎます(%dバイト、最大は%dバイト)" msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" msgstr "tsベクターのための文字列が長すぎます(%ldバイト、最大は%ldバイト)" -#: utils/adt/tsvector_op.c:772 +#: utils/adt/tsvector_op.c:238 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "識別不能な重み付け: \"%c\"" + +#: utils/adt/tsvector_op.c:242 +#, c-format +msgid "unrecognized weight: \"\\%03o\"" +msgstr "識別不能な重み付け: \"\\%03o\"" + +#: utils/adt/tsvector_op.c:767 #, c-format msgid "lexeme array may not contain nulls" msgstr "語彙素配列にはnullを含めてはいけません" -#: utils/adt/tsvector_op.c:777 +#: utils/adt/tsvector_op.c:772 #, c-format msgid "lexeme array may not contain empty strings" msgstr "語彙素配列には空文字列を含めてはいけません" -#: utils/adt/tsvector_op.c:846 +#: utils/adt/tsvector_op.c:841 #, c-format msgid "weight array may not contain nulls" msgstr "重み付け配列にはnullを含めてはいけません" -#: utils/adt/tsvector_op.c:870 -#, c-format -msgid "unrecognized weight: \"%c\"" -msgstr "識別不能な重み付け: \"%c\"" - -#: utils/adt/tsvector_op.c:2600 +#: utils/adt/tsvector_op.c:2573 #, c-format msgid "ts_stat query must return one tsvector column" msgstr "ts_statは1つのtsvector列のみを返さなければなりません" -#: utils/adt/tsvector_op.c:2793 +#: utils/adt/tsvector_op.c:2766 #, c-format msgid "tsvector column \"%s\" does not exist" msgstr "tsvector列\"%s\"は存在しません" -#: utils/adt/tsvector_op.c:2800 +#: utils/adt/tsvector_op.c:2773 #, c-format msgid "column \"%s\" is not of tsvector type" msgstr "値\"%s\"は型tsvectorではありません" -#: utils/adt/tsvector_op.c:2812 +#: utils/adt/tsvector_op.c:2785 #, c-format msgid "configuration column \"%s\" does not exist" msgstr "設定列\"%s\"は存在しません" -#: utils/adt/tsvector_op.c:2818 +#: utils/adt/tsvector_op.c:2791 #, c-format msgid "column \"%s\" is not of regconfig type" msgstr "%s列はregconfig型ではありません" -#: utils/adt/tsvector_op.c:2825 +#: utils/adt/tsvector_op.c:2798 #, c-format msgid "configuration column \"%s\" must not be null" msgstr "設定列\"%s\"をNULLにすることはできません" -#: utils/adt/tsvector_op.c:2838 +#: utils/adt/tsvector_op.c:2811 #, c-format msgid "text search configuration name \"%s\" must be schema-qualified" msgstr "テキスト検索設定名称\"%s\"はスキーマ修飾しなければなりません" -#: utils/adt/tsvector_op.c:2863 +#: utils/adt/tsvector_op.c:2836 #, c-format msgid "column \"%s\" is not of a character type" msgstr "列\"%s\"は文字型ではありません" @@ -32827,7 +33032,7 @@ msgstr "エスケープ文字がありません: \"%s\"" msgid "wrong position info in tsvector: \"%s\"" msgstr "tsvector内の位置情報が間違っています: \"%s\"" -#: utils/adt/uuid.c:531 utils/adt/uuid.c:628 +#: utils/adt/uuid.c:549 utils/adt/uuid.c:646 #, c-format msgid "could not generate random values" msgstr "乱数値を生成できませんでした" @@ -33126,47 +33331,47 @@ msgstr "不正な無効な問い合わせ" msgid "portal \"%s\" does not return tuples" msgstr "ポータル\"%s\"はタプルを返却しません" -#: utils/adt/xml.c:4413 +#: utils/adt/xml.c:4415 #, c-format msgid "invalid array for XML namespace mapping" msgstr "XML名前空間マッピングに対する不正な配列" -#: utils/adt/xml.c:4414 +#: utils/adt/xml.c:4416 #, c-format msgid "The array must be two-dimensional with length of the second axis equal to 2." msgstr "この配列は第2軸の長さが2である2次元配列でなければなりません。" -#: utils/adt/xml.c:4438 +#: utils/adt/xml.c:4440 #, c-format msgid "empty XPath expression" msgstr "空のXPath式" -#: utils/adt/xml.c:4490 +#: utils/adt/xml.c:4492 #, c-format msgid "neither namespace name nor URI may be null" msgstr "名前空間名もURIもnullにはできません" -#: utils/adt/xml.c:4497 +#: utils/adt/xml.c:4499 #, c-format msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" msgstr "\"%s\"という名前のXML名前空間およびURI\"%s\"を登録できませんでした" -#: utils/adt/xml.c:4846 +#: utils/adt/xml.c:4848 #, c-format msgid "DEFAULT namespace is not supported" msgstr "デフォルト名前空間は実装されていません" -#: utils/adt/xml.c:4875 +#: utils/adt/xml.c:4877 #, c-format msgid "row path filter must not be empty string" msgstr "行パスフィルタは空文字列であってはなりません" -#: utils/adt/xml.c:4909 +#: utils/adt/xml.c:4911 #, c-format msgid "column path filter must not be empty string" msgstr "列パスフィルタ空文字列であってはなりません" -#: utils/adt/xml.c:5056 +#: utils/adt/xml.c:5058 #, c-format msgid "more than one value returned by column XPath expression" msgstr "列XPath式が2つ以上の値を返却しました" @@ -33176,22 +33381,22 @@ msgstr "列XPath式が2つ以上の値を返却しました" msgid "could not determine actual argument type for polymorphic function \"%s\"" msgstr "多相関数\"%s\"の実際の引数の型を特定できませんでした" -#: utils/cache/lsyscache.c:1174 +#: utils/cache/lsyscache.c:1235 #, c-format msgid "cast from type %s to type %s does not exist" msgstr "型%sから型%sへのキャストは存在しません" -#: utils/cache/lsyscache.c:3120 utils/cache/lsyscache.c:3153 utils/cache/lsyscache.c:3186 utils/cache/lsyscache.c:3219 +#: utils/cache/lsyscache.c:3195 utils/cache/lsyscache.c:3228 utils/cache/lsyscache.c:3261 utils/cache/lsyscache.c:3294 #, c-format msgid "type %s is only a shell" msgstr "型%sは単なるシェルです" -#: utils/cache/lsyscache.c:3125 +#: utils/cache/lsyscache.c:3200 #, c-format msgid "no input function available for type %s" msgstr "型%sの利用可能な入力関数がありません" -#: utils/cache/lsyscache.c:3158 +#: utils/cache/lsyscache.c:3233 #, c-format msgid "no output function available for type %s" msgstr "型%sの利用可能な出力関数がありません" @@ -33201,27 +33406,27 @@ msgstr "型%sの利用可能な出力関数がありません" msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" msgstr "アクセスメソッド %2$s の演算子クラス\"%1$s\"は%4$s型に対応するサポート関数%3$dを含んでいません" -#: utils/cache/relcache.c:3807 +#: utils/cache/relcache.c:3809 #, c-format msgid "heap relfilenumber value not set when in binary upgrade mode" msgstr "バイナリアップグレードモード中にヒープのrelfilenumberの値が設定されていません" -#: utils/cache/relcache.c:3815 +#: utils/cache/relcache.c:3817 #, c-format msgid "unexpected request for new relfilenumber in binary upgrade mode" msgstr "バイナリアップグレードモード中に、予期しない新規relfilenumberの要求がありました" -#: utils/cache/relcache.c:6659 +#: utils/cache/relcache.c:6668 #, c-format msgid "could not create relation-cache initialization file \"%s\": %m" msgstr "リレーションキャッシュ初期化ファイル\"%sを作成できません: %m" -#: utils/cache/relcache.c:6661 +#: utils/cache/relcache.c:6670 #, c-format msgid "Continuing anyway, but there's something wrong." msgstr "とりあえず続行しますが、何かがおかしいです。" -#: utils/cache/relcache.c:6991 +#: utils/cache/relcache.c:7000 #, c-format msgid "could not remove cache file \"%s\": %m" msgstr "キャッシュファイル\"%s\"を削除できませんでした: %m" @@ -33241,7 +33446,7 @@ msgstr "リレーションマッピングファイル\"%s\"に不正なデータ msgid "relation mapping file \"%s\" contains incorrect checksum" msgstr "リレーションマッピングファイル\"%s\"の中に不正なチェックサムがあります" -#: utils/cache/typcache.c:1926 utils/fmgr/funcapi.c:576 +#: utils/cache/typcache.c:1928 utils/fmgr/funcapi.c:576 #, c-format msgid "record type has not been registered" msgstr "レコード型は登録されていません" @@ -33690,170 +33895,170 @@ msgstr "initdbする必要があるかもしれません" msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." msgstr "データディレクトリはPostgreSQLバージョン%sで初期化されましたが、これはバージョン%sとは互換性がありません" -#: utils/init/postinit.c:278 +#: utils/init/postinit.c:284 #, c-format msgid "replication connection authorized: user=%s" msgstr "レプリケーション接続の認証完了: ユーザー=%s" -#: utils/init/postinit.c:281 +#: utils/init/postinit.c:287 #, c-format msgid "connection authorized: user=%s" msgstr "接続の認証完了: ユーザー=%s" -#: utils/init/postinit.c:284 +#: utils/init/postinit.c:290 #, c-format msgid " database=%s" msgstr " データベース=%s" -#: utils/init/postinit.c:287 +#: utils/init/postinit.c:293 #, c-format msgid " application_name=%s" msgstr " application_name=%s" -#: utils/init/postinit.c:292 +#: utils/init/postinit.c:298 #, c-format msgid " SSL enabled (protocol=%s, cipher=%s, bits=%d)" msgstr " SSL有効(プロトコル=%s、暗号化方式=%s、ビット長=%d)" -#: utils/init/postinit.c:304 +#: utils/init/postinit.c:310 #, c-format msgid " GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s, principal=%s)" msgstr " GSS (認証=%s、暗号化=%s、委任資格証明=%s、プリンシパル=%s)" -#: utils/init/postinit.c:305 utils/init/postinit.c:306 utils/init/postinit.c:307 utils/init/postinit.c:312 utils/init/postinit.c:313 utils/init/postinit.c:314 +#: utils/init/postinit.c:311 utils/init/postinit.c:312 utils/init/postinit.c:313 utils/init/postinit.c:318 utils/init/postinit.c:319 utils/init/postinit.c:320 msgid "no" msgstr "いいえ" -#: utils/init/postinit.c:305 utils/init/postinit.c:306 utils/init/postinit.c:307 utils/init/postinit.c:312 utils/init/postinit.c:313 utils/init/postinit.c:314 +#: utils/init/postinit.c:311 utils/init/postinit.c:312 utils/init/postinit.c:313 utils/init/postinit.c:318 utils/init/postinit.c:319 utils/init/postinit.c:320 msgid "yes" msgstr "はい" -#: utils/init/postinit.c:311 +#: utils/init/postinit.c:317 #, c-format msgid " GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s)" msgstr " GSS (認証=%s、暗号化=%s、委任資格証明=%s)" -#: utils/init/postinit.c:351 +#: utils/init/postinit.c:357 #, c-format msgid "database \"%s\" has disappeared from pg_database" msgstr "データベース\"%s\"はpg_databaseから消失しました" -#: utils/init/postinit.c:353 +#: utils/init/postinit.c:359 #, c-format msgid "Database OID %u now seems to belong to \"%s\"." msgstr "OID%uのデータベースは\"%s\"に属するようです。" -#: utils/init/postinit.c:373 +#: utils/init/postinit.c:379 #, c-format msgid "database \"%s\" is not currently accepting connections" msgstr "現在データベース\"%s\"は接続を受け付けません" -#: utils/init/postinit.c:386 +#: utils/init/postinit.c:392 #, c-format msgid "permission denied for database \"%s\"" msgstr "データベース\"%s\"へのアクセスが拒否されました" -#: utils/init/postinit.c:387 +#: utils/init/postinit.c:393 #, c-format msgid "User does not have CONNECT privilege." msgstr "ユーザーはCONNECT権限を持ちません。" -#: utils/init/postinit.c:407 +#: utils/init/postinit.c:413 #, c-format msgid "too many connections for database \"%s\"" msgstr "データベース\"%s\"への接続が多すぎます" -#: utils/init/postinit.c:437 +#: utils/init/postinit.c:443 #, c-format msgid "database locale is incompatible with operating system" msgstr "データベースのロケールがオペレーティングシステムと互換性がありません" -#: utils/init/postinit.c:438 +#: utils/init/postinit.c:444 #, c-format msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." msgstr "データベースは LC_CTYPE \"%s\"で初期化されていますが、setlocale()でこれを認識されません" -#: utils/init/postinit.c:440 +#: utils/init/postinit.c:446 #, c-format msgid "Recreate the database with another locale or install the missing locale." msgstr "データベースを別のロケールで再生成するか、または不足しているロケールをインストールしてください" -#: utils/init/postinit.c:475 +#: utils/init/postinit.c:481 #, c-format msgid "database \"%s\" has a collation version mismatch" msgstr "データベース\"%s\"で照合順序バージョンの不一致が起きています" -#: utils/init/postinit.c:477 +#: utils/init/postinit.c:483 #, c-format msgid "The database was created using collation version %s, but the operating system provides version %s." msgstr "データベースは照合順序バージョン%sで作成されていますが、オペレーティングシステムはバージョン%sを提供しています。" -#: utils/init/postinit.c:480 +#: utils/init/postinit.c:486 #, c-format msgid "Rebuild all objects in this database that use the default collation and run ALTER DATABASE %s REFRESH COLLATION VERSION, or build PostgreSQL with the right library version." msgstr "このデータベース内でデフォルトの照合順序を使用している全てのオブジェクトを再構築して、ALTER DATABASE %s REFRESH COLLATION VERSIONを実行するか、正しいバージョンのライブラリを用いてPostgreSQLをビルドしてください。" -#: utils/init/postinit.c:570 +#: utils/init/postinit.c:576 #, c-format msgid "too many server processes configured" msgstr "サーバープロセス数の設定が大きすぎます" -#: utils/init/postinit.c:571 +#: utils/init/postinit.c:577 #, c-format msgid "\"max_connections\" (%d) plus \"autovacuum_worker_slots\" (%d) plus \"max_worker_processes\" (%d) plus \"max_wal_senders\" (%d) must be less than %d." msgstr "\"max_connections\" (%d) + \"autovacuum_worker_slots\" (%d) + \"max_worker_processes\" (%d) + \"max_wal_senders\" (%d)は%dより小さくなければなりません。" -#: utils/init/postinit.c:920 +#: utils/init/postinit.c:926 #, c-format msgid "no roles are defined in this database system" msgstr "データベースシステム内でロールが定義されていません" -#: utils/init/postinit.c:921 +#: utils/init/postinit.c:927 #, c-format msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." msgstr "すぐに CREATE USER \"%s\" SUPERUSER; を実行してください。" -#: utils/init/postinit.c:966 +#: utils/init/postinit.c:972 #, c-format msgid "must be superuser to connect in binary upgrade mode" msgstr "バイナリアップグレードモード中に接続するにはスーパーユーザーである必要があります" -#: utils/init/postinit.c:986 +#: utils/init/postinit.c:992 #, c-format msgid "remaining connection slots are reserved for roles with the %s attribute" msgstr "残りの接続枠は%s属性を持つロールのために予約されています" -#: utils/init/postinit.c:992 +#: utils/init/postinit.c:998 #, c-format msgid "remaining connection slots are reserved for roles with privileges of the \"%s\" role" msgstr "残りの接続枠は\"%s\"ロールの権限を持つロールのために予約されています" -#: utils/init/postinit.c:1004 +#: utils/init/postinit.c:1010 #, c-format msgid "permission denied to start WAL sender" msgstr "WAL送信プロセスを開始する権限がありません" -#: utils/init/postinit.c:1005 +#: utils/init/postinit.c:1011 #, c-format msgid "Only roles with the %s attribute may start a WAL sender process." msgstr "%s属性を持つロールのみがWAL送信プロセスを開始できます。" -#: utils/init/postinit.c:1126 +#: utils/init/postinit.c:1132 #, c-format msgid "It seems to have just been dropped or renamed." msgstr "削除またはリネームされたばかりのようです。" -#: utils/init/postinit.c:1130 +#: utils/init/postinit.c:1136 #, c-format msgid "database %u does not exist" msgstr "データベース %u は存在しません" -#: utils/init/postinit.c:1139 +#: utils/init/postinit.c:1145 #, c-format msgid "cannot connect to invalid database \"%s\"" msgstr "無効なデータベース\"%s\"への接続はできません" -#: utils/init/postinit.c:1200 +#: utils/init/postinit.c:1206 #, c-format msgid "The database subdirectory \"%s\" is missing." msgstr "データベースのサブディレクトリ\"%s\"がありません。" @@ -34086,6 +34291,13 @@ msgstr "利用可能な値: " msgid "." msgstr "." +#. translator: This is a separator in a list of entity +#. names. +#. +#: utils/misc/guc.c:3182 +msgid ", " +msgstr ", " + #: utils/misc/guc.c:3374 #, c-format msgid "parameter \"%s\" cannot be set during a parallel operation" @@ -34216,199 +34428,199 @@ msgstr "NULLは%sに対して不正な値です" msgid "SET requires parameter name" msgstr "SETにはパラメータ名が必要です" -#: utils/misc/guc_tables.c:738 +#: utils/misc/guc_tables.c:739 msgid "Ungrouped" msgstr "その他" -#: utils/misc/guc_tables.c:739 +#: utils/misc/guc_tables.c:740 msgid "File Locations" msgstr "ファイルの位置" -#: utils/misc/guc_tables.c:740 +#: utils/misc/guc_tables.c:741 msgid "Connections and Authentication / Connection Settings" msgstr "接続と認証/接続設定" -#: utils/misc/guc_tables.c:741 +#: utils/misc/guc_tables.c:742 msgid "Connections and Authentication / TCP Settings" msgstr "接続と認証/TCP設定" -#: utils/misc/guc_tables.c:742 +#: utils/misc/guc_tables.c:743 msgid "Connections and Authentication / Authentication" msgstr "接続と認証/認証" -#: utils/misc/guc_tables.c:743 +#: utils/misc/guc_tables.c:744 msgid "Connections and Authentication / SSL" msgstr "接続と認証/SSL" -#: utils/misc/guc_tables.c:744 +#: utils/misc/guc_tables.c:745 msgid "Resource Usage / Time" msgstr "リソース使用 / 時間" -#: utils/misc/guc_tables.c:745 +#: utils/misc/guc_tables.c:746 msgid "Resource Usage / Memory" msgstr "使用リソース/メモリ" -#: utils/misc/guc_tables.c:746 +#: utils/misc/guc_tables.c:747 msgid "Resource Usage / Disk" msgstr "使用リソース/ディスク" -#: utils/misc/guc_tables.c:747 +#: utils/misc/guc_tables.c:748 msgid "Resource Usage / Kernel Resources" msgstr "使用リソース/カーネルリソース" -#: utils/misc/guc_tables.c:748 +#: utils/misc/guc_tables.c:749 msgid "Resource Usage / Background Writer" msgstr "使用リソース / バックグラウンド・ライタ" -#: utils/misc/guc_tables.c:749 +#: utils/misc/guc_tables.c:750 msgid "Resource Usage / I/O" msgstr "使用リソース/ I/O" -#: utils/misc/guc_tables.c:750 +#: utils/misc/guc_tables.c:751 msgid "Resource Usage / Worker Processes" msgstr "使用リソース/ワーカープロセス" -#: utils/misc/guc_tables.c:751 +#: utils/misc/guc_tables.c:752 msgid "Write-Ahead Log / Settings" msgstr "先行書き込みログ / 設定" -#: utils/misc/guc_tables.c:752 +#: utils/misc/guc_tables.c:753 msgid "Write-Ahead Log / Checkpoints" msgstr "先行書き込みログ / チェックポイント" -#: utils/misc/guc_tables.c:753 +#: utils/misc/guc_tables.c:754 msgid "Write-Ahead Log / Archiving" msgstr "先行書き込みログ / アーカイビング" -#: utils/misc/guc_tables.c:754 +#: utils/misc/guc_tables.c:755 msgid "Write-Ahead Log / Recovery" msgstr "先行書き込みログ / リカバリ" -#: utils/misc/guc_tables.c:755 +#: utils/misc/guc_tables.c:756 msgid "Write-Ahead Log / Archive Recovery" msgstr "先行書き込みログ / アーカイブリカバリ" -#: utils/misc/guc_tables.c:756 +#: utils/misc/guc_tables.c:757 msgid "Write-Ahead Log / Recovery Target" msgstr "先行書き込みログ / チェックポイント" -#: utils/misc/guc_tables.c:757 +#: utils/misc/guc_tables.c:758 msgid "Write-Ahead Log / Summarization" msgstr "先行書き込みログ / 集約" -#: utils/misc/guc_tables.c:758 +#: utils/misc/guc_tables.c:759 msgid "Replication / Sending Servers" msgstr "レプリケーション / 送信サーバー" -#: utils/misc/guc_tables.c:759 +#: utils/misc/guc_tables.c:760 msgid "Replication / Primary Server" msgstr "レプリケーション / プライマリサーバー" -#: utils/misc/guc_tables.c:760 +#: utils/misc/guc_tables.c:761 msgid "Replication / Standby Servers" msgstr "レプリケーション / スタンバイサーバー" -#: utils/misc/guc_tables.c:761 +#: utils/misc/guc_tables.c:762 msgid "Replication / Subscribers" msgstr "レプリケーション / サブスクライバ" -#: utils/misc/guc_tables.c:762 +#: utils/misc/guc_tables.c:763 msgid "Query Tuning / Planner Method Configuration" msgstr "問い合わせのチューニング / プランナ手法設定" -#: utils/misc/guc_tables.c:763 +#: utils/misc/guc_tables.c:764 msgid "Query Tuning / Planner Cost Constants" msgstr "問い合わせのチューニング / プランナコスト定数" -#: utils/misc/guc_tables.c:764 +#: utils/misc/guc_tables.c:765 msgid "Query Tuning / Genetic Query Optimizer" msgstr "問い合わせのチューニング / 遺伝的問い合わせオプティマイザ" -#: utils/misc/guc_tables.c:765 +#: utils/misc/guc_tables.c:766 msgid "Query Tuning / Other Planner Options" msgstr "問い合わせのチューニング / その他のプランオプション" -#: utils/misc/guc_tables.c:766 +#: utils/misc/guc_tables.c:767 msgid "Reporting and Logging / Where to Log" msgstr "レポートとログ出力 / ログの出力先" -#: utils/misc/guc_tables.c:767 +#: utils/misc/guc_tables.c:768 msgid "Reporting and Logging / When to Log" msgstr "レポートとログ出力 / ログのタイミング" -#: utils/misc/guc_tables.c:768 +#: utils/misc/guc_tables.c:769 msgid "Reporting and Logging / What to Log" msgstr "レポートとログ出力 / ログの内容" -#: utils/misc/guc_tables.c:769 +#: utils/misc/guc_tables.c:770 msgid "Reporting and Logging / Process Title" msgstr "レポートとログ出力 / プロセス表記" -#: utils/misc/guc_tables.c:770 +#: utils/misc/guc_tables.c:771 msgid "Statistics / Monitoring" msgstr "統計情報 / 監視" -#: utils/misc/guc_tables.c:771 +#: utils/misc/guc_tables.c:772 msgid "Statistics / Cumulative Query and Index Statistics" msgstr "統計情報 / 問い合わせとインデックスの累積統計情報" -#: utils/misc/guc_tables.c:772 +#: utils/misc/guc_tables.c:773 msgid "Vacuuming / Automatic Vacuuming" msgstr "VACUUM / 自動VACUUM" -#: utils/misc/guc_tables.c:773 +#: utils/misc/guc_tables.c:774 msgid "Vacuuming / Cost-Based Vacuum Delay" msgstr "VACUUM / コストベースVACUUM遅延" -#: utils/misc/guc_tables.c:774 +#: utils/misc/guc_tables.c:775 msgid "Vacuuming / Default Behavior" msgstr "VACUUM / デフォルト動作" -#: utils/misc/guc_tables.c:775 +#: utils/misc/guc_tables.c:776 msgid "Vacuuming / Freezing" msgstr "VACUUM / 凍結" -#: utils/misc/guc_tables.c:776 +#: utils/misc/guc_tables.c:777 msgid "Client Connection Defaults / Statement Behavior" msgstr "クライアント接続のデフォルト設定 / 文の振舞い" -#: utils/misc/guc_tables.c:777 +#: utils/misc/guc_tables.c:778 msgid "Client Connection Defaults / Locale and Formatting" msgstr "クライアント接続のデフォルト設定 / ロケールと整形" -#: utils/misc/guc_tables.c:778 +#: utils/misc/guc_tables.c:779 msgid "Client Connection Defaults / Shared Library Preloading" msgstr "クライアント接続のデフォルト設定 / ライブラリの事前読み込み" -#: utils/misc/guc_tables.c:779 +#: utils/misc/guc_tables.c:780 msgid "Client Connection Defaults / Other Defaults" msgstr "クライアント接続のデフォルト設定 / その他のデフォルト設定" -#: utils/misc/guc_tables.c:780 +#: utils/misc/guc_tables.c:781 msgid "Lock Management" msgstr "ロック管理" -#: utils/misc/guc_tables.c:781 +#: utils/misc/guc_tables.c:782 msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" msgstr "バージョンおよびプラットフォーム間の互換性 / PostgreSQLの以前のバージョン" -#: utils/misc/guc_tables.c:782 +#: utils/misc/guc_tables.c:783 msgid "Version and Platform Compatibility / Other Platforms and Clients" msgstr "バージョンおよびプラットフォーム間の互換性 / 他のプラットフォームおよびクライアント" -#: utils/misc/guc_tables.c:783 +#: utils/misc/guc_tables.c:784 msgid "Error Handling" msgstr "エラーハンドリング" -#: utils/misc/guc_tables.c:784 +#: utils/misc/guc_tables.c:785 msgid "Preset Options" msgstr "事前設定オプション" -#: utils/misc/guc_tables.c:785 +#: utils/misc/guc_tables.c:786 msgid "Customized Options" msgstr "独自オプション" -#: utils/misc/guc_tables.c:786 +#: utils/misc/guc_tables.c:787 msgid "Developer Options" msgstr "開発者向けオプション" @@ -34437,22 +34649,22 @@ msgstr "問い合わせはテーブル\"%s\"に対する行レベルセキュリ msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." msgstr "テーブルの所有者に対するポリシを無効にするには、ALTER TABLE NO FORCE ROW LEVEL SECURITY を使ってください。" -#: utils/misc/stack_depth.c:101 +#: utils/misc/stack_depth.c:102 #, c-format msgid "stack depth limit exceeded" msgstr "スタック長制限を越えました" -#: utils/misc/stack_depth.c:102 +#: utils/misc/stack_depth.c:103 #, c-format msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." msgstr "プラットフォームのスタック長制限が適切であることを確認した後に、設定パラメータ\"max_stack_depth\" (現在 %dkB)を増やしてください。" -#: utils/misc/stack_depth.c:149 +#: utils/misc/stack_depth.c:165 #, c-format msgid "\"max_stack_depth\" must not exceed %zdkB." msgstr "\"max_stack_depth\"は%zdkBを越えてはなりません。" -#: utils/misc/stack_depth.c:151 +#: utils/misc/stack_depth.c:167 #, c-format msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." msgstr "プラットフォームのスタック長制限を\"ulimit -s\"または同等の機能を使用して増加してください" @@ -34766,6 +34978,9 @@ msgstr "異なるデータベースからのスナップショットを読み込 #~ msgid "RADIUS server not specified" #~ msgstr "RADIUS サーバーが指定されていません" +#~ msgid "Relation \"%s\" has insufficient replication identity." +#~ msgstr "リレーション\"%s\"のレプリケーション識別の定義が不十分です。" + #~ msgid "Remote row %s" #~ msgstr "リモート行 %s" @@ -34818,6 +35033,12 @@ msgstr "異なるデータベースからのスナップショットを読み込 #~ msgid "cannot mark index clustered in partitioned table" #~ msgstr "パーティションテーブル内のインデックスは CLUSTER 済みとマークできません`" +#~ msgid "cannot process relation \"%s\"" +#~ msgstr "リレーション\"%s\"を処理できません" + +#~ msgid "cannot repack relation \"%s\"" +#~ msgstr "リレーション\"%s\"はREPACKできません" + #~ msgid "cannot synchronize replication slots when standby promotion is ongoing" #~ msgstr "スタンバイの昇格処理中はリプリケーションスロットの同期はできません" @@ -34885,9 +35106,18 @@ msgstr "異なるデータベースからのスナップショットを読み込 #~ msgid "extended statistics require at least 2 columns" #~ msgstr "拡張統計情報には最低でも2つの列が必要です" +#~ msgid "failed to apply concurrent DELETE" +#~ msgstr "同時実行されたDELETEの適用に失敗しました" + +#~ msgid "failed to apply concurrent UPDATE" +#~ msgstr "同時実行されたUPDATEの適用に失敗しました" + #~ msgid "grantor must be current user" #~ msgstr "権限付与者は現在のユーザーでなければなりません" +#~ msgid "insufficient number of attributes stored separately" +#~ msgstr "別途格納されていた属性の数が不足しています" + #~ msgid "invalid RADIUS port number: \"%s\"" #~ msgstr "不正なRADIUSポート番号: \"%s\"" @@ -34921,6 +35151,12 @@ msgstr "異なるデータベースからのスナップショットを読み込 #~ msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" #~ msgstr "最古のマルチトランザクション%uが見つかりません、アクセス可能な最古のものは%u、切り詰めをスキップします" +#~ msgid "option \"%s\" is specified more than once" +#~ msgstr "オプション\"%s\"が複数指定されました" + +#~ msgid "option name at variadic position %d is null" +#~ msgstr "可変長引数の位置%dのオプション名がnullです" + #~ msgid "page containing LP_DEAD items is marked as all-visible in relation \"%s\" page %u" #~ msgstr "リレーション\"%s\"のページ %u はLP_DEAD項目を含みませんが、全可視(all-visible)とマークされています" @@ -34975,6 +35211,9 @@ msgstr "異なるデータベースからのスナップショットを読み込 #~ msgid "unrecognized VACUUM option \"%s\"" #~ msgstr "認識できないVACUUMオプション \"%s\"" +#~ msgid "unrecognized option: \"%s\"" +#~ msgstr "認識できないオプション: \"%s\"" + #~ msgid "unrecognized value for CREATE_REPLICATION_SLOT option \"%s\": \"%s\"" #~ msgstr "CREATE_REPLICATION_SLOTのオプション\"%s\"に対する認識できない値: \"%s\"" @@ -34987,5 +35226,8 @@ msgstr "異なるデータベースからのスナップショットを読み込 #~ msgid "vacuuming \"%s.%s\"" #~ msgstr "\"%s.%s\"に対してVACUUMを実行しています" +#~ msgid "value for option \"%s\" must not be null" +#~ msgstr "オプション\"%s\"の値はnullであってはなりません" + #~ msgid "when building statistics on a single expression, statistics kinds may not be specified" #~ msgstr "単一式上の統計情報の構築時には、統計種別は指定できません" diff --git a/src/backend/po/ka.po b/src/backend/po/ka.po index b7ef0a5cf43..d26da511043 100644 --- a/src/backend/po/ka.po +++ b/src/backend/po/ka.po @@ -34653,1336 +34653,3 @@ msgstr "" msgid "cannot import a snapshot from a different database" msgstr "სხვა ბაზიდან სწრაფი ასლის შემოტანა შეუძლებელია" -#, c-format -#~ msgid " GSS (authenticated=%s, encrypted=%s)" -#~ msgstr " GSS (ავთენტიფიცირებული=%s, დაშიფრული=%s)" - -#, c-format -#~ msgid "\"%s\" array cannot contain NULL values" -#~ msgstr "\"%s\" მასივი, არ შეიძლება, NULL მნიშვნელობებს შეიცავდეს" - -#, c-format -#~ msgid "\"%s\" cannot be NULL" -#~ msgstr "\"%s\" არ შეიძლება, NULL იყოს" - -#, c-format -#~ msgid "\"%s\" is not a partition" -#~ msgstr "\"%s\" დანაყოფი არაა" - -#, c-format -#~ msgid "\"%s\" is not a physical replication slot." -#~ msgstr "\"%s\" ფიზიკური რეპლიკაციის სლოტი არაა." - -#, c-format -#~ msgid "\"%s\" must be set to -1 during binary upgrade mode." -#~ msgstr "ბინარული განახლების რეჟიმისას \"%s\"-ის მნიშვნელობა -1-ზე უნდა დააყენოთ." - -#, c-format -#~ msgid "\"%s\" must be set to 0 during binary upgrade mode." -#~ msgstr "ბინარული განახლების რეჟიმისას \"%s\"-ის მნიშვნელობა 0-ზე უნდა დააყენოთ." - -#, c-format -#~ msgid "\"%s\" must be set to 0 on platforms that lack support for issuing read-ahead advice." -#~ msgstr "\"%s\" უნდა იყოს 0 პლატფორმებზე, რომლებსაც წინასწარ-წაკითხვის მითითების მხარდაჭერა არ გააჩნიათ." - -#, c-format -#~ msgid "\"RN\" not supported for input" -#~ msgstr "\"RN\" შეყვანისთვის მხარდაჭერილი არაა" - -#, c-format -#~ msgid "\"debug_io_direct\" is not supported for data because BLCKSZ is too small" -#~ msgstr "\"debug_io_direct\" მონაცემებისთვის მხარდაჭერილი არაა, რადგან BLCKSZ ძალიან პატარაა" - -#, c-format -#~ msgid "\"debug_io_direct\" is not supported on this platform." -#~ msgstr "\"debug_io_direct\" ამ პლატფორმაზე მხარდაჭერილი არაა." - -#, c-format -#~ msgid "\"maintenance_io_concurrency\" must be set to 0 on platforms that lack posix_fadvise()." -#~ msgstr "პლატფორმებზე, რომლებზეც posix_fadvise() ხელმისაწვდომი არაა, \"maintenance_io_concurrency\"-ის მნიშვნელობა 0-ის ტოლი უნდა ყოს." - -#, c-format -#~ msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" -#~ msgstr "\"max_wal_size\"-ი \"wal_segment_size\"-ზე, მინიმუმ, ორჯერ მეტი უნდა იყოს" - -#, c-format -#~ msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" -#~ msgstr "\"min_wal_size\"-ი \"wal_segment_size\"-ზე მინიმუმ ორჯერ მეტი უნდა იყოს" - -#, c-format -#~ msgid "\"recovery_target_timeline\" is not a valid number." -#~ msgstr "\"recovery_target_timeline\" სწორი რიცხვი არაა." - -#, c-format -#~ msgid "\"synchronous_standby_names\" parser failed" -#~ msgstr "\"synchronous_standby_names\"-ის დამმუშავებლის შეცდომა" - -#, c-format -#~ msgid "%s cannot be executed within a pipeline" -#~ msgstr "%s ფუნქციიდან ვერ გაეშვება" - -#, c-format -#~ msgid "%s requires a \"none\" or \"stored\" value" -#~ msgstr "%s მოითხოვს მნიშვნელობას \"none' ან \"stored\"" - -#, c-format -#~ msgid "%s requires a Boolean value or \"match\"" -#~ msgstr "%s -ს ლოგიკური მნიშვნელობა უნდა ჰქონდეს, ან \"match\"" - -#, c-format -#~ msgid "%s with OID %u does not exist" -#~ msgstr "%s OID-ით %u არ არსებობს" - -#~ msgid "-1 indicates that the value could not be determined." -#~ msgstr "-1 ნიშნავს, რომ მნიშვნელობა ვერ განისაზღვრა." - -#, c-format -#~ msgid "-X requires a power of two value between 1 MB and 1 GB" -#~ msgstr "-X მოითხოვს მნიშვნელობას, რომელიც ორის ხარისხია და არის 1 მბ-სა და 1გბ-ს შორის" - -#~ msgid "0 turns this feature off." -#~ msgstr "0 გამორთავს ამ ფუნქციას." - -#~ msgid ": " -#~ msgstr ": " - -#~ msgid "A value of -1 disables this feature." -#~ msgstr "მნიშვნელობა -1 გამორთავს ამ ფუნქციას." - -#~ msgid "A value of 0 turns off the timeout." -#~ msgstr "0 მოლოდინის ვადას გამორთავს." - -#, c-format -#~ msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" -#~ msgstr "ALTER SUBSCRIPTION ... REFRESH დაუშვებელია გათიშული გამოწერებისთვის" - -#, c-format -#~ msgid "ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns in tables with check constraints" -#~ msgstr "ALTER TABLE / SET EXPRESSION მხარდაჭერილი არაა ვირტუალური გენერირებული სვეტებისთვის შეზღუდვების შემოწმების მქონე ცხრილებში" - -#, c-format -#~ msgid "Abort reason: recovery conflict" -#~ msgstr "გაუქმების მიზეზი: აღდგენის კონფლიქტი" - -#, c-format -#~ msgid "BUFFER_USAGE_LIMIT option must be 0 or between %d kB and %d kB" -#~ msgstr "BUFFER_USAGE_LIMIT პარამეტრი 0 ან %d კბ-სა და %d კბ-ს შორის უნდა იყოს" - -#, c-format -#~ msgid "COPY DEFAULT only available using COPY FROM" -#~ msgstr "COPY DEFAULT მხოლოდ COPY FROM-ის გამოყენების დროსაა ხელმისაწვდომი" - -#, c-format -#~ msgid "COPY ESCAPE requires CSV mode" -#~ msgstr "COPY ESCAPE-ს CSV რეჟიმი სჭირდება" - -#, c-format -#~ msgid "COPY FORCE_NOT_NULL cannot be used with COPY TO" -#~ msgstr "COPY FORCE_NOT_NULL-ს COPY TO-სთან ერთად ვერ გამოიყენებთ" - -#, c-format -#~ msgid "COPY FORCE_NOT_NULL requires CSV mode" -#~ msgstr "COPY FORCE_NOT_NULL-ს CSV რეჟიმი სჭირდება" - -#, c-format -#~ msgid "COPY FORCE_NULL cannot be used with COPY TO" -#~ msgstr "COPY FORCE_NULL-ს COPY TO-სთან ერთად ვერ გამოიყენებთ" - -#, c-format -#~ msgid "COPY FORCE_NULL requires CSV mode" -#~ msgstr "COPY FORCE_NULL-ს CSV რეჟიმი სჭირდება" - -#, c-format -#~ msgid "COPY FORCE_QUOTE cannot be used with COPY FROM" -#~ msgstr "COPY FORCE_QUOTE-ს COPY FROM-სთან ერთად ვერ გამოიყენებთ" - -#, c-format -#~ msgid "COPY FORCE_QUOTE requires CSV mode" -#~ msgstr "COPY FORCE_QUOTE-ს CSV რეჟიმი სჭირდება" - -#, c-format -#~ msgid "COPY LOG_VERBOSITY \"%s\" not recognized" -#~ msgstr "COPY LOG_VERBOSITY \"%s\" უცნობია" - -#, c-format -#~ msgid "COPY ON_ERROR \"%s\" not recognized" -#~ msgstr "COPY ON_ERROR \"%s\" უცნობია" - -#, c-format -#~ msgid "COPY ON_ERROR cannot be used with COPY TO" -#~ msgstr "COPY ON_ERROR-ს COPY TO-სთან ერთად ვერ გამოიყენებთ" - -#, c-format -#~ msgid "COPY delimiter must not appear in the DEFAULT specification" -#~ msgstr "COPY-ის გამყოფი DEFAULT-ის სპეციფიკაციაში არ უნდა გამოჩნდეს" - -#, c-format -#~ msgid "COPY escape available only in CSV mode" -#~ msgstr "COPY-ის სპეცსიმბოლო მხოლოდ CSV -ის რეჟიმშია ხელმისაწვდომი" - -#, c-format -#~ msgid "COPY force not null available only in CSV mode" -#~ msgstr "COPY-ის პარამეტრი force not null მხოლოდ CSV რეჟიმში შეგიძლიათ, გამოიყენოთ" - -#, c-format -#~ msgid "COPY force not null only available using COPY FROM" -#~ msgstr "COPY-ის პარამეტრი force not null მხოლოდ COPY FROM-ის გამოყენების დროსაა ხელმისაწვდომი" - -#, c-format -#~ msgid "COPY force null available only in CSV mode" -#~ msgstr "COPY-ის პარამეტრი force null მხოლოდ CSV რეჟიმში შეგიძლიათ, გამოიყენოთ" - -#, c-format -#~ msgid "COPY force null only available using COPY FROM" -#~ msgstr "COPY-ის პარამეტრი force null მხოლოდ COPY FROM-ის გამოყენების დროსაა ხელმისაწვდომი" - -#, c-format -#~ msgid "COPY force quote available only in CSV mode" -#~ msgstr "COPY-ის პარამეტრი force quote მხოლოდ CSV რეჟიმში შეგიძლიათ, გამოიყენოთ" - -#, c-format -#~ msgid "COPY force quote only available using COPY TO" -#~ msgstr "COPY-ის პარამეტრი force quote მხოლოდ COPY TO-ის გამოყენების დროსაა ხელმისაწვდომი" - -#, c-format -#~ msgid "COPY quote available only in CSV mode" -#~ msgstr "COPY-ის ბრჭყალი მხოლოდ CSV -ის რეჟიმშია ხელმისაწვდომი" - -#, c-format -#~ msgid "CSV quote character must not appear in the DEFAULT specification" -#~ msgstr "CSV-ის ბრჭყალის სიმბოლო DEFAULT-ის სპეციფიკაციაში არ უნდა გამოჩნდეს" - -#, c-format -#~ msgid "Change \"wal_level\" to be \"logical\" or higher." -#~ msgstr "შეცვალეთ \"wal_level\" \"logical\"-ზე ან უფრო მაღალზე." - -#, c-format -#~ msgid "Consider creating the slot \"%s\" or amend parameter %s." -#~ msgstr "განიხილეთ, შექმნათ სლოტი \"%s\", ან მიაწერეთ პარამეტრი %s." - -#, c-format -#~ msgid "Consider increasing the configuration parameter \"max_worker_processes\"." -#~ msgstr "გაითვალისწინეთ, რომ შეიძლება კონფიგურაციის პარამეტრის \"max_worker_processes\" გაზრდა გჭირდებათ." - -#~ msgid "Controls when to replicate or apply each change." -#~ msgstr "აკონტროლებს, როდის მოხდება თითოეული ცვლილების რეპლიკაცია ან გადატარება." - -#, c-format -#~ msgid "Could not close file \"%s\": %m." -#~ msgstr "ფაილის (%s) დახურვის შეცდომა: %m." - -#, c-format -#~ msgid "Could not fsync file \"%s\": %m." -#~ msgstr "ფაილის (%s) fsync-ის შეცდომა: %m." - -#, c-format -#~ msgid "Could not open extension control file \"%s\": %m." -#~ msgstr "გაფართოების კონტროლის ფაილის (\"%s\") გახსნის შეცდომა: %m." - -#, c-format -#~ msgid "Could not open file \"%s\": %m." -#~ msgstr "ფაილის (%s) გახსნის შეცდომა: %m." - -#, c-format -#~ msgid "DEFAULT partition should be one" -#~ msgstr "DEFAULT დანაყოფი ერთი უნდა იყოს" - -#, c-format -#~ msgid "ECDH: could not create key" -#~ msgstr "ECDH: გასაღების შექნის შეცდომა" - -#, c-format -#~ msgid "ECDH: unrecognized curve name: %s" -#~ msgstr "ECDH: მრუდის უცნობი სახელი: %s" - -#, c-format -#~ msgid "EXPLAIN option SERIALIZE requires ANALYZE" -#~ msgstr "EXPLAIN-ის პარამეტრს SERIALIZE 'ANALYZE' სჭირდება" - -#, c-format -#~ msgid "EXPLAIN option TIMING requires ANALYZE" -#~ msgstr "EXPLAIN -ის პარამეტრ TIMING-ს ANALYZE სჭირდება" - -#, c-format -#~ msgid "EXPLAIN options ANALYZE and GENERIC_PLAN cannot be used together" -#~ msgstr "EXPLAIN-ის პარამეტრები ANALYZE და GENERIC_PLAN ერთად არ შეიძლება, გამოიყენოთ" - -#~ msgid "Enables logging of recovery-related debugging information." -#~ msgstr "აღდგენასთან კავშირში მყოფი გამართვის ინფორმაციის ჟურნალში ჩაწერის ჩართვა." - -#~ msgid "Enables per-database user names." -#~ msgstr "თითოეული ბაზისთვის საკუთარი მომხმარებლის სახელების ჩართვა." - -#, c-format -#~ msgid "Execute a database-wide VACUUM in database with OID %u with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings." -#~ msgstr "მთელ ბაზაზე მომტვერსასრუტების შესრულება ბაზაში OID-ით %u შემცირებული \"vacuum_multixact_freeze_min_age\" და \"vacuum_multixact_freeze_table_age\" პარამეტრებით." - -#, c-format -#~ msgid "Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings." -#~ msgstr "მთელ ბაზაზე მომტვერსასრუტების შესრულება მითითებულ ბაზაში შემცირებული \"vacuum_multixact_freeze_min_age\" და \"vacuum_multixact_freeze_table_age\" პარამეტრებით." - -#, c-format -#~ msgid "Existing constraint \"%s\" is marked NO INHERIT." -#~ msgstr "არსებული შეზღუდვა \"%s\" დანიშნულია, როგორც NO INHERIT." - -#, c-format -#~ msgid "Existing local row %s" -#~ msgstr "არსებული ლოკალური მწკრივი %s" - -#, c-format -#~ msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" -#~ msgstr "FORCE_NOT_NULL სვეტი \"%s\" COPY-ის მიერ მითითებული არაა" - -#, c-format -#~ msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" -#~ msgstr "FORCE_QUOTE სვეტი \"%s\" COPY-ის მიერ მითითებული არაა" - -#, c-format -#~ msgid "For example, FROM (SELECT ...) [AS] foo." -#~ msgstr "მაგალითად, FROM (SELECT ...) [AS] foo." - -#, c-format -#~ msgid "For example, FROM (VALUES ...) [AS] foo." -#~ msgstr "მაგალითად, FROM (VALUES ...) [AS] foo." - -#, c-format -#~ msgid "Foreign tables cannot have TRUNCATE triggers." -#~ msgstr "გარე ცხრილებს TRUNCATE ტრიგერები ვერ ექნებათ." - -#~ msgid "If blank, no prefix is used." -#~ msgstr "თუ ცარიელია, პრეფიქსი არ გამოიყენება." - -#~ msgid "Incremental parser requires incremental lexer" -#~ msgstr "ინკრემენტულ დამმუშავებელს ინკრემენტული lexer სჭირდება" - -#, c-format -#~ msgid "Invalid list syntax in parameter \"log_connections\"." -#~ msgstr "არასწორი სიის სინტაქსი პარამეტრში \"log_connections\"." - -#, c-format -#~ msgid "Invalid list syntax in parameter %s" -#~ msgstr "არასწორი სიის სინტაქსი პარამეტრში %s" - -#~ msgid "JSON nested too deep, maximum permitted depth is 6400" -#~ msgstr "JSON მეტისმეტად ღრმადაა ერთმანეთში ჩალაგებული. მაქსიმალური დასაშვები სიღრმეა 6400" - -#, c-format -#~ msgid "JSON_TABLE column names must be distinct from one another" -#~ msgstr "JSON_TABLE-ის სვეტის სახელები ერთმანეთისგან უნდა განსხვავდებოდნენ" - -#, c-format -#~ msgid "LIKE is not supported for creating foreign tables" -#~ msgstr "გარე ცხრილების შექმნისთვის LIKE მხარდაჭერილი არაა" - -#~ msgid "Log backtrace for any error with error code XX000 (internal error)." -#~ msgstr "ნებისმიერი შეცდომის უკუტრეისის ჩაწერა ჟურნალში შეცდომის კოდით XX000 (შიდა შეცდომა)." - -#~ msgid "Logs each successful connection." -#~ msgstr "ყოველი წარმატებული შესვლის ჟურნალში ჩაწერა." - -#, c-format -#~ msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" -#~ msgstr "MD5 ავთენტიკაცია მაშინ, როცა \"db_user_namespace\" ჩართულია, მხარდაჭერილი არაა" - -#, c-format -#~ msgid "MERGE not supported in COPY" -#~ msgstr "COPY-ში MERGE მხარდაჭერილი არაა" - -#, c-format -#~ msgid "MERGE not supported in WITH query" -#~ msgstr "\"MERGE\"-ი \"WITH\" მოთხოვნაში მხარდაუჭერელია" - -#, c-format -#~ msgid "MaxFragments should be >= 0" -#~ msgstr "MaxFragments >= 0 უნდა იყოს" - -#~ msgid "Maximum number of table synchronization workers per subscription." -#~ msgstr "თითოეული გამოწერის ცხრილის სინქრონიზაციის დამხმარე პროცესების მაქსიმალური რაოდენობა." - -#, c-format -#~ msgid "MinWords should be less than MaxWords" -#~ msgstr "MinWords MaxWords-ზე ნაკლები უნდა იყოს" - -#, c-format -#~ msgid "MinWords should be positive" -#~ msgstr "MinWords დადებით უნდა იყოს" - -#, c-format -#~ msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" -#~ msgstr "NULLS FIRST/LAST პირობაზე ON CONFLICT დაშვებული არაა" - -#, c-format -#~ msgid "Object keys should be text." -#~ msgstr "ობიექტის გასაღებები ტექსტი უნდა იყოს." - -#, c-format -#~ msgid "PID %d is no longer a PostgreSQL server process" -#~ msgstr "პროცესი PID-ით %d PostgreSQL-ის სერვერის პროცესს აღარ წარმოადგენს" - -#, c-format -#~ msgid "Please report this to <%s>." -#~ msgstr "გთხოვთ, შეატყობინოთ <%s>." - -#, c-format -#~ msgid "RADIUS authentication does not support passwords longer than %d characters" -#~ msgstr "RADIUS-ით ავთენტიკაციისას %d სიმბოლოზე გრძელი პაროლები მხარდაჭერილი არაა" - -#, c-format -#~ msgid "RADIUS authentication failed for user \"%s\"" -#~ msgstr "რადიუსით ავთენტიფიკაცია მომხმარებლისთვის \"%s\" ვერ მოხერხდა" - -#, c-format -#~ msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" -#~ msgstr "RADIUS პასუხს %s-დან დაზიანებული სიგრძე გააჩნია: %d (რეალური სიგრძე %d)" - -#, c-format -#~ msgid "RADIUS response from %s has incorrect MD5 signature" -#~ msgstr "%s-დან მიღებული RADIUS პასუხის MD5 ხელმოწერა არასწორია" - -#, c-format -#~ msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" -#~ msgstr "%s-დან მიღებულ RADIUS-ს პასუხს არასწორი კოდი (%d) გააჩნია მომხმარებლისთვის \"%s\"" - -#, c-format -#~ msgid "RADIUS response from %s is to a different request: %d (should be %d)" -#~ msgstr "RADIUS პასუხი %s-დან სხვა მოთხოვნას ეკუთვნის: %d (უნდა იყოს %d)" - -#, c-format -#~ msgid "RADIUS response from %s too short: %d" -#~ msgstr "RADIUS პასუხი %s-დან მეტისმეტად მოკლეა: %d" - -#, c-format -#~ msgid "RADIUS response from %s was sent from incorrect port: %d" -#~ msgstr "RADIUS პასუხი \"%s\" გამოგზავნილია არასწორი პორტიდან: %d" - -#, c-format -#~ msgid "RADIUS secret not specified" -#~ msgstr "RADIUS-ის პაროლი მითითებული არაა" - -#, c-format -#~ msgid "RADIUS server not specified" -#~ msgstr "RADIUS სერვერი მითითებული არაა" - -#, c-format -#~ msgid "RECHECK is no longer required" -#~ msgstr "RECHECK საჭირო აღარაა" - -#~ msgid "Recursive descent parser cannot use incremental lexer" -#~ msgstr "რეკურსიულ დაღმავალ დამმუშავებელს ინკრემენტული lexer-ის გამოყენება არ შეუძლია" - -#, c-format -#~ msgid "Remote row %s" -#~ msgstr "დაშორებული მწკრივი %s" - -#, c-format -#~ msgid "Replica identity %s" -#~ msgstr "რეპლიკის იდენტიფიკატორი %s" - -#, c-format -#~ msgid "Replica identity full %s" -#~ msgstr "რეპლიკის იდენტიფიკატორი სრული %s" - -#, c-format -#~ msgid "Replication slot \"%s\" does not exist." -#~ msgstr "რეპლიკაციის სლოტი \"%s\" არ არსებობს." - -#~ msgid "Resource Usage / Asynchronous Behavior" -#~ msgstr "რესურსების გამოყენება / ასინქრონული ქცევა" - -#, c-format -#~ msgid "SQL/JSON item cannot be cast to target type" -#~ msgstr "SQL/JSON ჩანაწერი მითითებულ ტიპში ვერ გადავა" - -#, c-format -#~ msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." -#~ msgstr "სერვერის FLOAT8PASSBYVAL = %s, ბიბლიოთეკას კი %s." - -#, c-format -#~ msgid "Server has FUNC_MAX_ARGS = %d, library has %d." -#~ msgstr "სერვერის FUNC_MAX_ARGS = %d, ბიბლიოთეკას კი %d." - -#, c-format -#~ msgid "Server has INDEX_MAX_KEYS = %d, library has %d." -#~ msgstr "სერვერის INDEX_MAX_KEYS = %d, ბიბლიოთეკას კი %d." - -#, c-format -#~ msgid "Set \"wal_level\" to \"logical\" before creating subscriptions." -#~ msgstr "გამოწერების შექმნამდე საჭიროა \"wal_level\" -ის \"logical\" (ლოგიკურზე) დაყენება." - -#~ msgid "Sets the curve to use for ECDH." -#~ msgstr "ECDH-სთვის გამოყენებული მრუდის დაყენება." - -#, c-format -#~ msgid "ShortWord should be >= 0" -#~ msgstr "ShortWord >= 0 უნდა იყოს" - -#~ msgid "Shows the character classification and case conversion locale." -#~ msgstr "სიმბოლოების ზომის გადაყვანისა და სიმბოლოების კლასიფიკაციის ენის ჩვენება." - -#~ msgid "Shows the collation order locale." -#~ msgstr "დალაგების წესის ჩვენება." - -#, c-format -#~ msgid "Subscribed publication %s is subscribing to other publications." -#~ msgid_plural "Subscribed publications %s are subscribing to other publications." -#~ msgstr[0] "გამოწერილი პუბლიკაცია %s სხვა პუბლიკაციებს იწერს." -#~ msgstr[1] "გამოწერილი პუბლიკაცია %s სხვა პუბლიკაციებს იწერს." - -#, c-format -#~ msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." -#~ msgstr "მონაცემთა ბაზის კლასტერის ინიციალიზაცია მოხდა CATALOG_VERSION_NO %d -ით, მაგრამ სერვერი აგებულია CATALOG_VERSION_NO %d-ით." - -#, c-format -#~ msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." -#~ msgstr "მონაცემთა ბაზის კლასტერის ინიციალიზაცია მოხდა INDEX_MAX_KEYS %d -ით, მაგრამ სერვერი აგებულია INDEX_MAX_KEYS %d-ით." - -#, c-format -#~ msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." -#~ msgstr "მონაცემთა ბაზის კლასტერის ინიციალიზაცია მოხდა LOBLKSIZE %d -ით, მაგრამ სერვერი აგებულია LOBLKSIZE %d-ით." - -#, c-format -#~ msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." -#~ msgstr "მონაცემთა ბაზის კლასტერის ინიციალიზაცია მოხდა MAXALIGN %d -ით, მაგრამ სერვერი აგებულია MAXALIGN %d-ით." - -#, c-format -#~ msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." -#~ msgstr "მონაცემთა ბაზის კლასტერის ინიციალიზაცია მოხდა NAMEDATALEN %d -ით, მაგრამ სერვერი აგებულია NAMEDATALEN %d-ით." - -#, c-format -#~ msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." -#~ msgstr "მონაცემთა ბაზის კლასტერის ინიციალიზაცია მოხდა RELSEG_SIZE%d -ით, მაგრამ სერვერი აგებულია RELSEG_SIZE %d-ით." - -#, c-format -#~ msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." -#~ msgstr "მონაცემთა ბაზის კლასტერის ინიციალიზაცია მოხდა TOAST_MAX_CHUNK_SIZE %d -ით, მაგრამ სერვერი აგებულია TOAST_MAX_CHUNK_SIZE %d-ით." - -#, c-format -#~ msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." -#~ msgstr "მონაცემთა ბაზის კლასტერის ინიციალიზაცია მოხდა USE_FLOAT8_BYVA -ის გარეშე, მაგრამ სერვერი აგებულია USE_FLOAT8_BYVAL-ით." - -#, c-format -#~ msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." -#~ msgstr "მონაცემთა ბაზის კლასტერის ინიციალიზაცია მოხდა XLOG_BLCKSZ%d -ით, მაგრამ სერვერი აგებულია XLOG_BLCKSZ%d-ით." - -#, c-format -#~ msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." -#~ msgstr "მონაცემთა ბაზის კლასტერის ინიციალიზაცია მოხდა USE_FLOAT8_BYVAL-ის გარეშე, მაგრამ სერვერი აგებულია USE_FLOAT8_BYVAL-ით." - -#, c-format -#~ msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." -#~ msgstr "ბაზა ინიციალიზებული იყო LC_COLLATE \"%s\"-ით, რომელსაც setlocale() ვერ ცნობს." - -#, c-format -#~ msgid "The owner of a FOR ALL TABLES publication must be a superuser." -#~ msgstr "FOR ALL TABLES გამოცემის მფლობელი ზემომხმარებელი უნდა იყოს." - -#, c-format -#~ msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." -#~ msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." -#~ msgstr[0] "ბრძანება კი შექმნიდა %u-წევრიან მულტიტრანზაქციას, მაგრამ დარჩენილი ადგილი მხოლოდ %u წევრს ეყოფა." -#~ msgstr[1] "ბრძანება კი შექმნიდა %u-წევრიან მულტიტრანზაქციას, მაგრამ დარჩენილი ადგილი მხოლოდ %u წევრს ეყოფა." - -#, c-format -#~ msgid "This feature is not yet supported on partitioned tables." -#~ msgstr "ეს ოპერაცია დაყოფილი ცხრილებისთვის ჯერჯერობით მხარდაჭერილი არაა." - -#, c-format -#~ msgid "This slot is being synced from the primary server." -#~ msgstr "მიმდინარეობს ამ სლოტის სინქრონიზაცია ძირითადი სერვერიდან." - -#, c-format -#~ msgid "Unmatched \"%c\" character." -#~ msgstr "სიმბოლო \"%c\" არ ემთხვევა." - -#, c-format -#~ msgid "Update your data type." -#~ msgstr "განაახლეთ თქვენი მონაცემთა ტიპი." - -#, c-format -#~ msgid "Use ALTER DATABASE ... REFRESH COLLATION VERSION instead." -#~ msgstr "სანაცვლოდ გამოიყენეთ ALTER DATABASE ... REFRESH COLLATION VERSION." - -#, c-format -#~ msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION instead." -#~ msgstr "სანაცვლოდ გამოიყენეთ ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION." - -#, c-format -#~ msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." -#~ msgstr "სანაცვლოდ გამოიყენეთ ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY." - -#, c-format -#~ msgid "Use ALTER TABLE instead." -#~ msgstr "ამის ნაცვლად გამოიყენეთ ALTER TABLE." - -#, c-format -#~ msgid "Use ALTER TYPE instead." -#~ msgstr "ამის ნაცვლად გამოიყენეთ ALTER TYPE." - -#, c-format -#~ msgid "VALUES in FROM must have an alias" -#~ msgstr "FROM-ში VALUES-ს აუცილებელია მეტსახელი ჰქონდეს" - -#, c-format -#~ msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" -#~ msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" -#~ msgstr[0] "WAL სეგმენტის ზომა ორის ხარისხი უნდა იყოს, 1 მბ-სა და 1გბ-ს შორის, მაგრამ კონტროლის ფაილში მითითებულია %d ბაიტი" -#~ msgstr[1] "WAL სეგმენტის ზომა ორის ხარისხი უნდა იყოს, 1 მბ-სა და 1გბ-ს შორის, მაგრამ კონტროლის ფაილში მითითებულია %d ბაიტი" - -#~ msgid "Zero prints all actions. -1 turns autovacuum logging off." -#~ msgstr "0-ს ყველა ქმედება გამოაქვს. -1 გამორთავს ავტომომტვერსასრუტებას." - -#~ msgid "Zero prints all queries. -1 turns this feature off." -#~ msgstr "0-ს ყველა მოთხოვნა გამოაქვს, -1 გამორთავს ამ ფუნქციას." - -#, c-format -#~ msgid "aborting startup due to startup process failure" -#~ msgstr "გაშვების გაუქმება გაშვების პროცესის შეცდომის გამო" - -#, c-format -#~ msgid "attribute \"%s\" is not a range type" -#~ msgstr "ატრიბუტი \"%s\" შუალედის ტიპი არაა" - -#, c-format -#~ msgid "attribute %d of relation \"%s\" does not exist" -#~ msgstr "ატრიბუტი %d ურთიერთობისთვის \"%s\" არ არსებობს" - -#, c-format -#~ msgid "authentication file token too long, skipping: \"%s\"" -#~ msgstr "ავთენტიკაციის ფაილის კოდი ძალიან გრძელია. გამოტოვება: \"%s\"" - -#, c-format -#~ msgid "bad magic number in dynamic shared memory segment" -#~ msgstr "არასწორი მაგიური რიცხვი დინამიურ გაზიარებულ მეხსიერების სეგმენტში" - -#~ msgid "bogus input" -#~ msgstr "საეჭვო შეყვანა" - -#, c-format -#~ msgid "cannot add NOT NULL constraint to column \"%s\" of relation \"%s\" with inheritance children" -#~ msgstr "ვერ დავამატე NOT NULL შეზღუდვა სვეტს \"%s\" ურთიერთობაზე \"%s\" რომელსაც მემკვიდრეობითი შვილები გააჩნია" - -#, c-format -#~ msgid "cannot change NO INHERIT status of NOT NULL constraint \"%s\" in relation \"%s\"" -#~ msgstr "ურთიერთობაზე \"%2$s\" NOT NULL შეზღუდვის \"%1$s\" NO INHERIT სტატუსს ვერ შეცვლით" - -#, c-format -#~ msgid "cannot change access method of a partitioned table" -#~ msgstr "დაყოფილი ცხრილის წვდომის მეთოდის შეცვლა შეუძლებელია" - -#, c-format -#~ msgid "cannot change inheritance of partitioned table" -#~ msgstr "დაყოფილი ცხრილის მემკვიდრეობითობის შეცვლა შეუძლებელია" - -#, c-format -#~ msgid "cannot commit subtransactions during a parallel operation" -#~ msgstr "პარალელური ოპერაციის დროს ქვეტრანსაქციების გადაგზავნა შეუძლებელია" - -#, c-format -#~ msgid "cannot copy from partitioned table \"%s\"" -#~ msgstr "დაყოფილი ცხრილიდან კოპირების შეცდომა: %s" - -#, c-format -#~ msgid "cannot create exclusion constraints on partitioned table \"%s\"" -#~ msgstr "დაყოფილ ცხრილზე (\"%s\") ექსკლუზიური შეზღუდვების შექმნა შეუძლებელია" - -#, c-format -#~ msgid "cannot create restricted tokens on this platform: error code %lu" -#~ msgstr "ამ პლატფორმაზე შეზღუდული კოდების შექმნა შეუძლებელია: შეცდომის კოდი %lu" - -#, c-format -#~ msgid "cannot mark index clustered in partitioned table" -#~ msgstr "დაყოფილ ცხრილში ინდექსის დაკლასტერებულად მონიშვნა შეუძლებელია" - -#, c-format -#~ msgid "cannot match partition key to an index using access method \"%s\"" -#~ msgstr "წვდომის მეთოდით \"%s\" დანაყოფის გასაღების ინდექსთან დამთხვევა შეუძლებელია" - -#, c-format -#~ msgid "cannot move table \"%s\" to schema \"%s\"" -#~ msgstr "ცხრილის (%s) სქემაში (%s) გადატანა შეუძლებელია" - -#, c-format -#~ msgid "cannot reindex invalid index \"%s.%s\" concurrently, skipping" -#~ msgstr "არასწორი ინდექსის \"%s.%s\" პარალელური რეინდექსი შეუძლებელია. გამოტოვება" - -#, c-format -#~ msgid "cannot remove constraint from only the partitioned table when partitions exist" -#~ msgstr "შეზღუდვის წაშლა მხოლოდ დაყოფილი ცხრილიდან მაშინ, როცა დანაყოფები არსებობს, შეუძლებელია" - -#, c-format -#~ msgid "cannot specify DEFAULT in BINARY mode" -#~ msgstr "'BINARY' რეჟიმში DEFAULT-ს ვერ მიუთითებთ" - -#, c-format -#~ msgid "cannot specify DELIMITER in BINARY mode" -#~ msgstr "რეჟიმში BINARY \"DELIMITER\"-ს ვერ მიუთითებთ" - -#, c-format -#~ msgid "cannot specify HEADER in BINARY mode" -#~ msgstr "რეჟიმში BINARY \"HEADER\"-ს ვერ მიუთითებთ" - -#, c-format -#~ msgid "cannot specify both attname and attnum" -#~ msgstr "ორივეს attname და attnum ვერ მიუთითებთ" - -#, c-format -#~ msgid "cannot start subtransactions during a parallel operation" -#~ msgstr "პარალელური ოპერაციის დროს ქვეტრანსაქციების დაწყება შეუძლებელია" - -#, c-format -#~ msgid "cannot subtract infinite timestamps" -#~ msgstr "უსასრულო დროის შტამპების გამოკლება შეუძლებელია" - -#, c-format -#~ msgid "cannot synchronize replication slots when standby promotion is ongoing" -#~ msgstr "რეპლიკაციის სლოტების სინქრონიზაცია შეუძლებელია უქმეს წახალისების მიმდინარეობისას" - -#, c-format -#~ msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON LARGE OBJECTS" -#~ msgstr "'IN SCHEMA' პირობის გამოყენება GRANT/REVOKE ON LARGE OBJECT-ის გამოყენებისას შეუძლებელია" - -#, c-format -#~ msgid "cannot use RETURNING type %s in %s" -#~ msgstr "'RETURNING'-ის ტიპს '%s' %s-ში ვერ გამოიყენებთ" - -#, c-format -#~ msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" -#~ msgstr "ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, ან ldapurl-ის ldapprefix-სთან ერთად გამოყენება შეუძლებელია" - -#, c-format -#~ msgid "cannot use more than one FOR ORDINALITY column" -#~ msgstr "ერთზე მეტ FOR ORDINALITY სვეტს ვერ გამოიყენებთ" - -#, c-format -#~ msgid "cannot use publication EXCEPT clause for relation \"%s\"" -#~ msgstr "ურთიერთობისთვის \"%s\" პუბლიკაციის პირობას EXCEPT ვერ გამოიყენებთ" - -#, c-format -#~ msgid "cannot vacuum temporary tables of other sessions" -#~ msgstr "სხვა სესიების დროებითი ცხრილების მომტვერსასრუტება შეუძლებელია" - -#, c-format -#~ msgid "collation provider LIBC is not supported on this platform" -#~ msgstr "კოლაციის მომწოდებელი LIBC ამ პლატფორმაზე მხარდაჭერილი არაა" - -#, c-format -#~ msgid "column \"%s\" cannot be used in multivariate statistics because its type %s has no default btree operator class" -#~ msgstr "სვეტს \"%s\" მულტივარიანტულ სტატისტიკაში ვერ გამოიყენებთ, რადგან მის ტიპს \"%s\" ნაგულისხმევი ორობითი ხის ოპერატორის კლასი არ გააჩნია" - -#, c-format -#~ msgid "column \"%s\" of relation \"%s\" is not a stored generated column" -#~ msgstr "ურთიერთობის \"%2$s\" სვეტი \"%1$s\" დამახსოვრებული გენერირებული სვეტი არაა" - -#, c-format -#~ msgid "constraint \"%s\" of relation \"%s\" is not a foreign key, check, or not-null constraint" -#~ msgstr "შეზღუდვა \"%s\" ურთიერთობისთვის \"%s\" გარე გასაღებს, შემოწმებას, ან არანულოვან შეზღუდვას არ წარმოადგენს" - -#, c-format -#~ msgid "conversion with OID %u does not exist" -#~ msgstr "გადაყვანა OID-ით %u არ არსებობს" - -#, c-format -#~ msgid "could not bind local RADIUS socket: %m" -#~ msgstr "ლოკალურ RADIUS სოკეტზე მიბმის შეცდომა: %m" - -#, c-format -#~ msgid "could not check status on RADIUS socket: %m" -#~ msgstr "შეცდომა RADIUS სოკეტის სტატუსის შემოწმებისას: %m" - -#, c-format -#~ msgid "could not create RADIUS socket: %m" -#~ msgstr "შეცდომა RADIUS სოკეტის შექმნისას: %m" - -#, c-format -#~ msgid "could not find redo location %X/%X referenced by checkpoint record at %X/%X" -#~ msgstr "ვერ ვიპოვე გამეორების მდებარეობა %X/%X, რომელსაც მიმართავს საკონტროლო წერტილის ჩანაწერი მისამართზე %X/%X" - -#, c-format -#~ msgid "could not find replication state slot for replication origin with OID %u which was acquired by %d" -#~ msgstr "რეპლიკაციის მდგომარეობის სლოტის აღმოჩენა შეუძლებელია რეპლიკაციის წყაროსთვის OID-ით %u, რომელიც მიიღო %d-მა" - -#, c-format -#~ msgid "could not fork WAL receiver process: %m" -#~ msgstr "\"WAL\"-ის მიმღების პროცესის ფორკის შეცდომა: %m" - -#, c-format -#~ msgid "could not fork WAL summarizer process: %m" -#~ msgstr "\"WAL\"-ის შემჯამებელი პროცესის ფორკის შეცდომა: %m" - -#, c-format -#~ msgid "could not fork WAL writer process: %m" -#~ msgstr "\"WAL\" -ის ჩამწერი პროცესის ფორკის შეცდომა: %m" - -#, c-format -#~ msgid "could not fork archiver process: %m" -#~ msgstr "არქივატორის პროცესის ფორკის შეცდომა: %m" - -#, c-format -#~ msgid "could not fork autovacuum launcher process: %m" -#~ msgstr "გამშვების პროცესის ავტომომტვერსასრუტების პრობლემა: %m" - -#, c-format -#~ msgid "could not fork autovacuum worker process: %m" -#~ msgstr "ავტომომტვერსასრუტების დამხმარე პროცესის ფორკის შეცდომა: %m" - -#, c-format -#~ msgid "could not fork background writer process: %m" -#~ msgstr "ფონური ჩამწერის პროცესის ფორკის შეცდომა: %m" - -#, c-format -#~ msgid "could not fork checkpointer process: %m" -#~ msgstr "საკონტროლო წერტილების პროცესის ფორკის შეცდომა: %m" - -#, c-format -#~ msgid "could not fork slot sync worker process: %m" -#~ msgstr "სლოტების სინქრონიზაციის დამხმარე პროცესის ფორკი შეუძლებელია: %m" - -#, c-format -#~ msgid "could not fork startup process: %m" -#~ msgstr "გამშვები პროცესის ფორკის შეცდომა: %m" - -#, c-format -#~ msgid "could not fork worker process: %m" -#~ msgstr "დამხმარე პროცესის ფორკის შეცდომა: %m" - -#, c-format -#~ msgid "could not form array type name for type \"%s\"" -#~ msgstr "ტიპისთვის (%s) მასივის ტიპის სახელის ფორმირება შეუძლებელია" - -#, c-format -#~ msgid "could not generate random encryption vector" -#~ msgstr "შემთხვევითი დაშიფვრის ვექტორის გენერაციის შეცდომა" - -#, c-format -#~ msgid "could not identify current directory: %m" -#~ msgstr "მიმდინარე საქაღალდის იდენტიფიკაციის პრობლემა: %m" - -#, c-format -#~ msgid "could not load library \"%s\": error code %lu" -#~ msgstr "ბიბლიოთეკის (\"%s\") ჩატვირთვის შეცდომა: შეცდომის კოდი: %lu" - -#, c-format -#~ msgid "could not load pg_hba.conf" -#~ msgstr "pg_hba.conf -ის ჩატვირთვის სეცდომა" - -#, c-format -#~ msgid "could not look up local user ID %d: %s" -#~ msgstr "ლოკალური მომხმარებლის ID-ის (%d) ამოხსნა შეუძლებელია: %s" - -#, c-format -#~ msgid "could not parse RADIUS identifiers list \"%s\"" -#~ msgstr "'RADIUS'-ის იდენტიფიკატორების ჩამონათვალის \"%s\" დამუშავება შეუძლებელია" - -#, c-format -#~ msgid "could not parse RADIUS port list \"%s\"" -#~ msgstr "\"RADIUS\"-ის პორტების სიის დამუშავება შეუძლებელია: %s" - -#, c-format -#~ msgid "could not parse RADIUS secret list \"%s\"" -#~ msgstr "'RADIUS'-ის საიდუმლოების სიის დამუშავება შეუძლებელია: %s" - -#, c-format -#~ msgid "could not parse RADIUS server list \"%s\"" -#~ msgstr "\"RADIUS\"-ის სერვერების სიის დამუშავება შეუძლებელია: %s" - -#, c-format -#~ msgid "could not perform MD5 encryption of password: %s" -#~ msgstr "პაროლის MD5-ით დაშიფვრა შეუძლებელია: %s" - -#, c-format -#~ msgid "could not perform MD5 encryption of received packet: %s" -#~ msgstr "მიღებული პაკეტის MD5-ით დაშიფვრა შეუძლებელია: %s" - -#, c-format -#~ msgid "could not read RADIUS response: %m" -#~ msgstr "შეცდომა RADIUS პასუხის წაკითხვისას: %m" - -#, c-format -#~ msgid "could not read from streaming transaction's changes file \"%s\": read only %zu of %zu bytes" -#~ msgstr "შეკუმშული ფაილის (\"%s\") წაკითხვის შეცდომა: წაკითხულია %zu %zu-დან" - -#, c-format -#~ msgid "could not read from streaming transaction's subxact file \"%s\": read only %zu of %zu bytes" -#~ msgstr "შეკუმშული ფაილის (\"%s\") წაკითხვის შეცდომა: წაკითხულია %zu ბაიტი %zu-დან" - -#, c-format -#~ msgid "could not remove file \"%s\": %s\n" -#~ msgstr "ფაილის წაშლის შეცდომა \"%s\": %s\n" - -#, c-format -#~ msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" -#~ msgstr "სტატისტიკის დროებითი ფაილის \"%s\"-დან \"%s\" -მდე სახელის გადარქმევა შეუძლებელია: %m" - -#, c-format -#~ msgid "could not send RADIUS packet: %m" -#~ msgstr "შეცდომა RADIUS პაკეტის გაგზავნისას: %m" - -#, c-format -#~ msgid "could not set compression flag for %s: %s" -#~ msgstr "%s-სთვის შეკუმშვის დონის დაყენების შეცდომა: %s" - -#, c-format -#~ msgid "could not stat promote trigger file \"%s\": %m" -#~ msgstr "წახალისების ტრიგერის ფაილი (\"%s\") არ არსებობს: %m" - -#, c-format -#~ msgid "could not sync slot \"%s\"" -#~ msgstr "სლოტის \"%s\" სინქრონიზაცია შეუძლებელია" - -#, c-format -#~ msgid "could not synchronize replication slot \"%s\" because remote slot precedes local slot" -#~ msgstr "რეპლიკაციის სლოტის სინქრონიზაცია \"%s\" შეუძლებელია, რადგან დაშორებული სლოტი წინ უსწრებს ლოკალურ სლოტს" - -#, c-format -#~ msgid "could not translate RADIUS server name \"%s\" to address: %s" -#~ msgstr "შეცდომა RADIUS სერვერის სახელის \"%s\" მისამართში თარგმნისას: %s" - -#, c-format -#~ msgid "could not unlink file \"%s\": %m" -#~ msgstr "ფაილის (%s) ბმულის მოხსნის შეცდომა: %m" - -#, c-format -#~ msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" -#~ msgstr "ბაზა ბრძანებებს არ იღებს, რათა თავიდან აიცილოს ჩაციკვლით მონაცემების კარგვა ბაზისთვის \"%s\"" - -#, c-format -#~ msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" -#~ msgstr "ბაზა ბრძანებებს არ იღებს, რათა თავიდან აიცილოს ჩაციკვლით მონაცემების კარგვა ბაზისთვის OID-ით %u" - -#, c-format -#~ msgid "database with OID %u must be vacuumed before %d more multixact member is used" -#~ msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" -#~ msgstr[0] "ბაზა OID-ით %u უნდა მომტვერსასრუტდეს მანამდე, სანამ კიდევ %d მულტიტრანზაქციული წევრი იქნება გამოყენებული" -#~ msgstr[1] "ბაზა OID-ით %u უნდა მომტვერსასრუტდეს მანამდე, სანამ კიდევ %d მულტიტრანზაქციული წევრი იქნება გამოყენებული" - -#, c-format -#~ msgid "date format is not recognized: \"%s\"" -#~ msgstr "თარიღის ფორმატი უცნობია: \"%s\"" - -#, c-format -#~ msgid "datetime format is not recognized: \"%s\"" -#~ msgstr "datetime-ის ფორმატი უცნობია: \"%s\"" - -#, c-format -#~ msgid "duplicate JSON key %s" -#~ msgstr "დუბლირებული JSON გასაღები %s" - -#, c-format -#~ msgid "duplicate JSON object key" -#~ msgstr "დუბლირებული JSON ობიექტის გასაღები" - -#, c-format -#~ msgid "end-of-copy marker corrupt" -#~ msgstr "კოპირების-დასასრულის სანიშნი დაზიანებულია" - -#, c-format -#~ msgid "extended statistics require at least 2 columns" -#~ msgstr "გაფართოებულ სტატისტიკას მინიმუმ 2 სვეტი სჭირდება" - -#, c-format -#~ msgid "extension with OID %u does not exist" -#~ msgstr "გაფართოება OID-ით %u არ არსებობს" - -#, c-format -#~ msgid "grantor must be current user" -#~ msgstr "მიმნიჭებელი მიმდინარე მომხმარებელი უნდა იყოს" - -#, c-format -#~ msgid "gtsvector_in not implemented" -#~ msgstr "gtsvector_in განხორციელებული არაა" - -#, c-format -#~ msgid "index %lld out of valid range, 0..%lld" -#~ msgstr "ინდექსი %lld დასაშვებ დიაპაზონს (0..%lld) გარეთაა" - -#, c-format -#~ msgid "int2vector has too many elements" -#~ msgstr "int2vector -ს მეტისმეტად ბევრი ელემენტი აქვს" - -#, c-format -#~ msgid "interval out of range." -#~ msgstr "ინტერვალი დაშვებული შუალედის გარეთაა." - -#, c-format -#~ msgid "invalid JSON_TABLE expression" -#~ msgstr "\"JSON_TABLE\"-ის არასწორი გამოსახულება" - -#, c-format -#~ msgid "invalid JSON_TABLE plan" -#~ msgstr "\"JSON_TABLE\"-ის არასწორი გეგმა" - -#, c-format -#~ msgid "invalid ON ERROR behavior" -#~ msgstr "\"ON UPDATE\"-ის არასწორი ქცევა" - -#, c-format -#~ msgid "invalid ON ERROR behavior for column \"%s\"" -#~ msgstr "\"ON ERROR\"-ის არასწორი ქცევა სვეტისთვის \"%s\"" - -#, c-format -#~ msgid "invalid RADIUS port number: \"%s\"" -#~ msgstr "\"RADIUS\"-ის არასწორი პორტი: \"%s\"" - -#, c-format -#~ msgid "invalid checkpoint link in backup_label file" -#~ msgstr "backup_label ფაილში არსებული საკონტროლო წერტილი არასწორია" - -#, c-format -#~ msgid "invalid input string for \"Y,YYY\"" -#~ msgstr "არასწორი შეყვანილი სტრიქონი \"Y,YYY\"-სთვის" - -#, c-format -#~ msgid "invalid length of primary checkpoint record" -#~ msgstr "ძირითადი საკონტროლო წერტილის ჩანაწერის არასწორი სიგრძე" - -#, c-format -#~ msgid "invalid length of query cancel key" -#~ msgstr "მოთხოვნის გაუქმების გასაღების სიგრძე არასწორია" - -#, c-format -#~ msgid "invalid parameter name \"%s\"" -#~ msgstr "პარამეტრის არასწორი სახელი \"%s\"" - -#, c-format -#~ msgid "invalid record offset at %X/%X" -#~ msgstr "ჩანაწერის არასწორი წანაცვლება მისამართზე %X/%X" - -#, c-format -#~ msgid "invalid resource manager ID in primary checkpoint record" -#~ msgstr "ძირითად საკონტროლო წერტილში აღწერილი რესურსის მმართველის ID არასწორია" - -#, c-format -#~ msgid "invalid segment number %d in file \"%s\"" -#~ msgstr "არასწორი სეგმენტის ნომერი %d ფაილში \"%s\"" - -#~ msgid "invalid unicode sequence" -#~ msgstr "უნიკოდის არასწორი მიმდევრობა" - -#, c-format -#~ msgid "invalid xl_info in primary checkpoint record" -#~ msgstr "ძირითადი საკონტროლო წერტილის არასწორი xl_info" - -#, c-format -#~ msgid "language with OID %u does not exist" -#~ msgstr "ენა OID-ით %u არ არსებობს" - -#, c-format -#~ msgid "list of RADIUS secrets cannot be empty" -#~ msgstr "'RADIUS' საიდუმლოების სია არ შეიძლება, ცარიელი იყოს" - -#, c-format -#~ msgid "list of RADIUS servers cannot be empty" -#~ msgstr "'RADIUS' სერვერების სია არ შეიძლება, ცარიელი იყოს" - -#, c-format -#~ msgid "logical decoding requires \"wal_level\" >= \"logical\"" -#~ msgstr "ლოგიკურ გაშიფვრას \"wal_level\" >= \"logical\" ესაჭიროება" - -#~ msgid "logical replication apply worker" -#~ msgstr "ლოგიკური რეპლიკაციის გადატარების დამხმარე პროცესი" - -#, c-format -#~ msgid "lower bound of partition \"%s\" conflicts with upper bound of previous partition \"%s\"" -#~ msgstr "დანაყოფის \"%s\" ქვედა ზღვარი კონფლიქტშია ზედა ზღვართან წინა დანაყოფისთვის \"%s\"" - -#~ msgid "manifest system identifier not an integer" -#~ msgstr "მანიფესტის სისტემის იდენფიტიკატორი მთელი რიცხვი არაა" - -#, c-format -#~ msgid "missing contrecord at %X/%X" -#~ msgstr "მისამართზე %X/%X contrecord ალამი არ არსებობს" - -#, c-format -#~ msgid "multiple limit options not allowed" -#~ msgstr "ლიმიტის პარამეტრების მითითება მხოლოდ ერთხელ შეგიძლიათ" - -#, c-format -#~ msgid "multixact \"members\" limit exceeded" -#~ msgstr "მულტიტრანზაქციული \"წევრების\" ლიმიტი გადაჭარბებულია" - -#, c-format -#~ msgid "must be a superuser to terminate superuser process" -#~ msgstr "ზემომხმარებლის პროცესის დასასრულებლად ზემომხმარებელი უნდა ბრძანდებოდეთ" - -#, c-format -#~ msgid "must be superuser or have privileges of pg_checkpoint to do CHECKPOINT" -#~ msgstr "\"COPY\"-ის ფაილში ჩასაწერად ზემომხმარებლის ან pg_write_server_files როლის პრივილეგიებია საჭირო" - -#, c-format -#~ msgid "must be superuser or replication role to use replication slots" -#~ msgstr "რეპლიკაციის სლოტების შექმნისთვის ზემომხმარებლის ან რეპლიკაციის წვდომებია საჭირო" - -#, c-format -#~ msgid "must be superuser to alter superusers" -#~ msgstr "ზემომხმარებლის შესაცვლელად ზემომხმარებელი უნდა ბრძანდებოდეთ" - -#, c-format -#~ msgid "must be superuser to create bypassrls users" -#~ msgstr "bypassrls მომხმარებლების შესაქმნელად ზემომხმარებელი უნდა ბრძანდებოდეთ" - -#, c-format -#~ msgid "must be superuser to create replication users" -#~ msgstr "რეპლიკაციის მომხმარებლების შესაქმნელად ზემომხმარებელი უნდა ბრძანდებოდეთ" - -#, c-format -#~ msgid "must be superuser to create superusers" -#~ msgstr "ზემომხმარებლის შესაქმნელად ზემომხმარებელი უნდა ბრძანდებოდეთ" - -#, c-format -#~ msgid "must be superuser to drop superusers" -#~ msgstr "ზემომხმარებლის წასაშლელად ზემომხმარებელი უნდა ბრძანდებოდეთ" - -#, c-format -#~ msgid "must be superuser to rename superusers" -#~ msgstr "ზემომხმარებლის სახელის გადასარქმევად ზემომხმარებელი უნდა ბრძანდებოდეთ" - -#, c-format -#~ msgid "must be superuser to skip transaction" -#~ msgstr "ტრანზაქციის გამოსატოვებლად ზემომხმარებლის უფლებებია საჭირო" - -#, c-format -#~ msgid "must have CREATEROLE privilege" -#~ msgstr "უნდა გქონდეთ CREATEROLE პრივილეგია" - -#, c-format -#~ msgid "must have privileges of pg_create_subscription to create subscriptions" -#~ msgstr "გამოწერების შესაქმნელად pg_create_subscription-ის პრივილეგიები გჭიდებათ" - -#, c-format -#~ msgid "name \"%s\" is already used" -#~ msgstr "სახელი \"%s\" უკვე გამოყენებულია" - -#, c-format -#~ msgid "no SQL/JSON item" -#~ msgstr "\"SQL/JSON\" ჩანაწერების გარეშე" - -#, c-format -#~ msgid "nonstandard use of \\' in a string literal" -#~ msgstr "სტრიქონში \\' არასტანდარტულადაა გამოყენებული" - -#, c-format -#~ msgid "nonstandard use of \\\\ in a string literal" -#~ msgstr "სტრიქონში \\\\ არასტანდარტულადაა გამოყენებული" - -#~ msgid "not initialized" -#~ msgstr "ინიციალიზებული არაა" - -#, c-format -#~ msgid "not-null constraint on column \"%s\" must be removed in child tables too" -#~ msgstr "არანულოვანი შეზღუდვა სვეტზე \"%s\" შვილ ცხრილებშიც უნდა წაიშალოს" - -#, c-format -#~ msgid "not-null constraints are not supported on virtual generated columns" -#~ msgstr "ვირტუალურ დაგენერირებულ სვეტებზე არანულოვანი შეზღუდვები მხარდაჭერილი არაა" - -#, c-format -#~ msgid "object keys must be strings" -#~ msgstr "ობიექტის გასაღებები სტრიქონები უნდა იყოს" - -#, c-format -#~ msgid "oidvector has too many elements" -#~ msgstr "oidvector-ს მეტისმეტად ბევრი ელემენტი აქვს" - -#, c-format -#~ msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" -#~ msgstr "უძველესი მულტიტრანზაქცია %u ვერ ვიპოვე. უახლესი მულტიტრანზაქციაა %u. წაკვეთა გამოტოვებული იქნება" - -#, c-format -#~ msgid "operator class with OID %u does not exist" -#~ msgstr "ოპერატორის კლასი OID-ით %u არ არსებობს" - -#, c-format -#~ msgid "operator family with OID %u does not exist" -#~ msgstr "ოპერატორის ოჯახი OID-ით %u არ არსებობს" - -#, c-format -#~ msgid "operator with OID %u does not exist" -#~ msgstr "ოპერატორი OID-ით %u არ არსებობს" - -#, c-format -#~ msgid "" -#~ "out of memory\n" -#~ "\n" -#~ "Cannot enlarge string buffer containing %d bytes by %d more bytes.\n" -#~ msgstr "" -#~ "არასაკმარისი მეხსიერება\n" -#~ "\n" -#~ "შეუძლებელია სტრიქონის ბუფერის (%d ბაიტი) გაფართოება %d ბაიტით.\n" - -#, c-format -#~ msgid "out of memory while trying to decode a record of length %u" -#~ msgstr "%u სიგრძის მქონე ჩანაწერის დეკოდირებისთვის მეხსიერება საკმარისი არაა" - -#, c-format -#~ msgid "oversize GSSAPI packet sent by the client (%zu > %d)" -#~ msgstr "კლიენტის მიერ გამოგზავნილი GSSAPI-ის პაკეტი ძალიან დიდია (%zu > %d)" - -#, c-format -#~ msgid "parallel option requires a value between 0 and %d" -#~ msgstr "პარალელურ პარამეტრს ესაჭიროება მნიშვნელობა 0-სა და %d-ს შორის" - -#, c-format -#~ msgid "parallel workers for vacuum must be between 0 and %d" -#~ msgstr "პარალელური დამხმარე პროცესების რაოდენობა მომტვერსასრუტებისთვის 0-სა და %d-ს შორის უნდა იყოს" - -#, c-format -#~ msgid "parameter \"lc_collate\" must be specified" -#~ msgstr "უნდა იყოს მითითებული პარამეტრი \"lc_collate\"" - -#, c-format -#~ msgid "parameter \"lc_ctype\" must be specified" -#~ msgstr "უნდა იყოს მითითებული პარამეტრი \"lc_ctype\"" - -#, c-format -#~ msgid "promote trigger file found: %s" -#~ msgstr "ნაპოვნია წახალისების ტრიგერის ფაილი: %s" - -#, c-format -#~ msgid "proto_version option missing" -#~ msgstr "პარამეტრი proto_version მითითებული არაა" - -#, c-format -#~ msgid "publication_names option missing" -#~ msgstr "აკლა პარამეტრი publication_names" - -#, c-format -#~ msgid "record length %u at %X/%X too long" -#~ msgstr "ჩანაწერის სიგრძე %u მისამართზე %X/%X ძალიან გრძელია" - -#, c-format -#~ msgid "reltuples cannot be < -1.0" -#~ msgstr "reltuples ვერ იქნება < -1.0" - -#, c-format -#~ msgid "replication origin \"%s\" already exists" -#~ msgstr "რეპლიკაციის წყარო \"%s\" უკვე არსებობს" - -#, c-format -#~ msgid "requested shared memory size overflows size_t" -#~ msgstr "მოთხოვნილი გაზიარებული მეხსიერების ზომა site_t-ის გადავსებას იწვევს" - -#~ msgid "server process" -#~ msgstr "სერვერის პროცესი" - -#, c-format -#~ msgid "snapshot too old" -#~ msgstr "სწრაფი ასლი ძალიან ძველია" - -#, c-format -#~ msgid "specifying a table access method is not supported on a partitioned table" -#~ msgstr "ცხრილთან წვდომის მითითება დაყოფილ ცხრილზე მხარდაჭერილი არაა" - -#, c-format -#~ msgid "statistics creation on virtual generated columns is not supported" -#~ msgstr "ვირტუალურ გენერირებულ სვეტებზე სტატისტიკის შექმნა მხარდაჭერილი არაა" - -#, c-format -#~ msgid "statistics object with OID %u does not exist" -#~ msgstr "სტატისტიკის ობიექტი OID-ით %u არ არსებობს" - -#, c-format -#~ msgid "subquery in FROM must have an alias" -#~ msgstr "ქვემოთხოვნას \"FROM\"-ში მეტსახელი უნდა ჰქონდეს" - -#, c-format -#~ msgid "tablespaces are not supported on this platform" -#~ msgstr "ამ პლატფორმაზე ცხრილის სივრცეები მხარდაჭერილი არაა" - -#, c-format -#~ msgid "text search configuration with OID %u does not exist" -#~ msgstr "ტექსტის ძებნის კონფიგურაცია OID-ით \"%u\" არ არსებობს" - -#, c-format -#~ msgid "text search dictionary with OID %u does not exist" -#~ msgstr "ტექსტის ძებნის ლექსიკონი OID-ით \"%u\" არ არსებობს" - -#, c-format -#~ msgid "time format is not recognized: \"%s\"" -#~ msgstr "დროის ფორმატი უცნობია: \"%s\"" - -#, c-format -#~ msgid "time_tz format is not recognized: \"%s\"" -#~ msgstr "time_tz-ის ფორმატი უცნობია: \"%s\"" - -#, c-format -#~ msgid "timeout waiting for RADIUS response from %s" -#~ msgstr "%s-დან RADIUS პასუხის მოლოდინის ვადა ამოიწურა" - -#, c-format -#~ msgid "timestamp format is not recognized: \"%s\"" -#~ msgstr "დროის შტამპის ფორმატი უცნობია: \"%s\"" - -#, c-format -#~ msgid "timestamp_tz format is not recognized: \"%s\"" -#~ msgstr "timestamp_tz-ის ფორმატი უცნობია: \"%s\"" - -#, c-format -#~ msgid "too many wait events for extensions" -#~ msgstr "მეტისმეტად ბევრი მოცდის მოვლენა გაფართოებებისთვის" - -#, c-format -#~ msgid "unable to map dynamic shared memory segment" -#~ msgstr "დინამიური გაზიარებული მეხსიერების სეგმენტის მიბმის შეცდომა" - -#, c-format -#~ msgid "unexpected DEFAULT in COPY data" -#~ msgstr "\"COPY\"-ის მონაცემებში ნაპოვნია მოულოდნელი DEFAULT" - -#~ msgid "unexpected end of quoted string" -#~ msgstr "ციტირებული სტრიქონის მოულოდნელი დასასრული" - -#, c-format -#~ msgid "unexpected json parse error type: %d" -#~ msgstr "მოულოდნელი json-ის დამუშავების შეცდომის ტიპი: %d" - -#, c-format -#~ msgid "unknown compression option \"%s\"" -#~ msgstr "შეკუმშვის უცნობი პარამეტრი: \"%s\"" - -#, c-format -#~ msgid "unlinked permanent statistics file \"%s\"" -#~ msgstr "სტატისტიკის მუდმივი ფაილი მოხსნილია: %s" - -#, c-format -#~ msgid "unrecognized ANALYZE option \"%s\"" -#~ msgstr "\"ANALYZE\"-ის უცნობი პარამეტრი: %s" - -#, c-format -#~ msgid "unrecognized CLUSTER option \"%s\"" -#~ msgstr "\"CLUSTER\"-ის უცნობი პარამეტრი \"%s\"" - -#, c-format -#~ msgid "unrecognized DROP DATABASE option \"%s\"" -#~ msgstr "\"DROP DATABASE\"-ის უცნობი პარამეტრი \"%s\"" - -#, c-format -#~ msgid "unrecognized REINDEX option \"%s\"" -#~ msgstr "\"REINDEX\"-ის უცნობი პარამეტრი \"%s\"" - -#, c-format -#~ msgid "unrecognized VACUUM option \"%s\"" -#~ msgstr "\"VACUUM\"-ის უცნობი პარამეტრი: %s" - -#, c-format -#~ msgid "unrecognized value for CREATE_REPLICATION_SLOT option \"%s\": \"%s\"" -#~ msgstr "უცნობი მნიშვნელობა CREATE_REPLICATION_SLOT-ის პარამეტრისთვის \"%s\": \"%s\"" - -#, c-format -#~ msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" -#~ msgstr "\"EXPLAIN\"-ის უცნობი პარამეტრი \"%s\": \"%s\"" - -#, c-format -#~ msgid "vacuuming \"%s.%s\"" -#~ msgstr "დამტვერსასრუტება \"%s.%s\"" - -#, c-format -#~ msgid "value for \"Y,YYY\" in source string is out of range" -#~ msgstr "წყარო სტრიქონში \"Y,YYY\"-ის მნიშვნელობები დიაპაზონს გარეთაა" - -#, c-format -#~ msgid "wal_level must be set to \"replica\" or \"logical\" at server start." -#~ msgstr "სერვისის გაშვებისას wal_level -ის მნიშვნელობა უნდა იყოს \"replica\" ან \"logical\"." - -#, c-format -#~ msgid "when building statistics on a single expression, statistics kinds may not be specified" -#~ msgstr "როცა სტატისტიკის აგება ერთ გამოსახულებაზე მიმდინარეობს, სტატისტიკის ტიპის მითითება შეუძლებელია" diff --git a/src/bin/initdb/po/ka.po b/src/bin/initdb/po/ka.po index 47831476072..1664332b487 100644 --- a/src/bin/initdb/po/ka.po +++ b/src/bin/initdb/po/ka.po @@ -1156,18 +1156,3 @@ msgstr "" " %s\n" "\n" -#, c-format -#~ msgid " ICU locale: %s\n" -#~ msgstr " ICU ენა: %s\n" - -#, c-format -#~ msgid "ICU locale must be specified" -#~ msgstr "საჭროა ICU ენის მითითება" - -#, c-format -#~ msgid "argument of --wal-segsize must be a number" -#~ msgstr "--wal-segisze -ის არგუმენტი რიცხვი უნდა იყოს" - -#, c-format -#~ msgid "selecting default \"autovacuum_worker_slots\" ... %d\n" -#~ msgstr "მიმდინარეობს ნაგულისხმევი \"autovacuum_worker_slots\"-ის არჩევა ... %d\n" diff --git a/src/bin/pg_archivecleanup/po/de.po b/src/bin/pg_archivecleanup/po/de.po index 4147ea822a0..176e3ea28f4 100644 --- a/src/bin/pg_archivecleanup/po/de.po +++ b/src/bin/pg_archivecleanup/po/de.po @@ -1,5 +1,5 @@ # pg_archivecleanup message translation file for pg_archivecleanup -# Copyright (C) 2019-2025 PostgreSQL Global Development Group +# Copyright (C) 2019-2026 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # Peter Eisentraut , 2019 - 2026. # @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_archivecleanup (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-28 19:26+0000\n" -"PO-Revision-Date: 2026-05-29 07:41+0200\n" +"POT-Creation-Date: 2026-07-04 06:26+0000\n" +"PO-Revision-Date: 2026-07-04 12:57+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -214,11 +214,12 @@ msgstr "älteste zu behaltene WAL-Datei muss angegeben werden" msgid "too many command-line arguments" msgstr "zu viele Kommandozeilenargumente" -#: pg_archivecleanup.c:379 +#: pg_archivecleanup.c:380 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"No files will be removed." -msgstr "" -"Ausführen im Probelaufmodus.\n" -"Keine Dateien werden entfernt werden." +msgid "executing in dry-run mode" +msgstr "Ausführen im Probelaufmodus" + +#: pg_archivecleanup.c:381 +#, c-format +msgid "No files will be removed." +msgstr "Keine Dateien werden entfernt werden." diff --git a/src/bin/pg_archivecleanup/po/ja.po b/src/bin/pg_archivecleanup/po/ja.po index 112b6295521..019a26b9723 100644 --- a/src/bin/pg_archivecleanup/po/ja.po +++ b/src/bin/pg_archivecleanup/po/ja.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_archivecleanup (PostgreSQL 19)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-15 13:37+0900\n" -"PO-Revision-Date: 2026-05-15 14:52+0900\n" +"POT-Creation-Date: 2026-07-03 14:12+0900\n" +"PO-Revision-Date: 2026-07-06 14:39+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" @@ -213,11 +213,19 @@ msgstr "保存する最古のWALファイルを指定してください" msgid "too many command-line arguments" msgstr "コマンドライン引数が多すぎます" -#: pg_archivecleanup.c:379 +#: pg_archivecleanup.c:380 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"No files will be removed." -msgstr "" -"ドライランモードで実行します。\n" -"ファイルは一切削除されません。" +msgid "executing in dry-run mode" +msgstr "ドライランモードで実行します" + +#: pg_archivecleanup.c:381 +#, c-format +msgid "No files will be removed." +msgstr "ファイルの削除は行われません。" + +#~ msgid "" +#~ "Executing in dry-run mode.\n" +#~ "No files will be removed." +#~ msgstr "" +#~ "ドライランモードで実行します。\n" +#~ "ファイルは一切削除されません。" diff --git a/src/bin/pg_archivecleanup/po/ka.po b/src/bin/pg_archivecleanup/po/ka.po index 31c9bdf89ff..47c86eba0e8 100644 --- a/src/bin/pg_archivecleanup/po/ka.po +++ b/src/bin/pg_archivecleanup/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_archivecleanup (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-13 06:27+0000\n" -"PO-Revision-Date: 2026-05-13 09:04+0200\n" +"POT-Creation-Date: 2026-07-04 00:25+0000\n" +"PO-Revision-Date: 2026-07-04 07:36+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -218,23 +218,20 @@ msgstr "დატოვებული უძველესი WAL ფაილ msgid "too many command-line arguments" msgstr "მეტისმეტად ბევრი ბრძანების-სტრიქონის არგუმენტი" -#: pg_archivecleanup.c:379 +#: pg_archivecleanup.c:380 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"No files will be removed." -msgstr "" -"შესრულება მშრალი გაშვების რეჟიმში.\n" -"ფაილების წაშლა არ მოხდება." - -#, c-format -#~ msgid " -?, --help show this help, then exit\n" -#~ msgstr " -?, --help ამ დახმარების ჩვენება და გასვლა\n" +msgid "executing in dry-run mode" +msgstr "შესრულება მშრალი გაშვების რეჟიმში" +#: pg_archivecleanup.c:381 #, c-format -#~ msgid " -V, --version output version information, then exit\n" -#~ msgstr " -V, --version ვერსიის ჩვენება და გასვლა\n" +msgid "No files will be removed." +msgstr "ფაილები არ წაიშლება." #, c-format -#~ msgid " -x EXT clean up files if they have this extension\n" -#~ msgstr " -x EXT ფაილების გასუფთავება, თუ მათ ეს გაფართოება გააჩნიათ\n" +#~ msgid "" +#~ "Executing in dry-run mode.\n" +#~ "No files will be removed." +#~ msgstr "" +#~ "შესრულება მშრალი გაშვების რეჟიმში.\n" +#~ "ფაილების წაშლა არ მოხდება." diff --git a/src/bin/pg_basebackup/po/de.po b/src/bin/pg_basebackup/po/de.po index 5b5c77bb186..71364c78386 100644 --- a/src/bin/pg_basebackup/po/de.po +++ b/src/bin/pg_basebackup/po/de.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-28 13:23+0000\n" -"PO-Revision-Date: 2026-05-28 18:21+0200\n" +"POT-Creation-Date: 2026-07-04 06:23+0000\n" +"PO-Revision-Date: 2026-07-04 12:58+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -109,7 +109,7 @@ msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" #: ../../common/controldata_utils.c:133 ../../common/controldata_utils.c:281 #: ../../fe_utils/astreamer_file.c:141 ../../fe_utils/astreamer_file.c:282 -#: pg_recvlogical.c:651 +#: pg_recvlogical.c:655 #, c-format msgid "could not close file \"%s\": %m" msgstr "konnte Datei »%s« nicht schließen: %m" @@ -178,7 +178,7 @@ msgid "could not synchronize file system for file \"%s\": %m" msgstr "konnte Dateisystem für Datei »%s« nicht synchronisieren: %m" #: ../../common/file_utils.c:123 ../../common/file_utils.c:588 -#: ../../fe_utils/version.c:60 pg_receivewal.c:319 pg_recvlogical.c:354 +#: ../../fe_utils/version.c:60 pg_receivewal.c:319 pg_recvlogical.c:358 #, c-format msgid "could not stat file \"%s\": %m" msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" @@ -417,7 +417,7 @@ msgstr "%s muss im Bereich %d..%d sein" msgid "unrecognized sync method: %s" msgstr "unbekannte Sync-Methode: %s" -#: ../../fe_utils/option_utils.c:139 pg_createsubscriber.c:2439 +#: ../../fe_utils/option_utils.c:139 pg_createsubscriber.c:2434 #, c-format msgid "options %s and %s cannot be used together" msgstr "Optionen %s und %s können nicht zusammen verwendet werden" @@ -436,12 +436,12 @@ msgstr "Speicher aufgebraucht" msgid "%s" msgstr "%s" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "Argument des Shell-Befehls enthält Newline oder Carriage Return: »%s«\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "Datenbankname enthält Newline oder Carriage Return: »%s«\n" @@ -953,8 +953,8 @@ msgstr "Transferrate »%s« ist außerhalb des gültigen Bereichs" msgid "could not get COPY data stream: %s" msgstr "konnte COPY-Datenstrom nicht empfangen: %s" -#: pg_basebackup.c:1041 pg_recvlogical.c:451 pg_recvlogical.c:627 -#: receivelog.c:981 +#: pg_basebackup.c:1041 pg_recvlogical.c:455 pg_recvlogical.c:631 +#: receivelog.c:987 #, c-format msgid "could not read COPY data: %s" msgstr "konnte COPY-Daten nicht lesen: %s" @@ -1039,9 +1039,9 @@ msgstr "Verwenden Sie -X none oder -X fetch, um Log-Streaming abzuschalten." msgid "server does not support incremental backup" msgstr "Server unterstützt kein inkrementelles Backup" -#: pg_basebackup.c:1838 pg_basebackup.c:1996 pg_recvlogical.c:278 -#: receivelog.c:543 receivelog.c:582 streamutil.c:296 streamutil.c:370 -#: streamutil.c:422 streamutil.c:510 streamutil.c:667 streamutil.c:712 +#: pg_basebackup.c:1838 pg_basebackup.c:1996 pg_recvlogical.c:282 +#: receivelog.c:542 receivelog.c:588 streamutil.c:296 streamutil.c:370 +#: streamutil.c:422 streamutil.c:511 streamutil.c:672 streamutil.c:717 #, c-format msgid "could not send replication command \"%s\": %s" msgstr "konnte Replikationsbefehl »%s« nicht senden: %s" @@ -1232,21 +1232,21 @@ msgstr "ungültige Option »%s« für --wal-method, muss »fetch«, »stream« o #: pg_basebackup.c:2700 pg_basebackup.c:2712 pg_basebackup.c:2724 #: pg_basebackup.c:2732 pg_basebackup.c:2745 pg_basebackup.c:2751 #: pg_basebackup.c:2760 pg_basebackup.c:2772 pg_basebackup.c:2783 -#: pg_basebackup.c:2791 pg_createsubscriber.c:2418 pg_createsubscriber.c:2441 -#: pg_createsubscriber.c:2451 pg_createsubscriber.c:2459 -#: pg_createsubscriber.c:2487 pg_createsubscriber.c:2565 pg_receivewal.c:748 +#: pg_basebackup.c:2791 pg_createsubscriber.c:2413 pg_createsubscriber.c:2436 +#: pg_createsubscriber.c:2446 pg_createsubscriber.c:2454 +#: pg_createsubscriber.c:2482 pg_createsubscriber.c:2562 pg_receivewal.c:748 #: pg_receivewal.c:760 pg_receivewal.c:767 pg_receivewal.c:776 -#: pg_receivewal.c:783 pg_receivewal.c:793 pg_recvlogical.c:859 -#: pg_recvlogical.c:871 pg_recvlogical.c:881 pg_recvlogical.c:888 -#: pg_recvlogical.c:895 pg_recvlogical.c:902 pg_recvlogical.c:909 -#: pg_recvlogical.c:916 pg_recvlogical.c:923 pg_recvlogical.c:932 -#: pg_recvlogical.c:939 +#: pg_receivewal.c:783 pg_receivewal.c:793 pg_recvlogical.c:863 +#: pg_recvlogical.c:875 pg_recvlogical.c:885 pg_recvlogical.c:892 +#: pg_recvlogical.c:899 pg_recvlogical.c:906 pg_recvlogical.c:913 +#: pg_recvlogical.c:920 pg_recvlogical.c:927 pg_recvlogical.c:936 +#: pg_recvlogical.c:943 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Versuchen Sie »%s --help« für weitere Informationen." -#: pg_basebackup.c:2572 pg_createsubscriber.c:2449 pg_receivewal.c:758 -#: pg_recvlogical.c:869 +#: pg_basebackup.c:2572 pg_createsubscriber.c:2444 pg_receivewal.c:758 +#: pg_recvlogical.c:873 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" @@ -2002,151 +2002,147 @@ msgstr "Sie müssen %s als PostgreSQL-Superuser ausführen." msgid "database \"%s\" specified more than once for -d/--database" msgstr "Datenbank »%s« mehrmals für -d/--database angegeben" -#: pg_createsubscriber.c:2390 -#, c-format -msgid "publication \"%s\" specified more than once for --publication" -msgstr "Publikation »%s« mehrmals für --publication angegeben" - -#: pg_createsubscriber.c:2399 +#: pg_createsubscriber.c:2394 #, c-format msgid "replication slot \"%s\" specified more than once for --replication-slot" msgstr "Replikations-Slot »%s« mehrmals für --replication-slot angegeben" -#: pg_createsubscriber.c:2408 +#: pg_createsubscriber.c:2403 #, c-format msgid "subscription \"%s\" specified more than once for --subscription" msgstr "Subskription »%s« mehrmals für --subscription angegeben" -#: pg_createsubscriber.c:2414 +#: pg_createsubscriber.c:2409 #, c-format msgid "object type \"%s\" specified more than once for --clean" msgstr "Objekttyp »%s« mehrmals für --clean angegeben" -#: pg_createsubscriber.c:2458 +#: pg_createsubscriber.c:2453 #, c-format msgid "no subscriber data directory specified" msgstr "kein Datenverzeichnis für Subskriptionsserver angegeben" -#: pg_createsubscriber.c:2469 +#: pg_createsubscriber.c:2464 #, c-format msgid "could not determine current directory" msgstr "konnte aktuelles Verzeichnis nicht ermitteln" -#: pg_createsubscriber.c:2486 +#: pg_createsubscriber.c:2481 #, c-format msgid "no publisher connection string specified" msgstr "keine Verbindungsparameter für Publikationsserver angegeben" -#: pg_createsubscriber.c:2514 pg_recvlogical.c:348 +#: pg_createsubscriber.c:2509 pg_recvlogical.c:352 #, c-format msgid "could not open log file \"%s\": %m" msgstr "konnte Logdatei »%s« nicht öffnen: %m" -#: pg_createsubscriber.c:2522 +#: pg_createsubscriber.c:2518 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"The target directory will not be modified." -msgstr "" -"Ausführen im Probelaufmodus.\n" -"Das Zielverzeichnis wird nicht verändert werden." +msgid "executing in dry-run mode" +msgstr "Ausführen im Probelaufmodus" -#: pg_createsubscriber.c:2525 +#: pg_createsubscriber.c:2519 +#, c-format +msgid "The target directory will not be modified." +msgstr "Das Zielverzeichnis wird nicht verändert werden." + +#: pg_createsubscriber.c:2522 #, c-format msgid "validating publisher connection string" msgstr "validiere Verbindungsparameter für Publikationsserver" -#: pg_createsubscriber.c:2531 +#: pg_createsubscriber.c:2528 #, c-format msgid "validating subscriber connection string" msgstr "validiere Verbindungsparameter für Subskriptionsserver" -#: pg_createsubscriber.c:2548 +#: pg_createsubscriber.c:2545 #, c-format msgid "no database was specified" msgstr "keine Datenbank wurde angegeben" -#: pg_createsubscriber.c:2559 +#: pg_createsubscriber.c:2556 #, c-format msgid "database name \"%s\" was extracted from the publisher connection string" msgstr "Datenbankname »%s« wurde aus der Verbindungszeichenkette des Publikationsservers extrahiert" -#: pg_createsubscriber.c:2564 +#: pg_createsubscriber.c:2561 #, c-format msgid "no database name specified" msgstr "kein Datenbankname angegeben" -#: pg_createsubscriber.c:2574 +#: pg_createsubscriber.c:2571 #, c-format msgid "wrong number of publication names specified" msgstr "falsche Anzahl Publikationsnamen angegeben" -#: pg_createsubscriber.c:2575 +#: pg_createsubscriber.c:2572 #, c-format msgid "The number of specified publication names (%d) must match the number of specified database names (%d)." msgstr "Die Anzahl der angegebenen Publikationsnamen (%d) muss mit der Anzahl der angegebenen Datenbanknamen (%d) übereinstimmen." -#: pg_createsubscriber.c:2581 +#: pg_createsubscriber.c:2578 #, c-format msgid "wrong number of subscription names specified" msgstr "falsche Anzahl Subskriptionsnamen angegeben" -#: pg_createsubscriber.c:2582 +#: pg_createsubscriber.c:2579 #, c-format msgid "The number of specified subscription names (%d) must match the number of specified database names (%d)." msgstr "Die Anzahl der angegebenen Subskriptionsnamen (%d) muss mit der Anzahl der angegebenen Datenbanknamen (%d) übereinstimmen." -#: pg_createsubscriber.c:2588 +#: pg_createsubscriber.c:2585 #, c-format msgid "wrong number of replication slot names specified" msgstr "falsche Anzahl Replikations-Slot-Namen angegeben" -#: pg_createsubscriber.c:2589 +#: pg_createsubscriber.c:2586 #, c-format msgid "The number of specified replication slot names (%d) must match the number of specified database names (%d)." msgstr "Die Anzahl der angegebenen Replikations-Slot-Namen (%d) muss mit der Anzahl der angegebenen Datenbanknamen (%d) übereinstimmen." -#: pg_createsubscriber.c:2601 +#: pg_createsubscriber.c:2598 #, c-format msgid "invalid object type \"%s\" specified for option %s" msgstr "ungültiger Objekttyp »%s« für Option %s angegeben" -#: pg_createsubscriber.c:2603 +#: pg_createsubscriber.c:2600 #, c-format msgid "The valid value is: \"%s\"" msgstr "Der gültige Wert ist: »%s«" -#: pg_createsubscriber.c:2634 +#: pg_createsubscriber.c:2631 #, c-format msgid "subscriber data directory is not a copy of the source database cluster" msgstr "Datenverzeichnis des Subskriptionsservers ist keine Kopie des Quelldatenbankclusters" -#: pg_createsubscriber.c:2647 +#: pg_createsubscriber.c:2644 #, c-format msgid "standby server is running" msgstr "Standby-Server läuft" -#: pg_createsubscriber.c:2648 +#: pg_createsubscriber.c:2645 #, c-format msgid "Stop the standby server and try again." msgstr "Halten Sie den Standby-Server an und versuchen Sie erneut." -#: pg_createsubscriber.c:2657 +#: pg_createsubscriber.c:2654 #, c-format msgid "starting the standby server with command-line options" msgstr "starte den Standby-Server mit Kommandozeilenoptionen" -#: pg_createsubscriber.c:2673 pg_createsubscriber.c:2708 +#: pg_createsubscriber.c:2670 pg_createsubscriber.c:2705 #, c-format msgid "stopping the subscriber" msgstr "stoppe den Subskriptionsserver" -#: pg_createsubscriber.c:2687 +#: pg_createsubscriber.c:2684 #, c-format msgid "starting the subscriber" msgstr "starte den Subskriptionsserver" -#: pg_createsubscriber.c:2716 +#: pg_createsubscriber.c:2713 #, c-format msgid "Done!" msgstr "Fertig!" @@ -2244,7 +2240,7 @@ msgstr "Log-Streaming gestoppt bei %X/%08X (Zeitleiste %u)" msgid "switched to timeline %u at %X/%08X" msgstr "auf Zeitleiste %u umgeschaltet bei %X/%08X" -#: pg_receivewal.c:224 pg_recvlogical.c:1082 +#: pg_receivewal.c:224 pg_recvlogical.c:1086 #, c-format msgid "received interrupt signal, exiting" msgstr "Interrupt-Signal erhalten, beende" @@ -2314,7 +2310,7 @@ msgstr "kann Datei »%s« nicht prüfen: Komprimierung mit %s wird von dieser In msgid "starting log streaming at %X/%08X (timeline %u)" msgstr "starte Log-Streaming bei %X/%08X (Zeitleiste %u)" -#: pg_receivewal.c:693 pg_recvlogical.c:807 +#: pg_receivewal.c:693 pg_recvlogical.c:811 #, c-format msgid "could not parse end position \"%s\"" msgstr "konnte Endposition »%s« nicht parsen" @@ -2344,23 +2340,23 @@ msgstr "Komprimierung mit %s wird noch nicht unterstützt" msgid "replication connection using slot \"%s\" is unexpectedly database specific" msgstr "Replikationsverbindung, die Slot »%s« verwendet, ist unerwarteterweise datenbankspezifisch" -#: pg_receivewal.c:878 pg_recvlogical.c:991 +#: pg_receivewal.c:878 pg_recvlogical.c:995 #, c-format msgid "dropping replication slot \"%s\"" msgstr "lösche Replikations-Slot »%s«" -#: pg_receivewal.c:889 pg_recvlogical.c:1001 +#: pg_receivewal.c:889 pg_recvlogical.c:1005 #, c-format msgid "creating replication slot \"%s\"" msgstr "erzeuge Replikations-Slot »%s«" -#: pg_receivewal.c:918 pg_recvlogical.c:1035 +#: pg_receivewal.c:918 pg_recvlogical.c:1039 #, c-format msgid "disconnected" msgstr "Verbindung beendet" #. translator: check source for value for %d -#: pg_receivewal.c:922 pg_recvlogical.c:1040 +#: pg_receivewal.c:922 pg_recvlogical.c:1044 #, c-format msgid "disconnected; waiting %d seconds to try again" msgstr "Verbindung beendet; erneuter Versuch in %d Sekunden" @@ -2469,103 +2465,103 @@ msgstr "konnte Rückmeldungspaket nicht senden: %s" msgid "starting log streaming at %X/%08X (slot %s)" msgstr "starte Log-Streaming bei %X/%08X (Slot %s)" -#: pg_recvlogical.c:287 +#: pg_recvlogical.c:291 #, c-format msgid "streaming initiated" msgstr "Streaming eingeleitet" -#: pg_recvlogical.c:377 receivelog.c:890 +#: pg_recvlogical.c:381 receivelog.c:896 #, c-format msgid "invalid socket: %s" msgstr "ungültiges Socket: %s" -#: pg_recvlogical.c:430 receivelog.c:918 +#: pg_recvlogical.c:434 receivelog.c:924 #, c-format msgid "%s() failed: %m" msgstr "%s() fehlgeschlagen: %m" -#: pg_recvlogical.c:437 receivelog.c:967 +#: pg_recvlogical.c:441 receivelog.c:973 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "konnte keine Daten vom WAL-Stream empfangen: %s" -#: pg_recvlogical.c:479 pg_recvlogical.c:530 receivelog.c:1011 -#: receivelog.c:1074 +#: pg_recvlogical.c:483 pg_recvlogical.c:534 receivelog.c:1017 +#: receivelog.c:1080 #, c-format msgid "streaming header too small: %d" msgstr "Streaming-Header zu klein: %d" -#: pg_recvlogical.c:514 receivelog.c:847 +#: pg_recvlogical.c:518 receivelog.c:853 #, c-format msgid "unrecognized streaming header: \"%c\"" msgstr "unbekannter Streaming-Header: »%c«" -#: pg_recvlogical.c:568 pg_recvlogical.c:580 +#: pg_recvlogical.c:572 pg_recvlogical.c:584 #, c-format msgid "could not write %d bytes to log file \"%s\": %m" msgstr "konnte %d Bytes nicht in Logdatei »%s« schreiben: %m" -#: pg_recvlogical.c:638 receivelog.c:642 receivelog.c:679 +#: pg_recvlogical.c:642 receivelog.c:648 receivelog.c:685 #, c-format msgid "unexpected termination of replication stream: %s" msgstr "unerwarteter Abbruch des Replikations-Streams: %s" -#: pg_recvlogical.c:802 +#: pg_recvlogical.c:806 #, c-format msgid "could not parse start position \"%s\"" msgstr "konnte Startposition »%s« nicht parsen" -#: pg_recvlogical.c:880 +#: pg_recvlogical.c:884 #, c-format msgid "no slot specified" msgstr "kein Slot angegeben" -#: pg_recvlogical.c:887 +#: pg_recvlogical.c:891 #, c-format msgid "no target file specified" msgstr "keine Zieldatei angegeben" -#: pg_recvlogical.c:894 +#: pg_recvlogical.c:898 #, c-format msgid "no database specified" msgstr "keine Datenbank angegeben" -#: pg_recvlogical.c:901 +#: pg_recvlogical.c:905 #, c-format msgid "at least one action needs to be specified" msgstr "mindestens eine Aktion muss angegeben werden" -#: pg_recvlogical.c:908 +#: pg_recvlogical.c:912 #, c-format msgid "cannot use --create-slot or --start together with --drop-slot" msgstr "--create-slot oder --start kann nicht zusammen mit --drop-slot verwendet werden" -#: pg_recvlogical.c:915 +#: pg_recvlogical.c:919 #, c-format msgid "cannot use --create-slot or --drop-slot together with --startpos" msgstr "--create-slot oder --drop-slot kann nicht zusammen mit --startpos verwendet werden" -#: pg_recvlogical.c:922 +#: pg_recvlogical.c:926 #, c-format msgid "--endpos may only be specified with --start" msgstr "--endpos kann nur zusammen mit --start angegeben werden" -#: pg_recvlogical.c:931 pg_recvlogical.c:938 +#: pg_recvlogical.c:935 pg_recvlogical.c:942 #, c-format msgid "%s may only be specified with --create-slot" msgstr "%s kann nur zusammen mit --create-slot angegeben werden" -#: pg_recvlogical.c:975 +#: pg_recvlogical.c:979 #, c-format msgid "could not establish database-specific replication connection" msgstr "konnte keine datenbankspezifische Replikationsverbindung herstellen" -#: pg_recvlogical.c:1085 +#: pg_recvlogical.c:1089 #, c-format msgid "end position %X/%08X reached by keepalive" msgstr "Endposition %X/%08X durch Keepalive erreicht" -#: pg_recvlogical.c:1090 +#: pg_recvlogical.c:1094 #, c-format msgid "end position %X/%08X reached by WAL record at %X/%08X" msgstr "Endposition %X/%08X erreicht durch WAL-Eintrag bei %X/%08X" @@ -2612,7 +2608,7 @@ msgstr "konnte Write-Ahead-Log-Datei »%s« nicht öffnen: %s" msgid "not renaming \"%s\", segment is not complete" msgstr "»%s« wird nicht umbenannt, Segment ist noch nicht vollständig" -#: receivelog.c:227 receivelog.c:317 receivelog.c:688 +#: receivelog.c:227 receivelog.c:317 receivelog.c:694 #, c-format msgid "could not close file \"%s\": %s" msgstr "konnte Datei »%s« nicht schließen: %s" @@ -2642,67 +2638,67 @@ msgstr "inkompatible Serverversion %s; Client unterstützt Streaming nicht mit S msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" msgstr "inkompatible Serverversion %s; Client unterstützt Streaming nicht mit Serverversionen neuer als %s" -#: receivelog.c:508 +#: receivelog.c:505 #, c-format msgid "system identifier does not match between base backup and streaming connection" msgstr "Systemidentifikator stimmt nicht zwischen Basissicherung und Streaming-Verbindung überein" -#: receivelog.c:516 +#: receivelog.c:513 #, c-format msgid "starting timeline %u is not present in the server" msgstr "Startzeitleiste %u ist auf dem Server nicht vorhanden" -#: receivelog.c:555 +#: receivelog.c:554 #, c-format msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" msgstr "unerwartete Antwort auf Befehl TIMELINE_HISTORY: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" -#: receivelog.c:626 +#: receivelog.c:632 #, c-format msgid "server reported unexpected next timeline %u, following timeline %u" msgstr "Server berichtete unerwartete nächste Zeitleiste %u, folgend auf Zeitleiste %u" -#: receivelog.c:632 +#: receivelog.c:638 #, c-format msgid "server stopped streaming timeline %u at %X/%08X, but reported next timeline %u to begin at %X/%08X" msgstr "Server beendete Streaming von Zeitleiste %u bei %X/%08X, aber gab an, dass nächste Zeitleiste %u bei %X/%08X beginnt" -#: receivelog.c:672 +#: receivelog.c:678 #, c-format msgid "replication stream was terminated before stop point" msgstr "Replikationsstrom wurde vor Stopppunkt abgebrochen" -#: receivelog.c:718 +#: receivelog.c:724 #, c-format msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" msgstr "unerwartete Ergebnismenge nach Ende der Zeitleiste: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" -#: receivelog.c:727 +#: receivelog.c:733 #, c-format msgid "could not parse next timeline's starting point \"%s\"" msgstr "konnte Startpunkt der nächsten Zeitleiste (»%s«) nicht interpretieren" -#: receivelog.c:775 receivelog.c:1030 walmethods.c:1206 +#: receivelog.c:781 receivelog.c:1036 walmethods.c:1206 #, c-format msgid "could not fsync file \"%s\": %s" msgstr "konnte Datei »%s« nicht fsyncen: %s" -#: receivelog.c:1091 +#: receivelog.c:1097 #, c-format msgid "received write-ahead log record for offset %u with no file open" msgstr "Write-Ahead-Log-Eintrag für Offset %u erhalten ohne offene Datei" -#: receivelog.c:1101 +#: receivelog.c:1107 #, c-format msgid "got WAL data offset %08x, expected %08x" msgstr "WAL-Daten-Offset %08x erhalten, %08x erwartet" -#: receivelog.c:1136 +#: receivelog.c:1142 #, c-format msgid "could not write %d bytes to WAL file \"%s\": %s" msgstr "konnte %d Bytes nicht in WAL-Datei »%s« schreiben: %s" -#: receivelog.c:1161 receivelog.c:1201 receivelog.c:1229 +#: receivelog.c:1167 receivelog.c:1207 receivelog.c:1235 #, c-format msgid "could not send copy-end packet: %s" msgstr "konnte COPY-Ende-Paket nicht senden: %s" @@ -2763,32 +2759,32 @@ msgstr "Gruppenzugriffseinstellung konnte nicht interpretiert werden: %s" msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" msgstr "Konnte System nicht identifizieren: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet" -#: streamutil.c:519 +#: streamutil.c:520 #, c-format msgid "could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" msgstr "konnte Replikations-Slot »%s« nicht lesen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" -#: streamutil.c:531 +#: streamutil.c:532 #, c-format msgid "replication slot \"%s\" does not exist" msgstr "Replikations-Slot »%s« existiert nicht" -#: streamutil.c:542 +#: streamutil.c:543 #, c-format msgid "expected a physical replication slot, got type \"%s\" instead" msgstr "physischer Replikations-Slot wurde erwartet, stattdessen wurde Typ »%s« erhalten" -#: streamutil.c:556 +#: streamutil.c:557 #, c-format msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\"" msgstr "konnte restart_lsn »%s« für Replikations-Slot »%s« nicht parsen" -#: streamutil.c:678 +#: streamutil.c:683 #, c-format msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" msgstr "konnte Replikations-Slot »%s« nicht erzeugen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" -#: streamutil.c:722 +#: streamutil.c:727 #, c-format msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" msgstr "konnte Replikations-Slot »%s« nicht löschen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" diff --git a/src/bin/pg_basebackup/po/ja.po b/src/bin/pg_basebackup/po/ja.po index c0d36661622..cd344cc1c23 100644 --- a/src/bin/pg_basebackup/po/ja.po +++ b/src/bin/pg_basebackup/po/ja.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_basebackup (PostgreSQL 19)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-15 13:37+0900\n" -"PO-Revision-Date: 2026-05-15 15:15+0900\n" +"POT-Creation-Date: 2026-07-03 14:12+0900\n" +"PO-Revision-Date: 2026-07-06 14:37+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" @@ -113,7 +113,7 @@ msgstr "ファイル\"%1$s\"を読み込めませんでした: %3$zuバイトの #: ../../common/controldata_utils.c:133 ../../common/controldata_utils.c:281 #: ../../fe_utils/astreamer_file.c:141 ../../fe_utils/astreamer_file.c:282 -#: pg_recvlogical.c:651 +#: pg_recvlogical.c:655 #, c-format msgid "could not close file \"%s\": %m" msgstr "ファイル\"%s\"をクローズできませんでした: %m" @@ -138,7 +138,7 @@ msgstr "" #: ../../common/controldata_utils.c:231 ../../common/file_utils.c:69 #: ../../common/file_utils.c:370 ../../common/file_utils.c:428 #: ../../common/file_utils.c:502 ../../fe_utils/recovery_gen.c:141 -#: pg_basebackup.c:1834 pg_createsubscriber.c:1449 pg_receivewal.c:386 +#: pg_basebackup.c:1834 pg_createsubscriber.c:1448 pg_receivewal.c:386 #, c-format msgid "could not open file \"%s\": %m" msgstr "ファイル\"%s\"をオープンできませんでした: %m" @@ -181,7 +181,7 @@ msgid "could not synchronize file system for file \"%s\": %m" msgstr "ファイル\"%s\"に対してファイルシステムを同期できませんでした: %m" #: ../../common/file_utils.c:123 ../../common/file_utils.c:588 -#: ../../fe_utils/version.c:60 pg_receivewal.c:319 pg_recvlogical.c:354 +#: ../../fe_utils/version.c:60 pg_receivewal.c:319 pg_recvlogical.c:358 #, c-format msgid "could not stat file \"%s\": %m" msgstr "ファイル\"%s\"のstatに失敗しました: %m" @@ -247,7 +247,7 @@ msgstr "ファイル\"%s\"を作成できませんでした: %m" #: ../../fe_utils/astreamer_file.c:124 ../../fe_utils/astreamer_file.c:273 #: ../../fe_utils/recovery_gen.c:144 pg_basebackup.c:1421 pg_basebackup.c:1715 -#: pg_createsubscriber.c:1452 +#: pg_createsubscriber.c:1451 #, c-format msgid "could not write to file \"%s\": %m" msgstr "ファイル\"%s\"を書き込めませんでした: %m" @@ -268,7 +268,7 @@ msgid "unexpected state while extracting archive" msgstr "アーカイブの抽出中に想定外の状態" #: ../../fe_utils/astreamer_file.c:338 pg_basebackup.c:700 pg_basebackup.c:714 -#: pg_basebackup.c:759 pg_createsubscriber.c:1003 pg_createsubscriber.c:1007 +#: pg_basebackup.c:759 pg_createsubscriber.c:1002 pg_createsubscriber.c:1006 #, c-format msgid "could not create directory \"%s\": %m" msgstr "ディレクトリ\"%s\"を作成できませんでした: %m" @@ -420,7 +420,7 @@ msgstr "%sは%d..%dの範囲でなければなりません" msgid "unrecognized sync method: %s" msgstr "認識できない同期方式: %s" -#: ../../fe_utils/option_utils.c:139 pg_createsubscriber.c:2445 +#: ../../fe_utils/option_utils.c:139 pg_createsubscriber.c:2434 #, c-format msgid "options %s and %s cannot be used together" msgstr "オプション %s と %s は同時には使用できません" @@ -439,12 +439,12 @@ msgstr "メモリ不足です" msgid "%s" msgstr "%s" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "シェルコマンドの引数に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "データベース名に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" @@ -558,13 +558,13 @@ msgstr "" "%sは実行中のPostgreSQLサーバーのベースバックアップを取得します。\n" "\n" -#: pg_basebackup.c:395 pg_createsubscriber.c:288 pg_receivewal.c:79 +#: pg_basebackup.c:395 pg_createsubscriber.c:287 pg_receivewal.c:79 #: pg_recvlogical.c:86 #, c-format msgid "Usage:\n" msgstr "使用方法:\n" -#: pg_basebackup.c:396 pg_createsubscriber.c:289 pg_receivewal.c:80 +#: pg_basebackup.c:396 pg_createsubscriber.c:288 pg_receivewal.c:80 #: pg_recvlogical.c:87 #, c-format msgid " %s [OPTION]...\n" @@ -830,7 +830,7 @@ msgstr " -w, --no-password パスワードの入力を要求しない\n" msgid " -W, --password force password prompt (should happen automatically)\n" msgstr " -W, --password パスワード入力要求を強制(自動的に行われるはず)\n" -#: pg_basebackup.c:449 pg_createsubscriber.c:313 pg_receivewal.c:106 +#: pg_basebackup.c:449 pg_createsubscriber.c:312 pg_receivewal.c:106 #: pg_recvlogical.c:121 #, c-format msgid "" @@ -840,7 +840,7 @@ msgstr "" "\n" "バグは<%s>に報告してください。\n" -#: pg_basebackup.c:450 pg_createsubscriber.c:314 pg_receivewal.c:107 +#: pg_basebackup.c:450 pg_createsubscriber.c:313 pg_receivewal.c:107 #: pg_recvlogical.c:122 #, c-format msgid "%s home page: <%s>\n" @@ -892,7 +892,7 @@ msgstr "バックグラウンドスレッドを生成できませんでした: % msgid "directory \"%s\" exists but is not empty" msgstr "ディレクトリ\"%s\"は存在しますが空ではありません" -#: pg_basebackup.c:784 pg_createsubscriber.c:464 +#: pg_basebackup.c:784 pg_createsubscriber.c:463 #, c-format msgid "could not access directory \"%s\": %m" msgstr "ディレクトリ\"%s\"にアクセスできませんでした: %m" @@ -950,8 +950,8 @@ msgstr "転送速度\"%s\"が範囲外です" msgid "could not get COPY data stream: %s" msgstr "COPYデータストリームを取得できませんでした: %s" -#: pg_basebackup.c:1041 pg_recvlogical.c:451 pg_recvlogical.c:627 -#: receivelog.c:981 +#: pg_basebackup.c:1041 pg_recvlogical.c:455 pg_recvlogical.c:631 +#: receivelog.c:987 #, c-format msgid "could not read COPY data: %s" msgstr "COPYデータを読み取ることができませんでした: %s" @@ -1036,9 +1036,9 @@ msgstr "-X none または -X fetch でログストリーミングを無効にで msgid "server does not support incremental backup" msgstr "サーバーは差分バックアップをサポートしていません" -#: pg_basebackup.c:1838 pg_basebackup.c:1996 pg_recvlogical.c:278 -#: receivelog.c:543 receivelog.c:582 streamutil.c:296 streamutil.c:370 -#: streamutil.c:422 streamutil.c:510 streamutil.c:667 streamutil.c:712 +#: pg_basebackup.c:1838 pg_basebackup.c:1996 pg_recvlogical.c:282 +#: receivelog.c:542 receivelog.c:588 streamutil.c:296 streamutil.c:370 +#: streamutil.c:422 streamutil.c:511 streamutil.c:672 streamutil.c:717 #, c-format msgid "could not send replication command \"%s\": %s" msgstr "レプリケーションコマンド\"%s\"を送信できませんでした: %s" @@ -1229,21 +1229,21 @@ msgstr "不正な wal-method オプション\"%s\"、\"fetch\"、\"stream\" ま #: pg_basebackup.c:2700 pg_basebackup.c:2712 pg_basebackup.c:2724 #: pg_basebackup.c:2732 pg_basebackup.c:2745 pg_basebackup.c:2751 #: pg_basebackup.c:2760 pg_basebackup.c:2772 pg_basebackup.c:2783 -#: pg_basebackup.c:2791 pg_createsubscriber.c:2424 pg_createsubscriber.c:2447 -#: pg_createsubscriber.c:2457 pg_createsubscriber.c:2465 -#: pg_createsubscriber.c:2493 pg_createsubscriber.c:2571 pg_receivewal.c:748 +#: pg_basebackup.c:2791 pg_createsubscriber.c:2413 pg_createsubscriber.c:2436 +#: pg_createsubscriber.c:2446 pg_createsubscriber.c:2454 +#: pg_createsubscriber.c:2482 pg_createsubscriber.c:2562 pg_receivewal.c:748 #: pg_receivewal.c:760 pg_receivewal.c:767 pg_receivewal.c:776 -#: pg_receivewal.c:783 pg_receivewal.c:793 pg_recvlogical.c:859 -#: pg_recvlogical.c:871 pg_recvlogical.c:881 pg_recvlogical.c:888 -#: pg_recvlogical.c:895 pg_recvlogical.c:902 pg_recvlogical.c:909 -#: pg_recvlogical.c:916 pg_recvlogical.c:923 pg_recvlogical.c:932 -#: pg_recvlogical.c:939 +#: pg_receivewal.c:783 pg_receivewal.c:793 pg_recvlogical.c:863 +#: pg_recvlogical.c:875 pg_recvlogical.c:885 pg_recvlogical.c:892 +#: pg_recvlogical.c:899 pg_recvlogical.c:906 pg_recvlogical.c:913 +#: pg_recvlogical.c:920 pg_recvlogical.c:927 pg_recvlogical.c:936 +#: pg_recvlogical.c:943 #, c-format msgid "Try \"%s --help\" for more information." msgstr "詳細は\"%s --help\"を実行してください。" -#: pg_basebackup.c:2572 pg_createsubscriber.c:2455 pg_receivewal.c:758 -#: pg_recvlogical.c:869 +#: pg_basebackup.c:2572 pg_createsubscriber.c:2444 pg_receivewal.c:758 +#: pg_recvlogical.c:873 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "コマンドライン引数が多過ぎます(先頭は\"%s\"です)" @@ -1350,27 +1350,27 @@ msgstr "リカバリ完了後に失敗しました" msgid "The target server cannot be used as a physical replica anymore. You must recreate the physical replica before continuing." msgstr "以降この対象サーバーは物理複製としては使用できません。作業を継続する前に物理複製を再作成する必要があります。" -#: pg_createsubscriber.c:263 +#: pg_createsubscriber.c:262 #, c-format msgid "publication \"%s\" created in database \"%s\" on primary was left behind" msgstr "プライマリ上のデータベース\"%2$s\"で作成されたパブリケーション\"%1$s\"が残されています" -#: pg_createsubscriber.c:266 +#: pg_createsubscriber.c:265 #, c-format msgid "Drop this publication before trying again." msgstr "再試行の前にこのパブリケーションを削除してください。" -#: pg_createsubscriber.c:270 +#: pg_createsubscriber.c:269 #, c-format msgid "replication slot \"%s\" created in database \"%s\" on primary was left behind" msgstr "プライマリ上のデータベース\"%2$s\"で作成されたレプリケーションスロット\"%1$s\"が残されています" -#: pg_createsubscriber.c:273 pg_createsubscriber.c:1493 +#: pg_createsubscriber.c:272 pg_createsubscriber.c:1492 #, c-format msgid "Drop this replication slot soon to avoid retention of WAL files." msgstr "WALファイルの増加を避けるためにこのレプリケーションスロットを直ちに削除してください。" -#: pg_createsubscriber.c:286 +#: pg_createsubscriber.c:285 #, c-format msgid "" "%s creates a new logical replica from a standby server.\n" @@ -1379,7 +1379,7 @@ msgstr "" "%s スタンバイサーバーから新たな論理複製を作成します。\n" "\n" -#: pg_createsubscriber.c:290 pg_receivewal.c:81 pg_recvlogical.c:92 +#: pg_createsubscriber.c:289 pg_receivewal.c:81 pg_recvlogical.c:92 #, c-format msgid "" "\n" @@ -1388,7 +1388,7 @@ msgstr "" "\n" "オプション:\n" -#: pg_createsubscriber.c:291 +#: pg_createsubscriber.c:290 #, c-format msgid "" " -a, --all create subscriptions for all databases except template\n" @@ -1398,66 +1398,66 @@ msgstr "" " データベースを除くすべてのデータベースに\n" " サブスクリプションを作成する\n" -#: pg_createsubscriber.c:293 +#: pg_createsubscriber.c:292 #, c-format msgid " -d, --database=DBNAME database in which to create a subscription\n" msgstr " -d, --database=DBNAME サブスクリプションを作成するデータベース名\n" -#: pg_createsubscriber.c:294 +#: pg_createsubscriber.c:293 #, c-format msgid " -D, --pgdata=DATADIR location for the subscriber data directory\n" msgstr " -D, --pgdata=DATADIR サブスクライバのデータディレクトリの場所\n" -#: pg_createsubscriber.c:295 +#: pg_createsubscriber.c:294 #, c-format msgid " -l, --logdir=LOGDIR location for the log directory\n" msgstr " -l, --logdir=LOGDIR ログ用ディレクトリの位置\n" -#: pg_createsubscriber.c:296 +#: pg_createsubscriber.c:295 #, c-format msgid " -n, --dry-run dry run, just show what would be done\n" msgstr " -n, --dry-run 更新をせず、単に何が行なわれるかを表示\n" -#: pg_createsubscriber.c:297 +#: pg_createsubscriber.c:296 #, c-format msgid " -p, --subscriber-port=PORT subscriber port number (default %s)\n" msgstr " -p, --subscriber-port=PORT サブスクライバのポート番号 (デフォルト %s)\n" -#: pg_createsubscriber.c:298 +#: pg_createsubscriber.c:297 #, c-format msgid " -P, --publisher-server=CONNSTR publisher connection string\n" msgstr " -P, --publisher-server=CONNSTR パブリッシャの接続文字列\n" -#: pg_createsubscriber.c:299 +#: pg_createsubscriber.c:298 #, c-format msgid " -s, --socketdir=DIR socket directory to use (default current dir.)\n" msgstr "" " -s, --socketdir=DIR 使用するソケットディレクトリ(デフォルトは\n" " カレントディレクトリ)\n" -#: pg_createsubscriber.c:300 +#: pg_createsubscriber.c:299 #, c-format msgid " -t, --recovery-timeout=SECS seconds to wait for recovery to end\n" msgstr " -t, --recovery-timeout=SECS リカバリ完了を待機する秒数\n" -#: pg_createsubscriber.c:301 +#: pg_createsubscriber.c:300 #, c-format msgid " -T, --enable-two-phase enable two-phase commit for all subscriptions\n" msgstr "" " -T, --enable-two-phase 2相コミットをすべてのサブスクリプションに\n" " 対して有効化\n" -#: pg_createsubscriber.c:302 +#: pg_createsubscriber.c:301 #, c-format msgid " -U, --subscriber-username=NAME user name for subscriber connection\n" msgstr " -U, --subscriber-username=NAME サブスクライバ接続のユーザー名\n" -#: pg_createsubscriber.c:303 +#: pg_createsubscriber.c:302 #, c-format msgid " -v, --verbose output verbose messages\n" msgstr " -v, --verbose 冗長メッセージを出力\n" -#: pg_createsubscriber.c:304 +#: pg_createsubscriber.c:303 #, c-format msgid "" " --clean=OBJECTTYPE drop all objects of the specified type from specified\n" @@ -1467,7 +1467,7 @@ msgstr "" " 指定された種類のオブジェクトをすべて削除する;\n" " 指定可能なオブジェクト種別: \"%s\"\n" -#: pg_createsubscriber.c:306 +#: pg_createsubscriber.c:305 #, c-format msgid "" " --config-file=FILENAME use specified main server configuration\n" @@ -1476,678 +1476,674 @@ msgstr "" " --config-file=FILENAME ターゲットクラスタの実行時に、指定した\n" " メインのサーバー設定ファイルを使用する\n" -#: pg_createsubscriber.c:308 +#: pg_createsubscriber.c:307 #, c-format msgid " --publication=NAME publication name\n" msgstr " --publication=NAME パブリケーション名\n" -#: pg_createsubscriber.c:309 +#: pg_createsubscriber.c:308 #, c-format msgid " --replication-slot=NAME replication slot name\n" msgstr " --replication-slot=NAME レプリケーションスロット名\n" -#: pg_createsubscriber.c:310 +#: pg_createsubscriber.c:309 #, c-format msgid " --subscription=NAME subscription name\n" msgstr " --subscription=NAME サブスクリプション名\n" -#: pg_createsubscriber.c:311 +#: pg_createsubscriber.c:310 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version バージョン情報を表示して終了\n" -#: pg_createsubscriber.c:312 +#: pg_createsubscriber.c:311 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help このヘルプを表示して終了\n" -#: pg_createsubscriber.c:355 +#: pg_createsubscriber.c:354 #, c-format msgid "could not parse connection string: %s" msgstr "接続文字列をパースできませんでした: %s" -#: pg_createsubscriber.c:432 +#: pg_createsubscriber.c:431 #, c-format msgid "program \"%s\" is needed by %s but was not found in the same directory as \"%s\"" msgstr "%2$sにはプログラム\"%1$s\"が必要ですが、\"%3$s\"と同じディレクトリにはありませんでした。" -#: pg_createsubscriber.c:435 +#: pg_createsubscriber.c:434 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "\"%2$s\"がプログラム\"%1$s\"を見つけましたが、これは%3$sと同じバージョンではありませんでした。" -#: pg_createsubscriber.c:456 +#: pg_createsubscriber.c:455 #, c-format msgid "checking if directory \"%s\" is a cluster data directory" msgstr "ディレクトリ\"%s\"がクラスタデータディレクトリであることを確認中" -#: pg_createsubscriber.c:462 +#: pg_createsubscriber.c:461 #, c-format msgid "data directory \"%s\" does not exist" msgstr "データディレクトリ\"%s\"は存在しません" -#: pg_createsubscriber.c:475 +#: pg_createsubscriber.c:474 #, c-format msgid "data directory is of wrong version" msgstr "データディレクトリのバージョンが違います" -#: pg_createsubscriber.c:476 +#: pg_createsubscriber.c:475 #, c-format msgid "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\"." msgstr "ファイル\"%s\"では\"%s\"となっています、これはこのプログラムのバージョン\"%s\"と互換性がありません" -#: pg_createsubscriber.c:595 +#: pg_createsubscriber.c:594 #, c-format msgid "connection to database failed: %s" msgstr "データベース接続に失敗しました: %s" -#: pg_createsubscriber.c:608 streamutil.c:230 +#: pg_createsubscriber.c:607 streamutil.c:230 #, c-format msgid "could not clear \"search_path\": %s" msgstr "\"search_path\"を消去できませんでした: %s" -#: pg_createsubscriber.c:648 +#: pg_createsubscriber.c:647 #, c-format msgid "getting system identifier from publisher" msgstr "パブリッシャからシステム識別子を取得しています" -#: pg_createsubscriber.c:655 +#: pg_createsubscriber.c:654 #, c-format msgid "could not get system identifier: %s" msgstr "システム識別子を取得できませんでした: %s" -#: pg_createsubscriber.c:661 +#: pg_createsubscriber.c:660 #, c-format msgid "could not get system identifier: got %d rows, expected %d row" msgstr "システム識別子を取得できませんでした: 受信したのは%d行、想定は%d行" -#: pg_createsubscriber.c:668 +#: pg_createsubscriber.c:667 #, c-format msgid "system identifier is % on publisher" msgstr "パブリッシャのシステム識別子は%です" -#: pg_createsubscriber.c:688 +#: pg_createsubscriber.c:687 #, c-format msgid "getting system identifier from subscriber" msgstr "サブスクライバからシステム識別子を取得しています" -#: pg_createsubscriber.c:692 pg_createsubscriber.c:722 +#: pg_createsubscriber.c:691 pg_createsubscriber.c:721 #, c-format msgid "control file appears to be corrupt" msgstr "制御ファイルが破損しているようです" -#: pg_createsubscriber.c:696 pg_createsubscriber.c:740 +#: pg_createsubscriber.c:695 pg_createsubscriber.c:739 #, c-format msgid "system identifier is % on subscriber" msgstr "サブスクライバのシステム識別子は%です" -#: pg_createsubscriber.c:718 +#: pg_createsubscriber.c:717 #, c-format msgid "modifying system identifier of subscriber" msgstr "サブスクライバのシステム識別子を変更しています" -#: pg_createsubscriber.c:735 +#: pg_createsubscriber.c:734 #, c-format msgid "dry-run: would set system identifier to % on subscriber" msgstr "ドライラン: サブスクライバ上のシステム識別子は %に設定されます" -#: pg_createsubscriber.c:745 +#: pg_createsubscriber.c:744 #, c-format msgid "dry-run: would run pg_resetwal on the subscriber" msgstr "ドライラン: サブスクライバ上でpg_resetwalが実行されます" -#: pg_createsubscriber.c:747 +#: pg_createsubscriber.c:746 #, c-format msgid "running pg_resetwal on the subscriber" msgstr "サブスクライバ上でpg_resetwalを実行します" -#: pg_createsubscriber.c:771 +#: pg_createsubscriber.c:770 #, c-format msgid "successfully reset WAL on the subscriber" msgstr "サブスクライバ上でWALのリセットに成功しました" -#: pg_createsubscriber.c:773 +#: pg_createsubscriber.c:772 #, c-format msgid "could not reset WAL on subscriber: %s" msgstr "サブスクライバ上でWALのリセットができませんでした: %s" -#: pg_createsubscriber.c:798 +#: pg_createsubscriber.c:797 #, c-format msgid "could not obtain database OID: %s" msgstr "データベースOIDを取得できませんでした: %s" -#: pg_createsubscriber.c:805 +#: pg_createsubscriber.c:804 #, c-format msgid "could not obtain database OID: got %d rows, expected %d row" msgstr "データベースOIDを取得できませんでした: 受信したのは%d行、想定は%d行" -#: pg_createsubscriber.c:846 +#: pg_createsubscriber.c:845 #, c-format msgid "could not find publication \"%s\" in database \"%s\": %s" msgstr "データベース\"%2$s\"のパブリケーション\"%1$s\"が見つかりませんでした: %3$s" -#: pg_createsubscriber.c:900 +#: pg_createsubscriber.c:899 #, c-format msgid "using existing publication \"%s\" in database \"%s\"" msgstr "データベース\"%2$s\"で既存のパブリケーション\"%1$s\"を使用します" -#: pg_createsubscriber.c:939 +#: pg_createsubscriber.c:938 #, c-format msgid "could not write an additional WAL record: %s" msgstr "追加のWALレコードを書き込めませんでした: %s" -#: pg_createsubscriber.c:965 +#: pg_createsubscriber.c:964 #, c-format msgid "could not obtain recovery progress: %s" msgstr "リカバリ進捗を取得できませんでした: %s" -#: pg_createsubscriber.c:1030 +#: pg_createsubscriber.c:1029 #, c-format msgid "checking settings on publisher" msgstr "パブリッシャ上の設定を確認しています" -#: pg_createsubscriber.c:1040 +#: pg_createsubscriber.c:1039 #, c-format msgid "primary server cannot be in recovery" msgstr "プライマリサーバーがリカバリ中であってはなりません" -#: pg_createsubscriber.c:1066 +#: pg_createsubscriber.c:1065 #, c-format msgid "could not obtain publisher settings: %s" msgstr "パブリッシャの設定が取得できませんでした: %s" -#: pg_createsubscriber.c:1095 +#: pg_createsubscriber.c:1094 #, c-format msgid "publisher requires \"wal_level\" >= \"replica\"" msgstr "パブリッシャでは \"wal_level\" >= \"replica\" である必要があります" -#: pg_createsubscriber.c:1101 +#: pg_createsubscriber.c:1100 #, c-format msgid "publisher requires %d replication slots, but only %d remain" msgstr "パブリッシャは%d個のレプリケーションスロットを必要としますが、%d個しか残っていません" -#: pg_createsubscriber.c:1103 pg_createsubscriber.c:1112 -#: pg_createsubscriber.c:1222 pg_createsubscriber.c:1231 -#: pg_createsubscriber.c:1240 +#: pg_createsubscriber.c:1102 pg_createsubscriber.c:1111 +#: pg_createsubscriber.c:1221 pg_createsubscriber.c:1230 +#: pg_createsubscriber.c:1239 #, c-format msgid "Increase the configuration parameter \"%s\" to at least %d." msgstr "設定パラメータ\"%s\"を少なくとも%dに増やしてください。" -#: pg_createsubscriber.c:1110 +#: pg_createsubscriber.c:1109 #, c-format msgid "publisher requires %d WAL sender processes, but only %d remain" msgstr "パブリッシャは%d個のWAL senderプロセスを必要としますが、%d個しか残っていません" -#: pg_createsubscriber.c:1119 +#: pg_createsubscriber.c:1118 #, c-format msgid "two_phase option will not be enabled for replication slots" msgstr "レプリケーションスロットに対してtwo_phaseオプションは有効化されません" -#: pg_createsubscriber.c:1120 +#: pg_createsubscriber.c:1119 #, c-format msgid "Subscriptions will be created with the two_phase option disabled. Prepared transactions will be replicated at COMMIT PREPARED." msgstr "サブスクリプションはtwo_phaseオプションが無効な状態で作成されます。準備済みトランザクションはCOMMIT PREPAREDでレプリケートされます。" -#: pg_createsubscriber.c:1122 +#: pg_createsubscriber.c:1121 #, c-format msgid "You can use the command-line option --enable-two-phase to enable two_phase." msgstr "コマンドラインオプション --enable-two-phase で two_phase を有効にできます。" -#: pg_createsubscriber.c:1132 +#: pg_createsubscriber.c:1131 #, c-format msgid "required WAL could be removed from the publisher" msgstr "必要なWALがパブリッシャから削除される可能性があります" -#: pg_createsubscriber.c:1133 +#: pg_createsubscriber.c:1132 #, c-format msgid "Set the configuration parameter \"%s\" to -1 to ensure that required WAL files are not prematurely removed." msgstr "設定パラメータ\"%s\"を -1 に設定して、必要となるWALファイルが使用される前に削除されないようにしてください。" -#: pg_createsubscriber.c:1165 +#: pg_createsubscriber.c:1164 #, c-format msgid "checking settings on subscriber" msgstr "サブスクライバ上で設定を確認します" -#: pg_createsubscriber.c:1172 +#: pg_createsubscriber.c:1171 #, c-format msgid "target server must be a standby" msgstr "ターゲットサーバーはスタンバイである必要があります" -#: pg_createsubscriber.c:1196 +#: pg_createsubscriber.c:1195 #, c-format msgid "could not obtain subscriber settings: %s" msgstr "サブスクライバの設定を取得できませんでした: %s" -#: pg_createsubscriber.c:1220 +#: pg_createsubscriber.c:1219 #, c-format msgid "subscriber requires %d active replication origins, but only %d remain" msgstr "サブスクライバは%d個の有効なレプリケーション起源を必要としますが、%d個しか残ってません" -#: pg_createsubscriber.c:1229 +#: pg_createsubscriber.c:1228 #, c-format msgid "subscriber requires %d logical replication workers, but only %d remain" msgstr "サブスクライバは%d個の論理レプリケーションワーカーを必要としますが、%d個しか残っていません" -#: pg_createsubscriber.c:1238 +#: pg_createsubscriber.c:1237 #, c-format msgid "subscriber requires %d worker processes, but only %d remain" msgstr "サブスクライバは%d個のワーカープロセスを必要としますが、%d個しか残っていません" -#: pg_createsubscriber.c:1279 +#: pg_createsubscriber.c:1278 #, c-format msgid "dry-run: would drop subscription \"%s\" in database \"%s\"" msgstr "ドライラン: データベース\"%2$s\"のサブスクリプション\"%1$s\"は削除されます" -#: pg_createsubscriber.c:1283 +#: pg_createsubscriber.c:1282 #, c-format msgid "dropping subscription \"%s\" in database \"%s\"" msgstr "データベース\"%2$s\"のサブスクリプション\"%1$s\"の削除中" -#: pg_createsubscriber.c:1290 +#: pg_createsubscriber.c:1289 #, c-format msgid "could not drop subscription \"%s\": %s" msgstr "サブスクリプション\"%s\"を削除できませんでした: %s" -#: pg_createsubscriber.c:1325 +#: pg_createsubscriber.c:1324 #, c-format msgid "could not obtain pre-existing subscriptions: %s" msgstr "既存のサブスクリプションを取得できませんでした: %s" -#: pg_createsubscriber.c:1491 +#: pg_createsubscriber.c:1490 #, c-format msgid "could not drop replication slot \"%s\" on primary" msgstr "プライマリ上のレプリケーションスロット\"%s\"を削除できませんでした" -#: pg_createsubscriber.c:1525 +#: pg_createsubscriber.c:1524 #, c-format msgid "could not obtain failover replication slot information: %s" msgstr "フェイルオーバーレプリケーションスロットの情報を取得できませんでした: %s" -#: pg_createsubscriber.c:1527 pg_createsubscriber.c:1536 +#: pg_createsubscriber.c:1526 pg_createsubscriber.c:1535 #, c-format msgid "Drop the failover replication slots on subscriber soon to avoid retention of WAL files." msgstr "WALファイルの増加を避けるためにこのフェイルオーバーレプリケーションスロットを直ちに削除してください。" -#: pg_createsubscriber.c:1535 +#: pg_createsubscriber.c:1534 #, c-format msgid "could not drop failover replication slot" msgstr "フェイルオーバーレプリケーションスロットを削除できませんでした" -#: pg_createsubscriber.c:1558 +#: pg_createsubscriber.c:1557 #, c-format msgid "dry-run: would create the replication slot \"%s\" in database \"%s\" on publisher" msgstr "ドライラン: パブリッシャ上で、データベース\"%2$s\"のレプリケーションスロット\"%1$s\"が作成されます" -#: pg_createsubscriber.c:1561 +#: pg_createsubscriber.c:1560 #, c-format msgid "creating the replication slot \"%s\" in database \"%s\" on publisher" msgstr "パブリッシャ上で、データベース\"%2$s\"のレプリケーションスロット\"%1$s\"を作成します" -#: pg_createsubscriber.c:1580 +#: pg_createsubscriber.c:1579 #, c-format msgid "could not create replication slot \"%s\" in database \"%s\": %s" msgstr "データベース\"%2$s\"でレプリケーションスロット\"%1$s\"を作成できませんでした: %3$s" -#: pg_createsubscriber.c:1611 +#: pg_createsubscriber.c:1610 #, c-format msgid "dry-run: would drop the replication slot \"%s\" in database \"%s\"" msgstr "ドライラン: データベース\"%2$s\"のレプリケーションスロット\"%1$s\"が削除されます" -#: pg_createsubscriber.c:1614 +#: pg_createsubscriber.c:1613 #, c-format msgid "dropping the replication slot \"%s\" in database \"%s\"" msgstr "データベース\"%2$s\"のレプリケーションスロット\"%1$s:を削除します" -#: pg_createsubscriber.c:1630 +#: pg_createsubscriber.c:1629 #, c-format msgid "could not drop replication slot \"%s\" in database \"%s\": %s" msgstr "データベース\"%2$s\"のレプリケーションスロット\"%1$s\"を削除できませんでした: %3$s" -#: pg_createsubscriber.c:1651 +#: pg_createsubscriber.c:1649 #, c-format msgid "pg_ctl failed with exit code %d" msgstr "pg_ctlが終了コード%dで失敗しました" -#: pg_createsubscriber.c:1656 +#: pg_createsubscriber.c:1654 #, c-format msgid "pg_ctl was terminated by exception 0x%X" msgstr "pg_ctlが例外0x%Xによって終了させられました" -#: pg_createsubscriber.c:1658 +#: pg_createsubscriber.c:1656 #, c-format msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." msgstr "16進値の説明についてはC インクルードファイル\"ntstatus.h\"を参照してください。" -#: pg_createsubscriber.c:1660 +#: pg_createsubscriber.c:1658 #, c-format msgid "pg_ctl was terminated by signal %d: %s" msgstr "pg_ctlがシグナル%dによって終了させられました %s" -#: pg_createsubscriber.c:1666 +#: pg_createsubscriber.c:1664 #, c-format msgid "pg_ctl exited with unrecognized status %d" msgstr "pg_ctlが認識できない状態%dで終了しました" -#: pg_createsubscriber.c:1669 +#: pg_createsubscriber.c:1667 #, c-format msgid "The failed command was: %s" msgstr "失敗したコマンドは以下のとおりです: %s" -#: pg_createsubscriber.c:1722 +#: pg_createsubscriber.c:1720 #, c-format msgid "server was started" msgstr "サーバー起動完了" -#: pg_createsubscriber.c:1737 +#: pg_createsubscriber.c:1735 #, c-format msgid "server was stopped" msgstr "サーバーは停止しました" -#: pg_createsubscriber.c:1756 +#: pg_createsubscriber.c:1754 #, c-format msgid "waiting for the target server to reach the consistent state" msgstr "対象サーバーが一貫性のある状態に到達するのを待っています" -#: pg_createsubscriber.c:1774 +#: pg_createsubscriber.c:1772 #, c-format msgid "recovery timed out" msgstr "リカバリーがタイムアウトしました" -#: pg_createsubscriber.c:1786 +#: pg_createsubscriber.c:1784 #, c-format msgid "server did not end recovery" msgstr "サーバーはリカバリを完了しませんでした" -#: pg_createsubscriber.c:1788 +#: pg_createsubscriber.c:1786 #, c-format msgid "target server reached the consistent state" msgstr "対象サーバーが一貫性のある状態に到達しました" -#: pg_createsubscriber.c:1789 +#: pg_createsubscriber.c:1787 #, c-format msgid "If pg_createsubscriber fails after this point, you must recreate the physical replica before continuing." msgstr "もしpg_createsubscriberが今時点より後で失敗した場合は、作業を継続する前に物理レプリカを再作成する必要があります。" -#: pg_createsubscriber.c:1816 pg_createsubscriber.c:1946 +#: pg_createsubscriber.c:1814 pg_createsubscriber.c:1942 #, c-format msgid "could not obtain publication information: %s" msgstr "パブリケーション情報を取得できませんでした: %s" -#: pg_createsubscriber.c:1830 +#: pg_createsubscriber.c:1828 #, c-format msgid "publication \"%s\" already exists" msgstr "パブリケーション\"%s\"はすでに存在します" -#: pg_createsubscriber.c:1831 +#: pg_createsubscriber.c:1829 #, c-format msgid "Consider renaming this publication before continuing." msgstr "作業を継続する前にこのパブリケーションの名前を変更することを検討してください。" -#: pg_createsubscriber.c:1839 +#: pg_createsubscriber.c:1837 #, c-format msgid "dry-run: would create publication \"%s\" in database \"%s\"" msgstr "ドライラン: データベース\"%2$s\"でパブリケーション\"%1$s\"が作成されます" -#: pg_createsubscriber.c:1842 +#: pg_createsubscriber.c:1840 #, c-format msgid "creating publication \"%s\" in database \"%s\"" msgstr "データベース\"%2$s\"でパブリケーション\"%1$s\"を作成します" -#: pg_createsubscriber.c:1855 +#: pg_createsubscriber.c:1853 #, c-format msgid "could not create publication \"%s\" in database \"%s\": %s" msgstr "データベース\"%2$s\"でパブリケーション\"%1$s\"を作成できませんでした: %3$s" -#: pg_createsubscriber.c:1886 +#: pg_createsubscriber.c:1883 #, c-format msgid "dry-run: would drop publication \"%s\" in database \"%s\"" msgstr "ドライラン: データベース\"%2$s\"のパブリケーション\"%1$s\"が削除されます" -#: pg_createsubscriber.c:1889 +#: pg_createsubscriber.c:1886 #, c-format msgid "dropping publication \"%s\" in database \"%s\"" msgstr "データベース\"%2$s\"のパブリケーション\"%1$s\"を削除します" -#: pg_createsubscriber.c:1903 +#: pg_createsubscriber.c:1900 #, c-format msgid "could not drop publication \"%s\" in database \"%s\": %s" msgstr "データベース\"%2$s\"のパブリケーション\"%1$s\"が削除できませんでした: %3$s" -#: pg_createsubscriber.c:1939 +#: pg_createsubscriber.c:1935 #, c-format msgid "dropping all existing publications in database \"%s\"" msgstr "データベース\"%s\"のすべてのパブリケーションを削除します" -#: pg_createsubscriber.c:1970 +#: pg_createsubscriber.c:1964 #, c-format msgid "dry-run: would preserve existing publication \"%s\" in database \"%s\"" msgstr "ドライラン: データベース\"%2$s\"の既存のパブリケーション\"%1$s\"が維持されます" -#: pg_createsubscriber.c:1973 +#: pg_createsubscriber.c:1967 #, c-format msgid "preserving existing publication \"%s\" in database \"%s\"" msgstr "データベース\"%2$s\"で既存のパブリケーション\"%1$s\"を維持します" -#: pg_createsubscriber.c:2008 +#: pg_createsubscriber.c:2002 #, c-format msgid "dry-run: would create subscription \"%s\" in database \"%s\"" msgstr "ドライラン: データベース\"%2$s\"でサブスクリプション\"%1$s\"が作成されます" -#: pg_createsubscriber.c:2011 +#: pg_createsubscriber.c:2005 #, c-format msgid "creating subscription \"%s\" in database \"%s\"" msgstr "データベース\"%2$s\"でサブスクリプション\"%1$s\"を作成します" -#: pg_createsubscriber.c:2033 +#: pg_createsubscriber.c:2027 #, c-format msgid "could not create subscription \"%s\" in database \"%s\": %s" msgstr "データベース\"%2$s\"でサブスクリプション\"%1$s\"を作成できませんでした: %3$s" -#: pg_createsubscriber.c:2078 +#: pg_createsubscriber.c:2072 #, c-format msgid "could not obtain subscription OID: %s" msgstr "サブスクリプションOIDが取得できませんでした: %s" -#: pg_createsubscriber.c:2085 +#: pg_createsubscriber.c:2079 #, c-format msgid "could not obtain subscription OID: got %d rows, expected %d row" msgstr "サブスクリプションOIDが取得できませんでした: 受信したのは%d行、想定は%d行" -#: pg_createsubscriber.c:2110 +#: pg_createsubscriber.c:2104 #, c-format msgid "dry-run: would set the replication progress (node name \"%s\", LSN %s) in database \"%s\"" msgstr "ドライラン: データベース\"%3$s\"でのレプリケーション進捗(ノード名 \"%1$s\", LSN %2$s)が設定されます" -#: pg_createsubscriber.c:2113 +#: pg_createsubscriber.c:2107 #, c-format msgid "setting the replication progress (node name \"%s\", LSN %s) in database \"%s\"" msgstr "データベース\"%3$s\"でのレプリケーションの進捗を設定しています(ノード名\"%1$s\", LSN %2$s)" -#: pg_createsubscriber.c:2128 +#: pg_createsubscriber.c:2122 #, c-format msgid "could not set replication progress for subscription \"%s\": %s" msgstr "サブスクリプション\"%s\"にレプリケーション進捗を設定できませんでした: %s" -#: pg_createsubscriber.c:2160 +#: pg_createsubscriber.c:2154 #, c-format msgid "dry-run: would enable subscription \"%s\" in database \"%s\"" msgstr "ドライラン: データベース\"%2$s\"のサブスクリプション\"%1$s\"が有効化されます" -#: pg_createsubscriber.c:2163 +#: pg_createsubscriber.c:2157 #, c-format msgid "enabling subscription \"%s\" in database \"%s\"" msgstr "データベース\"%2$s\"のサブスクリプション\"%1$s\"を有効にします" -#: pg_createsubscriber.c:2175 +#: pg_createsubscriber.c:2169 #, c-format msgid "could not enable subscription \"%s\": %s" msgstr "サブスクリプション\"%s\"を有効化できませんでした: %s" -#: pg_createsubscriber.c:2221 +#: pg_createsubscriber.c:2215 #, c-format msgid "could not obtain a list of databases: %s" msgstr "データベースの一覧を取得できませんでした: %s" -#: pg_createsubscriber.c:2327 +#: pg_createsubscriber.c:2321 #, c-format msgid "cannot be executed by \"root\"" msgstr "\"root\"では実行できません" -#: pg_createsubscriber.c:2328 +#: pg_createsubscriber.c:2322 #, c-format msgid "You must run %s as the PostgreSQL superuser." msgstr "PostgreSQLのスーパーユーザーで%sを実行しなければなりません" -#: pg_createsubscriber.c:2351 +#: pg_createsubscriber.c:2345 #, c-format msgid "database \"%s\" specified more than once for -d/--database" msgstr "-d/--database に対してデータベース\"%s\"が複数回指定されました" -#: pg_createsubscriber.c:2396 -#, c-format -msgid "publication \"%s\" specified more than once for --publication" -msgstr "--publication に対してパブリケーション\"%s\"が複数回指定されました" - -#: pg_createsubscriber.c:2405 +#: pg_createsubscriber.c:2394 #, c-format msgid "replication slot \"%s\" specified more than once for --replication-slot" msgstr "--replication-slot に対してレプリケーションスロット\"%s\"が複数回指定されました" -#: pg_createsubscriber.c:2414 +#: pg_createsubscriber.c:2403 #, c-format msgid "subscription \"%s\" specified more than once for --subscription" msgstr "--subscription に対してブスクリプション\"%s\"が複数回指定されました" -#: pg_createsubscriber.c:2420 +#: pg_createsubscriber.c:2409 #, c-format msgid "object type \"%s\" specified more than once for --clean" msgstr "--clean に対してオブジェクト種別\"%s\"が複数回指定されました" -#: pg_createsubscriber.c:2464 +#: pg_createsubscriber.c:2453 #, c-format msgid "no subscriber data directory specified" msgstr "サブスクライバのデータディレクトリが指定されていません" -#: pg_createsubscriber.c:2475 +#: pg_createsubscriber.c:2464 #, c-format msgid "could not determine current directory" msgstr "カレントディレクトリを特定できませんでした" -#: pg_createsubscriber.c:2492 +#: pg_createsubscriber.c:2481 #, c-format msgid "no publisher connection string specified" msgstr "パブリッシャの接続文字列が指定されていません" -#: pg_createsubscriber.c:2520 pg_recvlogical.c:348 +#: pg_createsubscriber.c:2509 pg_recvlogical.c:352 #, c-format msgid "could not open log file \"%s\": %m" msgstr "ロックファイル\"%s\"をオープンできませんでした: %m" -#: pg_createsubscriber.c:2528 +#: pg_createsubscriber.c:2518 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"The target directory will not be modified." -msgstr "" -"ドライランモードで実行します。\n" -"ターゲットディレクトリは更新されません。" +msgid "executing in dry-run mode" +msgstr "ドライランモードで実行します" + +#: pg_createsubscriber.c:2519 +#, c-format +msgid "The target directory will not be modified." +msgstr "対象ディレクトリの内容は変更されません。" -#: pg_createsubscriber.c:2531 +#: pg_createsubscriber.c:2522 #, c-format msgid "validating publisher connection string" msgstr "パブリッシャの接続文字列の検証中" -#: pg_createsubscriber.c:2537 +#: pg_createsubscriber.c:2528 #, c-format msgid "validating subscriber connection string" msgstr "サブスクライバの接続文字列の検証中" -#: pg_createsubscriber.c:2554 +#: pg_createsubscriber.c:2545 #, c-format msgid "no database was specified" msgstr "データベースが指定されていません" -#: pg_createsubscriber.c:2565 +#: pg_createsubscriber.c:2556 #, c-format msgid "database name \"%s\" was extracted from the publisher connection string" msgstr "データベース名\"%s\"がパブリッシャの接続文字列から抽出されました" -#: pg_createsubscriber.c:2570 +#: pg_createsubscriber.c:2561 #, c-format msgid "no database name specified" msgstr "データベース名が指定されていません" -#: pg_createsubscriber.c:2580 +#: pg_createsubscriber.c:2571 #, c-format msgid "wrong number of publication names specified" msgstr "指定されたパブリケーション名の数が間違っています" -#: pg_createsubscriber.c:2581 +#: pg_createsubscriber.c:2572 #, c-format msgid "The number of specified publication names (%d) must match the number of specified database names (%d)." msgstr "パブリケーション名の数(%d)はデータベース名の数(%d)と一致している必要があります。" -#: pg_createsubscriber.c:2587 +#: pg_createsubscriber.c:2578 #, c-format msgid "wrong number of subscription names specified" msgstr "指定されたサブスクリプション名の数が間違っています" -#: pg_createsubscriber.c:2588 +#: pg_createsubscriber.c:2579 #, c-format msgid "The number of specified subscription names (%d) must match the number of specified database names (%d)." msgstr "サブスクリプション名の数(%d)はデータベース名の数(%d)と一致している必要があります。" -#: pg_createsubscriber.c:2594 +#: pg_createsubscriber.c:2585 #, c-format msgid "wrong number of replication slot names specified" msgstr "指定されたレプリケーションスロット名の数が間違っています" -#: pg_createsubscriber.c:2595 +#: pg_createsubscriber.c:2586 #, c-format msgid "The number of specified replication slot names (%d) must match the number of specified database names (%d)." msgstr "レプリケーションスロット名の数(%d)はデータベース名の数(%d)と一致している必要があります。" -#: pg_createsubscriber.c:2607 +#: pg_createsubscriber.c:2598 #, c-format msgid "invalid object type \"%s\" specified for option %s" msgstr "オプション %2$s に対して不正なオブジェクト種別\"%1$s\"が指定されました" -#: pg_createsubscriber.c:2609 +#: pg_createsubscriber.c:2600 #, c-format msgid "The valid value is: \"%s\"" msgstr "指定可能な値は: \"%s\"" -#: pg_createsubscriber.c:2640 +#: pg_createsubscriber.c:2631 #, c-format msgid "subscriber data directory is not a copy of the source database cluster" msgstr "サブスクライバのデータディレクトリは元データベースクラスタのコピーではありません" -#: pg_createsubscriber.c:2653 +#: pg_createsubscriber.c:2644 #, c-format msgid "standby server is running" msgstr "スタンバイサーバーが稼働中です" -#: pg_createsubscriber.c:2654 +#: pg_createsubscriber.c:2645 #, c-format msgid "Stop the standby server and try again." msgstr "このスタンバイサーバーを停止してから再試行してください。" -#: pg_createsubscriber.c:2663 +#: pg_createsubscriber.c:2654 #, c-format msgid "starting the standby server with command-line options" msgstr "コマンドラインオプションを指定してスタンバイサーバーを起動しています" -#: pg_createsubscriber.c:2679 pg_createsubscriber.c:2714 +#: pg_createsubscriber.c:2670 pg_createsubscriber.c:2705 #, c-format msgid "stopping the subscriber" msgstr "サブスクライバを起動しています" -#: pg_createsubscriber.c:2693 +#: pg_createsubscriber.c:2684 #, c-format msgid "starting the subscriber" msgstr "サブスクライバを起動しています" -#: pg_createsubscriber.c:2722 +#: pg_createsubscriber.c:2713 #, c-format msgid "Done!" msgstr "完了!" @@ -2248,7 +2244,7 @@ msgstr "%X/%08X (タイムライン %u)でログのストリーミングを停 msgid "switched to timeline %u at %X/%08X" msgstr "%3$X/%2$08Xで タイムライン%1$uに切り替えました" -#: pg_receivewal.c:224 pg_recvlogical.c:1082 +#: pg_receivewal.c:224 pg_recvlogical.c:1086 #, c-format msgid "received interrupt signal, exiting" msgstr "割り込みシグナルを受信、終了します" @@ -2318,7 +2314,7 @@ msgstr "ファイル\"%s\"の確認ができません: %sによる圧縮はこ msgid "starting log streaming at %X/%08X (timeline %u)" msgstr "%X/%08X (タイムライン %u)からログのストリーミングを開始" -#: pg_receivewal.c:693 pg_recvlogical.c:807 +#: pg_receivewal.c:693 pg_recvlogical.c:811 #, c-format msgid "could not parse end position \"%s\"" msgstr "終了位置\"%s\"をパースできませんでした" @@ -2348,23 +2344,23 @@ msgstr "%sによる圧縮`まだサポートされていません" msgid "replication connection using slot \"%s\" is unexpectedly database specific" msgstr "スロット\"%s\"を使用するレプリケーション接続で、想定に反してデータベースが指定されています" -#: pg_receivewal.c:878 pg_recvlogical.c:991 +#: pg_receivewal.c:878 pg_recvlogical.c:995 #, c-format msgid "dropping replication slot \"%s\"" msgstr "レプリケーションスロット\"%s\"を削除しています" -#: pg_receivewal.c:889 pg_recvlogical.c:1001 +#: pg_receivewal.c:889 pg_recvlogical.c:1005 #, c-format msgid "creating replication slot \"%s\"" msgstr "レプリケーションスロット\"%s\"を作成しています" -#: pg_receivewal.c:918 pg_recvlogical.c:1035 +#: pg_receivewal.c:918 pg_recvlogical.c:1039 #, c-format msgid "disconnected" msgstr "切断しました" #. translator: check source for value for %d -#: pg_receivewal.c:922 pg_recvlogical.c:1040 +#: pg_receivewal.c:922 pg_recvlogical.c:1044 #, c-format msgid "disconnected; waiting %d seconds to try again" msgstr "切断しました; %d秒待機して再試行します" @@ -2475,103 +2471,103 @@ msgstr "フィードバックパケットを送信できませんでした: %s" msgid "starting log streaming at %X/%08X (slot %s)" msgstr "%X/%08X からログのストリーミングを開始します (スロット %s)" -#: pg_recvlogical.c:287 +#: pg_recvlogical.c:291 #, c-format msgid "streaming initiated" msgstr "ストリーミングを開始しました" -#: pg_recvlogical.c:377 receivelog.c:890 +#: pg_recvlogical.c:381 receivelog.c:896 #, c-format msgid "invalid socket: %s" msgstr "無効なソケット: %s" -#: pg_recvlogical.c:430 receivelog.c:918 +#: pg_recvlogical.c:434 receivelog.c:924 #, c-format msgid "%s() failed: %m" msgstr "%s() が失敗しました: %m" -#: pg_recvlogical.c:437 receivelog.c:967 +#: pg_recvlogical.c:441 receivelog.c:973 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "WAL ストリームからデータを受信できませんでした: %s" -#: pg_recvlogical.c:479 pg_recvlogical.c:530 receivelog.c:1011 -#: receivelog.c:1074 +#: pg_recvlogical.c:483 pg_recvlogical.c:534 receivelog.c:1017 +#: receivelog.c:1080 #, c-format msgid "streaming header too small: %d" msgstr "ストリーミングヘッダが小さ過ぎます: %d" -#: pg_recvlogical.c:514 receivelog.c:847 +#: pg_recvlogical.c:518 receivelog.c:853 #, c-format msgid "unrecognized streaming header: \"%c\"" msgstr "ストリーミングヘッダを認識できませんでした: \"%c\"" -#: pg_recvlogical.c:568 pg_recvlogical.c:580 +#: pg_recvlogical.c:572 pg_recvlogical.c:584 #, c-format msgid "could not write %d bytes to log file \"%s\": %m" msgstr "%dバイトをログファイル\"%s\"に書き込めませんでした: %m" -#: pg_recvlogical.c:638 receivelog.c:642 receivelog.c:679 +#: pg_recvlogical.c:642 receivelog.c:648 receivelog.c:685 #, c-format msgid "unexpected termination of replication stream: %s" msgstr "レプリケーションストリームが突然終了しました: %s" -#: pg_recvlogical.c:802 +#: pg_recvlogical.c:806 #, c-format msgid "could not parse start position \"%s\"" msgstr "開始位置\"%s\"をパースできませんでした" -#: pg_recvlogical.c:880 +#: pg_recvlogical.c:884 #, c-format msgid "no slot specified" msgstr "スロットが指定されていません" -#: pg_recvlogical.c:887 +#: pg_recvlogical.c:891 #, c-format msgid "no target file specified" msgstr "ターゲットファイルが指定されていません" -#: pg_recvlogical.c:894 +#: pg_recvlogical.c:898 #, c-format msgid "no database specified" msgstr "データベースが指定されていません" -#: pg_recvlogical.c:901 +#: pg_recvlogical.c:905 #, c-format msgid "at least one action needs to be specified" msgstr "少なくとも一つのアクションを指定する必要があります" -#: pg_recvlogical.c:908 +#: pg_recvlogical.c:912 #, c-format msgid "cannot use --create-slot or --start together with --drop-slot" msgstr "--create-slot や --start は --drop-slot と同時には指定できません" -#: pg_recvlogical.c:915 +#: pg_recvlogical.c:919 #, c-format msgid "cannot use --create-slot or --drop-slot together with --startpos" msgstr "--create-slot や --drop-slot は --startpos と同時には指定できません" -#: pg_recvlogical.c:922 +#: pg_recvlogical.c:926 #, c-format msgid "--endpos may only be specified with --start" msgstr "--endpos は --start が指定されているときにのみ指定可能です" -#: pg_recvlogical.c:931 pg_recvlogical.c:938 +#: pg_recvlogical.c:935 pg_recvlogical.c:942 #, c-format msgid "%s may only be specified with --create-slot" msgstr "%s は--create-slotが指定されているときにのみ指定可能です" -#: pg_recvlogical.c:975 +#: pg_recvlogical.c:979 #, c-format msgid "could not establish database-specific replication connection" msgstr "データベース指定のレプリケーション接続が確立できませんでした" -#: pg_recvlogical.c:1085 +#: pg_recvlogical.c:1089 #, c-format msgid "end position %X/%08X reached by keepalive" msgstr "キープアライブで終了位置 %X/%08X に到達しました" -#: pg_recvlogical.c:1090 +#: pg_recvlogical.c:1094 #, c-format msgid "end position %X/%08X reached by WAL record at %X/%08X" msgstr "%X/%08X のWALレコードで終了位置 %X/%08X に到達しました" @@ -2617,7 +2613,7 @@ msgstr "先行書き込みログファイル\"%s\"をオープンできません msgid "not renaming \"%s\", segment is not complete" msgstr "\"%s\"の名前を変更しません、セグメントが完成していません" -#: receivelog.c:227 receivelog.c:317 receivelog.c:688 +#: receivelog.c:227 receivelog.c:317 receivelog.c:694 #, c-format msgid "could not close file \"%s\": %s" msgstr "ファイル\"%s\"をクローズできませんでした: %s" @@ -2647,67 +2643,67 @@ msgstr "非互換のサーバーバージョン%s、クライアントは%sよ msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" msgstr "非互換のサーバーバージョン%s、クライアントは%sより新しいサーバーバージョンからのストリーミングをサポートしていません" -#: receivelog.c:508 +#: receivelog.c:505 #, c-format msgid "system identifier does not match between base backup and streaming connection" msgstr "システム識別子がベースバックアップとストリーミング接続の間で一致しません" -#: receivelog.c:516 +#: receivelog.c:513 #, c-format msgid "starting timeline %u is not present in the server" msgstr "開始タイムライン%uがサーバーに存在しません" -#: receivelog.c:555 +#: receivelog.c:554 #, c-format msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" msgstr "TIMELINE_HISTORYコマンドへの想定外の応答: 受信したのは%d行%d列、想定は%d行%d列" -#: receivelog.c:626 +#: receivelog.c:632 #, c-format msgid "server reported unexpected next timeline %u, following timeline %u" msgstr "サーバーがタイムライン%2$uに続いて想定外のタイムライン%1$uを通知してきました" -#: receivelog.c:632 +#: receivelog.c:638 #, c-format msgid "server stopped streaming timeline %u at %X/%08X, but reported next timeline %u to begin at %X/%08X" msgstr "サーバーはタイムライン%uのストリーミングを%X/%08Xで停止しました、しかし次のタイムライン%uが%X/%08Xから開始すると通知してきています" -#: receivelog.c:672 +#: receivelog.c:678 #, c-format msgid "replication stream was terminated before stop point" msgstr "レプリケーションストリームが停止ポイントより前で終了しました" -#: receivelog.c:718 +#: receivelog.c:724 #, c-format msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" msgstr "タイムライン終了後に想定外の結果セット: 受信したのは%d行%d列、想定は%d行%d列" -#: receivelog.c:727 +#: receivelog.c:733 #, c-format msgid "could not parse next timeline's starting point \"%s\"" msgstr "次のタイムラインの開始ポイント\"%s\"をパースできませんでした" -#: receivelog.c:775 receivelog.c:1030 walmethods.c:1206 +#: receivelog.c:781 receivelog.c:1036 walmethods.c:1206 #, c-format msgid "could not fsync file \"%s\": %s" msgstr "ファイル\"%s\"をfsyncできませんでした: %s" -#: receivelog.c:1091 +#: receivelog.c:1097 #, c-format msgid "received write-ahead log record for offset %u with no file open" msgstr "ファイルがオープンされていない状態で、オフセット%uに対する先行書き込みログレコードを受信しました" -#: receivelog.c:1101 +#: receivelog.c:1107 #, c-format msgid "got WAL data offset %08x, expected %08x" msgstr "WALデータオフセット%08xを受信、想定は%08x" -#: receivelog.c:1136 +#: receivelog.c:1142 #, c-format msgid "could not write %d bytes to WAL file \"%s\": %s" msgstr "WALファイル\"%2$s\"に%1$dバイト書き込めませんでした: %3$s" -#: receivelog.c:1161 receivelog.c:1201 receivelog.c:1229 +#: receivelog.c:1167 receivelog.c:1207 receivelog.c:1235 #, c-format msgid "could not send copy-end packet: %s" msgstr "コピー終端パケットを送信できませんでした: %s" @@ -2767,32 +2763,32 @@ msgstr "グループアクセスフラグがパースできませんでした: % msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" msgstr "システムを識別できませんでした: 受信したのは%d行%d列、想定は%d行%d列以上" -#: streamutil.c:519 +#: streamutil.c:520 #, c-format msgid "could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" msgstr "レプリケーションスロット\"%s\"を読み取れませんでした: 受信したのは%d行%d列、想定は%d行%d列" -#: streamutil.c:531 +#: streamutil.c:532 #, c-format msgid "replication slot \"%s\" does not exist" msgstr "レプリケーションスロット\"%s\"は存在しません" -#: streamutil.c:542 +#: streamutil.c:543 #, c-format msgid "expected a physical replication slot, got type \"%s\" instead" msgstr "物理レプリケーションスロットが必要ですが、タイプは\"%s\"でした" -#: streamutil.c:556 +#: streamutil.c:557 #, c-format msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\"" msgstr "レプリケーションスロット\"%2$s\"のrestart_lsn\"%1$s\"をパースできませんでした" -#: streamutil.c:678 +#: streamutil.c:683 #, c-format msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" msgstr "レプリケーションスロット\"%s\"を作成できませんでした: 受信したのは%d行%d列、想定は%d行%d列" -#: streamutil.c:722 +#: streamutil.c:727 #, c-format msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" msgstr "レプリケーションスロット\"%s\"を削除できませんでした: 受信したのは%d行%d列、想定は%d行%d列" @@ -2837,6 +2833,9 @@ msgstr "圧縮ストリームをクローズできませんでした" #~ msgid "options %s and -a/--all cannot be used together" #~ msgstr "%s と -a/--all は同時には使用できません" +#~ msgid "publication \"%s\" specified more than once for --publication" +#~ msgstr "--publication に対してパブリケーション\"%s\"が複数回指定されました" + #~ msgid "subscriber successfully changed the system identifier" #~ msgstr "サブスクライバはシステム識別子の変更に成功しました" diff --git a/src/bin/pg_basebackup/po/ka.po b/src/bin/pg_basebackup/po/ka.po index 6cc8365324a..081c5313594 100644 --- a/src/bin/pg_basebackup/po/ka.po +++ b/src/bin/pg_basebackup/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_basebackup (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-13 06:23+0000\n" -"PO-Revision-Date: 2026-05-13 09:08+0200\n" +"POT-Creation-Date: 2026-07-04 00:22+0000\n" +"PO-Revision-Date: 2026-07-04 07:35+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -109,7 +109,7 @@ msgstr "\"%s\"-ის წაკითხვის შეცდომა: წა #: ../../common/controldata_utils.c:133 ../../common/controldata_utils.c:281 #: ../../fe_utils/astreamer_file.c:141 ../../fe_utils/astreamer_file.c:282 -#: pg_recvlogical.c:651 +#: pg_recvlogical.c:655 #, c-format msgid "could not close file \"%s\": %m" msgstr "ფაილის (%s) დახურვის შეცდომა: %m" @@ -133,7 +133,7 @@ msgstr "" #: ../../common/controldata_utils.c:231 ../../common/file_utils.c:69 #: ../../common/file_utils.c:370 ../../common/file_utils.c:428 #: ../../common/file_utils.c:502 ../../fe_utils/recovery_gen.c:141 -#: pg_basebackup.c:1834 pg_createsubscriber.c:1449 pg_receivewal.c:386 +#: pg_basebackup.c:1834 pg_createsubscriber.c:1448 pg_receivewal.c:386 #, c-format msgid "could not open file \"%s\": %m" msgstr "ფაილის (%s) გახსნის შეცდომა: %m" @@ -176,7 +176,7 @@ msgid "could not synchronize file system for file \"%s\": %m" msgstr "შეუძლებელია ფაილური სისტემის სინქრონიზაცია ფაილისთვის \"%s\": %m" #: ../../common/file_utils.c:123 ../../common/file_utils.c:588 -#: ../../fe_utils/version.c:60 pg_receivewal.c:319 pg_recvlogical.c:354 +#: ../../fe_utils/version.c:60 pg_receivewal.c:319 pg_recvlogical.c:358 #, c-format msgid "could not stat file \"%s\": %m" msgstr "ფაილი \"%s\" არ არსებობს: %m" @@ -242,7 +242,7 @@ msgstr "ფაილის (%s) შექმნის შეცდომა: %m" #: ../../fe_utils/astreamer_file.c:124 ../../fe_utils/astreamer_file.c:273 #: ../../fe_utils/recovery_gen.c:144 pg_basebackup.c:1421 pg_basebackup.c:1715 -#: pg_createsubscriber.c:1452 +#: pg_createsubscriber.c:1451 #, c-format msgid "could not write to file \"%s\": %m" msgstr "ფაილში (%s) ჩაწერის შეცდომა: %m" @@ -263,7 +263,7 @@ msgid "unexpected state while extracting archive" msgstr "არქივის გაშლის მოულოდნელი მდგომარეობა" #: ../../fe_utils/astreamer_file.c:338 pg_basebackup.c:700 pg_basebackup.c:714 -#: pg_basebackup.c:759 pg_createsubscriber.c:1003 pg_createsubscriber.c:1007 +#: pg_basebackup.c:759 pg_createsubscriber.c:1002 pg_createsubscriber.c:1006 #, c-format msgid "could not create directory \"%s\": %m" msgstr "საქაღალდის (%s) შექმნის შეცდომა: %m" @@ -415,7 +415,7 @@ msgstr "%s არაა საზღვრებში %d-დან %d-მდე msgid "unrecognized sync method: %s" msgstr "უცნობი სინქრონიზაციის მეთოდი: %s" -#: ../../fe_utils/option_utils.c:139 pg_createsubscriber.c:2445 +#: ../../fe_utils/option_utils.c:139 pg_createsubscriber.c:2434 #, c-format msgid "options %s and %s cannot be used together" msgstr "პარამეტრებს %s და -%s ერთად ვერ გამოიყენებთ" @@ -434,12 +434,12 @@ msgstr "არასაკმარისი მეხსიერება" msgid "%s" msgstr "%s" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "გარსის ბრძანების არგუმენტი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "მონაცემთა ბაზის სახელი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" @@ -553,13 +553,13 @@ msgstr "" "%s გაშვებული PostgreSQL სერვერის მარქაფს იღებს.\n" "\n" -#: pg_basebackup.c:395 pg_createsubscriber.c:288 pg_receivewal.c:79 +#: pg_basebackup.c:395 pg_createsubscriber.c:287 pg_receivewal.c:79 #: pg_recvlogical.c:86 #, c-format msgid "Usage:\n" msgstr "გამოყენება:\n" -#: pg_basebackup.c:396 pg_createsubscriber.c:289 pg_receivewal.c:80 +#: pg_basebackup.c:396 pg_createsubscriber.c:288 pg_receivewal.c:80 #: pg_recvlogical.c:87 #, c-format msgid " %s [OPTION]...\n" @@ -824,7 +824,7 @@ msgstr " -w, --no-password არასოდეს მკითხო msgid " -W, --password force password prompt (should happen automatically)\n" msgstr " -W, --password პაროლის ყოველთვის კითხვა (ავტომატურად უნდა ხდებოდეს)\n" -#: pg_basebackup.c:449 pg_createsubscriber.c:313 pg_receivewal.c:106 +#: pg_basebackup.c:449 pg_createsubscriber.c:312 pg_receivewal.c:106 #: pg_recvlogical.c:121 #, c-format msgid "" @@ -834,7 +834,7 @@ msgstr "" "\n" "შეცდომების შესახებ მიწერეთ: %s\n" -#: pg_basebackup.c:450 pg_createsubscriber.c:314 pg_receivewal.c:107 +#: pg_basebackup.c:450 pg_createsubscriber.c:313 pg_receivewal.c:107 #: pg_recvlogical.c:122 #, c-format msgid "%s home page: <%s>\n" @@ -886,7 +886,7 @@ msgstr "ფონური ნაკადის შექმნის შეც msgid "directory \"%s\" exists but is not empty" msgstr "საქაღალდე \"%s\" არსებობს, მაგრამ ცარიელი არაა" -#: pg_basebackup.c:784 pg_createsubscriber.c:464 +#: pg_basebackup.c:784 pg_createsubscriber.c:463 #, c-format msgid "could not access directory \"%s\": %m" msgstr "საქაღალდის (%s) წვდომის შეცდომა: %m" @@ -947,8 +947,8 @@ msgstr "გადაცემის სიჩქარის მნიშვნ msgid "could not get COPY data stream: %s" msgstr "\"COPY\"-ის მონაცემების ნაკადის მიღების შეცდომა: %s" -#: pg_basebackup.c:1041 pg_recvlogical.c:451 pg_recvlogical.c:627 -#: receivelog.c:981 +#: pg_basebackup.c:1041 pg_recvlogical.c:455 pg_recvlogical.c:631 +#: receivelog.c:987 #, c-format msgid "could not read COPY data: %s" msgstr "\"COPY\"-ის მონაცემების წაკითხვის შეცდომა: %s" @@ -1033,9 +1033,9 @@ msgstr "ჟურნალის ნაკადის გასათიშა msgid "server does not support incremental backup" msgstr "სერვერს ინკრემენტული მარქაფის მხარდაჭერა არ გააჩნია" -#: pg_basebackup.c:1838 pg_basebackup.c:1996 pg_recvlogical.c:278 -#: receivelog.c:543 receivelog.c:582 streamutil.c:296 streamutil.c:370 -#: streamutil.c:422 streamutil.c:510 streamutil.c:667 streamutil.c:712 +#: pg_basebackup.c:1838 pg_basebackup.c:1996 pg_recvlogical.c:282 +#: receivelog.c:542 receivelog.c:588 streamutil.c:296 streamutil.c:370 +#: streamutil.c:422 streamutil.c:511 streamutil.c:672 streamutil.c:717 #, c-format msgid "could not send replication command \"%s\": %s" msgstr "რეპლიკაციის ბრძანების (\"%s\") გაგზავნის შეცდომა: %s" @@ -1226,21 +1226,21 @@ msgstr "wal-method-ის არასწორი მნიშვნელო #: pg_basebackup.c:2700 pg_basebackup.c:2712 pg_basebackup.c:2724 #: pg_basebackup.c:2732 pg_basebackup.c:2745 pg_basebackup.c:2751 #: pg_basebackup.c:2760 pg_basebackup.c:2772 pg_basebackup.c:2783 -#: pg_basebackup.c:2791 pg_createsubscriber.c:2424 pg_createsubscriber.c:2447 -#: pg_createsubscriber.c:2457 pg_createsubscriber.c:2465 -#: pg_createsubscriber.c:2493 pg_createsubscriber.c:2571 pg_receivewal.c:748 +#: pg_basebackup.c:2791 pg_createsubscriber.c:2413 pg_createsubscriber.c:2436 +#: pg_createsubscriber.c:2446 pg_createsubscriber.c:2454 +#: pg_createsubscriber.c:2482 pg_createsubscriber.c:2562 pg_receivewal.c:748 #: pg_receivewal.c:760 pg_receivewal.c:767 pg_receivewal.c:776 -#: pg_receivewal.c:783 pg_receivewal.c:793 pg_recvlogical.c:859 -#: pg_recvlogical.c:871 pg_recvlogical.c:881 pg_recvlogical.c:888 -#: pg_recvlogical.c:895 pg_recvlogical.c:902 pg_recvlogical.c:909 -#: pg_recvlogical.c:916 pg_recvlogical.c:923 pg_recvlogical.c:932 -#: pg_recvlogical.c:939 +#: pg_receivewal.c:783 pg_receivewal.c:793 pg_recvlogical.c:863 +#: pg_recvlogical.c:875 pg_recvlogical.c:885 pg_recvlogical.c:892 +#: pg_recvlogical.c:899 pg_recvlogical.c:906 pg_recvlogical.c:913 +#: pg_recvlogical.c:920 pg_recvlogical.c:927 pg_recvlogical.c:936 +#: pg_recvlogical.c:943 #, c-format msgid "Try \"%s --help\" for more information." msgstr "მეტი ინფორმაციისთვის სცადეთ '%s --help'." -#: pg_basebackup.c:2572 pg_createsubscriber.c:2455 pg_receivewal.c:758 -#: pg_recvlogical.c:869 +#: pg_basebackup.c:2572 pg_createsubscriber.c:2444 pg_receivewal.c:758 +#: pg_recvlogical.c:873 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "მეტისმეტად ბევრი ბრძანების-სტრიქონის არგუმენტი (პირველია \"%s\")" @@ -1347,27 +1347,27 @@ msgstr "ჩავარდა აღდგენის დასრულებ msgid "The target server cannot be used as a physical replica anymore. You must recreate the physical replica before continuing." msgstr "სამიზნე სერვერს ფიზიკურ რეპლიკად ვეღარ გამოიყენებთ. გაგრძელებამდე ფიზიკური რეპლიკა თავიდან უნდა შექმნათ." -#: pg_createsubscriber.c:263 +#: pg_createsubscriber.c:262 #, c-format msgid "publication \"%s\" created in database \"%s\" on primary was left behind" msgstr "გამოცემა \"%s\", შექმნილი მონაცემთა ბაზაში \"%s\" ძირითადზე, გამოტოვებულია" -#: pg_createsubscriber.c:266 +#: pg_createsubscriber.c:265 #, c-format msgid "Drop this publication before trying again." msgstr "მოაცილეთ ეს გამოცემა, სანამ თავიდან სცდით." -#: pg_createsubscriber.c:270 +#: pg_createsubscriber.c:269 #, c-format msgid "replication slot \"%s\" created in database \"%s\" on primary was left behind" msgstr "რეპლიკაციის სლოტი \"%s\" შეიქმნა მონაცემთა ბაზაში \"%s\" ძირითადზე, შეიძლება, გამოტოვებულია" -#: pg_createsubscriber.c:273 pg_createsubscriber.c:1493 +#: pg_createsubscriber.c:272 pg_createsubscriber.c:1492 #, c-format msgid "Drop this replication slot soon to avoid retention of WAL files." msgstr "ამ რეპლიკაციის სლოტის მალე წაშლა WAL ფაილების მორჩენის თავიდან ასაცილებლად." -#: pg_createsubscriber.c:286 +#: pg_createsubscriber.c:285 #, c-format msgid "" "%s creates a new logical replica from a standby server.\n" @@ -1376,7 +1376,7 @@ msgstr "" "%s შექმნის ახალ ლოგიკური რეპლიკას უქმე სერვერიდან.\n" "\n" -#: pg_createsubscriber.c:290 pg_receivewal.c:81 pg_recvlogical.c:92 +#: pg_createsubscriber.c:289 pg_receivewal.c:81 pg_recvlogical.c:92 #, c-format msgid "" "\n" @@ -1385,7 +1385,7 @@ msgstr "" "\n" "პარამეტრები:\n" -#: pg_createsubscriber.c:291 +#: pg_createsubscriber.c:290 #, c-format msgid "" " -a, --all create subscriptions for all databases except template\n" @@ -1394,62 +1394,62 @@ msgstr "" " -a, --all გამოწერების შექმნა ყველა მონაცემთა ბაზისთვის გარდა შაბლონი\n" " მონაცემთა ბაზების და მონაცემთა ბაზებისთვის, რომლებთანაც დაკავშირება აკრძალულია\n" -#: pg_createsubscriber.c:293 +#: pg_createsubscriber.c:292 #, c-format msgid " -d, --database=DBNAME database in which to create a subscription\n" msgstr " -d, --database=ბაზისსახელი მონაცემთა ბაზა, რომელშიც გნებავთ, გამოწერა შექმნათ\n" -#: pg_createsubscriber.c:294 +#: pg_createsubscriber.c:293 #, c-format msgid " -D, --pgdata=DATADIR location for the subscriber data directory\n" msgstr " -D, --pgdata=DATADIR გამომწერის მონაცემების საქაღალდის მდებარეობა\n" -#: pg_createsubscriber.c:295 +#: pg_createsubscriber.c:294 #, c-format msgid " -l, --logdir=LOGDIR location for the log directory\n" msgstr " -l, --logdir=LOGDIR ჟურნალის საქაღალდის მდებარეობა\n" -#: pg_createsubscriber.c:296 +#: pg_createsubscriber.c:295 #, c-format msgid " -n, --dry-run dry run, just show what would be done\n" msgstr " -n, --dry-run განახლების გარეშე. უბრალოდ ნაჩვენები იქნება, რა მოხდებოდა\n" -#: pg_createsubscriber.c:297 +#: pg_createsubscriber.c:296 #, c-format msgid " -p, --subscriber-port=PORT subscriber port number (default %s)\n" msgstr " -p, --subscriber-port=პორტი გამომწერის პორტის ნომერი (ნაგულისხმევი %s)\n" -#: pg_createsubscriber.c:298 +#: pg_createsubscriber.c:297 #, c-format msgid " -P, --publisher-server=CONNSTR publisher connection string\n" msgstr " -P, --publisher-server=CONNSTR გამომცემელთან მიერთების სტრიქონი\n" -#: pg_createsubscriber.c:299 +#: pg_createsubscriber.c:298 #, c-format msgid " -s, --socketdir=DIR socket directory to use (default current dir.)\n" msgstr " -s, --socketdir=DIR სოკეტის საქაღალდე (ნაგულისხმევია მიმდინარე.)\n" -#: pg_createsubscriber.c:300 +#: pg_createsubscriber.c:299 #, c-format msgid " -t, --recovery-timeout=SECS seconds to wait for recovery to end\n" msgstr " -t, --recovery-timeout=წამები რამდენი წამი დაველოდო აღდგენის დასრულებას\n" -#: pg_createsubscriber.c:301 +#: pg_createsubscriber.c:300 #, c-format msgid " -T, --enable-two-phase enable two-phase commit for all subscriptions\n" msgstr " -T, --enable-two-phase ორფაზიანი კომიტების ჩართვა ყველა გამოწერისთვის\n" -#: pg_createsubscriber.c:302 +#: pg_createsubscriber.c:301 #, c-format msgid " -U, --subscriber-username=NAME user name for subscriber connection\n" msgstr " -U, --subscriber-username=სახელი მომხმარებლის სახელი გამომწერის კავშირისთვის\n" -#: pg_createsubscriber.c:303 +#: pg_createsubscriber.c:302 #, c-format msgid " -v, --verbose output verbose messages\n" msgstr " -v, --verbose დამატებითი ინფორმაციის გამოტანა\n" -#: pg_createsubscriber.c:304 +#: pg_createsubscriber.c:303 #, c-format msgid "" " --clean=OBJECTTYPE drop all objects of the specified type from specified\n" @@ -1458,7 +1458,7 @@ msgstr "" " --clean=ობიექტისტიპი წაშლის მითითებული ტიპის ყველა ობიექტს მითითებული\n" " მონაცემთა ბაზებიდან გამომწერზე. იღებს: \"%s\"\n" -#: pg_createsubscriber.c:306 +#: pg_createsubscriber.c:305 #, c-format msgid "" " --config-file=FILENAME use specified main server configuration\n" @@ -1467,678 +1467,674 @@ msgstr "" " --config-file=FILENAME სამიზნე კლასტერის გაშვებისას მთავარი \n" " სერვერის მითითებული კონფიგურაციის ფაილის გამოყენება\n" -#: pg_createsubscriber.c:308 +#: pg_createsubscriber.c:307 #, c-format msgid " --publication=NAME publication name\n" msgstr " --publication=NAME პუბლიკაციის სახელი\n" -#: pg_createsubscriber.c:309 +#: pg_createsubscriber.c:308 #, c-format msgid " --replication-slot=NAME replication slot name\n" msgstr " --replication-slot=სახელი რეპლიკაციის სლოტის სახელი\n" -#: pg_createsubscriber.c:310 +#: pg_createsubscriber.c:309 #, c-format msgid " --subscription=NAME subscription name\n" msgstr " --subscription=NAME გამოწერის სახელი\n" -#: pg_createsubscriber.c:311 +#: pg_createsubscriber.c:310 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version ვერსიის ინფორმაციის გამოტანა და გასვლა\n" -#: pg_createsubscriber.c:312 +#: pg_createsubscriber.c:311 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ამ დახმარების ჩვენება და გასვლა\n" -#: pg_createsubscriber.c:355 +#: pg_createsubscriber.c:354 #, c-format msgid "could not parse connection string: %s" msgstr "შეერთების სტრიქონის დამუშავების შეცდომა: %s" -#: pg_createsubscriber.c:432 +#: pg_createsubscriber.c:431 #, c-format msgid "program \"%s\" is needed by %s but was not found in the same directory as \"%s\"" msgstr "პროგრამა \"%s\" სჭირდება \"%s\"-ს, მაგრამ იგივე საქაღალდეში, სადაც \"%s\", ნაპოვნი არაა" -#: pg_createsubscriber.c:435 +#: pg_createsubscriber.c:434 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "პროგრამა „%s“ ნაპოვნია „%s“-ის მიერ, მაგრამ ვერსია, იგივეა არაა, რაც %s" -#: pg_createsubscriber.c:456 +#: pg_createsubscriber.c:455 #, c-format msgid "checking if directory \"%s\" is a cluster data directory" msgstr "შემოწმება, არის თუ არა საქაღალდე \"%s\" კლასტერის მონაცემების საქაღალდე" -#: pg_createsubscriber.c:462 +#: pg_createsubscriber.c:461 #, c-format msgid "data directory \"%s\" does not exist" msgstr "მონაცემების საქაღალდე არ არსებობს: \"%s\"" -#: pg_createsubscriber.c:475 +#: pg_createsubscriber.c:474 #, c-format msgid "data directory is of wrong version" msgstr "მონაცემების საქაღალდე არასწორ ვერსიას ეკუთვნის" -#: pg_createsubscriber.c:476 +#: pg_createsubscriber.c:475 #, c-format msgid "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\"." msgstr "ფაილი \"%s\" შეიცავს \"%s\"-ს, რომელიც ამ პროგრამის ვერსიასთან (%s) შეუთავსებელია." -#: pg_createsubscriber.c:595 +#: pg_createsubscriber.c:594 #, c-format msgid "connection to database failed: %s" msgstr "მონაცემთა ბაზასთან მიერთება ჩავარდა: %s" -#: pg_createsubscriber.c:608 streamutil.c:230 +#: pg_createsubscriber.c:607 streamutil.c:230 #, c-format msgid "could not clear \"search_path\": %s" msgstr "\"search_path\"-ის გასუფთავების პრობლემა: %s" -#: pg_createsubscriber.c:648 +#: pg_createsubscriber.c:647 #, c-format msgid "getting system identifier from publisher" msgstr "სისტემური იდენტიფიკატორის მიღება გამომცემლისგან" -#: pg_createsubscriber.c:655 +#: pg_createsubscriber.c:654 #, c-format msgid "could not get system identifier: %s" msgstr "ვერ მივიღე სისტემის იდენტიფიკატორი: %s" -#: pg_createsubscriber.c:661 +#: pg_createsubscriber.c:660 #, c-format msgid "could not get system identifier: got %d rows, expected %d row" msgstr "სისტემური იდენტიფიკატორის მიღება შეუძლებელია: მივიღე %d მწკრივი. მოველოდი %d მწკრივს" -#: pg_createsubscriber.c:668 +#: pg_createsubscriber.c:667 #, c-format msgid "system identifier is % on publisher" msgstr "სისტემური იდენტიფიკატორი % გამომცემელზეა" -#: pg_createsubscriber.c:688 +#: pg_createsubscriber.c:687 #, c-format msgid "getting system identifier from subscriber" msgstr "სისტემური იდენტიფიკატორის მიღება გამომწერისგან" -#: pg_createsubscriber.c:692 pg_createsubscriber.c:722 +#: pg_createsubscriber.c:691 pg_createsubscriber.c:721 #, c-format msgid "control file appears to be corrupt" msgstr "როგორც ჩანს, საკონტროლო ფაილი დაზიანებულია" -#: pg_createsubscriber.c:696 pg_createsubscriber.c:740 +#: pg_createsubscriber.c:695 pg_createsubscriber.c:739 #, c-format msgid "system identifier is % on subscriber" msgstr "სისტემური იდენტიფიკატორი % გამომწერზეა" -#: pg_createsubscriber.c:718 +#: pg_createsubscriber.c:717 #, c-format msgid "modifying system identifier of subscriber" msgstr "გამომწერის სისტემური იდენტიფიკატორის შეცვლა" -#: pg_createsubscriber.c:735 +#: pg_createsubscriber.c:734 #, c-format msgid "dry-run: would set system identifier to % on subscriber" msgstr "მშრალი გაშვება: დააყენებს სისტემური იდენტიფიკატორს % გამომწერზე" -#: pg_createsubscriber.c:745 +#: pg_createsubscriber.c:744 #, c-format msgid "dry-run: would run pg_resetwal on the subscriber" msgstr "მშრალი გაშვება: pg_resetwal-ის გაშვება გამომწერზე" -#: pg_createsubscriber.c:747 +#: pg_createsubscriber.c:746 #, c-format msgid "running pg_resetwal on the subscriber" msgstr "pg_resetwal-ის გაშვება გამომწერზე" -#: pg_createsubscriber.c:771 +#: pg_createsubscriber.c:770 #, c-format msgid "successfully reset WAL on the subscriber" msgstr "WAL-ის ჩამოყრა წარმატებულია გამომწერზე" -#: pg_createsubscriber.c:773 +#: pg_createsubscriber.c:772 #, c-format msgid "could not reset WAL on subscriber: %s" msgstr "WAL-ის ჩამოყრა შეუძლებელია გამომწერზე: %s" -#: pg_createsubscriber.c:798 +#: pg_createsubscriber.c:797 #, c-format msgid "could not obtain database OID: %s" msgstr "ვერ მივიღე მონაცემთა ბაზის OID: %s" -#: pg_createsubscriber.c:805 +#: pg_createsubscriber.c:804 #, c-format msgid "could not obtain database OID: got %d rows, expected %d row" msgstr "ვერ მივიღე მონაცემთა ბაზის OID: მივიღე %d მწკრივი, მოველოდი %d მწკრივს" -#: pg_createsubscriber.c:846 +#: pg_createsubscriber.c:845 #, c-format msgid "could not find publication \"%s\" in database \"%s\": %s" msgstr "ვერ ვიპოვე გამოცემა \"%s\" მონაცემთა ბაზაში \"%s\": %s" -#: pg_createsubscriber.c:900 +#: pg_createsubscriber.c:899 #, c-format msgid "using existing publication \"%s\" in database \"%s\"" msgstr "გამოიყენება არსებული გამოცემა \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:939 +#: pg_createsubscriber.c:938 #, c-format msgid "could not write an additional WAL record: %s" msgstr "ვერ ჩავწერე დამატებითი WAL ჩანაწერი: %s" -#: pg_createsubscriber.c:965 +#: pg_createsubscriber.c:964 #, c-format msgid "could not obtain recovery progress: %s" msgstr "აღდგენის მიმდინარეობის მდგომარეობის მიღება შეუძლებელია: %s" -#: pg_createsubscriber.c:1030 +#: pg_createsubscriber.c:1029 #, c-format msgid "checking settings on publisher" msgstr "პარამეტრების შექმნა გამომცემელზე" -#: pg_createsubscriber.c:1040 +#: pg_createsubscriber.c:1039 #, c-format msgid "primary server cannot be in recovery" msgstr "ძირითადი სერვერი აღდგენის რეჟიმში ვერ იქნება" -#: pg_createsubscriber.c:1066 +#: pg_createsubscriber.c:1065 #, c-format msgid "could not obtain publisher settings: %s" msgstr "გამომცემლის პარამეტრების მიღება შეუძლებელია: %s" -#: pg_createsubscriber.c:1095 +#: pg_createsubscriber.c:1094 #, c-format msgid "publisher requires \"wal_level\" >= \"replica\"" msgstr "გამომცემელს სჭირდება \"wal_level\" >= \"replica\"" -#: pg_createsubscriber.c:1101 +#: pg_createsubscriber.c:1100 #, c-format msgid "publisher requires %d replication slots, but only %d remain" msgstr "გამომცემელს %d რეპლიკაციის სლოტი სჭირდება, მაგრამ დარჩენილია, მხოლოდ, %d" -#: pg_createsubscriber.c:1103 pg_createsubscriber.c:1112 -#: pg_createsubscriber.c:1222 pg_createsubscriber.c:1231 -#: pg_createsubscriber.c:1240 +#: pg_createsubscriber.c:1102 pg_createsubscriber.c:1111 +#: pg_createsubscriber.c:1221 pg_createsubscriber.c:1230 +#: pg_createsubscriber.c:1239 #, c-format msgid "Increase the configuration parameter \"%s\" to at least %d." msgstr "გაზარდეთ კონფიგურაციის პარამეტრი \"%s\" %d-მდე მაინც." -#: pg_createsubscriber.c:1110 +#: pg_createsubscriber.c:1109 #, c-format msgid "publisher requires %d WAL sender processes, but only %d remain" msgstr "გამომცემელს %d WAL-ის გამგზავნი პროცესი სჭირდება, მაგრამ დარჩენილია, მხოლოდ, %d" -#: pg_createsubscriber.c:1119 +#: pg_createsubscriber.c:1118 #, c-format msgid "two_phase option will not be enabled for replication slots" msgstr "პარამეტრი two_phase რეპლიკაციის სლოტებისთვის არ ჩაირთვება" -#: pg_createsubscriber.c:1120 +#: pg_createsubscriber.c:1119 #, c-format msgid "Subscriptions will be created with the two_phase option disabled. Prepared transactions will be replicated at COMMIT PREPARED." msgstr "გამოწერები two_phase პარამეტრით გათიშული შეიქმნება. მომზადებული ტრანზაქციების რეპლიკაცია მოხდება COMMIT PREPARED-თან." -#: pg_createsubscriber.c:1122 +#: pg_createsubscriber.c:1121 #, c-format msgid "You can use the command-line option --enable-two-phase to enable two_phase." msgstr "'two_phase'-ის ჩასართავად, შეგიძლიათ, გამოიყენოთ ბრძანების სტრიქონის პარამეტრი --enable-two-phase." -#: pg_createsubscriber.c:1132 +#: pg_createsubscriber.c:1131 #, c-format msgid "required WAL could be removed from the publisher" msgstr "აუცილებელი WAL-ის წაშლა შესაძლებელია გამომცემლიდან" -#: pg_createsubscriber.c:1133 +#: pg_createsubscriber.c:1132 #, c-format msgid "Set the configuration parameter \"%s\" to -1 to ensure that required WAL files are not prematurely removed." msgstr "დააყენეთ კონფიგურაციის პარამეტრი \"%s\" მნიშვნელობაზე -1, რომ დარწმუნდეთ, რომ WAL ფაილები საჭიროზე ადრე არ წაიშლება." -#: pg_createsubscriber.c:1165 +#: pg_createsubscriber.c:1164 #, c-format msgid "checking settings on subscriber" msgstr "პარამეტრების შემოწმება გამომწერზე" -#: pg_createsubscriber.c:1172 +#: pg_createsubscriber.c:1171 #, c-format msgid "target server must be a standby" msgstr "სამიზნე სერვერი უქმე უნდა იყოს" -#: pg_createsubscriber.c:1196 +#: pg_createsubscriber.c:1195 #, c-format msgid "could not obtain subscriber settings: %s" msgstr "გამომწერის პარამეტრების მიღება შეუძლებელია: %s" -#: pg_createsubscriber.c:1220 +#: pg_createsubscriber.c:1219 #, c-format msgid "subscriber requires %d active replication origins, but only %d remain" msgstr "გამომწერს %d აქტიური რეპლიკაციის წყარო სჭირდება, მაგრამ დარჩენილია, მხოლოდ, %d" -#: pg_createsubscriber.c:1229 +#: pg_createsubscriber.c:1228 #, c-format msgid "subscriber requires %d logical replication workers, but only %d remain" msgstr "გამომწერს %d ლოგიკური რეპლიკაციის დამხმარე პროცესი სჭირდება, მაგრამ დარჩენილია, მხოლოდ, %d" -#: pg_createsubscriber.c:1238 +#: pg_createsubscriber.c:1237 #, c-format msgid "subscriber requires %d worker processes, but only %d remain" msgstr "გამომწერს %d დამხმარე პროცესი სჭირდება, მაგრამ დარჩენილია, მხოლოდ, %d" -#: pg_createsubscriber.c:1279 +#: pg_createsubscriber.c:1278 #, c-format msgid "dry-run: would drop subscription \"%s\" in database \"%s\"" msgstr "მშრალი გაშვება: მოხდება მოცილება გამოწერისა \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:1283 +#: pg_createsubscriber.c:1282 #, c-format msgid "dropping subscription \"%s\" in database \"%s\"" msgstr "მოხდება მოცილება გამოწერისა \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:1290 +#: pg_createsubscriber.c:1289 #, c-format msgid "could not drop subscription \"%s\": %s" msgstr "ვერ მოვაცილე გამოწერა \"%s\": %s" -#: pg_createsubscriber.c:1325 +#: pg_createsubscriber.c:1324 #, c-format msgid "could not obtain pre-existing subscriptions: %s" msgstr "ვერ მივიღე უკვე არსებული გამოწერები: %s" -#: pg_createsubscriber.c:1491 +#: pg_createsubscriber.c:1490 #, c-format msgid "could not drop replication slot \"%s\" on primary" msgstr "ვერ წავშალე რეპლიკაციის სლოტი \"%s\" ძირითადზე" -#: pg_createsubscriber.c:1525 +#: pg_createsubscriber.c:1524 #, c-format msgid "could not obtain failover replication slot information: %s" msgstr "გადასართველი რეპლიკაციის სლოტის ინფორმაციის მიღება შეუძლებელია: %s" -#: pg_createsubscriber.c:1527 pg_createsubscriber.c:1536 +#: pg_createsubscriber.c:1526 pg_createsubscriber.c:1535 #, c-format msgid "Drop the failover replication slots on subscriber soon to avoid retention of WAL files." msgstr "გამომწერზე გადასართველი რეპლიკაციის სლოტების მალე წაშლა WAL ფაილების მორჩენის თავიდან ასაცილებლად." -#: pg_createsubscriber.c:1535 +#: pg_createsubscriber.c:1534 #, c-format msgid "could not drop failover replication slot" msgstr "გადასართველი რეპლიკაციის სლოტი წაშლა შეუძლებელია" -#: pg_createsubscriber.c:1558 +#: pg_createsubscriber.c:1557 #, c-format msgid "dry-run: would create the replication slot \"%s\" in database \"%s\" on publisher" msgstr "მშრალი გაშვება: შექმნის რეპლიკაციის სლოტს \"%s\" მონაცემთა ბაზაში \"%s\" გამომცემელზე" -#: pg_createsubscriber.c:1561 +#: pg_createsubscriber.c:1560 #, c-format msgid "creating the replication slot \"%s\" in database \"%s\" on publisher" msgstr "იქმნება რეპლიკაციის სლოტი \"%s\" მონაცემთა ბაზაში \"%s\" გამომცემელზე" -#: pg_createsubscriber.c:1580 +#: pg_createsubscriber.c:1579 #, c-format msgid "could not create replication slot \"%s\" in database \"%s\": %s" msgstr "ვერ შევქმენი რეპლიკაციის სლოტი \"%s\" მონაცემთა ბაზაში \"%s\": %s" -#: pg_createsubscriber.c:1611 +#: pg_createsubscriber.c:1610 #, c-format msgid "dry-run: would drop the replication slot \"%s\" in database \"%s\"" msgstr "მშრალი გაშვება: წაიშლება რეპლიკაციის სლოტი \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:1614 +#: pg_createsubscriber.c:1613 #, c-format msgid "dropping the replication slot \"%s\" in database \"%s\"" msgstr "იშლება რეპლიკაციის სლოტი \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:1630 +#: pg_createsubscriber.c:1629 #, c-format msgid "could not drop replication slot \"%s\" in database \"%s\": %s" msgstr "ვერ წავშალე რეპლიკაციის სლოტი \"%s\" მონაცემთა ბაზაში \"%s\": %s" -#: pg_createsubscriber.c:1651 +#: pg_createsubscriber.c:1649 #, c-format msgid "pg_ctl failed with exit code %d" msgstr "pg_ctl ჩავარდა გამოსვლის კოდით %d" -#: pg_createsubscriber.c:1656 +#: pg_createsubscriber.c:1654 #, c-format msgid "pg_ctl was terminated by exception 0x%X" msgstr "pg_ctl შეწყდა გამონაკლისით 0x%X" -#: pg_createsubscriber.c:1658 +#: pg_createsubscriber.c:1656 #, c-format msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." msgstr "თექვსმეტობითი მნიშვნელობის აღწერისთვის იხილეთ C-ის ჩასასმელი ფაილი \"ntstatus.h\"." -#: pg_createsubscriber.c:1660 +#: pg_createsubscriber.c:1658 #, c-format msgid "pg_ctl was terminated by signal %d: %s" msgstr "pg_ctl შეწყვეტილია სიგნალით %d: %s" -#: pg_createsubscriber.c:1666 +#: pg_createsubscriber.c:1664 #, c-format msgid "pg_ctl exited with unrecognized status %d" msgstr "pg_ctl დასრულდა უცნობი სტატუსით %d" -#: pg_createsubscriber.c:1669 +#: pg_createsubscriber.c:1667 #, c-format msgid "The failed command was: %s" msgstr "ჩავარდნილი ბრძანება იყო: %s" -#: pg_createsubscriber.c:1722 +#: pg_createsubscriber.c:1720 #, c-format msgid "server was started" msgstr "სერვერი გაეშვა" -#: pg_createsubscriber.c:1737 +#: pg_createsubscriber.c:1735 #, c-format msgid "server was stopped" msgstr "სერვერი გამოირთო" -#: pg_createsubscriber.c:1756 +#: pg_createsubscriber.c:1754 #, c-format msgid "waiting for the target server to reach the consistent state" msgstr "სამიზნე სერვერის მდგრად მდგომარეობაში გადასვლის მოლოდინი" -#: pg_createsubscriber.c:1774 +#: pg_createsubscriber.c:1772 #, c-format msgid "recovery timed out" msgstr "აღდგენის მოლოდინის ვადა ამოიწურა" -#: pg_createsubscriber.c:1786 +#: pg_createsubscriber.c:1784 #, c-format msgid "server did not end recovery" msgstr "სერვერმა აღდგენა არ დაამთავრა" -#: pg_createsubscriber.c:1788 +#: pg_createsubscriber.c:1786 #, c-format msgid "target server reached the consistent state" msgstr "სამიზნე სერვერმა მიაღწია მდგრად მდგომარეობას" -#: pg_createsubscriber.c:1789 +#: pg_createsubscriber.c:1787 #, c-format msgid "If pg_createsubscriber fails after this point, you must recreate the physical replica before continuing." msgstr "თუ ამ წერტილის შემდეგ pg_createsubscriber ჩავარდება, გაგრძელებამდე ფიზიკური რეპლიკა თავიდან უნდა შექმნათ." -#: pg_createsubscriber.c:1816 pg_createsubscriber.c:1946 +#: pg_createsubscriber.c:1814 pg_createsubscriber.c:1942 #, c-format msgid "could not obtain publication information: %s" msgstr "გამოცემის ინფორმაციის მიღება შეუძლებელია: %s" -#: pg_createsubscriber.c:1830 +#: pg_createsubscriber.c:1828 #, c-format msgid "publication \"%s\" already exists" msgstr "პუბლიკაცია \"%s\" უკვე არსებობს" -#: pg_createsubscriber.c:1831 +#: pg_createsubscriber.c:1829 #, c-format msgid "Consider renaming this publication before continuing." msgstr "განიხილეთ ამ პუბლიკაციის სახელის გადარქმევა ხელახლა ცდამდე." -#: pg_createsubscriber.c:1839 +#: pg_createsubscriber.c:1837 #, c-format msgid "dry-run: would create publication \"%s\" in database \"%s\"" msgstr "მშრალი გაშვება: შექმნის გამოცემას \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:1842 +#: pg_createsubscriber.c:1840 #, c-format msgid "creating publication \"%s\" in database \"%s\"" msgstr "იქმნება გამოცემა \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:1855 +#: pg_createsubscriber.c:1853 #, c-format msgid "could not create publication \"%s\" in database \"%s\": %s" msgstr "ვერ შევქმენი გამოცემა \"%s\" მონაცემთა ბაზაში \"%s\": %s" -#: pg_createsubscriber.c:1886 +#: pg_createsubscriber.c:1883 #, c-format msgid "dry-run: would drop publication \"%s\" in database \"%s\"" msgstr "მშრალი გაშვება: წაშლის გამოცემას \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:1889 +#: pg_createsubscriber.c:1886 #, c-format msgid "dropping publication \"%s\" in database \"%s\"" msgstr "ვშლი გამოცემას \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:1903 +#: pg_createsubscriber.c:1900 #, c-format msgid "could not drop publication \"%s\" in database \"%s\": %s" msgstr "ვერ წავშალე გამოცემა \"%s\" მონაცემთა ბაზაში \"%s\": %s" -#: pg_createsubscriber.c:1939 +#: pg_createsubscriber.c:1935 #, c-format msgid "dropping all existing publications in database \"%s\"" msgstr "ვშლი ყველა არსებულ გამოცემას მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:1970 +#: pg_createsubscriber.c:1964 #, c-format msgid "dry-run: would preserve existing publication \"%s\" in database \"%s\"" msgstr "მშრალი გაშვება: შეინარჩუნებს არსებულ გამოცემას \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:1973 +#: pg_createsubscriber.c:1967 #, c-format msgid "preserving existing publication \"%s\" in database \"%s\"" msgstr "არსებული გამოცემა \"%s\" შენარჩუნდება მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:2008 +#: pg_createsubscriber.c:2002 #, c-format msgid "dry-run: would create subscription \"%s\" in database \"%s\"" msgstr "მშრალი გაშვება: შექმნის გამოწერას \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:2011 +#: pg_createsubscriber.c:2005 #, c-format msgid "creating subscription \"%s\" in database \"%s\"" msgstr "იქმნება გამოწერა \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:2033 +#: pg_createsubscriber.c:2027 #, c-format msgid "could not create subscription \"%s\" in database \"%s\": %s" msgstr "ვერ შევქმენი გამოწერა \"%s\" მონაცემთა ბაზაში \"%s\": %s" -#: pg_createsubscriber.c:2078 +#: pg_createsubscriber.c:2072 #, c-format msgid "could not obtain subscription OID: %s" msgstr "ვერ მივიღე გამოწერის OID: %s" -#: pg_createsubscriber.c:2085 +#: pg_createsubscriber.c:2079 #, c-format msgid "could not obtain subscription OID: got %d rows, expected %d row" msgstr "ვერ მივიღე გამოწერის OID: მივიღე %d მწკრივი, მოველოდი %d მწკრივს" -#: pg_createsubscriber.c:2110 +#: pg_createsubscriber.c:2104 #, c-format msgid "dry-run: would set the replication progress (node name \"%s\", LSN %s) in database \"%s\"" msgstr "მშრალი გაშვება: დააყენებს რეპლიკაციის მიმდინარეობას (კვანძის სახელი \"%s\", LSN %s) მონაცემთა ბაზაზე \"%s\"" -#: pg_createsubscriber.c:2113 +#: pg_createsubscriber.c:2107 #, c-format msgid "setting the replication progress (node name \"%s\", LSN %s) in database \"%s\"" msgstr "რეპლიკაციის მიმდინარეობის (კვანძის სახელი \"%s\", LSN %s) დაყენება მონაცემთა ბაზაზე \"%s\"" -#: pg_createsubscriber.c:2128 +#: pg_createsubscriber.c:2122 #, c-format msgid "could not set replication progress for subscription \"%s\": %s" msgstr "შეუძლებელია რეპლიკაციის მიმდინარეობის დაყენება გამოწერისთვის \"%s\": %s" -#: pg_createsubscriber.c:2160 +#: pg_createsubscriber.c:2154 #, c-format msgid "dry-run: would enable subscription \"%s\" in database \"%s\"" msgstr "მშრალი გაშვება: ჩაირთვება გამოწერა \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:2163 +#: pg_createsubscriber.c:2157 #, c-format msgid "enabling subscription \"%s\" in database \"%s\"" msgstr "ჩაირთვება გამოწერა \"%s\" მონაცემთა ბაზაში \"%s\"" -#: pg_createsubscriber.c:2175 +#: pg_createsubscriber.c:2169 #, c-format msgid "could not enable subscription \"%s\": %s" msgstr "ვერ ჩავრთე გამოწერა \"%s\": %s" -#: pg_createsubscriber.c:2221 +#: pg_createsubscriber.c:2215 #, c-format msgid "could not obtain a list of databases: %s" msgstr "ვერ მივიღე მონაცემთა ბაზების სია: %s" -#: pg_createsubscriber.c:2327 +#: pg_createsubscriber.c:2321 #, c-format msgid "cannot be executed by \"root\"" msgstr "root-ით ვერ გაეშვება" -#: pg_createsubscriber.c:2328 +#: pg_createsubscriber.c:2322 #, c-format msgid "You must run %s as the PostgreSQL superuser." msgstr "%s PostgreSQL-ის ზემომხმარებლით უნდა გაუშვათ." -#: pg_createsubscriber.c:2351 +#: pg_createsubscriber.c:2345 #, c-format msgid "database \"%s\" specified more than once for -d/--database" msgstr "მონაცემთა ბაზა \"%s\" ერთზე მეტჯერაა მითითებული პარამეტრისთვის -d/--database" -#: pg_createsubscriber.c:2396 -#, c-format -msgid "publication \"%s\" specified more than once for --publication" -msgstr "პუბლიკაცია \"%s\" მითითებულია ერთზე მეტჯერ პარამეტრისთვის --publication" - -#: pg_createsubscriber.c:2405 +#: pg_createsubscriber.c:2394 #, c-format msgid "replication slot \"%s\" specified more than once for --replication-slot" msgstr "რეპლიკაციის სლოტი \"%s\" მითითებულია ერთზე მეტჯერ პარამეტრისთვის --repilication-slot" -#: pg_createsubscriber.c:2414 +#: pg_createsubscriber.c:2403 #, c-format msgid "subscription \"%s\" specified more than once for --subscription" msgstr "გამოწერა \"%s\" მითითებულია ერთზე მეტჯერ პარამეტრისთვის --subscription" -#: pg_createsubscriber.c:2420 +#: pg_createsubscriber.c:2409 #, c-format msgid "object type \"%s\" specified more than once for --clean" msgstr "პარამეტრისთვის --clean ობიექტის ტიპი \"%s\" ერთზე მეტჯერაა მითითებული" -#: pg_createsubscriber.c:2464 +#: pg_createsubscriber.c:2453 #, c-format msgid "no subscriber data directory specified" msgstr "გამომწერის მონაცემების საქაღალდე მითითებული არაა" -#: pg_createsubscriber.c:2475 +#: pg_createsubscriber.c:2464 #, c-format msgid "could not determine current directory" msgstr "მიმდინარე საქაღალდის იდენტიფიკაციის პრობლემა" -#: pg_createsubscriber.c:2492 +#: pg_createsubscriber.c:2481 #, c-format msgid "no publisher connection string specified" msgstr "გამომცემლის მიერთების სტრიქონი მითითებული არაა" -#: pg_createsubscriber.c:2520 pg_recvlogical.c:348 +#: pg_createsubscriber.c:2509 pg_recvlogical.c:352 #, c-format msgid "could not open log file \"%s\": %m" msgstr "ჟურნალის ფაილის გახსნის შეცდომა \"%s\": %m" -#: pg_createsubscriber.c:2528 +#: pg_createsubscriber.c:2518 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"The target directory will not be modified." -msgstr "" -"შესრულება მშრალი გაშვების რეჟიმში.\n" -"სამიზნე საქაღალდე არ შეიცვლება." +msgid "executing in dry-run mode" +msgstr "შესრულება მშრალი გაშვების რეჟიმში" -#: pg_createsubscriber.c:2531 +#: pg_createsubscriber.c:2519 +#, c-format +msgid "The target directory will not be modified." +msgstr "სამიზნე საქაღალდე არ შეიცვლება." + +#: pg_createsubscriber.c:2522 #, c-format msgid "validating publisher connection string" msgstr "გამომცემლის მიერთების სტრიქონის გადამოწმება" -#: pg_createsubscriber.c:2537 +#: pg_createsubscriber.c:2528 #, c-format msgid "validating subscriber connection string" msgstr "მიმდინარეობს გამომწერის დაკავშირების სტრიქონის გადამოწმება" -#: pg_createsubscriber.c:2554 +#: pg_createsubscriber.c:2545 #, c-format msgid "no database was specified" msgstr "ბაზა მითითებული არაა" -#: pg_createsubscriber.c:2565 +#: pg_createsubscriber.c:2556 #, c-format msgid "database name \"%s\" was extracted from the publisher connection string" msgstr "ბაზა \"%s\" გამოღებულია გამომცემლის მიერთების სტრიქონიდან" -#: pg_createsubscriber.c:2570 +#: pg_createsubscriber.c:2561 #, c-format msgid "no database name specified" msgstr "ბაზის სახელი მითითებული არაა" -#: pg_createsubscriber.c:2580 +#: pg_createsubscriber.c:2571 #, c-format msgid "wrong number of publication names specified" msgstr "მითითებულია გამოცემის სახელების არასწორი რაოდენობა" -#: pg_createsubscriber.c:2581 +#: pg_createsubscriber.c:2572 #, c-format msgid "The number of specified publication names (%d) must match the number of specified database names (%d)." msgstr "გამოცემის სახელების რაოდენობა (%d) ბაზის სახელების მითითებულ რაოდენობას (%d) უნდა ემთხვეოდეს." -#: pg_createsubscriber.c:2587 +#: pg_createsubscriber.c:2578 #, c-format msgid "wrong number of subscription names specified" msgstr "მითითებულია გამოწერის სახელების არასწორი რაოდენობა" -#: pg_createsubscriber.c:2588 +#: pg_createsubscriber.c:2579 #, c-format msgid "The number of specified subscription names (%d) must match the number of specified database names (%d)." msgstr "მითითებული გამოწერის სახელების რაოდენობა (%d) მითითებული ბაზის სახელების რაოდენობას (%d) უნდა ემთხვეოდეს." -#: pg_createsubscriber.c:2594 +#: pg_createsubscriber.c:2585 #, c-format msgid "wrong number of replication slot names specified" msgstr "მითითებულია რეპლიკაციის სლოტის სახელების არასწორი რაოდენობა" -#: pg_createsubscriber.c:2595 +#: pg_createsubscriber.c:2586 #, c-format msgid "The number of specified replication slot names (%d) must match the number of specified database names (%d)." msgstr "რეპლიკაციის სლოტების მითითებული სახელების რაოდენობა (%d) ბაზის სახელების მითითებულ რაოდენობას (%d) უნდა ემთხვეოდეს." -#: pg_createsubscriber.c:2607 +#: pg_createsubscriber.c:2598 #, c-format msgid "invalid object type \"%s\" specified for option %s" msgstr "პარამეტრისთვის %2$s-ისთვის მითითებულია არასწორი ობიექტის ტიპი \"%1$s\"" -#: pg_createsubscriber.c:2609 +#: pg_createsubscriber.c:2600 #, c-format msgid "The valid value is: \"%s\"" msgstr "სწორი მნიშვნელობაა: \"%s\"" -#: pg_createsubscriber.c:2640 +#: pg_createsubscriber.c:2631 #, c-format msgid "subscriber data directory is not a copy of the source database cluster" msgstr "გამომწერის მონაცემების საქაღალდე წყარო ბაზის კლასტერის ასლი არაა" -#: pg_createsubscriber.c:2653 +#: pg_createsubscriber.c:2644 #, c-format msgid "standby server is running" msgstr "უქმე სერვერი გაშვებულია" -#: pg_createsubscriber.c:2654 +#: pg_createsubscriber.c:2645 #, c-format msgid "Stop the standby server and try again." msgstr "გააჩერეთ უქმე სერვერი და თავიდან სცადეთ." -#: pg_createsubscriber.c:2663 +#: pg_createsubscriber.c:2654 #, c-format msgid "starting the standby server with command-line options" msgstr "მიმდინარეობს უქმე სერვერის გაშვება ბრძანების სტრიქონის პარამეტრებით" -#: pg_createsubscriber.c:2679 pg_createsubscriber.c:2714 +#: pg_createsubscriber.c:2670 pg_createsubscriber.c:2705 #, c-format msgid "stopping the subscriber" msgstr "გამომწერის გაჩერება" -#: pg_createsubscriber.c:2693 +#: pg_createsubscriber.c:2684 #, c-format msgid "starting the subscriber" msgstr "გამომწერის გაშვება" -#: pg_createsubscriber.c:2722 +#: pg_createsubscriber.c:2713 #, c-format msgid "Done!" msgstr "შესრულებულია!" @@ -2234,7 +2230,7 @@ msgstr "ჟურნალის ნაკადი შეჩერდა მი msgid "switched to timeline %u at %X/%08X" msgstr "გადავერთე დროის ხაზზე %u მისამართზე %X/%08X" -#: pg_receivewal.c:224 pg_recvlogical.c:1082 +#: pg_receivewal.c:224 pg_recvlogical.c:1086 #, c-format msgid "received interrupt signal, exiting" msgstr "მიღებულია შეწყვეტის სიგნალი. გამოსვლა" @@ -2304,7 +2300,7 @@ msgstr "ფაილის (%s) შემოწმება შეუძლე msgid "starting log streaming at %X/%08X (timeline %u)" msgstr "ჟურნალის ნაკადი დაიწყო მისამართზე %X/%08X (დროის ხაზი %u)" -#: pg_receivewal.c:693 pg_recvlogical.c:807 +#: pg_receivewal.c:693 pg_recvlogical.c:811 #, c-format msgid "could not parse end position \"%s\"" msgstr "ბოლო პოზიციის დამუშავების შეცდომა: %s" @@ -2334,23 +2330,23 @@ msgstr "%s-სთან დაკავშირების მხარდა msgid "replication connection using slot \"%s\" is unexpectedly database specific" msgstr "რეპლიკაციის შეერთება სლოტით \"%s\" მოულოდნელად ბაზაზეა დამოკიდებული" -#: pg_receivewal.c:878 pg_recvlogical.c:991 +#: pg_receivewal.c:878 pg_recvlogical.c:995 #, c-format msgid "dropping replication slot \"%s\"" msgstr "რეპლიკაციის სლოტის წაშლა: %s" -#: pg_receivewal.c:889 pg_recvlogical.c:1001 +#: pg_receivewal.c:889 pg_recvlogical.c:1005 #, c-format msgid "creating replication slot \"%s\"" msgstr "რეპლიკაციის სლოტის შექმნა \"%s\"" -#: pg_receivewal.c:918 pg_recvlogical.c:1035 +#: pg_receivewal.c:918 pg_recvlogical.c:1039 #, c-format msgid "disconnected" msgstr "გათიშულია" #. translator: check source for value for %d -#: pg_receivewal.c:922 pg_recvlogical.c:1040 +#: pg_receivewal.c:922 pg_recvlogical.c:1044 #, c-format msgid "disconnected; waiting %d seconds to try again" msgstr "გათიშულია; თავიდან ცდამდე დაყოვნება %d წამია" @@ -2458,103 +2454,103 @@ msgstr "უკუკავშირის პაკეტის გაგზა msgid "starting log streaming at %X/%08X (slot %s)" msgstr "ჟურნალის ნაკადის დაწყება მისამართზე %X/%08X (სლოტი %s)" -#: pg_recvlogical.c:287 +#: pg_recvlogical.c:291 #, c-format msgid "streaming initiated" msgstr "ნაკადი ინიცირებულია" -#: pg_recvlogical.c:377 receivelog.c:890 +#: pg_recvlogical.c:381 receivelog.c:896 #, c-format msgid "invalid socket: %s" msgstr "არასწორი სოკეტი: %s" -#: pg_recvlogical.c:430 receivelog.c:918 +#: pg_recvlogical.c:434 receivelog.c:924 #, c-format msgid "%s() failed: %m" msgstr "%s()-ის შეცდომა: %m" -#: pg_recvlogical.c:437 receivelog.c:967 +#: pg_recvlogical.c:441 receivelog.c:973 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "\"WAL\" ნაკადიდან მონაცემების მიღების შეცდომა: %s" -#: pg_recvlogical.c:479 pg_recvlogical.c:530 receivelog.c:1011 -#: receivelog.c:1074 +#: pg_recvlogical.c:483 pg_recvlogical.c:534 receivelog.c:1017 +#: receivelog.c:1080 #, c-format msgid "streaming header too small: %d" msgstr "ნაკადის თავსართი ძალიან პატარაა: %d" -#: pg_recvlogical.c:514 receivelog.c:847 +#: pg_recvlogical.c:518 receivelog.c:853 #, c-format msgid "unrecognized streaming header: \"%c\"" msgstr "ნაკადის უცნობი თავსართი: \"%c\"" -#: pg_recvlogical.c:568 pg_recvlogical.c:580 +#: pg_recvlogical.c:572 pg_recvlogical.c:584 #, c-format msgid "could not write %d bytes to log file \"%s\": %m" msgstr "%d ბაიტის ჩაწერის შეცდომა ჟურნალის ფაილში \"%s\": %m" -#: pg_recvlogical.c:638 receivelog.c:642 receivelog.c:679 +#: pg_recvlogical.c:642 receivelog.c:648 receivelog.c:685 #, c-format msgid "unexpected termination of replication stream: %s" msgstr "რეპლიკაციის ნაკადის მოულოდნელი დასასრული: %s" -#: pg_recvlogical.c:802 +#: pg_recvlogical.c:806 #, c-format msgid "could not parse start position \"%s\"" msgstr "საწყისი მდებარეობის დამუშავების შეცდომა: %s" -#: pg_recvlogical.c:880 +#: pg_recvlogical.c:884 #, c-format msgid "no slot specified" msgstr "სლოტი მითითებული არაა" -#: pg_recvlogical.c:887 +#: pg_recvlogical.c:891 #, c-format msgid "no target file specified" msgstr "სამიზნე ფაილი მითითებული არაა" -#: pg_recvlogical.c:894 +#: pg_recvlogical.c:898 #, c-format msgid "no database specified" msgstr "ბაზა მითითებული არაა" -#: pg_recvlogical.c:901 +#: pg_recvlogical.c:905 #, c-format msgid "at least one action needs to be specified" msgstr "საჭიროა, სულ ცოტა, ერთი ქმედების მითითება" -#: pg_recvlogical.c:908 +#: pg_recvlogical.c:912 #, c-format msgid "cannot use --create-slot or --start together with --drop-slot" msgstr "--create-slot -ს და ---start-ს -drop-slot -თან ერთად ვერ გამოიყენებთ" -#: pg_recvlogical.c:915 +#: pg_recvlogical.c:919 #, c-format msgid "cannot use --create-slot or --drop-slot together with --startpos" msgstr "--create-slot -ს და --drop-slot-ს --startpos -თან ერთად ვერ გამოიყენებთ" -#: pg_recvlogical.c:922 +#: pg_recvlogical.c:926 #, c-format msgid "--endpos may only be specified with --start" msgstr "--endpos -ის მითითება მხოლოდ --start -თან ერთად შეიძლება" -#: pg_recvlogical.c:931 pg_recvlogical.c:938 +#: pg_recvlogical.c:935 pg_recvlogical.c:942 #, c-format msgid "%s may only be specified with --create-slot" msgstr "%s-ის მითითება, მხოლოდ, --create-slot -თან ერთად შეიძლება" -#: pg_recvlogical.c:975 +#: pg_recvlogical.c:979 #, c-format msgid "could not establish database-specific replication connection" msgstr "ბაზაზე-დამოკიდებული რეპლიკაციის შეერთების დამყარების შეცდომა" -#: pg_recvlogical.c:1085 +#: pg_recvlogical.c:1089 #, c-format msgid "end position %X/%08X reached by keepalive" msgstr "ბოლო მდებარეობა %X/%08X keepalive-ის მიერ მიღწეული" -#: pg_recvlogical.c:1090 +#: pg_recvlogical.c:1094 #, c-format msgid "end position %X/%08X reached by WAL record at %X/%08X" msgstr "ბოლო მდებარეობა %X/%08X WAL ჩანაწერის მიერ მიღწეულია მისამართზე %X/%08X" @@ -2601,7 +2597,7 @@ msgstr "წინასწარ-ჩაწერადი ჟურნალი msgid "not renaming \"%s\", segment is not complete" msgstr "\"%s\"-ის სახელი არ შეიცვლება. სეგმენტი დაუსრულებელია" -#: receivelog.c:227 receivelog.c:317 receivelog.c:688 +#: receivelog.c:227 receivelog.c:317 receivelog.c:694 #, c-format msgid "could not close file \"%s\": %s" msgstr "ფაილის (\"%s\") დახურვის შეცდომა: %s" @@ -2631,67 +2627,67 @@ msgstr "სერვერის შეუთავსებელი ვერ msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" msgstr "სერვერის შეუთავსებელი ვერსია %s: კლიენტს ნაკადის მხარდაჭერა სერვერებიდან, რომლის ვერსიაც მაღალია %s-ზე, არ გააჩნია" -#: receivelog.c:508 +#: receivelog.c:505 #, c-format msgid "system identifier does not match between base backup and streaming connection" msgstr "სისტემის იდენტიფიკატორი ბაზს მარქაფსა და ნაკადურ შეერთებას შორის არ ემთხვევა" -#: receivelog.c:516 +#: receivelog.c:513 #, c-format msgid "starting timeline %u is not present in the server" msgstr "დაწყების დროის ხაზი %u სერვერზე არ არსებობს" -#: receivelog.c:555 +#: receivelog.c:554 #, c-format msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" msgstr "მოულოდნელი პასუხი TIMELINE_HISTORY ბრძანებაზე: მივიღე %d მწკრივი და %d ველი, ველოდებოდი %d მწკრივს და %d ველს" -#: receivelog.c:626 +#: receivelog.c:632 #, c-format msgid "server reported unexpected next timeline %u, following timeline %u" msgstr "სერვერის პასუხში მოულოდნელი შემდეგი დროის ხაზია (%u), დროის ხაზის შემდეგ: %u" -#: receivelog.c:632 +#: receivelog.c:638 #, c-format msgid "server stopped streaming timeline %u at %X/%08X, but reported next timeline %u to begin at %X/%08X" msgstr "სერვერმა შეწყვიტა დროის ხაზის %u ნაკადი მისამართზე %X/%08X, მაგრამ მოიწერა, რომ შემდეგი დროის ხაზი %u მისამართზე %X/%08X იწყება" -#: receivelog.c:672 +#: receivelog.c:678 #, c-format msgid "replication stream was terminated before stop point" msgstr "რეპლიკაციის ნაკადი გაჩერების წერტილამდე შეწყდა" -#: receivelog.c:718 +#: receivelog.c:724 #, c-format msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" msgstr "მოულოდნელი შედეგების ნაკრები დროის-ხაზის-დამთავრების შემდეგ: მივიღე %d მწკრივი და %d ველი. მოველოდი %d მწკრივს და %d ველს" -#: receivelog.c:727 +#: receivelog.c:733 #, c-format msgid "could not parse next timeline's starting point \"%s\"" msgstr "შემდეგი დროის ხაზის დაწყების წერტილის (%s) დამუშავების შეცდომა" -#: receivelog.c:775 receivelog.c:1030 walmethods.c:1206 +#: receivelog.c:781 receivelog.c:1036 walmethods.c:1206 #, c-format msgid "could not fsync file \"%s\": %s" msgstr "ფაილის (\"%s\") fsync-ის შეცდომა: %s" -#: receivelog.c:1091 +#: receivelog.c:1097 #, c-format msgid "received write-ahead log record for offset %u with no file open" msgstr "მიღებულია წინასწარ-ჩაწერადი ჟურნალის ჩანაწერი წანაცვლებისთვის %u მაშინ, როცა ფაილები ღია არაა" -#: receivelog.c:1101 +#: receivelog.c:1107 #, c-format msgid "got WAL data offset %08x, expected %08x" msgstr "მიღებული WAL მონაცემის წანაცვლება %08x, მოველოდი %08x" -#: receivelog.c:1136 +#: receivelog.c:1142 #, c-format msgid "could not write %d bytes to WAL file \"%s\": %s" msgstr "%d ბაიტის WAL ფაილში (\"%s\") ჩაწერის შეცდომა: %s" -#: receivelog.c:1161 receivelog.c:1201 receivelog.c:1229 +#: receivelog.c:1167 receivelog.c:1207 receivelog.c:1235 #, c-format msgid "could not send copy-end packet: %s" msgstr "copy-end პაკეტის გაგზავნის შეცდომა: %s" @@ -2752,32 +2748,32 @@ msgstr "ჯგუფის წვდომის ალმის დამუშ msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" msgstr "სისტემის ამოცნობის შეცდომა: მივიღე %d მწკრივი და %d ველი. მოველოდი %d მწკრივს და %d ან მეტ ველს" -#: streamutil.c:519 +#: streamutil.c:520 #, c-format msgid "could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" msgstr "რეპლიკაციის სლოტის (\"%s\") წაკითხვის შეცდომა: მივიღე %d მწკრივი და %d ველი. მოველოდი %d მწკრივს და %d ველს" -#: streamutil.c:531 +#: streamutil.c:532 #, c-format msgid "replication slot \"%s\" does not exist" msgstr "რეპლიკაციის სლოტი \"%s\"არ არსებობს" -#: streamutil.c:542 +#: streamutil.c:543 #, c-format msgid "expected a physical replication slot, got type \"%s\" instead" msgstr "მოველოდი ფიზიკური რეპლიკაციის სლოტს. მივიღე: %s" -#: streamutil.c:556 +#: streamutil.c:557 #, c-format msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\"" msgstr "restart_lsn \"%s\"-ის დამუშავების შეცდომა რეპლიკაციის სლოტისთვის \"%s\"" -#: streamutil.c:678 +#: streamutil.c:683 #, c-format msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" msgstr "რეპლიკაციის სლოტის (\"%s\") შექმნის შეცდომა: მივიღე %d მწკრივი და %d ველი. მოველოდი %d მწკრივს და %d ველს" -#: streamutil.c:722 +#: streamutil.c:727 #, c-format msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" msgstr "რეპლიკაციის სლოტის (\"%s\") გადაგდების შეცდომა: მივიღე %d მწკრივი და %d ველი. მოველოდი %d მწკრივს და %d ველს" @@ -2811,167 +2807,5 @@ msgid "could not close compression stream" msgstr "შეკუმშვის ნაკადის დახურვის შეცდომა" #, c-format -#~ msgid "" -#~ " --config-file=FILENAME use specified main server configuration\n" -#~ " file when running target cluster\n" -#~ msgstr "" -#~ " --config-file=FILENAME სამიზნე კლასტერის გაშვებისას მთავარი \n" -#~ " სერვერის მითითებული კონფიგურაციის ფაილში გამოყენება\n" - -#, c-format -#~ msgid " -s, --socket-directory=DIR socket directory to use (default current directory)\n" -#~ msgstr " -s, --socket-directory=DIR სოკეტის საქაღალდე (ნაგულისხმევია მიმდინარე.)\n" - -#, c-format -#~ msgid " -?, --help show this help, then exit\n" -#~ msgstr " -?, --help ამ დახმარების ჩვენება და გასვლა\n" - -#, c-format -#~ msgid " -V, --version output version information, then exit\n" -#~ msgstr " -V, --version ვერსიის ინფორმაციის გამოტანა და გასვლა\n" - -#, c-format -#~ msgid "%s cannot be used with -a/--all" -#~ msgstr "%s-ს ვერ გამოიყენებთ -a/--all -თან ერთად" - -#, c-format -#~ msgid "--failover may only be specified with --create-slot" -#~ msgstr "--failover პარამეტრის მითითება, მხოლოდ, --create-slot პარამეტრთან ერთად შეგიძლიათ" - -#, c-format -#~ msgid "Consider increasing max_logical_replication_workers to at least %d." -#~ msgstr "განიხილეთ max_logical_replication_workers-ის გაზრდა მინიმუმ %d-მდე." - -#, c-format -#~ msgid "Consider increasing max_replication_slots to at least %d." -#~ msgstr "განიხილეთ max_replication_slots-ის გაზრდა მინიმუმ %d-მდე." - -#, c-format -#~ msgid "Consider increasing max_wal_senders to at least %d." -#~ msgstr "განიხილეთ max_wal_senders-ის გაზრდა მინიმუმ %d-მდე." - -#, c-format -#~ msgid "Consider increasing max_worker_processes to at least %d." -#~ msgstr "განიხილეთ max_worker_processes-ის გაზრდა მინიმუმ %d-მდე." - -#, c-format -#~ msgid "The valid option is: \"publications\"" -#~ msgstr "სწორი პარამეტრია \"publications\"" - -#, c-format -#~ msgid "This build does not support compression with %s." -#~ msgstr "ამ აგებაში %s-ით შეკუმშვის მხარდაჭრა არ არსებობს." - -#, c-format -#~ msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte" -#~ msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes" -#~ msgstr[0] "WAL-ის სეგმენტის ზომა ორის ხარისხი უნდა იყოს 1 მბ-სა და 1გბ-ს შორის, მაგრამ დაშორებულმა სერვერმა %d ბაიტიანი მნიშვნელობა დააბრუნა" -#~ msgstr[1] "WAL-ის სეგმენტის ზომა ორის ხარისხი უნდა იყოს 1 მბ-სა და 1გბ-ს შორის, მაგრამ დაშორებულმა სერვერმა %d ბაიტიანი მნიშვნელობა დააბრუნა" - -#, c-format -#~ msgid "could not change system identifier of subscriber: %s" -#~ msgstr "ვერ შევცვალე სისტემურ იდენტიფიკატორი გამომწერისთვის: %s" - -#, c-format -#~ msgid "could not check file \"%s\"" -#~ msgstr "ფაილის შემოწმება შეუძლებელია: %s" - -#, c-format -#~ msgid "could not clear search_path: %s" -#~ msgstr "search_path-ის გასუფთავების პრობლემა: %s" - -#, c-format -#~ msgid "could not determine seek position in file \"%s\": %s" -#~ msgstr "ფაილში %s გადახვევის მდებარეობის დადგენა შეუძლებელია: %s" - -#, c-format -#~ msgid "could not obtain replication slot information: got %d rows, expected %d row" -#~ msgstr "ვერ მივიღე რეპლიკაციის სლოტის ინფორმაცია: მივიღე %d მწკრივი, მოველოდი %d მწკრივს" - -#, c-format -#~ msgid "could not set compression flag for %s: %s" -#~ msgstr "%s-სთვის შეკუმშვის დონის დაყენების შეცდომა: %s" - -#, c-format -#~ msgid "create replication slot \"%s\" on publisher" -#~ msgstr "რეპლიკაციის სლოტის \"%s\" შექმნა გამომცემელზე" - -#, c-format -#~ msgid "directory \"%s\" is not a database cluster directory" -#~ msgstr "საქაღალდე \"%s\" ბაზის კლასტერის საქაღალდეს არ წარმოადგენს" - -#, c-format -#~ msgid "duplicate database \"%s\"" -#~ msgstr "განმეორებადი ბაზა \"%s\"" - -#, c-format -#~ msgid "duplicate publication \"%s\"" -#~ msgstr "განმეორებადი გამოცემა \"%s\"" - -#, c-format -#~ msgid "duplicate replication slot \"%s\"" -#~ msgstr "განმეორებადი რეპლიკაციის სლოტი \"%s\"" - -#, c-format -#~ msgid "duplicate subscription \"%s\"" -#~ msgstr "განმეორებადი გამოწერა \"%s\"" - -#, c-format -#~ msgid "log streamer with pid %d exiting" -#~ msgstr "ჟურნალის ნაკადის პროცესი pid-ით %d ასრულებს მუშაობას" - -#, c-format -#~ msgid "no value specified for --compress, switching to default" -#~ msgstr "--compress -ის მნიშვნელობა მითითებული არაა. გამოიყენება ნაგულისხმები" - -#, c-format -#~ msgid "options %s and -a/--all cannot be used together" -#~ msgstr "პარამეტრებს %s და -a/--all ერთად ვერ გამოიყენებთ" - -#, c-format -#~ msgid "primary has replication slot \"%s\"" -#~ msgstr "ძირითადს აქვს რეპლიკაციის სლოტი \"%s\"" - -#, c-format -#~ msgid "standby is up and running" -#~ msgstr "უქმე ჩართულია და მუშაობს" - -#, c-format -#~ msgid "standby server disconnected from the primary" -#~ msgstr "უქმე სერვერ გაითიშა ძირითადისგან" - -#, c-format -#~ msgid "subscriber failed to change system identifier: exit code: %d" -#~ msgstr "გამომწერის სისტემური იდენტიფიკატორის შეცვლა ჩავარდა: გამოსვლის კოდი: %d" - -#, c-format -#~ msgid "subscriber successfully changed the system identifier" -#~ msgstr "გამომწერმა სისტემური იდენტიფიკატორი წარმატებით შეცვალა" - -#, c-format -#~ msgid "symlinks are not supported on this platform" -#~ msgstr "სიმბმულები ამ პლატფორმაზე მხარდაჭერილი არაა" - -#, c-format -#~ msgid "tar file trailer exceeds 2 blocks" -#~ msgstr "tar ფაილის ბოლოსართი 2 ბლოკს სცდება" - -#, c-format -#~ msgid "this build does not support gzip compression" -#~ msgstr "ამ აგებაში gzip შეკუმშვის მხარდაჭერა არ არსებობს" - -#, c-format -#~ msgid "this build does not support lz4 compression" -#~ msgstr "ამ აგებაში lz4 შეკუმშვის მხარდაჭერა არ არსებობს" - -#, c-format -#~ msgid "this build does not support zstd compression" -#~ msgstr "ამ აგებაში zstd შეკუმშვის მხარდაჭერა არ არსებობს" - -#, c-format -#~ msgid "unknown compression option \"%s\"" -#~ msgstr "შეკუმშვის უცნობი პარამეტრი: \"%s\"" - -#, c-format -#~ msgid "validating connection string on subscriber" -#~ msgstr "შეერთების სტრიქონის დადასტურება გამომწერზე" +#~ msgid "publication \"%s\" specified more than once for --publication" +#~ msgstr "პუბლიკაცია \"%s\" მითითებულია ერთზე მეტჯერ პარამეტრისთვის --publication" diff --git a/src/bin/pg_combinebackup/po/de.po b/src/bin/pg_combinebackup/po/de.po index 7dbd3602e7f..f51108b0720 100644 --- a/src/bin/pg_combinebackup/po/de.po +++ b/src/bin/pg_combinebackup/po/de.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_combinebackup (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-28 19:25+0000\n" -"PO-Revision-Date: 2026-04-10 16:13+0200\n" +"POT-Creation-Date: 2026-07-04 06:26+0000\n" +"PO-Revision-Date: 2026-07-04 12:58+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -41,7 +41,7 @@ msgid "could not open file \"%s\" for reading: %m" msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" #: ../../common/controldata_utils.c:111 copy_file.c:164 load_manifest.c:161 -#: load_manifest.c:199 pg_combinebackup.c:1367 reconstruct.c:542 +#: load_manifest.c:199 pg_combinebackup.c:1369 reconstruct.c:542 #, c-format msgid "could not read file \"%s\": %m" msgstr "konnte Datei »%s« nicht lesen: %m" @@ -52,8 +52,8 @@ msgid "could not read file \"%s\": read %d of %zu" msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" #: ../../common/controldata_utils.c:133 ../../common/controldata_utils.c:281 -#: backup_label.c:174 copy_file.c:71 pg_combinebackup.c:558 reconstruct.c:369 -#: reconstruct.c:742 write_manifest.c:187 +#: backup_label.c:174 copy_file.c:71 pg_combinebackup.c:560 reconstruct.c:369 +#: reconstruct.c:745 write_manifest.c:187 #, c-format msgid "could not close file \"%s\": %m" msgstr "konnte Datei »%s« nicht schließen: %m" @@ -80,13 +80,13 @@ msgstr "" #: ../../common/file_utils.c:370 ../../common/file_utils.c:428 #: ../../common/file_utils.c:502 backup_label.c:143 copy_file.c:69 #: copy_file.c:153 copy_file.c:185 copy_file.c:189 copy_file.c:239 -#: copy_file.c:282 load_manifest.c:128 pg_combinebackup.c:543 reconstruct.c:525 +#: copy_file.c:282 load_manifest.c:128 pg_combinebackup.c:545 reconstruct.c:525 #: reconstruct.c:640 write_manifest.c:250 #, c-format msgid "could not open file \"%s\": %m" msgstr "konnte Datei »%s« nicht öffnen: %m" -#: ../../common/controldata_utils.c:250 backup_label.c:160 reconstruct.c:761 +#: ../../common/controldata_utils.c:250 backup_label.c:160 reconstruct.c:764 #: write_manifest.c:260 #, c-format msgid "could not write file \"%s\": %m" @@ -146,7 +146,7 @@ msgstr "konnte Dateisystem für Datei »%s« nicht synchronisieren: %m" #: ../../common/file_utils.c:123 ../../common/file_utils.c:588 #: ../../fe_utils/version.c:60 backup_label.c:187 load_manifest.c:133 -#: pg_combinebackup.c:695 pg_combinebackup.c:1151 pg_combinebackup.c:1350 +#: pg_combinebackup.c:697 pg_combinebackup.c:1153 pg_combinebackup.c:1352 #: reconstruct.c:204 reconstruct.c:422 #, c-format msgid "could not stat file \"%s\": %m" @@ -159,7 +159,7 @@ msgid "this build does not support sync method \"%s\"" msgstr "diese Installation unterstützt Sync-Methode »%s« nicht" #: ../../common/file_utils.c:156 ../../common/file_utils.c:304 -#: pg_combinebackup.c:953 pg_combinebackup.c:1223 +#: pg_combinebackup.c:955 pg_combinebackup.c:1225 #, c-format msgid "could not open directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" @@ -456,7 +456,7 @@ msgstr "Optionen %s und %s können nicht zusammen verwendet werden" msgid "could not open version file \"%s\": %m" msgstr "konnte Versionsdatei »%s« nicht öffnen: %m" -#: ../../fe_utils/version.c:62 pg_combinebackup.c:1352 +#: ../../fe_utils/version.c:62 pg_combinebackup.c:1354 #, c-format msgid "file \"%s\" is too large" msgstr "Datei »%s« ist zu groß" @@ -496,13 +496,13 @@ msgstr "%s: konnte %s nicht finden" msgid "%s: %s requires %s" msgstr "%s: %s benötigt %s" -#: backup_label.c:162 reconstruct.c:763 +#: backup_label.c:162 reconstruct.c:766 #, c-format msgid "could not write file \"%s\": wrote %d of %d" msgstr "konnte Datei »%s« nicht schreiben: %d von %d geschrieben" -#: backup_label.c:166 copy_file.c:160 copy_file.c:207 reconstruct.c:723 -#: reconstruct.c:769 write_manifest.c:270 +#: backup_label.c:166 copy_file.c:160 copy_file.c:207 reconstruct.c:726 +#: reconstruct.c:772 write_manifest.c:270 #, c-format msgid "could not update checksum of file \"%s\"" msgstr "konnte Prüfsumme der Datei »%s« nicht aktualisieren" @@ -517,7 +517,7 @@ msgstr "konnte nicht in Datei »%s« schreiben: %m" msgid "could not write to file \"%s\", offset %u: wrote %d of %d" msgstr "konnte nicht in Datei »%s«, Position %u schreiben: %d von %d geschrieben" -#: copy_file.c:213 reconstruct.c:786 +#: copy_file.c:213 reconstruct.c:789 #, c-format msgid "could not read from file \"%s\": %m" msgstr "konnte nicht aus Datei »%s« lesen: %m" @@ -537,7 +537,7 @@ msgstr "konnte Datei »%s« nicht erstellen: %m" msgid "error while cloning file \"%s\" to \"%s\": %s" msgstr "Fehler beim Klonen von Datei »%s« nach »%s«: %s" -#: copy_file.c:259 pg_combinebackup.c:261 +#: copy_file.c:259 pg_combinebackup.c:263 #, c-format msgid "file cloning not supported on this platform" msgstr "Klonen von Dateien wird auf dieser Plattform nicht unterstützt" @@ -547,7 +547,7 @@ msgstr "Klonen von Dateien wird auf dieser Plattform nicht unterstützt" msgid "error while copying file range from \"%s\" to \"%s\": %m" msgstr "Fehler beim Kopieren von Dateibereich von »%s« nach »%s«: %m" -#: copy_file.c:299 pg_combinebackup.c:274 reconstruct.c:726 +#: copy_file.c:299 pg_combinebackup.c:276 reconstruct.c:729 #, c-format msgid "copy_file_range not supported on this platform" msgstr "copy_file_range wird auf dieser Plattform nicht unterstützt" @@ -602,146 +602,147 @@ msgstr "keine Eingabeverzeichnisse angegeben" msgid "no output directory specified" msgstr "kein Ausgabeverzeichnis angegeben" -#: pg_combinebackup.c:246 +#: pg_combinebackup.c:247 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"The target directory will not be modified." -msgstr "" -"Ausführen im Probelaufmodus.\n" -"Das Zielverzeichnis wird nicht verändert werden." +msgid "executing in dry-run mode" +msgstr "Ausführen im Probelaufmodus" + +#: pg_combinebackup.c:248 +#, c-format +msgid "The target directory will not be modified." +msgstr "Das Zielverzeichnis wird nicht verändert werden." -#: pg_combinebackup.c:282 +#: pg_combinebackup.c:284 #, c-format msgid "server version too old" msgstr "Serverversion zu alt" -#: pg_combinebackup.c:316 +#: pg_combinebackup.c:318 #, c-format msgid "%s: manifest system identifier is %, but control file has %" msgstr "%s: Systemidentifikator im Manifest ist %, aber Kontrolldatei hat %" -#: pg_combinebackup.c:355 +#: pg_combinebackup.c:357 #, c-format msgid "cannot generate a manifest because no manifest is available for the final input backup" msgstr "kann kein Manifest erzeugen, weil kein Manifest für das letzte Eingabe-Backup verfügbar ist" -#: pg_combinebackup.c:402 +#: pg_combinebackup.c:404 #, c-format msgid "could not create symbolic link from \"%s\" to \"%s\": %m" msgstr "konnte symbolische Verknüpfung von »%s« nach »%s« nicht erzeugen: %m" -#: pg_combinebackup.c:414 pg_combinebackup.c:749 pg_combinebackup.c:947 +#: pg_combinebackup.c:416 pg_combinebackup.c:751 pg_combinebackup.c:949 #, c-format msgid "could not create directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" -#: pg_combinebackup.c:444 +#: pg_combinebackup.c:446 #, c-format msgid "--link mode was used; any modifications to the output directory might destructively modify input directories" msgstr "Modus --link wurde verwendet; Änderungen am Ausgabeverzeichnis könnten die Eingabeverzeichnisse destruktiv verändern" -#: pg_combinebackup.c:474 +#: pg_combinebackup.c:476 #, c-format msgid "directory name too long" msgstr "Verzeichnisname zu lang" -#: pg_combinebackup.c:481 +#: pg_combinebackup.c:483 #, c-format msgid "multiple \"=\" signs in tablespace mapping" msgstr "mehrere »=«-Zeichen im Tablespace-Mapping" -#: pg_combinebackup.c:489 +#: pg_combinebackup.c:491 #, c-format msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" msgstr "ungültiges Tablespace-Mapping-Format »%s«, muss »ALTES_VERZ=NEUES_VERZ« sein" -#: pg_combinebackup.c:500 +#: pg_combinebackup.c:502 #, c-format msgid "old directory is not an absolute path in tablespace mapping: %s" msgstr "altes Verzeichnis im Tablespace-Mapping ist kein absoluter Pfad: %s" -#: pg_combinebackup.c:504 +#: pg_combinebackup.c:506 #, c-format msgid "new directory is not an absolute path in tablespace mapping: %s" msgstr "neues Verzeichnis im Tablespace-Mapping ist kein absoluter Pfad: %s" -#: pg_combinebackup.c:573 +#: pg_combinebackup.c:575 #, c-format msgid "backup at \"%s\" is a full backup, but only the first backup should be a full backup" msgstr "Backup in »%s« ist ein volles Backup, aber nur das erste Backup sollte ein volles Backup sein" -#: pg_combinebackup.c:576 +#: pg_combinebackup.c:578 #, c-format msgid "backup at \"%s\" is an incremental backup, but the first backup should be a full backup" msgstr "Backup in »%s« ist ein inkrementelles Backup, aber das erste Backup sollte ein volles Backup sein" -#: pg_combinebackup.c:579 +#: pg_combinebackup.c:581 #, c-format msgid "backup at \"%s\" starts on timeline %u, but expected %u" msgstr "Backup in »%s« startet auf Zeitleiste %u, aber %u wurde erwartet" -#: pg_combinebackup.c:582 +#: pg_combinebackup.c:584 #, c-format msgid "backup at \"%s\" starts at LSN %X/%08X, but expected %X/%08X" msgstr "Backup in »%s« startet bei LSN %X/%08X, aber %X/%08X wurde erwartet" -#: pg_combinebackup.c:634 +#: pg_combinebackup.c:636 #, c-format msgid "%s: CRC is incorrect" msgstr "%s: CRC ist falsch" -#: pg_combinebackup.c:638 +#: pg_combinebackup.c:640 #, c-format msgid "%s: unexpected control file version" msgstr "%s: unerwartete Kontrolldateiversion" -#: pg_combinebackup.c:645 +#: pg_combinebackup.c:647 #, c-format msgid "%s: expected system identifier %, but found %" msgstr "%s: Systemidentifikator % erwartet, aber % gefunden" -#: pg_combinebackup.c:676 +#: pg_combinebackup.c:678 #, c-format msgid "only some backups have checksums enabled" msgstr "nur einige Sicherungen haben Prüfsummen aktiviert" -#: pg_combinebackup.c:677 +#: pg_combinebackup.c:679 #, c-format msgid "Disable, and optionally reenable, checksums on the output directory to avoid failures." msgstr "Schalten Sie für das Ausgabeverzeichnis Prüfsummen aus, und optional wieder an, um Fehler zu vermeiden." -#: pg_combinebackup.c:712 +#: pg_combinebackup.c:714 #, c-format msgid "removing output directory \"%s\"" msgstr "Ausgabeverzeichnis »%s« wird entfernt" -#: pg_combinebackup.c:714 +#: pg_combinebackup.c:716 #, c-format msgid "failed to remove output directory" msgstr "konnte Ausgabeverzeichnis nicht entfernen" -#: pg_combinebackup.c:718 +#: pg_combinebackup.c:720 #, c-format msgid "removing contents of output directory \"%s\"" msgstr "entferne Inhalt des Ausgabeverzeichnisses »%s«" -#: pg_combinebackup.c:721 +#: pg_combinebackup.c:723 #, c-format msgid "failed to remove contents of output directory" msgstr "konnte Inhalt des Ausgabeverzeichnisses nicht entfernen" -#: pg_combinebackup.c:761 +#: pg_combinebackup.c:763 #, c-format msgid "directory \"%s\" exists but is not empty" msgstr "Verzeichnis »%s« existiert aber ist nicht leer" -#: pg_combinebackup.c:764 +#: pg_combinebackup.c:766 #, c-format msgid "could not access directory \"%s\": %m" msgstr "konnte nicht auf Verzeichnis »%s« zugreifen: %m" -#: pg_combinebackup.c:778 +#: pg_combinebackup.c:780 #, c-format msgid "" "%s reconstructs full backups from incrementals.\n" @@ -750,17 +751,17 @@ msgstr "" "%s rekonstruiert volle Backups aus inkrementellen.\n" "\n" -#: pg_combinebackup.c:779 +#: pg_combinebackup.c:781 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" -#: pg_combinebackup.c:780 +#: pg_combinebackup.c:782 #, c-format msgid " %s [OPTION]... DIRECTORY...\n" msgstr " %s [OPTION]... VERZEICHNIS...\n" -#: pg_combinebackup.c:781 +#: pg_combinebackup.c:783 #, c-format msgid "" "\n" @@ -769,34 +770,34 @@ msgstr "" "\n" "Optionen:\n" -#: pg_combinebackup.c:782 +#: pg_combinebackup.c:784 #, c-format msgid " -d, --debug generate lots of debugging output\n" msgstr " -d, --debug erzeuge eine Menge Debug-Ausgaben\n" -#: pg_combinebackup.c:783 +#: pg_combinebackup.c:785 #, c-format msgid " -k, --link link files instead of copying\n" msgstr " -k, --link Dateien verknüpfen statt kopieren\n" -#: pg_combinebackup.c:784 +#: pg_combinebackup.c:786 #, c-format msgid " -n, --dry-run do not actually do anything\n" msgstr " -n, --dry-run nichts wirklich ausführen\n" -#: pg_combinebackup.c:785 +#: pg_combinebackup.c:787 #, c-format msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgstr "" " -N, --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" " geschrieben sind\n" -#: pg_combinebackup.c:786 +#: pg_combinebackup.c:788 #, c-format msgid " -o, --output=DIRECTORY output directory\n" msgstr " -o, --output=VERZEICHNIS Ausgabeverzeichnis\n" -#: pg_combinebackup.c:787 +#: pg_combinebackup.c:789 #, c-format msgid "" " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" @@ -805,22 +806,22 @@ msgstr "" " -T, --tablespace-mapping=ALTES_VERZ=NEUES_VERZ\n" " Tablespace in ALTES_VERZ nach NEUES_VERZ verlagern\n" -#: pg_combinebackup.c:789 +#: pg_combinebackup.c:791 #, c-format msgid " --clone clone (reflink) files instead of copying\n" msgstr " --clone Dateien klonen (reflink) statt kopieren\n" -#: pg_combinebackup.c:790 +#: pg_combinebackup.c:792 #, c-format msgid " --copy copy files (default)\n" msgstr " --copy Dateien kopieren (Voreinstellung)\n" -#: pg_combinebackup.c:791 +#: pg_combinebackup.c:793 #, c-format msgid " --copy-file-range copy using copy_file_range() system call\n" msgstr " --copy-file-range mit Systemaufruf copy_file_range() kopieren\n" -#: pg_combinebackup.c:792 +#: pg_combinebackup.c:794 #, c-format msgid "" " --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" @@ -829,29 +830,29 @@ msgstr "" " --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" " Algorithmus für Manifest-Prüfsummen\n" -#: pg_combinebackup.c:794 +#: pg_combinebackup.c:796 #, c-format msgid " --no-manifest suppress generation of backup manifest\n" msgstr " --no-manifest Erzeugen des Backup-Manifests unterbinden\n" -#: pg_combinebackup.c:795 +#: pg_combinebackup.c:797 #, c-format msgid " --sync-method=METHOD set method for syncing files to disk\n" msgstr "" " --sync-method=METHODE Methode zum Synchronisieren vond Dateien auf\n" " Festplatte setzen\n" -#: pg_combinebackup.c:796 +#: pg_combinebackup.c:798 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: pg_combinebackup.c:797 +#: pg_combinebackup.c:799 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_combinebackup.c:799 +#: pg_combinebackup.c:801 #, c-format msgid "" "\n" @@ -860,57 +861,57 @@ msgstr "" "\n" "Berichten Sie Fehler an <%s>.\n" -#: pg_combinebackup.c:800 +#: pg_combinebackup.c:802 #, c-format msgid "%s home page: <%s>\n" msgstr "%s Homepage: <%s>\n" -#: pg_combinebackup.c:1015 +#: pg_combinebackup.c:1017 #, c-format msgid "skipping symbolic link \"%s\"" msgstr "überspringe symbolische Verknüpfung »%s«" -#: pg_combinebackup.c:1017 +#: pg_combinebackup.c:1019 #, c-format msgid "skipping special file \"%s\"" msgstr "überspringe besondere Datei »%s«" -#: pg_combinebackup.c:1093 reconstruct.c:305 +#: pg_combinebackup.c:1095 reconstruct.c:305 #, c-format msgid "manifest file \"%s\" contains no entry for file \"%s\"" msgstr "Manifestdatei »%s« enthält keinen Eintrag für Datei »%s«" -#: pg_combinebackup.c:1276 +#: pg_combinebackup.c:1278 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" -#: pg_combinebackup.c:1279 +#: pg_combinebackup.c:1281 #, c-format msgid "target of symbolic link \"%s\" is too long" msgstr "Ziel der symbolischen Verknüpfung »%s« ist zu lang" -#: pg_combinebackup.c:1282 +#: pg_combinebackup.c:1284 #, c-format msgid "target of symbolic link \"%s\" is relative" msgstr "Ziel der symbolischen Verknüpfung »%s« ist relativ" -#: pg_combinebackup.c:1304 +#: pg_combinebackup.c:1306 #, c-format msgid "tablespace at \"%s\" has no tablespace mapping" msgstr "Tablespace in »%s« hat kein Tablespace-Mapping" -#: pg_combinebackup.c:1322 +#: pg_combinebackup.c:1324 #, c-format msgid "tablespaces with OIDs %u and %u both point at directory \"%s\"" msgstr "die Tablespaces mit OIDs %u und %u zeigen beide auf Verzeichnis »%s«" -#: pg_combinebackup.c:1331 +#: pg_combinebackup.c:1333 #, c-format msgid "could not close directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht schließen: %m" -#: pg_combinebackup.c:1369 +#: pg_combinebackup.c:1371 #, c-format msgid "could not read file \"%s\": read %zd of %lld" msgstr "konnte Datei »%s« nicht lesen: %zd von %lld gelesen" @@ -945,7 +946,12 @@ msgstr "Datei »%s« hat Truncation-Blocklänge %u, was die Segmentgröße %u ü msgid "could not read file \"%s\": read %d of %u" msgstr "konnte Datei »%s« nicht lesen: %d von %u gelesen" -#: reconstruct.c:788 +#: reconstruct.c:709 +#, c-format +msgid "unexpected end of file while copying file range from \"%s\" to \"%s\"" +msgstr "unerwartetes Dateiende beim Kopieren von Dateibereich von »%s« nach »%s«" + +#: reconstruct.c:791 #, c-format msgid "could not read from file \"%s\", offset %llu: read %d of %d" msgstr "konnte nicht aus Datei »%s«, Position %llu lesen: %d von %d gelesen" @@ -954,7 +960,3 @@ msgstr "konnte nicht aus Datei »%s«, Position %llu lesen: %d von %d gelesen" #, c-format msgid "could not write file \"%s\": wrote %zd of %d" msgstr "konnte Datei »%s« nicht schreiben: %zd von %d geschrieben" - -#, c-format -#~ msgid "%s: could not parse version number" -#~ msgstr "%s: konnte Versionsnummer nicht parsen" diff --git a/src/bin/pg_combinebackup/po/ja.po b/src/bin/pg_combinebackup/po/ja.po index 2e32bae8363..c1699bc123b 100644 --- a/src/bin/pg_combinebackup/po/ja.po +++ b/src/bin/pg_combinebackup/po/ja.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_combinebackup (PostgreSQL 19)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-15 13:37+0900\n" -"PO-Revision-Date: 2026-05-15 14:54+0900\n" +"POT-Creation-Date: 2026-07-03 14:12+0900\n" +"PO-Revision-Date: 2026-07-06 15:34+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: \n" "Language: ja\n" @@ -43,7 +43,7 @@ msgid "could not open file \"%s\" for reading: %m" msgstr "ファイル\"%s\"を読み込み用にオープンできませんでした: %m" #: ../../common/controldata_utils.c:111 copy_file.c:164 load_manifest.c:161 -#: load_manifest.c:199 pg_combinebackup.c:1367 reconstruct.c:542 +#: load_manifest.c:199 pg_combinebackup.c:1369 reconstruct.c:542 #, c-format msgid "could not read file \"%s\": %m" msgstr "ファイル\"%s\"の読み込みに失敗しました: %m" @@ -54,8 +54,8 @@ msgid "could not read file \"%s\": read %d of %zu" msgstr "ファイル\"%1$s\"を読み込めませんでした: %3$zuバイトのうち%2$dバイトを読み込みました" #: ../../common/controldata_utils.c:133 ../../common/controldata_utils.c:281 -#: backup_label.c:174 copy_file.c:71 pg_combinebackup.c:558 reconstruct.c:369 -#: reconstruct.c:742 write_manifest.c:187 +#: backup_label.c:174 copy_file.c:71 pg_combinebackup.c:560 reconstruct.c:369 +#: reconstruct.c:745 write_manifest.c:187 #, c-format msgid "could not close file \"%s\": %m" msgstr "ファイル\"%s\"をクローズできませんでした: %m" @@ -81,13 +81,13 @@ msgstr "" #: ../../common/file_utils.c:370 ../../common/file_utils.c:428 #: ../../common/file_utils.c:502 backup_label.c:143 copy_file.c:69 #: copy_file.c:153 copy_file.c:185 copy_file.c:189 copy_file.c:239 -#: copy_file.c:282 load_manifest.c:128 pg_combinebackup.c:543 reconstruct.c:525 +#: copy_file.c:282 load_manifest.c:128 pg_combinebackup.c:545 reconstruct.c:525 #: reconstruct.c:640 write_manifest.c:250 #, c-format msgid "could not open file \"%s\": %m" msgstr "ファイル\"%s\"をオープンできませんでした: %m" -#: ../../common/controldata_utils.c:250 backup_label.c:160 reconstruct.c:761 +#: ../../common/controldata_utils.c:250 backup_label.c:160 reconstruct.c:764 #: write_manifest.c:260 #, c-format msgid "could not write file \"%s\": %m" @@ -147,7 +147,7 @@ msgstr "ファイル\"%s\"に対してファイルシステムを同期できま #: ../../common/file_utils.c:123 ../../common/file_utils.c:588 #: ../../fe_utils/version.c:60 backup_label.c:187 load_manifest.c:133 -#: pg_combinebackup.c:695 pg_combinebackup.c:1151 pg_combinebackup.c:1350 +#: pg_combinebackup.c:697 pg_combinebackup.c:1153 pg_combinebackup.c:1352 #: reconstruct.c:204 reconstruct.c:422 #, c-format msgid "could not stat file \"%s\": %m" @@ -160,7 +160,7 @@ msgid "this build does not support sync method \"%s\"" msgstr "このビルドでは同期方式\"%s\"をサポートしていません" #: ../../common/file_utils.c:156 ../../common/file_utils.c:304 -#: pg_combinebackup.c:953 pg_combinebackup.c:1223 +#: pg_combinebackup.c:955 pg_combinebackup.c:1225 #, c-format msgid "could not open directory \"%s\": %m" msgstr "ディレクトリ\"%s\"をオープンできませんでした: %m" @@ -457,7 +457,7 @@ msgstr "オプション %s と %s は同時には使用できません" msgid "could not open version file \"%s\": %m" msgstr "バージョンファイル\"%s\"をオープンできませんでした: %m" -#: ../../fe_utils/version.c:62 pg_combinebackup.c:1352 +#: ../../fe_utils/version.c:62 pg_combinebackup.c:1354 #, c-format msgid "file \"%s\" is too large" msgstr "ファイル\"%s\"は大きすぎます" @@ -497,13 +497,13 @@ msgstr "%s: %sが見つかりませんでした" msgid "%s: %s requires %s" msgstr "%s: %sは%sを必要とします" -#: backup_label.c:162 reconstruct.c:763 +#: backup_label.c:162 reconstruct.c:766 #, c-format msgid "could not write file \"%s\": wrote %d of %d" msgstr "ファイル\"%1$s\"の書き込みができませんでした: %3$dバイト中%2$dバイト書き込みました" -#: backup_label.c:166 copy_file.c:160 copy_file.c:207 reconstruct.c:723 -#: reconstruct.c:769 write_manifest.c:270 +#: backup_label.c:166 copy_file.c:160 copy_file.c:207 reconstruct.c:726 +#: reconstruct.c:772 write_manifest.c:270 #, c-format msgid "could not update checksum of file \"%s\"" msgstr "ファイル\"%s\"のチェックサムの更新ができませんでした" @@ -518,7 +518,7 @@ msgstr "ファイル\"%s\"を書き出せませんでした: %m" msgid "could not write to file \"%s\", offset %u: wrote %d of %d" msgstr "ファイル \"%1$s\"、オフセット%2$uで書き込みができませんでした: %4$dバイト中%3$dバイト書き込みました" -#: copy_file.c:213 reconstruct.c:786 +#: copy_file.c:213 reconstruct.c:789 #, c-format msgid "could not read from file \"%s\": %m" msgstr "ファイル\"%s\"から読み取れませんでした: %m" @@ -538,7 +538,7 @@ msgstr "ファイル\"%s\"を作成できませんでした: %m" msgid "error while cloning file \"%s\" to \"%s\": %s" msgstr "ファイル\"%s\"の\"%s\"へのクローニング中のエラー: %s" -#: copy_file.c:259 pg_combinebackup.c:261 +#: copy_file.c:259 pg_combinebackup.c:263 #, c-format msgid "file cloning not supported on this platform" msgstr "このプラットフォームではファイルのクローンはサポートされません" @@ -548,7 +548,7 @@ msgstr "このプラットフォームではファイルのクローンはサポ msgid "error while copying file range from \"%s\" to \"%s\": %m" msgstr "\"%s\"の\"%s\"へのファイル範囲のコピー中のエラー: %m" -#: copy_file.c:299 pg_combinebackup.c:274 reconstruct.c:726 +#: copy_file.c:299 pg_combinebackup.c:276 reconstruct.c:729 #, c-format msgid "copy_file_range not supported on this platform" msgstr "このプラットフォームではcopy_file_rangeはサポートされません" @@ -603,146 +603,147 @@ msgstr "入力ディレクトリが指定されていません" msgid "no output directory specified" msgstr "出力ディレクトリが指定されていません" -#: pg_combinebackup.c:246 +#: pg_combinebackup.c:247 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"The target directory will not be modified." -msgstr "" -"ドライランモードで実行します。\n" -"ターゲットディレクトリは更新されません。" +msgid "executing in dry-run mode" +msgstr "ドライランモードで実行します" -#: pg_combinebackup.c:282 +#: pg_combinebackup.c:248 +#, c-format +msgid "The target directory will not be modified." +msgstr "対象ディレクトリの内容は変更されません。" + +#: pg_combinebackup.c:284 #, c-format msgid "server version too old" msgstr "サーバーバージョンが古すぎます" -#: pg_combinebackup.c:316 +#: pg_combinebackup.c:318 #, c-format msgid "%s: manifest system identifier is %, but control file has %" msgstr "%s: 目録のシステム識別子が%ですが、制御ファイルでは%です" -#: pg_combinebackup.c:355 +#: pg_combinebackup.c:357 #, c-format msgid "cannot generate a manifest because no manifest is available for the final input backup" msgstr "最後の入力バックアップに目録がないため目録を生成できません" -#: pg_combinebackup.c:402 +#: pg_combinebackup.c:404 #, c-format msgid "could not create symbolic link from \"%s\" to \"%s\": %m" msgstr "\"%s\"から\"%s\"へのシンボリックリンクを作成できませんでした: %m" -#: pg_combinebackup.c:414 pg_combinebackup.c:749 pg_combinebackup.c:947 +#: pg_combinebackup.c:416 pg_combinebackup.c:751 pg_combinebackup.c:949 #, c-format msgid "could not create directory \"%s\": %m" msgstr "ディレクトリ\"%s\"を作成できませんでした: %m" -#: pg_combinebackup.c:444 +#: pg_combinebackup.c:446 #, c-format msgid "--link mode was used; any modifications to the output directory might destructively modify input directories" msgstr "--link モードが使用されています。出力ディレクトリに変更を加えると、入力ディレクトリが破壊的に変更される可能性があります。" -#: pg_combinebackup.c:474 +#: pg_combinebackup.c:476 #, c-format msgid "directory name too long" msgstr "ディレクトリ名が長すぎます" -#: pg_combinebackup.c:481 +#: pg_combinebackup.c:483 #, c-format msgid "multiple \"=\" signs in tablespace mapping" msgstr "テーブル空間のマッピングに複数の\"=\"記号があります" -#: pg_combinebackup.c:489 +#: pg_combinebackup.c:491 #, c-format msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" msgstr "テーブル空間のマッピング形式\"%s\"が不正です。\"旧DIR=新DIR\"でなければなりません" -#: pg_combinebackup.c:500 +#: pg_combinebackup.c:502 #, c-format msgid "old directory is not an absolute path in tablespace mapping: %s" msgstr "テーブル空間のマッピングにおいて、旧ディレクトリが絶対パスではありません: %s" -#: pg_combinebackup.c:504 +#: pg_combinebackup.c:506 #, c-format msgid "new directory is not an absolute path in tablespace mapping: %s" msgstr "テーブル空間のマッピングにおいて、新ディレクトリが絶対パスではありません: %s" -#: pg_combinebackup.c:573 +#: pg_combinebackup.c:575 #, c-format msgid "backup at \"%s\" is a full backup, but only the first backup should be a full backup" msgstr "\"%s\"のバックアップはフルバックアップですが、最初のバックアップのみがフルバックアップである必要があります" -#: pg_combinebackup.c:576 +#: pg_combinebackup.c:578 #, c-format msgid "backup at \"%s\" is an incremental backup, but the first backup should be a full backup" msgstr "\"%s\"のバックアップは差分バックアップですが、最初のバックアップはフルバックアップである必要があります" -#: pg_combinebackup.c:579 +#: pg_combinebackup.c:581 #, c-format msgid "backup at \"%s\" starts on timeline %u, but expected %u" msgstr "\"%s\"のバックアップはタイムライン%uで始まっていますが、%uを期待していました" -#: pg_combinebackup.c:582 +#: pg_combinebackup.c:584 #, c-format msgid "backup at \"%s\" starts at LSN %X/%08X, but expected %X/%08X" msgstr "\"%s\"のバックアップはLSN %X/%08Xで始まっていますが、%X/%08Xを期待していました" -#: pg_combinebackup.c:634 +#: pg_combinebackup.c:636 #, c-format msgid "%s: CRC is incorrect" msgstr "%s: CRCが正しくありません" -#: pg_combinebackup.c:638 +#: pg_combinebackup.c:640 #, c-format msgid "%s: unexpected control file version" msgstr "%s: 予期しない制御ファイルバージョン" -#: pg_combinebackup.c:645 +#: pg_combinebackup.c:647 #, c-format msgid "%s: expected system identifier %, but found %" msgstr "%s: システム識別子 % を予期していましたが、% でした" -#: pg_combinebackup.c:676 +#: pg_combinebackup.c:678 #, c-format msgid "only some backups have checksums enabled" msgstr "一部のバックアップのみチェックサムが有効化されています" -#: pg_combinebackup.c:677 +#: pg_combinebackup.c:679 #, c-format msgid "Disable, and optionally reenable, checksums on the output directory to avoid failures." msgstr "失敗を防止するためには出力先ディレクトリでのチェックサムを無効にして、必要に応じて再度有効にしてください。" -#: pg_combinebackup.c:712 +#: pg_combinebackup.c:714 #, c-format msgid "removing output directory \"%s\"" msgstr "出力ディレクトリ\"%s\"を削除しています" -#: pg_combinebackup.c:714 +#: pg_combinebackup.c:716 #, c-format msgid "failed to remove output directory" msgstr "出力ディレクトリの削除に失敗しました" -#: pg_combinebackup.c:718 +#: pg_combinebackup.c:720 #, c-format msgid "removing contents of output directory \"%s\"" msgstr "出力ディレクトリ\"%s\"の内容の削除中" -#: pg_combinebackup.c:721 +#: pg_combinebackup.c:723 #, c-format msgid "failed to remove contents of output directory" msgstr "出力ディレクトリの内容の削除に失敗しました" -#: pg_combinebackup.c:761 +#: pg_combinebackup.c:763 #, c-format msgid "directory \"%s\" exists but is not empty" msgstr "ディレクトリ\"%s\"は存在しますが、空ではありません" -#: pg_combinebackup.c:764 +#: pg_combinebackup.c:766 #, c-format msgid "could not access directory \"%s\": %m" msgstr "ディレクトリ\"%s\"にアクセスできませんでした: %m" -#: pg_combinebackup.c:778 +#: pg_combinebackup.c:780 #, c-format msgid "" "%s reconstructs full backups from incrementals.\n" @@ -751,17 +752,17 @@ msgstr "" "%s 差分からフルバックアップを再構築する。\n" "\n" -#: pg_combinebackup.c:779 +#: pg_combinebackup.c:781 #, c-format msgid "Usage:\n" msgstr "使用方法:\n" -#: pg_combinebackup.c:780 +#: pg_combinebackup.c:782 #, c-format msgid " %s [OPTION]... DIRECTORY...\n" msgstr " %s [オプション]... ディレクトリ...\n" -#: pg_combinebackup.c:781 +#: pg_combinebackup.c:783 #, c-format msgid "" "\n" @@ -770,32 +771,32 @@ msgstr "" "\n" "オプション:\n" -#: pg_combinebackup.c:782 +#: pg_combinebackup.c:784 #, c-format msgid " -d, --debug generate lots of debugging output\n" msgstr " -d, --debug 多くのデバッグ用の出力を生成\n" -#: pg_combinebackup.c:783 +#: pg_combinebackup.c:785 #, c-format msgid " -k, --link link files instead of copying\n" msgstr " -k, --link コピーする代わりにリンクを作成する\n" -#: pg_combinebackup.c:784 +#: pg_combinebackup.c:786 #, c-format msgid " -n, --dry-run do not actually do anything\n" msgstr " -n, --dry-run 実際には何もしない\n" -#: pg_combinebackup.c:785 +#: pg_combinebackup.c:787 #, c-format msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgstr " -N, --no-sync 変更の安全なディスクへの書き出しを待機しない\n" -#: pg_combinebackup.c:786 +#: pg_combinebackup.c:788 #, c-format msgid " -o, --output=DIRECTORY output directory\n" msgstr " -o, --output=DIRECTORY 出力ディレクトリ\n" -#: pg_combinebackup.c:787 +#: pg_combinebackup.c:789 #, c-format msgid "" " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" @@ -804,24 +805,24 @@ msgstr "" " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" " OLDDIRにあるテーブルスペースをNEWDIRへ移動\n" -#: pg_combinebackup.c:789 +#: pg_combinebackup.c:791 #, c-format msgid " --clone clone (reflink) files instead of copying\n" msgstr "" " --clone ファイルをコピーする代わりにクローニング(reflink)\n" " を行う\n" -#: pg_combinebackup.c:790 +#: pg_combinebackup.c:792 #, c-format msgid " --copy copy files (default)\n" msgstr " --copy ファイルをコピーする(デフォルト)\n" -#: pg_combinebackup.c:791 +#: pg_combinebackup.c:793 #, c-format msgid " --copy-file-range copy using copy_file_range() system call\n" msgstr " --copy-file-range copy_file_range()システムコールでコピーする\n" -#: pg_combinebackup.c:792 +#: pg_combinebackup.c:794 #, c-format msgid "" " --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" @@ -830,27 +831,27 @@ msgstr "" " --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" " 目録チェックサムのアルゴリズムを指定\n" -#: pg_combinebackup.c:794 +#: pg_combinebackup.c:796 #, c-format msgid " --no-manifest suppress generation of backup manifest\n" msgstr " --no-manifest バックアップマニフェストの生成を抑止\n" -#: pg_combinebackup.c:795 +#: pg_combinebackup.c:797 #, c-format msgid " --sync-method=METHOD set method for syncing files to disk\n" msgstr " --sync-method=METHOD ファイルをディスクに同期させる方法を指定\n" -#: pg_combinebackup.c:796 +#: pg_combinebackup.c:798 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version バージョン情報を表示して終了\n" -#: pg_combinebackup.c:797 +#: pg_combinebackup.c:799 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help このヘルプを表示して終了\n" -#: pg_combinebackup.c:799 +#: pg_combinebackup.c:801 #, c-format msgid "" "\n" @@ -859,57 +860,57 @@ msgstr "" "\n" "バグは<%s>に報告してください。\n" -#: pg_combinebackup.c:800 +#: pg_combinebackup.c:802 #, c-format msgid "%s home page: <%s>\n" msgstr "%s ホームページ: <%s>\n" -#: pg_combinebackup.c:1015 +#: pg_combinebackup.c:1017 #, c-format msgid "skipping symbolic link \"%s\"" msgstr "シンボリックリンク\"%s\"をスキップします" -#: pg_combinebackup.c:1017 +#: pg_combinebackup.c:1019 #, c-format msgid "skipping special file \"%s\"" msgstr "スペシャルファイル\"%s\"をスキップしています" -#: pg_combinebackup.c:1093 reconstruct.c:305 +#: pg_combinebackup.c:1095 reconstruct.c:305 #, c-format msgid "manifest file \"%s\" contains no entry for file \"%s\"" msgstr "目録ファイル\"%s\" にはファイル\"%s\"のエントリがありません" -#: pg_combinebackup.c:1276 +#: pg_combinebackup.c:1278 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "シンボリックリンク\"%s\"を読めませんでした: %m" -#: pg_combinebackup.c:1279 +#: pg_combinebackup.c:1281 #, c-format msgid "target of symbolic link \"%s\" is too long" msgstr "シンボリックリンク\"%s\"のターゲットが長すぎます" -#: pg_combinebackup.c:1282 +#: pg_combinebackup.c:1284 #, c-format msgid "target of symbolic link \"%s\" is relative" msgstr "シンボリックリンク\"%s\"のターゲットが相対的です" -#: pg_combinebackup.c:1304 +#: pg_combinebackup.c:1306 #, c-format msgid "tablespace at \"%s\" has no tablespace mapping" msgstr "\"%s\"にあるテーブルスペースに対応するテーブルスペースマッピングがありません" -#: pg_combinebackup.c:1322 +#: pg_combinebackup.c:1324 #, c-format msgid "tablespaces with OIDs %u and %u both point at directory \"%s\"" msgstr "OID %uと%uのテーブルスペースがどちらもディレクトリ\"%s\"を指しています" -#: pg_combinebackup.c:1331 +#: pg_combinebackup.c:1333 #, c-format msgid "could not close directory \"%s\": %m" msgstr "ディレクトリ\"%s\"をクローズできませんでした: %m" -#: pg_combinebackup.c:1369 +#: pg_combinebackup.c:1371 #, c-format msgid "could not read file \"%s\": read %zd of %lld" msgstr "ファイル\"%1$s\"を読み込めませんでした: %3$lldバイトのうち%2$zdバイトを読み込みました" @@ -944,7 +945,12 @@ msgstr "ファイル\"%s\"の切り詰めブロック長%uがセグメントサ msgid "could not read file \"%s\": read %d of %u" msgstr "ファイル\"%1$s\"を読み込めませんでした: %3$uバイトのうち%2$dバイトを読み込みました" -#: reconstruct.c:788 +#: reconstruct.c:709 +#, c-format +msgid "unexpected end of file while copying file range from \"%s\" to \"%s\"" +msgstr "\"%s\"の\"%s\"へのファイル範囲のコピー中に予期しないファイル終端" + +#: reconstruct.c:791 #, c-format msgid "could not read from file \"%s\", offset %llu: read %d of %d" msgstr "ファイル \"%1$s\"、オフセット%2$lluから読み取れませんでした: %4$d中%3$d" diff --git a/src/bin/pg_combinebackup/po/ka.po b/src/bin/pg_combinebackup/po/ka.po index 8999ca66956..46b678f20c1 100644 --- a/src/bin/pg_combinebackup/po/ka.po +++ b/src/bin/pg_combinebackup/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_combinebackup (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-13 06:26+0000\n" -"PO-Revision-Date: 2026-05-13 09:09+0200\n" +"POT-Creation-Date: 2026-07-04 00:25+0000\n" +"PO-Revision-Date: 2026-07-04 07:34+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: \n" "Language: ka\n" @@ -43,7 +43,7 @@ msgid "could not open file \"%s\" for reading: %m" msgstr "ფაილის (%s) გახსნის შეცდომა: %m" #: ../../common/controldata_utils.c:111 copy_file.c:164 load_manifest.c:161 -#: load_manifest.c:199 pg_combinebackup.c:1367 reconstruct.c:542 +#: load_manifest.c:199 pg_combinebackup.c:1369 reconstruct.c:542 #, c-format msgid "could not read file \"%s\": %m" msgstr "ფაილის (%s) წაკითხვის შეცდომა: %m" @@ -54,8 +54,8 @@ msgid "could not read file \"%s\": read %d of %zu" msgstr "\"%s\"-ის წაკითხვის შეცდომა: წაკითხულია %d %zu-დან" #: ../../common/controldata_utils.c:133 ../../common/controldata_utils.c:281 -#: backup_label.c:174 copy_file.c:71 pg_combinebackup.c:558 reconstruct.c:369 -#: reconstruct.c:742 write_manifest.c:187 +#: backup_label.c:174 copy_file.c:71 pg_combinebackup.c:560 reconstruct.c:369 +#: reconstruct.c:745 write_manifest.c:187 #, c-format msgid "could not close file \"%s\": %m" msgstr "ფაილის (%s) დახურვის შეცდომა: %m" @@ -80,13 +80,13 @@ msgstr "" #: ../../common/file_utils.c:370 ../../common/file_utils.c:428 #: ../../common/file_utils.c:502 backup_label.c:143 copy_file.c:69 #: copy_file.c:153 copy_file.c:185 copy_file.c:189 copy_file.c:239 -#: copy_file.c:282 load_manifest.c:128 pg_combinebackup.c:543 reconstruct.c:525 +#: copy_file.c:282 load_manifest.c:128 pg_combinebackup.c:545 reconstruct.c:525 #: reconstruct.c:640 write_manifest.c:250 #, c-format msgid "could not open file \"%s\": %m" msgstr "ფაილის (%s) გახსნის შეცდომა: %m" -#: ../../common/controldata_utils.c:250 backup_label.c:160 reconstruct.c:761 +#: ../../common/controldata_utils.c:250 backup_label.c:160 reconstruct.c:764 #: write_manifest.c:260 #, c-format msgid "could not write file \"%s\": %m" @@ -146,7 +146,7 @@ msgstr "შეუძლებელია ფაილური სისტე #: ../../common/file_utils.c:123 ../../common/file_utils.c:588 #: ../../fe_utils/version.c:60 backup_label.c:187 load_manifest.c:133 -#: pg_combinebackup.c:695 pg_combinebackup.c:1151 pg_combinebackup.c:1350 +#: pg_combinebackup.c:697 pg_combinebackup.c:1153 pg_combinebackup.c:1352 #: reconstruct.c:204 reconstruct.c:422 #, c-format msgid "could not stat file \"%s\": %m" @@ -159,7 +159,7 @@ msgid "this build does not support sync method \"%s\"" msgstr "ამ აგებას სინქრონიზაციის მეთოდის \"%s\" მხარდაჭერა არ გააჩნია" #: ../../common/file_utils.c:156 ../../common/file_utils.c:304 -#: pg_combinebackup.c:953 pg_combinebackup.c:1223 +#: pg_combinebackup.c:955 pg_combinebackup.c:1225 #, c-format msgid "could not open directory \"%s\": %m" msgstr "საქაღალდის (%s) გახსნის შეცდომა: %m" @@ -456,7 +456,7 @@ msgstr "პარამეტრებს %s და -%s ერთად ვე msgid "could not open version file \"%s\": %m" msgstr "ვერსიის ფაილის გახსნის შეცდომა \"%s\": %m" -#: ../../fe_utils/version.c:62 pg_combinebackup.c:1352 +#: ../../fe_utils/version.c:62 pg_combinebackup.c:1354 #, c-format msgid "file \"%s\" is too large" msgstr "%s: ფაილი ძალიან დიდია" @@ -496,13 +496,13 @@ msgstr "%s: %s ვერ ვიპოვე" msgid "%s: %s requires %s" msgstr "%s: %s-ს %s სჭირდება" -#: backup_label.c:162 reconstruct.c:763 +#: backup_label.c:162 reconstruct.c:766 #, c-format msgid "could not write file \"%s\": wrote %d of %d" msgstr "ფაილში \"%s\" ჩაწერა შეუძლებელია. ჩაწერილია %d %d-დან" -#: backup_label.c:166 copy_file.c:160 copy_file.c:207 reconstruct.c:723 -#: reconstruct.c:769 write_manifest.c:270 +#: backup_label.c:166 copy_file.c:160 copy_file.c:207 reconstruct.c:726 +#: reconstruct.c:772 write_manifest.c:270 #, c-format msgid "could not update checksum of file \"%s\"" msgstr "ფაილის (\"%s\") საკონტროლო ჯამის განახლების შეცდომა" @@ -517,7 +517,7 @@ msgstr "ფაილში (%s) ჩაწერის შეცდომა: %m" msgid "could not write to file \"%s\", offset %u: wrote %d of %d" msgstr "ფაილში \"%s\" ჩაწერის შეცდომა. წანაცვლება %u: ჩავწერე %d ბაიტი %d-დან" -#: copy_file.c:213 reconstruct.c:786 +#: copy_file.c:213 reconstruct.c:789 #, c-format msgid "could not read from file \"%s\": %m" msgstr "ფაილიდან (\"%s\") წაკითხვის შეცდომა: %m" @@ -537,7 +537,7 @@ msgstr "ფაილის (%s) შექმნის შეცდომა: %m" msgid "error while cloning file \"%s\" to \"%s\": %s" msgstr "შეცდომა ფაილის დაკლონვისას \"%s\"-დან \"%s\"-მდე: %s" -#: copy_file.c:259 pg_combinebackup.c:261 +#: copy_file.c:259 pg_combinebackup.c:263 #, c-format msgid "file cloning not supported on this platform" msgstr "ამ პლატფორმაზე კლონირება მხარდაჭერილი არაა" @@ -547,7 +547,7 @@ msgstr "ამ პლატფორმაზე კლონირება მ msgid "error while copying file range from \"%s\" to \"%s\": %m" msgstr "შეცდომა ფაილბის შუალედის კოპირებისას \"%s\"-დან \"%s\"-მდე: %m" -#: copy_file.c:299 pg_combinebackup.c:274 reconstruct.c:726 +#: copy_file.c:299 pg_combinebackup.c:276 reconstruct.c:729 #, c-format msgid "copy_file_range not supported on this platform" msgstr "ამ პლატფორმაზე copy_file_range მხარდაჭერილი არაა" @@ -602,146 +602,147 @@ msgstr "შეყვანის საქაღალდეები მით msgid "no output directory specified" msgstr "გამოტანის საქაღალდე მითითებული არაა" -#: pg_combinebackup.c:246 +#: pg_combinebackup.c:247 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"The target directory will not be modified." -msgstr "" -"შესრულება მშრალი გაშვების რეჟიმში.\n" -"სამიზნე საქაღალდე არ შეიცვლება." +msgid "executing in dry-run mode" +msgstr "შესრულება მშრალი გაშვების რეჟიმში" -#: pg_combinebackup.c:282 +#: pg_combinebackup.c:248 +#, c-format +msgid "The target directory will not be modified." +msgstr "სამიზნე საქაღალდე არ შეიცვლება." + +#: pg_combinebackup.c:284 #, c-format msgid "server version too old" msgstr "სერვერის ვერსია ძალიან ძველია" -#: pg_combinebackup.c:316 +#: pg_combinebackup.c:318 #, c-format msgid "%s: manifest system identifier is %, but control file has %" msgstr "%s: მანიფესტის სისტემის იდენტიფიკატორია %, მაგრამ კონტროლის ფაილი შეიცავს %-ს" -#: pg_combinebackup.c:355 +#: pg_combinebackup.c:357 #, c-format msgid "cannot generate a manifest because no manifest is available for the final input backup" msgstr "მანიფესტის გენერაცია შეუძლებელია, რადგან საბოლოო შეყვანის მარქაფისთვის მანიფესტი ხელმისაწვდომი არაა" -#: pg_combinebackup.c:402 +#: pg_combinebackup.c:404 #, c-format msgid "could not create symbolic link from \"%s\" to \"%s\": %m" msgstr "%s-დან %s-მდე სიმბმულის შექმნა შეუძლებელია: %m" -#: pg_combinebackup.c:414 pg_combinebackup.c:749 pg_combinebackup.c:947 +#: pg_combinebackup.c:416 pg_combinebackup.c:751 pg_combinebackup.c:949 #, c-format msgid "could not create directory \"%s\": %m" msgstr "საქაღალდის (%s) შექმნის შეცდომა: %m" -#: pg_combinebackup.c:444 +#: pg_combinebackup.c:446 #, c-format msgid "--link mode was used; any modifications to the output directory might destructively modify input directories" msgstr "გამოყენებული იყო რეჟიმი --link. გამოტანის საქაღალდის ნებისმიერმა ცვლილებამ, შეიძლება, შეყვანის საქაღალდეები დამანგრევლად შეცვალოს" -#: pg_combinebackup.c:474 +#: pg_combinebackup.c:476 #, c-format msgid "directory name too long" msgstr "საქაღალდის სახელი ძალიან გრძელია" -#: pg_combinebackup.c:481 +#: pg_combinebackup.c:483 #, c-format msgid "multiple \"=\" signs in tablespace mapping" msgstr "ცხრილების სივრცის მიბმაში ერთზე მეტი \"=\" ნიშანია" -#: pg_combinebackup.c:489 +#: pg_combinebackup.c:491 #, c-format msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" msgstr "ცხრილების მიბმის არასწორი ფორმატი \"%s\", უნდა იყოს \"OLDDIR=NEWDIR\"" -#: pg_combinebackup.c:500 +#: pg_combinebackup.c:502 #, c-format msgid "old directory is not an absolute path in tablespace mapping: %s" msgstr "ძველი საქაღალდის ბილიკი ცხრილის სივრცის მიბმაში აბსოლუტური არაა: %s" -#: pg_combinebackup.c:504 +#: pg_combinebackup.c:506 #, c-format msgid "new directory is not an absolute path in tablespace mapping: %s" msgstr "ახალი საქაღალდის ბილიკი ცხრილის სივრცის მიბმაში აბსოლუტური არაა: %s" -#: pg_combinebackup.c:573 +#: pg_combinebackup.c:575 #, c-format msgid "backup at \"%s\" is a full backup, but only the first backup should be a full backup" msgstr "მარქაფი მისამართზე \"%s\" სრული მარქაფია, მაგრამ, მხოლოდ, პირველი მარქაფი უნდა იყოს სრული" -#: pg_combinebackup.c:576 +#: pg_combinebackup.c:578 #, c-format msgid "backup at \"%s\" is an incremental backup, but the first backup should be a full backup" msgstr "მარქაფი მისამართზე \"%s\" ინკრემენტული მარქაფია, მაგრამ პირველი მარქაფი სრული უნდა იყოს" -#: pg_combinebackup.c:579 +#: pg_combinebackup.c:581 #, c-format msgid "backup at \"%s\" starts on timeline %u, but expected %u" msgstr "მარქაფი მისამართზე \"%s\" იწყება დროის ხაზზე %u, მაგრამ მოველოდი მნიშვნელობას %u" -#: pg_combinebackup.c:582 +#: pg_combinebackup.c:584 #, c-format msgid "backup at \"%s\" starts at LSN %X/%08X, but expected %X/%08X" msgstr "მარქაფი მისამართზე \"%s\" იწყება LSN-თან %X/%08X, მაგრამ მოველოდი მნიშვნელობას %X/%08X" -#: pg_combinebackup.c:634 +#: pg_combinebackup.c:636 #, c-format msgid "%s: CRC is incorrect" msgstr "%s: CRC არასწორია" -#: pg_combinebackup.c:638 +#: pg_combinebackup.c:640 #, c-format msgid "%s: unexpected control file version" msgstr "%s: მოულოდნელი საკონტროლო ფაილის ვერსია" -#: pg_combinebackup.c:645 +#: pg_combinebackup.c:647 #, c-format msgid "%s: expected system identifier %, but found %" msgstr "%s: მოველოდი სისტემის იდენტიფიკატორს %, ნაპოვნი მნიშვნელობაა %" -#: pg_combinebackup.c:676 +#: pg_combinebackup.c:678 #, c-format msgid "only some backups have checksums enabled" msgstr "საკონტროლო ჯამები, მხოლოდ, ზოგიერთ მარქაფს ჰქონდა" -#: pg_combinebackup.c:677 +#: pg_combinebackup.c:679 #, c-format msgid "Disable, and optionally reenable, checksums on the output directory to avoid failures." msgstr "გამორთვა და არასავალდებულოდ თავიდან ჩართვა საკონტროლო ჯამებისა გამოტანის საქაღალდეზე, ჩავარდნების თავიდან ასაცილებლად." -#: pg_combinebackup.c:712 +#: pg_combinebackup.c:714 #, c-format msgid "removing output directory \"%s\"" msgstr "წაიშლება გამოტანის საქაღალდე \"%s\"" -#: pg_combinebackup.c:714 +#: pg_combinebackup.c:716 #, c-format msgid "failed to remove output directory" msgstr "გამოტანის საქაღალდის წაშლა ჩავარდა" -#: pg_combinebackup.c:718 +#: pg_combinebackup.c:720 #, c-format msgid "removing contents of output directory \"%s\"" msgstr "წაიშლება შემცველობა გამოტანის საქაღალდისთვის \"%s\"" -#: pg_combinebackup.c:721 +#: pg_combinebackup.c:723 #, c-format msgid "failed to remove contents of output directory" msgstr "გამოტანის საქაღალდის შემცველობის წაშლა ჩავარდა" -#: pg_combinebackup.c:761 +#: pg_combinebackup.c:763 #, c-format msgid "directory \"%s\" exists but is not empty" msgstr "საქაღალდე \"%s\" არსებობს, მაგრამ ცარიელი არაა" -#: pg_combinebackup.c:764 +#: pg_combinebackup.c:766 #, c-format msgid "could not access directory \"%s\": %m" msgstr "საქაღალდის (%s) წვდომის შეცდომა: %m" -#: pg_combinebackup.c:778 +#: pg_combinebackup.c:780 #, c-format msgid "" "%s reconstructs full backups from incrementals.\n" @@ -750,17 +751,17 @@ msgstr "" "%s სრული მარქაფების აგება ინკრემენტულებისგან.\n" "\n" -#: pg_combinebackup.c:779 +#: pg_combinebackup.c:781 #, c-format msgid "Usage:\n" msgstr "გამოყენება:\n" -#: pg_combinebackup.c:780 +#: pg_combinebackup.c:782 #, c-format msgid " %s [OPTION]... DIRECTORY...\n" msgstr " %s [პარამეტრი]... საქაღალდე...\n" -#: pg_combinebackup.c:781 +#: pg_combinebackup.c:783 #, c-format msgid "" "\n" @@ -769,32 +770,32 @@ msgstr "" "\n" "პარამეტრები:\n" -#: pg_combinebackup.c:782 +#: pg_combinebackup.c:784 #, c-format msgid " -d, --debug generate lots of debugging output\n" msgstr " -d, --debug გასამართი ინფორმაციის გენერაცია\n" -#: pg_combinebackup.c:783 +#: pg_combinebackup.c:785 #, c-format msgid " -k, --link link files instead of copying\n" msgstr " -k, --link ფაილებზე ბმულების შექმნა მათი კოპირების ნაცვლად\n" -#: pg_combinebackup.c:784 +#: pg_combinebackup.c:786 #, c-format msgid " -n, --dry-run do not actually do anything\n" msgstr " -n, --dry-run არაფერი სინამდვილეში არ ქნა\n" -#: pg_combinebackup.c:785 +#: pg_combinebackup.c:787 #, c-format msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgstr " -N, --no-sync არ დაველოდო ცვლილებების დისკზე უსაფრთხოდ ჩაწერას\n" -#: pg_combinebackup.c:786 +#: pg_combinebackup.c:788 #, c-format msgid " -o, --output=DIRECTORY output directory\n" msgstr " -o, --output=საქაღალდე გამოტანის საქაღალდე\n" -#: pg_combinebackup.c:787 +#: pg_combinebackup.c:789 #, c-format msgid "" " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" @@ -803,22 +804,22 @@ msgstr "" " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" " ცხრილების სივრცის OLDDIR-დან NEWDIR-ში გადატანა\n" -#: pg_combinebackup.c:789 +#: pg_combinebackup.c:791 #, c-format msgid " --clone clone (reflink) files instead of copying\n" msgstr " --clone ფაილების დაკლონვა (reflink) კოპირების ნაცვლად\n" -#: pg_combinebackup.c:790 +#: pg_combinebackup.c:792 #, c-format msgid " --copy copy files (default)\n" msgstr " --copy ფაილების კოპირება (ნაგულისხმევი)\n" -#: pg_combinebackup.c:791 +#: pg_combinebackup.c:793 #, c-format msgid " --copy-file-range copy using copy_file_range() system call\n" msgstr " --copy-file-range კოპირება სისტემური ფუნქციით copy_file_range()\n" -#: pg_combinebackup.c:792 +#: pg_combinebackup.c:794 #, c-format msgid "" " --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" @@ -827,27 +828,27 @@ msgstr "" " --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" " მანიფესტების საკონტროლო ჯამის გამოსათვლელი ალფორითმი\n" -#: pg_combinebackup.c:794 +#: pg_combinebackup.c:796 #, c-format msgid " --no-manifest suppress generation of backup manifest\n" msgstr " --no-manifest მარქაფის მანიფესტი არ შეიქმნება\n" -#: pg_combinebackup.c:795 +#: pg_combinebackup.c:797 #, c-format msgid " --sync-method=METHOD set method for syncing files to disk\n" msgstr " --sync-method=მეთოდი ფაილების დისკზე სინქრონიზაციის მეთოდის დაყენება\n" -#: pg_combinebackup.c:796 +#: pg_combinebackup.c:798 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version ვერსიის ინფორმაციის გამოტანა და გასვლა\n" -#: pg_combinebackup.c:797 +#: pg_combinebackup.c:799 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ამ დახმარების ჩვენება და გასვლა\n" -#: pg_combinebackup.c:799 +#: pg_combinebackup.c:801 #, c-format msgid "" "\n" @@ -856,57 +857,57 @@ msgstr "" "\n" "შეცდომების შესახებ მიწერეთ: %s\n" -#: pg_combinebackup.c:800 +#: pg_combinebackup.c:802 #, c-format msgid "%s home page: <%s>\n" msgstr "%s-ის საწყისი გვერდია: <%s>\n" -#: pg_combinebackup.c:1015 +#: pg_combinebackup.c:1017 #, c-format msgid "skipping symbolic link \"%s\"" msgstr "%s: სიმბმულია. გამოტოვება" -#: pg_combinebackup.c:1017 +#: pg_combinebackup.c:1019 #, c-format msgid "skipping special file \"%s\"" msgstr "სპეციალური ფაილის გამოტოვება \"%s\"" -#: pg_combinebackup.c:1093 reconstruct.c:305 +#: pg_combinebackup.c:1095 reconstruct.c:305 #, c-format msgid "manifest file \"%s\" contains no entry for file \"%s\"" msgstr "მანიფესტის ფაილი \"%s\" ფაილისთვის \"%s\" ჩანაწერებს არ შეიცავს" -#: pg_combinebackup.c:1276 +#: pg_combinebackup.c:1278 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "სიმბოლური ბმის \"%s\" წაკითხვის შეცდომა: %m" -#: pg_combinebackup.c:1279 +#: pg_combinebackup.c:1281 #, c-format msgid "target of symbolic link \"%s\" is too long" msgstr "სიმბოლური ბმულის \"%s\" სამიზნე მეტისმეტად გრძელია" -#: pg_combinebackup.c:1282 +#: pg_combinebackup.c:1284 #, c-format msgid "target of symbolic link \"%s\" is relative" msgstr "სიმბმულის \"%s\" სამიზნე ფარდობითია" -#: pg_combinebackup.c:1304 +#: pg_combinebackup.c:1306 #, c-format msgid "tablespace at \"%s\" has no tablespace mapping" msgstr "ცხრილები სივრცეს მისამართზე \"%s\" ცხრილების სივრცის ასახვები არ გააჩნია" -#: pg_combinebackup.c:1322 +#: pg_combinebackup.c:1324 #, c-format msgid "tablespaces with OIDs %u and %u both point at directory \"%s\"" msgstr "ცხრილის სივრცეები OID-ებით %u და %u, ორივე მიუთითებს საქაღალდეზე \"%s\"-ზე" -#: pg_combinebackup.c:1331 +#: pg_combinebackup.c:1333 #, c-format msgid "could not close directory \"%s\": %m" msgstr "საქაღალდის %s-ზე დახურვის შეცდომა: %m" -#: pg_combinebackup.c:1369 +#: pg_combinebackup.c:1371 #, c-format msgid "could not read file \"%s\": read %zd of %lld" msgstr "ფაილის \"%s\" წაკითხვა შეუძლებელია: წაკითხულია %zd %lld-დან" @@ -941,7 +942,12 @@ msgstr "ფაილს \"%s\" აქვს წაკვეთის ბლო msgid "could not read file \"%s\": read %d of %u" msgstr "ფაილის \"%s\" წაკითხვის შეცდომა: წაკითხულია %d %u-დან" -#: reconstruct.c:788 +#: reconstruct.c:709 +#, c-format +msgid "unexpected end of file while copying file range from \"%s\" to \"%s\"" +msgstr "მოულოდნელი ფაილის დასასრული ფაილის შუალედის კოპირებისას \"%s\"-იდან \"%s\"-მდე" + +#: reconstruct.c:791 #, c-format msgid "could not read from file \"%s\", offset %llu: read %d of %d" msgstr "ფაილიდან \"%s\" წაკითხვის შეცდომა. წანაცვლება %llu: წაკითხულია %d %d-დან" @@ -950,59 +956,3 @@ msgstr "ფაილიდან \"%s\" წაკითხვის შეცდ #, c-format msgid "could not write file \"%s\": wrote %zd of %d" msgstr "ფაილში \"%s\" ჩაწერა შეუძლებელია. ჩაწერილია %zd %d-დან" - -#, c-format -#~ msgid "\"%s\" contains no entry for \"%s\"" -#~ msgstr "\"%s\" არ შეიცავს ჩანაწერს \"%s\"-სთვის" - -#, c-format -#~ msgid "\"%s\" does not exist" -#~ msgstr "\"%s\" არ არსებობს" - -#, c-format -#~ msgid "%s: could not parse version number" -#~ msgstr "%s: ვერსის ნომრის დამუშავების შეცდომა" - -#, c-format -#~ msgid "could not close \"%s\": %m" -#~ msgstr "\"%s\" ვერ დავხურე: %m" - -#, c-format -#~ msgid "could not open \"%s\": %m" -#~ msgstr "\"%s\" ვერ გავხსენი: %m" - -#, c-format -#~ msgid "could not read file \"%s\": read only %d of %d bytes at offset %llu" -#~ msgstr "ვერ წავიკითხე ფაილი \"%s\": წავიკითხე, მხოლოდ %d ბაიტი %d-დან წანაცვლებაზე %llu" - -#, c-format -#~ msgid "could not read file \"%s\": read only %d of %u bytes" -#~ msgstr "ვერ წავიკითხე ფაილი \"%s\": წავიკითხე, მხოლოდ, %d ბაიტი %u-დან" - -#, c-format -#~ msgid "could not read file \"%s\": read only %zd of %lld bytes" -#~ msgstr "ვერ წავიკითხე ფაილი \"%s\": წავიკითხე, მხოლოდ, %zd ბაიტი %lld-დან" - -#, c-format -#~ msgid "could not stat \"%s\": %m" -#~ msgstr "\"%s\" ვერ აღმოვაჩინე: %m" - -#, c-format -#~ msgid "could not write \"%s\": %m" -#~ msgstr "\"%s\"-ში ჩაწერის შეცდომა: %m" - -#, c-format -#~ msgid "could not write file \"%s\": wrote only %d of %d bytes" -#~ msgstr "ვერ ჩავწერე ფაილი \"%s\": ჩავწერე, მხოლოდ, %d ბაიტი %d-დან" - -#, c-format -#~ msgid "could not write file \"%s\": wrote only %d of %d bytes at offset %u" -#~ msgstr "ფაილში \"%s\" ჩაწერის შეცდომა: ჩავწერე მხოლოდ %d ბაიტი %d-დან , წანაცვლებაზე %u" - -#, c-format -#~ msgid "error while linking file from \"%s\" to \"%s\": %m" -#~ msgstr "შეცდომა ფაილის ბმულის შექმნისას \"%s\"-დან \"%s\"-მდე: %m" - -#, c-format -#~ msgid "unexpected json parse error type: %d" -#~ msgstr "მოულოდნელი json-ის დამუშავების შეცდომის ტიპი: %d" diff --git a/src/bin/pg_config/po/ka.po b/src/bin/pg_config/po/ka.po index 6a46e3a88c1..c51c4091cbf 100644 --- a/src/bin/pg_config/po/ka.po +++ b/src/bin/pg_config/po/ka.po @@ -284,14 +284,3 @@ msgstr "%s: საკუთარი პროგრამის გამშვ msgid "%s: invalid argument: %s\n" msgstr "%s: არასწორი არგუმენტი: %s\n" -#, c-format -#~ msgid "could not change directory to \"%s\": %m" -#~ msgstr "საქაღალდის %s-ზე შეცვლის შეცდომა: %m" - -#, c-format -#~ msgid "could not identify current directory: %m" -#~ msgstr "მიმდინარე საქაღალდის იდენტიფიკაციის პრობლემა: %m" - -#, c-format -#~ msgid "could not read symbolic link \"%s\": %m" -#~ msgstr "სიმბოლური ბმის \"%s\" წაკითხვის შეცდომა: %m" diff --git a/src/bin/pg_controldata/po/ka.po b/src/bin/pg_controldata/po/ka.po index 4b77c3f3d02..4ffbe6a9dd6 100644 --- a/src/bin/pg_controldata/po/ka.po +++ b/src/bin/pg_controldata/po/ka.po @@ -551,26 +551,3 @@ msgstr "უნიშნო" msgid "Mock authentication nonce: %s\n" msgstr "ფსევდოავთენტიკაციის შემთხვევითი რიცხვი: %s\n" -#, c-format -#~ msgid "" -#~ "The WAL segment size stored in the file, %d byte, is not a power of two\n" -#~ "between 1 MB and 1 GB. The file is corrupt and the results below are\n" -#~ "untrustworthy.\n" -#~ "\n" -#~ msgid_plural "" -#~ "The WAL segment size stored in the file, %d bytes, is not a power of two\n" -#~ "between 1 MB and 1 GB. The file is corrupt and the results below are\n" -#~ "untrustworthy.\n" -#~ "\n" -#~ msgstr[0] "" -#~ "ფაილში შენახული WAL სეგმენტის ზომა, %d ბაიტი, არ არის ორის \n" -#~ "ხარისხი1 მბ-დან 1 გბ-მდე. ფაილი დაზიანებულია და ქვემოთ მოცემულია შედეგები\n" -#~ "არასანდოა.\n" -#~ msgstr[1] "" -#~ "ფაილში შენახული WAL სეგმენტის ზომა, %d ბაიტი, არ არის ორის \n" -#~ "ხარისხი1 მბ-დან 1 გბ-მდე. ფაილი დაზიანებულია და ქვემოთ მოცემულია შედეგები\n" -#~ "არასანდოა.\n" - -#, c-format -#~ msgid "WARNING: invalid WAL segment size\n" -#~ msgstr "გაფრთხლება: WAL-ის სეგმენტის არასწორი ზომა\n" diff --git a/src/bin/pg_ctl/po/ka.po b/src/bin/pg_ctl/po/ka.po index dcd28b91a4c..bd379a0c169 100644 --- a/src/bin/pg_ctl/po/ka.po +++ b/src/bin/pg_ctl/po/ka.po @@ -866,22 +866,3 @@ msgstr "%s: ოპერაცია მითითებული არაა msgid "%s: no database directory specified and environment variable PGDATA unset\n" msgstr "%s: ბაზის საქაღალდე და გარემოს ცვლადი PGDATA მითითებული არაა\n" -#, c-format -#~ msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -#~ msgstr "%s: გაფრთხილება: ამ პლატფორმაზე შეზღუდული კოდების შექმნა შეუძლებელია\n" - -#, c-format -#~ msgid "%s: WARNING: could not locate all job object functions in system API\n" -#~ msgstr "%s: გაფრთხილება: სისტემურ API-ში დავალების ობიექტის ყველა ფუნქცია არ არსებობს\n" - -#, c-format -#~ msgid "could not change directory to \"%s\": %m" -#~ msgstr "საქაღალდის %s-ზე შეცვლის შეცდომა: %m" - -#, c-format -#~ msgid "could not identify current directory: %m" -#~ msgstr "მიმდინარე საქაღალდის იდენტიფიკაციის პრობლემა: %m" - -#, c-format -#~ msgid "could not read symbolic link \"%s\": %m" -#~ msgstr "სიმბოლური ბმის \"%s\" წაკითხვის შეცდომა: %m" diff --git a/src/bin/pg_dump/po/de.po b/src/bin/pg_dump/po/de.po index 3361d61e8f7..0a2aaf390b2 100644 --- a/src/bin/pg_dump/po/de.po +++ b/src/bin/pg_dump/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-28 19:25+0000\n" -"PO-Revision-Date: 2026-04-26 12:25+0200\n" +"POT-Creation-Date: 2026-06-30 04:25+0000\n" +"PO-Revision-Date: 2026-07-04 01:15+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -124,7 +124,7 @@ msgstr "konnte nicht von Befehl »%s« lesen: %m" msgid "no data was returned by command \"%s\"" msgstr "Befehl »%s« gab keine Daten zurück" -#: ../../common/exec.c:406 parallel.c:1625 +#: ../../common/exec.c:406 parallel.c:1611 #, c-format msgid "%s() failed: %m" msgstr "%s() fehlgeschlagen: %m" @@ -156,7 +156,6 @@ msgstr "ungültige Speicheranforderungsgröße %zu * %zu\n" #: ../../common/file_utils.c:69 ../../common/file_utils.c:370 #: ../../common/file_utils.c:428 ../../common/file_utils.c:502 -#: pg_dumpall.c:2037 pg_restore.c:1075 #, c-format msgid "could not open file \"%s\": %m" msgstr "konnte Datei »%s« nicht öffnen: %m" @@ -242,17 +241,21 @@ msgstr "%s muss im Bereich %d..%d sein" msgid "unrecognized sync method: %s" msgstr "unbekannte Sync-Methode: %s" -#: ../../fe_utils/option_utils.c:139 +#: ../../fe_utils/option_utils.c:139 pg_dumpall.c:411 pg_dumpall.c:419 +#: pg_dumpall.c:431 pg_dumpall.c:436 pg_restore.c:355 pg_restore.c:362 +#: pg_restore.c:382 pg_restore.c:385 pg_restore.c:388 pg_restore.c:393 +#: pg_restore.c:396 pg_restore.c:399 pg_restore.c:404 pg_restore.c:409 +#: pg_restore.c:412 pg_restore.c:416 pg_restore.c:420 pg_restore.c:428 #, c-format msgid "options %s and %s cannot be used together" msgstr "Optionen %s und %s können nicht zusammen verwendet werden" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "Argument des Shell-Befehls enthält Newline oder Carriage Return: »%s«\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "Datenbankname enthält Newline oder Carriage Return: »%s«\n" @@ -621,7 +624,7 @@ msgstr "Passwort: " msgid "%s" msgstr "%s" -#: connectdb.c:157 pg_dumpall.c:595 pg_restore.c:1184 +#: connectdb.c:157 pg_dumpall.c:524 #, c-format msgid "could not connect to database \"%s\"" msgstr "konnte nicht mit der Datenbank »%s« verbinden" @@ -646,22 +649,22 @@ msgstr "Abbruch wegen unpassender Serverversion" msgid "server version: %s; %s version: %s" msgstr "Version des Servers: %s; Version von %s: %s" -#: connectdb.c:282 pg_dumpall.c:2243 +#: connectdb.c:282 pg_dumpall.c:1806 #, c-format msgid "executing %s" msgstr "führe %s aus" -#: connectdb.c:288 pg_backup_db.c:210 pg_dumpall.c:2249 +#: connectdb.c:288 pg_backup_db.c:210 pg_dumpall.c:1812 #, c-format msgid "query failed: %s" msgstr "Anfrage fehlgeschlagen: %s" -#: connectdb.c:289 pg_backup_db.c:212 pg_dumpall.c:2250 +#: connectdb.c:289 pg_backup_db.c:212 pg_dumpall.c:1813 #, c-format msgid "Query was: %s" msgstr "Anfrage war: %s" -#: dumputils.c:956 pg_dumpall.c:2030 +#: dumputils.c:956 #, c-format msgid "could not create directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" @@ -731,27 +734,27 @@ msgstr "nicht unterstützter Filterobjekttyp: »%.*s«" msgid "%s() failed: error code %d" msgstr "%s() fehlgeschlagen: Fehlercode %d" -#: parallel.c:975 +#: parallel.c:961 #, c-format msgid "could not create communication channels: %m" msgstr "konnte Kommunikationskanäle nicht erzeugen: %m" -#: parallel.c:1032 +#: parallel.c:1018 #, c-format msgid "could not create worker process: %m" msgstr "konnte Arbeitsprozess nicht erzeugen: %m" -#: parallel.c:1162 +#: parallel.c:1148 #, c-format msgid "unrecognized command received from leader: \"%s\"" msgstr "unbekannter Befehl vom Leader-Prozess empfangen: »%s«" -#: parallel.c:1205 parallel.c:1443 +#: parallel.c:1191 parallel.c:1429 #, c-format msgid "invalid message received from worker: \"%s\"" msgstr "ungültige Nachricht vom Arbeitsprozess empfangen: »%s«" -#: parallel.c:1337 +#: parallel.c:1323 #, c-format msgid "" "could not obtain lock on relation \"%s\"\n" @@ -760,52 +763,52 @@ msgstr "" "konnte Sperre für Relation »%s« nicht setzen\n" "Das bedeutet meistens, dass jemand eine ACCESS-EXCLUSIVE-Sperre auf die Tabelle gesetzt hat, nachdem der pg-dump-Elternprozess die anfängliche ACCESS-SHARE-Sperre gesetzt hatte." -#: parallel.c:1426 +#: parallel.c:1412 #, c-format msgid "a worker process died unexpectedly" msgstr "ein Arbeitsprozess endete unerwartet" -#: parallel.c:1548 parallel.c:1666 +#: parallel.c:1534 parallel.c:1652 #, c-format msgid "could not write to the communication channel: %m" msgstr "konnte nicht in den Kommunikationskanal schreiben: %m" -#: parallel.c:1750 +#: parallel.c:1736 #, c-format msgid "pgpipe: could not create socket: error code %d" msgstr "pgpipe: konnte Socket nicht erzeugen: Fehlercode %d" -#: parallel.c:1761 +#: parallel.c:1747 #, c-format msgid "pgpipe: could not bind: error code %d" msgstr "pgpipe: konnte nicht binden: Fehlercode %d" -#: parallel.c:1768 +#: parallel.c:1754 #, c-format msgid "pgpipe: could not listen: error code %d" msgstr "pgpipe: konnte nicht auf Socket hören: Fehlercode %d" -#: parallel.c:1775 +#: parallel.c:1761 #, c-format msgid "pgpipe: %s() failed: error code %d" msgstr "pgpipe: %s() fehlgeschlagen: Fehlercode %d" -#: parallel.c:1786 +#: parallel.c:1772 #, c-format msgid "pgpipe: could not create second socket: error code %d" msgstr "pgpipe: konnte zweites Socket nicht erzeugen: Fehlercode %d" -#: parallel.c:1795 +#: parallel.c:1781 #, c-format msgid "pgpipe: could not connect socket: error code %d" msgstr "pgpipe: konnte Socket nicht verbinden: Fehlercode %d" -#: parallel.c:1804 +#: parallel.c:1790 #, c-format msgid "pgpipe: could not accept connection: error code %d" msgstr "pgpipe: konnte Verbindung nicht annehmen: Fehlercode %d" -#: pg_backup_archiver.c:272 pg_backup_archiver.c:1770 +#: pg_backup_archiver.c:272 pg_backup_archiver.c:1748 #, c-format msgid "could not close output file: %m" msgstr "konnte Ausgabedatei nicht schließen: %m" @@ -820,442 +823,442 @@ msgstr "Archivelemente nicht in richtiger Abschnittsreihenfolge" msgid "unexpected section code %d" msgstr "unerwarteter Abschnittscode %d" -#: pg_backup_archiver.c:368 +#: pg_backup_archiver.c:363 #, c-format msgid "parallel restore is not supported with this archive file format" msgstr "parallele Wiederherstellung wird von diesem Archivdateiformat nicht unterstützt" -#: pg_backup_archiver.c:372 +#: pg_backup_archiver.c:367 #, c-format msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" msgstr "parallele Wiederherstellung wird mit Archiven, die mit pg_dump vor 8.0 erstellt worden sind, nicht unterstützt" -#: pg_backup_archiver.c:393 +#: pg_backup_archiver.c:388 #, c-format msgid "cannot restore from compressed archive (%s)" msgstr "kann komprimiertes Archiv nicht wiederherstellen (%s)" -#: pg_backup_archiver.c:413 +#: pg_backup_archiver.c:408 #, c-format msgid "connecting to database for restore" msgstr "verbinde mit der Datenbank zur Wiederherstellung" -#: pg_backup_archiver.c:415 +#: pg_backup_archiver.c:410 #, c-format msgid "direct database connections are not supported in pre-1.3 archives" msgstr "direkte Datenbankverbindungen sind in Archiven vor Version 1.3 nicht unterstützt" -#: pg_backup_archiver.c:458 +#: pg_backup_archiver.c:453 #, c-format msgid "implied no-schema restore" msgstr "implizit wird das Schema nicht wiederhergestellt" -#: pg_backup_archiver.c:537 +#: pg_backup_archiver.c:532 #, c-format msgid "dropping %s %s" msgstr "entferne %s %s" -#: pg_backup_archiver.c:669 +#: pg_backup_archiver.c:664 #, c-format msgid "could not find where to insert IF EXISTS in statement \"%s\"" msgstr "konnte nicht bestimmen, wo IF EXISTS in die Anweisung »%s« eingefügt werden soll" -#: pg_backup_archiver.c:876 pg_backup_archiver.c:878 +#: pg_backup_archiver.c:858 pg_backup_archiver.c:860 #, c-format msgid "warning from original dump file: %s" msgstr "Warnung aus der ursprünglichen Ausgabedatei: %s" -#: pg_backup_archiver.c:912 +#: pg_backup_archiver.c:894 #, c-format msgid "creating %s \"%s.%s\"" msgstr "erstelle %s »%s.%s«" -#: pg_backup_archiver.c:915 +#: pg_backup_archiver.c:897 #, c-format msgid "creating %s \"%s\"" msgstr "erstelle %s »%s«" -#: pg_backup_archiver.c:965 +#: pg_backup_archiver.c:947 #, c-format msgid "connecting to new database \"%s\"" msgstr "verbinde mit neuer Datenbank »%s«" -#: pg_backup_archiver.c:992 +#: pg_backup_archiver.c:974 #, c-format msgid "processing %s" msgstr "verarbeite %s" -#: pg_backup_archiver.c:1014 +#: pg_backup_archiver.c:996 #, c-format msgid "processing data for table \"%s.%s\"" msgstr "verarbeite Daten für Tabelle »%s.%s«" -#: pg_backup_archiver.c:1084 +#: pg_backup_archiver.c:1066 #, c-format msgid "executing %s %s" msgstr "führe %s %s aus" -#: pg_backup_archiver.c:1153 +#: pg_backup_archiver.c:1135 #, c-format msgid "disabling triggers for %s" msgstr "schalte Trigger für %s aus" -#: pg_backup_archiver.c:1179 +#: pg_backup_archiver.c:1161 #, c-format msgid "enabling triggers for %s" msgstr "schalte Trigger für %s ein" -#: pg_backup_archiver.c:1244 +#: pg_backup_archiver.c:1226 #, c-format msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" msgstr "interner Fehler -- WriteData kann nicht außerhalb des Kontexts einer DataDumper-Routine aufgerufen werden" -#: pg_backup_archiver.c:1439 +#: pg_backup_archiver.c:1421 #, c-format msgid "large-object output not supported in chosen format" msgstr "Large-Object-Ausgabe im gewählten Format nicht unterstützt" -#: pg_backup_archiver.c:1502 +#: pg_backup_archiver.c:1484 #, c-format msgid "restored %d large object" msgid_plural "restored %d large objects" msgstr[0] "%d Large Object wiederhergestellt" msgstr[1] "%d Large Objects wiederhergestellt" -#: pg_backup_archiver.c:1529 pg_backup_tar.c:683 +#: pg_backup_archiver.c:1511 pg_backup_tar.c:683 #, c-format msgid "restoring large object with OID %u" msgstr "Wiederherstellung von Large Object mit OID %u" -#: pg_backup_archiver.c:1541 +#: pg_backup_archiver.c:1523 #, c-format msgid "could not create large object %u: %s" msgstr "konnte Large Object %u nicht erstellen: %s" -#: pg_backup_archiver.c:1546 pg_dump.c:4197 +#: pg_backup_archiver.c:1528 pg_dump.c:4197 #, c-format msgid "could not open large object %u: %s" msgstr "konnte Large Object %u nicht öffnen: %s" -#: pg_backup_archiver.c:1602 +#: pg_backup_archiver.c:1584 #, c-format msgid "could not open TOC file \"%s\": %m" msgstr "konnte Inhaltsverzeichnisdatei »%s« nicht öffnen: %m" -#: pg_backup_archiver.c:1630 +#: pg_backup_archiver.c:1612 #, c-format msgid "line ignored: %s" msgstr "Zeile ignoriert: %s" -#: pg_backup_archiver.c:1637 pg_backup_db.c:548 +#: pg_backup_archiver.c:1619 pg_backup_db.c:548 #, c-format msgid "could not find entry for ID %d" msgstr "konnte Eintrag für ID %d nicht finden" -#: pg_backup_archiver.c:1660 pg_backup_directory.c:187 +#: pg_backup_archiver.c:1642 pg_backup_directory.c:187 #: pg_backup_directory.c:563 #, c-format msgid "could not close TOC file: %m" msgstr "konnte Inhaltsverzeichnisdatei nicht schließen: %m" -#: pg_backup_archiver.c:1751 pg_backup_custom.c:151 pg_backup_directory.c:301 +#: pg_backup_archiver.c:1729 pg_backup_custom.c:151 pg_backup_directory.c:301 #: pg_backup_directory.c:550 pg_backup_directory.c:616 -#: pg_backup_directory.c:634 pg_dumpall.c:567 +#: pg_backup_directory.c:634 pg_dumpall.c:558 #, c-format msgid "could not open output file \"%s\": %m" msgstr "konnte Ausgabedatei »%s« nicht öffnen: %m" -#: pg_backup_archiver.c:1753 pg_backup_custom.c:157 +#: pg_backup_archiver.c:1731 pg_backup_custom.c:157 #, c-format msgid "could not open output file: %m" msgstr "konnte Ausgabedatei nicht öffnen: %m" -#: pg_backup_archiver.c:1836 +#: pg_backup_archiver.c:1814 #, c-format msgid "wrote %zu byte of large object data (result = %d)" msgid_plural "wrote %zu bytes of large object data (result = %d)" msgstr[0] "%zu Byte Large-Object-Daten geschrieben (Ergebnis = %d)" msgstr[1] "%zu Bytes Large-Object-Daten geschrieben (Ergebnis = %d)" -#: pg_backup_archiver.c:1842 +#: pg_backup_archiver.c:1820 #, c-format msgid "could not write to large object: %s" msgstr "konnte Large Object nicht schreiben: %s" -#: pg_backup_archiver.c:1932 +#: pg_backup_archiver.c:1910 #, c-format msgid "while INITIALIZING:" msgstr "in Phase INITIALIZING:" -#: pg_backup_archiver.c:1937 +#: pg_backup_archiver.c:1915 #, c-format msgid "while PROCESSING TOC:" msgstr "in Phase PROCESSING TOC:" -#: pg_backup_archiver.c:1942 +#: pg_backup_archiver.c:1920 #, c-format msgid "while FINALIZING:" msgstr "in Phase FINALIZING:" -#: pg_backup_archiver.c:1947 +#: pg_backup_archiver.c:1925 #, c-format msgid "from TOC entry %d; %u %u %s %s %s" msgstr "in Inhaltsverzeichniseintrag %d; %u %u %s %s %s" -#: pg_backup_archiver.c:2023 +#: pg_backup_archiver.c:2001 #, c-format msgid "bad dumpId" msgstr "ungültige DumpId" -#: pg_backup_archiver.c:2044 +#: pg_backup_archiver.c:2022 #, c-format msgid "bad table dumpId for TABLE DATA item" msgstr "ungültige Tabellen-DumpId für »TABLE DATA«-Eintrag" -#: pg_backup_archiver.c:2136 +#: pg_backup_archiver.c:2114 #, c-format msgid "unexpected data offset flag %d" msgstr "unerwartete Datenoffsetmarkierung %d" -#: pg_backup_archiver.c:2149 +#: pg_backup_archiver.c:2127 #, c-format msgid "file offset in dump file is too large" msgstr "Dateioffset in Dumpdatei ist zu groß" -#: pg_backup_archiver.c:2260 pg_restore.c:939 +#: pg_backup_archiver.c:2238 #, c-format msgid "directory name too long: \"%s\"" msgstr "Verzeichnisname zu lang: »%s«" -#: pg_backup_archiver.c:2310 +#: pg_backup_archiver.c:2288 #, c-format msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" msgstr "Verzeichnis »%s« scheint kein gültiges Archiv zu sein (»toc.dat« existiert nicht)" -#: pg_backup_archiver.c:2318 pg_backup_custom.c:168 pg_backup_custom.c:820 +#: pg_backup_archiver.c:2296 pg_backup_custom.c:168 pg_backup_custom.c:820 #: pg_backup_directory.c:172 pg_backup_directory.c:358 #, c-format msgid "could not open input file \"%s\": %m" msgstr "konnte Eingabedatei »%s« nicht öffnen: %m" -#: pg_backup_archiver.c:2325 pg_backup_custom.c:174 +#: pg_backup_archiver.c:2303 pg_backup_custom.c:174 #, c-format msgid "could not open input file: %m" msgstr "konnte Eingabedatei nicht öffnen: %m" -#: pg_backup_archiver.c:2331 +#: pg_backup_archiver.c:2309 #, c-format msgid "could not read input file: %m" msgstr "konnte Eingabedatei nicht lesen: %m" -#: pg_backup_archiver.c:2333 +#: pg_backup_archiver.c:2311 #, c-format msgid "input file is too short (read %zu, expected 5)" msgstr "Eingabedatei ist zu kurz (gelesen: %zu, erwartet: 5)" -#: pg_backup_archiver.c:2364 +#: pg_backup_archiver.c:2342 #, c-format msgid "input file appears to be a text format dump. Please use psql." msgstr "Eingabedatei ist anscheinend ein Dump im Textformat. Bitte verwenden Sie psql." -#: pg_backup_archiver.c:2370 +#: pg_backup_archiver.c:2348 #, c-format msgid "input file does not appear to be a valid archive (too short?)" msgstr "Eingabedatei scheint kein gültiges Archiv zu sein (zu kurz?)" -#: pg_backup_archiver.c:2376 +#: pg_backup_archiver.c:2354 #, c-format msgid "input file does not appear to be a valid tar archive" msgstr "Eingabedatei scheint kein gültiges Tar-Archiv zu sein" -#: pg_backup_archiver.c:2385 +#: pg_backup_archiver.c:2363 #, c-format msgid "could not close input file: %m" msgstr "konnte Eingabedatei nicht schließen: %m" -#: pg_backup_archiver.c:2464 +#: pg_backup_archiver.c:2442 #, c-format msgid "could not open stdout for appending: %m" msgstr "konnte Standardausgabe nicht zum Anhängen öffnen: %m" -#: pg_backup_archiver.c:2509 +#: pg_backup_archiver.c:2487 #, c-format msgid "unrecognized file format \"%d\"" msgstr "nicht erkanntes Dateiformat »%d«" -#: pg_backup_archiver.c:2590 pg_backup_archiver.c:4859 +#: pg_backup_archiver.c:2568 pg_backup_archiver.c:4845 #, c-format msgid "finished item %d %s %s" msgstr "Element %d %s %s abgeschlossen" -#: pg_backup_archiver.c:2594 pg_backup_archiver.c:4872 +#: pg_backup_archiver.c:2572 pg_backup_archiver.c:4858 #, c-format msgid "worker process failed: exit code %d" msgstr "Arbeitsprozess fehlgeschlagen: Code %d" -#: pg_backup_archiver.c:2692 +#: pg_backup_archiver.c:2670 #, c-format msgid "unexpected TOC entry in WriteToc(): %d %s %s" msgstr "unerwarteter TOC-Eintrag in WriteToc(): %d %s %s" -#: pg_backup_archiver.c:2696 pg_backup_custom.c:440 pg_backup_custom.c:506 +#: pg_backup_archiver.c:2674 pg_backup_custom.c:440 pg_backup_custom.c:506 #: pg_backup_custom.c:642 pg_backup_custom.c:878 pg_backup_tar.c:1004 #: pg_backup_tar.c:1009 #, c-format msgid "error during file seek: %m" msgstr "Fehler beim Suchen in Datei: %m" -#: pg_backup_archiver.c:2754 +#: pg_backup_archiver.c:2732 #, c-format msgid "entry ID %d out of range -- perhaps a corrupt TOC" msgstr "ID %d des Eintrags außerhalb des gültigen Bereichs -- vielleicht ein verfälschtes Inhaltsverzeichnis" -#: pg_backup_archiver.c:2837 +#: pg_backup_archiver.c:2815 #, c-format msgid "restoring tables WITH OIDS is not supported anymore" msgstr "Wiederherstellung von Tabellen mit WITH OIDS wird nicht mehr unterstützt" -#: pg_backup_archiver.c:2919 +#: pg_backup_archiver.c:2897 #, c-format msgid "unrecognized encoding \"%s\"" msgstr "nicht erkannte Kodierung »%s«" -#: pg_backup_archiver.c:2925 +#: pg_backup_archiver.c:2903 #, c-format msgid "invalid ENCODING item: %s" msgstr "ungültiger ENCODING-Eintrag: %s" -#: pg_backup_archiver.c:2943 +#: pg_backup_archiver.c:2921 #, c-format msgid "invalid STDSTRINGS item: %s" msgstr "ungültiger STDSTRINGS-Eintrag: %s" -#: pg_backup_archiver.c:2968 +#: pg_backup_archiver.c:2946 #, c-format msgid "schema \"%s\" not found" msgstr "Schema »%s« nicht gefunden" -#: pg_backup_archiver.c:2975 +#: pg_backup_archiver.c:2953 #, c-format msgid "table \"%s\" not found" msgstr "Tabelle »%s« nicht gefunden" -#: pg_backup_archiver.c:2982 +#: pg_backup_archiver.c:2960 #, c-format msgid "index \"%s\" not found" msgstr "Index »%s« nicht gefunden" -#: pg_backup_archiver.c:2989 +#: pg_backup_archiver.c:2967 #, c-format msgid "function \"%s\" not found" msgstr "Funktion »%s« nicht gefunden" -#: pg_backup_archiver.c:2996 +#: pg_backup_archiver.c:2974 #, c-format msgid "trigger \"%s\" not found" msgstr "Trigger »%s« nicht gefunden" -#: pg_backup_archiver.c:3528 +#: pg_backup_archiver.c:3517 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "konnte Sitzungsbenutzer nicht auf »%s« setzen: %s" -#: pg_backup_archiver.c:3670 +#: pg_backup_archiver.c:3659 #, c-format msgid "could not set \"search_path\" to \"%s\": %s" msgstr "konnte »search_path« nicht auf »%s« setzen: %s" -#: pg_backup_archiver.c:3731 +#: pg_backup_archiver.c:3720 #, c-format msgid "could not set \"default_tablespace\" to %s: %s" msgstr "konnte »default_tablespace« nicht auf »%s« setzen: %s" -#: pg_backup_archiver.c:3780 +#: pg_backup_archiver.c:3769 #, c-format msgid "could not set \"default_table_access_method\": %s" msgstr "konnte »default_table_access_method« nicht setzen: %s" -#: pg_backup_archiver.c:3829 +#: pg_backup_archiver.c:3818 #, c-format msgid "could not alter table access method: %s" msgstr "konnte Tabellenzugriffsmethode nicht ändern: %s" -#: pg_backup_archiver.c:3934 +#: pg_backup_archiver.c:3920 #, c-format msgid "don't know how to set owner for object type \"%s\"" msgstr "kann Eigentümer für Objekttyp »%s« nicht setzen" -#: pg_backup_archiver.c:4069 +#: pg_backup_archiver.c:4055 #, c-format msgid "unexpected TOC entry in _printTocEntry(): %d %s %s" msgstr "unerwarteter TOC-Eintrag in _printTocEntry(): %d %s %s" -#: pg_backup_archiver.c:4217 +#: pg_backup_archiver.c:4203 #, c-format msgid "did not find magic string in file header" msgstr "magische Zeichenkette im Dateikopf nicht gefunden" -#: pg_backup_archiver.c:4231 +#: pg_backup_archiver.c:4217 #, c-format msgid "unsupported version (%d.%d) in file header" msgstr "nicht unterstützte Version (%d.%d) im Dateikopf" -#: pg_backup_archiver.c:4236 +#: pg_backup_archiver.c:4222 #, c-format msgid "sanity check on integer size (%zu) failed" msgstr "Prüfung der Integer-Größe (%zu) fehlgeschlagen" -#: pg_backup_archiver.c:4239 +#: pg_backup_archiver.c:4225 #, c-format msgid "archive was made on a machine with larger integers, some operations might fail" msgstr "Archiv wurde auf einer Maschine mit größeren Integers erstellt; einige Operationen könnten fehlschlagen" -#: pg_backup_archiver.c:4249 +#: pg_backup_archiver.c:4235 #, c-format msgid "expected format (%d) differs from format found in file (%d)" msgstr "erwartetes Format (%d) ist nicht das gleiche wie das in der Datei gefundene (%d)" -#: pg_backup_archiver.c:4271 +#: pg_backup_archiver.c:4257 #, c-format msgid "archive is compressed, but this installation does not support compression (%s) -- no data will be available" msgstr "Archiv ist komprimiert, aber diese Installation unterstützt keine Komprimierung (%s) -- keine Daten verfügbar" -#: pg_backup_archiver.c:4307 +#: pg_backup_archiver.c:4293 #, c-format msgid "invalid creation date in header" msgstr "ungültiges Erstellungsdatum im Kopf" -#: pg_backup_archiver.c:4441 +#: pg_backup_archiver.c:4427 #, c-format msgid "processing item %d %s %s" msgstr "verarbeite Element %d %s %s" -#: pg_backup_archiver.c:4526 +#: pg_backup_archiver.c:4512 #, c-format msgid "entering main parallel loop" msgstr "Eintritt in Hauptparallelschleife" -#: pg_backup_archiver.c:4537 +#: pg_backup_archiver.c:4523 #, c-format msgid "skipping item %d %s %s" msgstr "Element %d %s %s wird übersprungen" -#: pg_backup_archiver.c:4546 +#: pg_backup_archiver.c:4532 #, c-format msgid "launching item %d %s %s" msgstr "starte Element %d %s %s" -#: pg_backup_archiver.c:4600 +#: pg_backup_archiver.c:4586 #, c-format msgid "finished main parallel loop" msgstr "Hauptparallelschleife beendet" -#: pg_backup_archiver.c:4636 +#: pg_backup_archiver.c:4622 #, c-format msgid "processing missed item %d %s %s" msgstr "verarbeite verpasstes Element %d %s %s" -#: pg_backup_archiver.c:5178 +#: pg_backup_archiver.c:5164 #, c-format msgid "table \"%s\" could not be created, will not restore its data" msgstr "Tabelle »%s« konnte nicht erzeugt werden, ihre Daten werden nicht wiederhergestellt werden" @@ -1523,9 +1526,10 @@ msgstr "beschädigter Tar-Kopf in %s gefunden (%d erwartet, %d berechnet), Datei msgid "unrecognized section name: \"%s\"" msgstr "unbekannter Abschnittsname: »%s«" -#: pg_backup_utils.c:57 pg_dump.c:804 pg_dump.c:821 pg_dumpall.c:410 -#: pg_dumpall.c:420 pg_dumpall.c:478 pg_dumpall.c:611 pg_restore.c:361 -#: pg_restore.c:377 pg_restore.c:585 pg_restore.c:1207 +#: pg_backup_utils.c:57 pg_dump.c:804 pg_dump.c:821 pg_dumpall.c:384 +#: pg_dumpall.c:394 pg_dumpall.c:404 pg_dumpall.c:413 pg_dumpall.c:421 +#: pg_dumpall.c:438 pg_dumpall.c:540 pg_restore.c:326 pg_restore.c:342 +#: pg_restore.c:357 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Versuchen Sie »%s --help« für weitere Informationen." @@ -1535,7 +1539,7 @@ msgstr "Versuchen Sie »%s --help« für weitere Informationen." msgid "out of on_exit_nicely slots" msgstr "on_exit_nicely-Slots aufgebraucht" -#: pg_dump.c:819 pg_dumpall.c:418 pg_restore.c:375 +#: pg_dump.c:819 pg_dumpall.c:392 pg_restore.c:340 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" @@ -1545,7 +1549,7 @@ msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" msgid "option %s is not supported with parallel backup" msgstr "Option %s wird nicht mit paralleler Sicherung unterstützt" -#: pg_dump.c:864 pg_dumpall.c:463 pg_restore.c:490 +#: pg_dump.c:864 pg_dumpall.c:426 pg_restore.c:460 #, c-format msgid "option %s requires option %s" msgstr "Option %s erfordert Option %s" @@ -1555,12 +1559,12 @@ msgstr "Option %s erfordert Option %s" msgid "option %s requires option %s, %s, or %s" msgstr "Option %s erfordert Option %s, %s oder %s" -#: pg_dump.c:903 pg_dumpall.c:579 pg_restore.c:407 +#: pg_dump.c:903 pg_dumpall.c:508 pg_restore.c:375 #, c-format msgid "could not generate restrict key" msgstr "konnte Restrict-Schlüssel nicht erzeugen" -#: pg_dump.c:905 pg_dumpall.c:581 pg_restore.c:409 +#: pg_dump.c:905 pg_dumpall.c:510 pg_restore.c:377 #, c-format msgid "invalid restrict key" msgstr "ungültiger Restrict-Schlüssel" @@ -1619,7 +1623,7 @@ msgstr "" "%s exportiert eine PostgreSQL-Datenbank als SQL-Skript oder in anderen Formaten.\n" "\n" -#: pg_dump.c:1294 pg_dumpall.c:872 pg_restore.c:749 +#: pg_dump.c:1294 pg_dumpall.c:705 pg_restore.c:536 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" @@ -1629,7 +1633,7 @@ msgstr "Aufruf:\n" msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [OPTION]... [DBNAME]\n" -#: pg_dump.c:1297 pg_dumpall.c:875 pg_restore.c:752 +#: pg_dump.c:1297 pg_dumpall.c:708 pg_restore.c:539 #, c-format msgid "" "\n" @@ -1643,7 +1647,7 @@ msgstr "" msgid " -f, --file=FILENAME output file or directory name\n" msgstr " -f, --file=DATEINAME Name der Ausgabedatei oder des -verzeichnisses\n" -#: pg_dump.c:1299 pg_dumpall.c:877 +#: pg_dump.c:1299 #, c-format msgid "" " -F, --format=c|d|t|p output file format (custom, directory, tar,\n" @@ -1657,12 +1661,12 @@ msgstr "" msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" msgstr " -j, --jobs=NUM so viele parallele Jobs zur Sicherung verwenden\n" -#: pg_dump.c:1302 pg_dumpall.c:879 +#: pg_dump.c:1302 pg_dumpall.c:710 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose »Verbose«-Modus\n" -#: pg_dump.c:1303 pg_dumpall.c:880 +#: pg_dump.c:1303 pg_dumpall.c:711 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" @@ -1676,12 +1680,12 @@ msgstr "" " -Z, --compress=METHODE[:DETAIL]\n" " wie angegeben komprimieren\n" -#: pg_dump.c:1306 pg_dumpall.c:881 +#: pg_dump.c:1306 pg_dumpall.c:712 #, c-format msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" msgstr " --lock-wait-timeout=ZEIT Abbruch nach ZEIT Warten auf Tabellensperre\n" -#: pg_dump.c:1307 pg_dumpall.c:913 +#: pg_dump.c:1307 pg_dumpall.c:744 #, c-format msgid " --no-sync do not wait for changes to be written safely to disk\n" msgstr "" @@ -1695,12 +1699,12 @@ msgstr "" " --sync-method=METHODE Methode zum Synchronisieren von Dateien auf\n" " Festplatte setzen\n" -#: pg_dump.c:1309 pg_dumpall.c:882 +#: pg_dump.c:1309 pg_dumpall.c:713 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_dump.c:1311 pg_dumpall.c:883 +#: pg_dump.c:1311 pg_dumpall.c:714 #, c-format msgid "" "\n" @@ -1709,7 +1713,7 @@ msgstr "" "\n" "Optionen die den Inhalt der Ausgabe kontrollieren:\n" -#: pg_dump.c:1312 pg_dumpall.c:884 +#: pg_dump.c:1312 pg_dumpall.c:715 #, c-format msgid " -a, --data-only dump only the data, not the schema or statistics\n" msgstr " -a, --data-only nur die Daten ausgeben, nicht das Schema oder Statistiken\n" @@ -1734,7 +1738,7 @@ msgstr " -B, --no-large-objects Large Objects nicht mit ausgeben\n" msgid " --no-blobs (same as --no-large-objects, deprecated)\n" msgstr " --no-blobs (gleich --no-large-objects, veraltet)\n" -#: pg_dump.c:1317 pg_restore.c:763 +#: pg_dump.c:1317 pg_restore.c:550 #, c-format msgid " -c, --clean clean (drop) database objects before recreating\n" msgstr " -c, --clean Datenbankobjekte vor der Wiedererstellung löschen\n" @@ -1751,7 +1755,7 @@ msgstr "" msgid " -e, --extension=PATTERN dump the specified extension(s) only\n" msgstr " -e, --extension=MUSTER nur die angegebene(n) Erweiterung(en) ausgeben\n" -#: pg_dump.c:1320 pg_dumpall.c:886 +#: pg_dump.c:1320 pg_dumpall.c:717 #, c-format msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" msgstr " -E, --encoding=KODIERUNG Daten in Kodierung KODIERUNG ausgeben\n" @@ -1775,7 +1779,7 @@ msgstr "" " -O, --no-owner Wiederherstellung der Objekteigentümerschaft im\n" " »plain text«-Format auslassen\n" -#: pg_dump.c:1325 pg_dumpall.c:890 +#: pg_dump.c:1325 pg_dumpall.c:721 #, c-format msgid " -s, --schema-only dump only the schema, no data or statistics\n" msgstr " -s, --schema-only nur das Schema ausgeben, nicht Daten oder Statistiken\n" @@ -1795,31 +1799,31 @@ msgstr " -t, --table=MUSTER nur die angegebene(n) Tabelle(n) ausgeben msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" msgstr " -T, --exclude-table=MUSTER die angegebene(n) Tabelle(n) NICHT ausgeben\n" -#: pg_dump.c:1329 pg_dumpall.c:893 +#: pg_dump.c:1329 pg_dumpall.c:724 #, c-format msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" msgstr " -x, --no-privileges Zugriffsprivilegien (grant/revoke) nicht ausgeben\n" -#: pg_dump.c:1330 pg_dumpall.c:894 +#: pg_dump.c:1330 pg_dumpall.c:725 #, c-format msgid " --binary-upgrade for use by upgrade utilities only\n" msgstr " --binary-upgrade wird nur von Upgrade-Programmen verwendet\n" -#: pg_dump.c:1331 pg_dumpall.c:895 +#: pg_dump.c:1331 pg_dumpall.c:726 #, c-format msgid " --column-inserts dump data as INSERT commands with column names\n" msgstr "" " --column-inserts Daten als INSERT-Anweisungen mit Spaltennamen\n" " ausgeben\n" -#: pg_dump.c:1332 pg_dumpall.c:896 +#: pg_dump.c:1332 pg_dumpall.c:727 #, c-format msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" msgstr "" " --disable-dollar-quoting Dollar-Quoting abschalten, normales SQL-Quoting\n" " verwenden\n" -#: pg_dump.c:1333 pg_dumpall.c:897 pg_restore.c:781 +#: pg_dump.c:1333 pg_dumpall.c:728 pg_restore.c:567 #, c-format msgid " --disable-triggers disable triggers during data-only restore\n" msgstr "" @@ -1867,7 +1871,7 @@ msgstr "" " Daten der angegebenen Tabelle(n) NICHT ausgeben,\n" " einschließlich abgeleiteter und Partitionstabellen\n" -#: pg_dump.c:1344 pg_dumpall.c:899 +#: pg_dump.c:1344 pg_dumpall.c:730 #, c-format msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" msgstr " --extra-float-digits=ZAHL Einstellung für extra_float_digits\n" @@ -1881,7 +1885,7 @@ msgstr "" " --filter=DATEINAME Objekte und Daten basierend auf Ausdrücken in DATEINAME\n" " mit sichern oder überspringen\n" -#: pg_dump.c:1347 pg_dumpall.c:901 pg_restore.c:786 +#: pg_dump.c:1347 pg_dumpall.c:732 pg_restore.c:571 #, c-format msgid " --if-exists use IF EXISTS when dropping objects\n" msgstr " --if-exists IF EXISTS verwenden, wenn Objekte gelöscht werden\n" @@ -1897,96 +1901,96 @@ msgstr "" " Daten von Fremdtabellen auf Fremdservern, die\n" " mit MUSTER übereinstimmen, mit sichern\n" -#: pg_dump.c:1351 pg_dumpall.c:902 +#: pg_dump.c:1351 pg_dumpall.c:733 #, c-format msgid " --inserts dump data as INSERT commands, rather than COPY\n" msgstr " --inserts Daten als INSERT-Anweisungen statt COPY ausgeben\n" -#: pg_dump.c:1352 pg_dumpall.c:903 +#: pg_dump.c:1352 pg_dumpall.c:734 #, c-format msgid " --load-via-partition-root load partitions via the root table\n" msgstr " --load-via-partition-root Partitionen über die Wurzeltabelle laden\n" -#: pg_dump.c:1353 pg_dumpall.c:904 +#: pg_dump.c:1353 pg_dumpall.c:735 #, c-format msgid " --no-comments do not dump comment commands\n" msgstr " --no-comments Kommentar-Befehle nicht ausgeben\n" -#: pg_dump.c:1354 pg_dumpall.c:905 +#: pg_dump.c:1354 pg_dumpall.c:736 #, c-format msgid " --no-data do not dump data\n" msgstr " --no-data Daten nicht ausgeben\n" -#: pg_dump.c:1355 pg_dumpall.c:906 +#: pg_dump.c:1355 pg_dumpall.c:737 #, c-format msgid " --no-policies do not dump row security policies\n" msgstr " --no-policies Policys für Sicherheit auf Zeilenebene nicht ausgeben\n" -#: pg_dump.c:1356 pg_dumpall.c:907 +#: pg_dump.c:1356 pg_dumpall.c:738 #, c-format msgid " --no-publications do not dump publications\n" msgstr " --no-publications Publikationen nicht ausgeben\n" -#: pg_dump.c:1357 pg_dumpall.c:909 +#: pg_dump.c:1357 pg_dumpall.c:740 #, c-format msgid " --no-schema do not dump schema\n" msgstr " --no-schema Schema nicht ausgeben\n" -#: pg_dump.c:1358 pg_dumpall.c:910 +#: pg_dump.c:1358 pg_dumpall.c:741 #, c-format msgid " --no-security-labels do not dump security label assignments\n" msgstr " --no-security-labels Security-Label-Zuweisungen nicht ausgeben\n" -#: pg_dump.c:1359 pg_dumpall.c:911 +#: pg_dump.c:1359 pg_dumpall.c:742 #, c-format msgid " --no-statistics do not dump statistics\n" msgstr " --no-statistics Statistiken nicht ausgeben\n" -#: pg_dump.c:1360 pg_dumpall.c:912 +#: pg_dump.c:1360 pg_dumpall.c:743 #, c-format msgid " --no-subscriptions do not dump subscriptions\n" msgstr " --no-subscriptions Subskriptionen nicht ausgeben\n" -#: pg_dump.c:1361 pg_dumpall.c:914 +#: pg_dump.c:1361 pg_dumpall.c:745 #, c-format msgid " --no-table-access-method do not dump table access methods\n" msgstr " --no-table-access-method Tabellenzugriffsmethoden nicht ausgeben\n" -#: pg_dump.c:1362 pg_dumpall.c:915 +#: pg_dump.c:1362 pg_dumpall.c:746 #, c-format msgid " --no-tablespaces do not dump tablespace assignments\n" msgstr " --no-tablespaces Tablespace-Zuordnungen nicht ausgeben\n" -#: pg_dump.c:1363 pg_dumpall.c:916 +#: pg_dump.c:1363 pg_dumpall.c:747 #, c-format msgid " --no-toast-compression do not dump TOAST compression methods\n" msgstr " --no-toast-compression TOAST-Komprimierungsmethoden nicht ausgeben\n" -#: pg_dump.c:1364 pg_dumpall.c:917 +#: pg_dump.c:1364 pg_dumpall.c:748 #, c-format msgid " --no-unlogged-table-data do not dump unlogged table data\n" msgstr " --no-unlogged-table-data Daten in ungeloggten Tabellen nicht ausgeben\n" -#: pg_dump.c:1365 pg_dumpall.c:918 +#: pg_dump.c:1365 pg_dumpall.c:749 #, c-format msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" msgstr " --on-conflict-do-nothing INSERT-Befehle mit ON CONFLICT DO NOTHING ausgeben\n" -#: pg_dump.c:1366 pg_dumpall.c:919 +#: pg_dump.c:1366 pg_dumpall.c:750 #, c-format msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" msgstr "" " --quote-all-identifiers alle Bezeichner in Anführungszeichen, selbst wenn\n" " kein Schlüsselwort\n" -#: pg_dump.c:1367 pg_dumpall.c:920 pg_restore.c:800 +#: pg_dump.c:1367 pg_dumpall.c:751 pg_restore.c:584 #, c-format msgid " --restrict-key=RESTRICT_KEY use provided string as psql \\restrict key\n" msgstr "" " --restrict-key=RESTRICT_KEY angegebene Zeichenkette als Schlüssel für psql\n" " \\restrict verwenden\n" -#: pg_dump.c:1368 pg_dumpall.c:921 +#: pg_dump.c:1368 pg_dumpall.c:752 #, c-format msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" msgstr " --rows-per-insert=ANZAHL Anzahl Zeilen pro INSERT; impliziert --inserts\n" @@ -1998,7 +2002,7 @@ msgstr "" " --section=ABSCHNITT angegebenen Abschnitt ausgeben (pre-data, data\n" " oder post-data)\n" -#: pg_dump.c:1370 pg_dumpall.c:922 +#: pg_dump.c:1370 pg_dumpall.c:753 #, c-format msgid " --sequence-data include sequence data in dump\n" msgstr " --sequence-data Sequenzdaten in Ausgabe einfügen\n" @@ -2013,17 +2017,17 @@ msgstr " --serializable-deferrable warten bis der Dump ohne Anomalien laufen msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" msgstr " --snapshot=SNAPSHOT angegebenen Snapshot für den Dump verwenden\n" -#: pg_dump.c:1373 pg_dumpall.c:923 +#: pg_dump.c:1373 pg_dumpall.c:754 #, c-format msgid " --statistics dump the statistics\n" msgstr " --statistics die Statistiken ausgeben\n" -#: pg_dump.c:1374 pg_dumpall.c:924 +#: pg_dump.c:1374 pg_dumpall.c:755 #, c-format msgid " --statistics-only dump only the statistics, not schema or data\n" msgstr " --statistics-only nur die Statistiken ausgeben, nicht Schema oder Daten\n" -#: pg_dump.c:1375 pg_restore.c:804 +#: pg_dump.c:1375 pg_restore.c:588 #, c-format msgid "" " --strict-names require table and/or schema include patterns to\n" @@ -2041,7 +2045,7 @@ msgstr "" " --table-and-children=MUSTER nur die angegebene(n) Tabelle(n) ausgeben,\n" " einschließlich abgeleiteter und Partitionstabellen\n" -#: pg_dump.c:1379 pg_dumpall.c:925 pg_restore.c:807 +#: pg_dump.c:1379 pg_dumpall.c:756 pg_restore.c:591 #, c-format msgid "" " --use-set-session-authorization\n" @@ -2053,7 +2057,7 @@ msgstr "" " OWNER Befehle verwenden, um Eigentümerschaft zu\n" " setzen\n" -#: pg_dump.c:1383 pg_dumpall.c:929 pg_restore.c:811 +#: pg_dump.c:1383 pg_dumpall.c:760 pg_restore.c:595 #, c-format msgid "" "\n" @@ -2067,32 +2071,32 @@ msgstr "" msgid " -d, --dbname=DBNAME database to dump\n" msgstr " -d, --dbname=DBNAME auszugebende Datenbank\n" -#: pg_dump.c:1385 pg_dumpall.c:931 pg_restore.c:812 +#: pg_dump.c:1385 pg_dumpall.c:762 pg_restore.c:596 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=HOSTNAME Name des Datenbankservers oder Socket-Verzeichnis\n" -#: pg_dump.c:1386 pg_dumpall.c:933 pg_restore.c:813 +#: pg_dump.c:1386 pg_dumpall.c:764 pg_restore.c:597 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=PORT Portnummer des Datenbankservers\n" -#: pg_dump.c:1387 pg_dumpall.c:934 pg_restore.c:814 +#: pg_dump.c:1387 pg_dumpall.c:765 pg_restore.c:598 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr " -U, --username=NAME Datenbankbenutzername\n" -#: pg_dump.c:1388 pg_dumpall.c:935 pg_restore.c:815 +#: pg_dump.c:1388 pg_dumpall.c:766 pg_restore.c:599 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password niemals nach Passwort fragen\n" -#: pg_dump.c:1389 pg_dumpall.c:936 pg_restore.c:816 +#: pg_dump.c:1389 pg_dumpall.c:767 pg_restore.c:600 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr " -W, --password nach Passwort fragen (sollte automatisch geschehen)\n" -#: pg_dump.c:1390 pg_dumpall.c:937 +#: pg_dump.c:1390 pg_dumpall.c:768 #, c-format msgid " --role=ROLENAME do SET ROLE before dump\n" msgstr " --role=ROLLENNAME vor der Ausgabe SET ROLE ausführen\n" @@ -2110,17 +2114,17 @@ msgstr "" "PGDATABASE verwendet.\n" "\n" -#: pg_dump.c:1394 pg_dumpall.c:941 pg_restore.c:823 +#: pg_dump.c:1394 pg_dumpall.c:772 pg_restore.c:607 #, c-format msgid "Report bugs to <%s>.\n" msgstr "Berichten Sie Fehler an <%s>.\n" -#: pg_dump.c:1395 pg_dumpall.c:942 pg_restore.c:824 +#: pg_dump.c:1395 pg_dumpall.c:773 pg_restore.c:608 #, c-format msgid "%s home page: <%s>\n" msgstr "%s Homepage: <%s>\n" -#: pg_dump.c:1413 pg_dumpall.c:628 +#: pg_dump.c:1413 pg_dumpall.c:570 #, c-format msgid "invalid client encoding \"%s\" specified" msgstr "ungültige Clientkodierung »%s« angegeben" @@ -2135,8 +2139,7 @@ msgstr "parallele Dumps von Standby-Servern werden von dieser Serverversion nich msgid "invalid output format \"%s\" specified" msgstr "ungültiges Ausgabeformat »%s« angegeben" -#: pg_dump.c:1679 pg_dump.c:1735 pg_dump.c:1788 pg_dumpall.c:1966 -#: pg_restore.c:1001 +#: pg_dump.c:1679 pg_dump.c:1735 pg_dump.c:1788 pg_dumpall.c:1610 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "falscher qualifizierter Name (zu viele Namensteile): %s" @@ -2307,13 +2310,13 @@ msgstr "Sanity-Check fehlgeschlagen, Elterntabelle mit OID %u von Sequenz mit OI msgid "failed sanity check, table OID %u appearing in pg_partitioned_table not found" msgstr "Sanity-Check fehlgeschlagen, Tabellen-OID %u, die in pg_partitioned_table erscheint, nicht gefunden" -#: pg_dump.c:8184 pg_dump.c:8480 pg_dump.c:8943 pg_dump.c:9611 pg_dump.c:9755 +#: pg_dump.c:8182 pg_dump.c:8480 pg_dump.c:8943 pg_dump.c:9611 pg_dump.c:9755 #: pg_dump.c:9900 pg_dump.c:10000 #, c-format msgid "unrecognized table OID %u" msgstr "unbekannte Tabellen-OID %u" -#: pg_dump.c:8188 +#: pg_dump.c:8186 #, c-format msgid "unexpected index data for table \"%s\"" msgstr "unerwartete Indexdaten für Tabelle »%s«" @@ -2618,8 +2621,8 @@ msgstr "kein referenzierendes Objekt %u %u" msgid "no referenced object %u %u" msgstr "kein referenziertes Objekt %u %u" -#: pg_dump.c:21024 pg_dump.c:21062 pg_dumpall.c:2365 pg_restore.c:858 -#: pg_restore.c:904 +#: pg_dump.c:21024 pg_dump.c:21062 pg_dumpall.c:1858 pg_restore.c:642 +#: pg_restore.c:688 #, c-format msgid "%s filter for \"%s\" is not allowed" msgstr "%s-Filter für »%s« ist nicht erlaubt" @@ -2661,32 +2664,22 @@ msgstr "Führen Sie einen vollen Dump statt eines Dumps mit --data-only durch, u msgid "could not resolve dependency loop among these items:" msgstr "konnte Abhängigkeitsschleife zwischen diesen Elementen nicht auflösen:" -#: pg_dumpall.c:260 +#: pg_dumpall.c:239 #, c-format msgid "program \"%s\" is needed by %s but was not found in the same directory as \"%s\"" msgstr "Programm »%s« wird von %s benötigt, aber wurde nicht im selben Verzeichnis wie »%s« gefunden" -#: pg_dumpall.c:263 +#: pg_dumpall.c:242 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "Programm »%s« wurde von »%s« gefunden, aber es hatte nicht die gleiche Version wie %s" -#: pg_dumpall.c:476 -#, c-format -msgid "option %s=d|c|t requires option %s" -msgstr "Option %s=d|c|t erfordert Option %s" - -#: pg_dumpall.c:484 +#: pg_dumpall.c:401 #, c-format -msgid "option %s can only be used with %s=plain" -msgstr "Option %s kann nur mit %s=plain verwendet werden" +msgid "option %s cannot be used together with %s, %s, or %s" +msgstr "Option %s kann nicht zusammen mit %s, %s oder %s verwendet werden" -#: pg_dumpall.c:489 -#, c-format -msgid "options %s and %s cannot be used together in non-text dump" -msgstr "Optionen %s und %s können nicht zusammen verwendet werden, wenn das Ausgabeformat nicht »plain« ist" - -#: pg_dumpall.c:609 pg_restore.c:1205 +#: pg_dumpall.c:538 #, c-format msgid "" "could not connect to databases \"postgres\" or \"template1\"\n" @@ -2695,91 +2688,89 @@ msgstr "" "konnte nicht mit Datenbank »postgres« oder »template1« verbinden\n" "Bitte geben Sie eine alternative Datenbank an." -#: pg_dumpall.c:871 +#: pg_dumpall.c:704 #, c-format msgid "" -"%s exports a PostgreSQL database cluster as an SQL script or to other formats.\n" -"\n" -msgstr "" -"%s exportiert einen PostgreSQL-Datenbankcluster als SQL-Skript oder in anderen Formaten.\n" +"%s exports a PostgreSQL database cluster as an SQL script.\n" "\n" +msgstr "%s exportiert einen PostgreSQL-Datenbankcluster als SQL-Skript.\n\n" -#: pg_dumpall.c:873 +#: pg_dumpall.c:706 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [OPTION]...\n" -#: pg_dumpall.c:876 +#: pg_dumpall.c:709 #, c-format msgid " -f, --file=FILENAME output file name\n" msgstr " -f, --file=DATEINAME Name der Ausgabedatei\n" -#: pg_dumpall.c:885 +#: pg_dumpall.c:716 #, c-format msgid " -c, --clean clean (drop) databases before recreating\n" msgstr " -c, --clean Datenbanken vor der Wiedererstellung löschen\n" -#: pg_dumpall.c:887 +#: pg_dumpall.c:718 #, c-format msgid " -g, --globals-only dump only global objects, no databases\n" msgstr " -g, --globals-only nur globale Objekte ausgeben, keine Datenbanken\n" -#: pg_dumpall.c:888 pg_restore.c:773 +#: pg_dumpall.c:719 pg_restore.c:559 #, c-format msgid " -O, --no-owner skip restoration of object ownership\n" msgstr "" " -O, --no-owner Wiederherstellung der Objekteigentümerschaft\n" " auslassen\n" -#: pg_dumpall.c:889 +#: pg_dumpall.c:720 #, c-format msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" msgstr "" " -r, --roles-only nur Rollen ausgeben, keine Datenbanken oder\n" " Tablespaces\n" -#: pg_dumpall.c:891 +#: pg_dumpall.c:722 #, c-format msgid " -S, --superuser=NAME superuser user name to use in the dump\n" msgstr " -S, --superuser=NAME Superusername für den Dump\n" -#: pg_dumpall.c:892 +#: pg_dumpall.c:723 #, c-format msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" msgstr "" " -t, --tablespaces-only nur Tablespaces ausgeben, keine Datenbanken oder\n" " Rollen\n" -#: pg_dumpall.c:898 +#: pg_dumpall.c:729 #, c-format msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" msgstr "" " --exclude-database=MUSTER Datenbanken deren Name mit MUSTER übereinstimmt\n" " überspringen\n" -#: pg_dumpall.c:900 +#: pg_dumpall.c:731 #, c-format msgid " --filter=FILENAME exclude databases based on expressions in FILENAME\n" msgstr "" " --filter=DATEINAME Datenbanken basierend auf Ausdrücken in DATEINAME\n" " überspringen\n" -#: pg_dumpall.c:908 +#: pg_dumpall.c:739 #, c-format msgid " --no-role-passwords do not dump passwords for roles\n" msgstr " --no-role-passwords Rollenpasswörter nicht mit ausgeben\n" -#: pg_dumpall.c:930 +#: pg_dumpall.c:761 #, c-format msgid " -d, --dbname=CONNSTR connect using connection string\n" msgstr " -d, --dbname=VERBDG mit angegebenen Verbindungsparametern verbinden\n" -#: pg_dumpall.c:932 +#: pg_dumpall.c:763 #, c-format msgid " -l, --database=DBNAME alternative default database\n" msgstr " -l, --database=DBNAME alternative Standarddatenbank\n" -#: pg_dumpall.c:939 +#: pg_dumpall.c:770 #, c-format msgid "" "\n" @@ -2792,213 +2783,151 @@ msgstr "" "Standardausgabe geschrieben.\n" "\n" -#: pg_dumpall.c:1107 +#: pg_dumpall.c:915 #, c-format msgid "role name starting with \"pg_\" skipped (%s)" msgstr "mit »pg_« anfangender Rollenname übersprungen (%s)" #. translator: %s represents a numeric role OID -#: pg_dumpall.c:1366 +#: pg_dumpall.c:1132 #, c-format msgid "ignoring role grant for missing role with OID %s" msgstr "Rollen-Grant für fehlende Rolle mit OID %s wird ignoriert" -#: pg_dumpall.c:1404 +#: pg_dumpall.c:1170 #, c-format msgid "could not find a legal dump ordering for memberships in role \"%s\"" msgstr "konnte keine legale Dump-Reihenfolge für Mitgliedschaften in Rolle »%s« finden" #. translator: %s represents a numeric role OID -#: pg_dumpall.c:1430 +#: pg_dumpall.c:1196 #, c-format msgid "ignoring role grant to missing role with OID %s" msgstr "Rollen-Grant an fehlende Rolle mit OID %s wird ignoriert" #. translator: %s represents a numeric role OID -#: pg_dumpall.c:1445 +#: pg_dumpall.c:1211 #, c-format msgid "grant of role \"%s\" to \"%s\" has invalid grantor OID %s" msgstr "Grant von Rolle »%s« an »%s« hat ungültige Grantor-OID %s" -#: pg_dumpall.c:1447 +#: pg_dumpall.c:1213 #, c-format msgid "This grant will be dumped without GRANTED BY." msgstr "Dieser Grant wird ohne GRANTED BY ausgegeben werden." -#: pg_dumpall.c:1580 +#: pg_dumpall.c:1331 #, c-format msgid "could not parse ACL list (%s) for parameter \"%s\"" msgstr "konnte ACL-Zeichenkette (%s) für Parameter »%s« nicht interpretieren" -#: pg_dumpall.c:1743 +#: pg_dumpall.c:1458 #, c-format msgid "could not parse ACL list (%s) for tablespace \"%s\"" msgstr "konnte ACL-Zeichenkette (%s) für Tablespace »%s« nicht interpretieren" -#: pg_dumpall.c:2067 pg_restore.c:1029 +#: pg_dumpall.c:1672 #, c-format msgid "excluding database \"%s\"" msgstr "Datenbank »%s« übersprungen" -#: pg_dumpall.c:2071 +#: pg_dumpall.c:1676 #, c-format msgid "dumping database \"%s\"" msgstr "Ausgabe der Datenbank »%s«" -#: pg_dumpall.c:2123 +#: pg_dumpall.c:1709 #, c-format msgid "pg_dump failed on database \"%s\", exiting" msgstr "pg_dump für Datenbank »%s« fehlgeschlagen; beende" -#: pg_dumpall.c:2129 +#: pg_dumpall.c:1715 #, c-format msgid "could not re-open the output file \"%s\": %m" msgstr "konnte die Ausgabedatei »%s« nicht neu öffnen: %m" -#: pg_dumpall.c:2196 +#: pg_dumpall.c:1759 #, c-format msgid "running \"%s\"" msgstr "führe »%s« aus" -#: pg_dumpall.c:2322 -#, c-format -msgid "" -"database, role, or tablespace names contain a newline or carriage return character, which is not supported in non-plain-text dumps:\n" -"%s" -msgstr "" -"Datenbank-, Rollen- oder Tablespace-Namen enthalten Newline- oder Carriage-Return-Zeichen, was in Ausgabeformaten außer »plain« nicht unterstützt wird:\n" -"%s" - -#: pg_dumpall.c:2385 +#: pg_dumpall.c:1878 msgid "unsupported filter object" msgstr "nicht unterstütztes Filterobjekt" -#: pg_dumpall.c:2426 -#, c-format -msgid "unrecognized output format \"%s\"; please specify \"c\", \"d\", \"p\", or \"t\"" -msgstr "unbekanntes Ausgabeformat »%s«; bitte »c«, »d«, »p« oder »t« angeben" - -#: pg_restore.c:383 +#: pg_restore.c:348 #, c-format msgid "one of -d/--dbname and -f/--file must be specified" msgstr "entweder -d/--dbname oder -f/--file muss angegeben werden" -#: pg_restore.c:463 +#: pg_restore.c:433 #, c-format msgid "cannot specify both --single-transaction and multiple jobs" msgstr "--single-transaction und mehrere Jobs können nicht zusammen verwendet werden" -#: pg_restore.c:510 +#: pg_restore.c:480 #, c-format msgid "archive format \"%s\" is not supported; please use psql" msgstr "Archivformat »%s« wird nicht unterstützt; bitte psql verwenden" -#: pg_restore.c:514 +#: pg_restore.c:484 #, c-format msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" msgstr "unbekanntes Archivformat »%s«; bitte »c«, »d« oder »t« angeben" -#: pg_restore.c:537 pg_restore.c:540 pg_restore.c:544 pg_restore.c:561 -#: pg_restore.c:565 pg_restore.c:569 -#, c-format -msgid "option %s cannot be used when restoring an archive created by pg_dumpall" -msgstr "Option %s kann nicht verwendet werden, wenn ein von pg_dumpall erzeugtes Archiv wiederhergestellt wird" - -#: pg_restore.c:547 -#, c-format -msgid "options %s and %s cannot be used together when restoring an archive created by pg_dumpall" -msgstr "Optionen %s und %s können nicht zusammen verwendet werden, wenn ein von pg_dumpall erzeugtes Archiv wiederhergestellt wird" - -#: pg_restore.c:557 -#, c-format -msgid "--if-exists is implied by --clean for pg_dumpall archives" -msgstr "--if-exists wird bei pg_dumpall-Archiven durch --clean impliziert" - -#: pg_restore.c:573 -#, c-format -msgid "option %s cannot exclude %s when restoring a pg_dumpall archive" -msgstr "Option %s kann %s nicht ausschließen, wenn ein pg_dumpall-Archiv wiederhergestellt wird" - -#: pg_restore.c:583 -#, c-format -msgid "option %s must be specified when restoring an archive created by pg_dumpall" -msgstr "Option %s muss angegeben werden, wenn ein von pg_dumpall erzeugtes Archiv wiederhergestellt wird" - -#: pg_restore.c:586 -#, c-format -msgid "Individual databases can be restored using their specific archives." -msgstr "Individuelle Datenbanken können aus ihren eigenen Archiven wiederhergestellt werden." - -#: pg_restore.c:599 -#, c-format -msgid "skipping restore of global objects because %s was specified" -msgstr "Wiederherstellung globaler Objekte wird übersprungen, weil %s angegeben wurde" - -#: pg_restore.c:603 -#, c-format -msgid "database restoring skipped because option %s was specified" -msgstr "Wiederherstellung der Datenbank wurde übersprungen, weil Option %s angegeben wurde" - -#: pg_restore.c:620 pg_restore.c:625 -#, c-format -msgid "option %s can be used only when restoring an archive created by pg_dumpall" -msgstr "Option %s kann nur verwendet werden, wenn ein von pg_dumpall erzeugtes Archiv wiederhergestellt wird" - -#: pg_restore.c:635 +#: pg_restore.c:522 #, c-format msgid "errors ignored on restore: %d" msgstr "bei Wiederherstellung ignorierte Fehler: %d" -#: pg_restore.c:748 +#: pg_restore.c:535 #, c-format msgid "" -"%s restores PostgreSQL databases from archives created by pg_dump or pg_dumpall.\n" -"\n" -msgstr "" -"%s stellt PostgreSQL-Datenbanken wieder her, die mit pg_dump oder pg_dumpall gesichert wurden.\n" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" "\n" +msgstr "%s stellt eine PostgreSQL-Datenbank wieder her, die mit pg_dump gesichert wurde.\n\n" -#: pg_restore.c:750 +#: pg_restore.c:537 #, c-format msgid " %s [OPTION]... [FILE]\n" msgstr " %s [OPTION]... [DATEI]\n" -#: pg_restore.c:753 +#: pg_restore.c:540 #, c-format msgid " -d, --dbname=NAME connect to database name\n" msgstr " -d, --dbname=NAME mit angegebener Datenbank verbinden\n" -#: pg_restore.c:754 +#: pg_restore.c:541 #, c-format msgid " -f, --file=FILENAME output file name (- for stdout)\n" msgstr " -f, --file=DATEINAME Name der Ausgabedatei (- für stdout)\n" -#: pg_restore.c:755 +#: pg_restore.c:542 #, c-format msgid " -F, --format=c|d|t backup file format (should be automatic)\n" msgstr " -F, --format=c|d|t Format der Backup-Datei (sollte automatisch gehen)\n" -#: pg_restore.c:756 +#: pg_restore.c:543 #, c-format msgid " -l, --list print summarized TOC of the archive\n" msgstr " -l, --list Inhaltsverzeichnis für dieses Archiv anzeigen\n" -#: pg_restore.c:757 +#: pg_restore.c:544 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose »Verbose«-Modus\n" -#: pg_restore.c:758 +#: pg_restore.c:545 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: pg_restore.c:759 +#: pg_restore.c:546 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_restore.c:761 +#: pg_restore.c:548 #, c-format msgid "" "\n" @@ -3007,39 +2936,34 @@ msgstr "" "\n" "Optionen die die Wiederherstellung kontrollieren:\n" -#: pg_restore.c:762 +#: pg_restore.c:549 #, c-format msgid " -a, --data-only restore only the data, no schema\n" msgstr " -a, --data-only nur die Daten wiederherstellen, nicht das Schema\n" -#: pg_restore.c:764 +#: pg_restore.c:551 #, c-format msgid " -C, --create create the target database\n" msgstr " -C, --create Zieldatenbank erzeugen\n" -#: pg_restore.c:765 +#: pg_restore.c:552 #, c-format msgid " -e, --exit-on-error exit on error, default is to continue\n" msgstr " -e, --exit-on-error bei Fehler beenden, Voreinstellung ist fortsetzen\n" -#: pg_restore.c:766 -#, c-format -msgid " -g, --globals-only restore only global objects, no databases\n" -msgstr " -g, --globals-only nur globale Objekte wiederherstellen, keine Datenbanken\n" - -#: pg_restore.c:767 +#: pg_restore.c:553 #, c-format msgid " -I, --index=NAME restore named index\n" msgstr " -I, --index=NAME benannten Index wiederherstellen\n" -#: pg_restore.c:768 +#: pg_restore.c:554 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" msgstr "" " -j, --jobs=NUM so viele parallele Jobs zur Wiederherstellung\n" " verwenden\n" -#: pg_restore.c:769 +#: pg_restore.c:555 #, c-format msgid "" " -L, --use-list=FILENAME use table of contents from this file for\n" @@ -3048,64 +2972,59 @@ msgstr "" " -L, --use-list=DATEINAME Inhaltsverzeichnis aus dieser Datei zur Auswahl oder\n" " Sortierung der Ausgabe verwenden\n" -#: pg_restore.c:771 +#: pg_restore.c:557 #, c-format msgid " -n, --schema=NAME restore only objects in this schema\n" msgstr " -n, --schema=NAME nur Objekte in diesem Schema wiederherstellen\n" -#: pg_restore.c:772 +#: pg_restore.c:558 #, c-format msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" msgstr " -N, ---exclude-schema=NAME Objekte in diesem Schema nicht wiederherstellen\n" -#: pg_restore.c:774 +#: pg_restore.c:560 #, c-format msgid " -P, --function=NAME(args) restore named function\n" msgstr " -P, --function=NAME(args) benannte Funktion wiederherstellen\n" -#: pg_restore.c:775 +#: pg_restore.c:561 #, c-format msgid " -s, --schema-only restore only the schema, no data\n" msgstr " -s, --schema-only nur das Schema wiederherstellen, nicht die Daten\n" -#: pg_restore.c:776 +#: pg_restore.c:562 #, c-format msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" msgstr " -S, --superuser=NAME Name des Superusers, um Trigger auszuschalten\n" -#: pg_restore.c:777 +#: pg_restore.c:563 #, c-format msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" msgstr "" " -t, --table=NAME benannte Relation (Tabelle, Sicht, usw.)\n" " wiederherstellen\n" -#: pg_restore.c:778 +#: pg_restore.c:564 #, c-format msgid " -T, --trigger=NAME restore named trigger\n" msgstr " -T, --trigger=NAME benannten Trigger wiederherstellen\n" -#: pg_restore.c:779 +#: pg_restore.c:565 #, c-format msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" msgstr " -x, --no-privileges Wiederherstellung der Zugriffsprivilegien auslassen\n" -#: pg_restore.c:780 +#: pg_restore.c:566 #, c-format msgid " -1, --single-transaction restore as a single transaction\n" msgstr " -1, --single-transaction Wiederherstellung als eine einzige Transaktion\n" -#: pg_restore.c:782 +#: pg_restore.c:568 #, c-format msgid " --enable-row-security enable row security\n" msgstr " --enable-row-security Sicherheit auf Zeilenebene einschalten\n" -#: pg_restore.c:783 -#, c-format -msgid " --exclude-database=PATTERN do not restore the specified database(s)\n" -msgstr " --exclude-database=MUSTER die angegebene(n) Datenbank(en) NICHT wiederherstellen\n" - -#: pg_restore.c:784 +#: pg_restore.c:569 #, c-format msgid "" " --filter=FILENAME restore or skip objects based on expressions\n" @@ -3114,17 +3033,17 @@ msgstr "" " --filter=DATEINAME Objekte basierend auf Ausdrücken in DATEINAME\n" " wiederherstellen oder überspringen\n" -#: pg_restore.c:787 +#: pg_restore.c:572 #, c-format msgid " --no-comments do not restore comment commands\n" msgstr " --no-comments Kommentar-Befehle nicht wiederherstellen\n" -#: pg_restore.c:788 +#: pg_restore.c:573 #, c-format msgid " --no-data do not restore data\n" msgstr " --no-data Daten nicht wiederherstellen\n" -#: pg_restore.c:789 +#: pg_restore.c:574 #, c-format msgid "" " --no-data-for-failed-tables do not restore data of tables that could not be\n" @@ -3133,93 +3052,87 @@ msgstr "" " --no-data-for-failed-tables Daten für Tabellen, die nicht erzeugt werden\n" " konnten, nicht wiederherstellen\n" -#: pg_restore.c:791 -#, c-format -msgid " --no-globals do not restore global objects (roles and tablespaces)\n" -msgstr " --no-globals globale Objekte (Rollen und Tablespaces) nicht wiederherstellen\n" - -#: pg_restore.c:792 +#: pg_restore.c:576 #, c-format msgid " --no-policies do not restore row security policies\n" msgstr "" " --no-policies Policys für Sicherheit auf Zeilenebene nicht\n" " wiederherstellen\n" -#: pg_restore.c:793 +#: pg_restore.c:577 #, c-format msgid " --no-publications do not restore publications\n" msgstr " --no-publications Publikationen nicht wiederherstellen\n" -#: pg_restore.c:794 +#: pg_restore.c:578 #, c-format msgid " --no-schema do not restore schema\n" msgstr " --no-schema Schema nicht wiederherstellen\n" -#: pg_restore.c:795 +#: pg_restore.c:579 #, c-format msgid " --no-security-labels do not restore security labels\n" msgstr " --no-security-labels Security-Labels nicht wiederherstellen\n" -#: pg_restore.c:796 +#: pg_restore.c:580 #, c-format msgid " --no-statistics do not restore statistics\n" msgstr " --no-statistics Statistiken nicht wiederherstellen\n" -#: pg_restore.c:797 +#: pg_restore.c:581 #, c-format msgid " --no-subscriptions do not restore subscriptions\n" msgstr " --no-subscriptions Subskriptionen nicht wiederherstellen\n" -#: pg_restore.c:798 +#: pg_restore.c:582 #, c-format msgid " --no-table-access-method do not restore table access methods\n" msgstr " --no-table-access-method Tabellenzugriffsmethoden nicht wiederherstellen\n" -#: pg_restore.c:799 +#: pg_restore.c:583 #, c-format msgid " --no-tablespaces do not restore tablespace assignments\n" msgstr " --no-tablespaces Tablespace-Zuordnungen nicht wiederherstellen\n" -#: pg_restore.c:801 +#: pg_restore.c:585 #, c-format msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" msgstr "" " --section=ABSCHNITT angegebenen Abschnitt wiederherstellen (pre-data,\n" " data oder post-data)\n" -#: pg_restore.c:802 +#: pg_restore.c:586 #, c-format msgid " --statistics restore the statistics\n" msgstr " --statistics die Statistiken wiederherstellen\n" -#: pg_restore.c:803 +#: pg_restore.c:587 #, c-format msgid " --statistics-only restore only the statistics, not schema or data\n" msgstr " --statistics-only nur die Statistiken wiederherstellen, nicht Schema oder Daten\n" -#: pg_restore.c:806 +#: pg_restore.c:590 #, c-format msgid " --transaction-size=N commit after every N objects\n" msgstr " --transaction-size=N jeweils nach N Objekten committen\n" -#: pg_restore.c:817 +#: pg_restore.c:601 #, c-format msgid " --role=ROLENAME do SET ROLE before restore\n" msgstr " --role=ROLLENNAME vor der Wiederherstellung SET ROLE ausführen\n" -#: pg_restore.c:819 +#: pg_restore.c:603 #, c-format msgid "" "\n" -"The options -I, -n, -N, -P, -t, -T, --section, and --exclude-database can be\n" -"combined and specified multiple times to select multiple objects.\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" msgstr "" "\n" -"Die Optionen -I, -n, -N, -P, -t, -T, --section und --exclude-database\n" -"können kombiniert und mehrfach angegeben werden, um mehrere Objekte\n" -"auszuwählen.\n" +"Die Optionen -I, -n, -N, -P, -t, -T und --section können kombiniert\n" +"und mehrfach angegeben werden, um mehrere Objekte auszuwählen.\n" -#: pg_restore.c:822 +#: pg_restore.c:606 #, c-format msgid "" "\n" @@ -3230,66 +3143,126 @@ msgstr "" "Wenn keine Eingabedatei angegeben ist, wird die Standardeingabe verwendet.\n" "\n" -#: pg_restore.c:1012 #, c-format -msgid "database name \"%s\" matches --exclude-database pattern \"%s\"" -msgstr "Datenbankname »%s« stimmt mit »--exclude-database«-Muster »%s« überein" +#~ msgid " --exclude-database=PATTERN do not restore the specified database(s)\n" +#~ msgstr " --exclude-database=MUSTER die angegebene(n) Datenbank(en) NICHT wiederherstellen\n" + +#, c-format +#~ msgid " --no-globals do not restore global objects (roles and tablespaces)\n" +#~ msgstr " --no-globals globale Objekte (Rollen und Tablespaces) nicht wiederherstellen\n" + +#, c-format +#~ msgid " -g, --globals-only restore only global objects, no databases\n" +#~ msgstr " -g, --globals-only nur globale Objekte wiederherstellen, keine Datenbanken\n" + +#, c-format +#~ msgid "--if-exists is implied by --clean for pg_dumpall archives" +#~ msgstr "--if-exists wird bei pg_dumpall-Archiven durch --clean impliziert" + +#, c-format +#~ msgid "Individual databases can be restored using their specific archives." +#~ msgstr "Individuelle Datenbanken können aus ihren eigenen Archiven wiederhergestellt werden." + +#, c-format +#~ msgid "database name \"%s\" matches --exclude-database pattern \"%s\"" +#~ msgstr "Datenbankname »%s« stimmt mit »--exclude-database«-Muster »%s« überein" + +#, c-format +#~ msgid "database restoring is skipped because file \"%s\" does not exist in directory \"%s\"" +#~ msgstr "Wiederherstellung der Datenbank übersprungen, weil Datei »%s« nicht in Verzeichnis »%s« existiert" + +#, c-format +#~ msgid "database restoring skipped because option %s was specified" +#~ msgstr "Wiederherstellung der Datenbank wurde übersprungen, weil Option %s angegeben wurde" + +#, c-format +#~ msgid "" +#~ "database, role, or tablespace names contain a newline or carriage return character, which is not supported in non-plain-text dumps:\n" +#~ "%s" +#~ msgstr "" +#~ "Datenbank-, Rollen- oder Tablespace-Namen enthalten Newline- oder Carriage-Return-Zeichen, was in Ausgabeformaten außer »plain« nicht unterstützt wird:\n" +#~ "%s" + +#, c-format +#~ msgid "errors ignored on database \"%s\" restore: %d" +#~ msgstr "bei Wiederherstellung von Datenbank »%s« ignorierte Fehler: %d" + +#, c-format +#~ msgid "found %d database name in \"%s\"" +#~ msgid_plural "found %d database names in \"%s\"" +#~ msgstr[0] "%d Datenbankname in »%s« gefunden" +#~ msgstr[1] "%d Datenbanknamen in »%s« gefunden" + +#, c-format +#~ msgid "found database \"%s\" (OID: %u) in file \"%s\"" +#~ msgstr "Datenbank »%s« (OID: %u) in Datei »%s« gefunden" + +#, c-format +#~ msgid "invalid entry in file \"%s\" on line %d" +#~ msgstr "ungültiger Eintrag in Datei »%s« auf Zeile %d" + +#, c-format +#~ msgid "need to restore %d databases out of %d databases" +#~ msgstr "%d Datenbanken aus %d Datenbanken müssen wiederhergestellt werden" + +#, c-format +#~ msgid "no database needs restoring out of %d database" +#~ msgid_plural "no database needs restoring out of %d databases" +#~ msgstr[0] "keine Datenbank aus %d Datenbank muss wiederhergestellt werden" +#~ msgstr[1] "keine Datenbank aus %d Datenbanken muss wiederhergestellt werden" + +#, c-format +#~ msgid "number of restored databases is %d" +#~ msgstr "Anzahl wiederhergestellter Datenbanken ist %d" + +#, c-format +#~ msgid "option %s can be used only when restoring an archive created by pg_dumpall" +#~ msgstr "Option %s kann nur verwendet werden, wenn ein von pg_dumpall erzeugtes Archiv wiederhergestellt wird" + +#, c-format +#~ msgid "option %s can only be used with %s=plain" +#~ msgstr "Option %s kann nur mit %s=plain verwendet werden" -#: pg_restore.c:1065 #, c-format -msgid "database restoring is skipped because file \"%s\" does not exist in directory \"%s\"" -msgstr "Wiederherstellung der Datenbank übersprungen, weil Datei »%s« nicht in Verzeichnis »%s« existiert" +#~ msgid "option %s cannot be used when restoring an archive created by pg_dumpall" +#~ msgstr "Option %s kann nicht verwendet werden, wenn ein von pg_dumpall erzeugtes Archiv wiederhergestellt wird" -#: pg_restore.c:1112 #, c-format -msgid "invalid entry in file \"%s\" on line %d" -msgstr "ungültiger Eintrag in Datei »%s« auf Zeile %d" +#~ msgid "option %s cannot exclude %s when restoring a pg_dumpall archive" +#~ msgstr "Option %s kann %s nicht ausschließen, wenn ein pg_dumpall-Archiv wiederhergestellt wird" -#: pg_restore.c:1119 #, c-format -msgid "found database \"%s\" (OID: %u) in file \"%s\"" -msgstr "Datenbank »%s« (OID: %u) in Datei »%s« gefunden" +#~ msgid "option %s must be specified when restoring an archive created by pg_dumpall" +#~ msgstr "Option %s muss angegeben werden, wenn ein von pg_dumpall erzeugtes Archiv wiederhergestellt wird" -#: pg_restore.c:1167 #, c-format -msgid "found %d database name in \"%s\"" -msgid_plural "found %d database names in \"%s\"" -msgstr[0] "%d Datenbankname in »%s« gefunden" -msgstr[1] "%d Datenbanknamen in »%s« gefunden" +#~ msgid "option %s=d|c|t requires option %s" +#~ msgstr "Option %s=d|c|t erfordert Option %s" -#: pg_restore.c:1189 pg_restore.c:1198 #, c-format -msgid "trying to connect to database \"%s\"" -msgstr "versuche mit Datenbank »%s« zu verbinden" +#~ msgid "options %s and %s cannot be used together in non-text dump" +#~ msgstr "Optionen %s und %s können nicht zusammen verwendet werden, wenn das Ausgabeformat nicht »plain« ist" -#: pg_restore.c:1224 #, c-format -msgid "no database needs restoring out of %d database" -msgid_plural "no database needs restoring out of %d databases" -msgstr[0] "keine Datenbank aus %d Datenbank muss wiederhergestellt werden" -msgstr[1] "keine Datenbank aus %d Datenbanken muss wiederhergestellt werden" +#~ msgid "options %s and %s cannot be used together when restoring an archive created by pg_dumpall" +#~ msgstr "Optionen %s und %s können nicht zusammen verwendet werden, wenn ein von pg_dumpall erzeugtes Archiv wiederhergestellt wird" -#: pg_restore.c:1232 #, c-format -msgid "need to restore %d databases out of %d databases" -msgstr "%d Datenbanken aus %d Datenbanken müssen wiederhergestellt werden" +#~ msgid "restoring database \"%s\"" +#~ msgstr "Datenbank »%s« wird wiederhergestellt" -#: pg_restore.c:1278 #, c-format -msgid "restoring database \"%s\"" -msgstr "Datenbank »%s« wird wiederhergestellt" +#~ msgid "skipping restore of database \"%s\": database does not exist and %s was not specified" +#~ msgstr "Wiederherstellung von Datenbank »%s« wird übersprungen: Datenbank existiert nicht und %s wurde nicht angegeben" -#: pg_restore.c:1300 #, c-format -msgid "skipping restore of database \"%s\": database does not exist and %s was not specified" -msgstr "Wiederherstellung von Datenbank »%s« wird übersprungen: Datenbank existiert nicht und %s wurde nicht angegeben" +#~ msgid "skipping restore of global objects because %s was specified" +#~ msgstr "Wiederherstellung globaler Objekte wird übersprungen, weil %s angegeben wurde" -#: pg_restore.c:1318 #, c-format -msgid "errors ignored on database \"%s\" restore: %d" -msgstr "bei Wiederherstellung von Datenbank »%s« ignorierte Fehler: %d" +#~ msgid "trying to connect to database \"%s\"" +#~ msgstr "versuche mit Datenbank »%s« zu verbinden" -#: pg_restore.c:1322 #, c-format -msgid "number of restored databases is %d" -msgstr "Anzahl wiederhergestellter Datenbanken ist %d" +#~ msgid "unrecognized output format \"%s\"; please specify \"c\", \"d\", \"p\", or \"t\"" +#~ msgstr "unbekanntes Ausgabeformat »%s«; bitte »c«, »d«, »p« oder »t« angeben" diff --git a/src/bin/pg_dump/po/ja.po b/src/bin/pg_dump/po/ja.po index 388ca7e92a2..1957a46d7ed 100644 --- a/src/bin/pg_dump/po/ja.po +++ b/src/bin/pg_dump/po/ja.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_dump (PostgreSQL 19)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-15 13:37+0900\n" -"PO-Revision-Date: 2026-05-15 15:39+0900\n" +"POT-Creation-Date: 2026-07-03 14:12+0900\n" +"PO-Revision-Date: 2026-07-06 14:41+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" @@ -129,7 +129,7 @@ msgstr "コマンド\"%s\"から読み取れませんでした: %m" msgid "no data was returned by command \"%s\"" msgstr "コマンド\"%s\"がデータを返却しませんでした" -#: ../../common/exec.c:406 parallel.c:1625 +#: ../../common/exec.c:406 parallel.c:1611 #, c-format msgid "%s() failed: %m" msgstr "%s() が失敗しました: %m" @@ -161,7 +161,6 @@ msgstr "メモリ割り当て要求サイズ %zu * %zu が不正です\n" #: ../../common/file_utils.c:69 ../../common/file_utils.c:370 #: ../../common/file_utils.c:428 ../../common/file_utils.c:502 -#: pg_dumpall.c:2037 pg_restore.c:1075 #, c-format msgid "could not open file \"%s\": %m" msgstr "ファイル\"%s\"をオープンできませんでした: %m" @@ -247,17 +246,21 @@ msgstr "%sは%d..%dの範囲でなければなりません" msgid "unrecognized sync method: %s" msgstr "認識できない同期方式: %s" -#: ../../fe_utils/option_utils.c:139 +#: ../../fe_utils/option_utils.c:139 pg_dumpall.c:411 pg_dumpall.c:419 +#: pg_dumpall.c:431 pg_dumpall.c:436 pg_restore.c:355 pg_restore.c:362 +#: pg_restore.c:382 pg_restore.c:385 pg_restore.c:388 pg_restore.c:393 +#: pg_restore.c:396 pg_restore.c:399 pg_restore.c:404 pg_restore.c:409 +#: pg_restore.c:412 pg_restore.c:416 pg_restore.c:420 pg_restore.c:428 #, c-format msgid "options %s and %s cannot be used together" msgstr "オプション %s と %s は同時には使用できません" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "シェルコマンドの引数に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "データベース名に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" @@ -626,7 +629,7 @@ msgstr "パスワード: " msgid "%s" msgstr "%s" -#: connectdb.c:157 pg_dumpall.c:595 pg_restore.c:1184 +#: connectdb.c:157 pg_dumpall.c:524 #, c-format msgid "could not connect to database \"%s\"" msgstr "データベース\"%s\"へ接続できませんでした" @@ -651,22 +654,22 @@ msgstr "サーバーバージョンの不一致のため処理を中断します msgid "server version: %s; %s version: %s" msgstr "サーバーバージョン: %s、%s バージョン: %s" -#: connectdb.c:282 pg_dumpall.c:2243 +#: connectdb.c:282 pg_dumpall.c:1778 #, c-format msgid "executing %s" msgstr "%s を実行しています" -#: connectdb.c:288 pg_backup_db.c:210 pg_dumpall.c:2249 +#: connectdb.c:288 pg_backup_db.c:210 pg_dumpall.c:1784 #, c-format msgid "query failed: %s" msgstr "問い合わせが失敗しました: %s" -#: connectdb.c:289 pg_backup_db.c:212 pg_dumpall.c:2250 +#: connectdb.c:289 pg_backup_db.c:212 pg_dumpall.c:1785 #, c-format msgid "Query was: %s" msgstr "問い合わせ: %s" -#: dumputils.c:956 pg_dumpall.c:2030 +#: dumputils.c:956 #, c-format msgid "could not create directory \"%s\": %m" msgstr "ディレクトリ\"%s\"を作成できませんでした: %m" @@ -736,27 +739,27 @@ msgstr "サポートされないフィルターオブジェクトタイプ: \"%. msgid "%s() failed: error code %d" msgstr "%s()が失敗しました: エラーコード %d" -#: parallel.c:975 +#: parallel.c:961 #, c-format msgid "could not create communication channels: %m" msgstr "通信チャンネルを作成できませんでした: %m" -#: parallel.c:1032 +#: parallel.c:1018 #, c-format msgid "could not create worker process: %m" msgstr "ワーカープロセスを作成できませんでした: %m" -#: parallel.c:1162 +#: parallel.c:1148 #, c-format msgid "unrecognized command received from leader: \"%s\"" msgstr "リーダーから認識不能のコマンドを受信しました: \"%s\"" -#: parallel.c:1205 parallel.c:1443 +#: parallel.c:1191 parallel.c:1429 #, c-format msgid "invalid message received from worker: \"%s\"" msgstr "ワーカーから不正なメッセージを受信しました: \"%s\"" -#: parallel.c:1337 +#: parallel.c:1323 #, c-format msgid "" "could not obtain lock on relation \"%s\"\n" @@ -765,52 +768,52 @@ msgstr "" "リレーション\"%s\"のロックを獲得できませんでした。\n" "通常これは、pg_dumpの親プロセスが初期のACCESS SHAREロックを獲得した後にだれかがテーブルに対してACCESS EXCLUSIVEロックを要求したことを意味しています。" -#: parallel.c:1426 +#: parallel.c:1412 #, c-format msgid "a worker process died unexpectedly" msgstr "ワーカープロセスが突然終了しました" -#: parallel.c:1548 parallel.c:1666 +#: parallel.c:1534 parallel.c:1652 #, c-format msgid "could not write to the communication channel: %m" msgstr "通信チャンネルに書き込めませんでした: %m" -#: parallel.c:1750 +#: parallel.c:1736 #, c-format msgid "pgpipe: could not create socket: error code %d" msgstr "pgpipe: ソケットを作成できませんでした: エラーコード %d" -#: parallel.c:1761 +#: parallel.c:1747 #, c-format msgid "pgpipe: could not bind: error code %d" msgstr "pgpipe: バインドできませんでした: エラーコード %d" -#: parallel.c:1768 +#: parallel.c:1754 #, c-format msgid "pgpipe: could not listen: error code %d" msgstr "pgpipe: リッスンできませんでした: エラーコード %d" -#: parallel.c:1775 +#: parallel.c:1761 #, c-format msgid "pgpipe: %s() failed: error code %d" msgstr "pgpipe: %s()が失敗しました: エラーコード %d" -#: parallel.c:1786 +#: parallel.c:1772 #, c-format msgid "pgpipe: could not create second socket: error code %d" msgstr "pgpipe: 第二ソケットを作成できませんでした: エラーコード %d" -#: parallel.c:1795 +#: parallel.c:1781 #, c-format msgid "pgpipe: could not connect socket: error code %d" msgstr "pgpipe: ソケットを接続できませんでした: エラーコード %d" -#: parallel.c:1804 +#: parallel.c:1790 #, c-format msgid "pgpipe: could not accept connection: error code %d" msgstr "pgpipe: 接続を受け付けられませんでした: エラーコード %d" -#: pg_backup_archiver.c:272 pg_backup_archiver.c:1770 +#: pg_backup_archiver.c:272 pg_backup_archiver.c:1748 #, c-format msgid "could not close output file: %m" msgstr "出力ファイルをクローズできませんでした: %m" @@ -825,440 +828,440 @@ msgstr "アーカイブ項目が正しいセクション順ではありません msgid "unexpected section code %d" msgstr "想定外のセクションコード %d" -#: pg_backup_archiver.c:368 +#: pg_backup_archiver.c:363 #, c-format msgid "parallel restore is not supported with this archive file format" msgstr "このアーカイブファイル形式での並列はサポートしていません" -#: pg_backup_archiver.c:372 +#: pg_backup_archiver.c:367 #, c-format msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" msgstr "8.0 より古い pg_dump で作られたアーカイブでの並列リストアはサポートしていません" -#: pg_backup_archiver.c:393 +#: pg_backup_archiver.c:388 #, c-format msgid "cannot restore from compressed archive (%s)" msgstr "圧縮アーカイブから復元できませんでした(%s)" -#: pg_backup_archiver.c:413 +#: pg_backup_archiver.c:408 #, c-format msgid "connecting to database for restore" msgstr "リストアのためデータベースに接続しています" -#: pg_backup_archiver.c:415 +#: pg_backup_archiver.c:410 #, c-format msgid "direct database connections are not supported in pre-1.3 archives" msgstr "1.3より古いアーカイブではデータベースへの直接接続はサポートされていません" -#: pg_backup_archiver.c:458 +#: pg_backup_archiver.c:453 #, c-format msgid "implied no-schema restore" msgstr "暗黙的にスキーマなしのリストアを行います" -#: pg_backup_archiver.c:537 +#: pg_backup_archiver.c:532 #, c-format msgid "dropping %s %s" msgstr "%s %sを削除しています" -#: pg_backup_archiver.c:669 +#: pg_backup_archiver.c:664 #, c-format msgid "could not find where to insert IF EXISTS in statement \"%s\"" msgstr "文\"%s\"中に IF EXISTS を挿入すべき場所が見つかりませでした" -#: pg_backup_archiver.c:876 pg_backup_archiver.c:878 +#: pg_backup_archiver.c:858 pg_backup_archiver.c:860 #, c-format msgid "warning from original dump file: %s" msgstr "オリジナルのダンプファイルからの警告: %s" -#: pg_backup_archiver.c:912 +#: pg_backup_archiver.c:894 #, c-format msgid "creating %s \"%s.%s\"" msgstr "%s \"%s.%s\"を作成しています" -#: pg_backup_archiver.c:915 +#: pg_backup_archiver.c:897 #, c-format msgid "creating %s \"%s\"" msgstr "%s \"%s\"を作成しています" -#: pg_backup_archiver.c:965 +#: pg_backup_archiver.c:947 #, c-format msgid "connecting to new database \"%s\"" msgstr "新しいデータベース\"%s\"に接続しています" -#: pg_backup_archiver.c:992 +#: pg_backup_archiver.c:974 #, c-format msgid "processing %s" msgstr "%sを処理しています" -#: pg_backup_archiver.c:1014 +#: pg_backup_archiver.c:996 #, c-format msgid "processing data for table \"%s.%s\"" msgstr "テーブル\"%s.%s\"のデータを処理しています" -#: pg_backup_archiver.c:1084 +#: pg_backup_archiver.c:1066 #, c-format msgid "executing %s %s" msgstr "%s %sを実行しています" -#: pg_backup_archiver.c:1153 +#: pg_backup_archiver.c:1135 #, c-format msgid "disabling triggers for %s" msgstr "%sのトリガを無効にしています" -#: pg_backup_archiver.c:1179 +#: pg_backup_archiver.c:1161 #, c-format msgid "enabling triggers for %s" msgstr "%sのトリガを有効にしています" -#: pg_backup_archiver.c:1244 +#: pg_backup_archiver.c:1226 #, c-format msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" msgstr "内部エラー -- WriteDataはDataDumperルーチンのコンテクスト外では呼び出せません" -#: pg_backup_archiver.c:1439 +#: pg_backup_archiver.c:1421 #, c-format msgid "large-object output not supported in chosen format" msgstr "選択した形式ではラージオブジェクト出力をサポートしていません" -#: pg_backup_archiver.c:1502 +#: pg_backup_archiver.c:1484 #, c-format msgid "restored %d large object" msgid_plural "restored %d large objects" msgstr[0] "%d個のラージオブジェクトを復元しました" -#: pg_backup_archiver.c:1529 pg_backup_tar.c:683 +#: pg_backup_archiver.c:1511 pg_backup_tar.c:683 #, c-format msgid "restoring large object with OID %u" msgstr "OID %uのラージオブジェクトをリストアしています" -#: pg_backup_archiver.c:1541 +#: pg_backup_archiver.c:1523 #, c-format msgid "could not create large object %u: %s" msgstr "ラージオブジェクト %u を作成できませんでした: %s" -#: pg_backup_archiver.c:1546 pg_dump.c:4197 +#: pg_backup_archiver.c:1528 pg_dump.c:4158 #, c-format msgid "could not open large object %u: %s" msgstr "ラージオブジェクト %u をオープンできませんでした: %s" -#: pg_backup_archiver.c:1602 +#: pg_backup_archiver.c:1584 #, c-format msgid "could not open TOC file \"%s\": %m" msgstr "TOCファイル\"%s\"をオープンできませんでした: %m" -#: pg_backup_archiver.c:1630 +#: pg_backup_archiver.c:1612 #, c-format msgid "line ignored: %s" msgstr "行を無視しました: %s" -#: pg_backup_archiver.c:1637 pg_backup_db.c:548 +#: pg_backup_archiver.c:1619 pg_backup_db.c:548 #, c-format msgid "could not find entry for ID %d" msgstr "ID %dのエントリがありませんでした" -#: pg_backup_archiver.c:1660 pg_backup_directory.c:187 +#: pg_backup_archiver.c:1642 pg_backup_directory.c:187 #: pg_backup_directory.c:563 #, c-format msgid "could not close TOC file: %m" msgstr "TOCファイルをクローズできませんでした: %m" -#: pg_backup_archiver.c:1751 pg_backup_custom.c:151 pg_backup_directory.c:301 +#: pg_backup_archiver.c:1729 pg_backup_custom.c:151 pg_backup_directory.c:301 #: pg_backup_directory.c:550 pg_backup_directory.c:616 -#: pg_backup_directory.c:634 pg_dumpall.c:567 +#: pg_backup_directory.c:634 pg_dumpall.c:558 #, c-format msgid "could not open output file \"%s\": %m" msgstr "出力ファイル\"%s\"をオープンできませんでした: %m" -#: pg_backup_archiver.c:1753 pg_backup_custom.c:157 +#: pg_backup_archiver.c:1731 pg_backup_custom.c:157 #, c-format msgid "could not open output file: %m" msgstr "出力ファイルをオープンできませんでした: %m" -#: pg_backup_archiver.c:1836 +#: pg_backup_archiver.c:1814 #, c-format msgid "wrote %zu byte of large object data (result = %d)" msgid_plural "wrote %zu bytes of large object data (result = %d)" msgstr[0] "ラージオブジェクトデータを%zuバイト書き出しました(結果は%d)" -#: pg_backup_archiver.c:1842 +#: pg_backup_archiver.c:1820 #, c-format msgid "could not write to large object: %s" msgstr "ラージオブジェクトに書き込めませんでした: %s" -#: pg_backup_archiver.c:1932 +#: pg_backup_archiver.c:1910 #, c-format msgid "while INITIALIZING:" msgstr "初期化中:" -#: pg_backup_archiver.c:1937 +#: pg_backup_archiver.c:1915 #, c-format msgid "while PROCESSING TOC:" msgstr "TOC処理中:" -#: pg_backup_archiver.c:1942 +#: pg_backup_archiver.c:1920 #, c-format msgid "while FINALIZING:" msgstr "終了処理中:" -#: pg_backup_archiver.c:1947 +#: pg_backup_archiver.c:1925 #, c-format msgid "from TOC entry %d; %u %u %s %s %s" msgstr "TOCエントリ%d; %u %u %s %s %s から" -#: pg_backup_archiver.c:2023 +#: pg_backup_archiver.c:2001 #, c-format msgid "bad dumpId" msgstr "不正なdumpId" -#: pg_backup_archiver.c:2044 +#: pg_backup_archiver.c:2022 #, c-format msgid "bad table dumpId for TABLE DATA item" msgstr "TABLE DATA項目に対する不正なテーブルdumpId" -#: pg_backup_archiver.c:2136 +#: pg_backup_archiver.c:2114 #, c-format msgid "unexpected data offset flag %d" msgstr "想定外のデータオフセットフラグ %d" -#: pg_backup_archiver.c:2149 +#: pg_backup_archiver.c:2127 #, c-format msgid "file offset in dump file is too large" msgstr "ダンプファイルのファイルオフセットが大きすぎます" -#: pg_backup_archiver.c:2260 pg_restore.c:939 +#: pg_backup_archiver.c:2238 #, c-format msgid "directory name too long: \"%s\"" msgstr "ディレクトリ名が長すぎます: \"%s\"" -#: pg_backup_archiver.c:2310 +#: pg_backup_archiver.c:2288 #, c-format msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" msgstr "ディレクトリ\"%s\"は有効なアーカイブではないようです(\"toc.dat\"がありません)" -#: pg_backup_archiver.c:2318 pg_backup_custom.c:168 pg_backup_custom.c:820 +#: pg_backup_archiver.c:2296 pg_backup_custom.c:168 pg_backup_custom.c:820 #: pg_backup_directory.c:172 pg_backup_directory.c:358 #, c-format msgid "could not open input file \"%s\": %m" msgstr "入力ファイル\"%s\"をオープンできませんでした: %m" -#: pg_backup_archiver.c:2325 pg_backup_custom.c:174 +#: pg_backup_archiver.c:2303 pg_backup_custom.c:174 #, c-format msgid "could not open input file: %m" msgstr "入力ファイルをオープンできませんでした: %m" -#: pg_backup_archiver.c:2331 +#: pg_backup_archiver.c:2309 #, c-format msgid "could not read input file: %m" msgstr "入力ファイルを読み込めませんでした: %m" -#: pg_backup_archiver.c:2333 +#: pg_backup_archiver.c:2311 #, c-format msgid "input file is too short (read %zu, expected 5)" msgstr "入力ファイルが短すぎます (読み取り %zu、想定は 5)" -#: pg_backup_archiver.c:2364 +#: pg_backup_archiver.c:2342 #, c-format msgid "input file appears to be a text format dump. Please use psql." msgstr "入力ファイルがテキスト形式のようです。psqlを使用してください。" -#: pg_backup_archiver.c:2370 +#: pg_backup_archiver.c:2348 #, c-format msgid "input file does not appear to be a valid archive (too short?)" msgstr "入力ファイルが有効なアーカイブではないようです(小さすぎる?)" -#: pg_backup_archiver.c:2376 +#: pg_backup_archiver.c:2354 #, c-format msgid "input file does not appear to be a valid tar archive" msgstr "入力ファイルが有効なtarアーカイブではないようです" -#: pg_backup_archiver.c:2385 +#: pg_backup_archiver.c:2363 #, c-format msgid "could not close input file: %m" msgstr "入力ファイルをクローズできませんでした: %m" -#: pg_backup_archiver.c:2464 +#: pg_backup_archiver.c:2442 #, c-format msgid "could not open stdout for appending: %m" msgstr "標準出力を追記用にオープンできませんでした: %m" -#: pg_backup_archiver.c:2509 +#: pg_backup_archiver.c:2487 #, c-format msgid "unrecognized file format \"%d\"" msgstr "認識不能のファイル形式\"%d\"" -#: pg_backup_archiver.c:2590 pg_backup_archiver.c:4859 +#: pg_backup_archiver.c:2568 pg_backup_archiver.c:4845 #, c-format msgid "finished item %d %s %s" msgstr "項目 %d %s %s の処理が完了" -#: pg_backup_archiver.c:2594 pg_backup_archiver.c:4872 +#: pg_backup_archiver.c:2572 pg_backup_archiver.c:4858 #, c-format msgid "worker process failed: exit code %d" msgstr "ワーカープロセスの処理失敗: 終了コード %d" -#: pg_backup_archiver.c:2692 +#: pg_backup_archiver.c:2670 #, c-format msgid "unexpected TOC entry in WriteToc(): %d %s %s" msgstr "WriteToc()で想定外のTOCエントリ: %d %s %s" -#: pg_backup_archiver.c:2696 pg_backup_custom.c:440 pg_backup_custom.c:506 +#: pg_backup_archiver.c:2674 pg_backup_custom.c:440 pg_backup_custom.c:506 #: pg_backup_custom.c:642 pg_backup_custom.c:878 pg_backup_tar.c:1004 #: pg_backup_tar.c:1009 #, c-format msgid "error during file seek: %m" msgstr "ファイルシーク中にエラーがありました: %m" -#: pg_backup_archiver.c:2754 +#: pg_backup_archiver.c:2732 #, c-format msgid "entry ID %d out of range -- perhaps a corrupt TOC" msgstr "エントリID%dは範囲外です -- おそらくTOCの破損です" -#: pg_backup_archiver.c:2837 +#: pg_backup_archiver.c:2815 #, c-format msgid "restoring tables WITH OIDS is not supported anymore" msgstr "WITH OIDSと定義されたテーブルのリストアは今後サポートされません" -#: pg_backup_archiver.c:2919 +#: pg_backup_archiver.c:2897 #, c-format msgid "unrecognized encoding \"%s\"" msgstr "認識不能のエンコーディング\"%s\"" -#: pg_backup_archiver.c:2925 +#: pg_backup_archiver.c:2903 #, c-format msgid "invalid ENCODING item: %s" msgstr "不正なENCODING項目: %s" -#: pg_backup_archiver.c:2943 +#: pg_backup_archiver.c:2921 #, c-format msgid "invalid STDSTRINGS item: %s" msgstr "不正なSTDSTRINGS項目: %s" -#: pg_backup_archiver.c:2968 +#: pg_backup_archiver.c:2946 #, c-format msgid "schema \"%s\" not found" msgstr "スキーマ \"%s\"が見つかりません" -#: pg_backup_archiver.c:2975 +#: pg_backup_archiver.c:2953 #, c-format msgid "table \"%s\" not found" msgstr "テーブル\"%s\"が見つかりません" -#: pg_backup_archiver.c:2982 +#: pg_backup_archiver.c:2960 #, c-format msgid "index \"%s\" not found" msgstr "インデックス\"%s\"が見つかりません" -#: pg_backup_archiver.c:2989 +#: pg_backup_archiver.c:2967 #, c-format msgid "function \"%s\" not found" msgstr "関数\"%s\"が見つかりません" -#: pg_backup_archiver.c:2996 +#: pg_backup_archiver.c:2974 #, c-format msgid "trigger \"%s\" not found" msgstr "トリガ\"%s\"が見つかりません" -#: pg_backup_archiver.c:3528 +#: pg_backup_archiver.c:3517 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "セッションユーザーを\"%s\"に設定できませんでした: %s" -#: pg_backup_archiver.c:3670 +#: pg_backup_archiver.c:3659 #, c-format msgid "could not set \"search_path\" to \"%s\": %s" msgstr "\"search_path\"を\"%s\"に設定できませんでした: %s" -#: pg_backup_archiver.c:3731 +#: pg_backup_archiver.c:3720 #, c-format msgid "could not set \"default_tablespace\" to %s: %s" msgstr "\"default_tablespace\"を\"%s\"に設定できませんでした: %s" -#: pg_backup_archiver.c:3780 +#: pg_backup_archiver.c:3769 #, c-format msgid "could not set \"default_table_access_method\": %s" msgstr "\"default_table_access_method\"を設定できませんでした: %s" -#: pg_backup_archiver.c:3829 +#: pg_backup_archiver.c:3818 #, c-format msgid "could not alter table access method: %s" msgstr "テーブルアクセスメソッドを変更できませんでした: %s" -#: pg_backup_archiver.c:3934 +#: pg_backup_archiver.c:3920 #, c-format msgid "don't know how to set owner for object type \"%s\"" msgstr "オブジェクトタイプ%sに対する所有者の設定方法がわかりません" -#: pg_backup_archiver.c:4069 +#: pg_backup_archiver.c:4055 #, c-format msgid "unexpected TOC entry in _printTocEntry(): %d %s %s" msgstr "_printTocEntry()で想定外のTOCエントリ: %d %s %s" -#: pg_backup_archiver.c:4217 +#: pg_backup_archiver.c:4203 #, c-format msgid "did not find magic string in file header" msgstr "ファイルヘッダにマジック文字列がありませんでした" -#: pg_backup_archiver.c:4231 +#: pg_backup_archiver.c:4217 #, c-format msgid "unsupported version (%d.%d) in file header" msgstr "ファイルヘッダ内のバージョン(%d.%d)はサポートされていません" -#: pg_backup_archiver.c:4236 +#: pg_backup_archiver.c:4222 #, c-format msgid "sanity check on integer size (%zu) failed" msgstr "整数のサイズ(%zu)に関する健全性検査が失敗しました" -#: pg_backup_archiver.c:4239 +#: pg_backup_archiver.c:4225 #, c-format msgid "archive was made on a machine with larger integers, some operations might fail" msgstr "アーカイブはより大きなサイズの整数を持つマシンで作成されました、一部の操作が失敗する可能性があります" -#: pg_backup_archiver.c:4249 +#: pg_backup_archiver.c:4235 #, c-format msgid "expected format (%d) differs from format found in file (%d)" msgstr "想定した形式(%d)はファイル内にある形式(%d)と異なります" -#: pg_backup_archiver.c:4271 +#: pg_backup_archiver.c:4257 #, c-format msgid "archive is compressed, but this installation does not support compression (%s) -- no data will be available" msgstr "アーカイブは圧縮されていますが、このインストールでは圧縮をサポートしていません (%s)-- データは利用できません" -#: pg_backup_archiver.c:4307 +#: pg_backup_archiver.c:4293 #, c-format msgid "invalid creation date in header" msgstr "ヘッダ内の作成日付が不正です" -#: pg_backup_archiver.c:4441 +#: pg_backup_archiver.c:4427 #, c-format msgid "processing item %d %s %s" msgstr "項目 %d %s %s を処理しています" -#: pg_backup_archiver.c:4526 +#: pg_backup_archiver.c:4512 #, c-format msgid "entering main parallel loop" msgstr "メインの並列ループに入ります" -#: pg_backup_archiver.c:4537 +#: pg_backup_archiver.c:4523 #, c-format msgid "skipping item %d %s %s" msgstr "項目 %d %s %s をスキップしています" -#: pg_backup_archiver.c:4546 +#: pg_backup_archiver.c:4532 #, c-format msgid "launching item %d %s %s" msgstr "項目 %d %s %s に着手します" -#: pg_backup_archiver.c:4600 +#: pg_backup_archiver.c:4586 #, c-format msgid "finished main parallel loop" msgstr "メインの並列ループが終了しました" -#: pg_backup_archiver.c:4636 +#: pg_backup_archiver.c:4622 #, c-format msgid "processing missed item %d %s %s" msgstr "やり残し項目 %d %s %s を処理しています" -#: pg_backup_archiver.c:5178 +#: pg_backup_archiver.c:5164 #, c-format msgid "table \"%s\" could not be created, will not restore its data" msgstr "テーブル\"%s\"を作成できませんでした、このテーブルのデータは復元されません" @@ -1374,7 +1377,7 @@ msgstr "PQputCopyEnd からエラーが返されました: %s" msgid "COPY failed for table \"%s\": %s" msgstr "テーブル\"%s\"へのコピーに失敗しました: %s" -#: pg_backup_db.c:460 pg_dump.c:2514 +#: pg_backup_db.c:460 pg_dump.c:2488 #, c-format msgid "unexpected extra results during COPY of table \"%s\"" msgstr "ファイル\"%s\"をCOPY中に想定していない余分な結果がありました" @@ -1524,9 +1527,10 @@ msgstr "破損したtarヘッダが%sにありました(想定 %d、算出結果 msgid "unrecognized section name: \"%s\"" msgstr "認識不可のセクション名: \"%s\"" -#: pg_backup_utils.c:57 pg_dump.c:804 pg_dump.c:821 pg_dumpall.c:410 -#: pg_dumpall.c:420 pg_dumpall.c:478 pg_dumpall.c:611 pg_restore.c:361 -#: pg_restore.c:377 pg_restore.c:585 pg_restore.c:1207 +#: pg_backup_utils.c:57 pg_dump.c:804 pg_dump.c:821 pg_dumpall.c:384 +#: pg_dumpall.c:394 pg_dumpall.c:404 pg_dumpall.c:413 pg_dumpall.c:421 +#: pg_dumpall.c:438 pg_dumpall.c:540 pg_restore.c:326 pg_restore.c:342 +#: pg_restore.c:357 #, c-format msgid "Try \"%s --help\" for more information." msgstr "詳細は\"%s --help\"を実行してください。" @@ -1536,7 +1540,7 @@ msgstr "詳細は\"%s --help\"を実行してください。" msgid "out of on_exit_nicely slots" msgstr "on_exit_nicelyスロットが足りません" -#: pg_dump.c:819 pg_dumpall.c:418 pg_restore.c:375 +#: pg_dump.c:819 pg_dumpall.c:392 pg_restore.c:340 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "コマンドライン引数が多すぎます(先頭は\"%s\")" @@ -1546,7 +1550,7 @@ msgstr "コマンドライン引数が多すぎます(先頭は\"%s\")" msgid "option %s is not supported with parallel backup" msgstr "オプション %s はパラレルバックアップではサポートされません" -#: pg_dump.c:864 pg_dumpall.c:463 pg_restore.c:490 +#: pg_dump.c:864 pg_dumpall.c:426 pg_restore.c:460 #, c-format msgid "option %s requires option %s" msgstr "%s オプション指定時は %s オプションも必要です" @@ -1556,12 +1560,12 @@ msgstr "%s オプション指定時は %s オプションも必要です" msgid "option %s requires option %s, %s, or %s" msgstr "%s オプション指定時は %s、%s または %s オプションが必要です" -#: pg_dump.c:903 pg_dumpall.c:579 pg_restore.c:407 +#: pg_dump.c:903 pg_dumpall.c:508 pg_restore.c:375 #, c-format msgid "could not generate restrict key" msgstr "制限キーを生成できませんでした" -#: pg_dump.c:905 pg_dumpall.c:581 pg_restore.c:409 +#: pg_dump.c:905 pg_dumpall.c:510 pg_restore.c:377 #, c-format msgid "invalid restrict key" msgstr "不正な制限キー" @@ -1620,7 +1624,7 @@ msgstr "" "%sは、ひとつのPostgreSQLデータベースをSQLスクリプトまたは他の形式でエクスポートします。\n" "\n" -#: pg_dump.c:1294 pg_dumpall.c:872 pg_restore.c:749 +#: pg_dump.c:1294 pg_dumpall.c:705 pg_restore.c:536 #, c-format msgid "Usage:\n" msgstr "使用方法:\n" @@ -1630,7 +1634,7 @@ msgstr "使用方法:\n" msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [OPTION]... [DBNAME]\n" -#: pg_dump.c:1297 pg_dumpall.c:875 pg_restore.c:752 +#: pg_dump.c:1297 pg_dumpall.c:708 pg_restore.c:539 #, c-format msgid "" "\n" @@ -1644,7 +1648,7 @@ msgstr "" msgid " -f, --file=FILENAME output file or directory name\n" msgstr " -f, --file=ファイル名 出力ファイルまたはディレクトリの名前\n" -#: pg_dump.c:1299 pg_dumpall.c:877 +#: pg_dump.c:1299 #, c-format msgid "" " -F, --format=c|d|t|p output file format (custom, directory, tar,\n" @@ -1658,12 +1662,12 @@ msgstr "" msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" msgstr " -j, --jobs=NUM ダンプ時に指定した数の並列ジョブを使用\n" -#: pg_dump.c:1302 pg_dumpall.c:879 +#: pg_dump.c:1302 pg_dumpall.c:710 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose 冗長モード\n" -#: pg_dump.c:1303 pg_dumpall.c:880 +#: pg_dump.c:1303 pg_dumpall.c:711 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version バージョン情報を表示して終了\n" @@ -1677,12 +1681,12 @@ msgstr "" " -Z, --compress=方式[:詳細]\n" " 指定のとおり圧縮\n" -#: pg_dump.c:1306 pg_dumpall.c:881 +#: pg_dump.c:1306 pg_dumpall.c:712 #, c-format msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" msgstr " --lock-wait-timeout=TIMEOUT テーブルロックをTIMEOUT待ってから失敗\n" -#: pg_dump.c:1307 pg_dumpall.c:913 +#: pg_dump.c:1307 pg_dumpall.c:744 #, c-format msgid " --no-sync do not wait for changes to be written safely to disk\n" msgstr " --no-sync 変更のディスクへの安全な書き出しを待機しない\n" @@ -1694,12 +1698,12 @@ msgstr "" " --sync-method=METHOD ファイルをディスクに同期させる方法を指定\n" "\n" -#: pg_dump.c:1309 pg_dumpall.c:882 +#: pg_dump.c:1309 pg_dumpall.c:713 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help このヘルプを表示して終了\n" -#: pg_dump.c:1311 pg_dumpall.c:883 +#: pg_dump.c:1311 pg_dumpall.c:714 #, c-format msgid "" "\n" @@ -1708,7 +1712,7 @@ msgstr "" "\n" "出力内容を制御するためのオプション:\n" -#: pg_dump.c:1312 pg_dumpall.c:884 +#: pg_dump.c:1312 pg_dumpall.c:715 #, c-format msgid " -a, --data-only dump only the data, not the schema or statistics\n" msgstr " -a, --data-only データのみをダンプし、スキーマまたは統計情報をダンプしない\n" @@ -1737,7 +1741,7 @@ msgstr "" " --no-blobs (--no-large-objectsに同じ、非推奨)\n" "\n" -#: pg_dump.c:1317 pg_restore.c:763 +#: pg_dump.c:1317 pg_restore.c:550 #, c-format msgid " -c, --clean clean (drop) database objects before recreating\n" msgstr " -c, --clean 再作成前にデータベースオブジェクトを整理(削除)\n" @@ -1752,7 +1756,7 @@ msgstr " -C, --create ダンプにデータベース生成用 msgid " -e, --extension=PATTERN dump the specified extension(s) only\n" msgstr " -e, --extension=PATTERN 指定した機能拡張(群)のみをダンプ\n" -#: pg_dump.c:1320 pg_dumpall.c:886 +#: pg_dump.c:1320 pg_dumpall.c:717 #, c-format msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" msgstr " -E, --encoding=ENCODING 指定した符号化方式でデータをダンプ\n" @@ -1776,7 +1780,7 @@ msgstr "" " -O, --no-owner プレインテキスト形式で、オブジェクト所有権の\n" " 復元を行わない\n" -#: pg_dump.c:1325 pg_dumpall.c:890 +#: pg_dump.c:1325 pg_dumpall.c:721 #, c-format msgid " -s, --schema-only dump only the schema, no data or statistics\n" msgstr "" @@ -1800,29 +1804,29 @@ msgstr " -t, --table=PATTERN 指定したテーブル(群)のみをダ msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" msgstr " -T, --exclude-table=PATTERN 指定したテーブル(群)をダンプしない\n" -#: pg_dump.c:1329 pg_dumpall.c:893 +#: pg_dump.c:1329 pg_dumpall.c:724 #, c-format msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" msgstr " -x, --no-privileges 権限(grant/revoke)をダンプしない\n" -#: pg_dump.c:1330 pg_dumpall.c:894 +#: pg_dump.c:1330 pg_dumpall.c:725 #, c-format msgid " --binary-upgrade for use by upgrade utilities only\n" msgstr " --binary-upgrade アップグレードユーティリティ専用\n" -#: pg_dump.c:1331 pg_dumpall.c:895 +#: pg_dump.c:1331 pg_dumpall.c:726 #, c-format msgid " --column-inserts dump data as INSERT commands with column names\n" msgstr " --column-inserts 列名指定のINSERTコマンドでデータをダンプ\n" -#: pg_dump.c:1332 pg_dumpall.c:896 +#: pg_dump.c:1332 pg_dumpall.c:727 #, c-format msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" msgstr "" " --disable-dollar-quoting ドル記号による引用符付けを禁止、SQL標準の引用符\n" " 付けを使用\n" -#: pg_dump.c:1333 pg_dumpall.c:897 pg_restore.c:781 +#: pg_dump.c:1333 pg_dumpall.c:728 pg_restore.c:567 #, c-format msgid " --disable-triggers disable triggers during data-only restore\n" msgstr " --disable-triggers データのみの復元の際にトリガを無効化\n" @@ -1868,7 +1872,7 @@ msgstr "" " 指定したテーブル(群)のデータを子テーブルを含めて\n" " ダンプしない\n" -#: pg_dump.c:1344 pg_dumpall.c:899 +#: pg_dump.c:1344 pg_dumpall.c:730 #, c-format msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" msgstr " --extra-float-digits=NUM extra_float_digitsの設定を上書きする\n" @@ -1882,7 +1886,7 @@ msgstr "" " --filter=FILENAME オブジェクトやデータの指定や除外を\n" " FILENAMEに記述された式をもとに行う\n" -#: pg_dump.c:1347 pg_dumpall.c:901 pg_restore.c:786 +#: pg_dump.c:1347 pg_dumpall.c:732 pg_restore.c:571 #, c-format msgid " --if-exists use IF EXISTS when dropping objects\n" msgstr " --if-exists オブジェクト削除の際に IF EXISTS を使用\n" @@ -1898,94 +1902,94 @@ msgstr "" " PATTERNに合致する外部サーバー上の外部テーブルの\n" " データを含める\n" -#: pg_dump.c:1351 pg_dumpall.c:902 +#: pg_dump.c:1351 pg_dumpall.c:733 #, c-format msgid " --inserts dump data as INSERT commands, rather than COPY\n" msgstr " --inserts COPYではなくINSERTコマンドでデータをダンプ\n" -#: pg_dump.c:1352 pg_dumpall.c:903 +#: pg_dump.c:1352 pg_dumpall.c:734 #, c-format msgid " --load-via-partition-root load partitions via the root table\n" msgstr " --load-via-partition-root 子テーブルをルートテーブル経由でロードする\n" -#: pg_dump.c:1353 pg_dumpall.c:904 +#: pg_dump.c:1353 pg_dumpall.c:735 #, c-format msgid " --no-comments do not dump comment commands\n" msgstr " --no-comments コメントコマンドをダンプしない\n" -#: pg_dump.c:1354 pg_dumpall.c:905 +#: pg_dump.c:1354 pg_dumpall.c:736 #, c-format msgid " --no-data do not dump data\n" msgstr " --no-data データをダンプしない\n" -#: pg_dump.c:1355 pg_dumpall.c:906 +#: pg_dump.c:1355 pg_dumpall.c:737 #, c-format msgid " --no-policies do not dump row security policies\n" msgstr " --no-policies 行セキュリティポリシーをダンプしない\n" -#: pg_dump.c:1356 pg_dumpall.c:907 +#: pg_dump.c:1356 pg_dumpall.c:738 #, c-format msgid " --no-publications do not dump publications\n" msgstr " --no-publications パブリケーションをダンプしない\n" -#: pg_dump.c:1357 pg_dumpall.c:909 +#: pg_dump.c:1357 pg_dumpall.c:740 #, c-format msgid " --no-schema do not dump schema\n" msgstr " --no-schema スキーマをダンプしない\n" -#: pg_dump.c:1358 pg_dumpall.c:910 +#: pg_dump.c:1358 pg_dumpall.c:741 #, c-format msgid " --no-security-labels do not dump security label assignments\n" msgstr " --no-security-labels セキュリティラベルの割り当てをダンプしない\n" -#: pg_dump.c:1359 pg_dumpall.c:911 +#: pg_dump.c:1359 pg_dumpall.c:742 #, c-format msgid " --no-statistics do not dump statistics\n" msgstr " --no-statistics 統計情報をダンプしない\n" -#: pg_dump.c:1360 pg_dumpall.c:912 +#: pg_dump.c:1360 pg_dumpall.c:743 #, c-format msgid " --no-subscriptions do not dump subscriptions\n" msgstr " --no-subscriptions サブスクリプションをダンプしない\n" -#: pg_dump.c:1361 pg_dumpall.c:914 +#: pg_dump.c:1361 pg_dumpall.c:745 #, c-format msgid " --no-table-access-method do not dump table access methods\n" msgstr " --no-table-access-method テーブルアクセスメソッドをダンプしない\n" -#: pg_dump.c:1362 pg_dumpall.c:915 +#: pg_dump.c:1362 pg_dumpall.c:746 #, c-format msgid " --no-tablespaces do not dump tablespace assignments\n" msgstr " --no-tablespaces テーブルスペースの割り当てをダンプしない\n" -#: pg_dump.c:1363 pg_dumpall.c:916 +#: pg_dump.c:1363 pg_dumpall.c:747 #, c-format msgid " --no-toast-compression do not dump TOAST compression methods\n" msgstr " --no-toast-compression TOAST圧縮方式をダンプしない\n" -#: pg_dump.c:1364 pg_dumpall.c:917 +#: pg_dump.c:1364 pg_dumpall.c:748 #, c-format msgid " --no-unlogged-table-data do not dump unlogged table data\n" msgstr " --no-unlogged-table-data 非ログテーブルのデータをダンプしない\n" -#: pg_dump.c:1365 pg_dumpall.c:918 +#: pg_dump.c:1365 pg_dumpall.c:749 #, c-format msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" msgstr " --on-conflict-do-nothing INSERTコマンドにON CONFLICT DO NOTHINGを付加する\n" -#: pg_dump.c:1366 pg_dumpall.c:919 +#: pg_dump.c:1366 pg_dumpall.c:750 #, c-format msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" msgstr "" " --quote-all-identifiers すべての識別子をキーワードでなかったとしても\n" " 引用符で囲む\n" -#: pg_dump.c:1367 pg_dumpall.c:920 pg_restore.c:800 +#: pg_dump.c:1367 pg_dumpall.c:751 pg_restore.c:584 #, c-format msgid " --restrict-key=RESTRICT_KEY use provided string as psql \\restrict key\n" msgstr " --restrict-key=RESTRICT_KEY \\restrict メタコマンドのキーに指定文字列を使う\n" -#: pg_dump.c:1368 pg_dumpall.c:921 +#: pg_dump.c:1368 pg_dumpall.c:752 #, c-format msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" msgstr " --rows-per-insert=NROWS INSERT毎の行数; --insertsを暗黙的に指定する\n" @@ -1997,7 +2001,7 @@ msgstr "" " --section=SECTION 指定したセクション(pre-data、data または\n" " post-data)をダンプする\n" -#: pg_dump.c:1370 pg_dumpall.c:922 +#: pg_dump.c:1370 pg_dumpall.c:753 #, c-format msgid " --sequence-data include sequence data in dump\n" msgstr " --sequence-data ダンプにシーケンスデータを含める\n" @@ -2012,19 +2016,19 @@ msgstr " --serializable-deferrable ダンプを異常なく実行できる msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" msgstr " --snapshot=SNAPSHOT ダンプに指定のスナップショットを使用する\n" -#: pg_dump.c:1373 pg_dumpall.c:923 +#: pg_dump.c:1373 pg_dumpall.c:754 #, c-format msgid " --statistics dump the statistics\n" msgstr " --statistics 統計情報をダンプする\n" -#: pg_dump.c:1374 pg_dumpall.c:924 +#: pg_dump.c:1374 pg_dumpall.c:755 #, c-format msgid " --statistics-only dump only the statistics, not schema or data\n" msgstr "" " --statistics-only 統計情報のみをダンプし、スキーマまたはデータを\n" " ダンプしない\n" -#: pg_dump.c:1375 pg_restore.c:804 +#: pg_dump.c:1375 pg_restore.c:588 #, c-format msgid "" " --strict-names require table and/or schema include patterns to\n" @@ -2042,7 +2046,7 @@ msgstr "" " --table-and-children=PATTERN 指定したテーブル(群)のみを子テーブル\n" " を含めてダンプ\n" -#: pg_dump.c:1379 pg_dumpall.c:925 pg_restore.c:807 +#: pg_dump.c:1379 pg_dumpall.c:756 pg_restore.c:591 #, c-format msgid "" " --use-set-session-authorization\n" @@ -2053,7 +2057,7 @@ msgstr "" " 所有者をセットする際、ALTER OWNERコマンドの代わり\n" " にSET SESSION AUTHORIZATIONコマンドを使用する\n" -#: pg_dump.c:1383 pg_dumpall.c:929 pg_restore.c:811 +#: pg_dump.c:1383 pg_dumpall.c:760 pg_restore.c:595 #, c-format msgid "" "\n" @@ -2067,36 +2071,36 @@ msgstr "" msgid " -d, --dbname=DBNAME database to dump\n" msgstr " -d, --dbname=DBNAME ダンプするデータベース\n" -#: pg_dump.c:1385 pg_dumpall.c:931 pg_restore.c:812 +#: pg_dump.c:1385 pg_dumpall.c:762 pg_restore.c:596 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr "" " -h, --host=HOSTNAME データベースサーバーのホストまたはソケット\n" " ディレクトリ\n" -#: pg_dump.c:1386 pg_dumpall.c:933 pg_restore.c:813 +#: pg_dump.c:1386 pg_dumpall.c:764 pg_restore.c:597 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=PORT データベースサーバーのポート番号\n" -#: pg_dump.c:1387 pg_dumpall.c:934 pg_restore.c:814 +#: pg_dump.c:1387 pg_dumpall.c:765 pg_restore.c:598 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr " -U, --username=NAME 指定したデータベースユーザーで接続\n" -#: pg_dump.c:1388 pg_dumpall.c:935 pg_restore.c:815 +#: pg_dump.c:1388 pg_dumpall.c:766 pg_restore.c:599 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password パスワード入力を要求しない\n" -#: pg_dump.c:1389 pg_dumpall.c:936 pg_restore.c:816 +#: pg_dump.c:1389 pg_dumpall.c:767 pg_restore.c:600 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr "" " -W, --password パスワードプロンプトを強制表示\n" " (自動的に表示されるはず)\n" -#: pg_dump.c:1390 pg_dumpall.c:937 +#: pg_dump.c:1390 pg_dumpall.c:768 #, c-format msgid " --role=ROLENAME do SET ROLE before dump\n" msgstr " --role=ROLENAME ダンプの前に SET ROLE を行う\n" @@ -2113,514 +2117,508 @@ msgstr "" "データベース名が指定されなかった場合、環境変数PGDATABASEが使用されます\n" "\n" -#: pg_dump.c:1394 pg_dumpall.c:941 pg_restore.c:823 +#: pg_dump.c:1394 pg_dumpall.c:772 pg_restore.c:607 #, c-format msgid "Report bugs to <%s>.\n" msgstr "バグは<%s>に報告してください。\n" -#: pg_dump.c:1395 pg_dumpall.c:942 pg_restore.c:824 +#: pg_dump.c:1395 pg_dumpall.c:773 pg_restore.c:608 #, c-format msgid "%s home page: <%s>\n" msgstr "%s ホームページ: <%s>\n" -#: pg_dump.c:1413 pg_dumpall.c:628 +#: pg_dump.c:1413 pg_dumpall.c:570 #, c-format msgid "invalid client encoding \"%s\" specified" msgstr "不正なクライアントエンコーディング\"%s\"が指定されました" -#: pg_dump.c:1573 -#, c-format -msgid "parallel dumps from standby servers are not supported by this server version" -msgstr "スタンバイサーバーからの並列ダンプはこのサーバーバージョンではサポートされません" - -#: pg_dump.c:1638 +#: pg_dump.c:1629 #, c-format msgid "invalid output format \"%s\" specified" msgstr "不正な出力形式\"%s\"が指定されました" -#: pg_dump.c:1679 pg_dump.c:1735 pg_dump.c:1788 pg_dumpall.c:1966 -#: pg_restore.c:1001 +#: pg_dump.c:1670 pg_dump.c:1726 pg_dump.c:1779 pg_dumpall.c:1582 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "修飾名が不適切です(ドット区切りの名前が多すぎます): %s" -#: pg_dump.c:1687 +#: pg_dump.c:1678 #, c-format msgid "no matching schemas were found for pattern \"%s\"" msgstr "パターン\"%s\"にマッチするスキーマが見つかりません" -#: pg_dump.c:1740 +#: pg_dump.c:1731 #, c-format msgid "no matching extensions were found for pattern \"%s\"" msgstr "パターン\"%s\"に合致する機能拡張が見つかりません" -#: pg_dump.c:1793 +#: pg_dump.c:1784 #, c-format msgid "no matching foreign servers were found for pattern \"%s\"" msgstr "パターン\"%s\"にマッチする外部サーバーが見つかりません" -#: pg_dump.c:1864 +#: pg_dump.c:1855 #, c-format msgid "improper relation name (too many dotted names): %s" msgstr "リレーション名が不適切です(ドット区切りの名前が多すぎます): %s" -#: pg_dump.c:1886 +#: pg_dump.c:1877 #, c-format msgid "no matching tables were found for pattern \"%s\"" msgstr "パターン \"%s\"にマッチするテーブルが見つかりません" -#: pg_dump.c:1913 +#: pg_dump.c:1904 #, c-format msgid "You are currently not connected to a database." msgstr "現在データベースに接続していません。" -#: pg_dump.c:1916 +#: pg_dump.c:1907 #, c-format msgid "cross-database references are not implemented: %s" msgstr "データベース間の参照は実装されていません: %s" -#: pg_dump.c:2382 +#: pg_dump.c:2356 #, c-format msgid "dumping contents of table \"%s.%s\"" msgstr "テーブル \"%s.%s\"の内容をダンプしています" -#: pg_dump.c:2495 +#: pg_dump.c:2469 #, c-format msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." msgstr "テーブル\"%s\"の内容のダンプに失敗: PQgetCopyData()が失敗しました。" -#: pg_dump.c:2496 pg_dump.c:2506 +#: pg_dump.c:2470 pg_dump.c:2480 #, c-format msgid "Error message from server: %s" msgstr "サーバーのエラーメッセージ: %s" -#: pg_dump.c:2497 pg_dump.c:2507 +#: pg_dump.c:2471 pg_dump.c:2481 #, c-format msgid "Command was: %s" msgstr "コマンド: %s" -#: pg_dump.c:2505 +#: pg_dump.c:2479 #, c-format msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." msgstr "テーブル\"%s\"の内容のダンプに失敗: PQgetResult()が失敗しました。" -#: pg_dump.c:2596 +#: pg_dump.c:2570 #, c-format msgid "wrong number of fields retrieved from table \"%s\"" msgstr "テーブル\"%s\"から取得したフィールドの数が間違っています" -#: pg_dump.c:3317 +#: pg_dump.c:3287 #, c-format msgid "saving database definition" msgstr "データベース定義を保存しています" -#: pg_dump.c:3432 +#: pg_dump.c:3399 #, c-format msgid "unrecognized locale provider: %s" msgstr "認識できない照合順序プロバイダ: %s" -#: pg_dump.c:3830 +#: pg_dump.c:3791 #, c-format msgid "saving encoding = %s" msgstr "encoding = %s を保存しています" -#: pg_dump.c:3855 +#: pg_dump.c:3816 #, c-format msgid "saving \"standard_conforming_strings = %s\"" msgstr "\"standard_conforming_strings = %s\" を保存しています" -#: pg_dump.c:3894 +#: pg_dump.c:3855 #, c-format msgid "could not parse result of current_schemas()" msgstr "current_schemas()の結果をパースできませんでした" -#: pg_dump.c:3913 +#: pg_dump.c:3874 #, c-format msgid "saving \"search_path = %s\"" msgstr "\"search_path = %s\" を保存しています" -#: pg_dump.c:3949 +#: pg_dump.c:3910 #, c-format msgid "reading large objects" msgstr "ラージオブジェクトを読み込んでいます" -#: pg_dump.c:4186 +#: pg_dump.c:4147 #, c-format msgid "saving large objects \"%s\"" msgstr "ラージオブジェクト\"%s\"を保存しています" -#: pg_dump.c:4207 +#: pg_dump.c:4168 #, c-format msgid "error reading large object %u: %s" msgstr "ラージオブジェクト %u を読み取り中にエラーがありました: %s" -#: pg_dump.c:4315 +#: pg_dump.c:4272 #, c-format msgid "reading row-level security policies" msgstr "行レベルセキュリティポリシーを読み取ります" -#: pg_dump.c:4456 +#: pg_dump.c:4410 #, c-format msgid "unexpected policy command type: %c" msgstr "想定外のポリシコマンドタイプ: \"%c\"" -#: pg_dump.c:4984 pg_dump.c:5600 pg_dump.c:8240 pg_dump.c:13795 pg_dump.c:20347 -#: pg_dump.c:20349 pg_dump.c:20990 +#: pg_dump.c:4938 pg_dump.c:5554 pg_dump.c:8075 pg_dump.c:13583 pg_dump.c:20049 +#: pg_dump.c:20051 pg_dump.c:20692 #, c-format msgid "could not parse %s array" msgstr "%s配列をパースできませんでした" -#: pg_dump.c:5204 +#: pg_dump.c:5158 #, c-format msgid "subscriptions not dumped because current user is not a superuser" msgstr "現在のユーザーがスーパーユーザーではないため、サブスクリプションはダンプされません" -#: pg_dump.c:5455 +#: pg_dump.c:5409 #, c-format msgid "subscription with OID %u does not exist" msgstr "OID %uのサブスクリプションは存在しません" -#: pg_dump.c:5462 +#: pg_dump.c:5416 #, c-format msgid "failed sanity check, relation with OID %u not found" msgstr "健全性検査に失敗しました、OID %u のリレーションがありません" -#: pg_dump.c:6065 +#: pg_dump.c:6019 #, c-format msgid "could not find parent extension for %s %s" msgstr "%s %sの親となる機能拡張がありませんでした" -#: pg_dump.c:6203 +#: pg_dump.c:6157 #, c-format msgid "schema with OID %u does not exist" msgstr "OID %uのスキーマは存在しません" -#: pg_dump.c:7261 +#: pg_dump.c:7134 #, c-format msgid "cannot dump statistics for relation kind \"%c\"" msgstr "リレーション種別 '%c' の統計情報はダンプできません" -#: pg_dump.c:7774 pg_dump.c:19674 +#: pg_dump.c:7613 pg_dump.c:19378 #, c-format msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" msgstr "健全性検査に失敗しました、OID %2$u であるシーケンスの OID %1$u である親テーブルがありません" -#: pg_dump.c:7919 +#: pg_dump.c:7758 #, c-format msgid "failed sanity check, table OID %u appearing in pg_partitioned_table not found" msgstr "健全性検査に失敗しました、pg_partitioned_tableにあるテーブルOID %u が見つかりません" -#: pg_dump.c:8184 pg_dump.c:8480 pg_dump.c:8943 pg_dump.c:9611 pg_dump.c:9755 -#: pg_dump.c:9900 pg_dump.c:10000 +#: pg_dump.c:8017 pg_dump.c:8311 pg_dump.c:8774 pg_dump.c:9430 pg_dump.c:9574 +#: pg_dump.c:9719 pg_dump.c:9819 #, c-format msgid "unrecognized table OID %u" msgstr "認識できないテーブルOID %u" -#: pg_dump.c:8188 +#: pg_dump.c:8021 #, c-format msgid "unexpected index data for table \"%s\"" msgstr "テーブル\"%s\"に対する想定外のインデックスデータ" -#: pg_dump.c:8730 +#: pg_dump.c:8561 #, c-format msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" msgstr "健全性検査に失敗しました、OID %2$u であるpg_rewriteエントリのOID %1$u である親テーブルが見つかりません" -#: pg_dump.c:9618 +#: pg_dump.c:9437 #, c-format msgid "unexpected column data for table \"%s\"" msgstr "テーブル\"%s\"に対する想定外の列データ" -#: pg_dump.c:9652 +#: pg_dump.c:9471 #, c-format msgid "invalid column numbering in table \"%s\"" msgstr "テーブル\"%s\"の列番号が不正です" -#: pg_dump.c:9717 +#: pg_dump.c:9536 #, c-format msgid "finding table default expressions" msgstr "テーブルのデフォルト式を探しています" -#: pg_dump.c:9759 +#: pg_dump.c:9578 #, c-format msgid "invalid adnum value %d for table \"%s\"" msgstr "テーブル\"%2$s\"用のadnumの値%1$dが不正です" -#: pg_dump.c:9852 +#: pg_dump.c:9671 #, c-format msgid "finding invalid not-null constraints" msgstr "未検証の非NULL制約を探しています" -#: pg_dump.c:9950 +#: pg_dump.c:9769 #, c-format msgid "finding table check constraints" msgstr "テーブルのチェック制約を探しています" -#: pg_dump.c:10004 +#: pg_dump.c:9823 #, c-format msgid "expected %d check constraint on table \"%s\" but found %d" msgid_plural "expected %d check constraints on table \"%s\" but found %d" msgstr[0] "テーブル\"%2$s\"で想定する検査制約は%1$d個でしたが、%3$dありました" -#: pg_dump.c:10008 +#: pg_dump.c:9827 #, c-format msgid "The system catalogs might be corrupted." msgstr "システムカタログが破損している可能性があります。" -#: pg_dump.c:10823 +#: pg_dump.c:10642 #, c-format msgid "role with OID %u does not exist" msgstr "OID が %u であるロールは存在しません" -#: pg_dump.c:10935 pg_dump.c:10964 +#: pg_dump.c:10752 pg_dump.c:10781 #, c-format msgid "unsupported pg_init_privs entry: %u %u %d" msgstr "非サポートのpg_init_privsエントリ: %u %u %d" -#: pg_dump.c:11286 +#: pg_dump.c:11093 #, c-format msgid "statistics dumped out of order (current: %d %s %s, expected: %d %s %s)" msgstr "統計情報が異常な順序でダンプされています (現在: %d %s %s, 想定: %d %s %s)" -#: pg_dump.c:11441 +#: pg_dump.c:11237 #, c-format msgid "unexpected null attname" msgstr "attname が NULL です" -#: pg_dump.c:11470 +#: pg_dump.c:11266 #, c-format msgid "could not find index attname \"%s\"" msgstr "\"%s\" というインデックスのattnameは見つかりませんでした" -#: pg_dump.c:11957 +#: pg_dump.c:11753 #, c-format msgid "missing metadata for large objects \"%s\"" msgstr "ラージオブジェクト\"%s\"のメタデータがありません" -#: pg_dump.c:12238 +#: pg_dump.c:12034 #, c-format msgid "typtype of data type \"%s\" appears to be invalid" msgstr "データ型\"%s\"のtyptypeが不正なようです" -#: pg_dump.c:13866 +#: pg_dump.c:13654 #, c-format msgid "unrecognized provolatile value for function \"%s\"" msgstr "関数\"%s\"のprovolatileの値が認識できません" -#: pg_dump.c:13916 pg_dump.c:15816 +#: pg_dump.c:13704 pg_dump.c:15579 #, c-format msgid "unrecognized proparallel value for function \"%s\"" msgstr "関数\"%s\"のproparallel値が認識できません" -#: pg_dump.c:14050 pg_dump.c:14156 pg_dump.c:14163 +#: pg_dump.c:13838 pg_dump.c:13944 pg_dump.c:13951 #, c-format msgid "could not find function definition for function with OID %u" msgstr "OID %uの関数の関数定義が見つかりませんでした" -#: pg_dump.c:14089 +#: pg_dump.c:13877 #, c-format msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" msgstr "pg_cast.castfuncまたはpg_cast.castmethodフィールドの値がおかしいです" -#: pg_dump.c:14092 +#: pg_dump.c:13880 #, c-format msgid "bogus value in pg_cast.castmethod field" msgstr "pg_cast.castmethod フィールドの値がおかしいです" -#: pg_dump.c:14182 +#: pg_dump.c:13970 #, c-format msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" msgstr "おかしな変換定義、trffromsql か trftosql の少なくとも一方は非ゼロであるはずです" -#: pg_dump.c:14199 +#: pg_dump.c:13987 #, c-format msgid "bogus value in pg_transform.trffromsql field" msgstr "pg_cast.castmethod フィールドの値がおかしいです" -#: pg_dump.c:14220 +#: pg_dump.c:14008 #, c-format msgid "bogus value in pg_transform.trftosql field" msgstr "pg_cast.castmethod フィールドの値がおかしいです" -#: pg_dump.c:14365 +#: pg_dump.c:14153 #, c-format msgid "postfix operators are not supported anymore (operator \"%s\")" msgstr "後置演算子は今後サポートされません(演算子\"%s\")" -#: pg_dump.c:14535 +#: pg_dump.c:14323 #, c-format msgid "could not find operator with OID %s" msgstr "OID %sの演算子がありませんでした" -#: pg_dump.c:14603 +#: pg_dump.c:14391 #, c-format msgid "invalid type \"%c\" of access method \"%s\"" msgstr "アクセスメソッド\"%2$s\"の不正なタイプ\"%1$c\"" -#: pg_dump.c:15277 pg_dump.c:15345 +#: pg_dump.c:15060 pg_dump.c:15128 #, c-format msgid "unrecognized collation provider: %s" msgstr "認識できないの照合順序プロバイダ: %s" -#: pg_dump.c:15286 pg_dump.c:15293 pg_dump.c:15304 pg_dump.c:15314 -#: pg_dump.c:15329 +#: pg_dump.c:15069 pg_dump.c:15076 pg_dump.c:15087 pg_dump.c:15097 +#: pg_dump.c:15112 #, c-format msgid "invalid collation \"%s\"" msgstr "不正な照合順序\"%s\"" -#: pg_dump.c:15735 +#: pg_dump.c:15498 #, c-format msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" msgstr "集約\"%s\"のaggfinalmodifyの値が識別できません" -#: pg_dump.c:15791 +#: pg_dump.c:15554 #, c-format msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" msgstr "集約\"%s\"のaggmfinalmodifyの値が識別できません" -#: pg_dump.c:16514 +#: pg_dump.c:16277 #, c-format msgid "unrecognized object type in default privileges: %d" msgstr "デフォルト権限設定中の認識できないオブジェクト型: %d" -#: pg_dump.c:16530 +#: pg_dump.c:16293 #, c-format msgid "could not parse default ACL list (%s)" msgstr "デフォルトの ACL リスト(%s)をパースできませんでした" -#: pg_dump.c:16614 +#: pg_dump.c:16377 #, c-format msgid "could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)" msgstr "オブジェクト\"%3$s\"(%4$s)の初期ACLリスト(%1$s)またはデフォルト値(%2$s)をパースできませんでした" -#: pg_dump.c:16639 +#: pg_dump.c:16402 #, c-format msgid "could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)" msgstr "オブジェクト\"%3$s\"(%4$s)のACLリスト(%1$s)またはデフォルト値(%2$s)をパースできませんでした" -#: pg_dump.c:17194 +#: pg_dump.c:16944 #, c-format msgid "query to obtain definition of view \"%s\" returned no data" msgstr "ビュー\"%s\"の定義を取り出すための問い合わせがデータを返却しませんでした" -#: pg_dump.c:17197 +#: pg_dump.c:16947 #, c-format msgid "query to obtain definition of view \"%s\" returned more than one definition" msgstr "ビュー\"%s\"の定義を取り出すための問い合わせが2つ以上の定義を返却しました" -#: pg_dump.c:17204 +#: pg_dump.c:16954 #, c-format msgid "definition of view \"%s\" appears to be empty (length zero)" msgstr "ビュー\"%s\"の定義が空のようです(長さが0)" -#: pg_dump.c:17289 +#: pg_dump.c:17039 #, c-format msgid "WITH OIDS is not supported anymore (table \"%s\")" msgstr "WITH OIDSは今後サポートされません(テーブル\"%s\")" -#: pg_dump.c:17352 +#: pg_dump.c:17102 #, c-format msgid "query to obtain definition of property graph \"%s\" returned no data" msgstr "プロパティグラフ\"%s\"の定義を取得する問い合わせがデータを返却しませんでした" -#: pg_dump.c:17355 +#: pg_dump.c:17105 #, c-format msgid "query to obtain definition of property graph \"%s\" returned more than one definition" msgstr "プロパティグラフ\"%s\"の定義を取得する問い合わせが複数の定義を返却しました" -#: pg_dump.c:17362 +#: pg_dump.c:17112 #, c-format msgid "definition of property graph \"%s\" appears to be empty (length zero)" msgstr "プロパティグラフ\"%s\"の定義が空のようです(長さが0)" -#: pg_dump.c:18471 +#: pg_dump.c:18221 #, c-format msgid "invalid column number %d for table \"%s\"" msgstr "テーブル\"%2$s\"の列番号%1$dは不正です" -#: pg_dump.c:18549 +#: pg_dump.c:18299 #, c-format msgid "could not parse index statistic columns" msgstr "インデックス統計列をパースできませんでした" -#: pg_dump.c:18551 +#: pg_dump.c:18301 #, c-format msgid "could not parse index statistic values" msgstr "インデックス統計値をパースできませんでした" -#: pg_dump.c:18553 +#: pg_dump.c:18303 #, c-format msgid "mismatched number of columns and values for index statistics" msgstr "インデックス統計に対して列と値の数が合致しません" -#: pg_dump.c:18965 +#: pg_dump.c:18715 #, c-format msgid "inherited cannot be NULL" msgstr "inherited をNULL にはできません" -#: pg_dump.c:19062 +#: pg_dump.c:18812 #, c-format msgid "missing index for constraint \"%s\"" msgstr "制約\"%s\"のインデックスが見つかりません" -#: pg_dump.c:19331 +#: pg_dump.c:19081 #, c-format msgid "unrecognized constraint type: %c" msgstr "制約のタイプが識別できません: %c" -#: pg_dump.c:19384 +#: pg_dump.c:19134 #, c-format msgid "unrecognized sequence type: %s" msgstr "認識されないシーケンスの型\"%s\"" -#: pg_dump.c:19517 pg_dump.c:19755 +#: pg_dump.c:19257 +#, c-format +msgid "unrecognized sequence type: %d" +msgstr "認識されないシーケンスの型: %d" + +#: pg_dump.c:19457 #, c-format msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" msgstr[0] "シーケンス\"%s\"のデータを得るための問い合わせが%d行返却しました(想定は1)" -#: pg_dump.c:19553 -#, c-format -msgid "unrecognized sequence type: %d" -msgstr "認識されないシーケンスの型: %d" - -#: pg_dump.c:19778 +#: pg_dump.c:19480 #, c-format msgid "failed to get data for sequence \"%s\"; user may lack SELECT privilege on the sequence or the sequence may have been concurrently dropped" msgstr "シーケンス \"%s\" のデータ取得に失敗しました; ユーザーがこのシーケンスへのSELECT権限を持っていないか、このシーケンスが並行して削除された可能性があります" -#: pg_dump.c:20099 +#: pg_dump.c:19801 #, c-format msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" msgstr "テーブル\"%2$s\"のルール\"%1$s\"を得るための問い合わせが失敗しました: 間違った行数が返却されました" -#: pg_dump.c:20252 +#: pg_dump.c:19954 #, c-format msgid "could not find referenced extension %u" msgstr "親の機能拡張%uが見つかりません" -#: pg_dump.c:20351 +#: pg_dump.c:20053 #, c-format msgid "mismatched number of configurations and conditions for extension" msgstr "機能拡張に対して設定と条件の数が一致しません" -#: pg_dump.c:20483 +#: pg_dump.c:20185 #, c-format msgid "reading dependency data" msgstr "データの依存データを読み込んでいます" -#: pg_dump.c:20580 +#: pg_dump.c:20282 #, c-format msgid "no referencing object %u %u" msgstr "参照元オブジェクト%u %uがありません" -#: pg_dump.c:20591 +#: pg_dump.c:20293 #, c-format msgid "no referenced object %u %u" msgstr "参照先オブジェクト%u %uがありません" -#: pg_dump.c:21024 pg_dump.c:21062 pg_dumpall.c:2365 pg_restore.c:858 -#: pg_restore.c:904 +#: pg_dump.c:20726 pg_dump.c:20764 pg_dumpall.c:1830 pg_restore.c:642 +#: pg_restore.c:688 #, c-format msgid "%s filter for \"%s\" is not allowed" msgstr "\"%2$s\"に対しては%1$sフィルターを指定できません" @@ -2661,32 +2659,22 @@ msgstr "この問題を回避するために--data-onlyダンプの代わりに msgid "could not resolve dependency loop among these items:" msgstr "以下の項目の間の依存関係のループを解決できませんでした:" -#: pg_dumpall.c:260 +#: pg_dumpall.c:239 #, c-format msgid "program \"%s\" is needed by %s but was not found in the same directory as \"%s\"" msgstr "%2$sには\"%1$s\"プログラムが必要ですが、\"%3$s\"と同じディレクトリにありませんでした。" -#: pg_dumpall.c:263 +#: pg_dumpall.c:242 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "\"%2$s\"がプログラム\"%1$s\"を見つけましたが、これは%3$sと同じバージョンではありませんでした。" -#: pg_dumpall.c:476 -#, c-format -msgid "option %s=d|c|t requires option %s" -msgstr "オプション %s が d|c|t の場合は %s オプションも必要です" - -#: pg_dumpall.c:484 +#: pg_dumpall.c:401 #, c-format -msgid "option %s can only be used with %s=plain" -msgstr "オプション %s は %s=plain の場合にのみ指定可能です" +msgid "option %s cannot be used together with %s, %s, or %s" +msgstr " %s オプションと %s、%s および %s は同時には使用できません" -#: pg_dumpall.c:489 -#, c-format -msgid "options %s and %s cannot be used together in non-text dump" -msgstr "非テキスト形式のダンプでは、オプション %s と %s は同時には使用できません" - -#: pg_dumpall.c:609 pg_restore.c:1205 +#: pg_dumpall.c:538 #, c-format msgid "" "could not connect to databases \"postgres\" or \"template1\"\n" @@ -2695,89 +2683,89 @@ msgstr "" "\"postgres\"または\"template1\"データベースに接続できませんでした\n" "代わりのデータベースを指定してください。" -#: pg_dumpall.c:871 +#: pg_dumpall.c:704 #, c-format msgid "" -"%s exports a PostgreSQL database cluster as an SQL script or to other formats.\n" +"%s exports a PostgreSQL database cluster as an SQL script.\n" "\n" msgstr "" -"%sは、ひとつのPostgreSQLデータベースクラスタをSQLスクリプトまたは他の形式でエクスポートします。\n" +"%sは、PostgreSQLデータベースクラスタをSQLスクリプト形式でエクスポートします。\n" "\n" -#: pg_dumpall.c:873 +#: pg_dumpall.c:706 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [OPTION]...\n" -#: pg_dumpall.c:876 +#: pg_dumpall.c:709 #, c-format msgid " -f, --file=FILENAME output file name\n" msgstr " -f, --file=ファイル名 出力ファイル名\n" -#: pg_dumpall.c:885 +#: pg_dumpall.c:716 #, c-format msgid " -c, --clean clean (drop) databases before recreating\n" msgstr " -c, --clean 再作成前にデータベースを整理(削除)\n" -#: pg_dumpall.c:887 +#: pg_dumpall.c:718 #, c-format msgid " -g, --globals-only dump only global objects, no databases\n" msgstr "" " -g, --globals-only グローバルオブジェクトのみをダンプし、\n" " データベースをダンプしない\n" -#: pg_dumpall.c:888 pg_restore.c:773 +#: pg_dumpall.c:719 pg_restore.c:559 #, c-format msgid " -O, --no-owner skip restoration of object ownership\n" msgstr " -O, --no-owner オブジェクトの所有権の復元を省略\n" -#: pg_dumpall.c:889 +#: pg_dumpall.c:720 #, c-format msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" msgstr "" " -r, --roles-only ロールのみをダンプ。\n" " データベースとテーブル空間をダンプしない\n" -#: pg_dumpall.c:891 +#: pg_dumpall.c:722 #, c-format msgid " -S, --superuser=NAME superuser user name to use in the dump\n" msgstr "" " -S, --superuser=NAME ダンプで使用するスーパーユーザーのユーザー名を\n" " 指定\n" -#: pg_dumpall.c:892 +#: pg_dumpall.c:723 #, c-format msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" msgstr "" " -t, --tablespaces-only テーブル空間のみをダンプ。データベースとロールを\n" " ダンプしない\n" -#: pg_dumpall.c:898 +#: pg_dumpall.c:729 #, c-format msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" msgstr " --exclude-database=PATTERN PATTERNに合致する名前のデータベースを除外\n" -#: pg_dumpall.c:900 +#: pg_dumpall.c:731 #, c-format msgid " --filter=FILENAME exclude databases based on expressions in FILENAME\n" msgstr " --filter=FILENAME FILENAMEで指定された式に基づいてデータベースを除外する\n" -#: pg_dumpall.c:908 +#: pg_dumpall.c:739 #, c-format msgid " --no-role-passwords do not dump passwords for roles\n" msgstr " --no-role-passwords ロールのパスワードをダンプしない\n" -#: pg_dumpall.c:930 +#: pg_dumpall.c:761 #, c-format msgid " -d, --dbname=CONNSTR connect using connection string\n" msgstr " -d, --dbname=CONSTR 接続文字列を用いた接続\n" -#: pg_dumpall.c:932 +#: pg_dumpall.c:763 #, c-format msgid " -l, --database=DBNAME alternative default database\n" msgstr " -l, --database=DBNAME 代替のデフォルトデータベースを指定\n" -#: pg_dumpall.c:939 +#: pg_dumpall.c:770 #, c-format msgid "" "\n" @@ -2789,215 +2777,155 @@ msgstr "" "-f/--file が指定されない場合、SQLスクリプトは標準出力に書き出されます。\n" "\n" -#: pg_dumpall.c:1107 +#: pg_dumpall.c:887 #, c-format msgid "role name starting with \"pg_\" skipped (%s)" msgstr "\"pg_\"で始まるロール名はスキップされました(%s)" #. translator: %s represents a numeric role OID -#: pg_dumpall.c:1366 +#: pg_dumpall.c:1104 #, c-format msgid "ignoring role grant for missing role with OID %s" msgstr "存在しないOID %s のロールに対するGRANTを無視します" -#: pg_dumpall.c:1404 +#: pg_dumpall.c:1142 #, c-format msgid "could not find a legal dump ordering for memberships in role \"%s\"" msgstr "ロール\"%s\"のメンバーシップに対して正当なダンプ順序が見つかりませんでした" #. translator: %s represents a numeric role OID -#: pg_dumpall.c:1430 +#: pg_dumpall.c:1168 #, c-format msgid "ignoring role grant to missing role with OID %s" msgstr "存在しないOID %s のロールへのGRANTを無視します" #. translator: %s represents a numeric role OID -#: pg_dumpall.c:1445 +#: pg_dumpall.c:1183 #, c-format msgid "grant of role \"%s\" to \"%s\" has invalid grantor OID %s" msgstr "ロール \"%s\"から\"%s\"へのGRANTの権限付与者 OID %s が不正です" -#: pg_dumpall.c:1447 +#: pg_dumpall.c:1185 #, c-format msgid "This grant will be dumped without GRANTED BY." msgstr "このGRANTは GRANTED BY なしでダンプされます。" -#: pg_dumpall.c:1580 +#: pg_dumpall.c:1303 #, c-format msgid "could not parse ACL list (%s) for parameter \"%s\"" msgstr "パラメータ\"%2$s\"のACLリスト(%1$s)をパースできませんでした" -#: pg_dumpall.c:1743 +#: pg_dumpall.c:1430 #, c-format msgid "could not parse ACL list (%s) for tablespace \"%s\"" msgstr "テーブル空間\"%2$s\"のACLリスト(%1$s)をパースできませんでした" -#: pg_dumpall.c:2067 pg_restore.c:1029 +#: pg_dumpall.c:1644 #, c-format msgid "excluding database \"%s\"" msgstr "データベース\"%s\"を除外します" -#: pg_dumpall.c:2071 +#: pg_dumpall.c:1648 #, c-format msgid "dumping database \"%s\"" msgstr "データベース\"%s\"をダンプしています" -#: pg_dumpall.c:2123 +#: pg_dumpall.c:1681 #, c-format msgid "pg_dump failed on database \"%s\", exiting" msgstr "データベース\"%s\"のダンプが失敗しました、終了します" -#: pg_dumpall.c:2129 +#: pg_dumpall.c:1687 #, c-format msgid "could not re-open the output file \"%s\": %m" msgstr "出力ファイル\"%s\"を再オープンできませんでした: %m" -#: pg_dumpall.c:2196 +#: pg_dumpall.c:1731 #, c-format msgid "running \"%s\"" msgstr "\"%s\"を実行しています" -#: pg_dumpall.c:2322 -#, c-format -msgid "" -"database, role, or tablespace names contain a newline or carriage return character, which is not supported in non-plain-text dumps:\n" -"%s" -msgstr "" -"データベース、ロールまたはテーブル空間の名前に改行文字(NL)または復帰文字(CR)が含まれていますが、そのような名前は非プレーンテキストダンプでは使用できません:\n" -"%s" - -#: pg_dumpall.c:2385 +#: pg_dumpall.c:1850 msgid "unsupported filter object" msgstr "サポートされていないフィルターオブジェクト" -#: pg_dumpall.c:2426 -#, c-format -msgid "unrecognized output format \"%s\"; please specify \"c\", \"d\", \"p\", or \"t\"" -msgstr "出力形式\"%s\"が認識できません; \"c\"、\"d\"、\"p\"または\"t\"を指定してください" - -#: pg_restore.c:383 +#: pg_restore.c:348 #, c-format msgid "one of -d/--dbname and -f/--file must be specified" msgstr "-d/--dbnameと-f/--fileのどちらか一方が指定されていなければなりません" -#: pg_restore.c:463 +#: pg_restore.c:433 #, c-format msgid "cannot specify both --single-transaction and multiple jobs" msgstr "--single-transaction と複数ジョブは同時には指定できません" -#: pg_restore.c:510 +#: pg_restore.c:480 #, c-format msgid "archive format \"%s\" is not supported; please use psql" msgstr "アーカイブ形式\"%s\"はサポートされていません、psqlを使ってください" -#: pg_restore.c:514 +#: pg_restore.c:484 #, c-format msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" msgstr "アーカイブ形式\"%s\"が認識できません; \"c\"、\"d\"または\"t\"を指定してください" -#: pg_restore.c:537 pg_restore.c:540 pg_restore.c:544 pg_restore.c:561 -#: pg_restore.c:565 pg_restore.c:569 -#, c-format -msgid "option %s cannot be used when restoring an archive created by pg_dumpall" -msgstr "pg_dumpallで作成したアーカイブの復元の際は、オプション %s は使用できません" - -#: pg_restore.c:547 -#, c-format -msgid "options %s and %s cannot be used together when restoring an archive created by pg_dumpall" -msgstr "pg_dumpallで作成したアーカイブの復元の際は、オプション %s と %s は同時には使用できません" - -#: pg_restore.c:557 -#, c-format -msgid "--if-exists is implied by --clean for pg_dumpall archives" -msgstr "pg_dumpall アーカイブでは、--clean を指定すると、--if-exists が暗黙的に指定されます" - -#: pg_restore.c:573 -#, c-format -msgid "option %s cannot exclude %s when restoring a pg_dumpall archive" -msgstr "pg_dumpallアーカイブの復元の際は、オプション %s で %s を除外できません" - -#: pg_restore.c:583 -#, c-format -msgid "option %s must be specified when restoring an archive created by pg_dumpall" -msgstr "pg_dumpallで作成したアーカイブの復元の際は、オプション %s の指定が必須となります" - -#: pg_restore.c:586 -#, c-format -msgid "Individual databases can be restored using their specific archives." -msgstr "個別のデータベースは、対応するアーカイブを使って復元できます。" - -#: pg_restore.c:599 -#, c-format -msgid "skipping restore of global objects because %s was specified" -msgstr "%s が指定されたため、グローバルオブジェクトの復元はスキップします" - -#: pg_restore.c:603 -#, c-format -msgid "database restoring skipped because option %s was specified" -msgstr "オプション %s が指定されたため、データベースの復元がスキップされました" - -#: pg_restore.c:620 pg_restore.c:625 -#, c-format -msgid "option %s can be used only when restoring an archive created by pg_dumpall" -msgstr "オプション %s はpg_dumpall で作成されたアーカイブからの復元の場合のみ使用可能です" - -#: pg_restore.c:635 +#: pg_restore.c:522 #, c-format msgid "errors ignored on restore: %d" msgstr "リストア中に無視されたエラー数: %d" -#: pg_restore.c:748 +#: pg_restore.c:535 #, c-format msgid "" -"%s restores PostgreSQL databases from archives created by pg_dump or pg_dumpall.\n" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" "\n" msgstr "" -"%sは pg_dump または pg_dumpall で作成したアーカイブからPostgreSQLデータベースを復元します。\n" +"%sはpg_dumpで作成したアーカイブからPostgreSQLデータベースを復元します。\n" "\n" -#: pg_restore.c:750 +#: pg_restore.c:537 #, c-format msgid " %s [OPTION]... [FILE]\n" msgstr " %s [OPTION]... [FILE]\n" -#: pg_restore.c:753 +#: pg_restore.c:540 #, c-format msgid " -d, --dbname=NAME connect to database name\n" msgstr " -d, --dbname=NAME 接続するデータベース名\n" -#: pg_restore.c:754 +#: pg_restore.c:541 #, c-format msgid " -f, --file=FILENAME output file name (- for stdout)\n" msgstr " -f, --file=FILENAME 出力ファイル名(- で標準出力)\n" -#: pg_restore.c:755 +#: pg_restore.c:542 #, c-format msgid " -F, --format=c|d|t backup file format (should be automatic)\n" msgstr "" " -F, --format=c|d|t バックアップファイルの形式\n" " (自動的に設定されるはずです)\n" -#: pg_restore.c:756 +#: pg_restore.c:543 #, c-format msgid " -l, --list print summarized TOC of the archive\n" msgstr " -l, --list アーカイブのTOCの要約を表示\n" -#: pg_restore.c:757 +#: pg_restore.c:544 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose 冗長モード\n" -#: pg_restore.c:758 +#: pg_restore.c:545 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version バージョン情報を表示し、終了します\n" -#: pg_restore.c:759 +#: pg_restore.c:546 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help このヘルプを表示し、終了します\n" -#: pg_restore.c:761 +#: pg_restore.c:548 #, c-format msgid "" "\n" @@ -3006,39 +2934,32 @@ msgstr "" "\n" "リストア制御用のオプション:\n" -#: pg_restore.c:762 +#: pg_restore.c:549 #, c-format msgid " -a, --data-only restore only the data, no schema\n" msgstr " -a, --data-only データのみを復元。スキーマを復元しない\n" -#: pg_restore.c:764 +#: pg_restore.c:551 #, c-format msgid " -C, --create create the target database\n" msgstr " -C, --create 対象のデータベースを作成\n" -#: pg_restore.c:765 +#: pg_restore.c:552 #, c-format msgid " -e, --exit-on-error exit on error, default is to continue\n" msgstr " -e, --exit-on-error エラー時に終了。デフォルトは継続\n" -#: pg_restore.c:766 -#, c-format -msgid " -g, --globals-only restore only global objects, no databases\n" -msgstr "" -" -g, --globals-only グローバルオブジェクトのみを復元し、\n" -" データベースを復元しない\n" - -#: pg_restore.c:767 +#: pg_restore.c:553 #, c-format msgid " -I, --index=NAME restore named index\n" msgstr " -I, --index=NAME 指名したインデックスを復元n\n" -#: pg_restore.c:768 +#: pg_restore.c:554 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" msgstr " -j, --jobs=NUM リストア時に指定した数の並列ジョブを使用\n" -#: pg_restore.c:769 +#: pg_restore.c:555 #, c-format msgid "" " -L, --use-list=FILENAME use table of contents from this file for\n" @@ -3047,62 +2968,57 @@ msgstr "" " -L, --use-list=FILENAME このファイルの内容に従って SELECT や\n" " 出力のソートを行います\n" -#: pg_restore.c:771 +#: pg_restore.c:557 #, c-format msgid " -n, --schema=NAME restore only objects in this schema\n" msgstr " -n, --schema=NAME 指定したスキーマのオブジェクトのみを復元\n" -#: pg_restore.c:772 +#: pg_restore.c:558 #, c-format msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" msgstr " -N, --exclude-schema=NAME 指定したスキーマのオブジェクトは復元しない\n" -#: pg_restore.c:774 +#: pg_restore.c:560 #, c-format msgid " -P, --function=NAME(args) restore named function\n" msgstr " -P, --function=NAME(args) 指名された関数を復元\n" -#: pg_restore.c:775 +#: pg_restore.c:561 #, c-format msgid " -s, --schema-only restore only the schema, no data\n" msgstr " -s, --schema-only スキーマのみを復元。データを復元しない\n" -#: pg_restore.c:776 +#: pg_restore.c:562 #, c-format msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" msgstr " -S, --superuser=NAME トリガを無効にするためのスーパーユーザーの名前\n" -#: pg_restore.c:777 +#: pg_restore.c:563 #, c-format msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" msgstr " -t, --table=NAME 指名したリレーション(テーブル、ビューなど)を復元\n" -#: pg_restore.c:778 +#: pg_restore.c:564 #, c-format msgid " -T, --trigger=NAME restore named trigger\n" msgstr " -T, --trigger=NAME 指名したトリガを復元\n" -#: pg_restore.c:779 +#: pg_restore.c:565 #, c-format msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" msgstr " -x, --no-privileges アクセス権限(grant/revoke)の復元を省略\n" -#: pg_restore.c:780 +#: pg_restore.c:566 #, c-format msgid " -1, --single-transaction restore as a single transaction\n" msgstr " -1, --single-transaction リストアを単一トランザクションで実行\n" -#: pg_restore.c:782 +#: pg_restore.c:568 #, c-format msgid " --enable-row-security enable row security\n" msgstr " --enable-row-security 行セキュリティを有効にします\n" -#: pg_restore.c:783 -#, c-format -msgid " --exclude-database=PATTERN do not restore the specified database(s)\n" -msgstr " --exclude-database=PATTERN 指定したテーブル(群)を復元しない\n" - -#: pg_restore.c:784 +#: pg_restore.c:569 #, c-format msgid "" " --filter=FILENAME restore or skip objects based on expressions\n" @@ -3111,107 +3027,100 @@ msgstr "" " --filter=FILENAME オブジェクトの復元またはスキップをFILENAMEに\n" " 記述されている式を元に行う\n" -#: pg_restore.c:787 +#: pg_restore.c:572 #, c-format msgid " --no-comments do not restore comment commands\n" msgstr " --no-comments コメントコマンドを復元しない\n" -#: pg_restore.c:788 +#: pg_restore.c:573 #, c-format msgid " --no-data do not restore data\n" msgstr " --no-data データを復元しない\n" -#: pg_restore.c:789 +#: pg_restore.c:574 #, c-format msgid "" " --no-data-for-failed-tables do not restore data of tables that could not be\n" " created\n" msgstr " --no-data-for-failed-tables 作成できなかったテーブルのデータは復元しない\n" -#: pg_restore.c:791 -#, c-format -msgid " --no-globals do not restore global objects (roles and tablespaces)\n" -msgstr "" -" --no-globals グローバルオブジェクト(ロールおよびテーブル\n" -" スペース)を復元しない\n" - -#: pg_restore.c:792 +#: pg_restore.c:576 #, c-format msgid " --no-policies do not restore row security policies\n" msgstr " --no-policies 行セキュリティポリシーを復元しない\n" -#: pg_restore.c:793 +#: pg_restore.c:577 #, c-format msgid " --no-publications do not restore publications\n" msgstr " --no-publications パブリケーションを復元しない\n" -#: pg_restore.c:794 +#: pg_restore.c:578 #, c-format msgid " --no-schema do not restore schema\n" msgstr " --no-schema スキーマを復元しない\n" -#: pg_restore.c:795 +#: pg_restore.c:579 #, c-format msgid " --no-security-labels do not restore security labels\n" msgstr " --no-security-labels セキュリティラベルを復元しない\n" -#: pg_restore.c:796 +#: pg_restore.c:580 #, c-format msgid " --no-statistics do not restore statistics\n" msgstr " --no-statistics 統計情報を復元しない\n" -#: pg_restore.c:797 +#: pg_restore.c:581 #, c-format msgid " --no-subscriptions do not restore subscriptions\n" msgstr " --no-subscriptions サブスクリプションを復元しない\n" -#: pg_restore.c:798 +#: pg_restore.c:582 #, c-format msgid " --no-table-access-method do not restore table access methods\n" msgstr " --no-table-access-method テーブルアクセスメソッドを復元しない\n" -#: pg_restore.c:799 +#: pg_restore.c:583 #, c-format msgid " --no-tablespaces do not restore tablespace assignments\n" msgstr " --no-tablespaces テーブル空間の割り当てを復元しない\n" -#: pg_restore.c:801 +#: pg_restore.c:585 #, c-format msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" msgstr " --section=SECTION 指定されたセクション(データ前部、データ、データ後部)を復元\n" -#: pg_restore.c:802 +#: pg_restore.c:586 #, c-format msgid " --statistics restore the statistics\n" msgstr " --statistics 統計情報を復元する\n" -#: pg_restore.c:803 +#: pg_restore.c:587 #, c-format msgid " --statistics-only restore only the statistics, not schema or data\n" msgstr " --statistics-only 統計情報のみを復元、スキーマやデータを復元しない\n" -#: pg_restore.c:806 +#: pg_restore.c:590 #, c-format msgid " --transaction-size=N commit after every N objects\n" msgstr " --transaction-size=N Nオブジェクトごとにコミットします\n" -#: pg_restore.c:817 +#: pg_restore.c:601 #, c-format msgid " --role=ROLENAME do SET ROLE before restore\n" msgstr " --role=ROLENAME リストアに先立って SET ROLE します\n" -#: pg_restore.c:819 +#: pg_restore.c:603 #, c-format msgid "" "\n" -"The options -I, -n, -N, -P, -t, -T, --section, and --exclude-database can be\n" -"combined and specified multiple times to select multiple objects.\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" msgstr "" "\n" -"オプション -I、-n、-N、-P、-t、-T、--section および --exclude-database を組み\n" -"合わせて複数回指定することで複数のオブジェクトを指定できます。\n" +"オプション -I、-n、-N、-P、-t、-T および --section を組み合わせて複数回\n" +"指定することで複数のオブジェクトを指定できます。\n" -#: pg_restore.c:822 +#: pg_restore.c:606 #, c-format msgid "" "\n" @@ -3222,80 +3131,91 @@ msgstr "" "入力ファイル名が指定されない場合、標準入力が使用されます。\n" "\n" -#: pg_restore.c:1012 -#, c-format -msgid "database name \"%s\" matches --exclude-database pattern \"%s\"" -msgstr "データベース名 \"%s\" が --exclude-database のパターン \"%s\" に合致します" +#~ msgid " --exclude-database=PATTERN do not restore the specified database(s)\n" +#~ msgstr " --exclude-database=PATTERN 指定したテーブル(群)を復元しない\n" -#: pg_restore.c:1065 -#, c-format -msgid "database restoring is skipped because file \"%s\" does not exist in directory \"%s\"" -msgstr "ファイル\"%s\"がディレクトリ\"%s\"に存在しないため、データベースの復元をスキップします" +#~ msgid " --no-globals do not restore global objects (roles and tablespaces)\n" +#~ msgstr "" +#~ " --no-globals グローバルオブジェクト(ロールおよびテーブル\n" +#~ " スペース)を復元しない\n" -#: pg_restore.c:1112 -#, c-format -msgid "invalid entry in file \"%s\" on line %d" -msgstr "%2$d行目のファイル\"%1$s\"中の不正なエントリ" +#~ msgid " -g, --globals-only restore only global objects, no databases\n" +#~ msgstr "" +#~ " -g, --globals-only グローバルオブジェクトのみを復元し、\n" +#~ " データベースを復元しない\n" -#: pg_restore.c:1119 -#, c-format -msgid "found database \"%s\" (OID: %u) in file \"%s\"" -msgstr "データベース\"%s\" (OID: %u)はファイル\"%s\"中にあります" +#~ msgid "" +#~ "%s exports a PostgreSQL database cluster as an SQL script or to other formats.\n" +#~ "\n" +#~ msgstr "" +#~ "%sは、ひとつのPostgreSQLデータベースクラスタをSQLスクリプトまたは他の形式でエクスポートします。\n" +#~ "\n" -#: pg_restore.c:1167 -#, c-format -msgid "found %d database name in \"%s\"" -msgid_plural "found %d database names in \"%s\"" -msgstr[0] "\"%2$s\" 内に %1$d 個のデータベース名がありました" +#~ msgid "--if-exists is implied by --clean for pg_dumpall archives" +#~ msgstr "pg_dumpall アーカイブでは、--clean を指定すると、--if-exists が暗黙的に指定されます" -#: pg_restore.c:1189 pg_restore.c:1198 -#, c-format -msgid "trying to connect to database \"%s\"" -msgstr "データベース\"%s\"へ接続試行中" +#~ msgid "Individual databases can be restored using their specific archives." +#~ msgstr "個別のデータベースは、対応するアーカイブを使って復元できます。" -#: pg_restore.c:1224 -#, c-format -msgid "no database needs restoring out of %d database" -msgid_plural "no database needs restoring out of %d databases" -msgstr[0] "%d 個のデータベースの中で復元が必要なものはありません" +#~ msgid "database name \"%s\" matches --exclude-database pattern \"%s\"" +#~ msgstr "データベース名 \"%s\" が --exclude-database のパターン \"%s\" に合致します" -#: pg_restore.c:1232 -#, c-format -msgid "need to restore %d databases out of %d databases" -msgstr "%2$d個のデータベースのうち、%1$d個のデータベースの復元が必要です" +#~ msgid "database restoring is skipped because file \"%s\" does not exist in directory \"%s\"" +#~ msgstr "ファイル\"%s\"がディレクトリ\"%s\"に存在しないため、データベースの復元をスキップします" -#: pg_restore.c:1278 -#, c-format -msgid "restoring database \"%s\"" -msgstr "データベース\"%s\"を復元します" +#~ msgid "database restoring skipped because option %s was specified" +#~ msgstr "オプション %s が指定されたため、データベースの復元がスキップされました" -#: pg_restore.c:1300 -#, c-format -msgid "skipping restore of database \"%s\": database does not exist and %s was not specified" -msgstr "データベース\"%s\"の復元をスキップします: データベースは存在せず、%s も指定されていません" +#~ msgid "" +#~ "database, role, or tablespace names contain a newline or carriage return character, which is not supported in non-plain-text dumps:\n" +#~ "%s" +#~ msgstr "" +#~ "データベース、ロールまたはテーブル空間の名前に改行文字(NL)または復帰文字(CR)が含まれていますが、そのような名前は非プレーンテキストダンプでは使用できません:\n" +#~ "%s" -#: pg_restore.c:1318 -#, c-format -msgid "errors ignored on database \"%s\" restore: %d" -msgstr "データベース \"%s\" の復元中に無視されたエラーの数: %d" +#~ msgid "errors ignored on database \"%s\" restore: %d" +#~ msgstr "データベース \"%s\" の復元中に無視されたエラーの数: %d" -#: pg_restore.c:1322 -#, c-format -msgid "number of restored databases is %d" -msgstr "復元されたデータベースの数は %d" +#~ msgid "found %d database name in \"%s\"" +#~ msgid_plural "found %d database names in \"%s\"" +#~ msgstr[0] "\"%2$s\" 内に %1$d 個のデータベース名がありました" -#~ msgid "" -#~ "%s exports a PostgreSQL database cluster as an SQL script.\n" -#~ "\n" -#~ msgstr "" -#~ "%sは、PostgreSQLデータベースクラスタをSQLスクリプト形式でエクスポートします。\n" -#~ "\n" +#~ msgid "found database \"%s\" (OID: %u) in file \"%s\"" +#~ msgstr "データベース\"%s\" (OID: %u)はファイル\"%s\"中にあります" #~ msgid "found orphaned pg_auth_members entry for role %s" #~ msgstr "ロール %s に対する pg_auth_members エントリがありましたが、このロールは存在しません" -#~ msgid "option %s cannot be used together with %s, %s, or %s" -#~ msgstr " %s オプションと %s、%s および %s は同時には使用できません" +#~ msgid "invalid entry in file \"%s\" on line %d" +#~ msgstr "%2$d行目のファイル\"%1$s\"中の不正なエントリ" + +#~ msgid "need to restore %d databases out of %d databases" +#~ msgstr "%2$d個のデータベースのうち、%1$d個のデータベースの復元が必要です" + +#~ msgid "no database needs restoring out of %d database" +#~ msgid_plural "no database needs restoring out of %d databases" +#~ msgstr[0] "%d 個のデータベースの中で復元が必要なものはありません" + +#~ msgid "number of restored databases is %d" +#~ msgstr "復元されたデータベースの数は %d" + +#~ msgid "option %s can be used only when restoring an archive created by pg_dumpall" +#~ msgstr "オプション %s はpg_dumpall で作成されたアーカイブからの復元の場合のみ使用可能です" + +#~ msgid "option %s can only be used with %s=plain" +#~ msgstr "オプション %s は %s=plain の場合にのみ指定可能です" + +#~ msgid "option %s cannot be used when restoring an archive created by pg_dumpall" +#~ msgstr "pg_dumpallで作成したアーカイブの復元の際は、オプション %s は使用できません" + +#~ msgid "option %s cannot exclude %s when restoring a pg_dumpall archive" +#~ msgstr "pg_dumpallアーカイブの復元の際は、オプション %s で %s を除外できません" + +#~ msgid "option %s must be specified when restoring an archive created by pg_dumpall" +#~ msgstr "pg_dumpallで作成したアーカイブの復元の際は、オプション %s の指定が必須となります" + +#~ msgid "option %s=d|c|t requires option %s" +#~ msgstr "オプション %s が d|c|t の場合は %s オプションも必要です" #~ msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only" #~ msgstr "--exclude-database オプションは -g/--globals-only、-r/--roles-only もしくは -t/--tablespaces-only と一緒には使用できません" @@ -3309,6 +3229,12 @@ msgstr "復元されたデータベースの数は %d" #~ msgid "option --restrict-key can only be used with --format=plain" #~ msgstr "オプション --restrict-key は --format=plain を指定したときのみ指定可能です" +#~ msgid "options %s and %s cannot be used together in non-text dump" +#~ msgstr "非テキスト形式のダンプでは、オプション %s と %s は同時には使用できません" + +#~ msgid "options %s and %s cannot be used together when restoring an archive created by pg_dumpall" +#~ msgstr "pg_dumpallで作成したアーカイブの復元の際は、オプション %s と %s は同時には使用できません" + #~ msgid "options --statistics and --no-statistics cannot be used together" #~ msgstr "オプション --statistics と --no-statistics とは同時には使用できません" @@ -3356,3 +3282,21 @@ msgstr "復元されたデータベースの数は %d" #~ msgid "options -s/--schema-only and -a/--data-only cannot be used together" #~ msgstr "-s/--schema-only と -a/--data-only オプションは同時には使用できません" + +#~ msgid "parallel dumps from standby servers are not supported by this server version" +#~ msgstr "スタンバイサーバーからの並列ダンプはこのサーバーバージョンではサポートされません" + +#~ msgid "restoring database \"%s\"" +#~ msgstr "データベース\"%s\"を復元します" + +#~ msgid "skipping restore of database \"%s\": database does not exist and %s was not specified" +#~ msgstr "データベース\"%s\"の復元をスキップします: データベースは存在せず、%s も指定されていません" + +#~ msgid "skipping restore of global objects because %s was specified" +#~ msgstr "%s が指定されたため、グローバルオブジェクトの復元はスキップします" + +#~ msgid "trying to connect to database \"%s\"" +#~ msgstr "データベース\"%s\"へ接続試行中" + +#~ msgid "unrecognized output format \"%s\"; please specify \"c\", \"d\", \"p\", or \"t\"" +#~ msgstr "出力形式\"%s\"が認識できません; \"c\"、\"d\"、\"p\"または\"t\"を指定してください" diff --git a/src/bin/pg_dump/po/ka.po b/src/bin/pg_dump/po/ka.po index 0da2850c7a5..53b2804cdf6 100644 --- a/src/bin/pg_dump/po/ka.po +++ b/src/bin/pg_dump/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_dump (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-13 06:26+0000\n" -"PO-Revision-Date: 2026-05-13 09:10+0200\n" +"POT-Creation-Date: 2026-06-30 04:25+0000\n" +"PO-Revision-Date: 2026-07-02 06:23+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -125,7 +125,7 @@ msgstr "ბრძანებიდან \"%s\" წაკითხვის შ msgid "no data was returned by command \"%s\"" msgstr "ბრძანებამ \"%s\" მონაცემები არ დააბრუნა" -#: ../../common/exec.c:406 parallel.c:1625 +#: ../../common/exec.c:406 parallel.c:1611 #, c-format msgid "%s() failed: %m" msgstr "%s()-ის შეცდომა: %m" @@ -157,7 +157,6 @@ msgstr "არასწორი მეხსიერების გამო #: ../../common/file_utils.c:69 ../../common/file_utils.c:370 #: ../../common/file_utils.c:428 ../../common/file_utils.c:502 -#: pg_dumpall.c:2037 pg_restore.c:1075 #, c-format msgid "could not open file \"%s\": %m" msgstr "ფაილის (%s) გახსნის შეცდომა: %m" @@ -243,17 +242,21 @@ msgstr "%s არაა საზღვრებში %d-დან %d-მდე msgid "unrecognized sync method: %s" msgstr "უცნობი სინქრონიზაციის მეთოდი: %s" -#: ../../fe_utils/option_utils.c:139 +#: ../../fe_utils/option_utils.c:139 pg_dumpall.c:411 pg_dumpall.c:419 +#: pg_dumpall.c:431 pg_dumpall.c:436 pg_restore.c:355 pg_restore.c:362 +#: pg_restore.c:382 pg_restore.c:385 pg_restore.c:388 pg_restore.c:393 +#: pg_restore.c:396 pg_restore.c:399 pg_restore.c:404 pg_restore.c:409 +#: pg_restore.c:412 pg_restore.c:416 pg_restore.c:420 pg_restore.c:428 #, c-format msgid "options %s and %s cannot be used together" msgstr "პარამეტრებს %s და -%s ერთად ვერ გამოიყენებთ" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "გარსის ბრძანების არგუმენტი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "მონაცემთა ბაზის სახელი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" @@ -468,22 +471,22 @@ msgstr "გამოწერების კითხვა" msgid "reading subscription membership of relations" msgstr "ურთიერთობების გამოწერის წევრობის კითხვა" -#: common.c:310 +#: common.c:311 #, c-format msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" msgstr "სისწორის შემოწმების შეცდომა. ცხრილის (\"%2$s\", OID %3$u) მშობელი OID (%1$u) არ არსებობს" -#: common.c:352 +#: common.c:353 #, c-format msgid "invalid number of parents %d for table \"%s\"" msgstr "მშობლების არასწორი რაოდენობა %d ცხრილისთვის \"%s\"" -#: common.c:1129 +#: common.c:1131 #, c-format msgid "could not parse numeric array \"%s\": too many numbers" msgstr "რიცხვითი მასივის \"%s\" დამუშავების შეცდომა: მეტისმეტად ბევრი რიცხვი" -#: common.c:1141 +#: common.c:1143 #, c-format msgid "could not parse numeric array \"%s\": invalid character in number" msgstr "რიცხვითი მასივის \"%s\" დამუშავების შეცდომა: რიცხვში არასწორის სიმბოლოებია" @@ -622,7 +625,7 @@ msgstr "პაროლი: " msgid "%s" msgstr "%s" -#: connectdb.c:157 pg_dumpall.c:595 pg_restore.c:1184 +#: connectdb.c:157 pg_dumpall.c:524 #, c-format msgid "could not connect to database \"%s\"" msgstr "მონაცემთა ბაზასთან დაკავშირება ვერ მოხერხდა \"%s\"" @@ -647,22 +650,22 @@ msgstr "ოპერაცია გაუქმდა სერვერის msgid "server version: %s; %s version: %s" msgstr "სერვერის ვერსია: %s; %s ვერსია: %s" -#: connectdb.c:282 pg_dumpall.c:2243 +#: connectdb.c:282 pg_dumpall.c:1806 #, c-format msgid "executing %s" msgstr "%s -ის შესრულება" -#: connectdb.c:288 pg_backup_db.c:210 pg_dumpall.c:2249 +#: connectdb.c:288 pg_backup_db.c:210 pg_dumpall.c:1812 #, c-format msgid "query failed: %s" msgstr "მოთხოვნის შეცდომა: %s" -#: connectdb.c:289 pg_backup_db.c:212 pg_dumpall.c:2250 +#: connectdb.c:289 pg_backup_db.c:212 pg_dumpall.c:1813 #, c-format msgid "Query was: %s" msgstr "მოთხოვნის შინაარსი: %s" -#: dumputils.c:956 pg_dumpall.c:2030 +#: dumputils.c:956 #, c-format msgid "could not create directory \"%s\": %m" msgstr "საქაღალდის (%s) შექმნის შეცდომა: %m" @@ -732,27 +735,27 @@ msgstr "მხარდაუჭერელი ფილტრის ობი msgid "%s() failed: error code %d" msgstr "%s() -ის შეცდომა: შეცდომის კოდი: %d" -#: parallel.c:975 +#: parallel.c:961 #, c-format msgid "could not create communication channels: %m" msgstr "საკომუნიკაციო არხების შექმნა ვერ მოხერხდა: %m" -#: parallel.c:1032 +#: parallel.c:1018 #, c-format msgid "could not create worker process: %m" msgstr "დამხმარე პროცესის შექმნა შეუძლებელია: %m" -#: parallel.c:1162 +#: parallel.c:1148 #, c-format msgid "unrecognized command received from leader: \"%s\"" msgstr "თავსართიდან მიღებული ბრძანება უცნობია: %s" -#: parallel.c:1205 parallel.c:1443 +#: parallel.c:1191 parallel.c:1429 #, c-format msgid "invalid message received from worker: \"%s\"" msgstr "დამხმარე პროცესისგან მიღებულია არასწორი შეტყობინება: %s" -#: parallel.c:1337 +#: parallel.c:1323 #, c-format msgid "" "could not obtain lock on relation \"%s\"\n" @@ -761,52 +764,52 @@ msgstr "" "ურთიერთობის (\"%s\") დაბლოკვის შეცდომა\n" "ეს ჩვეულებრივ ნიშნავს, რომ ვინმემ მოითხოვა ACCESS EXCLUSIVE ბლოკი ცხრილზე მას შემდეგ, რაც pg_dump-ის მშობელმა პროცესმა საწყისი ACCESS SHARE ბლოკი ცხრილზე უკვე მიიღო." -#: parallel.c:1426 +#: parallel.c:1412 #, c-format msgid "a worker process died unexpectedly" msgstr "დამხმარე პროტოკოლის პროცესი მოულოდნელად მოკვდა" -#: parallel.c:1548 parallel.c:1666 +#: parallel.c:1534 parallel.c:1652 #, c-format msgid "could not write to the communication channel: %m" msgstr "საკომუნიკაციო არხში ჩაწერის შეცდომა: %m" -#: parallel.c:1750 +#: parallel.c:1736 #, c-format msgid "pgpipe: could not create socket: error code %d" msgstr "pgpipe: სოკეტის შექმნის შეცდომა. შეცდომის კოდი: %d" -#: parallel.c:1761 +#: parallel.c:1747 #, c-format msgid "pgpipe: could not bind: error code %d" msgstr "pgpipe: მიბმის შეცდომა: შეცდომის კოდი: %d" -#: parallel.c:1768 +#: parallel.c:1754 #, c-format msgid "pgpipe: could not listen: error code %d" msgstr "pgpipe: მოსმენის შეცდომა: შეცდომის კოდი: %d" -#: parallel.c:1775 +#: parallel.c:1761 #, c-format msgid "pgpipe: %s() failed: error code %d" msgstr "pgpipe: %s() -ის შეცდომა: შეცდომის კოდი %d" -#: parallel.c:1786 +#: parallel.c:1772 #, c-format msgid "pgpipe: could not create second socket: error code %d" msgstr "pgpipe: მეორე სოკეტის შექნა შეუძლებელია: შეცდომის კოდი: %d" -#: parallel.c:1795 +#: parallel.c:1781 #, c-format msgid "pgpipe: could not connect socket: error code %d" msgstr "pgpipe: სოკეტთან მიერთების შეცდომა: შეცდომის კოდი %d" -#: parallel.c:1804 +#: parallel.c:1790 #, c-format msgid "pgpipe: could not accept connection: error code %d" msgstr "pgpipe: შეერთების დადასტურება შეუძლებელია: შეცდომის კოდი %d" -#: pg_backup_archiver.c:272 pg_backup_archiver.c:1770 +#: pg_backup_archiver.c:272 pg_backup_archiver.c:1748 #, c-format msgid "could not close output file: %m" msgstr "გამოტანის ფაილის დახურვის შეცდომა: %m" @@ -821,442 +824,442 @@ msgstr "არქივის ჩანაწერების მიმდე msgid "unexpected section code %d" msgstr "სექციის მოულოდნელი კოდი %d" -#: pg_backup_archiver.c:368 +#: pg_backup_archiver.c:363 #, c-format msgid "parallel restore is not supported with this archive file format" msgstr "არქივის ფაილის ამ ფორმატზე პარალელური აღდგენა მხარდაჭერილი არაა" -#: pg_backup_archiver.c:372 +#: pg_backup_archiver.c:367 #, c-format msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" msgstr "არქივის ფაილზე, რომელიც 8.0 pg_dump-ით ან უფრო ძველით შეიქმნა, პარალელური აღდგენა მხარდაჭერილი არაა" -#: pg_backup_archiver.c:393 +#: pg_backup_archiver.c:388 #, c-format msgid "cannot restore from compressed archive (%s)" msgstr "შეკუმშული არქივიდან (%s) აღდგენა შეუძლებელია" -#: pg_backup_archiver.c:413 +#: pg_backup_archiver.c:408 #, c-format msgid "connecting to database for restore" msgstr "მონაცემთა ბაზასთან დაკავშირება აღდგენისთვის" -#: pg_backup_archiver.c:415 +#: pg_backup_archiver.c:410 #, c-format msgid "direct database connections are not supported in pre-1.3 archives" msgstr "ბაზასთან პირდაპირი შეერთება 1.3 ან უფრო ძველ არქივებში მხარდაჭერილი არაა" -#: pg_backup_archiver.c:458 +#: pg_backup_archiver.c:453 #, c-format msgid "implied no-schema restore" msgstr "სავარაუდო no-schema-ის აღდგენა" -#: pg_backup_archiver.c:537 +#: pg_backup_archiver.c:532 #, c-format msgid "dropping %s %s" msgstr "მოცილება %s %s" -#: pg_backup_archiver.c:669 +#: pg_backup_archiver.c:664 #, c-format msgid "could not find where to insert IF EXISTS in statement \"%s\"" msgstr "ვერ ვიპოვე, ოპერაციაში \"%s\" IF EXISTS სად უნდა ჩავსვა" -#: pg_backup_archiver.c:876 pg_backup_archiver.c:878 +#: pg_backup_archiver.c:858 pg_backup_archiver.c:860 #, c-format msgid "warning from original dump file: %s" msgstr "გაფრთხილება საწყისი გამოტანილი ფაილიდან: %s" -#: pg_backup_archiver.c:912 +#: pg_backup_archiver.c:894 #, c-format msgid "creating %s \"%s.%s\"" msgstr "იქმნება %s \"%s.%s\"" -#: pg_backup_archiver.c:915 +#: pg_backup_archiver.c:897 #, c-format msgid "creating %s \"%s\"" msgstr "იქმნება %s \"%s\"" -#: pg_backup_archiver.c:965 +#: pg_backup_archiver.c:947 #, c-format msgid "connecting to new database \"%s\"" msgstr "ახალ ბაზასთან მიერთება \"%s\"" -#: pg_backup_archiver.c:992 +#: pg_backup_archiver.c:974 #, c-format msgid "processing %s" msgstr "დამუშავება %s" -#: pg_backup_archiver.c:1014 +#: pg_backup_archiver.c:996 #, c-format msgid "processing data for table \"%s.%s\"" msgstr "მონაცემების დამუშავება ცხრილისთვის \"%s.%s\"" -#: pg_backup_archiver.c:1084 +#: pg_backup_archiver.c:1066 #, c-format msgid "executing %s %s" msgstr "შესრულება %s %s" -#: pg_backup_archiver.c:1153 +#: pg_backup_archiver.c:1135 #, c-format msgid "disabling triggers for %s" msgstr "%s-სთვის ტრიგერების გამორთვა" -#: pg_backup_archiver.c:1179 +#: pg_backup_archiver.c:1161 #, c-format msgid "enabling triggers for %s" msgstr "%s-სთვის ტრიგერების ჩართვა" -#: pg_backup_archiver.c:1244 +#: pg_backup_archiver.c:1226 #, c-format msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" msgstr "შიდა შეცდომა -- WriteData-ს DataDumper-ის ქვეპროგრამის კონტექსტის გარეთ ვერ გამოიძახებთ" -#: pg_backup_archiver.c:1439 +#: pg_backup_archiver.c:1421 #, c-format msgid "large-object output not supported in chosen format" msgstr "არჩეულ ფორმატს დიდი ობიექტების გამოტანის საშუალება არ გააჩნია" -#: pg_backup_archiver.c:1502 +#: pg_backup_archiver.c:1484 #, c-format msgid "restored %d large object" msgid_plural "restored %d large objects" msgstr[0] "აღდგენილია %d დიდი ობიექტი" msgstr[1] "აღდგენილია %d დიდი ობიექტი" -#: pg_backup_archiver.c:1529 pg_backup_tar.c:683 +#: pg_backup_archiver.c:1511 pg_backup_tar.c:683 #, c-format msgid "restoring large object with OID %u" msgstr "მიმდინარეობს დიდი ობიექტის აღდგენა OID-ით: %u" -#: pg_backup_archiver.c:1541 +#: pg_backup_archiver.c:1523 #, c-format msgid "could not create large object %u: %s" msgstr "დიდი ობიექტის (%u) შექმნის შეცდომა: %s" -#: pg_backup_archiver.c:1546 pg_dump.c:4197 +#: pg_backup_archiver.c:1528 pg_dump.c:4197 #, c-format msgid "could not open large object %u: %s" msgstr "დიდი ობიექტის (%u) გახსნის შეცდომა: %s" -#: pg_backup_archiver.c:1602 +#: pg_backup_archiver.c:1584 #, c-format msgid "could not open TOC file \"%s\": %m" msgstr "TOC ფაილის (%s) გახსნის შეცდომა: %m" -#: pg_backup_archiver.c:1630 +#: pg_backup_archiver.c:1612 #, c-format msgid "line ignored: %s" msgstr "ხაზი გამოტოვებულია: %s" -#: pg_backup_archiver.c:1637 pg_backup_db.c:548 +#: pg_backup_archiver.c:1619 pg_backup_db.c:548 #, c-format msgid "could not find entry for ID %d" msgstr "ჩანაწერი ID-ით %d არ არსებობს" -#: pg_backup_archiver.c:1660 pg_backup_directory.c:187 +#: pg_backup_archiver.c:1642 pg_backup_directory.c:187 #: pg_backup_directory.c:563 #, c-format msgid "could not close TOC file: %m" msgstr "TOC ფაილის დახურვის შეცდომა: %m" -#: pg_backup_archiver.c:1751 pg_backup_custom.c:151 pg_backup_directory.c:301 +#: pg_backup_archiver.c:1729 pg_backup_custom.c:151 pg_backup_directory.c:301 #: pg_backup_directory.c:550 pg_backup_directory.c:616 -#: pg_backup_directory.c:634 pg_dumpall.c:567 +#: pg_backup_directory.c:634 pg_dumpall.c:558 #, c-format msgid "could not open output file \"%s\": %m" msgstr "გამოტანის ფაილის (\"%s\") გახსნის შეცდომა: %m" -#: pg_backup_archiver.c:1753 pg_backup_custom.c:157 +#: pg_backup_archiver.c:1731 pg_backup_custom.c:157 #, c-format msgid "could not open output file: %m" msgstr "გამოტანის ფაილის გახსნის შეცდომა: %m" -#: pg_backup_archiver.c:1836 +#: pg_backup_archiver.c:1814 #, c-format msgid "wrote %zu byte of large object data (result = %d)" msgid_plural "wrote %zu bytes of large object data (result = %d)" msgstr[0] "ჩაწერილია დიდი ობიექტის მონაცემების %zu ბაიტი (შედეგი = %d)" msgstr[1] "ჩაწერილია დიდი ობიექტის მონაცემების %zu ბაიტი (შედეგი = %d)" -#: pg_backup_archiver.c:1842 +#: pg_backup_archiver.c:1820 #, c-format msgid "could not write to large object: %s" msgstr "დიდი ობიექტის ჩაწერის შეცდომა: %s" -#: pg_backup_archiver.c:1932 +#: pg_backup_archiver.c:1910 #, c-format msgid "while INITIALIZING:" msgstr "INITIALIZING-ის დროს:" -#: pg_backup_archiver.c:1937 +#: pg_backup_archiver.c:1915 #, c-format msgid "while PROCESSING TOC:" msgstr "PROCESSING TOC-ის დროს:" -#: pg_backup_archiver.c:1942 +#: pg_backup_archiver.c:1920 #, c-format msgid "while FINALIZING:" msgstr "FINALIZING-ის დროს:" -#: pg_backup_archiver.c:1947 +#: pg_backup_archiver.c:1925 #, c-format msgid "from TOC entry %d; %u %u %s %s %s" msgstr "შინაარსის ჩანაწერიდან %d; %u %u %s %s %s" -#: pg_backup_archiver.c:2023 +#: pg_backup_archiver.c:2001 #, c-format msgid "bad dumpId" msgstr "არასწორი dumpId" -#: pg_backup_archiver.c:2044 +#: pg_backup_archiver.c:2022 #, c-format msgid "bad table dumpId for TABLE DATA item" msgstr "ცხრილის არასწორი dumpId-ი TABLE DATA ელემენტისთვის" -#: pg_backup_archiver.c:2136 +#: pg_backup_archiver.c:2114 #, c-format msgid "unexpected data offset flag %d" msgstr "მონაცემების წანაცვლების მოულოდნელი ალამი: %d" -#: pg_backup_archiver.c:2149 +#: pg_backup_archiver.c:2127 #, c-format msgid "file offset in dump file is too large" msgstr "გამოტანილ ფაილში ფაილის წანაცვლება ძალიან დიდია" -#: pg_backup_archiver.c:2260 pg_restore.c:939 +#: pg_backup_archiver.c:2238 #, c-format msgid "directory name too long: \"%s\"" msgstr "საქაღალდის სახელი ძალიან გრძელია : \"%s\"" -#: pg_backup_archiver.c:2310 +#: pg_backup_archiver.c:2288 #, c-format msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" msgstr "საქაღალდე \"%s\" სწორ არქივს არ ჰგავს (\"toc.dat\" არ არსებობს)" -#: pg_backup_archiver.c:2318 pg_backup_custom.c:168 pg_backup_custom.c:820 +#: pg_backup_archiver.c:2296 pg_backup_custom.c:168 pg_backup_custom.c:820 #: pg_backup_directory.c:172 pg_backup_directory.c:358 #, c-format msgid "could not open input file \"%s\": %m" msgstr "შეყვანის ფაილის (\"%s\") გახსნის შეცდომა: %m" -#: pg_backup_archiver.c:2325 pg_backup_custom.c:174 +#: pg_backup_archiver.c:2303 pg_backup_custom.c:174 #, c-format msgid "could not open input file: %m" msgstr "შეყვანის ფაილის გახსნის შეცდომა: %m" -#: pg_backup_archiver.c:2331 +#: pg_backup_archiver.c:2309 #, c-format msgid "could not read input file: %m" msgstr "შემოსატანი ფაილის წაკითხვის შეცდომა: %m" -#: pg_backup_archiver.c:2333 +#: pg_backup_archiver.c:2311 #, c-format msgid "input file is too short (read %zu, expected 5)" msgstr "შეყვანის ფაილი ძალიან მოკლეა (წავიკითხე %zu, მოველოდი: 5)" -#: pg_backup_archiver.c:2364 +#: pg_backup_archiver.c:2342 #, c-format msgid "input file appears to be a text format dump. Please use psql." msgstr "შეყვანის ფაილი, როგორც ჩანს, არის ტექსტის ფორმატის დამპია. გთხოვთ გამოიყენოთ psql." -#: pg_backup_archiver.c:2370 +#: pg_backup_archiver.c:2348 #, c-format msgid "input file does not appear to be a valid archive (too short?)" msgstr "შეყვანილი ფაილი სწორ არქივს არ ჰგავს (ძალიან მოკლეა)" -#: pg_backup_archiver.c:2376 +#: pg_backup_archiver.c:2354 #, c-format msgid "input file does not appear to be a valid tar archive" msgstr "შეყვანის ფაილი სწორ tar არქივს არ ჰგავს" -#: pg_backup_archiver.c:2385 +#: pg_backup_archiver.c:2363 #, c-format msgid "could not close input file: %m" msgstr "შეყვანის ფაილის დახურვის შეცდომა: %m" -#: pg_backup_archiver.c:2464 +#: pg_backup_archiver.c:2442 #, c-format msgid "could not open stdout for appending: %m" msgstr "stdout-ის ბოლოში მისაწერად გახსნა შეუძლებელია: %m" -#: pg_backup_archiver.c:2509 +#: pg_backup_archiver.c:2487 #, c-format msgid "unrecognized file format \"%d\"" msgstr "ფაილის უცნობი ფორმატი \"%d\"" -#: pg_backup_archiver.c:2590 pg_backup_archiver.c:4859 +#: pg_backup_archiver.c:2568 pg_backup_archiver.c:4845 #, c-format msgid "finished item %d %s %s" msgstr "დასრულებული ელემენტი %d %s %s" -#: pg_backup_archiver.c:2594 pg_backup_archiver.c:4872 +#: pg_backup_archiver.c:2572 pg_backup_archiver.c:4858 #, c-format msgid "worker process failed: exit code %d" msgstr "დამხმარე პროცესის შეცდომა: გამოსვლის კოდი %d" -#: pg_backup_archiver.c:2692 +#: pg_backup_archiver.c:2670 #, c-format msgid "unexpected TOC entry in WriteToc(): %d %s %s" msgstr "მოულოდნელი TOC-ის ჩანაწერი ფუნქციაში WriteToc(): %d %s %s" -#: pg_backup_archiver.c:2696 pg_backup_custom.c:440 pg_backup_custom.c:506 +#: pg_backup_archiver.c:2674 pg_backup_custom.c:440 pg_backup_custom.c:506 #: pg_backup_custom.c:642 pg_backup_custom.c:878 pg_backup_tar.c:1004 #: pg_backup_tar.c:1009 #, c-format msgid "error during file seek: %m" msgstr "ფაილში გადახვევის პრობლემა: %m" -#: pg_backup_archiver.c:2754 +#: pg_backup_archiver.c:2732 #, c-format msgid "entry ID %d out of range -- perhaps a corrupt TOC" msgstr "ელემენტის ID %d დიაპაზონს გარეთაა -- შეიძლება სარჩევი დაზიანებულია" -#: pg_backup_archiver.c:2837 +#: pg_backup_archiver.c:2815 #, c-format msgid "restoring tables WITH OIDS is not supported anymore" msgstr "ცხრილების, აღწერილი WITH OIDS -ით, აღდგენა მხარდაჭერილი აღარაა" -#: pg_backup_archiver.c:2919 +#: pg_backup_archiver.c:2897 #, c-format msgid "unrecognized encoding \"%s\"" msgstr "უცნობი კოდირება \"%s\"" -#: pg_backup_archiver.c:2925 +#: pg_backup_archiver.c:2903 #, c-format msgid "invalid ENCODING item: %s" msgstr "არასწორი ელემენტი \"ENCODING\": %s" -#: pg_backup_archiver.c:2943 +#: pg_backup_archiver.c:2921 #, c-format msgid "invalid STDSTRINGS item: %s" msgstr "არასწორი ელემენტი \"STDSTRINGS\": %s" -#: pg_backup_archiver.c:2968 +#: pg_backup_archiver.c:2946 #, c-format msgid "schema \"%s\" not found" msgstr "სქემა \"%s\" არ არსებობს" -#: pg_backup_archiver.c:2975 +#: pg_backup_archiver.c:2953 #, c-format msgid "table \"%s\" not found" msgstr "ცხრილი %s არ არსებობს" -#: pg_backup_archiver.c:2982 +#: pg_backup_archiver.c:2960 #, c-format msgid "index \"%s\" not found" msgstr "ინდექსი %s არ არსებობს" -#: pg_backup_archiver.c:2989 +#: pg_backup_archiver.c:2967 #, c-format msgid "function \"%s\" not found" msgstr "ფუნქცია %s არ არსებობს" -#: pg_backup_archiver.c:2996 +#: pg_backup_archiver.c:2974 #, c-format msgid "trigger \"%s\" not found" msgstr "ტრიგერი %s არ არსებობს" -#: pg_backup_archiver.c:3528 +#: pg_backup_archiver.c:3517 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "სესიის მომხმარებლის %s-ზე დაყენების შეცდომა: %s" -#: pg_backup_archiver.c:3670 +#: pg_backup_archiver.c:3659 #, c-format msgid "could not set \"search_path\" to \"%s\": %s" msgstr "\"session_path\"-ის %s-ზე დაყენების შეცდომა: %s" -#: pg_backup_archiver.c:3731 +#: pg_backup_archiver.c:3720 #, c-format msgid "could not set \"default_tablespace\" to %s: %s" msgstr "default_tablespace-ის %s-ზე დაყენების შეცდომა: %s" -#: pg_backup_archiver.c:3780 +#: pg_backup_archiver.c:3769 #, c-format msgid "could not set \"default_table_access_method\": %s" msgstr "default_table_access_method-ის დაყენების შეცდომა: %s" -#: pg_backup_archiver.c:3829 +#: pg_backup_archiver.c:3818 #, c-format msgid "could not alter table access method: %s" msgstr "ცხრილის წვდომის მეთოდის შეცვლა შეუძლებელია: %s" -#: pg_backup_archiver.c:3934 +#: pg_backup_archiver.c:3920 #, c-format msgid "don't know how to set owner for object type \"%s\"" msgstr "არ ვიცი, როგორ დავაყენო ობიექტის მოცემული ტიპის (%s) მფლობელი" -#: pg_backup_archiver.c:4069 +#: pg_backup_archiver.c:4055 #, c-format msgid "unexpected TOC entry in _printTocEntry(): %d %s %s" msgstr "მოულოდნელი TOC ჩანაწერი ფუნქციაში _printTocEntry(): %d %s %s" -#: pg_backup_archiver.c:4217 +#: pg_backup_archiver.c:4203 #, c-format msgid "did not find magic string in file header" msgstr "ფაილის თავსართში მაგიური სტრიქონი ნაპოვნი არაა" -#: pg_backup_archiver.c:4231 +#: pg_backup_archiver.c:4217 #, c-format msgid "unsupported version (%d.%d) in file header" msgstr "ფაილის თავსართში არსებული ვერსია (%d.%d) მხარდაუჭერელია" -#: pg_backup_archiver.c:4236 +#: pg_backup_archiver.c:4222 #, c-format msgid "sanity check on integer size (%zu) failed" msgstr "მთელი რიცხვის ზომის (%zu) სისწორის შემოწმების შეცდომა" -#: pg_backup_archiver.c:4239 +#: pg_backup_archiver.c:4225 #, c-format msgid "archive was made on a machine with larger integers, some operations might fail" msgstr "არქივი შეიქმნა მანქანაზე, სადაც მთელი რიცხვი უფრო დიდია. ზოგიერთი ოპერაცია შეიძლება შეცდომით დასრულდეს" -#: pg_backup_archiver.c:4249 +#: pg_backup_archiver.c:4235 #, c-format msgid "expected format (%d) differs from format found in file (%d)" msgstr "მოსალოდნელი ფორმატი (%d) განსხვავდება ფაილის ფორმატისგან (%d)" -#: pg_backup_archiver.c:4271 +#: pg_backup_archiver.c:4257 #, c-format msgid "archive is compressed, but this installation does not support compression (%s) -- no data will be available" msgstr "არქივი შეკუმშულია, მაგრამ ამ ვერსიას შეკუმშვის(%s) მხარდაჭერა არ გააჩნია -- მონაცემები მიუწვდომელი იქნება" -#: pg_backup_archiver.c:4307 +#: pg_backup_archiver.c:4293 #, c-format msgid "invalid creation date in header" msgstr "თავსართში არსებული შექმნის დრო არასწორია" -#: pg_backup_archiver.c:4441 +#: pg_backup_archiver.c:4427 #, c-format msgid "processing item %d %s %s" msgstr "მუშავდება ელემენტი %d %s %s" -#: pg_backup_archiver.c:4526 +#: pg_backup_archiver.c:4512 #, c-format msgid "entering main parallel loop" msgstr "მთავარი პარალელური მარყუჟის დასაწყისი" -#: pg_backup_archiver.c:4537 +#: pg_backup_archiver.c:4523 #, c-format msgid "skipping item %d %s %s" msgstr "ელემენტის გამოტოვება %d %s %s" -#: pg_backup_archiver.c:4546 +#: pg_backup_archiver.c:4532 #, c-format msgid "launching item %d %s %s" msgstr "ელემენტის გაშვება %d %s %s" -#: pg_backup_archiver.c:4600 +#: pg_backup_archiver.c:4586 #, c-format msgid "finished main parallel loop" msgstr "მთავარი პარალელური მარყუჟის დასასრული" -#: pg_backup_archiver.c:4636 +#: pg_backup_archiver.c:4622 #, c-format msgid "processing missed item %d %s %s" msgstr "გამორჩენილი ჩანაწერის დამუშავება %d %s %s" -#: pg_backup_archiver.c:5178 +#: pg_backup_archiver.c:5164 #, c-format msgid "table \"%s\" could not be created, will not restore its data" msgstr "ცხრილის (%s) შექმნა შეუძლებელია. მონაცემების აღდგენა არ მოხდება" @@ -1524,9 +1527,10 @@ msgstr "%s-ში ნაპოვნია დაზიანებული თ msgid "unrecognized section name: \"%s\"" msgstr "სექციის უცნობი სახელი: %s" -#: pg_backup_utils.c:57 pg_dump.c:804 pg_dump.c:821 pg_dumpall.c:410 -#: pg_dumpall.c:420 pg_dumpall.c:478 pg_dumpall.c:611 pg_restore.c:361 -#: pg_restore.c:377 pg_restore.c:585 pg_restore.c:1207 +#: pg_backup_utils.c:57 pg_dump.c:804 pg_dump.c:821 pg_dumpall.c:384 +#: pg_dumpall.c:394 pg_dumpall.c:404 pg_dumpall.c:413 pg_dumpall.c:421 +#: pg_dumpall.c:438 pg_dumpall.c:540 pg_restore.c:326 pg_restore.c:342 +#: pg_restore.c:357 #, c-format msgid "Try \"%s --help\" for more information." msgstr "მეტი ინფორმაციისთვის სცადეთ '%s --help'." @@ -1536,7 +1540,7 @@ msgstr "მეტი ინფორმაციისთვის სცად msgid "out of on_exit_nicely slots" msgstr "on_exit_nicely ტიპის სლოტები აღარ დარჩა" -#: pg_dump.c:819 pg_dumpall.c:418 pg_restore.c:375 +#: pg_dump.c:819 pg_dumpall.c:392 pg_restore.c:340 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "მეტისმეტად ბევრი ბრძანების-სტრიქონის არგუმენტი (პირველია \"%s\")" @@ -1546,7 +1550,7 @@ msgstr "მეტისმეტად ბევრი ბრძანები msgid "option %s is not supported with parallel backup" msgstr "პარამეტრი %s მხარდაუჭერელია პარალელური მარქაფისას" -#: pg_dump.c:864 pg_dumpall.c:463 pg_restore.c:490 +#: pg_dump.c:864 pg_dumpall.c:426 pg_restore.c:460 #, c-format msgid "option %s requires option %s" msgstr "პარამეტრს %s სჭირდება პარამეტრი %s" @@ -1556,12 +1560,12 @@ msgstr "პარამეტრს %s სჭირდება პარამ msgid "option %s requires option %s, %s, or %s" msgstr "პარამეტრს %s პარამეტრი %s, %s, ან %s" -#: pg_dump.c:903 pg_dumpall.c:579 pg_restore.c:407 +#: pg_dump.c:903 pg_dumpall.c:508 pg_restore.c:375 #, c-format msgid "could not generate restrict key" msgstr "შეზღუდვის გასაღების გენერაცია შეუძლებელია" -#: pg_dump.c:905 pg_dumpall.c:581 pg_restore.c:409 +#: pg_dump.c:905 pg_dumpall.c:510 pg_restore.c:377 #, c-format msgid "invalid restrict key" msgstr "არასწორი შეზღუდვის გასაღები" @@ -1620,7 +1624,7 @@ msgstr "" "%s გაიტანს PostgreSQL მონაცემთა ბაზას SQL სკრიპტის ან სხვა ფორმატის სახით.\n" "\n" -#: pg_dump.c:1294 pg_dumpall.c:872 pg_restore.c:749 +#: pg_dump.c:1294 pg_dumpall.c:705 pg_restore.c:536 #, c-format msgid "Usage:\n" msgstr "გამოყენება:\n" @@ -1630,7 +1634,7 @@ msgstr "გამოყენება:\n" msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [პარამეტრი]... [ბაზისსახელი]\n" -#: pg_dump.c:1297 pg_dumpall.c:875 pg_restore.c:752 +#: pg_dump.c:1297 pg_dumpall.c:708 pg_restore.c:539 #, c-format msgid "" "\n" @@ -1644,7 +1648,7 @@ msgstr "" msgid " -f, --file=FILENAME output file or directory name\n" msgstr " -f, --file=FILENAME გამოტანის ფაილის სახელი\n" -#: pg_dump.c:1299 pg_dumpall.c:877 +#: pg_dump.c:1299 #, c-format msgid "" " -F, --format=c|d|t|p output file format (custom, directory, tar,\n" @@ -1658,12 +1662,12 @@ msgstr "" msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" msgstr " -j, --jobs=NUM მითითებული რაოდენობის პარალელური დავალების გაშვება\n" -#: pg_dump.c:1302 pg_dumpall.c:879 +#: pg_dump.c:1302 pg_dumpall.c:710 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose დამატებითი ინფორმაციის გამოტანა\n" -#: pg_dump.c:1303 pg_dumpall.c:880 +#: pg_dump.c:1303 pg_dumpall.c:711 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version ვერსიის ინფორმაციის გამოტანა და გასვლა\n" @@ -1677,12 +1681,12 @@ msgstr "" " -Z, --compress=მეთოდი[:წვრილმანი]\n" " შეკუმშვის მითითება\n" -#: pg_dump.c:1306 pg_dumpall.c:881 +#: pg_dump.c:1306 pg_dumpall.c:712 #, c-format msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" msgstr " --lock-wait-timeout=TIMEOUT ცხრილის დაბლოკვისას TIMEOUT ის შემდეგ შეცდომის გამოგდება\n" -#: pg_dump.c:1307 pg_dumpall.c:913 +#: pg_dump.c:1307 pg_dumpall.c:744 #, c-format msgid " --no-sync do not wait for changes to be written safely to disk\n" msgstr " --no-sync არ დაველოდო ცვლილებების დისკზე უსაფრთხოდ ჩაწერას\n" @@ -1692,12 +1696,12 @@ msgstr " --no-sync არ დაველოდო ცვ msgid " --sync-method=METHOD set method for syncing files to disk\n" msgstr " --sync-method=მეთოდი ფაილების დისკზე სინქრონიზაციის მეთოდის დაყენება\n" -#: pg_dump.c:1309 pg_dumpall.c:882 +#: pg_dump.c:1309 pg_dumpall.c:713 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ამ დახმარების ჩვენება და გასვლა\n" -#: pg_dump.c:1311 pg_dumpall.c:883 +#: pg_dump.c:1311 pg_dumpall.c:714 #, c-format msgid "" "\n" @@ -1706,7 +1710,7 @@ msgstr "" "\n" "პარამეტრები, რომლებიც აკონტროლებენ გამოტანას:\n" -#: pg_dump.c:1312 pg_dumpall.c:884 +#: pg_dump.c:1312 pg_dumpall.c:715 #, c-format msgid " -a, --data-only dump only the data, not the schema or statistics\n" msgstr " -a, --data-only მოხდება, მხოლოდ, მონაცემების დამპი, მაგრამ არა სქემის ან სტატისტიკის\n" @@ -1731,7 +1735,7 @@ msgstr " -B, --no-large-objects დიდი ობიექტ msgid " --no-blobs (same as --no-large-objects, deprecated)\n" msgstr " --no-blobs (იგივე, რაც --no-large-objects, რომელიც მოძველებულია)\n" -#: pg_dump.c:1317 pg_restore.c:763 +#: pg_dump.c:1317 pg_restore.c:550 #, c-format msgid " -c, --clean clean (drop) database objects before recreating\n" msgstr " -c, --clean ბაზის ობიექტების წაშლა თავიდან შექმნამდე\n" @@ -1746,7 +1750,7 @@ msgstr " -C, --create გამოტანილში ბა msgid " -e, --extension=PATTERN dump the specified extension(s) only\n" msgstr " -e, --extension=PATTERN მხოლოდ მითითებული გაფართოებების გამოტანა\n" -#: pg_dump.c:1320 pg_dumpall.c:886 +#: pg_dump.c:1320 pg_dumpall.c:717 #, c-format msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" msgstr " -E, --encoding=ENCODING მხოლოდ მითითებული კოდირების მქონე მონაცემების გამოტანა\n" @@ -1770,7 +1774,7 @@ msgstr "" " -O, --no-owner უბრალო ტექსტურ ფორმატში ობიექტების მფლობელობის \n" " აღდგენის გამოტოვება\n" -#: pg_dump.c:1325 pg_dumpall.c:890 +#: pg_dump.c:1325 pg_dumpall.c:721 #, c-format msgid " -s, --schema-only dump only the schema, no data or statistics\n" msgstr " -s, --schema-only მოხდება, მხოლოდ, სქემის დამპი, მაგრამ არა მონაცემების ან სტატისტიკის\n" @@ -1790,27 +1794,27 @@ msgstr " -t, --table=შაბლონი მხოლოდ მი msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" msgstr " -T, --exclude-table=PATTERN მითითებული ცხრილები გამოტანილი არ იქნება\n" -#: pg_dump.c:1329 pg_dumpall.c:893 +#: pg_dump.c:1329 pg_dumpall.c:724 #, c-format msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" msgstr " -x, --no-privileges პრივილეგიები (dump/revoke) გამოტანილი არ იქნება\n" -#: pg_dump.c:1330 pg_dumpall.c:894 +#: pg_dump.c:1330 pg_dumpall.c:725 #, c-format msgid " --binary-upgrade for use by upgrade utilities only\n" msgstr " --binary-upgrade გამოიყენება მხოლოდ განახლების პროგრამების მიერ\n" -#: pg_dump.c:1331 pg_dumpall.c:895 +#: pg_dump.c:1331 pg_dumpall.c:726 #, c-format msgid " --column-inserts dump data as INSERT commands with column names\n" msgstr " --column-inserts მონაცემების დამპი ისე, როგორც ბრძანება INSERT, სვეტების სახელებით\n" -#: pg_dump.c:1332 pg_dumpall.c:896 +#: pg_dump.c:1332 pg_dumpall.c:727 #, c-format msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" msgstr " --disable-dollar-quoting დოლარით ციტირების გამორთვა. სტანდარტული SQL ციტირების გამოყენება\n" -#: pg_dump.c:1333 pg_dumpall.c:897 pg_restore.c:781 +#: pg_dump.c:1333 pg_dumpall.c:728 pg_restore.c:567 #, c-format msgid " --disable-triggers disable triggers during data-only restore\n" msgstr " --disable-triggers მხოლოდ მონაცემების აღდგენისას ტრიგერების გამორთვა\n" @@ -1856,7 +1860,7 @@ msgstr "" " მითითებული ცხრილების მონაცემები დამპში არ იქნება,\n" " შვილი და დაყოფილი ცხრილების ჩათვლით\n" -#: pg_dump.c:1344 pg_dumpall.c:899 +#: pg_dump.c:1344 pg_dumpall.c:730 #, c-format msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" msgstr " --extra-float-digits=NUM extra_float_digits-ის ნაგულისხმევი პარამეტრის გადაფარვა\n" @@ -1870,7 +1874,7 @@ msgstr "" " --filter=ფაილისსახელი დამპიდან ობიექტების და მონაცემების, რომლებიც ემთხვევა მითითებულ\n" " ფაილისსახელში მყოფ გამოსახულებას, ამოღება ან ჩასმა\n" -#: pg_dump.c:1347 pg_dumpall.c:901 pg_restore.c:786 +#: pg_dump.c:1347 pg_dumpall.c:732 pg_restore.c:571 #, c-format msgid " --if-exists use IF EXISTS when dropping objects\n" msgstr " --if-exists ობიექტების გადაყრისას IF EXISTS -ის გამოყენება\n" @@ -1886,92 +1890,92 @@ msgstr "" " მონაცემების ჩასმა უცხო სერვერებზე მდებარე , უცხო ცხრილებიდან, რომლებიც\n" " შაბლონს ემთხვევა\n" -#: pg_dump.c:1351 pg_dumpall.c:902 +#: pg_dump.c:1351 pg_dumpall.c:733 #, c-format msgid " --inserts dump data as INSERT commands, rather than COPY\n" msgstr " --inserts მონაცემების დამპი INSERT ბრძანებების მსგავსად, COPY-ის მაგიერ\n" -#: pg_dump.c:1352 pg_dumpall.c:903 +#: pg_dump.c:1352 pg_dumpall.c:734 #, c-format msgid " --load-via-partition-root load partitions via the root table\n" msgstr " --load-via-partition-root დანაყოფების root ცხრილს გავლით ჩატვირთვა\n" -#: pg_dump.c:1353 pg_dumpall.c:904 +#: pg_dump.c:1353 pg_dumpall.c:735 #, c-format msgid " --no-comments do not dump comment commands\n" msgstr " --no-comments კომენტარის ბრძანებების დამპი არ მოხდება\n" -#: pg_dump.c:1354 pg_dumpall.c:905 +#: pg_dump.c:1354 pg_dumpall.c:736 #, c-format msgid " --no-data do not dump data\n" msgstr " --no-data მონაცემების დამპი არ მოხდება\n" -#: pg_dump.c:1355 pg_dumpall.c:906 +#: pg_dump.c:1355 pg_dumpall.c:737 #, c-format msgid " --no-policies do not dump row security policies\n" msgstr " --no-policies მწკრივის უსაფრთხოების პოლიტიკის დამპი არ მოხდება\n" -#: pg_dump.c:1356 pg_dumpall.c:907 +#: pg_dump.c:1356 pg_dumpall.c:738 #, c-format msgid " --no-publications do not dump publications\n" msgstr " --no-publications გამოცემების გარეშე\n" -#: pg_dump.c:1357 pg_dumpall.c:909 +#: pg_dump.c:1357 pg_dumpall.c:740 #, c-format msgid " --no-schema do not dump schema\n" msgstr " --no-schema სქემების დამპი არ მოხდება\n" -#: pg_dump.c:1358 pg_dumpall.c:910 +#: pg_dump.c:1358 pg_dumpall.c:741 #, c-format msgid " --no-security-labels do not dump security label assignments\n" msgstr " --no-security-labels უსაფრთხოების ჭდეების მინიჭებების გარეშე\n" -#: pg_dump.c:1359 pg_dumpall.c:911 +#: pg_dump.c:1359 pg_dumpall.c:742 #, c-format msgid " --no-statistics do not dump statistics\n" msgstr " --no-statistics სტატისტიკის დამპი არ მოხდება\n" -#: pg_dump.c:1360 pg_dumpall.c:912 +#: pg_dump.c:1360 pg_dumpall.c:743 #, c-format msgid " --no-subscriptions do not dump subscriptions\n" msgstr " --no-subscriptions გამოწერების გარეშე\n" -#: pg_dump.c:1361 pg_dumpall.c:914 +#: pg_dump.c:1361 pg_dumpall.c:745 #, c-format msgid " --no-table-access-method do not dump table access methods\n" msgstr " --no-table-access-method ცხრილის წვდომის მეთოდები\n" -#: pg_dump.c:1362 pg_dumpall.c:915 +#: pg_dump.c:1362 pg_dumpall.c:746 #, c-format msgid " --no-tablespaces do not dump tablespace assignments\n" msgstr " --no-tablespaces ცხრილის სივრცის მინიჭებები\n" -#: pg_dump.c:1363 pg_dumpall.c:916 +#: pg_dump.c:1363 pg_dumpall.c:747 #, c-format msgid " --no-toast-compression do not dump TOAST compression methods\n" msgstr " --no-toast-compression TOAST-ის შეკუმშვის მეთოდები დამპში არ ჩაიწერება\n" -#: pg_dump.c:1364 pg_dumpall.c:917 +#: pg_dump.c:1364 pg_dumpall.c:748 #, c-format msgid " --no-unlogged-table-data do not dump unlogged table data\n" msgstr " --no-unlogged-table-data ის ცხრილები, რომლებსაც ჟურნალი არ აქვთ, დამპში არ ჩაიწერება\n" -#: pg_dump.c:1365 pg_dumpall.c:918 +#: pg_dump.c:1365 pg_dumpall.c:749 #, c-format msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" msgstr " --on-conflict-do-nothing INSERT ბრძანებებისთვის ON CONFLICT DO NOTHING -ის დამატება\n" -#: pg_dump.c:1366 pg_dumpall.c:919 +#: pg_dump.c:1366 pg_dumpall.c:750 #, c-format msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" msgstr " --quote-all-identifiers ყველა იდენტიფიკატორის ციტირება. მაშინაც კი, თუ ისინი საკვანძო სიტყვები არაა\n" -#: pg_dump.c:1367 pg_dumpall.c:920 pg_restore.c:800 +#: pg_dump.c:1367 pg_dumpall.c:751 pg_restore.c:584 #, c-format msgid " --restrict-key=RESTRICT_KEY use provided string as psql \\restrict key\n" msgstr " --restrict-key=RESTRICT_KEY მოწოდებული სტრიქონის გამოყენება, როგორც psql-ის \\შეზღუდვის გასაღები\n" -#: pg_dump.c:1368 pg_dumpall.c:921 +#: pg_dump.c:1368 pg_dumpall.c:752 #, c-format msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" msgstr " --rows-per-insert=NROWS მწკრივების რიცხვი თითოეული INSERT-ისთვის ; ასევე მიუთითებს --inserts\n" @@ -1981,7 +1985,7 @@ msgstr " --rows-per-insert=NROWS მწკრივების რიც msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" msgstr " --section=სექცია მითითებული სექცია (pre-data, data, ან post-data)\n" -#: pg_dump.c:1370 pg_dumpall.c:922 +#: pg_dump.c:1370 pg_dumpall.c:753 #, c-format msgid " --sequence-data include sequence data in dump\n" msgstr " --sequence-data მიმდევრობის მონაცემების ჩასმა დამპში\n" @@ -1996,17 +2000,17 @@ msgstr " --serializable-deferrable მოცდა, სანამ და msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" msgstr " --snapshot=SNAPSHOT დამპისთვის მითითებული სწრაფი ასლის გამოყენება\n" -#: pg_dump.c:1373 pg_dumpall.c:923 +#: pg_dump.c:1373 pg_dumpall.c:754 #, c-format msgid " --statistics dump the statistics\n" msgstr " --statistics სტატისტიკის დამპი\n" -#: pg_dump.c:1374 pg_dumpall.c:924 +#: pg_dump.c:1374 pg_dumpall.c:755 #, c-format msgid " --statistics-only dump only the statistics, not schema or data\n" msgstr " --statistics-only მოხდება, მხოლოდ, სტატისტიკის დამპი, მაგრამ არ სქემის ან მონაცემების\n" -#: pg_dump.c:1375 pg_restore.c:804 +#: pg_dump.c:1375 pg_restore.c:588 #, c-format msgid "" " --strict-names require table and/or schema include patterns to\n" @@ -2024,7 +2028,7 @@ msgstr "" " --table-and-children=შაბლონი მხოლოდ მითითებული ცხრილების დამპი,\n" " შვილი და დაყოფილი ცხრილების ჩათვლით\n" -#: pg_dump.c:1379 pg_dumpall.c:925 pg_restore.c:807 +#: pg_dump.c:1379 pg_dumpall.c:756 pg_restore.c:591 #, c-format msgid "" " --use-set-session-authorization\n" @@ -2035,7 +2039,7 @@ msgstr "" " მფლობელობის დასაყენებლად ALTER OWNER ბრძანებების მაგიერ\n" " SET SESSION AUTHORIZATION -ის გამოყენება\n" -#: pg_dump.c:1383 pg_dumpall.c:929 pg_restore.c:811 +#: pg_dump.c:1383 pg_dumpall.c:760 pg_restore.c:595 #, c-format msgid "" "\n" @@ -2049,32 +2053,32 @@ msgstr "" msgid " -d, --dbname=DBNAME database to dump\n" msgstr " -d, --dbname=ბაზისსახელი მონაცემთა ბაზის სახელი\n" -#: pg_dump.c:1385 pg_dumpall.c:931 pg_restore.c:812 +#: pg_dump.c:1385 pg_dumpall.c:762 pg_restore.c:596 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=HOSTNAME მონაცემთა ბაზის სერვერის ჰოსტის ან სოკეტის საქაღალდე\n" -#: pg_dump.c:1386 pg_dumpall.c:933 pg_restore.c:813 +#: pg_dump.c:1386 pg_dumpall.c:764 pg_restore.c:597 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=PORT მონაცემთა ბაზის სერვერის პორტი\n" -#: pg_dump.c:1387 pg_dumpall.c:934 pg_restore.c:814 +#: pg_dump.c:1387 pg_dumpall.c:765 pg_restore.c:598 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr " -U, --username=მომხმარებელი ბაზის მომხმარებლის სახელი\n" -#: pg_dump.c:1388 pg_dumpall.c:935 pg_restore.c:815 +#: pg_dump.c:1388 pg_dumpall.c:766 pg_restore.c:599 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password არასოდეს მკითხო პაროლი\n" -#: pg_dump.c:1389 pg_dumpall.c:936 pg_restore.c:816 +#: pg_dump.c:1389 pg_dumpall.c:767 pg_restore.c:600 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr " -W, --password პაროლის ყოველთვის კითხვა (ავტომატურად უნდა ხდებოდეს)\n" -#: pg_dump.c:1390 pg_dumpall.c:937 +#: pg_dump.c:1390 pg_dumpall.c:768 #, c-format msgid " --role=ROLENAME do SET ROLE before dump\n" msgstr " --role=ROLENAME აღდგენამდე SET ROLE -ის გაშვება\n" @@ -2092,17 +2096,17 @@ msgstr "" "ცვლადი გამოიყენება.\n" "\n" -#: pg_dump.c:1394 pg_dumpall.c:941 pg_restore.c:823 +#: pg_dump.c:1394 pg_dumpall.c:772 pg_restore.c:607 #, c-format msgid "Report bugs to <%s>.\n" msgstr "შეცდომების შესახებ მიწერეთ: <%s>\n" -#: pg_dump.c:1395 pg_dumpall.c:942 pg_restore.c:824 +#: pg_dump.c:1395 pg_dumpall.c:773 pg_restore.c:608 #, c-format msgid "%s home page: <%s>\n" msgstr "%s-ის საწყისი გვერდია: <%s>\n" -#: pg_dump.c:1413 pg_dumpall.c:628 +#: pg_dump.c:1413 pg_dumpall.c:570 #, c-format msgid "invalid client encoding \"%s\" specified" msgstr "კლიენტის მითითებული კოდირება არასწორია: %s" @@ -2117,8 +2121,7 @@ msgstr "სერვერის ამ ვერსიაში უქმე msgid "invalid output format \"%s\" specified" msgstr "გამოტანის მითითებული ფორმატი არასწორია: %s" -#: pg_dump.c:1679 pg_dump.c:1735 pg_dump.c:1788 pg_dumpall.c:1966 -#: pg_restore.c:1001 +#: pg_dump.c:1679 pg_dump.c:1735 pg_dump.c:1788 pg_dumpall.c:1610 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "არასწორი სრული სახელი (ძალიან ბევრი წერტილიანი სახელი): %s" @@ -2289,13 +2292,13 @@ msgstr "სისწორის შემოწმების შეცდო msgid "failed sanity check, table OID %u appearing in pg_partitioned_table not found" msgstr "სისწორის შემოწმების შეცდომა. pg_parttioned_table-ში მოხსენიებული ცხრილი OID-ით %u ვერ ვიპოვე" -#: pg_dump.c:8184 pg_dump.c:8480 pg_dump.c:8943 pg_dump.c:9611 pg_dump.c:9755 +#: pg_dump.c:8182 pg_dump.c:8480 pg_dump.c:8943 pg_dump.c:9611 pg_dump.c:9755 #: pg_dump.c:9900 pg_dump.c:10000 #, c-format msgid "unrecognized table OID %u" msgstr "ცხრილის უცნობი OID: %u" -#: pg_dump.c:8188 +#: pg_dump.c:8186 #, c-format msgid "unexpected index data for table \"%s\"" msgstr "მოულოდნელი ინდექსის მონაცემები ცხრილისთვის \"%s\"" @@ -2600,8 +2603,8 @@ msgstr "მიბმადი ობიექტის გარეშე %u %u" msgid "no referenced object %u %u" msgstr "მიბმული ობიექტის გარეშე %u %u" -#: pg_dump.c:21024 pg_dump.c:21062 pg_dumpall.c:2365 pg_restore.c:858 -#: pg_restore.c:904 +#: pg_dump.c:21024 pg_dump.c:21062 pg_dumpall.c:1858 pg_restore.c:642 +#: pg_restore.c:688 #, c-format msgid "%s filter for \"%s\" is not allowed" msgstr "ფილტრი %s \"%s\"-სთვის დაშვებული არაა" @@ -2643,32 +2646,22 @@ msgstr "ამ პრობლემის ასარიდებლად უ msgid "could not resolve dependency loop among these items:" msgstr "ამ ელემენტებს შორის დამოკიდებულებების მარყუჟის ამოხსნა შეუძლებელია:" -#: pg_dumpall.c:260 +#: pg_dumpall.c:239 #, c-format msgid "program \"%s\" is needed by %s but was not found in the same directory as \"%s\"" msgstr "პროგრამა \"%s\" სჭირდება \"%s\"-ს, მაგრამ იგივე საქაღალდეში, სადაც \"%s\", ნაპოვნი არაა" -#: pg_dumpall.c:263 +#: pg_dumpall.c:242 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "პროგრამა „%s“ ნაპოვნია „%s“-ის მიერ, მაგრამ ვერსია, იგივეა არაა, რაც %s" -#: pg_dumpall.c:476 +#: pg_dumpall.c:401 #, c-format -msgid "option %s=d|c|t requires option %s" -msgstr "პარამეტრს %s=d|c|t სჭირდება პარამეტრი %s" +msgid "option %s cannot be used together with %s, %s, or %s" +msgstr "პარამეტრს %s ვერ გამოიყენებთ პარამეტრებთან %s, %s, ან %s ერთად" -#: pg_dumpall.c:484 -#, c-format -msgid "option %s can only be used with %s=plain" -msgstr "პარამეტრს %s გამოიყენებთ, მხოლოდ, პარამეტრთან %s=plan ერთად" - -#: pg_dumpall.c:489 -#, c-format -msgid "options %s and %s cannot be used together in non-text dump" -msgstr "პარამეტრებს %s და -%s ერთად ვერ გამოიყენებთ არა-ტექსტურ დამპში" - -#: pg_dumpall.c:609 pg_restore.c:1205 +#: pg_dumpall.c:538 #, c-format msgid "" "could not connect to databases \"postgres\" or \"template1\"\n" @@ -2677,81 +2670,81 @@ msgstr "" "ვერ დაუკავშირდა მონაცემთა ბაზებს \"postgres\" ან \"template1\"\n" "გთხოვთ მიუთითოთ ალტერნატიული მონაცემთა ბაზა." -#: pg_dumpall.c:871 +#: pg_dumpall.c:704 #, c-format msgid "" -"%s exports a PostgreSQL database cluster as an SQL script or to other formats.\n" +"%s exports a PostgreSQL database cluster as an SQL script.\n" "\n" msgstr "" -"%s გაიტანს PostgreSQL მონაცემთა ბაზის კლასტერს SQL სკრიპტის ან სხვა ფორმატის სახით.\n" +"%s გაიტანს PostgreSQL მონაცემთა ბაზის კლასტერს SQL სკრიპტის სახით.\n" "\n" -#: pg_dumpall.c:873 +#: pg_dumpall.c:706 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [პარამეტრი]...\n" -#: pg_dumpall.c:876 +#: pg_dumpall.c:709 #, c-format msgid " -f, --file=FILENAME output file name\n" msgstr " -f, --file=FILENAME გამოტანის ფაილის სახელი\n" -#: pg_dumpall.c:885 +#: pg_dumpall.c:716 #, c-format msgid " -c, --clean clean (drop) databases before recreating\n" msgstr " -c, --clean ბაზის წაშლა თავიდან შექმნამდე\n" -#: pg_dumpall.c:887 +#: pg_dumpall.c:718 #, c-format msgid " -g, --globals-only dump only global objects, no databases\n" msgstr " -g, --globals-only წაიშლება მხოლოდ გლობალური ობიექტები და არა ბაზები\n" -#: pg_dumpall.c:888 pg_restore.c:773 +#: pg_dumpall.c:719 pg_restore.c:559 #, c-format msgid " -O, --no-owner skip restoration of object ownership\n" msgstr " -O, --no-owner ობიექტების მფლობელობის აღდგენის გამოტოვება\n" -#: pg_dumpall.c:889 +#: pg_dumpall.c:720 #, c-format msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" msgstr " -r, --roles-only გამოიტანს მხოლოდ როლებს და არც ბაზებს და არც ცხრილების სივრცეებს\n" -#: pg_dumpall.c:891 +#: pg_dumpall.c:722 #, c-format msgid " -S, --superuser=NAME superuser user name to use in the dump\n" msgstr " -S, --superuser=NAME გამოსაყენებელი ზემომხმარებლის სახელი\n" -#: pg_dumpall.c:892 +#: pg_dumpall.c:723 #, c-format msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" msgstr " -t, --tablespaces-only გამოიტანს მხლოდ ცხრილების სივრცეებს და არც ბაზებს და არც როლებს\n" -#: pg_dumpall.c:898 +#: pg_dumpall.c:729 #, c-format msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" msgstr " --exclude-database=PATTERN გამორიცხავს ბაზებს, რომლებიც PATTERN-ს ემთხვევა\n" -#: pg_dumpall.c:900 +#: pg_dumpall.c:731 #, c-format msgid " --filter=FILENAME exclude databases based on expressions in FILENAME\n" msgstr " --filter=FILENAME ფაილში მითითებული მონაცემთა ბაზების ამოღება\n" -#: pg_dumpall.c:908 +#: pg_dumpall.c:739 #, c-format msgid " --no-role-passwords do not dump passwords for roles\n" msgstr " --no-role-passwords როლების პაროლები გამოტანილ არ იქნება\n" -#: pg_dumpall.c:930 +#: pg_dumpall.c:761 #, c-format msgid " -d, --dbname=CONNSTR connect using connection string\n" msgstr " -d, --dbname=CONNSTR კავშირის სტრიქონი\n" -#: pg_dumpall.c:932 +#: pg_dumpall.c:763 #, c-format msgid " -l, --database=DBNAME alternative default database\n" msgstr " -l, --database=ბაზისსახელი ალტერნატიული ბაზის სახელი)\n" -#: pg_dumpall.c:939 +#: pg_dumpall.c:770 #, c-format msgid "" "\n" @@ -2764,213 +2757,153 @@ msgstr "" "სტანდარტულ გამოტანაზე იქნება გამოტანილი.\n" "\n" -#: pg_dumpall.c:1107 +#: pg_dumpall.c:915 #, c-format msgid "role name starting with \"pg_\" skipped (%s)" msgstr "როლის სახელი, რომელიც \"pg_\"-ით იწყება, გამოტოვებულია (%s)" #. translator: %s represents a numeric role OID -#: pg_dumpall.c:1366 +#: pg_dumpall.c:1132 #, c-format msgid "ignoring role grant for missing role with OID %s" msgstr "გამოტოვებულია როლის მინიჭება ნაკლული როლისთვის OID-ით %s" -#: pg_dumpall.c:1404 +#: pg_dumpall.c:1170 #, c-format msgid "could not find a legal dump ordering for memberships in role \"%s\"" msgstr "სწორი დამპის მიმდევრობა წევრობისთვის როლში \"%s\" აღმოჩენილი არაა" #. translator: %s represents a numeric role OID -#: pg_dumpall.c:1430 +#: pg_dumpall.c:1196 #, c-format msgid "ignoring role grant to missing role with OID %s" msgstr "გამოტოვებულია როლის მინიჭება ნაკლული როლისთვის OID-ით %s" #. translator: %s represents a numeric role OID -#: pg_dumpall.c:1445 +#: pg_dumpall.c:1211 #, c-format msgid "grant of role \"%s\" to \"%s\" has invalid grantor OID %s" msgstr "როლის \"%s\" მინიჭებას \"%s\"-ისთვის აქვს არასწორი მიმნიჭებლის OID %s" -#: pg_dumpall.c:1447 +#: pg_dumpall.c:1213 #, c-format msgid "This grant will be dumped without GRANTED BY." msgstr "ამ მინიჭების დამპი GRANTED BY-ის გარეშე მოხდება." -#: pg_dumpall.c:1580 +#: pg_dumpall.c:1331 #, c-format msgid "could not parse ACL list (%s) for parameter \"%s\"" msgstr "ვერ გაანალიზდა ACL სია (%s) პარამეტრისთვის \"%s\"" -#: pg_dumpall.c:1743 +#: pg_dumpall.c:1458 #, c-format msgid "could not parse ACL list (%s) for tablespace \"%s\"" msgstr "შეცდომა ACL-ის სიის (%s) დამუშავებისთვის ცხრილის სივრცისთვის \"%s\"" -#: pg_dumpall.c:2067 pg_restore.c:1029 +#: pg_dumpall.c:1672 #, c-format msgid "excluding database \"%s\"" msgstr "გამოირიცხა ბაზა \"%s\"" -#: pg_dumpall.c:2071 +#: pg_dumpall.c:1676 #, c-format msgid "dumping database \"%s\"" msgstr "დამპის გამოტანა ბაზისთვის \"%s\"" -#: pg_dumpall.c:2123 +#: pg_dumpall.c:1709 #, c-format msgid "pg_dump failed on database \"%s\", exiting" msgstr "pg_dump -ის შეცდომა ბაზაზე \"%s\". დასასრული" -#: pg_dumpall.c:2129 +#: pg_dumpall.c:1715 #, c-format msgid "could not re-open the output file \"%s\": %m" msgstr "გამოსატანი ფაილის თავიდან გახსნის შეცდომა \"%s\": %m" -#: pg_dumpall.c:2196 +#: pg_dumpall.c:1759 #, c-format msgid "running \"%s\"" msgstr "%s -ის გაშვება" -#: pg_dumpall.c:2322 -#, c-format -msgid "" -"database, role, or tablespace names contain a newline or carriage return character, which is not supported in non-plain-text dumps:\n" -"%s" -msgstr "" -"მონაცემთა ბაზა, როლი, ან ცხრილების სივრცე შეიცავს ახალი ხაზის, ან კარეტის დაბრუნების სიმბოლოს, რომელიც მხარდაჭერილი არაა არა-უბრალო-ტექსტურ დამპებში:\n" -"%s" - -#: pg_dumpall.c:2385 +#: pg_dumpall.c:1878 msgid "unsupported filter object" msgstr "მხარდაუჭერელი ფილტრის ობიექტი" -#: pg_dumpall.c:2426 -#, c-format -msgid "unrecognized output format \"%s\"; please specify \"c\", \"d\", \"p\", or \"t\"" -msgstr "უცნობი გამოტანის ფორმატი \"%s\"; გთხოვთ მიუთითოთ \"c\", \"d\" \"p\", ან \"t\"" - -#: pg_restore.c:383 +#: pg_restore.c:348 #, c-format msgid "one of -d/--dbname and -f/--file must be specified" msgstr "-d/--dbname და-f/--file -დან მხოლოდ ერთ-ერთის მითითება შეგიძლიათ" -#: pg_restore.c:463 +#: pg_restore.c:433 #, c-format msgid "cannot specify both --single-transaction and multiple jobs" msgstr "--single-transaction -ის მითითება ბევრ დავალებასთან ერთად შეუძლებელია" -#: pg_restore.c:510 +#: pg_restore.c:480 #, c-format msgid "archive format \"%s\" is not supported; please use psql" msgstr "არქივის ფორმატი \"%s\" მხარდაჭერილი არაა. გამოიყენეთ psql" -#: pg_restore.c:514 +#: pg_restore.c:484 #, c-format msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" msgstr "არქივის უცნობი ფორმატი \"%s\"; გთხოვთ მიუთითოთ \"გ\", \"დ\", ან \"t\"" -#: pg_restore.c:537 pg_restore.c:540 pg_restore.c:544 pg_restore.c:561 -#: pg_restore.c:565 pg_restore.c:569 -#, c-format -msgid "option %s cannot be used when restoring an archive created by pg_dumpall" -msgstr "პარამეტრს %s ვერ გამოიყენებთ pg_dumpall-ის მიერ შექმნილი არქივის აღდგენისას" - -#: pg_restore.c:547 -#, c-format -msgid "options %s and %s cannot be used together when restoring an archive created by pg_dumpall" -msgstr "პარამეტრებს %s და %s ვერ გამოიყენებთ pg_dumpall-ის მიერ შექმნილი არქივის აღდგენისას" - -#: pg_restore.c:557 -#, c-format -msgid "--if-exists is implied by --clean for pg_dumpall archives" -msgstr "pg_dumpall არქივებისთვის --clean გულისხმობს პარამეტრს --if-exists" - -#: pg_restore.c:573 -#, c-format -msgid "option %s cannot exclude %s when restoring a pg_dumpall archive" -msgstr "პარამეტრი %s ვერ გამორიცხავს %s-ს pg_dumpall-ის მიერ შექმნილი არქივის აღდგენისას" - -#: pg_restore.c:583 -#, c-format -msgid "option %s must be specified when restoring an archive created by pg_dumpall" -msgstr "პარამეტრი %s, მხოლოდ, მაშინ უნდა მიუთითოთ, როცა ხდება pg_dumpall-ის მიერ შექმნილი არქივის აღდგენა" - -#: pg_restore.c:586 -#, c-format -msgid "Individual databases can be restored using their specific archives." -msgstr "ინდივიდუალური მონაცემთა ბაზის აღდგენა მათი სპეციფიკური არქივების გამოყენებითაა შესაძლებელი." - -#: pg_restore.c:599 -#, c-format -msgid "skipping restore of global objects because %s was specified" -msgstr "გლობალური ობიექტების აღდგენა გამოტოვებულია, რადგან მითითებული იყო %s" - -#: pg_restore.c:603 -#, c-format -msgid "database restoring skipped because option %s was specified" -msgstr "მონაცემთა ბაზის აღდგენა გამოტოვებულია, რადგან მითითებულია პარამეტრი %s" - -#: pg_restore.c:620 pg_restore.c:625 -#, c-format -msgid "option %s can be used only when restoring an archive created by pg_dumpall" -msgstr "პარამეტრის %s გამოყენება, მხოლოდ, pg_dumpall-ით შექმნილი არქივის აღდგენისას შეგიძლიათ" - -#: pg_restore.c:635 +#: pg_restore.c:522 #, c-format msgid "errors ignored on restore: %d" msgstr "აღდგენისას იგნორირებული შეცდომების რაოდენობა: %d" -#: pg_restore.c:748 +#: pg_restore.c:535 #, c-format msgid "" -"%s restores PostgreSQL databases from archives created by pg_dump or pg_dumpall.\n" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" "\n" msgstr "" -"%s აღადგენს PostgreSQL მონაცემთა ბაზას pg_dump-ის, ან pg_dumpall-ის მიერ შექმნილი არქივებიდან.\n" +"%s აღადგენს PostgreSQL მონაცემთა ბაზას pg_dump-ის მიერ შექმნილი არქივებიდან.\n" "\n" -#: pg_restore.c:750 +#: pg_restore.c:537 #, c-format msgid " %s [OPTION]... [FILE]\n" msgstr " %s [პარამეტრი]... [ფაილი]\n" -#: pg_restore.c:753 +#: pg_restore.c:540 #, c-format msgid " -d, --dbname=NAME connect to database name\n" msgstr " -d, --dbname=ბაზისსახელი მონაცემთა ბაზის სახელი\n" -#: pg_restore.c:754 +#: pg_restore.c:541 #, c-format msgid " -f, --file=FILENAME output file name (- for stdout)\n" msgstr " -f, --file=FILENAME გამოტანის ფაილის სახელი(stdout-ზე გამოსატანად გამოიყენეთ \"-\")\n" -#: pg_restore.c:755 +#: pg_restore.c:542 #, c-format msgid " -F, --format=c|d|t backup file format (should be automatic)\n" msgstr " -F, --format=c|d|t მარქაფის ფაილის ფორმატი (ავტომატური უნდა იყოს)\n" -#: pg_restore.c:756 +#: pg_restore.c:543 #, c-format msgid " -l, --list print summarized TOC of the archive\n" msgstr " -l, --list არქივის სარჩევის მიმოხილვის გამოტანა\n" -#: pg_restore.c:757 +#: pg_restore.c:544 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose დამატებითი ინფორმაციის გამოტანა\n" -#: pg_restore.c:758 +#: pg_restore.c:545 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version ვერსიის ინფორმაციის გამოტანა და გასვლა\n" -#: pg_restore.c:759 +#: pg_restore.c:546 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ამ დახმარების ჩვენება და გასვლა\n" -#: pg_restore.c:761 +#: pg_restore.c:548 #, c-format msgid "" "\n" @@ -2979,37 +2912,32 @@ msgstr "" "\n" "პარამეტრები, რომლებიც აკონტროლებენ გამოტანას:\n" -#: pg_restore.c:762 +#: pg_restore.c:549 #, c-format msgid " -a, --data-only restore only the data, no schema\n" msgstr " -a, --data-only აღდგება მხოლოდ მონაცემები, სქემის გარეშე\n" -#: pg_restore.c:764 +#: pg_restore.c:551 #, c-format msgid " -C, --create create the target database\n" msgstr " -C, --create სამიზნე ბაზის შექმნა\n" -#: pg_restore.c:765 +#: pg_restore.c:552 #, c-format msgid " -e, --exit-on-error exit on error, default is to continue\n" msgstr " -e, --exit-on-error დაუყოვნებლივი გამოსვლა შეცდომის შემთხვევაში\n" -#: pg_restore.c:766 -#, c-format -msgid " -g, --globals-only restore only global objects, no databases\n" -msgstr " -g, --globals-only აღდგება, მხოლოდ, გლობალური ობიექტები და არა ბაზები\n" - -#: pg_restore.c:767 +#: pg_restore.c:553 #, c-format msgid " -I, --index=NAME restore named index\n" msgstr " -I, --index=NAME მითითებული სახელის მქონე ინდექსის აღდგენა\n" -#: pg_restore.c:768 +#: pg_restore.c:554 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" msgstr " -j, --jobs=NUM აღდგენისას მითითებული რაოდენობის პარალელური დავალების გაშვება\n" -#: pg_restore.c:769 +#: pg_restore.c:555 #, c-format msgid "" " -L, --use-list=FILENAME use table of contents from this file for\n" @@ -3018,62 +2946,57 @@ msgstr "" " -L, --use-list=FILENAME გამოტანის ასარჩევად/დასალაგებლად მითითებული\n" " ფაილის შემცველობის გამოყენება\n" -#: pg_restore.c:771 +#: pg_restore.c:557 #, c-format msgid " -n, --schema=NAME restore only objects in this schema\n" msgstr " -n, --schema=NAME მხოლოდ მითითებული სქემის ობიექტების აღდგენა\n" -#: pg_restore.c:772 +#: pg_restore.c:558 #, c-format msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" msgstr " -N, --exclude-schema=სახელი მითითებული სახელის მქონე სქემაში ობიექტები არ აღდგება\n" -#: pg_restore.c:774 +#: pg_restore.c:560 #, c-format msgid " -P, --function=NAME(args) restore named function\n" msgstr " -P, --function=სახელი(არგები) მითითებული სახელის მქონე ფუნქციის აღდგენა\n" -#: pg_restore.c:775 +#: pg_restore.c:561 #, c-format msgid " -s, --schema-only restore only the schema, no data\n" msgstr " -s, --schema-only აღდგება მხოლოდ სქემები, მონაცემები კი არა\n" -#: pg_restore.c:776 +#: pg_restore.c:562 #, c-format msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" msgstr " -S, --superuser=NAME ტრიგერების გამოსართავად გამოყენებული ზემომხმარებლის სახელი\n" -#: pg_restore.c:777 +#: pg_restore.c:563 #, c-format msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" msgstr " -t, --table=NAME მითითებული ურთიერთობის აღდგენა (ცხრილი, ხედი, და ა.შ.)\n" -#: pg_restore.c:778 +#: pg_restore.c:564 #, c-format msgid " -T, --trigger=NAME restore named trigger\n" msgstr " -T, --trigger=NAME მითითებული ტრიგერის აღდგენა \n" -#: pg_restore.c:779 +#: pg_restore.c:565 #, c-format msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" msgstr " -x, --no-privileges წვდომის პრივილეგიების აღდგენის გამოტოვება (grant/revoke)\n" -#: pg_restore.c:780 +#: pg_restore.c:566 #, c-format msgid " -1, --single-transaction restore as a single transaction\n" msgstr " -1, --single-transaction აღდგენის ერთ ტრანზაქციად გაშვება\n" -#: pg_restore.c:782 +#: pg_restore.c:568 #, c-format msgid " --enable-row-security enable row security\n" msgstr " --enable-row-security მწკრივების უსაფრთხოების ჩართვა\n" -#: pg_restore.c:783 -#, c-format -msgid " --exclude-database=PATTERN do not restore the specified database(s)\n" -msgstr " --exclude-database=PATTERN მითითებული მონაცემთა ბაზ(ებ)-ის აღდგენა არ მოხდება\n" - -#: pg_restore.c:784 +#: pg_restore.c:569 #, c-format msgid "" " --filter=FILENAME restore or skip objects based on expressions\n" @@ -3082,17 +3005,17 @@ msgstr "" " --filter=FILENAME ობიექტების აღდგენა ან გამოტოვება ფაილში\n" " მითითებული გამოსახულებების მიხედვით\n" -#: pg_restore.c:787 +#: pg_restore.c:572 #, c-format msgid " --no-comments do not restore comment commands\n" msgstr " --no-comments კომენტარის ბრძანებები არ აღდგება\n" -#: pg_restore.c:788 +#: pg_restore.c:573 #, c-format msgid " --no-data do not restore data\n" msgstr " --no-data მონაცემები არ აღდგება\n" -#: pg_restore.c:789 +#: pg_restore.c:574 #, c-format msgid "" " --no-data-for-failed-tables do not restore data of tables that could not be\n" @@ -3101,88 +3024,83 @@ msgstr "" " --no-data-for-failed-tables ცხრილების, რომლის შექმნა შეუძლებელია,\n" " მონაცემები არ აღდგება\n" -#: pg_restore.c:791 -#, c-format -msgid " --no-globals do not restore global objects (roles and tablespaces)\n" -msgstr " --no-globals გლობალური ობიექტები არ აღდგება (როლები და ცხრილის სივრცეები)\n" - -#: pg_restore.c:792 +#: pg_restore.c:576 #, c-format msgid " --no-policies do not restore row security policies\n" msgstr " --no-policies მწკრივის უსაფრთხოების პოლიტიკები არ აღდგება\n" -#: pg_restore.c:793 +#: pg_restore.c:577 #, c-format msgid " --no-publications do not restore publications\n" msgstr " --no-publications გამოცემები არ აღდგება\n" -#: pg_restore.c:794 +#: pg_restore.c:578 #, c-format msgid " --no-schema do not restore schema\n" msgstr " --no-schema სქემები არ აღდგება\n" -#: pg_restore.c:795 +#: pg_restore.c:579 #, c-format msgid " --no-security-labels do not restore security labels\n" msgstr " --no-security-labels უსაფრთხოების ჭდეები არ აღდგება\n" -#: pg_restore.c:796 +#: pg_restore.c:580 #, c-format msgid " --no-statistics do not restore statistics\n" msgstr " --no-statistics სტატისტიკის აღდგენა არ მოხდება\n" -#: pg_restore.c:797 +#: pg_restore.c:581 #, c-format msgid " --no-subscriptions do not restore subscriptions\n" msgstr " --no-subscriptions გამოწერები არ აღდგება\n" -#: pg_restore.c:798 +#: pg_restore.c:582 #, c-format msgid " --no-table-access-method do not restore table access methods\n" msgstr " --no-table-access-method ცხრილის წვდომის მეთოდები არ აღდგება\n" -#: pg_restore.c:799 +#: pg_restore.c:583 #, c-format msgid " --no-tablespaces do not restore tablespace assignments\n" msgstr " --no-tablespaces ცხრილის სივრცის მინიჭებები არ აღდგება\n" -#: pg_restore.c:801 +#: pg_restore.c:585 #, c-format msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" msgstr " --section=სექცია მითითებული სექციის აღდგენა (pre-data, data, ან post-data)\n" -#: pg_restore.c:802 +#: pg_restore.c:586 #, c-format msgid " --statistics restore the statistics\n" msgstr " --statistics სტატისტიკის აღდგენა\n" -#: pg_restore.c:803 +#: pg_restore.c:587 #, c-format msgid " --statistics-only restore only the statistics, not schema or data\n" msgstr " --statistics-only აღდგება, მხოლოდ, სტატისტიკა, სქემა, ან მონაცემები კი - არა\n" -#: pg_restore.c:806 +#: pg_restore.c:590 #, c-format msgid " --transaction-size=N commit after every N objects\n" msgstr " --transaction-size=N გადაცემა ყოველი N ობიექტის შემდეგ\n" -#: pg_restore.c:817 +#: pg_restore.c:601 #, c-format msgid " --role=ROLENAME do SET ROLE before restore\n" msgstr " --role=ROLENAME აღდგენამდე SET ROLE -ის გაშვება\n" -#: pg_restore.c:819 +#: pg_restore.c:603 #, c-format msgid "" "\n" -"The options -I, -n, -N, -P, -t, -T, --section, and --exclude-database can be\n" -"combined and specified multiple times to select multiple objects.\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" msgstr "" "\n" -"შესაძლებელია პარამეტრების -I, -n, -N, -P, -t, -T, --section და --exclude-database ერთად და მრავალჯერ მითითება ერთზე\n" +"შესაძლებელია პარამეტრების -I, -n, -N, -P, -t, -T და --section ერთად და მრავალჯერ მითითება ერთზე\n" "მეტი ობიექტის ამოსაღებად.\n" -#: pg_restore.c:822 +#: pg_restore.c:606 #, c-format msgid "" "\n" @@ -3193,328 +3111,126 @@ msgstr "" "თუ ფაილის სახელი მითითებული არაა, გამოყენებული იქნება სტანდარტული შეტანა.\n" "\n" -#: pg_restore.c:1012 -#, c-format -msgid "database name \"%s\" matches --exclude-database pattern \"%s\"" -msgstr "მონაცემთა ბაზის სახელი \"%s\" ემთხვევა --exclude-database-ის ნიმუშს \"%s\"" - -#: pg_restore.c:1065 -#, c-format -msgid "database restoring is skipped because file \"%s\" does not exist in directory \"%s\"" -msgstr "მონაცემთა ბაზის აღდგენა გამოტოვებულია, რადგან ფაილი \"%s\" არ არსებობს საქაღალდეში \"%s\"" - -#: pg_restore.c:1112 -#, c-format -msgid "invalid entry in file \"%s\" on line %d" -msgstr "არასწორი ჩანაწერი ფაილში \"%s\" ხაზზე %d" - -#: pg_restore.c:1119 #, c-format -msgid "found database \"%s\" (OID: %u) in file \"%s\"" -msgstr "აღმოჩენილია მონაცემთა ბაზა \"%s\" (OID: %u) ფაილში \"%s\"" +#~ msgid " --exclude-database=PATTERN do not restore the specified database(s)\n" +#~ msgstr " --exclude-database=PATTERN მითითებული მონაცემთა ბაზ(ებ)-ის აღდგენა არ მოხდება\n" -#: pg_restore.c:1167 #, c-format -msgid "found %d database name in \"%s\"" -msgid_plural "found %d database names in \"%s\"" -msgstr[0] "ნაპოვნია მონაცემთა ბაზის %d სახელი \"%s\"-ში" -msgstr[1] "ნაპოვნია მონაცემთა ბაზის %d სახელი \"%s\"-ში" +#~ msgid " --no-globals do not restore global objects (roles and tablespaces)\n" +#~ msgstr " --no-globals გლობალური ობიექტები არ აღდგება (როლები და ცხრილის სივრცეები)\n" -#: pg_restore.c:1189 pg_restore.c:1198 #, c-format -msgid "trying to connect to database \"%s\"" -msgstr "ვცდილობ, მივუერთდე მონაცემთა ბაზას \"%s\"" +#~ msgid " -g, --globals-only restore only global objects, no databases\n" +#~ msgstr " -g, --globals-only აღდგება, მხოლოდ, გლობალური ობიექტები და არა ბაზები\n" -#: pg_restore.c:1224 #, c-format -msgid "no database needs restoring out of %d database" -msgid_plural "no database needs restoring out of %d databases" -msgstr[0] "%d მონაცემთა ბაზიდან აღსადგენი არცერთია" -msgstr[1] "%d მონაცემთა ბაზიდან აღსადგენი არცერთია" +#~ msgid "--if-exists is implied by --clean for pg_dumpall archives" +#~ msgstr "pg_dumpall არქივებისთვის --clean გულისხმობს პარამეტრს --if-exists" -#: pg_restore.c:1232 #, c-format -msgid "need to restore %d databases out of %d databases" -msgstr "საჭიროა %d მონაცემთა ბაზების აღდგენა %d მონაცემთა ბაზებიდან" +#~ msgid "Individual databases can be restored using their specific archives." +#~ msgstr "ინდივიდუალური მონაცემთა ბაზის აღდგენა მათი სპეციფიკური არქივების გამოყენებითაა შესაძლებელი." -#: pg_restore.c:1278 #, c-format -msgid "restoring database \"%s\"" -msgstr "მიმდინარეობს აღდგენა მონაცემთა ბაზისთვის \"%s\"" +#~ msgid "database name \"%s\" matches --exclude-database pattern \"%s\"" +#~ msgstr "მონაცემთა ბაზის სახელი \"%s\" ემთხვევა --exclude-database-ის ნიმუშს \"%s\"" -#: pg_restore.c:1300 #, c-format -msgid "skipping restore of database \"%s\": database does not exist and %s was not specified" -msgstr "მონაცემთა ბაზის \"%s\" აღდგენა გამოტოვებული იქნება: მონაცემთა ბაზა არ არსებობს და %s მითითებული არაა" +#~ msgid "database restoring is skipped because file \"%s\" does not exist in directory \"%s\"" +#~ msgstr "მონაცემთა ბაზის აღდგენა გამოტოვებულია, რადგან ფაილი \"%s\" არ არსებობს საქაღალდეში \"%s\"" -#: pg_restore.c:1318 #, c-format -msgid "errors ignored on database \"%s\" restore: %d" -msgstr "მონაცემთა ბაზის \"%s\" აღდგენისას გამოტოვებული შეცდომები: %d" - -#: pg_restore.c:1322 -#, c-format -msgid "number of restored databases is %d" -msgstr "აღდგენილი მონაცემთა ბაზების რაოდენობა: %d" - -#, c-format -#~ msgid " %s" -#~ msgstr " %s" - -#, c-format -#~ msgid " --with-data dump the data\n" -#~ msgstr " --with-data მონაცემების დამპი\n" - -#, c-format -#~ msgid " --with-data restore the data\n" -#~ msgstr " --with-data მონაცემების აღდგენა\n" - -#, c-format -#~ msgid " --with-schema dump the schema\n" -#~ msgstr " --with-schema სქემების დამპი\n" - -#, c-format -#~ msgid " --with-schema restore the schema\n" -#~ msgstr " --with-schema სქემის აღდგენა\n" - -#, c-format -#~ msgid " -Z, --compress=0-9 compression level for compressed formats\n" -#~ msgstr " -Z, --compress=0-9 შეკუმშვის დონე\n" - -#, c-format -#~ msgid "" -#~ " -Z, --compress=METHOD[:LEVEL]\n" -#~ " compress as specified\n" -#~ msgstr "" -#~ " -Z, --compress=მეთოდი[:დონე]\n" -#~ " შეკუმშვის მითითება\n" +#~ msgid "database restoring skipped because option %s was specified" +#~ msgstr "მონაცემთა ბაზის აღდგენა გამოტოვებულია, რადგან მითითებულია პარამეტრი %s" #, c-format #~ msgid "" -#~ "%s exports a PostgreSQL database cluster as an SQL script.\n" -#~ "\n" +#~ "database, role, or tablespace names contain a newline or carriage return character, which is not supported in non-plain-text dumps:\n" +#~ "%s" #~ msgstr "" -#~ "%s გაიტანს PostgreSQL-ის მონაცემთა ბაზის კლასტერს SQL სკრიპტის სახით.\n" -#~ "\n" - -#, c-format -#~ msgid "cannot restore from compressed archive (compression not supported in this installation)" -#~ msgstr "შეკუმშული არქივიდან აღდგენა შეუძლებელია (ამ აგებაში შეკუმშვა მხარდაჭერილი არაა)" - -#, c-format -#~ msgid "considering PATTERN as NAME for --exclude-database option as no database connection while doing pg_restore" -#~ msgstr "PATTERN ჩაითვლება NAME-ის სახით პარამეტრისთვის --exclude-database, რადგან მონაცემთა ბაზასთან კავშირი არ არსებობს პროგრამის pg_restore გამოყენებისას" - -#, c-format -#~ msgid "could not change directory to \"%s\": %m" -#~ msgstr "საქაღალდის %s-ზე შეცვლის შეცდომა: %m" - -#, c-format -#~ msgid "could not close blob data file: %m" -#~ msgstr "ბლობის ფაილის დახურვის შეცდომა: %m" - -#, c-format -#~ msgid "could not close blobs TOC file: %m" -#~ msgstr "ბლობების შინაარსის ფაილის დახურვის შეცდომა: %m" - -#, c-format -#~ msgid "could not close directory \"%s\": %m" -#~ msgstr "საქაღალდის %s-ზე დახურვის შეცდომა: %m" - -#, c-format -#~ msgid "could not connect to database" -#~ msgstr "ბაზასთან მიერთების შეცდომა" - -#, c-format -#~ msgid "could not execute query: %s" -#~ msgstr "ვერ შევასრულე მოთხოვნა: %s" - -#, c-format -#~ msgid "could not identify current directory: %m" -#~ msgstr "მიმდინარე საქაღალდის იდენტიფიკაციის პრობლემა: %m" - -#, c-format -#~ msgid "could not open file: \"%s\"" -#~ msgstr "შეუძლებელია ფაილის გახსნა: \"%s\"" - -#, c-format -#~ msgid "could not read symbolic link \"%s\": %m" -#~ msgstr "სიმბოლური ბმის \"%s\" წაკითხვის შეცდომა: %m" - -#, c-format -#~ msgid "could not write to LOs TOC file: %s" -#~ msgstr "'LO'-ების სარჩევის ფაილში ჩაწერა შეუძლებელია: %s" - -#, c-format -#~ msgid "executing query: %s" -#~ msgstr "მიმდინარეობს შესრულება მოთხოვნის: %s" - -#, c-format -#~ msgid "failed to LZ4 compress data: %s" -#~ msgstr "'LZ4'-ით მონაცემების შეკუმშვა შეუძლებელია: %s" - -#, c-format -#~ msgid "failed to end compression: %s" -#~ msgstr "შეკუმშვის დასრულების შეცდომა: %s" - -#, c-format -#~ msgid "failed to end decompression: %s" -#~ msgstr "გაშლის დასრულების შეცდომა: %s" - -#, c-format -#~ msgid "found orphaned pg_auth_members entry for role %s" -#~ msgstr "აღმოჩენილია მიტოვებული pg_auth-ის წევრის ჩანაწერი როლისთვის %s" - -#, c-format -#~ msgid "ignored %d error in file \"%s\"" -#~ msgid_plural "ignored %d errors in file \"%s\"" -#~ msgstr[0] "გამოტოვებულია %d შეცდომა ფაილში \"%s\"" -#~ msgstr[1] "გამოტოვებულია %d შეცდომა ფაილში \"%s\"" - -#, c-format -#~ msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" -#~ msgstr "არასწორი არგუმენტის სტრიქონი (%s) ტრიგერისთვის \"%s\" ცხრილზე \"%s\"" - -#, c-format -#~ msgid "invalid compression code: %d" -#~ msgstr "შეკუმშვის არასწორი კოდი: %d" - -#, c-format -#~ msgid "not built with zlib support" -#~ msgstr "არ არის აგებული zlib მხარდაჭერით" - -#, c-format -#~ msgid "option %s cannot be used together with %s" -#~ msgstr "პარამეტრს %s ვერ გამოიყენებთ პარამეტრთან %s ერთად" - -#, c-format -#~ msgid "option --exclude-database can be used only when restoring an archive created by pg_dumpall" -#~ msgstr "პარამეტრის --exclude-database გამოყენება, მხოლოდ, pg_dumpall-ით შექმნილი არქივის აღდგენისას შეგიძლიათ" - -#, c-format -#~ msgid "option --exclude-database cannot be used together with -g/--globals-only" -#~ msgstr "პარამეტრი --exclude-database არ შეიძლება, გამოიყენოთ პარამეტრთან -g/--globals-only ერთად" - -#, c-format -#~ msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only" -#~ msgstr "პარამეტრი --exclude-database არ შეიძლება -g/--globals-only, -r/--roles-only, და -t/--tablespaces-only -სთან ერთად იყოს გამოყენებული" - -#, c-format -#~ msgid "option --if-exists requires option -c/--clean" -#~ msgstr "--if-exists -ს -c/--clean პარამეტრი ესაჭიროება" - -#, c-format -#~ msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts" -#~ msgstr "--on-conflict-do-nothing -ს --inserts, --rows-per-insert ან --column-inserts ესაჭიროება" - -#, c-format -#~ msgid "option --restrict-key can only be used with --format=plain" -#~ msgstr "პარამეტრს --restrict-key მხოლოდ, პარამეტრთან --format=plain ერთად იქნეს გამოყენებული" - -#, c-format -#~ msgid "option -F/--format=d|c|t requires option -f/--file" -#~ msgstr "პარამეტრს -F/--format=d|c|t სჭირდება პარამეტრი -f/--file" - -#, c-format -#~ msgid "option -L/--use-list cannot be used when restoring an archive created by pg_dumpall" -#~ msgstr "პარამეტრს -L/--use-list ვერ გამოიყენებთ pg_dumpall-ის მიერ შექმნილი არქივის აღდგენისას" - -#, c-format -#~ msgid "options --statistics and --no-statistics cannot be used together" -#~ msgstr "პარამეტრებს --statistics და --no-statistics ერთად ვერ გამოიყენებთ" - -#, c-format -#~ msgid "options --statistics-only and --no-statistics cannot be used together" -#~ msgstr "პარამეტრებს --statistics-only და --no-statistics ერთად ვერ გამოიყენებთ" - -#, c-format -#~ msgid "options --with-data and --no-data cannot be used together" -#~ msgstr "პარამეტრებს --with-data და --no-data ერთად ვერ გამოიყენებთ" - -#, c-format -#~ msgid "options --with-schema and --no-schema cannot be used together" -#~ msgstr "პარამეტრებს --with-schema და --no-schema ერთად ვერ გამოიყენებთ" - -#, c-format -#~ msgid "options --with-statistics and --no-statistics cannot be used together" -#~ msgstr "პარამეტრებს --with-statistics და --no-statistics ერთად ვერ გამოიყენებთ" +#~ "მონაცემთა ბაზა, როლი, ან ცხრილების სივრცე შეიცავს ახალი ხაზის, ან კარეტის დაბრუნების სიმბოლოს, რომელიც მხარდაჭერილი არაა არა-უბრალო-ტექსტურ დამპებში:\n" +#~ "%s" #, c-format -#~ msgid "options -1/--single-transaction and --transaction-size cannot be used together" -#~ msgstr "პარამეტრებს -1/--single-transaction და --transaction-size ერთად ვერ გამოიყენებთ" +#~ msgid "errors ignored on database \"%s\" restore: %d" +#~ msgstr "მონაცემთა ბაზის \"%s\" აღდგენისას გამოტოვებული შეცდომები: %d" #, c-format -#~ msgid "options -C/--create and -1/--single-transaction cannot be used together" -#~ msgstr "-C/--create და -1/--single-transaction ერთად არ გამოიყენება" +#~ msgid "found %d database name in \"%s\"" +#~ msgid_plural "found %d database names in \"%s\"" +#~ msgstr[0] "ნაპოვნია მონაცემთა ბაზის %d სახელი \"%s\"-ში" +#~ msgstr[1] "ნაპოვნია მონაცემთა ბაზის %d სახელი \"%s\"-ში" #, c-format -#~ msgid "options -a/--data-only and --no-data cannot be used together" -#~ msgstr "პარამეტრებს -a/--data-only და --no-data ერთად ვერ გამოიყენებთ" +#~ msgid "found database \"%s\" (OID: %u) in file \"%s\"" +#~ msgstr "აღმოჩენილია მონაცემთა ბაზა \"%s\" (OID: %u) ფაილში \"%s\"" #, c-format -#~ msgid "options -a/--data-only and --statistics-only cannot be used together" -#~ msgstr "პარამეტრებს -a/--data-only და --statistics-only ერთად ვერ გამოიყენებთ" +#~ msgid "invalid entry in file \"%s\" on line %d" +#~ msgstr "არასწორი ჩანაწერი ფაილში \"%s\" ხაზზე %d" #, c-format -#~ msgid "options -c/--clean and -a/--data-only cannot be used together" -#~ msgstr "პარამეტრები -c/--clean და -a/--data-only ერთად ვერ გამოიყენება" +#~ msgid "need to restore %d databases out of %d databases" +#~ msgstr "საჭიროა %d მონაცემთა ბაზების აღდგენა %d მონაცემთა ბაზებიდან" #, c-format -#~ msgid "options -d/--dbname and --restrict-key cannot be used together" -#~ msgstr "პარამეტრები -d/--dbname და --restrict-key ერთად არ შეიძლება, გამოყენებულ იქნას" +#~ msgid "no database needs restoring out of %d database" +#~ msgid_plural "no database needs restoring out of %d databases" +#~ msgstr[0] "%d მონაცემთა ბაზიდან აღსადგენი არცერთია" +#~ msgstr[1] "%d მონაცემთა ბაზიდან აღსადგენი არცერთია" #, c-format -#~ msgid "options -d/--dbname and -f/--file cannot be used together" -#~ msgstr "-d/--dbname და-f/--file ერთად არ გამოიყენება" +#~ msgid "number of restored databases is %d" +#~ msgstr "აღდგენილი მონაცემთა ბაზების რაოდენობა: %d" #, c-format -#~ msgid "options -g/--globals-only and -r/--roles-only cannot be used together" -#~ msgstr "პარამეტრები -g/--globals-only და -r/--roles-only ერთად ვერ გამოიყენება" +#~ msgid "option %s can be used only when restoring an archive created by pg_dumpall" +#~ msgstr "პარამეტრის %s გამოყენება, მხოლოდ, pg_dumpall-ით შექმნილი არქივის აღდგენისას შეგიძლიათ" #, c-format -#~ msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" -#~ msgstr "პარამეტრები -g/--globals-only და -t/--tablespaces-only ერთად ვერ გამოიყენება" +#~ msgid "option %s can only be used with %s=plain" +#~ msgstr "პარამეტრს %s გამოიყენებთ, მხოლოდ, პარამეტრთან %s=plan ერთად" #, c-format -#~ msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" -#~ msgstr "პარამეტრები -r/--roles-only და -t/--tablespaces-only ერთად ვერ გამოიყენება" +#~ msgid "option %s cannot be used when restoring an archive created by pg_dumpall" +#~ msgstr "პარამეტრს %s ვერ გამოიყენებთ pg_dumpall-ის მიერ შექმნილი არქივის აღდგენისას" #, c-format -#~ msgid "options -s/--schema-only and --include-foreign-data cannot be used together" -#~ msgstr "პარამეტრები -s/--schema-only და --include-foreign-data ერთად ვერ გამოიყენება" +#~ msgid "option %s cannot exclude %s when restoring a pg_dumpall archive" +#~ msgstr "პარამეტრი %s ვერ გამორიცხავს %s-ს pg_dumpall-ის მიერ შექმნილი არქივის აღდგენისას" #, c-format -#~ msgid "options -s/--schema-only and --no-schema cannot be used together" -#~ msgstr "პარამეტრებს -s/--schema-only და --no-schema ერთად ვერ გამოიყენებთ" +#~ msgid "option %s must be specified when restoring an archive created by pg_dumpall" +#~ msgstr "პარამეტრი %s, მხოლოდ, მაშინ უნდა მიუთითოთ, როცა ხდება pg_dumpall-ის მიერ შექმნილი არქივის აღდგენა" #, c-format -#~ msgid "options -s/--schema-only and --statistics-only cannot be used together" -#~ msgstr "პარამეტრებს -s/--schema-only და --statistics-only ერთად ვერ გამოიყენებთ" +#~ msgid "option %s=d|c|t requires option %s" +#~ msgstr "პარამეტრს %s=d|c|t სჭირდება პარამეტრი %s" #, c-format -#~ msgid "options -s/--schema-only and -a/--data-only cannot be used together" -#~ msgstr "პარამეტრები -s/--schema-only და -a/--data-only ერთად ვერ გამოიყენება" +#~ msgid "options %s and %s cannot be used together in non-text dump" +#~ msgstr "პარამეტრებს %s და -%s ერთად ვერ გამოიყენებთ არა-ტექსტურ დამპში" #, c-format -#~ msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" -#~ msgstr "მოთხოვნის შედეგია ნულოვანი ბმის ცხრილის სახელის უცხო გასაღების ტრიგერი \"%s\" ცხრილზე \"%s\" (ცხრილის OID: %u)" +#~ msgid "options %s and %s cannot be used together when restoring an archive created by pg_dumpall" +#~ msgstr "პარამეტრებს %s და %s ვერ გამოიყენებთ pg_dumpall-ის მიერ შექმნილი არქივის აღდგენისას" #, c-format -#~ msgid "reconnection failed: %s" -#~ msgstr "თავიდან მიერთების შეცდომა: %s" +#~ msgid "restoring database \"%s\"" +#~ msgstr "მიმდინარეობს აღდგენა მონაცემთა ბაზისთვის \"%s\"" #, c-format -#~ msgid "requested compression not available in this installation -- archive will be uncompressed" -#~ msgstr "მოთხოვნილი შეკუმშვა ამ აგებაში მხარდაუჭერელია. -- არქივი შეუკუმშავი იქნება" +#~ msgid "skipping restore of database \"%s\": database does not exist and %s was not specified" +#~ msgstr "მონაცემთა ბაზის \"%s\" აღდგენა გამოტოვებული იქნება: მონაცემთა ბაზა არ არსებობს და %s მითითებული არაა" #, c-format -#~ msgid "unexpected tgtype value: %d" -#~ msgstr "tgtype -ის არასწორი მნიშვნელობა: %d" +#~ msgid "skipping restore of global objects because %s was specified" +#~ msgstr "გლობალური ობიექტების აღდგენა გამოტოვებულია, რადგან მითითებული იყო %s" #, c-format -#~ msgid "unhandled mode \"%s\"" -#~ msgstr "დაუმუშავებელი რეჟიმი \"%s\"" +#~ msgid "trying to connect to database \"%s\"" +#~ msgstr "ვცდილობ, მივუერთდე მონაცემთა ბაზას \"%s\"" #, c-format -#~ msgid "unrecognized collation provider '%c'" -#~ msgstr "უცნობი კოლაციის მომწოდებელი '%c'" +#~ msgid "unrecognized output format \"%s\"; please specify \"c\", \"d\", \"p\", or \"t\"" +#~ msgstr "უცნობი გამოტანის ფორმატი \"%s\"; გთხოვთ მიუთითოთ \"c\", \"d\" \"p\", ან \"t\"" diff --git a/src/bin/pg_resetwal/po/ka.po b/src/bin/pg_resetwal/po/ka.po index 3ec324c7856..ef275df85cc 100644 --- a/src/bin/pg_resetwal/po/ka.po +++ b/src/bin/pg_resetwal/po/ka.po @@ -793,66 +793,3 @@ msgstr "" msgid "%s home page: <%s>\n" msgstr "%s-ის საწყისი გვერდია: <%s>\n" -#, c-format -#~ msgid " -?, --help show this help, then exit\n" -#~ msgstr " -?, --help ამ დახმარების ჩვენება და გასვლა\n" - -#, c-format -#~ msgid " -V, --version output version information, then exit\n" -#~ msgstr " -V, --version ვერსიის ინფორმაციის გამოტანა და გასვლა\n" - -#, c-format -#~ msgid " -f, --force force update to be done\n" -#~ msgstr " -f, --force ნაძალადევი განახლება\n" - -#, c-format -#~ msgid " [-D, --pgdata=]DATADIR data directory\n" -#~ msgstr " [-D, --pgdata=]DATADIR მონაცემების საქაღალდე\n" - -#, c-format -#~ msgid "Options:\n" -#~ msgstr "პარამეტრები:\n" - -#, c-format -#~ msgid "" -#~ "The database server was not shut down cleanly.\n" -#~ "Resetting the write-ahead log might cause data to be lost.\n" -#~ "If you want to proceed anyway, use -f to force reset.\n" -#~ msgstr "" -#~ "მონაცემთა ბაზის სერვერი სუფთად არ გამორთულა.\n" -#~ "წინასწარ-ჩაწერადი ჟურნალის საწყის მნიშვნელობაზე დაბრუნებამ შეიძლება მონაცემების დაკარგვა გამოიწვიოს.\n" -#~ "თუ გაგრძელება მაინც გნებავთ, გამოიყენეთ -f.\n" - -#, c-format -#~ msgid "" -#~ "Usage:\n" -#~ " %s [OPTION]... DATADIR\n" -#~ "\n" -#~ msgstr "" -#~ "გამოყენება: \n" -#~ " %s [პარამეტრი]... [მონაცემებისსაქაღალდე]\n" -#~ "\n" - -#, c-format -#~ msgid "argument of --wal-segsize must be a number" -#~ msgstr "--wal-segisze -ის არგუმენტი რიცხვი უნდა იყოს" - -#, c-format -#~ msgid "cannot create restricted tokens on this platform: error code %lu" -#~ msgstr "ამ პლატფორმაზე შეზღუდული კოდების შექმნა შეუძლებელია: შეცდომის კოდი %lu" - -#, c-format -#~ msgid "could not load library \"%s\": error code %lu" -#~ msgstr "ბიბლიოთეკის (\"%s\") ჩატვირთვის შეცდომა: შეცდომის კოდი: %lu" - -#, c-format -#~ msgid "multitransaction offset (-O) must be between 0 and %u" -#~ msgstr "მულტიტრანზაქციის წანაცვლება (-O) უნდა იყოს შუალედიდან 0 და %u" - -#, c-format -#~ msgid "transaction ID epoch (-e) must not be -1" -#~ msgstr "ტრანზაქციის ID-ის ეპოქა (-e) -1 არ უნდა იყოს" - -#, c-format -#~ msgid "unexpected empty file \"%s\"" -#~ msgstr "მოულოდნელად ფაილი ცარიელია: \"%s\"" diff --git a/src/bin/pg_rewind/po/de.po b/src/bin/pg_rewind/po/de.po index d16bca89438..870495e71f1 100644 --- a/src/bin/pg_rewind/po/de.po +++ b/src/bin/pg_rewind/po/de.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_rewind (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-04-17 09:56+0000\n" -"PO-Revision-Date: 2026-04-17 13:46+0200\n" +"POT-Creation-Date: 2026-07-04 06:27+0000\n" +"PO-Revision-Date: 2026-07-04 13:02+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -36,18 +36,18 @@ msgstr "Detail: " msgid "hint: " msgstr "Tipp: " -#: ../../common/controldata_utils.c:98 file_ops.c:326 +#: ../../common/controldata_utils.c:98 file_ops.c:349 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" -#: ../../common/controldata_utils.c:111 file_ops.c:341 local_source.c:102 +#: ../../common/controldata_utils.c:111 file_ops.c:364 local_source.c:102 #: local_source.c:161 parsexlog.c:371 #, c-format msgid "could not read file \"%s\": %m" msgstr "konnte Datei »%s« nicht lesen: %m" -#: ../../common/controldata_utils.c:120 file_ops.c:344 parsexlog.c:373 +#: ../../common/controldata_utils.c:120 file_ops.c:367 parsexlog.c:373 #, c-format msgid "could not read file \"%s\": read %d of %zu" msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" @@ -84,7 +84,7 @@ msgstr "" msgid "could not open file \"%s\": %m" msgstr "konnte Datei »%s« nicht öffnen: %m" -#: ../../common/controldata_utils.c:250 file_ops.c:117 +#: ../../common/controldata_utils.c:250 file_ops.c:120 #, c-format msgid "could not write file \"%s\": %m" msgstr "konnte Datei »%s« nicht schreiben: %m" @@ -95,24 +95,34 @@ msgstr "konnte Datei »%s« nicht schreiben: %m" msgid "could not fsync file \"%s\": %m" msgstr "konnte Datei »%s« nicht fsyncen: %m" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "Speicher aufgebraucht\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "ungültige Speicheranforderungsgröße %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "ungültige Speicheranforderungsgröße %zu * %zu\n" + #: ../../common/file_utils.c:75 #, c-format msgid "could not synchronize file system for file \"%s\": %m" msgstr "konnte Dateisystem für Datei »%s« nicht synchronisieren: %m" #: ../../common/file_utils.c:123 ../../common/file_utils.c:588 -#: ../../fe_utils/archive.c:86 file_ops.c:330 file_ops.c:417 +#: ../../fe_utils/archive.c:86 file_ops.c:353 file_ops.c:440 #, c-format msgid "could not stat file \"%s\": %m" msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" @@ -123,12 +133,12 @@ msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" msgid "this build does not support sync method \"%s\"" msgstr "diese Installation unterstützt Sync-Methode »%s« nicht" -#: ../../common/file_utils.c:156 ../../common/file_utils.c:304 file_ops.c:388 +#: ../../common/file_utils.c:156 ../../common/file_utils.c:304 file_ops.c:411 #, c-format msgid "could not open directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" -#: ../../common/file_utils.c:174 ../../common/file_utils.c:338 file_ops.c:462 +#: ../../common/file_utils.c:174 ../../common/file_utils.c:338 file_ops.c:485 #, c-format msgid "could not read directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht lesen: %m" @@ -240,92 +250,131 @@ msgstr "konnte nicht in Datei »%s« schreiben: %m" msgid "could not create file \"%s\": %m" msgstr "konnte Datei »%s« nicht erstellen: %m" -#: ../../fe_utils/recovery_gen.c:215 pg_rewind.c:314 +#: ../../fe_utils/recovery_gen.c:215 pg_rewind.c:316 #, c-format msgid "%s" msgstr "%s" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "Argument des Shell-Befehls enthält Newline oder Carriage Return: »%s«\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "Datenbankname enthält Newline oder Carriage Return: »%s«\n" -#: file_ops.c:67 +#: file_ops.c:52 +#, fuzzy, c-format +#| msgid "link target has unsafe path name: \"%s\"" +msgid "target file path is unsafe for open: \"%s\"" +msgstr "Ziel der Verknüpfung hat unsicheren Pfadnamen: »%s«" + +#: file_ops.c:70 #, c-format msgid "could not open target file \"%s\": %m" msgstr "konnte Zieldatei »%s« nicht öffnen: %m" -#: file_ops.c:81 +#: file_ops.c:84 #, c-format msgid "could not close target file \"%s\": %m" msgstr "konnte Zieldatei »%s« nicht schließen: %m" -#: file_ops.c:101 +#: file_ops.c:104 #, c-format msgid "could not seek in target file \"%s\": %m" msgstr "konnte Positionszeiger in Zieldatei »%s« nicht setzen: %m" -#: file_ops.c:150 file_ops.c:177 +#: file_ops.c:153 file_ops.c:180 #, c-format msgid "undefined file type for \"%s\"" msgstr "undefinierter Dateityp für »%s«" -#: file_ops.c:173 +#: file_ops.c:176 #, c-format msgid "invalid action (CREATE) for regular file" msgstr "ungültige Aktion (CREATE) für normale Datei" -#: file_ops.c:200 +#: file_ops.c:195 +#, fuzzy, c-format +#| msgid "link target has unsafe path name: \"%s\"" +msgid "target file path is unsafe for removal: \"%s\"" +msgstr "Ziel der Verknüpfung hat unsicheren Pfadnamen: »%s«" + +#: file_ops.c:206 #, c-format msgid "could not remove file \"%s\": %m" msgstr "konnte Datei »%s« nicht löschen: %m" #: file_ops.c:218 +#, fuzzy, c-format +#| msgid "link target has unsafe path name: \"%s\"" +msgid "target file path is unsafe for truncation: \"%s\"" +msgstr "Ziel der Verknüpfung hat unsicheren Pfadnamen: »%s«" + +#: file_ops.c:227 #, c-format msgid "could not open file \"%s\" for truncation: %m" msgstr "konnte Datei »%s« nicht zum Kürzen öffnen: %m" -#: file_ops.c:222 +#: file_ops.c:231 #, c-format msgid "could not truncate file \"%s\" to %u: %m" msgstr "konnte Datei »%s« nicht auf %u kürzen: %m" -#: file_ops.c:238 +#: file_ops.c:243 +#, c-format +msgid "target directory path is unsafe for directory creation: \"%s\"" +msgstr "" + +#: file_ops.c:251 #, c-format msgid "could not create directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" -#: file_ops.c:252 +#: file_ops.c:261 +#, c-format +msgid "target directory path is unsafe for directory removal: \"%s\"" +msgstr "" + +#: file_ops.c:269 #, c-format msgid "could not remove directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht löschen: %m" -#: file_ops.c:266 +#: file_ops.c:279 +#, fuzzy, c-format +#| msgid "link target has unsafe path name: \"%s\"" +msgid "target symlink path is unsafe for creation: \"%s\"" +msgstr "Ziel der Verknüpfung hat unsicheren Pfadnamen: »%s«" + +#: file_ops.c:286 #, c-format msgid "could not create symbolic link at \"%s\": %m" msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %m" -#: file_ops.c:280 +#: file_ops.c:296 +#, c-format +msgid "target symlink path is unsafe for removal: \"%s\"" +msgstr "" + +#: file_ops.c:303 #, c-format msgid "could not remove symbolic link \"%s\": %m" msgstr "konnte symbolische Verknüpfung »%s« nicht löschen: %m" -#: file_ops.c:441 +#: file_ops.c:464 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" -#: file_ops.c:444 +#: file_ops.c:467 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "Ziel für symbolische Verknüpfung »%s« ist zu lang" -#: file_ops.c:466 +#: file_ops.c:489 #, c-format msgid "could not close directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht schließen: %m" @@ -719,181 +768,184 @@ msgstr "Sie müssen %s als PostgreSQL-Superuser ausführen." msgid "could not read permissions of directory \"%s\": %m" msgstr "konnte Zugriffsrechte von Verzeichnis »%s« nicht lesen: %m" -#: pg_rewind.c:305 +#: pg_rewind.c:306 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"The target directory will not be modified." -msgstr "" +msgid "executing in dry-run mode" +msgstr "Ausführen im Probelaufmodus" + +#: pg_rewind.c:307 +#, c-format +msgid "The target directory will not be modified." +msgstr "Das Zielverzeichnis wird nicht verändert werden." -#: pg_rewind.c:317 +#: pg_rewind.c:319 #, c-format msgid "connected to server" msgstr "mit Server verbunden" -#: pg_rewind.c:378 +#: pg_rewind.c:380 #, c-format msgid "source and target cluster are on the same timeline" msgstr "Quell- und Ziel-Cluster sind auf der gleichen Zeitleiste" -#: pg_rewind.c:399 +#: pg_rewind.c:401 #, c-format msgid "servers diverged at WAL location %X/%08X on timeline %u" msgstr "Server divergierten bei WAL-Position %X/%08X auf Zeitleiste %u" -#: pg_rewind.c:460 +#: pg_rewind.c:462 #, c-format msgid "no rewind required" msgstr "kein Rückspulen nötig" -#: pg_rewind.c:473 +#: pg_rewind.c:475 #, c-format msgid "rewinding from last common checkpoint at %X/%08X on timeline %u" msgstr "Rückspulen ab letztem gemeinsamen Checkpoint bei %X/%08X auf Zeitleiste %u" -#: pg_rewind.c:483 +#: pg_rewind.c:485 #, c-format msgid "reading source file list" msgstr "lese Quelldateiliste" -#: pg_rewind.c:487 +#: pg_rewind.c:489 #, c-format msgid "reading target file list" msgstr "lese Zieldateiliste" -#: pg_rewind.c:496 +#: pg_rewind.c:498 #, c-format msgid "reading WAL in target" msgstr "lese WAL im Ziel-Cluster" -#: pg_rewind.c:517 +#: pg_rewind.c:519 #, c-format msgid "need to copy % MB (total source directory size is % MB)" msgstr "% MB müssen kopiert werden (Gesamtgröße des Quellverzeichnisses ist % MB)" -#: pg_rewind.c:535 +#: pg_rewind.c:537 #, c-format msgid "syncing target data directory" msgstr "synchronisiere Zieldatenverzeichnis" -#: pg_rewind.c:552 +#: pg_rewind.c:554 #, c-format msgid "Done!" msgstr "Fertig!" -#: pg_rewind.c:632 +#: pg_rewind.c:634 #, c-format msgid "no action decided for file \"%s\"" msgstr "keine Aktion bestimmt für Datei »%s«" -#: pg_rewind.c:664 +#: pg_rewind.c:666 #, c-format msgid "source system was modified while pg_rewind was running" msgstr "Quellsystem wurde verändert, während pg_rewind lief" -#: pg_rewind.c:668 +#: pg_rewind.c:670 #, c-format msgid "creating backup label and updating control file" msgstr "erzeuge Backup-Label und aktualisiere Kontrolldatei" -#: pg_rewind.c:718 +#: pg_rewind.c:720 #, c-format msgid "source system was in unexpected state at end of rewind" msgstr "Quellsystem war in einem unerwarteten Zustand am Ende des Rückspulens" -#: pg_rewind.c:750 +#: pg_rewind.c:752 #, c-format msgid "source and target clusters are from different systems" msgstr "Quell- und Ziel-Cluster sind von verschiedenen Systemen" -#: pg_rewind.c:758 +#: pg_rewind.c:760 #, c-format msgid "clusters are not compatible with this version of pg_rewind" msgstr "die Cluster sind nicht mit dieser Version von pg_rewind kompatibel" -#: pg_rewind.c:768 +#: pg_rewind.c:770 #, c-format msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" msgstr "Zielserver muss entweder Datenprüfsummen oder »wal_log_hints = on« verwenden" -#: pg_rewind.c:779 +#: pg_rewind.c:781 #, c-format msgid "target server must be shut down cleanly" msgstr "Zielserver muss sauber heruntergefahren worden sein" -#: pg_rewind.c:789 +#: pg_rewind.c:791 #, c-format msgid "source data directory must be shut down cleanly" msgstr "Quelldatenverzeichnis muss sauber heruntergefahren worden sein" -#: pg_rewind.c:836 +#: pg_rewind.c:838 #, c-format msgid "%*s/%s kB (%d%%) copied" msgstr "%*s/%s kB (%d%%) kopiert" -#: pg_rewind.c:962 +#: pg_rewind.c:964 #, c-format msgid "could not find common ancestor of the source and target cluster's timelines" msgstr "konnte keinen gemeinsamen Anfangspunkt in den Zeitleisten von Quell- und Ziel-Cluster finden" -#: pg_rewind.c:1003 +#: pg_rewind.c:1005 #, c-format msgid "backup label buffer too small" msgstr "Puffer für Backup-Label ist zu klein" -#: pg_rewind.c:1026 +#: pg_rewind.c:1028 #, c-format msgid "unexpected control file CRC" msgstr "unerwartete CRC in Kontrolldatei" -#: pg_rewind.c:1038 +#: pg_rewind.c:1040 #, c-format msgid "unexpected control file size %zu, expected %d" msgstr "unerwartete Kontrolldateigröße %zu, erwartet wurde %d" -#: pg_rewind.c:1048 +#: pg_rewind.c:1050 #, c-format msgid "invalid WAL segment size in control file (%d byte)" msgid_plural "invalid WAL segment size in control file (%d bytes)" msgstr[0] "ungültige WAL-Segmentgröße in Kontrolldatei (%d Byte)" msgstr[1] "ungültige WAL-Segmentgröße in Kontrolldatei (%d Bytes)" -#: pg_rewind.c:1052 +#: pg_rewind.c:1054 #, c-format msgid "The WAL segment size must be a power of two between 1 MB and 1 GB." msgstr "Die WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein." -#: pg_rewind.c:1089 pg_rewind.c:1157 +#: pg_rewind.c:1091 pg_rewind.c:1159 #, c-format msgid "program \"%s\" is needed by %s but was not found in the same directory as \"%s\"" msgstr "Programm »%s« wird von %s benötigt, aber wurde nicht im selben Verzeichnis wie »%s« gefunden" -#: pg_rewind.c:1092 pg_rewind.c:1160 +#: pg_rewind.c:1094 pg_rewind.c:1162 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "Programm »%s« wurde von »%s« gefunden, aber es hatte nicht die gleiche Version wie %s" -#: pg_rewind.c:1121 +#: pg_rewind.c:1123 #, c-format msgid "could not read \"restore_command\" from target cluster" msgstr "konnte »restore_command« des Ziel-Clusters nicht lesen" -#: pg_rewind.c:1126 +#: pg_rewind.c:1128 #, c-format msgid "\"restore_command\" is not set in the target cluster" msgstr "»restore_command« ist im Ziel-Cluster nicht gesetzt" -#: pg_rewind.c:1164 +#: pg_rewind.c:1166 #, c-format msgid "executing \"%s\" for target server to complete crash recovery" msgstr "führe »%s« für Zielserver aus, um Wiederherstellung abzuschließen" -#: pg_rewind.c:1202 +#: pg_rewind.c:1204 #, c-format msgid "postgres single-user mode in target cluster failed" msgstr "postgres im Einzelbenutzermodus im Ziel-Cluster fehlgeschlagen" -#: pg_rewind.c:1203 +#: pg_rewind.c:1205 #, c-format msgid "Command was: %s" msgstr "Die Anweisung war: %s" @@ -1008,82 +1060,82 @@ msgstr "unerwartete Pageaddr %X/%08X in WAL-Segment %s, LSN %X/%08X, Offset %u" msgid "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%08X, offset %u" msgstr "Zeitleisten-ID %u außer der Reihe (nach %u) in WAL-Segment %s, LSN %X/%08X, Offset %u" -#: xlogreader.c:1788 +#: xlogreader.c:1790 #, c-format msgid "out-of-order block_id %u at %X/%08X" msgstr "block_id %u außer der Reihe bei %X/%08X" -#: xlogreader.c:1812 +#: xlogreader.c:1814 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%08X" msgstr "BKPBLOCK_HAS_DATA gesetzt, aber keine Daten enthalten bei %X/%08X" -#: xlogreader.c:1819 +#: xlogreader.c:1821 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %d at %X/%08X" msgstr "BKPBLOCK_HAS_DATA nicht gesetzt, aber Datenlänge ist %d bei %X/%08X" -#: xlogreader.c:1855 +#: xlogreader.c:1857 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %d length %d block image length %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLE gesetzt, aber Loch Offset %d Länge %d Block-Abbild-Länge %d bei %X/%08X" -#: xlogreader.c:1871 +#: xlogreader.c:1873 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %d length %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLE nicht gesetzt, aber Loch Offset %d Länge %d bei %X/%08X" -#: xlogreader.c:1885 +#: xlogreader.c:1887 #, c-format msgid "BKPIMAGE_COMPRESSED set, but block image length %d at %X/%08X" msgstr "BKPIMAGE_COMPRESSED gesetzt, aber Block-Abbild-Länge %d bei %X/%08X" -#: xlogreader.c:1900 +#: xlogreader.c:1902 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image length is %d at %X/%08X" msgstr "weder BKPIMAGE_HAS_HOLE noch BKPIMAGE_COMPRESSED gesetzt, aber Block-Abbild-Länge ist %d bei %X/%08X" -#: xlogreader.c:1916 +#: xlogreader.c:1918 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%08X" msgstr "BKPBLOCK_SAME_REL gesetzt, aber keine vorangehende Relation bei %X/%08X" -#: xlogreader.c:1928 +#: xlogreader.c:1930 #, c-format msgid "invalid block_id %u at %X/%08X" msgstr "ungültige block_id %u bei %X/%08X" -#: xlogreader.c:1995 +#: xlogreader.c:1997 #, c-format msgid "record with invalid length at %X/%08X" msgstr "Datensatz mit ungültiger Länge bei %X/%08X" -#: xlogreader.c:2021 +#: xlogreader.c:2023 #, c-format msgid "could not locate backup block with ID %d in WAL record" msgstr "konnte Backup-Block mit ID %d nicht im WAL-Eintrag finden" -#: xlogreader.c:2105 +#: xlogreader.c:2107 #, c-format msgid "could not restore image at %X/%08X with invalid block %d specified" msgstr "konnte Abbild bei %X/%08X mit ungültigem angegebenen Block %d nicht wiederherstellen" -#: xlogreader.c:2112 +#: xlogreader.c:2114 #, c-format msgid "could not restore image at %X/%08X with invalid state, block %d" msgstr "konnte Abbild mit ungültigem Zustand bei %X/%08X nicht wiederherstellen, Block %d" -#: xlogreader.c:2139 xlogreader.c:2156 +#: xlogreader.c:2141 xlogreader.c:2158 #, c-format msgid "could not restore image at %X/%08X compressed with %s not supported by build, block %d" msgstr "konnte Abbild bei %X/%08X nicht wiederherstellen, komprimiert mit %s, nicht unterstützt von dieser Installation, Block %d" -#: xlogreader.c:2165 +#: xlogreader.c:2167 #, c-format msgid "could not restore image at %X/%08X compressed with unknown method, block %d" msgstr "konnte Abbild bei %X/%08X nicht wiederherstellen, komprimiert mit unbekannter Methode, Block %d" -#: xlogreader.c:2173 +#: xlogreader.c:2175 #, c-format msgid "could not decompress image at %X/%08X, block %d" msgstr "konnte Abbild bei %X/%08X nicht dekomprimieren, Block %d" diff --git a/src/bin/pg_rewind/po/ja.po b/src/bin/pg_rewind/po/ja.po index 11c935e5e0a..d941e30d95b 100644 --- a/src/bin/pg_rewind/po/ja.po +++ b/src/bin/pg_rewind/po/ja.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_rewind (PostgreSQL 19)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-15 13:37+0900\n" -"PO-Revision-Date: 2026-05-15 16:04+0900\n" +"POT-Creation-Date: 2026-07-03 14:13+0900\n" +"PO-Revision-Date: 2026-07-06 14:41+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" @@ -253,17 +253,17 @@ msgstr "ファイル\"%s\"を書き出せませんでした: %m" msgid "could not create file \"%s\": %m" msgstr "ファイル\"%s\"を作成できませんでした: %m" -#: ../../fe_utils/recovery_gen.c:215 pg_rewind.c:314 +#: ../../fe_utils/recovery_gen.c:215 pg_rewind.c:316 #, c-format msgid "%s" msgstr "%s" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "シェルコマンドの引数に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "データベース名に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" @@ -763,182 +763,183 @@ msgstr "PostgreSQLのスーパーユーザーで%sを実行しなければなり msgid "could not read permissions of directory \"%s\": %m" msgstr "ディレクトリ\"%s\"の権限を読み取れませんでした: %m" -#: pg_rewind.c:305 +#: pg_rewind.c:306 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"The target directory will not be modified." -msgstr "" -"ドライランモードで実行します。\n" -"ターゲットディレクトリは更新されません。" +msgid "executing in dry-run mode" +msgstr "ドライランモードで実行します" + +#: pg_rewind.c:307 +#, c-format +msgid "The target directory will not be modified." +msgstr "対象ディレクトリの内容は変更されません。" -#: pg_rewind.c:317 +#: pg_rewind.c:319 #, c-format msgid "connected to server" msgstr "サーバーへ接続しました" -#: pg_rewind.c:378 +#: pg_rewind.c:380 #, c-format msgid "source and target cluster are on the same timeline" msgstr "ソースとターゲットのクラスタが同一タイムライン上にあります" -#: pg_rewind.c:399 +#: pg_rewind.c:401 #, c-format msgid "servers diverged at WAL location %X/%08X on timeline %u" msgstr "タイムライン%3$uのWAL位置%1$X/%2$08Xで両サーバーが分岐しています" -#: pg_rewind.c:460 +#: pg_rewind.c:462 #, c-format msgid "no rewind required" msgstr "巻き戻しは必要ありません" -#: pg_rewind.c:473 +#: pg_rewind.c:475 #, c-format msgid "rewinding from last common checkpoint at %X/%08X on timeline %u" msgstr "タイムライン%3$uの%1$X/%2$08Xにある最新の共通チェックポイントから巻き戻しています" -#: pg_rewind.c:483 +#: pg_rewind.c:485 #, c-format msgid "reading source file list" msgstr "ソースファイルリストを読み込んでいます" -#: pg_rewind.c:487 +#: pg_rewind.c:489 #, c-format msgid "reading target file list" msgstr "ターゲットファイルリストを読み込んでいます" -#: pg_rewind.c:496 +#: pg_rewind.c:498 #, c-format msgid "reading WAL in target" msgstr "ターゲットでWALを読み込んでいます" -#: pg_rewind.c:517 +#: pg_rewind.c:519 #, c-format msgid "need to copy % MB (total source directory size is % MB)" msgstr "% MBコピーする必要があります (コピー元ディレクトリの合計サイズは % MBです)" -#: pg_rewind.c:535 +#: pg_rewind.c:537 #, c-format msgid "syncing target data directory" msgstr "ターゲットデータディレクトリを同期しています" -#: pg_rewind.c:552 +#: pg_rewind.c:554 #, c-format msgid "Done!" msgstr "完了!" -#: pg_rewind.c:632 +#: pg_rewind.c:634 #, c-format msgid "no action decided for file \"%s\"" msgstr "ファイル\"%s\"に対するアクションが決定されていません" -#: pg_rewind.c:664 +#: pg_rewind.c:666 #, c-format msgid "source system was modified while pg_rewind was running" msgstr "pg_rewindの実行中にソースシス7テムが更新されました" -#: pg_rewind.c:668 +#: pg_rewind.c:670 #, c-format msgid "creating backup label and updating control file" msgstr "backup labelを作成して制御ファイルを更新しています" -#: pg_rewind.c:718 +#: pg_rewind.c:720 #, c-format msgid "source system was in unexpected state at end of rewind" msgstr "巻き戻し完了時点のソースシステムが想定外の状態でした" -#: pg_rewind.c:750 +#: pg_rewind.c:752 #, c-format msgid "source and target clusters are from different systems" msgstr "ソースクラスタとターゲットクラスタは異なるシステムのものです" -#: pg_rewind.c:758 +#: pg_rewind.c:760 #, c-format msgid "clusters are not compatible with this version of pg_rewind" msgstr "クラスタは、このバージョンのpg_rewindとの互換性がありません" -#: pg_rewind.c:768 +#: pg_rewind.c:770 #, c-format msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" msgstr "ターゲットサーバーはデータチェックサムを利用している、または\"wal_log_hints = on\"である必要があります" -#: pg_rewind.c:779 +#: pg_rewind.c:781 #, c-format msgid "target server must be shut down cleanly" msgstr "ターゲットサーバーはきれいにシャットダウンされていなければなりません" -#: pg_rewind.c:789 +#: pg_rewind.c:791 #, c-format msgid "source data directory must be shut down cleanly" msgstr "ソースデータディレクトリはきれいにシャットダウンされていなければなりません" -#: pg_rewind.c:836 +#: pg_rewind.c:838 #, c-format msgid "%*s/%s kB (%d%%) copied" msgstr "%*s/%s kB (%d%%) コピーしました" -#: pg_rewind.c:962 +#: pg_rewind.c:964 #, c-format msgid "could not find common ancestor of the source and target cluster's timelines" msgstr "ソースクラスタとターゲットクラスタのタイムラインの共通の祖先を見つけられません" -#: pg_rewind.c:1003 +#: pg_rewind.c:1005 #, c-format msgid "backup label buffer too small" msgstr "バックアップラベルのバッファが小さすぎます" -#: pg_rewind.c:1026 +#: pg_rewind.c:1028 #, c-format msgid "unexpected control file CRC" msgstr "想定外の制御ファイルCRCです" -#: pg_rewind.c:1038 +#: pg_rewind.c:1040 #, c-format msgid "unexpected control file size %zu, expected %d" msgstr "想定外の制御ファイルのサイズ%zu、想定は%d" -#: pg_rewind.c:1048 +#: pg_rewind.c:1050 #, c-format msgid "invalid WAL segment size in control file (%d byte)" msgid_plural "invalid WAL segment size in control file (%d bytes)" msgstr[0] "制御ファイル中の不正なWALセグメントサイズ (%dバイト)" -#: pg_rewind.c:1052 +#: pg_rewind.c:1054 #, c-format msgid "The WAL segment size must be a power of two between 1 MB and 1 GB." msgstr "WALセグメントサイズは1MBから1GBまでの間の2の累乗でなければなりません。" -#: pg_rewind.c:1089 pg_rewind.c:1157 +#: pg_rewind.c:1091 pg_rewind.c:1159 #, c-format msgid "program \"%s\" is needed by %s but was not found in the same directory as \"%s\"" msgstr "%2$sには\"%1$s\"プログラムが必要ですが、\"%3$s\"と同じディレクトリにありませんでした。" -#: pg_rewind.c:1092 pg_rewind.c:1160 +#: pg_rewind.c:1094 pg_rewind.c:1162 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "\"%2$s\"がプログラム\"%1$s\"を見つけましたが、これは%3$sと同じバージョンではありませんでした。" -#: pg_rewind.c:1121 +#: pg_rewind.c:1123 #, c-format msgid "could not read \"restore_command\" from target cluster" msgstr "ターゲットクラスタから\"restore_command\"が読み取れませんでした" -#: pg_rewind.c:1126 +#: pg_rewind.c:1128 #, c-format msgid "\"restore_command\" is not set in the target cluster" msgstr "ターゲットクラスタで\"restore_command\"が設定されていません" -#: pg_rewind.c:1164 +#: pg_rewind.c:1166 #, c-format msgid "executing \"%s\" for target server to complete crash recovery" msgstr "ターゲットサーバーに対して\"%s\"を実行してクラッシュリカバリを完了させます" -#: pg_rewind.c:1202 +#: pg_rewind.c:1204 #, c-format msgid "postgres single-user mode in target cluster failed" msgstr "ターゲットクラスタでのpostgresコマンドのシングルユーザーモード実行に失敗しました" -#: pg_rewind.c:1203 +#: pg_rewind.c:1205 #, c-format msgid "Command was: %s" msgstr "コマンド: %s" @@ -1053,82 +1054,82 @@ msgstr "WALセグメント%3$s、LSN %4$X/%5$08X、オフセット%6$uで想定 msgid "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%08X, offset %u" msgstr "WALセグメント%3$s、LSN %4$X/%5$08X、オフセット%6$uで異常な順序のタイムラインID %1$u(%2$uの後)" -#: xlogreader.c:1788 +#: xlogreader.c:1790 #, c-format msgid "out-of-order block_id %u at %X/%08X" msgstr "%X/%08Xで異常な順序の block_id %u" -#: xlogreader.c:1812 +#: xlogreader.c:1814 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%08X" msgstr "%X/%08Xで、BKPBLOCK_HAS_DATAが設定されていますが、データがありません" -#: xlogreader.c:1819 +#: xlogreader.c:1821 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %d at %X/%08X" msgstr "BKPBLOCK_HAS_DATAが設定されていませんが、%2$X/%3$08Xのデータ長は%1$dです" -#: xlogreader.c:1855 +#: xlogreader.c:1857 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %d length %d block image length %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLEが設定されていますが、%4$X/%5$08Xでホールオフセット%1$d、長さ%2$d、ブロックイメージ長%3$dです" -#: xlogreader.c:1871 +#: xlogreader.c:1873 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %d length %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLEが設定されていませんが、%3$X/%4$08Xにおけるホールオフセット%1$dの長さが%2$dです" -#: xlogreader.c:1885 +#: xlogreader.c:1887 #, c-format msgid "BKPIMAGE_COMPRESSED set, but block image length %d at %X/%08X" msgstr "BKPIMAGE_COMPRESSEDが設定されていますが、%2$X/%3$08Xにおいてブロックイメージ長が%1$dです" -#: xlogreader.c:1900 +#: xlogreader.c:1902 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image length is %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLEもBKPIMAGE_COMPRESSEDも設定されていませんが、%2$X/%3$08Xにおいてブロックイメージ長が%1$dです" -#: xlogreader.c:1916 +#: xlogreader.c:1918 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%08X" msgstr "%X/%08Xで、BKPBLOCK_SAME_RELが設定されていますが、以前のリレーションがありません" -#: xlogreader.c:1928 +#: xlogreader.c:1930 #, c-format msgid "invalid block_id %u at %X/%08X" msgstr "%2$X/%3$08Xで、block_id %1$uが不正です" -#: xlogreader.c:1995 +#: xlogreader.c:1997 #, c-format msgid "record with invalid length at %X/%08X" msgstr "%X/%08Xで、レコード長が無効です" -#: xlogreader.c:2021 +#: xlogreader.c:2023 #, c-format msgid "could not locate backup block with ID %d in WAL record" msgstr "WALレコード中のID %dのバックアップブロックを特定できませんでした" -#: xlogreader.c:2105 +#: xlogreader.c:2107 #, c-format msgid "could not restore image at %X/%08X with invalid block %d specified" msgstr "%X/%08Xで、不正なブロック%dが指定されているためイメージが復元できませんでした" -#: xlogreader.c:2112 +#: xlogreader.c:2114 #, c-format msgid "could not restore image at %X/%08X with invalid state, block %d" msgstr "%X/%Xで、不正な状態であるためブロック%dのイメージが復元できませんでした" -#: xlogreader.c:2139 xlogreader.c:2156 +#: xlogreader.c:2141 xlogreader.c:2158 #, c-format msgid "could not restore image at %X/%08X compressed with %s not supported by build, block %d" msgstr "%1$X/%2$08Xで、このビルドでサポートされない圧縮方式%3$sで圧縮されているためブロック%4$dが復元できませんでした" -#: xlogreader.c:2165 +#: xlogreader.c:2167 #, c-format msgid "could not restore image at %X/%08X compressed with unknown method, block %d" msgstr "%X/%08Xで、イメージが未知の方式で圧縮されているためブロック%dが復元できませんでした" -#: xlogreader.c:2173 +#: xlogreader.c:2175 #, c-format msgid "could not decompress image at %X/%08X, block %d" msgstr "%X/%08Xで、ブロック%dが伸張できませんでした" diff --git a/src/bin/pg_rewind/po/ka.po b/src/bin/pg_rewind/po/ka.po index 006ce87430f..8595a43575e 100644 --- a/src/bin/pg_rewind/po/ka.po +++ b/src/bin/pg_rewind/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_rewind (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-13 06:27+0000\n" -"PO-Revision-Date: 2026-05-13 09:13+0200\n" +"POT-Creation-Date: 2026-07-04 00:26+0000\n" +"PO-Revision-Date: 2026-07-04 07:34+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -250,17 +250,17 @@ msgstr "ფაილში (%s) ჩაწერის შეცდომა: %m" msgid "could not create file \"%s\": %m" msgstr "ფაილის (%s) შექმნის შეცდომა: %m" -#: ../../fe_utils/recovery_gen.c:215 pg_rewind.c:314 +#: ../../fe_utils/recovery_gen.c:215 pg_rewind.c:316 #, c-format msgid "%s" msgstr "%s" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "გარსის ბრძანების არგუმენტი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "მონაცემთა ბაზის სახელი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" @@ -761,183 +761,184 @@ msgstr "%s PostgreSQL-ის ზემომხმარებლით უნ msgid "could not read permissions of directory \"%s\": %m" msgstr "საქაღალდის წვდომების წაკითხვა შეუძლებელია \"%s\": %m" -#: pg_rewind.c:305 +#: pg_rewind.c:306 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"The target directory will not be modified." -msgstr "" -"შესრულება მშრალი გაშვების რეჟიმში.\n" -"სამიზნე საქაღალდე არ შეიცვლება." +msgid "executing in dry-run mode" +msgstr "შესრულება მშრალი გაშვების რეჟიმში" + +#: pg_rewind.c:307 +#, c-format +msgid "The target directory will not be modified." +msgstr "სამიზნე საქაღალდე არ შეიცვლება." -#: pg_rewind.c:317 +#: pg_rewind.c:319 #, c-format msgid "connected to server" msgstr "სერვერთან მიერთება წარმატებულია" -#: pg_rewind.c:378 +#: pg_rewind.c:380 #, c-format msgid "source and target cluster are on the same timeline" msgstr "საწყისი და სამიზნე კლასტერები იგივე დროის ხაზზეა" -#: pg_rewind.c:399 +#: pg_rewind.c:401 #, c-format msgid "servers diverged at WAL location %X/%08X on timeline %u" msgstr "სერვერი დაშორდა WAL-ს მდებარეობაზე %X/%08X დროის ხაზზე %u" -#: pg_rewind.c:460 +#: pg_rewind.c:462 #, c-format msgid "no rewind required" msgstr "გადახვევა საჭირო არაა" -#: pg_rewind.c:473 +#: pg_rewind.c:475 #, c-format msgid "rewinding from last common checkpoint at %X/%08X on timeline %u" msgstr "ბოლო საერთო საგუშაგოდან %X/%08X საათზე გადახვევა ვადების %u" -#: pg_rewind.c:483 +#: pg_rewind.c:485 #, c-format msgid "reading source file list" msgstr "ფაილების წყაროს სიის კითხვა" -#: pg_rewind.c:487 +#: pg_rewind.c:489 #, c-format msgid "reading target file list" msgstr "სამიზნის ფაილების სიის კითხვა" -#: pg_rewind.c:496 +#: pg_rewind.c:498 #, c-format msgid "reading WAL in target" msgstr "სამიზნეში მყოფი WAL-ის კითხვა" -#: pg_rewind.c:517 +#: pg_rewind.c:519 #, c-format msgid "need to copy % MB (total source directory size is % MB)" msgstr "საჭიროა % მბ-ის კოპირება (საწყისი საქაღალდის სრული ზომაა % მბ)" -#: pg_rewind.c:535 +#: pg_rewind.c:537 #, c-format msgid "syncing target data directory" msgstr "მონაცემების სამიზე საქაღალდის სინქრონიზაცია" -#: pg_rewind.c:552 +#: pg_rewind.c:554 #, c-format msgid "Done!" msgstr "შესრულებულია!" -#: pg_rewind.c:632 +#: pg_rewind.c:634 #, c-format msgid "no action decided for file \"%s\"" msgstr "ფაილისთვის %s ქმედება არჩეული არაა" -#: pg_rewind.c:664 +#: pg_rewind.c:666 #, c-format msgid "source system was modified while pg_rewind was running" msgstr "საწყისი ფაილი შეიცვალა, სანამ pg_rewind იყო გაშვებული" -#: pg_rewind.c:668 +#: pg_rewind.c:670 #, c-format msgid "creating backup label and updating control file" msgstr "მარქაფის ჭდის შექმნა და საკონტროლო ფაილის განახლება" -#: pg_rewind.c:718 +#: pg_rewind.c:720 #, c-format msgid "source system was in unexpected state at end of rewind" msgstr "საწყისი სისტემა გადახვევისას გაურკვეველ მდგომარეობაში აღმოჩნდა" -#: pg_rewind.c:750 +#: pg_rewind.c:752 #, c-format msgid "source and target clusters are from different systems" msgstr "საწყისი და სამიზნე კლასტერები სხვადასახვა სისტემებიდანაა" -#: pg_rewind.c:758 +#: pg_rewind.c:760 #, c-format msgid "clusters are not compatible with this version of pg_rewind" msgstr "კლასტერები pg_rewind-ის ამ ვერსიასთან შეუთავსებელია" -#: pg_rewind.c:768 +#: pg_rewind.c:770 #, c-format msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" msgstr "სამზნე სერვერზე საჭიროა ან მონაცემების საკონტროლო ჯამების გამოყენება, ან \"wal_log_hints = on\"" -#: pg_rewind.c:779 +#: pg_rewind.c:781 #, c-format msgid "target server must be shut down cleanly" msgstr "სამიზნე ბაზა წესების დაცვით უნდა იყოს გამორთული" -#: pg_rewind.c:789 +#: pg_rewind.c:791 #, c-format msgid "source data directory must be shut down cleanly" msgstr "საწყისი ბაზა წესების დაცვით უნდა იყოს გამორთული" -#: pg_rewind.c:836 +#: pg_rewind.c:838 #, c-format msgid "%*s/%s kB (%d%%) copied" msgstr "%*s/%s კბ (%d%%) დაკოპირდა" -#: pg_rewind.c:962 +#: pg_rewind.c:964 #, c-format msgid "could not find common ancestor of the source and target cluster's timelines" msgstr "საწყისი და სამიზნე კლასტერების დროის ხაზის საერთო წინაპრის პოვნა შეუძლებელია" -#: pg_rewind.c:1003 +#: pg_rewind.c:1005 #, c-format msgid "backup label buffer too small" msgstr "მარქაფის ჭდის ბაფერი ძალიან პატარაა" -#: pg_rewind.c:1026 +#: pg_rewind.c:1028 #, c-format msgid "unexpected control file CRC" msgstr "კონტროლის ფაილის მოულოდნელი CRC" -#: pg_rewind.c:1038 +#: pg_rewind.c:1040 #, c-format msgid "unexpected control file size %zu, expected %d" msgstr "მოულოდნელი საკონტროლო ფაილის ზომა %zu, მოსალოდნელი %d" -#: pg_rewind.c:1048 +#: pg_rewind.c:1050 #, c-format msgid "invalid WAL segment size in control file (%d byte)" msgid_plural "invalid WAL segment size in control file (%d bytes)" msgstr[0] "არასწორი WAL სეგმენტის ზომა კონტროლის ფაილში (%d ბაიტი)" msgstr[1] "არასწორი WAL სეგმენტის ზომა კონტროლის ფაილში (%d ბაიტი)" -#: pg_rewind.c:1052 +#: pg_rewind.c:1054 #, c-format msgid "The WAL segment size must be a power of two between 1 MB and 1 GB." msgstr "WAL სეგმენტის ზომა ორის ხარისხი უნდა იყოს, შუალედიდან 1მბ-1გბ." -#: pg_rewind.c:1089 pg_rewind.c:1157 +#: pg_rewind.c:1091 pg_rewind.c:1159 #, c-format msgid "program \"%s\" is needed by %s but was not found in the same directory as \"%s\"" msgstr "პროგრამა \"%s\" სჭირდება \"%s\"-ს, მაგრამ იგივე საქაღალდეში, სადაც \"%s\", ნაპოვნი არაა" -#: pg_rewind.c:1092 pg_rewind.c:1160 +#: pg_rewind.c:1094 pg_rewind.c:1162 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "პროგრამა „%s“ ნაპოვნია „%s“-ის მიერ, მაგრამ ვერსია, იგივეა არაა, რაც %s" -#: pg_rewind.c:1121 +#: pg_rewind.c:1123 #, c-format msgid "could not read \"restore_command\" from target cluster" msgstr "სამიზნე კლასტერიდან \"restore_command\"-ის წაკითხვა შეუძლებელია" -#: pg_rewind.c:1126 +#: pg_rewind.c:1128 #, c-format msgid "\"restore_command\" is not set in the target cluster" msgstr "სამიზნე კლასტერში \"restore_command\" დაყენებული არაა" -#: pg_rewind.c:1164 +#: pg_rewind.c:1166 #, c-format msgid "executing \"%s\" for target server to complete crash recovery" msgstr "ავარიიდან სრულად აღდგენისთვის სამიზნე სერვერზე %s-ის შესრულდება" -#: pg_rewind.c:1202 +#: pg_rewind.c:1204 #, c-format msgid "postgres single-user mode in target cluster failed" msgstr "სამიზნე კლასტერში postgres-ის ერთმომხმარებლიანი რეჟიმის შეცდომა" -#: pg_rewind.c:1203 +#: pg_rewind.c:1205 #, c-format msgid "Command was: %s" msgstr "ბრძანება იყო: %s" @@ -1052,124 +1053,82 @@ msgstr "მოულოდნელი pageaddr %X/%08X ჟურნალის msgid "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%08X, offset %u" msgstr "მიმდევრობის-გარე დროის ხაზის ID %u (%u-ის შემდეგ) ჟურნალის სეგმენტში %s, LSN %X/%08X, წანაცვლება %u" -#: xlogreader.c:1788 +#: xlogreader.c:1790 #, c-format msgid "out-of-order block_id %u at %X/%08X" msgstr "ურიგო block_id %u მისამართზე %X/%08X" -#: xlogreader.c:1812 +#: xlogreader.c:1814 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%08X" msgstr "BKPBLOCK_HAS_DATA დაყენებულია, მაგრამ მონაცემები მისამართზე %X/%08X არ არსებობს" -#: xlogreader.c:1819 +#: xlogreader.c:1821 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %d at %X/%08X" msgstr "BKPBLOCK_HAS_DATA დაყენებულია, მაგრამ არსებობს მონაცემები სიგრძით %d მისამართზე %X/%08X" -#: xlogreader.c:1855 +#: xlogreader.c:1857 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %d length %d block image length %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLE დაყენებულია, მაგრამ ნახვრეტის წანაცვლება %d სიგრძე %d ბლოკის ასლის სიგრძე %d მისამართზე %X/%08X" -#: xlogreader.c:1871 +#: xlogreader.c:1873 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %d length %d at %X/%08X" msgstr "BKPIMAGE_HAS_HOLE დაყენებული არაა, მაგრამ ნახვრეტის წანაცვლება %d სიგრძე %d მისანართზე %X/%08X" -#: xlogreader.c:1885 +#: xlogreader.c:1887 #, c-format msgid "BKPIMAGE_COMPRESSED set, but block image length %d at %X/%08X" msgstr "BKPIMAGE_COMPRESSED დაყენებულია, მაგრამ ბლოკის ასლის სიგრძეა %d მისამართზე %X/%08X" -#: xlogreader.c:1900 +#: xlogreader.c:1902 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image length is %d at %X/%08X" msgstr "არც BKPIMAGE_HAS_HOLE და არც BKPIMAGE_COMPRESSED დაყენებული არაა, მაგრამ ბლოკის ასლის სიგრძე %d-ა, მისამართზე %X/%08X" -#: xlogreader.c:1916 +#: xlogreader.c:1918 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%08X" msgstr "BKPBLOCK_SAME_REL დაყენებულია, მაგრამ წინა მნიშვნელობა მითითებული არაა მისამართზე %X/%08X" -#: xlogreader.c:1928 +#: xlogreader.c:1930 #, c-format msgid "invalid block_id %u at %X/%08X" msgstr "არასწორი block_id %u %X/%08X" -#: xlogreader.c:1995 +#: xlogreader.c:1997 #, c-format msgid "record with invalid length at %X/%08X" msgstr "ჩანაწერი არასწორი სიგრძით მისამართზე %X/%08X" -#: xlogreader.c:2021 +#: xlogreader.c:2023 #, c-format msgid "could not locate backup block with ID %d in WAL record" msgstr "შეცდომა WAL ჩანაწერში მარქაფი ბლოკის, ID-ით %d, მოძებნისას" -#: xlogreader.c:2105 +#: xlogreader.c:2107 #, c-format msgid "could not restore image at %X/%08X with invalid block %d specified" msgstr "შეუძლებელია ასლის აღდგენა მისამართზე %X/%08X, როცა მითითებულია არასწორი ბლოკი %d" -#: xlogreader.c:2112 +#: xlogreader.c:2114 #, c-format msgid "could not restore image at %X/%08X with invalid state, block %d" msgstr "შეუძლებელია ასლის აღდგენა მისამართზე %X/%08X არასწორი მდგომარეობით, ბლოკი %d" -#: xlogreader.c:2139 xlogreader.c:2156 +#: xlogreader.c:2141 xlogreader.c:2158 #, c-format msgid "could not restore image at %X/%08X compressed with %s not supported by build, block %d" msgstr "აღდგენის შეცდომა მისამართზე %X/%08X, შეკუმშული %s-ით მხარდაჭერილი არაა აგების მიერ. ბლოკი %d" -#: xlogreader.c:2165 +#: xlogreader.c:2167 #, c-format msgid "could not restore image at %X/%08X compressed with unknown method, block %d" msgstr "შეუძლებელია ასლის აღდგენა მისამართზე %X/%08X, შეკუმშულია უცნობი მეთოდით, ბლოკი %d" -#: xlogreader.c:2173 +#: xlogreader.c:2175 #, c-format msgid "could not decompress image at %X/%08X, block %d" msgstr "შეუძლებელია ასლის გაშლა მისამართზე %X/%08X, ბლოკი %d" - -#, c-format -#~ msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" -#~ msgstr "%s სიმბმულია, მაგრამ სიმბოლური ბმულები ამ პლატფორმაზე მხარდაჭერილი არაა" - -#, c-format -#~ msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" -#~ msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" -#~ msgstr[0] "WAL სეგმენტის ზომა ორის ხარისხი უნდა იყოს, 1 მბ-სა და 1გბ-ს შორის, მაგრამ კონტროლის ფაილში მითითებულია %d ბაიტი" -#~ msgstr[1] "WAL სეგმენტის ზომა ორის ხარისხი უნდა იყოს, 1 მბ-სა და 1გბ-ს შორის, მაგრამ კონტროლის ფაილში მითითებულია %d ბაიტი" - -#, c-format -#~ msgid "cannot create restricted tokens on this platform: error code %lu" -#~ msgstr "ამ პლატფორმაზე შეზღუდული კოდების შექმნა შეუძლებელია: შეცდომის კოდი %lu" - -#, c-format -#~ msgid "cannot use restore_command with %%r placeholder" -#~ msgstr "restore_command-ის გამოყენება %%r ადგილმჭერის გარეშე გამოყენება შეუძლებელია" - -#, c-format -#~ msgid "could not load library \"%s\": error code %lu" -#~ msgstr "ბიბლიოთეკის (\"%s\") ჩატვირთვის შეცდომა: შეცდომის კოდი: %lu" - -#, c-format -#~ msgid "invalid control file" -#~ msgstr "არასწორი კონტროლის ფაილი" - -#, c-format -#~ msgid "invalid record offset at %X/%X" -#~ msgstr "ჩანაწერის არასწორი წანაცვლება მისამართზე %X/%X" - -#, c-format -#~ msgid "missing contrecord at %X/%X" -#~ msgstr "contrecord მისამართზე %X/%X არ არსებობს" - -#, c-format -#~ msgid "out of memory while trying to decode a record of length %u" -#~ msgstr "%u სიგრძის მქონე ჩანაწერის დეკოდირებისთვის მეხსიერება საკმარისი არაა" - -#, c-format -#~ msgid "record length %u at %X/%X too long" -#~ msgstr "ჩანაწერის სიგრძე %u მისამართზე %X/%X ძალიან გრძელია" diff --git a/src/bin/pg_test_timing/po/de.po b/src/bin/pg_test_timing/po/de.po index 14dce9f3b09..389ca9b1075 100644 --- a/src/bin/pg_test_timing/po/de.po +++ b/src/bin/pg_test_timing/po/de.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_test_timing (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-28 13:24+0000\n" -"PO-Revision-Date: 2026-05-28 19:11+0200\n" +"POT-Creation-Date: 2026-07-04 06:24+0000\n" +"PO-Revision-Date: 2026-07-04 13:00+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -41,21 +41,21 @@ msgstr "ungültige Speicheranforderungsgröße %zu * %zu\n" #: pg_test_timing.c:79 #, c-format -msgid "Usage: %s [-d DURATION] [-c CUTOFF]\n" -msgstr "Aufruf: %s [-d DAUER] [-c OBERGRENZE]\n" +msgid "Usage: %s [-c CUTOFF] [-d DURATION]\n" +msgstr "Aufruf: %s [-c OBERGRENZE] [-d DAUER]\n" -#: pg_test_timing.c:101 pg_test_timing.c:122 +#: pg_test_timing.c:100 pg_test_timing.c:121 #, c-format msgid "%s: invalid argument for option %s\n" msgstr "%s: ungültiges Argument für Option %s\n" -#: pg_test_timing.c:103 pg_test_timing.c:124 pg_test_timing.c:137 +#: pg_test_timing.c:102 pg_test_timing.c:123 pg_test_timing.c:137 #: pg_test_timing.c:149 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: pg_test_timing.c:110 pg_test_timing.c:130 +#: pg_test_timing.c:108 pg_test_timing.c:130 #, c-format msgid "%s: %s must be in range %u..%u\n" msgstr "%s: %s muss im Bereich %u..%u sein\n" @@ -115,21 +115,27 @@ msgstr "TSC-Kalibrierung konvergierte nicht.\n" msgid "" "\n" "TSC clock source will be used by default, unless timing_clock_source is set to 'system'.\n" -msgstr "\nTSC-Taktquelle wird standardmäßig verwendet, außer wenn timing_clock_source auf »system« gesetzt ist.\n" +msgstr "" +"\n" +"TSC-Taktquelle wird standardmäßig verwendet, außer wenn timing_clock_source auf »system« gesetzt ist.\n" #: pg_test_timing.c:242 #, c-format msgid "" "\n" "TSC clock source will not be used by default, unless timing_clock_source is set to 'tsc'.\n" -msgstr "\nTSC-Taktquelle wird standardmäßig nicht verwendet, außer wenn timing_clock_source auf »tsc« gesetzt ist.\n" +msgstr "" +"\n" +"TSC-Taktquelle wird standardmäßig nicht verwendet, außer wenn timing_clock_source auf »tsc« gesetzt ist.\n" #: pg_test_timing.c:245 #, c-format msgid "" "\n" "TSC clock source is not usable. Likely unable to determine TSC frequency. Are you running in an unsupported virtualized environment?\n" -msgstr "\nTSC-Taktquelle ist nicht benutzbar. Kann TSC-Frequenz wahrscheinlich nicht bestimmen. Wird eine nicht unterstützte virtualisierte Umgebung verwendet?\n" +msgstr "" +"\n" +"TSC-Taktquelle ist nicht benutzbar. Kann TSC-Frequenz wahrscheinlich nicht bestimmen. Wird eine nicht unterstützte virtualisierte Umgebung verwendet?\n" #: pg_test_timing.c:270 #, c-format diff --git a/src/bin/pg_test_timing/po/ja.po b/src/bin/pg_test_timing/po/ja.po index b20da6b9d4d..525f8363628 100644 --- a/src/bin/pg_test_timing/po/ja.po +++ b/src/bin/pg_test_timing/po/ja.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: pg_test_timing (PostgreSQL 17)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2022-07-14 10:48+0900\n" -"PO-Revision-Date: 2022-05-10 15:27+0900\n" -"Last-Translator: Michihide Hotta \n" +"POT-Creation-Date: 2026-07-03 14:13+0900\n" +"PO-Revision-Date: 2026-07-06 14:57+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" "Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" @@ -18,69 +18,217 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Poedit 1.8.13\n" -#: pg_test_timing.c:59 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format -msgid "Usage: %s [-d DURATION]\n" -msgstr "使用方法: %s [-d 期間]\n" +msgid "out of memory\n" +msgstr "メモリ不足です\n" -#: pg_test_timing.c:81 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "nullポインタは複製できません(内部エラー)\n" + +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "メモリ割り当て要求サイズ %zu + %zu が不正です\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "メモリ割り当て要求サイズ %zu * %zu が不正です\n" + +#: pg_test_timing.c:79 +#, c-format +msgid "Usage: %s [-c CUTOFF] [-d DURATION]\n" +msgstr "使用方法: %s [-c 閾値] [-d 継続時間]\n" + +#: pg_test_timing.c:100 pg_test_timing.c:121 #, c-format msgid "%s: invalid argument for option %s\n" msgstr "%s: オプション%sの引数が無効です\n" -#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109 +#: pg_test_timing.c:102 pg_test_timing.c:123 pg_test_timing.c:137 +#: pg_test_timing.c:149 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "\"%s --help\" で詳細を確認してください。\n" -#: pg_test_timing.c:90 +#: pg_test_timing.c:108 pg_test_timing.c:130 #, c-format msgid "%s: %s must be in range %u..%u\n" msgstr "%s: %sは%u..%uの範囲でなければなりません\n" -#: pg_test_timing.c:107 +#: pg_test_timing.c:147 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: コマンドライン引数が多すぎます(先頭は \"%s\")\n" -#: pg_test_timing.c:115 +#: pg_test_timing.c:154 +#, c-format +msgid "" +"Testing timing overhead for %u second.\n" +"\n" +msgid_plural "" +"Testing timing overhead for %u seconds.\n" +"\n" +msgstr[0] "タイミングのオーバーヘッドを%u秒間テストします。\n" + +#: pg_test_timing.c:209 +#, c-format +msgid "TSC frequency source: %s\n" +msgstr "TSC周波数取得元: %s\n" + +#: pg_test_timing.c:210 +#, c-format +msgid "TSC frequency in use: %d kHz\n" +msgstr "使用中のTSC周波数: %d kHz\n" + +#: pg_test_timing.c:216 +#, c-format +msgid "TSC frequency from calibration: %d kHz\n" +msgstr "校正後のTSC周波数: %d kHz\n" + +#: pg_test_timing.c:223 +#, c-format +msgid "" +"WARNING: Calibrated TSC frequency differs by %.1f%% from the " +"TSC frequency in use\n" +msgstr "" +"警告: 校正されたTSC周波数は、使用中のTSC周波数と%.1f%%異なって" +"います\n" + +#: pg_test_timing.c:225 #, c-format -msgid "Testing timing overhead for %u second.\n" -msgid_plural "Testing timing overhead for %u seconds.\n" -msgstr[0] "%u秒に対するタイミングのオーバーヘッドをテストしています。\n" +msgid "" +"HINT: Consider setting timing_clock_source to 'system'. Report " +"bugs to <%s>.\n" +msgstr "" +"ヒント: timing_clock_source を 'system' に設定することを検討し" +"てください。バグは <%s> に報告してください。\n" +"\n" + +#: pg_test_timing.c:230 +#, c-format +msgid "TSC calibration did not converge\n" +msgstr "TSCキャリブレーションが収束しませんでした\n" -#: pg_test_timing.c:151 +#: pg_test_timing.c:240 +#, c-format +msgid "" +"\n" +"TSC clock source will be used by default, unless " +"timing_clock_source is set to 'system'.\n" +msgstr "" +"\n" +"timing_clock_source が 'system'に設定されない限り、デフォルトで" +"TSCクロックソースが使用されます。\n" + +#: pg_test_timing.c:242 +#, c-format +msgid "" +"\n" +"TSC clock source will not be used by default, unless " +"timing_clock_source is set to 'tsc'.\n" +msgstr "" +"\n" +"timing_clock_source が 'tsc' に設定されない限り、デフォルトでは" +"TSCクロックソースは使用されません。\n" + +#: pg_test_timing.c:245 +#, c-format +msgid "" +"\n" +"TSC clock source is not usable. Likely unable to determine TSC " +"frequency. Are you running in an unsupported virtualized " +"environment?\n" +msgstr "" +"\n" +"TSCクロックソースは使用できません。おそらくTSC周波数を特定でき" +"ません。サポート対象外の仮想化環境で実行していませんか?\n" + +#: pg_test_timing.c:270 +#, c-format +msgid "Fast clock source: %s\n" +msgstr "高速クロックソース: %s\n" + +#: pg_test_timing.c:272 +#, c-format +msgid "System clock source: %s\n" +msgstr "システムクロックソース: %s\n" + +#: pg_test_timing.c:274 +#, c-format +msgid "Clock source: %s\n" +msgstr "クロックソース: %s\n" + +#: pg_test_timing.c:312 #, c-format msgid "Detected clock going backwards in time.\n" msgstr "クロックの時刻が逆行していることを検出しました。\n" -#: pg_test_timing.c:152 +#: pg_test_timing.c:313 #, c-format -msgid "Time warp: %d ms\n" -msgstr "逆行した時間: %d ms\n" +msgid "Time warp: % ns\n" +msgstr "逆行した時間: % ns\n" -#: pg_test_timing.c:175 +#: pg_test_timing.c:351 #, c-format -msgid "Per loop time including overhead: %0.2f ns\n" -msgstr "オーバーヘッド込みのループ時間毎: %0.2f ns\n" +msgid "Average loop time including overhead: %0.2f ns\n" +msgstr "オーバーヘッド込みの平均ループ時間: %0.2f ns\n" + +#: pg_test_timing.c:361 +msgid "<= ns" +msgstr "<= ns" -#: pg_test_timing.c:186 -msgid "< us" -msgstr "< us" +#: pg_test_timing.c:362 +msgid "ns" +msgstr "ns" -#: pg_test_timing.c:187 +#: pg_test_timing.c:363 #, no-c-format msgid "% of total" msgstr "全体の%" -#: pg_test_timing.c:188 +#: pg_test_timing.c:364 +#, no-c-format +msgid "running %" +msgstr "\"%s\"を実行中" + +#: pg_test_timing.c:365 msgid "count" msgstr "個数" -#: pg_test_timing.c:197 +#: pg_test_timing.c:375 +#, c-format +msgid "" +"WARNING: No timing measurements collected. Report this as a " +"bug to <%s>.\n" +msgstr "" +"警告: 時間計測情報が収集できませんでした。バグとして<%s>まで報" +"告してください。\n" + +#: pg_test_timing.c:389 #, c-format msgid "Histogram of timing durations:\n" -msgstr "タイミング持続時間のヒストグラム:\n" +msgstr "タイミング継続時間のヒストグラム:\n" + +#: pg_test_timing.c:409 +#, c-format +msgid "" +"\n" +"Observed timing durations up to %.4f%%:\n" +msgstr "" +"\n" +"観測された継続時間は最大で%.4f%%に達しました:\n" + +#~ msgid "" +#~ "%s: duration must be a positive integer (duration is \"%d" +#~ "\")\n" +#~ msgstr "" +#~ "%s: 持続時間は正の整数にする必要があります (持続時間は\"%d" +#~ "\")\n" -#~ msgid "%s: duration must be a positive integer (duration is \"%d\")\n" -#~ msgstr "%s: 持続時間は正の整数にする必要があります (持続時間は\"%d\")\n" +#~ msgid "< us" +#~ msgstr "< us" diff --git a/src/bin/pg_test_timing/po/ka.po b/src/bin/pg_test_timing/po/ka.po index 3c35c3d4645..ba1416f3851 100644 --- a/src/bin/pg_test_timing/po/ka.po +++ b/src/bin/pg_test_timing/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_test_timing (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-19 01:54+0000\n" -"PO-Revision-Date: 2026-05-19 04:45+0200\n" +"POT-Creation-Date: 2026-06-30 04:24+0000\n" +"PO-Revision-Date: 2026-07-02 06:16+0200\n" "Last-Translator: Temuri Doghonadze " "\n" "Language-Team: Georgian \n" @@ -45,21 +45,21 @@ msgstr "" #: pg_test_timing.c:79 #, c-format -msgid "Usage: %s [-d DURATION] [-c CUTOFF]\n" -msgstr "გამოყენება: %s [-d ხანგრძლივობა] [-c ამოჭრა]\n" +msgid "Usage: %s [-c CUTOFF] [-d DURATION]\n" +msgstr "გამოყენება: %s [-c ამოჭრა] [-d ხანგრძლივობა]\n" -#: pg_test_timing.c:101 pg_test_timing.c:122 +#: pg_test_timing.c:100 pg_test_timing.c:121 #, c-format msgid "%s: invalid argument for option %s\n" msgstr "%s: არასწორი არგუმენტი პარამეტრისთვის%s\n" -#: pg_test_timing.c:103 pg_test_timing.c:124 pg_test_timing.c:137 +#: pg_test_timing.c:102 pg_test_timing.c:123 pg_test_timing.c:137 #: pg_test_timing.c:149 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "მეტი ინფორმაციისთვის სცადეთ '%s --help'.\n" -#: pg_test_timing.c:110 pg_test_timing.c:130 +#: pg_test_timing.c:108 pg_test_timing.c:130 #, c-format msgid "%s: %s must be in range %u..%u\n" msgstr "%s: %s-ის დიაპაზონია %u..%u\n" @@ -230,6 +230,3 @@ msgid "" msgstr "" "\n" "დაკვირვებულია ათვლის ხანგრძლივობები მნიშვნელობამდე %.4f%%:\n" - -#~ msgid "< us" -#~ msgstr "< მკწმ" diff --git a/src/bin/pg_upgrade/po/de.po b/src/bin/pg_upgrade/po/de.po index 5d7563df66c..2b11885a3f6 100644 --- a/src/bin/pg_upgrade/po/de.po +++ b/src/bin/pg_upgrade/po/de.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_upgrade (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-28 13:23+0000\n" -"PO-Revision-Date: 2026-05-28 19:06+0200\n" +"POT-Creation-Date: 2026-07-04 06:24+0000\n" +"PO-Revision-Date: 2026-07-04 13:01+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -60,12 +60,12 @@ msgstr "Fehler beim Nachschlagen des Benutzernamens: Fehlercode %lu" msgid "options %s and %s cannot be used together" msgstr "Optionen %s und %s können nicht zusammen verwendet werden" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "Argument des Shell-Befehls enthält Newline oder Carriage Return: »%s«\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "Datenbankname enthält Newline oder Carriage Return: »%s«\n" @@ -784,12 +784,12 @@ msgstr "»wal_level« muss »replica« oder »logical« sein, aber es ist auf » #: check.c:2289 #, c-format -msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots on the old cluster plus one additional slot required for retaining conflict detection information (%d)" +msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots in the old cluster plus one additional slot required for retaining conflict detection information (%d)" msgstr "»max_replication_slots« (%d) muss größer als oder gleich der Anzahl der logischen Replikations-Slots im alten Cluster plus einen für Konflikterkennungsinformationen (%d) sein" #: check.c:2295 #, c-format -msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots (%d) on the old cluster" +msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots (%d) in the old cluster" msgstr "»max_replication_slots« (%d) muss größer als oder gleich der Anzahl der logischen Replikations-Slots (%d) im alten Cluster sein" #: check.c:2327 @@ -799,7 +799,7 @@ msgstr "Prüfe Konfiguration für Subskriptionen im neuen Cluster" #: check.c:2339 #, c-format -msgid "\"max_active_replication_origins\" (%d) must be greater than or equal to the number of subscriptions (%d) on the old cluster" +msgid "\"max_active_replication_origins\" (%d) must be greater than or equal to the number of subscriptions (%d) in the old cluster" msgstr "»max_active_replication_origins« (%d) muss größer als oder gleich der Anzahl der Subskriptionen (%d) im alten Cluster sein" #: check.c:2361 @@ -851,7 +851,7 @@ msgstr "Prüfe Namen der Datenbanken, Rollen und Tablespaces" #: check.c:2638 #, c-format msgid "" -"Your installation contains databases, roles, or tablespace with names\n" +"Your installation contains databases, roles, or tablespaces with names\n" "with invalid characters (newline or carriage return). To fix this,\n" "rename these objects.\n" "A list of all objects with invalid names is in the file:\n" diff --git a/src/bin/pg_upgrade/po/ja.po b/src/bin/pg_upgrade/po/ja.po index 0b2803a3900..58a23d1fed2 100644 --- a/src/bin/pg_upgrade/po/ja.po +++ b/src/bin/pg_upgrade/po/ja.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_upgrade (PostgreSQL 19)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-15 13:37+0900\n" -"PO-Revision-Date: 2026-05-15 16:38+0900\n" +"POT-Creation-Date: 2026-07-03 14:13+0900\n" +"PO-Revision-Date: 2026-07-06 15:03+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" @@ -65,12 +65,12 @@ msgstr "ユーザー名の参照に失敗: エラーコード %lu" msgid "options %s and %s cannot be used together" msgstr "オプション %s と %s は同時には使用できません" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "シェルコマンドの引数に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "データベース名に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" @@ -95,11 +95,11 @@ msgstr "ファイル\"%s\"は大きすぎます" msgid "could not parse version file \"%s\"" msgstr "バージョンファイル\"%s\"をパースできませんでした" -#: check.c:117 +#: check.c:116 msgid "Checking for system-defined composite types in user tables" msgstr "ユーザーテーブル内のシステム定義複合型を確認しています" -#: check.c:124 +#: check.c:123 msgid "" "Your installation contains system-defined composite types in user tables.\n" "These type OIDs are not stable across PostgreSQL versions,\n" @@ -111,28 +111,11 @@ msgstr "" "このクラスタは現時点ではアップグレードできません。問題の列を削除したのちに\n" "アップグレードを再実行することができます。\n" -#: check.c:138 -msgid "Checking for incompatible \"line\" data type" -msgstr "非互換の \"line\" データ型を確認しています" - -#: check.c:143 -msgid "" -"Your installation contains the \"line\" data type in user tables.\n" -"This data type changed its internal and input/output format\n" -"between your old and new versions so this\n" -"cluster cannot currently be upgraded. You can\n" -"drop the problem columns and restart the upgrade.\n" -msgstr "" -"このクラスタでは、ユーザーテーブルに\"line\"データ型が含まれています。\n" -"このデータ型は新旧のクラスタ間で内部形式および入出力フォーマットが\n" -"変更されているため、このクラスタは現時点ではアップグレードできません。\n" -"問題の列を削除したのちにアップグレードを再実行できます。\n" - -#: check.c:160 +#: check.c:139 msgid "Checking for reg* data types in user tables" msgstr "ユーザーテーブル内の reg * データ型をチェックしています" -#: check.c:188 +#: check.c:167 msgid "" "Your installation contains one of the reg* data types in user tables.\n" "These data types reference system OIDs that are not preserved by\n" @@ -144,11 +127,11 @@ msgstr "" "保存されないため、現時点ではこのクラスタをアップグレードすることはできません。\n" "問題の列を削除したのち、アップグレードを再実行できます。\n" -#: check.c:200 +#: check.c:179 msgid "Checking for incompatible \"aclitem\" data type" msgstr "非互換の\"aclitem\"データ型を確認しています" -#: check.c:205 +#: check.c:184 msgid "" "Your installation contains the \"aclitem\" data type in user tables.\n" "The internal format of \"aclitem\" changed in PostgreSQL version 16\n" @@ -160,27 +143,11 @@ msgstr "" "現時点ではこのクラスタをアップグレードすることはできません。\n" "問題の列を削除したのち、アップグレードを再実行できます。\n" -#: check.c:224 -msgid "Checking for invalid \"unknown\" user columns" -msgstr "無効な\"unknown\"ユーザー列をチェックしています" - -#: check.c:229 -msgid "" -"Your installation contains the \"unknown\" data type in user tables.\n" -"This data type is no longer allowed in tables, so this cluster\n" -"cannot currently be upgraded. You can drop the problem columns\n" -"and restart the upgrade.\n" -msgstr "" -"このクラスタでは、ユーザーテーブルに \"unknown\" データ型が含まれています。\n" -"このデータ型はもはやテーブル内では利用できないため、このクラスタは現時点\n" -"ではアップグレードできません。問題の列を削除したのち、アップグレードを\n" -"再実行できます。\n" - -#: check.c:246 +#: check.c:201 msgid "Checking for invalid \"sql_identifier\" user columns" msgstr "無効な\"sql_identifier\"ユーザー列を確認しています" -#: check.c:251 +#: check.c:206 msgid "" "Your installation contains the \"sql_identifier\" data type in user tables.\n" "The on-disk format for this data type has changed, so this\n" @@ -192,27 +159,11 @@ msgstr "" "アップグレードできません。問題のある列を削除した後にアップグレードを再実行する\n" "ことができます。\n" -#: check.c:262 -msgid "Checking for incompatible \"jsonb\" data type in user tables" -msgstr "ユーザーテーブル内の非互換の\"jsonb\"データ型を確認しています" - -#: check.c:267 -msgid "" -"Your installation contains the \"jsonb\" data type in user tables.\n" -"The internal format of \"jsonb\" changed during 9.4 beta so this\n" -"cluster cannot currently be upgraded. You can drop the problem \n" -"columns and restart the upgrade.\n" -msgstr "" -"このクラスタでは、ユーザーテーブルに\"jsonb\"データ型が含まれています。\n" -"この型の内部フォーマットは9.4ベータの間に変更されているため、現時点ではこの\n" -"クラスタをアップグレードすることはできません。 問題の列を削除したのち、\n" -"アップグレードを再実行できます。\n" - -#: check.c:279 +#: check.c:217 msgid "Checking for removed \"abstime\" data type in user tables" msgstr "ユーザーテーブル内の削除された\"abstime\"データ型を確認しています" -#: check.c:284 +#: check.c:222 msgid "" "Your installation contains the \"abstime\" data type in user tables.\n" "The \"abstime\" type has been removed in PostgreSQL version 12,\n" @@ -226,11 +177,11 @@ msgstr "" "問題の列を削除するか、他のデータ型に変更した後にアップグレードを\n" "再実行できます。\n" -#: check.c:292 +#: check.c:230 msgid "Checking for removed \"reltime\" data type in user tables" msgstr "ユーザーテーブル中内の削除された\"reltime\"データ型を確認しています" -#: check.c:297 +#: check.c:235 msgid "" "Your installation contains the \"reltime\" data type in user tables.\n" "The \"reltime\" type has been removed in PostgreSQL version 12,\n" @@ -243,11 +194,11 @@ msgstr "" "このクラスタは現時点ではアップグレードできません。問題の列を削除するか、\n" "他のデータ型に変更した後にアップグレードを再実行できます。\n" -#: check.c:305 +#: check.c:243 msgid "Checking for removed \"tinterval\" data type in user tables" msgstr "ユーザーテーブル内の削除された\"tinterval\"データ型を確認しています" -#: check.c:310 +#: check.c:248 msgid "" "Your installation contains the \"tinterval\" data type in user tables.\n" "The \"tinterval\" type has been removed in PostgreSQL version 12,\n" @@ -260,35 +211,35 @@ msgstr "" "このクラスタは現時点ではアップグレードできません。問題の列を削除するか、\n" "他のデータ型に変更した後にアップグレードを再実行できます。\n" -#: check.c:426 +#: check.c:364 #, c-format msgid "failed check: %s" msgstr "問題を検出した項目: %s" -#: check.c:429 +#: check.c:367 msgid "A list of the problem columns is in the file:" msgstr "問題の列の一覧は以下のファイルにあります:" -#: check.c:435 check.c:1070 check.c:1221 check.c:1285 check.c:1359 check.c:1445 -#: check.c:1533 check.c:1663 check.c:1732 check.c:1817 check.c:1906 -#: check.c:1950 check.c:2030 check.c:2380 check.c:2399 check.c:2415 -#: check.c:2459 check.c:2512 check.c:2625 file.c:378 file.c:415 function.c:214 -#: option.c:519 slru_io.c:113 version.c:97 version.c:178 +#: check.c:373 check.c:976 check.c:1127 check.c:1191 check.c:1265 check.c:1351 +#: check.c:1439 check.c:1567 check.c:1636 check.c:1721 check.c:1797 +#: check.c:1877 check.c:2227 check.c:2246 check.c:2262 check.c:2306 +#: check.c:2359 check.c:2472 file.c:214 file.c:251 function.c:214 option.c:519 +#: slru_io.c:113 version.c:51 #, c-format msgid "could not open file \"%s\": %m" msgstr "ファイル\"%s\"をオープンできませんでした: %m" -#: check.c:477 +#: check.c:415 #, c-format msgid "Checking data type usage" msgstr "データ型の使用を確認しています" -#: check.c:531 +#: check.c:469 #, c-format msgid "Data type checks failed: %s" msgstr "問題を検出したデータ型確認項目: %s" -#: check.c:580 +#: check.c:518 #, c-format msgid "" "Performing Consistency Checks on Old Live Server\n" @@ -297,7 +248,7 @@ msgstr "" "元の実行中サーバーの一貫性チェックを実行しています。\n" "--------------------------------------------------" -#: check.c:586 +#: check.c:524 #, c-format msgid "" "Performing Consistency Checks\n" @@ -306,12 +257,7 @@ msgstr "" "整合性チェックを実行しています。\n" "-----------------------------" -#: check.c:786 -#, c-format -msgid "Swap mode can only upgrade clusters from PostgreSQL version %s and later." -msgstr "スワップモードはPostgreSQL %s以降のバージョンからのアップグレードのみ可能です。" - -#: check.c:809 +#: check.c:719 #, c-format msgid "" "\n" @@ -320,7 +266,7 @@ msgstr "" "\n" "* クラスタは互換性があります *" -#: check.c:817 +#: check.c:727 #, c-format msgid "" "\n" @@ -331,7 +277,7 @@ msgstr "" "この後pg_upgradeが失敗した場合は、続ける前に新しいクラスタを\n" "initdbで再作成する必要があります。" -#: check.c:858 +#: check.c:764 #, c-format msgid "" "Some statistics are not transferred by pg_upgrade.\n" @@ -344,7 +290,7 @@ msgstr "" " %s/vacuumdb %s--all --analyze-in-stages --missing-stats-only\n" " %s/vacuumdb %s--all --analyze-only" -#: check.c:867 +#: check.c:773 #, c-format msgid "" "Running this script will delete the old cluster's data files:\n" @@ -353,7 +299,7 @@ msgstr "" "このスクリプトを実行すると、旧クラスタのデータファイルが削除されます:\n" " %s" -#: check.c:872 +#: check.c:778 #, c-format msgid "" "Could not create a script to delete the old cluster's data files\n" @@ -366,62 +312,62 @@ msgstr "" "ファイルを削除するためのスクリプトを作成できませんでした。 古い\n" "クラスタの内容は手動で削除する必要があります。" -#: check.c:884 +#: check.c:790 #, c-format msgid "Checking cluster versions" msgstr "クラスタのバージョンを確認しています" -#: check.c:896 +#: check.c:802 #, c-format msgid "This utility can only upgrade from PostgreSQL version %s and later." msgstr "このユーティリティではPostgreSQLバージョン%s以降のバージョンからのみアップグレードできます。" -#: check.c:901 +#: check.c:807 #, c-format msgid "This utility can only upgrade to PostgreSQL version %s." msgstr "このユーティリティは、PostgreSQLバージョン%sにのみアップグレードできます。" -#: check.c:910 +#: check.c:816 #, c-format msgid "This utility cannot be used to downgrade to older major PostgreSQL versions." msgstr "このユーティリティは PostgreSQL の過去のメジャーバージョンにダウングレードする用途では使用できません。" -#: check.c:915 +#: check.c:821 #, c-format msgid "Old cluster data and binary directories are from different major versions." msgstr "旧クラスタのデータとバイナリのディレクトリは異なるメジャーバージョンのものです。" -#: check.c:918 +#: check.c:824 #, c-format msgid "New cluster data and binary directories are from different major versions." msgstr "新クラスタのデータとバイナリのディレクトリは異なるメジャーバージョンのものです。" -#: check.c:929 +#: check.c:835 #, c-format msgid "The option %s cannot be used for upgrades from PostgreSQL %s and later." msgstr "PostgreSQL %2$s以降からのアップグレードでは %1$s オプションは使用できません。" -#: check.c:945 +#: check.c:851 #, c-format msgid "When checking a live server, the old and new port numbers must be different." msgstr "稼働中のサーバーをチェックする場合、新旧のポート番号が異なっている必要があります。" -#: check.c:965 +#: check.c:871 #, c-format msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"" msgstr "新クラスタのデータベース\"%s\"が空ではありません: リレーション\"%s.%s\"が見つかりました" -#: check.c:988 +#: check.c:894 #, c-format msgid "Checking new cluster tablespace directories" msgstr "新しいクラスタのテーブルスペースディレクトリを確認しています" -#: check.c:999 +#: check.c:905 #, c-format msgid "new cluster tablespace directory already exists: \"%s\"" msgstr "新しいクラスタのテーブル空間ディレクトリはすでに存在します: \"%s\"" -#: check.c:1033 +#: check.c:939 #, c-format msgid "" "\n" @@ -430,7 +376,7 @@ msgstr "" "\n" "警告: 新データディレクトリが旧データディレクトリ、つまり %sの中にあってはなりません" -#: check.c:1057 +#: check.c:963 #, c-format msgid "" "\n" @@ -439,54 +385,54 @@ msgstr "" "\n" "警告: ユーザー定義テーブル空間の場所がデータディレクトリ、つまり %s の中にあってはなりません。" -#: check.c:1067 +#: check.c:973 #, c-format msgid "Creating script to delete old cluster" msgstr "旧クラスタを削除するスクリプトを作成しています" -#: check.c:1095 +#: check.c:1001 #, c-format msgid "could not add execute permission to file \"%s\": %m" msgstr "ファイル\"%s\"に実行権限を追加できませんでした: %m" -#: check.c:1115 +#: check.c:1021 #, c-format msgid "Checking database user is the install user" msgstr "データベースユーザーがインストールユーザーかどうかをチェックしています" -#: check.c:1131 +#: check.c:1037 #, c-format msgid "database user \"%s\" is not the install user" msgstr "データベースユーザー\"%s\"がインストールユーザーではありません" -#: check.c:1142 +#: check.c:1048 #, c-format msgid "could not determine the number of users" msgstr "ユーザー数を特定できませんでした" -#: check.c:1150 +#: check.c:1056 #, c-format msgid "Only the install user can be defined in the new cluster." msgstr "新クラスタ内で定義できるのはインストールユーザーのみです。" -#: check.c:1180 +#: check.c:1086 #, c-format msgid "Checking database connection settings" msgstr "データベース接続の設定を確認しています" -#: check.c:1208 +#: check.c:1114 #, c-format msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false" msgstr "template0 には接続を許可してはなりません。すなわち、pg_database.datallowconn は false である必要があります" -#: check.c:1235 check.c:1296 check.c:1411 check.c:1504 check.c:1629 -#: check.c:1703 check.c:1786 check.c:1861 check.c:1919 check.c:1999 -#: check.c:2428 check.c:2568 check.c:2637 function.c:235 +#: check.c:1141 check.c:1202 check.c:1317 check.c:1410 check.c:1533 +#: check.c:1607 check.c:1690 check.c:1765 check.c:1846 check.c:2275 +#: check.c:2415 check.c:2484 function.c:235 #, c-format msgid "fatal" msgstr "致命的" -#: check.c:1236 +#: check.c:1142 #, c-format msgid "" "All non-template0 databases must allow connections, i.e. their\n" @@ -505,12 +451,12 @@ msgstr "" "一覧が以下のファイルにあります:\n" " %s" -#: check.c:1263 +#: check.c:1169 #, c-format msgid "Checking for unsupported encodings" msgstr "非サポートエンコーディングを確認しています" -#: check.c:1297 +#: check.c:1203 #, c-format msgid "" "Your installation contains databases using encodings that are\n" @@ -524,27 +470,27 @@ msgstr "" "データベースの一覧があります:\n" " %s" -#: check.c:1319 +#: check.c:1225 #, c-format msgid "Checking for prepared transactions" msgstr "準備済みトランザクションをチェックしています" -#: check.c:1328 +#: check.c:1234 #, c-format msgid "The source cluster contains prepared transactions" msgstr "移行元クラスタに準備済みトランザクションがあります" -#: check.c:1330 +#: check.c:1236 #, c-format msgid "The target cluster contains prepared transactions" msgstr "移行先クラスタに準備済みトランザクションがあります" -#: check.c:1387 +#: check.c:1293 #, c-format msgid "Checking for contrib/isn with bigint-passing mismatch" msgstr "bigint を渡す際にミスマッチが発生する contrib/isn をチェックしています" -#: check.c:1412 +#: check.c:1318 #, c-format msgid "" "Your installation contains \"contrib/isn\" functions which rely on the\n" @@ -564,12 +510,12 @@ msgstr "" "問題のある関数の一覧は以下のファイルにあります:\n" " %s" -#: check.c:1489 +#: check.c:1395 #, c-format msgid "Checking for user-defined postfix operators" msgstr "ユーザー定義の後置演算子を確認しています" -#: check.c:1505 +#: check.c:1411 #, c-format msgid "" "Your installation contains user-defined postfix operators, which are not\n" @@ -584,12 +530,12 @@ msgstr "" "以下のファイルにユーザー定義後置演算子の一覧があります:\n" " %s" -#: check.c:1557 +#: check.c:1463 #, c-format msgid "Checking for incompatible polymorphic functions" msgstr "非互換の多態関数を確認しています" -#: check.c:1630 +#: check.c:1534 #, c-format msgid "" "Your installation contains user-defined objects that refer to internal\n" @@ -607,12 +553,12 @@ msgstr "" "問題となるオブジェクトの一覧は以下のファイルにあります:\n" " %s" -#: check.c:1688 +#: check.c:1592 #, c-format msgid "Checking for tables WITH OIDS" msgstr "WITH OIDS宣言されたテーブルをチェックしています" -#: check.c:1704 +#: check.c:1608 #, c-format msgid "" "Your installation contains tables declared WITH OIDS, which is not\n" @@ -627,12 +573,12 @@ msgstr "" "以下のファイルにこの問題を抱えるテーブルの一覧があります:\n" " %s" -#: check.c:1760 +#: check.c:1664 #, c-format msgid "Checking for not-null constraint inconsistencies" msgstr "非NULL制約の整合性を確認しています" -#: check.c:1787 +#: check.c:1691 #, c-format msgid "" "Your installation contains inconsistent NOT NULL constraints.\n" @@ -651,12 +597,12 @@ msgstr "" "以下のファイルにリストされている各列に対して実行することで解消できます:\n" " %s" -#: check.c:1846 +#: check.c:1750 #, c-format msgid "Checking for uses of gist_inet_ops/gist_cidr_ops" msgstr "gist_inet_ops/gist_cidr_ops が使用されているかどうかを確認しています" -#: check.c:1862 +#: check.c:1766 #, c-format msgid "" "Your installation contains indexes that use btree_gist extension's\n" @@ -673,33 +619,12 @@ msgstr "" "この問題を持つインデックスの一覧は以下のファイルにあります:\n" " %s" -#: check.c:1889 -#, c-format -msgid "Checking for roles starting with \"pg_\"" -msgstr "'pg_' で始まるロールをチェックしています" - -#: check.c:1920 -#, c-format -msgid "" -"Your installation contains roles starting with \"pg_\".\n" -"\"pg_\" is a reserved prefix for system roles. The cluster\n" -"cannot be upgraded until these roles are renamed.\n" -"A list of roles starting with \"pg_\" is in the file:\n" -" %s" -msgstr "" -"このクラスタには\"pg_\"で始まるロールが含まれています。\n" -"\"pg_\"はシステムロールのために予約されている接頭辞で、これらのロールの\n" -"名前を変更しないとpg_upgradeではこのクラスタをアップグレードすることは\n" -"できません。\n" -"\"pg_\"で始まるロールの一覧は以下のファイルにあります:\n" -" %s" - -#: check.c:1971 +#: check.c:1818 #, c-format msgid "Checking for user-defined encoding conversions" msgstr "ユーザー定義のエンコーディング変換を確認しています" -#: check.c:2000 +#: check.c:1847 #, c-format msgid "" "Your installation contains user-defined encoding conversions.\n" @@ -717,17 +642,17 @@ msgstr "" "ユーザー定義のエンコーディング変換の一覧は以下のファイルにあります:\n" " %s" -#: check.c:2085 +#: check.c:1932 #, c-format msgid "Checking for objects affected by Unicode update" msgstr "Unicodeの更新によって影響を受けるオブジェクトを確認しています" -#: check.c:2184 version.c:139 +#: check.c:2031 #, c-format msgid "warning" msgstr "警告" -#: check.c:2185 +#: check.c:2032 #, c-format msgid "" "Your installation contains relations that might be affected by a new version of Unicode.\n" @@ -738,62 +663,62 @@ msgstr "" "影響を受ける可能性があるリレーションの一覧は以下のファイルにあります:\n" " %s" -#: check.c:2235 +#: check.c:2082 #, c-format msgid "Checking new cluster replication slots" msgstr "新しいクラスタのレプリケーションスロットを確認しています" -#: check.c:2247 +#: check.c:2094 #, c-format msgid "could not count the number of replication slots" msgstr "レプリケーションスロットの数を数えられませんでした" -#: check.c:2257 +#: check.c:2104 #, c-format msgid "expected 0 logical replication slots but found %d" msgstr "論理レプリケーションスロット数は0であることを期待していましたが、%d個ありました" -#: check.c:2266 +#: check.c:2113 #, c-format msgid "replication slot \"%s\" already exists in the new cluster" msgstr "レプリケーションスロット\"%s\"は新シクラスタにすでに存在します" -#: check.c:2276 check.c:2335 +#: check.c:2123 check.c:2182 #, c-format msgid "could not determine parameter settings on new cluster" msgstr "新クラスタ上のパラメータ設定を決定できませんでした" -#: check.c:2282 +#: check.c:2129 #, c-format msgid "\"wal_level\" must be \"replica\" or \"logical\" but is set to \"%s\"" msgstr "\"wal_level\"は\"replica\"または\"logical\"でなければなりませんが、\"%s\"に設定されています" -#: check.c:2289 +#: check.c:2136 #, c-format -msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots on the old cluster plus one additional slot required for retaining conflict detection information (%d)" -msgstr "\"max_replication_slots\" (%d) は、旧クラスタの論理レプリケーションスロット数に加えて、衝突検出のために必要な1つの追加スロットを含む合計(%d)以上である必要があります" +msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots in the old cluster plus one additional slot required for retaining conflict detection information (%d)" +msgstr "\"max_replication_slots\" (%d) は、旧クラスタの論理レプリケーションスロット数に、衝突検出情報を保持するために必要な追加スロット1つを加えた合計(%d)以上である必要があります。" -#: check.c:2295 +#: check.c:2142 #, c-format -msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots (%d) on the old cluster" -msgstr "\"max_replication_slots\" (%d) は旧クラスタにおける論理レプリケーションスロットの数(%d)以上でなければなりません" +msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots (%d) in the old cluster" +msgstr "\"max_replication_slots\" (%d) は旧クラスタの論理レプリケーションスロットの数(%d)以上でなければなりません" -#: check.c:2327 +#: check.c:2174 #, c-format msgid "Checking new cluster configuration for subscriptions" msgstr "新しいクラスタでのサブスクリプション構成を確認しています" -#: check.c:2339 +#: check.c:2186 #, c-format -msgid "\"max_active_replication_origins\" (%d) must be greater than or equal to the number of subscriptions (%d) on the old cluster" -msgstr "\"max_active_replication_origins\" (%d) は旧クラスタにおけるサブスクリプションの数(%d)以上でなければなりません" +msgid "\"max_active_replication_origins\" (%d) must be greater than or equal to the number of subscriptions (%d) in the old cluster" +msgstr "\"max_active_replication_origins\" (%d) は旧クラスタのサブスクリプションの数(%d)以上でなければなりません" -#: check.c:2361 +#: check.c:2208 #, c-format msgid "Checking logical replication slots" msgstr "論理レプリケーションスロットを確認しています" -#: check.c:2429 +#: check.c:2276 #, c-format msgid "" "Your installation contains logical replication slots that cannot be upgraded.\n" @@ -808,12 +733,12 @@ msgstr "" "問題のある列の一覧は、以下のファイルにあります: \n" " %s" -#: check.c:2487 +#: check.c:2334 #, c-format msgid "Checking subscription state" msgstr "サブスクリプションの状態を確認しています" -#: check.c:2569 +#: check.c:2416 #, c-format msgid "" "Your installation contains subscriptions without origin or having relations not in i (initialize) or r (ready) state.\n" @@ -827,15 +752,15 @@ msgstr "" "問題のあるサブスクリプションの一覧は、以下のファイルにあります: \n" " %s" -#: check.c:2595 +#: check.c:2442 #, c-format msgid "Checking names of databases, roles, and tablespaces" msgstr "データベース、ロール、およびテーブルスペースの名前を確認しています" -#: check.c:2638 +#: check.c:2485 #, c-format msgid "" -"Your installation contains databases, roles, or tablespace with names\n" +"Your installation contains databases, roles, or tablespaces with names\n" "with invalid characters (newline or carriage return). To fix this,\n" "rename these objects.\n" "A list of all objects with invalid names is in the file:\n" @@ -847,189 +772,189 @@ msgstr "" "以下のファイルに、不正な名前を持つすべてのオブジェクトの一覧があります:\n" " %s" -#: controldata.c:134 controldata.c:204 +#: controldata.c:127 controldata.c:192 #, c-format msgid "could not get control data using %s: %m" msgstr "%sで制御情報が取得できませんでした: %m" -#: controldata.c:144 +#: controldata.c:137 #, c-format msgid "%d: database cluster state problem" msgstr "%d: データベースクラスタの状態異常" -#: controldata.c:163 +#: controldata.c:156 #, c-format msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary." msgstr "移行元クラスタはリカバリモード中にシャットダウンされています。アップグレードをするにはドキュメントの通りに \"rsync\" を実行するか、プライマリとしてシャットダウンしてください。" -#: controldata.c:165 +#: controldata.c:158 #, c-format msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary." msgstr "移行先クラスタはリカバリモード中にシャットダウンされています。アップグレードをするにはドキュメントの通りに \"rsync\" を実行するか、プライマリとしてシャットダウンしてください。" -#: controldata.c:170 +#: controldata.c:163 #, c-format msgid "The source cluster was not shut down cleanly, state reported as: \"%s\"" msgstr "移行元クラスタはクリーンにシャットダウンされていません、状態は以下のように報告されています: \"%s\"" -#: controldata.c:172 +#: controldata.c:165 #, c-format msgid "The target cluster was not shut down cleanly, state reported as: \"%s\"" msgstr "移行先クラスタはクリーンにシャットダウンされていません、状態は以下のように報告されています: \"%s\"" -#: controldata.c:180 controldata.c:531 +#: controldata.c:173 controldata.c:468 #, c-format msgid "could not get control data using %s: %s" msgstr "%s で制御情報が取得できませんでした。: %s" -#: controldata.c:186 +#: controldata.c:179 #, c-format msgid "The source cluster lacks cluster state information:" msgstr "移行元クラスタにクラスタ状態情報がありません:" -#: controldata.c:188 +#: controldata.c:181 #, c-format msgid "The target cluster lacks cluster state information:" msgstr "移行先クラスタにクラスタ状態情報がありません:" -#: controldata.c:218 dump.c:54 exec.c:119 pg_upgrade.c:630 pg_upgrade.c:670 -#: pg_upgrade.c:1048 relfilenumber.c:605 server.c:34 util.c:337 +#: controldata.c:199 dump.c:54 exec.c:110 pg_upgrade.c:630 pg_upgrade.c:670 +#: pg_upgrade.c:1006 relfilenumber.c:588 server.c:34 util.c:337 #, c-format msgid "%s" msgstr "%s" -#: controldata.c:225 +#: controldata.c:206 #, c-format msgid "%d: pg_resetwal problem" msgstr "%d: pg_resetwal で問題発生" -#: controldata.c:235 controldata.c:245 controldata.c:256 controldata.c:267 -#: controldata.c:278 controldata.c:297 controldata.c:308 controldata.c:319 -#: controldata.c:330 controldata.c:341 controldata.c:352 controldata.c:363 -#: controldata.c:366 controldata.c:370 controldata.c:380 controldata.c:392 -#: controldata.c:403 controldata.c:414 controldata.c:425 controldata.c:436 -#: controldata.c:447 controldata.c:458 controldata.c:469 controldata.c:480 -#: controldata.c:491 controldata.c:502 controldata.c:513 controldata.c:522 +#: controldata.c:216 controldata.c:226 controldata.c:234 controldata.c:245 +#: controldata.c:256 controldata.c:267 controldata.c:278 controldata.c:289 +#: controldata.c:300 controldata.c:303 controldata.c:307 controldata.c:317 +#: controldata.c:329 controldata.c:340 controldata.c:351 controldata.c:362 +#: controldata.c:373 controldata.c:384 controldata.c:395 controldata.c:406 +#: controldata.c:417 controldata.c:428 controldata.c:439 controldata.c:450 +#: controldata.c:459 #, c-format msgid "%d: controldata retrieval problem" msgstr "%d: 制御情報の取得で問題発生" -#: controldata.c:619 +#: controldata.c:538 #, c-format msgid "The source cluster lacks some required control information:" msgstr "移行元クラスタに必要な制御情報の一部がありません:" -#: controldata.c:622 +#: controldata.c:541 #, c-format msgid "The target cluster lacks some required control information:" msgstr "移行先クラスタに必要な制御情報の一部がありません:" -#: controldata.c:625 +#: controldata.c:544 #, c-format msgid " checkpoint next XID" msgstr " チェックポイントにおける次のXID" -#: controldata.c:628 +#: controldata.c:547 #, c-format msgid " latest checkpoint next OID" msgstr " 最新のチェックポイントにおける次のOID" -#: controldata.c:631 +#: controldata.c:550 #, c-format msgid " latest checkpoint next MultiXactId" msgstr " 最新のチェックポイントにおける次のMultiXactId" -#: controldata.c:635 +#: controldata.c:553 #, c-format msgid " latest checkpoint oldest MultiXactId" msgstr " 最新のチェックポイントにおける最古のMultiXactId" -#: controldata.c:638 +#: controldata.c:556 #, c-format msgid " latest checkpoint oldestXID" msgstr " 最新のチェックポイントにおける最古のXID" -#: controldata.c:641 +#: controldata.c:559 #, c-format msgid " latest checkpoint next MultiXactOffset" msgstr " 最新のチェックポイントにおける次のMultiXactOffset" -#: controldata.c:644 +#: controldata.c:562 #, c-format msgid " first WAL segment after reset" msgstr " リセット後の最初のWALセグメント" -#: controldata.c:647 +#: controldata.c:565 #, c-format msgid " float8 argument passing method" msgstr " float8引数の引き渡し方法" -#: controldata.c:650 +#: controldata.c:568 #, c-format msgid " maximum alignment" msgstr " 最大アラインメント" -#: controldata.c:653 +#: controldata.c:571 #, c-format msgid " block size" msgstr " ブロックサイズ" -#: controldata.c:656 +#: controldata.c:574 #, c-format msgid " large relation segment size" msgstr " 大きなリレーションセグメントのサイズ" -#: controldata.c:659 +#: controldata.c:577 #, c-format msgid " WAL block size" msgstr " WALのブロックサイズ" -#: controldata.c:662 +#: controldata.c:580 #, c-format msgid " WAL segment size" msgstr " WALのセグメントサイズ" -#: controldata.c:665 +#: controldata.c:583 #, c-format msgid " maximum identifier length" msgstr " 識別子の最大長" -#: controldata.c:668 +#: controldata.c:586 #, c-format msgid " maximum number of indexed columns" msgstr " インデックス対象カラムの最大数" -#: controldata.c:671 +#: controldata.c:589 #, c-format msgid " maximum TOAST chunk size" msgstr " 最大のTOASTチャンクサイズ" -#: controldata.c:675 +#: controldata.c:592 #, c-format msgid " large-object chunk size" msgstr " ラージオブジェクトのチャンクサイズ" -#: controldata.c:678 +#: controldata.c:595 #, c-format msgid " dates/times are integers?" msgstr " 日付/時間が整数?" -#: controldata.c:682 +#: controldata.c:599 #, c-format msgid " data checksum version" msgstr " データチェックサムのバージョン" -#: controldata.c:686 +#: controldata.c:603 #, c-format msgid " default char signedness" msgstr " デフォルトのchar型の符号の有無" -#: controldata.c:688 +#: controldata.c:605 #, c-format msgid "Cannot continue without required control information, terminating" msgstr "必要な制御情報がないので続行できません。終了します" -#: controldata.c:703 +#: controldata.c:620 #, c-format msgid "" "old and new pg_controldata alignments are invalid or do not match.\n" @@ -1038,84 +963,84 @@ msgstr "" "新旧のpg_controldataのアラインメントが不正であるかかまたは一致しません\n" "一方のクラスタが32ビットで、他方が64ビットである可能性が高いです" -#: controldata.c:707 +#: controldata.c:624 #, c-format msgid "old and new pg_controldata block sizes are invalid or do not match" msgstr "新旧の pg_controldata におけるブロックサイズが有効でないかまたは一致しません" -#: controldata.c:710 +#: controldata.c:627 #, c-format msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match" msgstr "新旧の pg_controldata におけるリレーションの最大セグメントサイズが有効でないか一致しません" -#: controldata.c:713 +#: controldata.c:630 #, c-format msgid "old and new pg_controldata WAL block sizes are invalid or do not match" msgstr "新旧の pg_controldata における WAL ブロックサイズが有効でないか一致しません" -#: controldata.c:716 +#: controldata.c:633 #, c-format msgid "old and new pg_controldata WAL segment sizes are invalid or do not match" msgstr "新旧の pg_controldata におけるWALセグメントサイズが有効でないか一致しません" -#: controldata.c:719 +#: controldata.c:636 #, c-format msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match" msgstr "新旧の pg_controldata における識別子の最大長が有効でないか一致しません" -#: controldata.c:722 +#: controldata.c:639 #, c-format msgid "old and new pg_controldata maximum indexed columns are invalid or do not match" msgstr "新旧の pg_controldata におけるインデックス付き列の最大数が有効でないか一致しません" -#: controldata.c:725 +#: controldata.c:642 #, c-format msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match" msgstr "新旧の pg_controldata におけるTOASTチャンクサイズの最大値が有効でないか一致しません" -#: controldata.c:730 +#: controldata.c:646 #, c-format msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match" msgstr "新旧の pg_controldata におけるラージオブジェクトのチャンクサイズが有効でないかまたは一致しません" -#: controldata.c:733 +#: controldata.c:649 #, c-format msgid "old and new pg_controldata date/time storage types do not match" msgstr "新旧の pg_controldata における日付/時刻型データの保存バイト数が一致しません" -#: controldata.c:746 +#: controldata.c:662 #, c-format msgid "checksums are being enabled in the old cluster" msgstr "古いクラスタではチェックサムの有効化中です" -#: controldata.c:754 +#: controldata.c:670 #, c-format msgid "old cluster does not use data checksums but the new one does" msgstr "旧クラスタではデータチェックサムを使用していませんが、新クラスタでは使用しています" -#: controldata.c:757 +#: controldata.c:673 #, c-format msgid "old cluster uses data checksums but the new one does not" msgstr "旧クラスタではデータチェックサムを使用していますが、新クラスタでは使用していません" -#: controldata.c:759 +#: controldata.c:675 #, c-format msgid "old and new cluster pg_controldata checksum versions do not match" msgstr "新旧の pg_controldata 間でチェックサムのバージョンが一致しません" #. translator: %s is the file path of the control file -#: controldata.c:771 +#: controldata.c:687 #, c-format msgid "Adding \".old\" suffix to old \"%s\"" msgstr "古い \"%s\" に \".old\" サフィックスを追加します" -#: controldata.c:776 relfilenumber.c:385 relfilenumber.c:412 +#: controldata.c:692 relfilenumber.c:385 relfilenumber.c:412 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "ファイル\"%s\"の名前を\"%s\"に変更できませんでした: %m" #. translator: %s/%s is the file path of the control file -#: controldata.c:782 +#: controldata.c:698 #, c-format msgid "" "\n" @@ -1130,7 +1055,7 @@ msgstr "" "いるため、一度新クラスタを起動してしまうと旧クラスタは安全に起動\n" "することができなくなります。" -#: controldata.c:789 +#: controldata.c:705 #, c-format msgid "" "\n" @@ -1140,7 +1065,7 @@ msgstr "" "\n" "\"swap\"モードが使用されているため, 古いクラスタは今後安全に起動できません" -#: controldata.c:793 file.c:455 +#: controldata.c:709 file.c:291 #, c-format msgid "unrecognized transfer mode" msgstr "識別できない転送モード" @@ -1170,17 +1095,17 @@ msgstr "%s でpg_ctlのバージョンデータを取得できませんでした msgid "could not get pg_ctl version output from %s" msgstr "%s からpg_ctlのバージョン出力を取得できませんでした" -#: exec.c:113 exec.c:117 +#: exec.c:104 exec.c:108 #, c-format msgid "command too long" msgstr "コマンドが長すぎます" -#: exec.c:161 pg_upgrade.c:339 +#: exec.c:152 pg_upgrade.c:339 #, c-format msgid "could not open log file \"%s\": %m" msgstr "ロックファイル\"%s\"をオープンできませんでした: %m" -#: exec.c:193 +#: exec.c:184 #, c-format msgid "" "\n" @@ -1189,153 +1114,143 @@ msgstr "" "\n" "*失敗*" -#: exec.c:196 +#: exec.c:187 #, c-format msgid "There were problems executing \"%s\"" msgstr "" "\"%s実行で問題が発生しました\n" "`1" -#: exec.c:199 +#: exec.c:190 #, c-format msgid "" "Consult the last few lines of \"%s\" or \"%s\" for\n" "the probable cause of the failure." msgstr "ありうる失敗の原因については\"%s\"または\"%s\"の最後の数行を参照してください。" -#: exec.c:204 +#: exec.c:195 #, c-format msgid "" "Consult the last few lines of \"%s\" for\n" "the probable cause of the failure." msgstr "ありうる失敗の原因については、\"%s\"の最後の数行を参照してください。" -#: exec.c:219 pg_upgrade.c:349 +#: exec.c:210 pg_upgrade.c:349 #, c-format msgid "could not write to log file \"%s\": %m" msgstr "ログファイル\"%s\"に書き込めませんでした: %m" -#: exec.c:245 +#: exec.c:236 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "ファイル\"%s\"を読み込み用にオープンできませんでした: %m" -#: exec.c:271 +#: exec.c:262 #, c-format msgid "You must have read and write access in the current directory." msgstr "カレントディレクトリに対して読み書き可能なアクセス権が必要です。" -#: exec.c:324 exec.c:390 exec.c:440 +#: exec.c:315 exec.c:371 exec.c:417 #, c-format msgid "check for \"%s\" failed: %m" msgstr "\"%s\"のチェックに失敗しました: %m" -#: exec.c:327 exec.c:393 +#: exec.c:318 exec.c:374 #, c-format msgid "\"%s\" is not a directory" msgstr "\"%s\"はディレクトリではありません" -#: exec.c:445 +#: exec.c:422 #, c-format msgid "check for \"%s\" failed: cannot execute" msgstr "\"%s\"の確認に失敗しました: 実行できません" -#: exec.c:455 +#: exec.c:432 #, c-format msgid "check for \"%s\" failed: incorrect version: found \"%s\", expected \"%s\"" msgstr "\"%s\"の確認に失敗しました: 間違ったバージョン: 検出\"%s\"、想定\"%s\"" -#: file.c:44 +#: file.c:40 #, c-format msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %m" msgstr "リレーション\"%s.%s\"(\"%s\"から\"%s\"へ)のクローン中のエラー: %m" -#: file.c:51 +#: file.c:47 #, c-format msgid "error while cloning relation \"%s.%s\": could not open file \"%s\": %m" msgstr "リレーション\"%s.%s\"のクローン中のエラー: ファイル\"%s\"を開けませんでした: %m" -#: file.c:56 +#: file.c:52 #, c-format msgid "error while cloning relation \"%s.%s\": could not create file \"%s\": %m" msgstr "リレーション\"%s.%s\"のクローン中のエラー: ファイル\"%s\"を作成できませんでした: %m" -#: file.c:65 +#: file.c:61 #, c-format msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s" msgstr "リレーション\"%s.%s\"の(\"%s\"から\"%s\"への)クローン中にエラー: %s" -#: file.c:91 file.c:160 file.c:233 +#: file.c:87 file.c:156 #, c-format msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %m" msgstr "リレーション\"%s.%s\"のコピー中のエラー: ファイル\"%s\"を開けませんでした: %m" -#: file.c:96 file.c:165 file.c:242 +#: file.c:92 file.c:161 #, c-format msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %m" msgstr "リレーション\"%s.%s\"のコピー中のエラー: ファイル\"%s\"を作成できませんでした: %m" -#: file.c:110 file.c:266 +#: file.c:106 #, c-format msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %m" msgstr "リレーション\"%s.%s\"のコピー中のエラー: ファイル\"%s\"を読めませんでした: %m" -#: file.c:122 file.c:344 +#: file.c:118 #, c-format msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %m" msgstr "リレーション\"%s.%s\"のコピー中のエラー: ファイル\"%s\"に書き込めませんでした: %m" -#: file.c:136 +#: file.c:132 #, c-format msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %m" msgstr "リレーション\"%s.%s\"(\"%s\"から\"%s\"へ)のコピー中のエラー: %m" -#: file.c:172 +#: file.c:168 #, c-format msgid "error while copying relation \"%s.%s\": could not copy file range from \"%s\" to \"%s\": %m" msgstr "リレーション\"%s.%s\"のコピー中のエラー: \"%s\"から\"%s\"へのファイルの範囲コピーができませんでした: %m" -#: file.c:194 +#: file.c:190 #, c-format msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %m" msgstr "リレーション\"%s.%s\"(\"%s\"から\"%s\"へ)のリンク作成中のエラー: %m" -#: file.c:237 -#, c-format -msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %m" -msgstr "リレーション\"%s.%s\"のコピー中のエラー: ファイル\"%s\"をstatできませんでした: %m" - -#: file.c:269 -#, c-format -msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"" -msgstr "リレーション\"%s.%s\"のコピー中にエラー: ファイル\"%s\"中に不完全なページがありました" - -#: file.c:371 file.c:387 +#: file.c:207 file.c:223 #, c-format msgid "could not clone file between old and new data directories: %m" msgstr "新旧ディレクトリ間のファイルのクローンができませんでした: %m" -#: file.c:383 file.c:420 slru_io.c:221 +#: file.c:219 file.c:256 slru_io.c:221 #, c-format msgid "could not create file \"%s\": %m" msgstr "ファイル\"%s\"を作成できませんでした: %m" -#: file.c:393 +#: file.c:229 #, c-format msgid "file cloning not supported on this platform" msgstr "このプラットフォームではファイルのクローンはサポートされません" -#: file.c:424 +#: file.c:260 #, c-format msgid "could not copy file range between old and new data directories: %m" msgstr "新旧ディレクトリ間のファイルの範囲コピーができませんでした: %m" -#: file.c:430 +#: file.c:266 #, c-format msgid "copy_file_range not supported on this platform" msgstr "このプラットフォームではcopy_file_rangeはサポートされません" -#: file.c:449 +#: file.c:285 #, c-format msgid "" "could not create hard link between old and new data directories: %m\n" @@ -1344,7 +1259,7 @@ msgstr "" "新旧のデータディレクトリ間でハードリンクを作成できませんでした: %m\n" "リンクモードでは、新旧のデータディレクトリが同じファイルシステム上にある必要があります。" -#: file.c:452 +#: file.c:288 #, c-format msgid "" "could not create hard link between old and new data directories: %m\n" @@ -1968,62 +1883,57 @@ msgstr "新クラスタ内のグローバルオブジェクトを復元してい msgid "Restoring database schemas in the new cluster" msgstr "新クラスタ内にデータベーススキーマを復元しています" -#: pg_upgrade.c:736 +#: pg_upgrade.c:729 #, c-format msgid "Deleting files from new %s" msgstr "新しい %s からファイルを削除しています" -#: pg_upgrade.c:740 +#: pg_upgrade.c:733 #, c-format msgid "could not delete directory \"%s\"" msgstr "ディレクトリ\"%s\"を削除できませんでした" -#: pg_upgrade.c:759 +#: pg_upgrade.c:752 #, c-format msgid "Copying old %s to new server" msgstr "旧の %s を新サーバーにコピーしています" -#: pg_upgrade.c:785 +#: pg_upgrade.c:775 #, c-format msgid "Setting oldest XID for new cluster" msgstr "新クラスタの、最古のXIDを設定しています" -#: pg_upgrade.c:793 +#: pg_upgrade.c:783 #, c-format msgid "Setting next transaction ID and epoch for new cluster" msgstr "新クラスタの、次のトランザクションIDと基点を設定しています" -#: pg_upgrade.c:823 pg_upgrade.c:886 +#: pg_upgrade.c:812 pg_upgrade.c:857 #, c-format msgid "Setting next multixact ID and offset for new cluster" msgstr "新クラスタの、次のmultixact IDとオフセットを設定しています" -#: pg_upgrade.c:882 +#: pg_upgrade.c:853 #, c-format msgid "Converting pg_multixact files" msgstr "pg_multixact のファイルを変換しています" -#: pg_upgrade.c:896 +#: pg_upgrade.c:867 #, c-format msgid "Resetting WAL archives" msgstr "WAL アーカイブをリセットしています" -#: pg_upgrade.c:939 +#: pg_upgrade.c:901 #, c-format msgid "Setting frozenxid and minmxid counters in new cluster" msgstr "新クラスタのfrozenxidとminmxidカウンタを設定しています" -#: pg_upgrade.c:941 -#, c-format -msgid "Setting minmxid counter in new cluster" -msgstr "新クラスタのminmxidカウンタを設定しています" - -#: pg_upgrade.c:1032 +#: pg_upgrade.c:990 #, c-format msgid "Restoring logical replication slots in the new cluster" msgstr "新クラスタ内の論理レプリケーションスロットを復元しています" -#: pg_upgrade.c:1094 +#: pg_upgrade.c:1052 #, c-format msgid "Creating the replication conflict detection slot" msgstr "レプリケーション衝突検出用スロットを作成しています" @@ -2088,37 +1998,32 @@ msgstr "ディレクトリ\"%s\"を同期できませんでした: %m" msgid "could not synchronize parent directory of \"%s\": %m" msgstr "\"%s\"の親ディレクトリを同期できませんでした: %m" -#: relfilenumber.c:593 +#: relfilenumber.c:576 #, c-format msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %m" msgstr "\"%s.%s\"ファイル (\"%s\"から\"%s\")の存在確認中のエラー: %m" -#: relfilenumber.c:610 -#, c-format -msgid "rewriting \"%s\" to \"%s\"" -msgstr "\"%s\"を\"%s\"に書き換えています" - -#: relfilenumber.c:618 +#: relfilenumber.c:593 #, c-format msgid "cloning \"%s\" to \"%s\"" msgstr "\"%s\"から\"%s\"へクローンしています" -#: relfilenumber.c:623 +#: relfilenumber.c:598 #, c-format msgid "copying \"%s\" to \"%s\"" msgstr "\"%s\"を\"%s\"にコピーしています" -#: relfilenumber.c:628 +#: relfilenumber.c:603 #, c-format msgid "copying \"%s\" to \"%s\" with copy_file_range" msgstr "\"%s\"を\"%s\"にcopy_file_rangeを使ってコピーしています" -#: relfilenumber.c:633 +#: relfilenumber.c:608 #, c-format msgid "linking \"%s\" to \"%s\"" msgstr "\"%s\"から\"%s\"へリンクを作成しています" -#: relfilenumber.c:639 +#: relfilenumber.c:614 #, c-format msgid "should never happen" msgstr "想定外のコードパス" @@ -2144,7 +2049,7 @@ msgstr "" "%s\n" "%s" -#: server.c:262 +#: server.c:261 #, c-format msgid "" "\n" @@ -2153,7 +2058,7 @@ msgstr "" "\n" "%s" -#: server.c:266 +#: server.c:265 #, c-format msgid "" "could not connect to source postmaster started with the command:\n" @@ -2162,7 +2067,7 @@ msgstr "" "以下のコマンドで起動した移行元postmasterに接続できませんでした:\n" "%s" -#: server.c:270 +#: server.c:269 #, c-format msgid "" "could not connect to target postmaster started with the command:\n" @@ -2171,22 +2076,22 @@ msgstr "" "以下のコマンドで起動した移行先postmasterに接続できませんでした:\n" "%s" -#: server.c:284 +#: server.c:283 #, c-format msgid "pg_ctl failed to start the source server, or connection failed" msgstr "pg_ctl が移行元サーバーの起動に失敗した、あるいは接続に失敗しました" -#: server.c:286 +#: server.c:285 #, c-format msgid "pg_ctl failed to start the target server, or connection failed" msgstr "pg_ctl が移行先サーバーの起動に失敗した、あるいは接続に失敗しました" -#: server.c:331 task.c:197 +#: server.c:330 task.c:197 #, c-format msgid "out of memory" msgstr "メモリ不足です" -#: server.c:344 +#: server.c:343 #, c-format msgid "libpq environment variable %s has a non-local server value: %s" msgstr "libpq の環境変数 %s で、ローカルでないサーバー値が設定されています: %s" @@ -2255,56 +2160,17 @@ msgstr "ディレクトリ\"%s\"にアクセスできませんでした: %m" msgid "ok" msgstr "ok" -#: version.c:62 -#, c-format -msgid "Checking for hash indexes" -msgstr "ハッシュインデックスをチェックしています" - -#: version.c:141 -#, c-format -msgid "" -"\n" -"Your installation contains hash indexes. These indexes have different\n" -"internal formats between your old and new clusters, so they must be\n" -"reindexed with the REINDEX command. After upgrading, you will be given\n" -"REINDEX instructions." -msgstr "" -"\n" -"このクラスタにはハッシュインデックスがあります。このインデックスは新旧のクラスタ間で\n" -"内部フォーマットが異なるため、REINDEX コマンドを使って再構築する必要があります。\n" -"アップグレードが終わったら、REINDEX を使った操作方法が指示されます。" - -#: version.c:147 -#, c-format -msgid "" -"\n" -"Your installation contains hash indexes. These indexes have different\n" -"internal formats between your old and new clusters, so they must be\n" -"reindexed with the REINDEX command. The file\n" -" %s\n" -"when executed by psql by the database superuser will recreate all invalid\n" -"indexes; until then, none of these indexes will be used." -msgstr "" -"\n" -"このクラスタにはハッシュインデックスがあります。このインデックスは新旧のクラスタ間で\n" -"内部フォーマットが異なるため、REINDEX コマンドを使って再構築する必要があります。\n" -"以下のファイル\n" -" %s\n" -"を、psqlを使用してデータベースのスーパーユーザーとして実行することで、無効になった\n" -"インデックスを再構築できます。\n" -"それまでは、これらのインデックスは使用されません。" - -#: version.c:203 +#: version.c:76 #, c-format msgid "Checking for extension updates" msgstr "機能拡張のアップデートを確認しています" -#: version.c:217 +#: version.c:90 #, c-format msgid "notice" msgstr "注意" -#: version.c:218 +#: version.c:91 #, c-format msgid "" "\n" @@ -2320,11 +2186,119 @@ msgstr "" "これらの機能拡張をアップデートできます。\n" " %s" +#~ msgid "" +#~ "\n" +#~ "Your installation contains hash indexes. These indexes have different\n" +#~ "internal formats between your old and new clusters, so they must be\n" +#~ "reindexed with the REINDEX command. After upgrading, you will be given\n" +#~ "REINDEX instructions." +#~ msgstr "" +#~ "\n" +#~ "このクラスタにはハッシュインデックスがあります。このインデックスは新旧のクラスタ間で\n" +#~ "内部フォーマットが異なるため、REINDEX コマンドを使って再構築する必要があります。\n" +#~ "アップグレードが終わったら、REINDEX を使った操作方法が指示されます。" + +#~ msgid "" +#~ "\n" +#~ "Your installation contains hash indexes. These indexes have different\n" +#~ "internal formats between your old and new clusters, so they must be\n" +#~ "reindexed with the REINDEX command. The file\n" +#~ " %s\n" +#~ "when executed by psql by the database superuser will recreate all invalid\n" +#~ "indexes; until then, none of these indexes will be used." +#~ msgstr "" +#~ "\n" +#~ "このクラスタにはハッシュインデックスがあります。このインデックスは新旧のクラスタ間で\n" +#~ "内部フォーマットが異なるため、REINDEX コマンドを使って再構築する必要があります。\n" +#~ "以下のファイル\n" +#~ " %s\n" +#~ "を、psqlを使用してデータベースのスーパーユーザーとして実行することで、無効になった\n" +#~ "インデックスを再構築できます。\n" +#~ "それまでは、これらのインデックスは使用されません。" + #~ msgid "\"wal_level\" must be \"logical\" but is set to \"%s\"" #~ msgstr "\"wal_level\"は\"logical\"でなければなりませんが\"%s\"に設定されています" +#~ msgid "Checking for hash indexes" +#~ msgstr "ハッシュインデックスをチェックしています" + +#~ msgid "Checking for incompatible \"jsonb\" data type in user tables" +#~ msgstr "ユーザーテーブル内の非互換の\"jsonb\"データ型を確認しています" + +#~ msgid "Checking for incompatible \"line\" data type" +#~ msgstr "非互換の \"line\" データ型を確認しています" + +#~ msgid "Checking for invalid \"unknown\" user columns" +#~ msgstr "無効な\"unknown\"ユーザー列をチェックしています" + +#~ msgid "Checking for roles starting with \"pg_\"" +#~ msgstr "'pg_' で始まるロールをチェックしています" + +#~ msgid "Setting minmxid counter in new cluster" +#~ msgstr "新クラスタのminmxidカウンタを設定しています" + #~ msgid "Setting oldest multixact ID in new cluster" #~ msgstr "新クラスタの最古のmultixact IDを設定しています" +#~ msgid "Swap mode can only upgrade clusters from PostgreSQL version %s and later." +#~ msgstr "スワップモードはPostgreSQL %s以降のバージョンからのアップグレードのみ可能です。" + #~ msgid "The replication slot \"pg_conflict_detection\" already exists on the new cluster" #~ msgstr "レプリケーションスロット\"pg_conflict_detection\"はすでに新しいクラスタに存在します" + +#~ msgid "" +#~ "Your installation contains roles starting with \"pg_\".\n" +#~ "\"pg_\" is a reserved prefix for system roles. The cluster\n" +#~ "cannot be upgraded until these roles are renamed.\n" +#~ "A list of roles starting with \"pg_\" is in the file:\n" +#~ " %s" +#~ msgstr "" +#~ "このクラスタには\"pg_\"で始まるロールが含まれています。\n" +#~ "\"pg_\"はシステムロールのために予約されている接頭辞で、これらのロールの\n" +#~ "名前を変更しないとpg_upgradeではこのクラスタをアップグレードすることは\n" +#~ "できません。\n" +#~ "\"pg_\"で始まるロールの一覧は以下のファイルにあります:\n" +#~ " %s" + +#~ msgid "" +#~ "Your installation contains the \"jsonb\" data type in user tables.\n" +#~ "The internal format of \"jsonb\" changed during 9.4 beta so this\n" +#~ "cluster cannot currently be upgraded. You can drop the problem \n" +#~ "columns and restart the upgrade.\n" +#~ msgstr "" +#~ "このクラスタでは、ユーザーテーブルに\"jsonb\"データ型が含まれています。\n" +#~ "この型の内部フォーマットは9.4ベータの間に変更されているため、現時点ではこの\n" +#~ "クラスタをアップグレードすることはできません。 問題の列を削除したのち、\n" +#~ "アップグレードを再実行できます。\n" + +#~ msgid "" +#~ "Your installation contains the \"line\" data type in user tables.\n" +#~ "This data type changed its internal and input/output format\n" +#~ "between your old and new versions so this\n" +#~ "cluster cannot currently be upgraded. You can\n" +#~ "drop the problem columns and restart the upgrade.\n" +#~ msgstr "" +#~ "このクラスタでは、ユーザーテーブルに\"line\"データ型が含まれています。\n" +#~ "このデータ型は新旧のクラスタ間で内部形式および入出力フォーマットが\n" +#~ "変更されているため、このクラスタは現時点ではアップグレードできません。\n" +#~ "問題の列を削除したのちにアップグレードを再実行できます。\n" + +#~ msgid "" +#~ "Your installation contains the \"unknown\" data type in user tables.\n" +#~ "This data type is no longer allowed in tables, so this cluster\n" +#~ "cannot currently be upgraded. You can drop the problem columns\n" +#~ "and restart the upgrade.\n" +#~ msgstr "" +#~ "このクラスタでは、ユーザーテーブルに \"unknown\" データ型が含まれています。\n" +#~ "このデータ型はもはやテーブル内では利用できないため、このクラスタは現時点\n" +#~ "ではアップグレードできません。問題の列を削除したのち、アップグレードを\n" +#~ "再実行できます。\n" + +#~ msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %m" +#~ msgstr "リレーション\"%s.%s\"のコピー中のエラー: ファイル\"%s\"をstatできませんでした: %m" + +#~ msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"" +#~ msgstr "リレーション\"%s.%s\"のコピー中にエラー: ファイル\"%s\"中に不完全なページがありました" + +#~ msgid "rewriting \"%s\" to \"%s\"" +#~ msgstr "\"%s\"を\"%s\"に書き換えています" diff --git a/src/bin/pg_upgrade/po/ka.po b/src/bin/pg_upgrade/po/ka.po index 0b3ff15e69d..ee558921a97 100644 --- a/src/bin/pg_upgrade/po/ka.po +++ b/src/bin/pg_upgrade/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_upgrade (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-13 06:24+0000\n" -"PO-Revision-Date: 2026-05-13 09:20+0200\n" +"POT-Creation-Date: 2026-06-30 04:23+0000\n" +"PO-Revision-Date: 2026-07-02 06:15+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -63,12 +63,12 @@ msgstr "მომხარებლის სახელის ამოხს msgid "options %s and %s cannot be used together" msgstr "პარამეტრებს %s და -%s ერთად ვერ გამოიყენებთ" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "გარსის ბრძანების არგუმენტი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "მონაცემთა ბაზის სახელი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" @@ -765,12 +765,12 @@ msgstr "\"wal_level\" უნდა იყოს \"replica\", ან \"logical\", #: check.c:2289 #, c-format -msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots on the old cluster plus one additional slot required for retaining conflict detection information (%d)" +msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots in the old cluster plus one additional slot required for retaining conflict detection information (%d)" msgstr "\"max_replication_slots\" (%d) ძველი კლასტერის ლოგიკური რეპლიკაციების სლოტების რაოდენობაზე მეტი ან ტოლი უნდა იყოს. პლუს საჭიროა კიდევ ერთი დამატებითი სლოტი კონფლიქტის შესახებ ინფორმაციის შესანახად (%d)" #: check.c:2295 #, c-format -msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots (%d) on the old cluster" +msgid "\"max_replication_slots\" (%d) must be greater than or equal to the number of logical replication slots (%d) in the old cluster" msgstr "\"max_replication_slots\" (%d) ძველი კლასტერის ლოგიკური რეპლიკაციების სლოტების რაოდენობაზე (%d) მეტი ან ტოლი უნდა იყოს" #: check.c:2327 @@ -780,8 +780,8 @@ msgstr "ახალი კლასტერის კონფიგურა #: check.c:2339 #, c-format -msgid "\"max_active_replication_origins\" (%d) must be greater than or equal to the number of subscriptions (%d) on the old cluster" -msgstr "\"max_active_replication_origins\" (%d) ძველი კლასტერის გამოწერების რაოდენობაზე (%d) მეტი ან ტოლი უნდა იყოს" +msgid "\"max_active_replication_origins\" (%d) must be greater than or equal to the number of subscriptions (%d) in the old cluster" +msgstr "\"max_active_replication_origins\" (%d) ძველი კლასტერის გამოწერების რაოდენობაზე (%d) მეტი, ან ტოლი უნდა იყოს" #: check.c:2361 #, c-format @@ -829,7 +829,7 @@ msgstr "მონაცემთა ბაზების, როლების #: check.c:2638 #, c-format msgid "" -"Your installation contains databases, roles, or tablespace with names\n" +"Your installation contains databases, roles, or tablespaces with names\n" "with invalid characters (newline or carriage return). To fix this,\n" "rename these objects.\n" "A list of all objects with invalid names is in the file:\n" @@ -2306,149 +2306,3 @@ msgstr "" " %s\n" ", როცა ის შესრულდება psql-ით ზემომხმარებლის მიერ, განაახლებს ამ\n" "გაფართოებებს." - -#, c-format -#~ msgid "" -#~ "\n" -#~ "\n" -#~ msgstr "" -#~ "\n" -#~ "\n" - -#, c-format -#~ msgid "%-*s\n" -#~ msgstr "%-*s\n" - -#, c-format -#~ msgid "%s\n" -#~ msgstr "%s\n" - -#, c-format -#~ msgid "%s() failed: %s" -#~ msgstr "%s()-ის შეცდომა: %s" - -#, c-format -#~ msgid "" -#~ "All the database, role and tablespace names should have only valid characters. A newline or \n" -#~ "carriage return character is not allowed in these object names. To fix this, please \n" -#~ "rename these names with valid names. \n" -#~ "To see all %d invalid object names, refer db_role_tablespace_invalid_names.txt file. \n" -#~ " %s" -#~ msgstr "" -#~ "ყველა მონაცემთა ბაზა, როლი და ცხრილების სივრცე, მხოლოდ, დაშვებულ სიმბოლოებს უნდა შეიცავდნენ.\n" -#~ "ახალი ხაზი, ან კარეტის გადატანის სიმბოლო ამ ობიექტის სახელებში დაშვებული არაა. გასასწორებლად,\n" -#~ "გადაარქვით სახელი სწორ სახელებზე.\n" -#~ "იმისათვის, რომ იხილოთ ყველა %d არასწორი ობიექტის სახელი, ჩაიხედეთ ფაილში db_role_tablespace_invalid_names.txt.\n" -#~ " %s" - -#, c-format -#~ msgid "Checking for incompatible \"jsonb\" data type" -#~ msgstr "შეუთავსებელი \"jsonb\" მონაცემთა ტიპის შემოწმება" - -#, c-format -#~ msgid "ICU locale values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" -#~ msgstr "ICU-ს ენის მნიშვნელობები მონაცემთა ბაზისთვის \"%s\" არ ემთხვევა: ძველი \"%s\", ახალი \"%s\"\n" - -#, c-format -#~ msgid "Setting oldest multixact ID in new cluster" -#~ msgstr "ახალ კლასტერში უძველესი მულტიტრანზაქციის ID-ის დაყენება" - -#, c-format -#~ msgid "The replication slot \"pg_conflict_detection\" already exists on the new cluster" -#~ msgstr "რეპლიკაციის სლოტი \"pg_conflict_detection\" ახალ კლასტერზე უკვე არსებობს" - -#, c-format -#~ msgid "The source cluster contains roles starting with \"pg_\"\n" -#~ msgstr "საწყისი კლასტერი შეიცავს როლებს, რომლებიც \"pg_\"-ით იწყება\n" - -#, c-format -#~ msgid "The target cluster contains roles starting with \"pg_\"\n" -#~ msgstr "სამიზნე კლასტერი შეიცავს როლებს, რომლებიც \"pg_\"-ით იწყება\n" - -#, c-format -#~ msgid "Unable to rename %s to %s.\n" -#~ msgstr "%s-ის %s-ად გადარქმევის შეცდომა.\n" - -#, c-format -#~ msgid "check for \"%s\" failed: %s" -#~ msgstr "\"%s\" შემოწმების შეცდომა: %s" - -#, c-format -#~ msgid "check for \"%s\" failed: cannot execute (permission denied)\n" -#~ msgstr "\"%s\" შემოწმების შეცდომა: გაშვების შეცდომა (წვდომა აკრძალულია)\n" - -#, c-format -#~ msgid "check for \"%s\" failed: not a regular file\n" -#~ msgstr "\"%s\" შემოწმება ვერ მოხერხდა: რეგულარული ფაილი არაა\n" - -#, c-format -#~ msgid "could not access directory \"%s\": %m\n" -#~ msgstr "საქაღალდის (%s) წვდომის შეცდომა: %m\n" - -#, c-format -#~ msgid "could not create directory \"%s\": %m\n" -#~ msgstr "საქაღალდის (%s) შექმნის შეცდომა: %m\n" - -#, c-format -#~ msgid "could not create file \"%s\": %s" -#~ msgstr "ფაილის (%s) შექმნის შეცდომა: %s" - -#, c-format -#~ msgid "could not create worker process: %s" -#~ msgstr "დამხმარე პროცესის შექმნა შეუძლებელია: %s" - -#, c-format -#~ msgid "could not get control data directory using %s: %s" -#~ msgstr "ვერ მივიღე მონაცემთა საქაღალდე %s გამოყენებით: %s" - -#, c-format -#~ msgid "could not open file \"%s\" for reading: %s" -#~ msgstr "შეცდომა %s-ის წასაკითხად გახსნისას: %s" - -#, c-format -#~ msgid "could not open file \"%s\": %s" -#~ msgstr "ფაილის გახსნის შეცდომა \"%s\": %s" - -#, c-format -#~ msgid "could not open file \"%s\": %s\n" -#~ msgstr "ფაილის გახსნის შეცდომა \"%s\": %s\n" - -#, c-format -#~ msgid "could not open log file \"%s\": %m\n" -#~ msgstr "ჟურნალის ფაილის გახსნის შეცდომა \"%s\": %m\n" - -#, c-format -#~ msgid "could not read permissions of directory \"%s\": %s" -#~ msgstr "საქაღალდის წვდომების წაკითხვა შეუძლებელია \"%s\": %s" - -#, c-format -#~ msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" -#~ msgstr "მონაცემთა ბაზის კოდირება \"%s\" არ ემთხვევა: ძველი \"%s\", ახალი \"%s\"\n" - -#, c-format -#~ msgid "failed to get system locale name for \"%s\"\n" -#~ msgstr "%s-სთვის სისტემური ენის მიღების შეცდომა\n" - -#, c-format -#~ msgid "failed to get the current locale\n" -#~ msgstr "მიმდინარე ენის მიღების პრობლემა\n" - -#, c-format -#~ msgid "failed to restore old locale \"%s\"\n" -#~ msgstr "ძველი ენის (\"%s\") აღდგენის პრობლემა\n" - -#, c-format -#~ msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" -#~ msgstr "მონაცემთა ბაზის lc_collate მნიშვნელობები \"%s\" არ ემთხვევა: ძველი \"%s\", ახალი \"%s\"\n" - -#, c-format -#~ msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" -#~ msgstr "მონაცემთა ბაზის lc_ctype მნიშვნელობები \"%s\" არ ემთხვევა: ძველი \"%s\", ახალი \"%s\"\n" - -#, c-format -#~ msgid "locale providers for database \"%s\" do not match: old \"%s\", new \"%s\"\n" -#~ msgstr "მონაცემთა ბაზის \"%s\" ენის მომწოდებლები არ ემთხვევა: ძველი \"%s\", ახალი \"%s\"\n" - -#, c-format -#~ msgid "too many command-line arguments (first is \"%s\")\n" -#~ msgstr "მეტისმეტად ბევრი ბრძანების-სტრიქონის არგუმენტი (პირველია \"%s\")\n" diff --git a/src/bin/pg_verifybackup/po/ka.po b/src/bin/pg_verifybackup/po/ka.po index 0398cf1c948..9fa395d4850 100644 --- a/src/bin/pg_verifybackup/po/ka.po +++ b/src/bin/pg_verifybackup/po/ka.po @@ -837,25 +837,3 @@ msgstr "" msgid "%s home page: <%s>\n" msgstr "%s-ის საწყისი გვერდია: <%s>\n" -#, c-format -#~ msgid "\"%s\" is not a plain file" -#~ msgstr "\"%s\" უბრალო ფაილი არაა" - -#~ msgid "parsing failed" -#~ msgstr "დამუშავების შეცდომა" - -#, c-format -#~ msgid "pg_waldump cannot read tar files" -#~ msgstr "pg_waldump-ს tar ფაილების წაკითხვა არ შეუძლია" - -#, c-format -#~ msgid "tar file trailer exceeds 2 blocks" -#~ msgstr "tar ფაილის ბოლოსართი 2 ბლოკს სცდება" - -#, c-format -#~ msgid "unexpected json parse error type: %d" -#~ msgstr "მოულოდნელი json-ის დამუშავების შეცდომის ტიპი: %d" - -#, c-format -#~ msgid "unexpected state while parsing tar file" -#~ msgstr "მოულოდნელი მდგომარეობა tar არქივის დამუშავებისას" diff --git a/src/bin/pg_waldump/po/ka.po b/src/bin/pg_waldump/po/ka.po index 3b5ef25f617..021ca7ab710 100644 --- a/src/bin/pg_waldump/po/ka.po +++ b/src/bin/pg_waldump/po/ka.po @@ -687,28 +687,3 @@ msgstr "შეუძლებელია ასლის აღდგენა msgid "could not decompress image at %X/%08X, block %d" msgstr "შეუძლებელია ასლის გაშლა მისამართზე %X/%08X, ბლოკი %d" -#, c-format -#~ msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" -#~ msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" -#~ msgstr[0] "WAL სეგმენტის ზომა ორის ხარისხი უნდა იყოს, 1 მბ-სა და 1 გბ-ს სორის, მაგრამ WAL ფაილის \"%s\" თავსართი %d ბაიტზე მიუთითებს" -#~ msgstr[1] "WAL სეგმენტის ზომა ორის ხარისხი უნდა იყოს, 1 მბ-სა და 1 გბ-ს სორის, მაგრამ WAL ფაილის \"%s\" თავსართი %d ბაიტზე მიუთითებს" - -#, c-format -#~ msgid "invalid record offset at %X/%X" -#~ msgstr "ჩანაწერის არასწორი წანაცვლება მისამართზე %X/%X" - -#, c-format -#~ msgid "invalid timeline specification: \"%s\"" -#~ msgstr "დროის ხაზის არასწორი სპეციფიკაცია: \"%s\"" - -#, c-format -#~ msgid "missing contrecord at %X/%X" -#~ msgstr "contrecord მისამართზე %X/%X არ არსებობს" - -#, c-format -#~ msgid "out of memory while trying to decode a record of length %u" -#~ msgstr "%u სიგრძის მქონე ჩანაწერის დეკოდირებისთვის მეხსიერება საკმარისი არაა" - -#, c-format -#~ msgid "record length %u at %X/%X too long" -#~ msgstr "ჩანაწერის სიგრძე %u მისამართზე %X/%X ძალიან გრძელია" diff --git a/src/bin/psql/po/de.po b/src/bin/psql/po/de.po index f4e83e9496f..c808e969a68 100644 --- a/src/bin/psql/po/de.po +++ b/src/bin/psql/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-04-20 04:22+0000\n" -"PO-Revision-Date: 2026-04-20 07:45+0200\n" +"POT-Creation-Date: 2026-07-09 08:52+0000\n" +"PO-Revision-Date: 2026-07-09 11:49+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -84,17 +84,27 @@ msgstr "%s() fehlgeschlagen: %m" msgid "out of memory" msgstr "Speicher aufgebraucht" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "Speicher aufgebraucht\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "ungültige Speicheranforderungsgröße %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "ungültige Speicheranforderungsgröße %zu * %zu\n" + #: ../../common/username.c:43 #, c-format msgid "could not look up effective user ID %ld: %s" @@ -154,42 +164,42 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu Zeile)" msgstr[1] "(%lu Zeilen)" -#: ../../fe_utils/print.c:3173 +#: ../../fe_utils/print.c:3191 #, c-format msgid "Interrupted\n" msgstr "Unterbrochen\n" -#: ../../fe_utils/print.c:3207 +#: ../../fe_utils/print.c:3225 #, c-format msgid "Cannot print table contents: number of cells % is equal to or exceeds maximum %zu.\n" msgstr "Kann Tabelleninhalt nicht ausgeben: Anzahl der Zellen % ist gleich oder überschreitet Maximum %zu.\n" -#: ../../fe_utils/print.c:3248 +#: ../../fe_utils/print.c:3266 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "Kann keinen weiteren Spaltenkopf zur Tabelle hinzufügen: Spaltenzahl %d überschritten.\n" -#: ../../fe_utils/print.c:3291 +#: ../../fe_utils/print.c:3309 #, c-format msgid "Cannot add cell to table content: total cell count of % exceeded.\n" msgstr "Kann keine weitere Zelle zur Tabelle hinzufügen: Zellengesamtzahl % überschritten.\n" -#: ../../fe_utils/print.c:3719 +#: ../../fe_utils/print.c:3737 #, c-format msgid "invalid output format (internal error): %d" msgstr "ungültiges Ausgabeformat (interner Fehler): %d" -#: ../../fe_utils/psqlscan.l:729 +#: ../../fe_utils/psqlscan.l:736 #, c-format msgid "skipping recursive expansion of variable \"%s\"" msgstr "rekursive Auswertung der Variable »%s« wird ausgelassen" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "Argument des Shell-Befehls enthält Newline oder Carriage Return: »%s«\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "Datenbankname enthält Newline oder Carriage Return: »%s«\n" @@ -347,7 +357,7 @@ msgstr "keine" msgid "no query buffer" msgstr "kein Anfragepuffer" -#: command.c:1390 command.c:6456 +#: command.c:1390 command.c:6462 #, c-format msgid "invalid line number: %s" msgstr "ungültige Zeilennummer: %s" @@ -361,9 +371,9 @@ msgstr "keine Änderungen" msgid "%s: invalid encoding name or conversion procedure not found" msgstr "%s: ungültiger Kodierungsname oder Umwandlungsprozedur nicht gefunden" -#: command.c:1657 command.c:2597 command.c:4076 command.c:4274 command.c:6562 -#: common.c:233 common.c:282 common.c:455 common.c:1178 common.c:1196 -#: common.c:1264 common.c:1376 common.c:1414 common.c:1705 common.c:1785 +#: command.c:1657 command.c:2597 command.c:4076 command.c:4274 command.c:6568 +#: common.c:233 common.c:282 common.c:457 common.c:1180 common.c:1198 +#: common.c:1266 common.c:1378 common.c:1416 common.c:1720 common.c:1800 #: copy.c:486 copy.c:731 large_obj.c:157 large_obj.c:192 large_obj.c:254 #: startup.c:310 #, c-format @@ -894,37 +904,37 @@ msgstr "Unicode-Spaltenlinienstil ist »%s«.\n" msgid "Unicode header line style is \"%s\".\n" msgstr "Unicode-Kopflinienstil ist »%s«.\n" -#: command.c:5899 +#: command.c:5905 #, c-format msgid "\\!: failed" msgstr "\\!: fehlgeschlagen" -#: command.c:5937 +#: command.c:5943 #, c-format msgid "\\watch cannot be used with an empty query" msgstr "\\watch kann nicht mit einer leeren Anfrage verwendet werden" -#: command.c:5969 +#: command.c:5975 #, c-format msgid "could not set timer: %m" msgstr "konnte Timer nicht setzen: %m" -#: command.c:6038 +#: command.c:6044 #, c-format msgid "%s\t%s (every %gs)\n" msgstr "%s\t%s (alle %gs)\n" -#: command.c:6041 +#: command.c:6047 #, c-format msgid "%s (every %gs)\n" msgstr "%s (alle %gs)\n" -#: command.c:6105 +#: command.c:6111 #, c-format msgid "could not wait for signals: %m" msgstr "konnte nicht auf Signale warten: %m" -#: command.c:6161 command.c:6168 common.c:667 common.c:674 +#: command.c:6167 command.c:6174 common.c:669 common.c:676 #, c-format msgid "" "/**** INTERNAL QUERY ****/\n" @@ -937,34 +947,34 @@ msgstr "" "/************************/\n" "\n" -#: command.c:6205 +#: command.c:6211 #, fuzzy #| msgid "List of functions" msgid "Get function's OID" msgstr "Liste der Funktionen" -#: command.c:6219 +#: command.c:6225 msgid "Get view's OID" msgstr "" -#: command.c:6261 +#: command.c:6267 #, fuzzy #| msgid "unexpected end of function definition" msgid "Get function's definition" msgstr "unerwartetes Ende der Funktionsdefinition" -#: command.c:6281 +#: command.c:6287 #, fuzzy #| msgid "change the definition of a table" msgid "Get view's definition and details" msgstr "ändert die Definition einer Tabelle" -#: command.c:6351 +#: command.c:6357 #, c-format msgid "\"%s.%s\" is not a view" msgstr "»%s.%s« ist keine Sicht" -#: command.c:6367 +#: command.c:6373 #, c-format msgid "could not parse reloptions array" msgstr "konnte reloptions-Array nicht interpretieren" @@ -979,87 +989,87 @@ msgstr "Escape kann nicht ohne aktive Verbindung ausgeführt werden" msgid "shell command argument contains a newline or carriage return: \"%s\"" msgstr "Argument des Shell-Befehls enthält Newline oder Carriage Return: »%s«" -#: common.c:363 +#: common.c:365 #, c-format msgid "connection to server was lost" msgstr "Verbindung zum Server wurde verloren" -#: common.c:367 +#: common.c:369 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "Die Verbindung zum Server wurde verloren. Versuche Reset: " -#: common.c:373 +#: common.c:375 #, c-format msgid "Failed.\n" msgstr "Fehlgeschlagen.\n" -#: common.c:390 +#: common.c:392 #, c-format msgid "Succeeded.\n" msgstr "Erfolgreich.\n" -#: common.c:445 common.c:1097 +#: common.c:447 common.c:1099 #, c-format msgid "unexpected PQresultStatus: %d" msgstr "unerwarteter PQresultStatus: %d" -#: common.c:606 +#: common.c:608 #, c-format msgid "Time: %.3f ms\n" msgstr "Zeit: %.3f ms\n" -#: common.c:621 +#: common.c:623 #, c-format msgid "Time: %.3f ms (%02d:%06.3f)\n" msgstr "Zeit: %.3f ms (%02d:%06.3f)\n" -#: common.c:630 +#: common.c:632 #, c-format msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" msgstr "Zeit: %.3f ms (%02d:%02d:%06.3f)\n" -#: common.c:637 +#: common.c:639 #, c-format msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" msgstr "Zeit: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" -#: common.c:661 common.c:718 common.c:1130 describe.c:6659 +#: common.c:663 common.c:720 common.c:1132 describe.c:6659 #, c-format msgid "You are currently not connected to a database." msgstr "Sie sind gegenwärtig nicht mit einer Datenbank verbunden." -#: common.c:749 +#: common.c:751 #, c-format msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" msgstr "Asynchrone Benachrichtigung »%s« mit Daten »%s« vom Serverprozess mit PID %d empfangen.\n" -#: common.c:752 +#: common.c:754 #, c-format msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "Asynchrone Benachrichtigung »%s« vom Serverprozess mit PID %d empfangen.\n" -#: common.c:783 +#: common.c:785 #, c-format msgid "could not print result table: %m" msgstr "konnte Ergebnistabelle nicht ausgeben: %m" -#: common.c:803 +#: common.c:805 #, c-format msgid "no rows returned for \\gset" msgstr "keine Zeilen für \\gset zurückgegeben" -#: common.c:808 +#: common.c:810 #, c-format msgid "more than one row returned for \\gset" msgstr "mehr als eine Zeile für \\gset zurückgegeben" -#: common.c:826 +#: common.c:828 #, c-format msgid "attempt to \\gset into specially treated variable \"%s\" ignored" msgstr "Versuch von \\gset in besonders behandelte Variable »%s« ignoriert" -#: common.c:1139 +#: common.c:1141 #, c-format msgid "" "/**(Single step mode: verify command)******************************************/\n" @@ -1070,7 +1080,7 @@ msgstr "" "%s\n" "/**(Drücken Sie die Eingabetaste um fortzufahren oder »x« um abzubrechen)******/\n" -#: common.c:1159 +#: common.c:1161 #, c-format msgid "" "/******** QUERY *********/\n" @@ -1083,48 +1093,48 @@ msgstr "" "/************************/\n" "\n" -#: common.c:1216 +#: common.c:1218 #, c-format msgid "STATEMENT: %s" msgstr "ANWEISUNG: %s" -#: common.c:1252 +#: common.c:1254 #, c-format msgid "unexpected transaction status (%d)" msgstr "unerwarteter Transaktionsstatus (%d)" -#: common.c:1398 describe.c:2198 +#: common.c:1400 describe.c:2198 msgid "Column" msgstr "Spalte" -#: common.c:1399 describe.c:179 describe.c:368 describe.c:386 describe.c:1094 +#: common.c:1401 describe.c:179 describe.c:368 describe.c:386 describe.c:1094 #: describe.c:1258 describe.c:1794 describe.c:1818 describe.c:2199 #: describe.c:4292 describe.c:4566 describe.c:4815 describe.c:4979 #: describe.c:6283 msgid "Type" msgstr "Typ" -#: common.c:1448 +#: common.c:1450 #, c-format msgid "The command has no result, or the result has no columns.\n" msgstr "Der Befehl hat kein Ergebnis oder das Ergebnis hat keine Spalten.\n" -#: common.c:1670 +#: common.c:1685 #, c-format msgid "No pending results to get" msgstr "Keine unerledigten Ergebnisse abzuholen" -#: common.c:1748 +#: common.c:1763 #, c-format msgid "fetching results in chunked mode failed" msgstr "Empfangen der Ergebnisse im Chunked-Modus fehlgeschlagen" -#: common.c:1797 +#: common.c:1812 #, c-format msgid "Pipeline aborted, command did not run" msgstr "Pipeline abgebrochen, Befehl wurde nicht ausgeführt" -#: common.c:1893 +#: common.c:1908 #, c-format msgid "COPY in a pipeline is not supported, aborting connection" msgstr "COPY in einer Pipeline wird nicht unterstützt, Verbindung wird abgebrochen" @@ -1189,47 +1199,47 @@ msgstr "abgebrochen wegen Lesenfehlers" msgid "trying to exit copy mode" msgstr "versuche, den COPY-Modus zu verlassen" -#: crosstabview.c:124 +#: crosstabview.c:127 #, c-format msgid "\\crosstabview: statement did not return a result set" msgstr "\\crosstabview: Anweisung hat keine Ergebnismenge zurückgegeben" -#: crosstabview.c:130 +#: crosstabview.c:133 #, c-format msgid "\\crosstabview: query must return at least three columns" msgstr "\\crosstabview: Anfrage muss mindestens drei Spalten zurückgeben" -#: crosstabview.c:157 +#: crosstabview.c:160 #, c-format msgid "\\crosstabview: vertical and horizontal headers must be different columns" msgstr "\\crosstabview: die vertikalen und horizontalen Kopffelder müssen verschiedene Spalten sein" -#: crosstabview.c:173 +#: crosstabview.c:176 #, c-format msgid "\\crosstabview: data column must be specified when query returns more than three columns" msgstr "\\crosstabview: Datenspalte muss angegeben werden, wenn die Anfrage mehr als drei Spalten zurückgibt" -#: crosstabview.c:229 +#: crosstabview.c:232 #, c-format msgid "\\crosstabview: maximum number of columns (%d) exceeded" msgstr "\\crosstabview: maximale Anzahl Spalten (%d) überschritten" -#: crosstabview.c:396 +#: crosstabview.c:399 #, c-format msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" msgstr "\\crosstabview: Anfrageergebnis enthält mehrfache Datenwerte für Zeile »%s«, Spalte »%s«" -#: crosstabview.c:643 +#: crosstabview.c:670 #, c-format msgid "\\crosstabview: column number %d is out of range 1..%d" msgstr "\\crosstabview: Spaltennummer %d ist außerhalb des zulässigen Bereichs 1..%d" -#: crosstabview.c:668 +#: crosstabview.c:695 #, c-format msgid "\\crosstabview: ambiguous column name: \"%s\"" msgstr "\\crosstabview: zweideutiger Spaltenname: »%s«" -#: crosstabview.c:676 +#: crosstabview.c:703 #, c-format msgid "\\crosstabview: column name not found: \"%s\"" msgstr "\\crosstabview: Spaltenname nicht gefunden: »%s«" @@ -1700,8 +1710,10 @@ msgid "Get publications containing this sequence" msgstr "" #: describe.c:1898 describe.c:3266 describe.c:5540 -msgid "Publications:" -msgstr "Publikationen:" +#, fuzzy +#| msgid "reading publications" +msgid "Included in publications:" +msgstr "lese Publikationen" #: describe.c:1916 #, c-format @@ -1718,34 +1730,24 @@ msgid "Get property graph information" msgstr "" #: describe.c:1960 -#, fuzzy -#| msgid "Elements" msgid "Element Alias" -msgstr "Elemente" +msgstr "Element-Alias" #: describe.c:1961 -#, fuzzy -#| msgid "Elements" msgid "Element Table" -msgstr "Elemente" +msgstr "Elementtabelle" #: describe.c:1962 -#, fuzzy -#| msgid "Elements" msgid "Element Kind" -msgstr "Elemente" +msgstr "Elementart" #: describe.c:1963 -#, fuzzy -#| msgid "Source type" msgid "Source Vertex Alias" -msgstr "Quelltyp" +msgstr "Quellknoten-Alias" #: describe.c:1964 -#, fuzzy -#| msgid "Destination" msgid "Destination Vertex Alias" -msgstr "Ziel" +msgstr "Zielknoten-Alias" #: describe.c:1971 #, c-format @@ -1914,21 +1916,23 @@ msgstr "" msgid "primary key, " msgstr "Primärschlüssel, " -#: describe.c:2507 -msgid "unique" -msgstr "unique" - -#: describe.c:2509 -msgid " nulls not distinct" +#: describe.c:2508 +#, fuzzy +#| msgid " nulls not distinct" +msgid "unique nulls not distinct, " msgstr " nulls not distinct" #: describe.c:2510 -msgid ", " -msgstr ", " +#, fuzzy +#| msgid "unique" +msgid "unique, " +msgstr "unique" +#. translator: the first %s is an index AM name (eg. btree) #: describe.c:2517 -#, c-format -msgid "for table \"%s.%s\"" +#, fuzzy, c-format +#| msgid "for table \"%s.%s\"" +msgid "%s, for table \"%s.%s\"" msgstr "für Tabelle »%s.%s«" #: describe.c:2521 @@ -2067,7 +2071,7 @@ msgstr "lese Publikationsmitgliedschaft von Tabellen" #: describe.c:3309 #, fuzzy #| msgid "Publications:" -msgid "Except publications:" +msgid "Excluded from publications:" msgstr "Publikationen:" #: describe.c:3327 @@ -4030,6 +4034,8 @@ msgid "" " \\pset [NAME [VALUE]] set table output option\n" " see \"\\? variables\" for valid options\n" msgstr "" +" \\pset [NAME [WERT]] Tabellenausgabeoption setzen\n" +" siehe »\\? variables« für gültige Optionen\n" #: help.c:295 #, c-format @@ -5084,13 +5090,13 @@ msgstr "%s: Speicher aufgebraucht" #: sql_help.c:3979 sql_help.c:3987 sql_help.c:4004 sql_help.c:4013 #: sql_help.c:4021 sql_help.c:4038 sql_help.c:4053 sql_help.c:4380 #: sql_help.c:4503 sql_help.c:4532 sql_help.c:4548 sql_help.c:4550 -#: sql_help.c:5004 sql_help.c:5100 sql_help.c:5148 sql_help.c:5267 -#: sql_help.c:5314 sql_help.c:5558 +#: sql_help.c:5002 sql_help.c:5098 sql_help.c:5146 sql_help.c:5265 +#: sql_help.c:5312 sql_help.c:5556 msgid "name" msgstr "Name" #: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:355 sql_help.c:2018 -#: sql_help.c:3664 sql_help.c:4861 +#: sql_help.c:3664 sql_help.c:4860 msgid "aggregate_signature" msgstr "Aggregatsignatur" @@ -5124,7 +5130,7 @@ msgstr "neuer_Eigentümer" msgid "new_schema" msgstr "neues_Schema" -#: sql_help.c:44 sql_help.c:2083 sql_help.c:3665 sql_help.c:4891 +#: sql_help.c:44 sql_help.c:2083 sql_help.c:3665 sql_help.c:4889 msgid "where aggregate_signature is:" msgstr "wobei Aggregatsignatur Folgendes ist:" @@ -5137,9 +5143,9 @@ msgstr "wobei Aggregatsignatur Folgendes ist:" #: sql_help.c:2087 sql_help.c:2090 sql_help.c:2250 sql_help.c:2269 #: sql_help.c:2272 sql_help.c:2590 sql_help.c:2795 sql_help.c:3666 #: sql_help.c:3669 sql_help.c:3672 sql_help.c:3763 sql_help.c:3852 -#: sql_help.c:3888 sql_help.c:4248 sql_help.c:4756 sql_help.c:4867 -#: sql_help.c:4874 sql_help.c:4881 sql_help.c:4892 sql_help.c:4895 -#: sql_help.c:4898 +#: sql_help.c:3888 sql_help.c:4248 sql_help.c:4756 sql_help.c:4866 +#: sql_help.c:4873 sql_help.c:4879 sql_help.c:4890 sql_help.c:4893 +#: sql_help.c:4896 msgid "argmode" msgstr "Argmodus" @@ -5152,8 +5158,8 @@ msgstr "Argmodus" #: sql_help.c:2088 sql_help.c:2091 sql_help.c:2251 sql_help.c:2270 #: sql_help.c:2273 sql_help.c:2591 sql_help.c:2796 sql_help.c:3667 #: sql_help.c:3670 sql_help.c:3673 sql_help.c:3764 sql_help.c:3853 -#: sql_help.c:3889 sql_help.c:4868 sql_help.c:4875 sql_help.c:4882 -#: sql_help.c:4893 sql_help.c:4896 sql_help.c:4899 +#: sql_help.c:3889 sql_help.c:4867 sql_help.c:4874 sql_help.c:4880 +#: sql_help.c:4891 sql_help.c:4894 sql_help.c:4897 msgid "argname" msgstr "Argname" @@ -5165,8 +5171,8 @@ msgstr "Argname" #: sql_help.c:2038 sql_help.c:2055 sql_help.c:2062 sql_help.c:2086 #: sql_help.c:2089 sql_help.c:2092 sql_help.c:2592 sql_help.c:2797 #: sql_help.c:3668 sql_help.c:3671 sql_help.c:3674 sql_help.c:3765 -#: sql_help.c:3854 sql_help.c:3890 sql_help.c:4869 sql_help.c:4876 -#: sql_help.c:4883 sql_help.c:4894 sql_help.c:4897 sql_help.c:4900 +#: sql_help.c:3854 sql_help.c:3890 sql_help.c:4868 sql_help.c:4875 +#: sql_help.c:4881 sql_help.c:4892 sql_help.c:4895 sql_help.c:4898 msgid "argtype" msgstr "Argtyp" @@ -5177,12 +5183,12 @@ msgstr "Argtyp" #: sql_help.c:2634 sql_help.c:2936 sql_help.c:3029 sql_help.c:3354 #: sql_help.c:3537 sql_help.c:3557 sql_help.c:3712 sql_help.c:4078 #: sql_help.c:4295 sql_help.c:4547 sql_help.c:4549 sql_help.c:4581 -#: sql_help.c:4584 sql_help.c:5395 sql_help.c:5450 +#: sql_help.c:4584 sql_help.c:5393 sql_help.c:5448 msgid "option" msgstr "Option" #: sql_help.c:115 sql_help.c:1083 sql_help.c:1803 sql_help.c:2635 -#: sql_help.c:2937 sql_help.c:3538 sql_help.c:3713 sql_help.c:5451 +#: sql_help.c:2937 sql_help.c:3538 sql_help.c:3713 sql_help.c:5449 msgid "where option can be:" msgstr "wobei Option Folgendes sein kann:" @@ -5209,7 +5215,7 @@ msgstr "neuer_Tablespace" #: sql_help.c:1095 sql_help.c:1098 sql_help.c:1160 sql_help.c:1162 #: sql_help.c:1163 sql_help.c:1319 sql_help.c:1321 sql_help.c:1811 #: sql_help.c:1815 sql_help.c:1818 sql_help.c:2602 sql_help.c:2801 -#: sql_help.c:4260 sql_help.c:4600 sql_help.c:4768 sql_help.c:5090 +#: sql_help.c:4260 sql_help.c:4600 sql_help.c:4768 sql_help.c:5088 msgid "configuration_parameter" msgstr "Konfigurationsparameter" @@ -5226,7 +5232,7 @@ msgstr "Konfigurationsparameter" #: sql_help.c:3030 sql_help.c:3071 sql_help.c:3196 sql_help.c:3210 #: sql_help.c:3225 sql_help.c:3275 sql_help.c:3283 sql_help.c:3310 #: sql_help.c:3328 sql_help.c:3355 sql_help.c:3558 sql_help.c:4296 -#: sql_help.c:5091 sql_help.c:5092 +#: sql_help.c:5089 sql_help.c:5090 msgid "value" msgstr "Wert" @@ -5256,7 +5262,7 @@ msgstr "wobei abgekürztes_Grant_oder_Revoke Folgendes sein kann:" #: sql_help.c:2639 sql_help.c:2640 sql_help.c:2641 sql_help.c:2775 #: sql_help.c:2941 sql_help.c:2942 sql_help.c:2943 sql_help.c:3542 #: sql_help.c:3543 sql_help.c:3544 sql_help.c:4275 sql_help.c:4279 -#: sql_help.c:4783 sql_help.c:4787 sql_help.c:5110 +#: sql_help.c:4783 sql_help.c:4787 sql_help.c:5108 msgid "role_name" msgstr "Rollenname" @@ -5268,16 +5274,16 @@ msgstr "Rollenname" #: sql_help.c:3047 sql_help.c:3052 sql_help.c:3054 sql_help.c:3191 #: sql_help.c:3205 sql_help.c:3220 sql_help.c:3233 sql_help.c:3245 #: sql_help.c:3279 sql_help.c:4329 sql_help.c:4346 sql_help.c:4348 -#: sql_help.c:4446 sql_help.c:4449 sql_help.c:4451 sql_help.c:4956 -#: sql_help.c:4957 sql_help.c:4966 sql_help.c:5003 sql_help.c:5019 -#: sql_help.c:5020 sql_help.c:5021 sql_help.c:5022 sql_help.c:5023 -#: sql_help.c:5024 sql_help.c:5065 sql_help.c:5066 sql_help.c:5076 -#: sql_help.c:5219 sql_help.c:5220 sql_help.c:5229 sql_help.c:5266 -#: sql_help.c:5282 sql_help.c:5283 sql_help.c:5284 sql_help.c:5285 -#: sql_help.c:5286 sql_help.c:5287 sql_help.c:5352 sql_help.c:5354 -#: sql_help.c:5425 sql_help.c:5510 sql_help.c:5511 sql_help.c:5520 -#: sql_help.c:5557 sql_help.c:5573 sql_help.c:5574 sql_help.c:5575 -#: sql_help.c:5576 sql_help.c:5577 sql_help.c:5578 +#: sql_help.c:4446 sql_help.c:4449 sql_help.c:4451 sql_help.c:4954 +#: sql_help.c:4955 sql_help.c:4964 sql_help.c:5001 sql_help.c:5017 +#: sql_help.c:5018 sql_help.c:5019 sql_help.c:5020 sql_help.c:5021 +#: sql_help.c:5022 sql_help.c:5063 sql_help.c:5064 sql_help.c:5074 +#: sql_help.c:5217 sql_help.c:5218 sql_help.c:5227 sql_help.c:5264 +#: sql_help.c:5280 sql_help.c:5281 sql_help.c:5282 sql_help.c:5283 +#: sql_help.c:5284 sql_help.c:5285 sql_help.c:5350 sql_help.c:5352 +#: sql_help.c:5423 sql_help.c:5508 sql_help.c:5509 sql_help.c:5518 +#: sql_help.c:5555 sql_help.c:5571 sql_help.c:5572 sql_help.c:5573 +#: sql_help.c:5574 sql_help.c:5575 sql_help.c:5576 msgid "expression" msgstr "Ausdruck" @@ -5326,14 +5332,14 @@ msgstr "wobei Elementobjekt Folgendes ist:" #: sql_help.c:2066 sql_help.c:2067 sql_help.c:2068 sql_help.c:2069 #: sql_help.c:2070 sql_help.c:2071 sql_help.c:2072 sql_help.c:2073 #: sql_help.c:2074 sql_help.c:2075 sql_help.c:2080 sql_help.c:2081 -#: sql_help.c:4857 sql_help.c:4862 sql_help.c:4863 sql_help.c:4864 -#: sql_help.c:4865 sql_help.c:4871 sql_help.c:4872 sql_help.c:4877 -#: sql_help.c:4878 sql_help.c:4879 sql_help.c:4884 sql_help.c:4885 -#: sql_help.c:4886 sql_help.c:4887 sql_help.c:4888 sql_help.c:4889 +#: sql_help.c:4856 sql_help.c:4861 sql_help.c:4862 sql_help.c:4863 +#: sql_help.c:4864 sql_help.c:4870 sql_help.c:4871 sql_help.c:4876 +#: sql_help.c:4877 sql_help.c:4882 sql_help.c:4883 sql_help.c:4884 +#: sql_help.c:4885 sql_help.c:4886 sql_help.c:4887 msgid "object_name" msgstr "Objektname" -#: sql_help.c:354 sql_help.c:2017 sql_help.c:4860 +#: sql_help.c:354 sql_help.c:2017 sql_help.c:4859 msgid "aggregate_name" msgstr "Aggregatname" @@ -5349,10 +5355,10 @@ msgstr "Zieltyp" #: sql_help.c:364 sql_help.c:820 sql_help.c:2035 sql_help.c:2317 #: sql_help.c:2360 sql_help.c:2440 sql_help.c:2718 sql_help.c:2749 -#: sql_help.c:3431 sql_help.c:4755 sql_help.c:4866 sql_help.c:4985 -#: sql_help.c:4989 sql_help.c:4993 sql_help.c:4996 sql_help.c:5248 -#: sql_help.c:5252 sql_help.c:5256 sql_help.c:5259 sql_help.c:5539 -#: sql_help.c:5543 sql_help.c:5547 sql_help.c:5550 +#: sql_help.c:3431 sql_help.c:4755 sql_help.c:4865 sql_help.c:4983 +#: sql_help.c:4987 sql_help.c:4991 sql_help.c:4994 sql_help.c:5246 +#: sql_help.c:5250 sql_help.c:5254 sql_help.c:5257 sql_help.c:5537 +#: sql_help.c:5541 sql_help.c:5545 sql_help.c:5548 msgid "function_name" msgstr "Funktionsname" @@ -5377,11 +5383,11 @@ msgstr "rechter_Typ" msgid "index_method" msgstr "Indexmethode" -#: sql_help.c:377 sql_help.c:2052 sql_help.c:4873 +#: sql_help.c:377 sql_help.c:2052 sql_help.c:4872 msgid "procedure_name" msgstr "Prozedurname" -#: sql_help.c:382 sql_help.c:2059 sql_help.c:4247 sql_help.c:4880 +#: sql_help.c:382 sql_help.c:2059 sql_help.c:4247 sql_help.c:4878 msgid "routine_name" msgstr "Routinenname" @@ -5446,10 +5452,10 @@ msgstr "Aktion" #: sql_help.c:4226 sql_help.c:4227 sql_help.c:4328 sql_help.c:4345 #: sql_help.c:4347 sql_help.c:4349 sql_help.c:4445 sql_help.c:4448 #: sql_help.c:4450 sql_help.c:4452 sql_help.c:4591 sql_help.c:4734 -#: sql_help.c:4735 sql_help.c:4859 sql_help.c:5028 sql_help.c:5035 -#: sql_help.c:5037 sql_help.c:5291 sql_help.c:5298 sql_help.c:5300 -#: sql_help.c:5351 sql_help.c:5353 sql_help.c:5355 sql_help.c:5413 -#: sql_help.c:5582 sql_help.c:5589 sql_help.c:5591 +#: sql_help.c:4735 sql_help.c:4858 sql_help.c:5026 sql_help.c:5033 +#: sql_help.c:5035 sql_help.c:5289 sql_help.c:5296 sql_help.c:5298 +#: sql_help.c:5349 sql_help.c:5351 sql_help.c:5353 sql_help.c:5411 +#: sql_help.c:5580 sql_help.c:5587 sql_help.c:5589 msgid "column_name" msgstr "Spaltenname" @@ -5483,7 +5489,7 @@ msgid "column_constraint" msgstr "Spalten-Constraint" #: sql_help.c:494 sql_help.c:636 sql_help.c:710 sql_help.c:1509 sql_help.c:2160 -#: sql_help.c:5406 +#: sql_help.c:5404 msgid "integer" msgstr "ganze_Zahl" @@ -5548,7 +5554,7 @@ msgid "role_specification" msgstr "Rollenangabe" #: sql_help.c:598 sql_help.c:600 sql_help.c:1832 sql_help.c:2386 -#: sql_help.c:2992 sql_help.c:3555 sql_help.c:4029 sql_help.c:5120 +#: sql_help.c:2992 sql_help.c:3555 sql_help.c:4029 sql_help.c:5118 msgid "user_name" msgstr "Benutzername" @@ -5584,7 +5590,7 @@ msgstr "Storage-Parameter" msgid "column_number" msgstr "Spaltennummer" -#: sql_help.c:659 sql_help.c:2040 sql_help.c:4870 +#: sql_help.c:659 sql_help.c:2040 sql_help.c:4869 msgid "large_object_oid" msgstr "Large-Object-OID" @@ -5645,9 +5651,9 @@ msgstr "Argumenttyp" #: sql_help.c:3306 sql_help.c:3427 sql_help.c:3612 sql_help.c:3842 #: sql_help.c:3899 sql_help.c:4005 sql_help.c:4222 sql_help.c:4228 #: sql_help.c:4292 sql_help.c:4326 sql_help.c:4590 sql_help.c:4730 -#: sql_help.c:4736 sql_help.c:4858 sql_help.c:4973 sql_help.c:5042 -#: sql_help.c:5236 sql_help.c:5305 sql_help.c:5347 sql_help.c:5412 -#: sql_help.c:5527 sql_help.c:5596 +#: sql_help.c:4736 sql_help.c:4857 sql_help.c:4971 sql_help.c:5040 +#: sql_help.c:5234 sql_help.c:5303 sql_help.c:5345 sql_help.c:5410 +#: sql_help.c:5525 sql_help.c:5594 msgid "table_name" msgstr "Tabellenname" @@ -5660,34 +5666,24 @@ msgid "check_expression" msgstr "Check-Ausdruck" #: sql_help.c:949 sql_help.c:2837 -#, fuzzy -#| msgid "saving database definition" msgid "vertex_table_definition" -msgstr "sichere Datenbankdefinition" +msgstr "Knotentabellendefinition" #: sql_help.c:950 sql_help.c:2838 -#, fuzzy -#| msgid "definition" msgid "edge_table_definition" -msgstr "Definition" +msgstr "Kantentabellendefinition" #: sql_help.c:952 -#, fuzzy -#| msgid "target_alias" msgid "vertex_table_alias" -msgstr "Zielalias" +msgstr "Knotentabellen-Alias" #: sql_help.c:954 -#, fuzzy -#| msgid "target_alias" msgid "edge_table_alias" -msgstr "Zielalias" +msgstr "Kantentabellen-Alias" #: sql_help.c:956 sql_help.c:961 sql_help.c:964 sql_help.c:969 -#, fuzzy -#| msgid "referenced_table_name" msgid "element_table_alias" -msgstr "verwiesener_Tabellenname" +msgstr "Elementtabellenname" #: sql_help.c:957 sql_help.c:962 sql_help.c:965 sql_help.c:970 sql_help.c:2859 #, fuzzy @@ -5724,7 +5720,7 @@ msgid "where publication_object is one of:" msgstr "wobei Publikationsobjekt Folgendes sein kann:" #: sql_help.c:1032 sql_help.c:1887 sql_help.c:2899 sql_help.c:4582 -#: sql_help.c:5396 +#: sql_help.c:5394 msgid "table_and_columns" msgstr "Tabelle-und-Spalten" @@ -5752,7 +5748,7 @@ msgid "table_object" msgstr "Elementobjekt" #: sql_help.c:1039 sql_help.c:1892 sql_help.c:2903 sql_help.c:4589 -#: sql_help.c:5411 +#: sql_help.c:5409 msgid "and table_and_columns is:" msgstr "und Tabelle-und-Spalten Folgendes ist:" @@ -5796,8 +5792,8 @@ msgstr "Minwert" msgid "maxvalue" msgstr "Maxwert" -#: sql_help.c:1210 sql_help.c:3012 sql_help.c:4969 sql_help.c:5079 -#: sql_help.c:5232 sql_help.c:5429 sql_help.c:5523 +#: sql_help.c:1210 sql_help.c:3012 sql_help.c:4967 sql_help.c:5077 +#: sql_help.c:5230 sql_help.c:5427 sql_help.c:5521 msgid "start" msgstr "Start" @@ -5936,8 +5932,8 @@ msgstr "und Tabellen-Constraint Folgendes ist:" msgid "exclude_element" msgstr "Exclude-Element" -#: sql_help.c:1573 sql_help.c:3255 sql_help.c:4967 sql_help.c:5077 -#: sql_help.c:5230 sql_help.c:5427 sql_help.c:5521 +#: sql_help.c:1573 sql_help.c:3255 sql_help.c:4965 sql_help.c:5075 +#: sql_help.c:5228 sql_help.c:5425 sql_help.c:5519 msgid "operator" msgstr "Operator" @@ -6030,7 +6026,7 @@ msgid "view_option_value" msgstr "Sichtoptionswert" #: sql_help.c:1888 sql_help.c:1931 sql_help.c:1955 sql_help.c:2153 -#: sql_help.c:4080 sql_help.c:4551 sql_help.c:4585 sql_help.c:5397 +#: sql_help.c:4080 sql_help.c:4551 sql_help.c:4585 sql_help.c:5395 msgid "where option can be one of:" msgstr "wobei Option eine der folgenden sein kann:" @@ -6040,28 +6036,28 @@ msgstr "wobei Option eine der folgenden sein kann:" #: sql_help.c:4085 sql_help.c:4086 sql_help.c:4087 sql_help.c:4088 #: sql_help.c:4089 sql_help.c:4090 sql_help.c:4091 sql_help.c:4552 #: sql_help.c:4554 sql_help.c:4586 sql_help.c:4587 sql_help.c:4588 -#: sql_help.c:5398 sql_help.c:5399 sql_help.c:5400 sql_help.c:5401 -#: sql_help.c:5402 sql_help.c:5403 sql_help.c:5404 sql_help.c:5405 -#: sql_help.c:5407 sql_help.c:5408 sql_help.c:5410 +#: sql_help.c:5396 sql_help.c:5397 sql_help.c:5398 sql_help.c:5399 +#: sql_help.c:5400 sql_help.c:5401 sql_help.c:5402 sql_help.c:5403 +#: sql_help.c:5405 sql_help.c:5406 sql_help.c:5408 msgid "boolean" msgstr "boolean" -#: sql_help.c:1891 sql_help.c:5409 +#: sql_help.c:1891 sql_help.c:5407 msgid "size" msgstr "Größe" -#: sql_help.c:1908 sql_help.c:5136 sql_help.c:5138 sql_help.c:5162 +#: sql_help.c:1908 sql_help.c:5134 sql_help.c:5136 sql_help.c:5160 msgid "transaction_mode" msgstr "Transaktionsmodus" -#: sql_help.c:1909 sql_help.c:5139 sql_help.c:5163 +#: sql_help.c:1909 sql_help.c:5137 sql_help.c:5161 msgid "where transaction_mode is one of:" msgstr "wobei Transaktionsmodus Folgendes sein kann:" -#: sql_help.c:1918 sql_help.c:4977 sql_help.c:4986 sql_help.c:4990 -#: sql_help.c:4994 sql_help.c:4997 sql_help.c:5240 sql_help.c:5249 -#: sql_help.c:5253 sql_help.c:5257 sql_help.c:5260 sql_help.c:5531 -#: sql_help.c:5540 sql_help.c:5544 sql_help.c:5548 sql_help.c:5551 +#: sql_help.c:1918 sql_help.c:4975 sql_help.c:4984 sql_help.c:4988 +#: sql_help.c:4992 sql_help.c:4995 sql_help.c:5238 sql_help.c:5247 +#: sql_help.c:5251 sql_help.c:5255 sql_help.c:5258 sql_help.c:5529 +#: sql_help.c:5538 sql_help.c:5542 sql_help.c:5546 sql_help.c:5549 msgid "argument" msgstr "Argument" @@ -6081,7 +6077,7 @@ msgstr "Policy-Name" msgid "rule_name" msgstr "Regelname" -#: sql_help.c:2082 sql_help.c:4890 +#: sql_help.c:2082 sql_help.c:4888 msgid "string_literal" msgstr "Zeichenkettenkonstante" @@ -6100,9 +6096,9 @@ msgstr "Befehl" #: sql_help.c:2146 sql_help.c:2961 sql_help.c:3430 sql_help.c:3617 #: sql_help.c:4344 sql_help.c:4351 sql_help.c:4436 sql_help.c:4439 -#: sql_help.c:4442 sql_help.c:4960 sql_help.c:4962 sql_help.c:5070 -#: sql_help.c:5072 sql_help.c:5223 sql_help.c:5225 sql_help.c:5358 -#: sql_help.c:5514 sql_help.c:5516 +#: sql_help.c:4442 sql_help.c:4958 sql_help.c:4960 sql_help.c:5068 +#: sql_help.c:5070 sql_help.c:5221 sql_help.c:5223 sql_help.c:5356 +#: sql_help.c:5512 sql_help.c:5514 msgid "condition" msgstr "Bedingung" @@ -6239,7 +6235,7 @@ msgstr "lc_collate" msgid "lc_ctype" msgstr "lc_ctype" -#: sql_help.c:2343 sql_help.c:4856 +#: sql_help.c:2343 sql_help.c:4855 msgid "provider" msgstr "Provider" @@ -6382,21 +6378,19 @@ msgstr "Storage-Typ" #: sql_help.c:2839 msgid "where vertex_table_definition is:" -msgstr "" +msgstr "wobei Knotentabellendefinition Folgendes ist:" #: sql_help.c:2840 -#, fuzzy -#| msgid "target_table_name" msgid "vertex_table_name" -msgstr "Zieltabellenname" +msgstr "Knotentabellenname" #: sql_help.c:2841 sql_help.c:2846 sql_help.c:3615 sql_help.c:4327 -#: sql_help.c:4974 sql_help.c:4980 sql_help.c:4983 sql_help.c:4987 -#: sql_help.c:4991 sql_help.c:4999 sql_help.c:5005 sql_help.c:5237 -#: sql_help.c:5243 sql_help.c:5246 sql_help.c:5250 sql_help.c:5254 -#: sql_help.c:5262 sql_help.c:5268 sql_help.c:5350 sql_help.c:5528 -#: sql_help.c:5534 sql_help.c:5537 sql_help.c:5541 sql_help.c:5545 -#: sql_help.c:5553 sql_help.c:5559 +#: sql_help.c:4972 sql_help.c:4978 sql_help.c:4981 sql_help.c:4985 +#: sql_help.c:4989 sql_help.c:4997 sql_help.c:5003 sql_help.c:5235 +#: sql_help.c:5241 sql_help.c:5244 sql_help.c:5248 sql_help.c:5252 +#: sql_help.c:5260 sql_help.c:5266 sql_help.c:5348 sql_help.c:5526 +#: sql_help.c:5532 sql_help.c:5535 sql_help.c:5539 sql_help.c:5543 +#: sql_help.c:5551 sql_help.c:5557 msgid "alias" msgstr "Alias" @@ -6405,16 +6399,12 @@ msgid "element_table_label_and_properties" msgstr "" #: sql_help.c:2844 -#, fuzzy -#| msgid "and table_constraint is:" msgid "and edge_table_definition is:" -msgstr "und Tabellen-Constraint Folgendes ist:" +msgstr "und Kantentabellendefinition Folgendes ist:" #: sql_help.c:2845 -#, fuzzy -#| msgid "target_table_name" msgid "edge_table_name" -msgstr "Zieltabellenname" +msgstr "Kantentabellenname" #: sql_help.c:2852 #, fuzzy @@ -6674,66 +6664,66 @@ msgstr "Trennzeichen" msgid "collatable" msgstr "sortierbar" -#: sql_help.c:3611 sql_help.c:4325 sql_help.c:4422 sql_help.c:4955 -#: sql_help.c:5064 sql_help.c:5218 sql_help.c:5346 sql_help.c:5509 +#: sql_help.c:3611 sql_help.c:4325 sql_help.c:4422 sql_help.c:4953 +#: sql_help.c:5062 sql_help.c:5216 sql_help.c:5344 sql_help.c:5507 msgid "with_query" msgstr "With-Anfrage" -#: sql_help.c:3613 sql_help.c:5348 +#: sql_help.c:3613 sql_help.c:5346 #, fuzzy #| msgid "new_column_name" msgid "range_column_name" msgstr "neuer_Spaltenname" -#: sql_help.c:3614 sql_help.c:5349 +#: sql_help.c:3614 sql_help.c:5347 msgid "for_portion_of_target" msgstr "" -#: sql_help.c:3616 sql_help.c:4959 sql_help.c:5007 sql_help.c:5009 -#: sql_help.c:5013 sql_help.c:5015 sql_help.c:5016 sql_help.c:5017 -#: sql_help.c:5069 sql_help.c:5222 sql_help.c:5270 sql_help.c:5272 -#: sql_help.c:5276 sql_help.c:5278 sql_help.c:5279 sql_help.c:5280 -#: sql_help.c:5357 sql_help.c:5513 sql_help.c:5561 sql_help.c:5563 -#: sql_help.c:5567 sql_help.c:5569 sql_help.c:5570 sql_help.c:5571 +#: sql_help.c:3616 sql_help.c:4957 sql_help.c:5005 sql_help.c:5007 +#: sql_help.c:5011 sql_help.c:5013 sql_help.c:5014 sql_help.c:5015 +#: sql_help.c:5067 sql_help.c:5220 sql_help.c:5268 sql_help.c:5270 +#: sql_help.c:5274 sql_help.c:5276 sql_help.c:5277 sql_help.c:5278 +#: sql_help.c:5355 sql_help.c:5511 sql_help.c:5559 sql_help.c:5561 +#: sql_help.c:5565 sql_help.c:5567 sql_help.c:5568 sql_help.c:5569 msgid "from_item" msgstr "From-Element" -#: sql_help.c:3618 sql_help.c:4117 sql_help.c:4480 sql_help.c:5359 +#: sql_help.c:3618 sql_help.c:4117 sql_help.c:4480 sql_help.c:5357 msgid "cursor_name" msgstr "Cursor-Name" -#: sql_help.c:3619 sql_help.c:4333 sql_help.c:4428 sql_help.c:5360 +#: sql_help.c:3619 sql_help.c:4333 sql_help.c:4428 sql_help.c:5358 msgid "output_alias" msgstr "Ausgabealias" -#: sql_help.c:3620 sql_help.c:4334 sql_help.c:4429 sql_help.c:5361 +#: sql_help.c:3620 sql_help.c:4334 sql_help.c:4429 sql_help.c:5359 msgid "output_expression" msgstr "Ausgabeausdruck" -#: sql_help.c:3621 sql_help.c:4335 sql_help.c:4430 sql_help.c:4958 -#: sql_help.c:5067 sql_help.c:5221 sql_help.c:5362 sql_help.c:5512 +#: sql_help.c:3621 sql_help.c:4335 sql_help.c:4430 sql_help.c:4956 +#: sql_help.c:5065 sql_help.c:5219 sql_help.c:5360 sql_help.c:5510 msgid "output_name" msgstr "Ausgabename" -#: sql_help.c:3622 sql_help.c:5363 +#: sql_help.c:3622 sql_help.c:5361 #, fuzzy #| msgid "where domain_constraint is:" msgid "where for_portion_of_target is:" msgstr "wobei Domänen-Constraint Folgendes ist:" -#: sql_help.c:3623 sql_help.c:5364 +#: sql_help.c:3623 sql_help.c:5362 #, fuzzy #| msgid "start_function" msgid "start_time" msgstr "Startfunktion" -#: sql_help.c:3624 sql_help.c:5365 +#: sql_help.c:3624 sql_help.c:5363 #, fuzzy #| msgid "end_function" msgid "end_time" msgstr "Endfunktion" -#: sql_help.c:3625 sql_help.c:5366 +#: sql_help.c:3625 sql_help.c:5364 #, fuzzy #| msgid "option" msgid "portion" @@ -6761,9 +6751,9 @@ msgstr "wobei Richtung eine der folgenden sein kann:" #: sql_help.c:4119 sql_help.c:4120 sql_help.c:4121 sql_help.c:4122 #: sql_help.c:4123 sql_help.c:4482 sql_help.c:4483 sql_help.c:4484 -#: sql_help.c:4485 sql_help.c:4486 sql_help.c:4968 sql_help.c:4970 -#: sql_help.c:5078 sql_help.c:5080 sql_help.c:5231 sql_help.c:5233 -#: sql_help.c:5428 sql_help.c:5430 sql_help.c:5522 sql_help.c:5524 +#: sql_help.c:4485 sql_help.c:4486 sql_help.c:4966 sql_help.c:4968 +#: sql_help.c:5076 sql_help.c:5078 sql_help.c:5229 sql_help.c:5231 +#: sql_help.c:5426 sql_help.c:5428 sql_help.c:5520 sql_help.c:5522 msgid "count" msgstr "Anzahl" @@ -6783,8 +6773,8 @@ msgstr "Argtyp" msgid "loid" msgstr "Large-Object-OID" -#: sql_help.c:4263 sql_help.c:4771 sql_help.c:5001 sql_help.c:5264 -#: sql_help.c:5555 +#: sql_help.c:4263 sql_help.c:4771 sql_help.c:4999 sql_help.c:5262 +#: sql_help.c:5553 #, fuzzy #| msgid "group_name" msgid "graph_name" @@ -6826,11 +6816,11 @@ msgstr "Indexprädikat" msgid "and conflict_action is one of:" msgstr "und Konfliktaktion Folgendes sein kann:" -#: sql_help.c:4350 sql_help.c:4453 sql_help.c:5356 +#: sql_help.c:4350 sql_help.c:4453 sql_help.c:5354 msgid "sub-SELECT" msgstr "Sub-SELECT" -#: sql_help.c:4359 sql_help.c:4494 sql_help.c:5322 +#: sql_help.c:4359 sql_help.c:4494 sql_help.c:5320 msgid "channel" msgstr "Kanal" @@ -6854,7 +6844,7 @@ msgstr "Zielalias" msgid "data_source" msgstr "Datenquelle" -#: sql_help.c:4426 sql_help.c:5010 sql_help.c:5273 sql_help.c:5564 +#: sql_help.c:4426 sql_help.c:5008 sql_help.c:5271 sql_help.c:5562 msgid "join_condition" msgstr "Verbundbedingung" @@ -6922,870 +6912,872 @@ msgstr "neue_Rolle" msgid "savepoint_name" msgstr "Sicherungspunktsname" -#: sql_help.c:4961 sql_help.c:5025 sql_help.c:5071 sql_help.c:5224 -#: sql_help.c:5288 sql_help.c:5515 sql_help.c:5579 +#: sql_help.c:4959 sql_help.c:5023 sql_help.c:5069 sql_help.c:5222 +#: sql_help.c:5286 sql_help.c:5513 sql_help.c:5577 msgid "grouping_element" msgstr "Gruppierelement" -#: sql_help.c:4963 sql_help.c:5073 sql_help.c:5226 sql_help.c:5517 +#: sql_help.c:4961 sql_help.c:5071 sql_help.c:5224 sql_help.c:5515 msgid "window_name" msgstr "Fenstername" -#: sql_help.c:4964 sql_help.c:5074 sql_help.c:5227 sql_help.c:5518 +#: sql_help.c:4962 sql_help.c:5072 sql_help.c:5225 sql_help.c:5516 msgid "window_definition" msgstr "Fensterdefinition" -#: sql_help.c:4965 sql_help.c:4979 sql_help.c:5029 sql_help.c:5075 -#: sql_help.c:5228 sql_help.c:5242 sql_help.c:5292 sql_help.c:5519 -#: sql_help.c:5533 sql_help.c:5583 +#: sql_help.c:4963 sql_help.c:4977 sql_help.c:5027 sql_help.c:5073 +#: sql_help.c:5226 sql_help.c:5240 sql_help.c:5290 sql_help.c:5517 +#: sql_help.c:5531 sql_help.c:5581 msgid "select" msgstr "Select" -#: sql_help.c:4971 sql_help.c:5081 sql_help.c:5234 sql_help.c:5525 +#: sql_help.c:4969 sql_help.c:5079 sql_help.c:5232 sql_help.c:5523 msgid "from_reference" msgstr "From-Referenz" -#: sql_help.c:4972 sql_help.c:5235 sql_help.c:5526 +#: sql_help.c:4970 sql_help.c:5233 sql_help.c:5524 msgid "where from_item can be one of:" msgstr "wobei From-Element Folgendes sein kann:" -#: sql_help.c:4975 sql_help.c:4981 sql_help.c:4984 sql_help.c:4988 -#: sql_help.c:5000 sql_help.c:5006 sql_help.c:5238 sql_help.c:5244 -#: sql_help.c:5247 sql_help.c:5251 sql_help.c:5263 sql_help.c:5269 -#: sql_help.c:5529 sql_help.c:5535 sql_help.c:5538 sql_help.c:5542 -#: sql_help.c:5554 sql_help.c:5560 +#: sql_help.c:4973 sql_help.c:4979 sql_help.c:4982 sql_help.c:4986 +#: sql_help.c:4998 sql_help.c:5004 sql_help.c:5236 sql_help.c:5242 +#: sql_help.c:5245 sql_help.c:5249 sql_help.c:5261 sql_help.c:5267 +#: sql_help.c:5527 sql_help.c:5533 sql_help.c:5536 sql_help.c:5540 +#: sql_help.c:5552 sql_help.c:5558 msgid "column_alias" msgstr "Spaltenalias" -#: sql_help.c:4976 sql_help.c:5239 sql_help.c:5530 +#: sql_help.c:4974 sql_help.c:5237 sql_help.c:5528 msgid "sampling_method" msgstr "Stichprobenmethode" -#: sql_help.c:4978 sql_help.c:5241 sql_help.c:5532 +#: sql_help.c:4976 sql_help.c:5239 sql_help.c:5530 msgid "seed" msgstr "Startwert" -#: sql_help.c:4982 sql_help.c:5027 sql_help.c:5245 sql_help.c:5290 -#: sql_help.c:5536 sql_help.c:5581 +#: sql_help.c:4980 sql_help.c:5025 sql_help.c:5243 sql_help.c:5288 +#: sql_help.c:5534 sql_help.c:5579 msgid "with_query_name" msgstr "With-Anfragename" -#: sql_help.c:4992 sql_help.c:4995 sql_help.c:4998 sql_help.c:5255 -#: sql_help.c:5258 sql_help.c:5261 sql_help.c:5546 sql_help.c:5549 -#: sql_help.c:5552 +#: sql_help.c:4990 sql_help.c:4993 sql_help.c:4996 sql_help.c:5253 +#: sql_help.c:5256 sql_help.c:5259 sql_help.c:5544 sql_help.c:5547 +#: sql_help.c:5550 msgid "column_definition" msgstr "Spaltendefinition" -#: sql_help.c:5002 sql_help.c:5265 sql_help.c:5556 +#: sql_help.c:5000 sql_help.c:5263 sql_help.c:5554 msgid "graph_pattern" msgstr "" -#: sql_help.c:5008 sql_help.c:5014 sql_help.c:5271 sql_help.c:5277 -#: sql_help.c:5562 sql_help.c:5568 +#: sql_help.c:5006 sql_help.c:5012 sql_help.c:5269 sql_help.c:5275 +#: sql_help.c:5560 sql_help.c:5566 msgid "join_type" msgstr "Verbundtyp" -#: sql_help.c:5011 sql_help.c:5274 sql_help.c:5565 +#: sql_help.c:5009 sql_help.c:5272 sql_help.c:5563 msgid "join_column" msgstr "Verbundspalte" -#: sql_help.c:5012 sql_help.c:5275 sql_help.c:5566 +#: sql_help.c:5010 sql_help.c:5273 sql_help.c:5564 msgid "join_using_alias" msgstr "Join-Using-Alias" -#: sql_help.c:5018 sql_help.c:5281 sql_help.c:5572 +#: sql_help.c:5016 sql_help.c:5279 sql_help.c:5570 msgid "and grouping_element can be one of:" msgstr "und Gruppierelement eins der folgenden sein kann:" -#: sql_help.c:5026 sql_help.c:5289 sql_help.c:5580 +#: sql_help.c:5024 sql_help.c:5287 sql_help.c:5578 msgid "and with_query is:" msgstr "und With-Anfrage ist:" -#: sql_help.c:5030 sql_help.c:5293 sql_help.c:5584 +#: sql_help.c:5028 sql_help.c:5291 sql_help.c:5582 msgid "values" msgstr "values" -#: sql_help.c:5031 sql_help.c:5294 sql_help.c:5585 +#: sql_help.c:5029 sql_help.c:5292 sql_help.c:5583 msgid "insert" msgstr "insert" -#: sql_help.c:5032 sql_help.c:5295 sql_help.c:5586 +#: sql_help.c:5030 sql_help.c:5293 sql_help.c:5584 msgid "update" msgstr "update" -#: sql_help.c:5033 sql_help.c:5296 sql_help.c:5587 +#: sql_help.c:5031 sql_help.c:5294 sql_help.c:5585 msgid "delete" msgstr "delete" -#: sql_help.c:5034 sql_help.c:5297 sql_help.c:5588 +#: sql_help.c:5032 sql_help.c:5295 sql_help.c:5586 msgid "merge" msgstr "merge" -#: sql_help.c:5036 sql_help.c:5299 sql_help.c:5590 +#: sql_help.c:5034 sql_help.c:5297 sql_help.c:5588 msgid "search_seq_col_name" msgstr "Search-Seq-Spaltenname" -#: sql_help.c:5038 sql_help.c:5301 sql_help.c:5592 +#: sql_help.c:5036 sql_help.c:5299 sql_help.c:5590 msgid "cycle_mark_col_name" msgstr "Cycle-Mark-Spaltenname" -#: sql_help.c:5039 sql_help.c:5302 sql_help.c:5593 +#: sql_help.c:5037 sql_help.c:5300 sql_help.c:5591 msgid "cycle_mark_value" msgstr "Cycle-Mark-Wert" -#: sql_help.c:5040 sql_help.c:5303 sql_help.c:5594 +#: sql_help.c:5038 sql_help.c:5301 sql_help.c:5592 msgid "cycle_mark_default" msgstr "Cycle-Mark-Standard" -#: sql_help.c:5041 sql_help.c:5304 sql_help.c:5595 +#: sql_help.c:5039 sql_help.c:5302 sql_help.c:5593 msgid "cycle_path_col_name" msgstr "Cycle-Pfad-Spaltenname" -#: sql_help.c:5068 +#: sql_help.c:5066 msgid "new_table" msgstr "neue_Tabelle" -#: sql_help.c:5137 +#: sql_help.c:5135 msgid "snapshot_id" msgstr "Snapshot-ID" -#: sql_help.c:5426 +#: sql_help.c:5424 msgid "sort_expression" msgstr "Sortierausdruck" -#: sql_help.c:5449 +#: sql_help.c:5447 msgid "lsn" msgstr "" -#: sql_help.c:5452 +#: sql_help.c:5450 #, fuzzy #| msgid "argmode" msgid "mode" msgstr "Argmodus" -#: sql_help.c:5453 +#: sql_help.c:5451 #, fuzzy #| msgid "timeout expired" msgid "timeout" msgstr "Timeout abgelaufen" -#: sql_help.c:5454 +#: sql_help.c:5452 msgid "and mode can be:" msgstr "" -#: sql_help.c:5602 sql_help.c:6610 +#: sql_help.c:5600 sql_help.c:6608 msgid "abort the current transaction" msgstr "bricht die aktuelle Transaktion ab" -#: sql_help.c:5608 +#: sql_help.c:5606 msgid "change the definition of an aggregate function" msgstr "ändert die Definition einer Aggregatfunktion" -#: sql_help.c:5614 +#: sql_help.c:5612 msgid "change the definition of a collation" msgstr "ändert die Definition einer Sortierfolge" -#: sql_help.c:5620 +#: sql_help.c:5618 msgid "change the definition of a conversion" msgstr "ändert die Definition einer Zeichensatzkonversion" -#: sql_help.c:5626 +#: sql_help.c:5624 msgid "change a database" msgstr "ändert eine Datenbank" -#: sql_help.c:5632 +#: sql_help.c:5630 msgid "define default access privileges" msgstr "definiert vorgegebene Zugriffsprivilegien" -#: sql_help.c:5638 +#: sql_help.c:5636 msgid "change the definition of a domain" msgstr "ändert die Definition einer Domäne" -#: sql_help.c:5644 +#: sql_help.c:5642 msgid "change the definition of an event trigger" msgstr "ändert die Definition eines Ereignistriggers" -#: sql_help.c:5650 +#: sql_help.c:5648 msgid "change the definition of an extension" msgstr "ändert die Definition einer Erweiterung" -#: sql_help.c:5656 +#: sql_help.c:5654 msgid "change the definition of a foreign-data wrapper" msgstr "ändert die Definition eines Fremddaten-Wrappers" -#: sql_help.c:5662 +#: sql_help.c:5660 msgid "change the definition of a foreign table" msgstr "ändert die Definition einer Fremdtabelle" -#: sql_help.c:5668 +#: sql_help.c:5666 msgid "change the definition of a function" msgstr "ändert die Definition einer Funktion" -#: sql_help.c:5674 +#: sql_help.c:5672 msgid "change role name or membership" msgstr "ändert Rollenname oder -mitglieder" -#: sql_help.c:5680 +#: sql_help.c:5678 msgid "change the definition of an index" msgstr "ändert die Definition eines Index" -#: sql_help.c:5686 +#: sql_help.c:5684 msgid "change the definition of a procedural language" msgstr "ändert die Definition einer prozeduralen Sprache" -#: sql_help.c:5692 +#: sql_help.c:5690 msgid "change the definition of a large object" msgstr "ändert die Definition eines Large Object" -#: sql_help.c:5698 +#: sql_help.c:5696 msgid "change the definition of a materialized view" msgstr "ändert die Definition einer materialisierten Sicht" -#: sql_help.c:5704 +#: sql_help.c:5702 msgid "change the definition of an operator" msgstr "ändert die Definition eines Operators" -#: sql_help.c:5710 +#: sql_help.c:5708 msgid "change the definition of an operator class" msgstr "ändert die Definition einer Operatorklasse" -#: sql_help.c:5716 +#: sql_help.c:5714 msgid "change the definition of an operator family" msgstr "ändert die Definition einer Operatorfamilie" -#: sql_help.c:5722 +#: sql_help.c:5720 msgid "change the definition of a row-level security policy" msgstr "ändert die Definition einer Policy für Sicherheit auf Zeilenebene" -#: sql_help.c:5728 +#: sql_help.c:5726 msgid "change the definition of a procedure" msgstr "ändert die Definition einer Prozedur" -#: sql_help.c:5734 +#: sql_help.c:5732 msgid "change the definition of an SQL-property graph" msgstr "ändert die Definition eines SQL-Property-Graphs" -#: sql_help.c:5740 +#: sql_help.c:5738 msgid "change the definition of a publication" msgstr "ändert die Definition einer Publikation" -#: sql_help.c:5746 sql_help.c:5848 +#: sql_help.c:5744 sql_help.c:5846 msgid "change a database role" msgstr "ändert eine Datenbankrolle" -#: sql_help.c:5752 +#: sql_help.c:5750 msgid "change the definition of a routine" msgstr "ändert die Definition einer Routine" -#: sql_help.c:5758 +#: sql_help.c:5756 msgid "change the definition of a rule" msgstr "ändert die Definition einer Regel" -#: sql_help.c:5764 +#: sql_help.c:5762 msgid "change the definition of a schema" msgstr "ändert die Definition eines Schemas" -#: sql_help.c:5770 +#: sql_help.c:5768 msgid "change the definition of a sequence generator" msgstr "ändert die Definition eines Sequenzgenerators" -#: sql_help.c:5776 +#: sql_help.c:5774 msgid "change the definition of a foreign server" msgstr "ändert die Definition eines Fremdservers" -#: sql_help.c:5782 +#: sql_help.c:5780 msgid "change the definition of an extended statistics object" msgstr "ändert die Definition eines erweiterten Statistikobjekts" -#: sql_help.c:5788 +#: sql_help.c:5786 msgid "change the definition of a subscription" msgstr "ändert die Definition einer Subskription" -#: sql_help.c:5794 +#: sql_help.c:5792 msgid "change a server configuration parameter" msgstr "ändert einen Server-Konfigurationsparameter" -#: sql_help.c:5800 +#: sql_help.c:5798 msgid "change the definition of a table" msgstr "ändert die Definition einer Tabelle" -#: sql_help.c:5806 +#: sql_help.c:5804 msgid "change the definition of a tablespace" msgstr "ändert die Definition eines Tablespace" -#: sql_help.c:5812 +#: sql_help.c:5810 msgid "change the definition of a text search configuration" msgstr "ändert die Definition einer Textsuchekonfiguration" -#: sql_help.c:5818 +#: sql_help.c:5816 msgid "change the definition of a text search dictionary" msgstr "ändert die Definition eines Textsuchewörterbuchs" -#: sql_help.c:5824 +#: sql_help.c:5822 msgid "change the definition of a text search parser" msgstr "ändert die Definition eines Textsucheparsers" -#: sql_help.c:5830 +#: sql_help.c:5828 msgid "change the definition of a text search template" msgstr "ändert die Definition einer Textsuchevorlage" -#: sql_help.c:5836 +#: sql_help.c:5834 msgid "change the definition of a trigger" msgstr "ändert die Definition eines Triggers" -#: sql_help.c:5842 +#: sql_help.c:5840 msgid "change the definition of a type" msgstr "ändert die Definition eines Typs" -#: sql_help.c:5854 +#: sql_help.c:5852 msgid "change the definition of a user mapping" msgstr "ändert die Definition einer Benutzerabbildung" -#: sql_help.c:5860 +#: sql_help.c:5858 msgid "change the definition of a view" msgstr "ändert die Definition einer Sicht" -#: sql_help.c:5866 +#: sql_help.c:5864 msgid "collect statistics about a database" msgstr "sammelt Statistiken über eine Datenbank" -#: sql_help.c:5872 sql_help.c:6688 +#: sql_help.c:5870 sql_help.c:6686 msgid "start a transaction block" msgstr "startet einen Transaktionsblock" -#: sql_help.c:5878 +#: sql_help.c:5876 msgid "invoke a procedure" msgstr "ruft eine Prozedur auf" -#: sql_help.c:5884 +#: sql_help.c:5882 msgid "force a write-ahead log checkpoint" msgstr "erzwingt einen Checkpoint im Write-Ahead-Log" -#: sql_help.c:5890 +#: sql_help.c:5888 msgid "close a cursor" msgstr "schließt einen Cursor" -#: sql_help.c:5896 +#: sql_help.c:5894 msgid "cluster a table according to an index" msgstr "clustert eine Tabelle nach einem Index" -#: sql_help.c:5902 +#: sql_help.c:5900 msgid "define or change the comment of an object" msgstr "definiert oder ändert den Kommentar eines Objektes" -#: sql_help.c:5908 sql_help.c:6478 +#: sql_help.c:5906 sql_help.c:6476 msgid "commit the current transaction" msgstr "schließt die aktuelle Transaktion ab" -#: sql_help.c:5914 +#: sql_help.c:5912 msgid "commit a transaction that was earlier prepared for two-phase commit" msgstr "schließt eine Transaktion ab, die vorher für Two-Phase-Commit vorbereitet worden war" -#: sql_help.c:5920 +#: sql_help.c:5918 msgid "copy data between a file and a table" msgstr "kopiert Daten zwischen einer Datei und einer Tabelle" -#: sql_help.c:5926 +#: sql_help.c:5924 msgid "define a new access method" msgstr "definiert eine neue Zugriffsmethode" -#: sql_help.c:5932 +#: sql_help.c:5930 msgid "define a new aggregate function" msgstr "definiert eine neue Aggregatfunktion" -#: sql_help.c:5938 +#: sql_help.c:5936 msgid "define a new cast" msgstr "definiert eine neue Typumwandlung" -#: sql_help.c:5944 +#: sql_help.c:5942 msgid "define a new collation" msgstr "definiert eine neue Sortierfolge" -#: sql_help.c:5950 +#: sql_help.c:5948 msgid "define a new encoding conversion" msgstr "definiert eine neue Kodierungskonversion" -#: sql_help.c:5956 +#: sql_help.c:5954 msgid "create a new database" msgstr "erzeugt eine neue Datenbank" -#: sql_help.c:5962 +#: sql_help.c:5960 msgid "define a new domain" msgstr "definiert eine neue Domäne" -#: sql_help.c:5968 +#: sql_help.c:5966 msgid "define a new event trigger" msgstr "definiert einen neuen Ereignistrigger" -#: sql_help.c:5974 +#: sql_help.c:5972 msgid "install an extension" msgstr "installiert eine Erweiterung" -#: sql_help.c:5980 +#: sql_help.c:5978 msgid "define a new foreign-data wrapper" msgstr "definiert einen neuen Fremddaten-Wrapper" -#: sql_help.c:5986 +#: sql_help.c:5984 msgid "define a new foreign table" msgstr "definiert eine neue Fremdtabelle" -#: sql_help.c:5992 +#: sql_help.c:5990 msgid "define a new function" msgstr "definiert eine neue Funktion" -#: sql_help.c:5998 sql_help.c:6064 sql_help.c:6166 +#: sql_help.c:5996 sql_help.c:6062 sql_help.c:6164 msgid "define a new database role" msgstr "definiert eine neue Datenbankrolle" -#: sql_help.c:6004 +#: sql_help.c:6002 msgid "define a new index" msgstr "definiert einen neuen Index" -#: sql_help.c:6010 +#: sql_help.c:6008 msgid "define a new procedural language" msgstr "definiert eine neue prozedurale Sprache" -#: sql_help.c:6016 +#: sql_help.c:6014 msgid "define a new materialized view" msgstr "definiert eine neue materialisierte Sicht" -#: sql_help.c:6022 +#: sql_help.c:6020 msgid "define a new operator" msgstr "definiert einen neuen Operator" -#: sql_help.c:6028 +#: sql_help.c:6026 msgid "define a new operator class" msgstr "definiert eine neue Operatorklasse" -#: sql_help.c:6034 +#: sql_help.c:6032 msgid "define a new operator family" msgstr "definiert eine neue Operatorfamilie" -#: sql_help.c:6040 +#: sql_help.c:6038 msgid "define a new row-level security policy for a table" msgstr "definiert eine neue Policy für Sicherheit auf Zeilenebene für eine Tabelle" -#: sql_help.c:6046 +#: sql_help.c:6044 msgid "define a new procedure" msgstr "definiert eine neue Prozedur" -#: sql_help.c:6052 -msgid "define an SQL-property graph" +#: sql_help.c:6050 +#, fuzzy +#| msgid "define an SQL-property graph" +msgid "define a new SQL-property graph" msgstr "definiert einen SQL-Property-Graph" -#: sql_help.c:6058 +#: sql_help.c:6056 msgid "define a new publication" msgstr "definiert eine neue Publikation" -#: sql_help.c:6070 +#: sql_help.c:6068 msgid "define a new rewrite rule" msgstr "definiert eine neue Umschreiberegel" -#: sql_help.c:6076 +#: sql_help.c:6074 msgid "define a new schema" msgstr "definiert ein neues Schema" -#: sql_help.c:6082 +#: sql_help.c:6080 msgid "define a new sequence generator" msgstr "definiert einen neuen Sequenzgenerator" -#: sql_help.c:6088 +#: sql_help.c:6086 msgid "define a new foreign server" msgstr "definiert einen neuen Fremdserver" -#: sql_help.c:6094 +#: sql_help.c:6092 msgid "define extended statistics" msgstr "definiert erweiterte Statistiken" -#: sql_help.c:6100 +#: sql_help.c:6098 msgid "define a new subscription" msgstr "definiert eine neue Subskription" -#: sql_help.c:6106 +#: sql_help.c:6104 msgid "define a new table" msgstr "definiert eine neue Tabelle" -#: sql_help.c:6112 sql_help.c:6646 +#: sql_help.c:6110 sql_help.c:6644 msgid "define a new table from the results of a query" msgstr "definiert eine neue Tabelle aus den Ergebnissen einer Anfrage" -#: sql_help.c:6118 +#: sql_help.c:6116 msgid "define a new tablespace" msgstr "definiert einen neuen Tablespace" -#: sql_help.c:6124 +#: sql_help.c:6122 msgid "define a new text search configuration" msgstr "definiert eine neue Textsuchekonfiguration" -#: sql_help.c:6130 +#: sql_help.c:6128 msgid "define a new text search dictionary" msgstr "definiert ein neues Textsuchewörterbuch" -#: sql_help.c:6136 +#: sql_help.c:6134 msgid "define a new text search parser" msgstr "definiert einen neuen Textsucheparser" -#: sql_help.c:6142 +#: sql_help.c:6140 msgid "define a new text search template" msgstr "definiert eine neue Textsuchevorlage" -#: sql_help.c:6148 +#: sql_help.c:6146 msgid "define a new transform" msgstr "definiert eine neue Transformation" -#: sql_help.c:6154 +#: sql_help.c:6152 msgid "define a new trigger" msgstr "definiert einen neuen Trigger" -#: sql_help.c:6160 +#: sql_help.c:6158 msgid "define a new data type" msgstr "definiert einen neuen Datentyp" -#: sql_help.c:6172 +#: sql_help.c:6170 msgid "define a new mapping of a user to a foreign server" msgstr "definiert eine neue Abbildung eines Benutzers auf einen Fremdserver" -#: sql_help.c:6178 +#: sql_help.c:6176 msgid "define a new view" msgstr "definiert eine neue Sicht" -#: sql_help.c:6184 +#: sql_help.c:6182 msgid "deallocate a prepared statement" msgstr "gibt einen vorbereiteten Befehl frei" -#: sql_help.c:6190 +#: sql_help.c:6188 msgid "define a cursor" msgstr "definiert einen Cursor" -#: sql_help.c:6196 +#: sql_help.c:6194 msgid "delete rows of a table" msgstr "löscht Zeilen einer Tabelle" -#: sql_help.c:6202 +#: sql_help.c:6200 msgid "discard session state" msgstr "verwirft den Sitzungszustand" -#: sql_help.c:6208 +#: sql_help.c:6206 msgid "execute an anonymous code block" msgstr "führt einen anonymen Codeblock aus" -#: sql_help.c:6214 +#: sql_help.c:6212 msgid "remove an access method" msgstr "entfernt eine Zugriffsmethode" -#: sql_help.c:6220 +#: sql_help.c:6218 msgid "remove an aggregate function" msgstr "entfernt eine Aggregatfunktion" -#: sql_help.c:6226 +#: sql_help.c:6224 msgid "remove a cast" msgstr "entfernt eine Typumwandlung" -#: sql_help.c:6232 +#: sql_help.c:6230 msgid "remove a collation" msgstr "entfernt eine Sortierfolge" -#: sql_help.c:6238 +#: sql_help.c:6236 msgid "remove a conversion" msgstr "entfernt eine Zeichensatzkonversion" -#: sql_help.c:6244 +#: sql_help.c:6242 msgid "remove a database" msgstr "entfernt eine Datenbank" -#: sql_help.c:6250 +#: sql_help.c:6248 msgid "remove a domain" msgstr "entfernt eine Domäne" -#: sql_help.c:6256 +#: sql_help.c:6254 msgid "remove an event trigger" msgstr "entfernt einen Ereignistrigger" -#: sql_help.c:6262 +#: sql_help.c:6260 msgid "remove an extension" msgstr "entfernt eine Erweiterung" -#: sql_help.c:6268 +#: sql_help.c:6266 msgid "remove a foreign-data wrapper" msgstr "entfernt einen Fremddaten-Wrapper" -#: sql_help.c:6274 +#: sql_help.c:6272 msgid "remove a foreign table" msgstr "entfernt eine Fremdtabelle" -#: sql_help.c:6280 +#: sql_help.c:6278 msgid "remove a function" msgstr "entfernt eine Funktion" -#: sql_help.c:6286 sql_help.c:6358 sql_help.c:6460 +#: sql_help.c:6284 sql_help.c:6356 sql_help.c:6458 msgid "remove a database role" msgstr "entfernt eine Datenbankrolle" -#: sql_help.c:6292 +#: sql_help.c:6290 msgid "remove an index" msgstr "entfernt einen Index" -#: sql_help.c:6298 +#: sql_help.c:6296 msgid "remove a procedural language" msgstr "entfernt eine prozedurale Sprache" -#: sql_help.c:6304 +#: sql_help.c:6302 msgid "remove a materialized view" msgstr "entfernt eine materialisierte Sicht" -#: sql_help.c:6310 +#: sql_help.c:6308 msgid "remove an operator" msgstr "entfernt einen Operator" -#: sql_help.c:6316 +#: sql_help.c:6314 msgid "remove an operator class" msgstr "entfernt eine Operatorklasse" -#: sql_help.c:6322 +#: sql_help.c:6320 msgid "remove an operator family" msgstr "entfernt eine Operatorfamilie" -#: sql_help.c:6328 +#: sql_help.c:6326 msgid "remove database objects owned by a database role" msgstr "entfernt die einer Datenbankrolle gehörenden Datenbankobjekte" -#: sql_help.c:6334 +#: sql_help.c:6332 msgid "remove a row-level security policy from a table" msgstr "entfernt eine Policy für Sicherheit auf Zeilenebene von einer Tabelle" -#: sql_help.c:6340 +#: sql_help.c:6338 msgid "remove a procedure" msgstr "entfernt eine Prozedur" -#: sql_help.c:6346 +#: sql_help.c:6344 msgid "remove an SQL-property graph" msgstr "entfernt einen SQL-Property-Graph" -#: sql_help.c:6352 +#: sql_help.c:6350 msgid "remove a publication" msgstr "entfernt eine Publikation" -#: sql_help.c:6364 +#: sql_help.c:6362 msgid "remove a routine" msgstr "entfernt eine Routine" -#: sql_help.c:6370 +#: sql_help.c:6368 msgid "remove a rewrite rule" msgstr "entfernt eine Umschreiberegel" -#: sql_help.c:6376 +#: sql_help.c:6374 msgid "remove a schema" msgstr "entfernt ein Schema" -#: sql_help.c:6382 +#: sql_help.c:6380 msgid "remove a sequence" msgstr "entfernt eine Sequenz" -#: sql_help.c:6388 +#: sql_help.c:6386 msgid "remove a foreign server descriptor" msgstr "entfernt einen Fremdserverdeskriptor" -#: sql_help.c:6394 +#: sql_help.c:6392 msgid "remove extended statistics" msgstr "entfernt erweiterte Statistiken" -#: sql_help.c:6400 +#: sql_help.c:6398 msgid "remove a subscription" msgstr "entfernt eine Subskription" -#: sql_help.c:6406 +#: sql_help.c:6404 msgid "remove a table" msgstr "entfernt eine Tabelle" -#: sql_help.c:6412 +#: sql_help.c:6410 msgid "remove a tablespace" msgstr "entfernt einen Tablespace" -#: sql_help.c:6418 +#: sql_help.c:6416 msgid "remove a text search configuration" msgstr "entfernt eine Textsuchekonfiguration" -#: sql_help.c:6424 +#: sql_help.c:6422 msgid "remove a text search dictionary" msgstr "entfernt ein Textsuchewörterbuch" -#: sql_help.c:6430 +#: sql_help.c:6428 msgid "remove a text search parser" msgstr "entfernt einen Textsucheparser" -#: sql_help.c:6436 +#: sql_help.c:6434 msgid "remove a text search template" msgstr "entfernt eine Textsuchevorlage" -#: sql_help.c:6442 +#: sql_help.c:6440 msgid "remove a transform" msgstr "entfernt eine Transformation" -#: sql_help.c:6448 +#: sql_help.c:6446 msgid "remove a trigger" msgstr "entfernt einen Trigger" -#: sql_help.c:6454 +#: sql_help.c:6452 msgid "remove a data type" msgstr "entfernt einen Datentyp" -#: sql_help.c:6466 +#: sql_help.c:6464 msgid "remove a user mapping for a foreign server" msgstr "entfernt eine Benutzerabbildung für einen Fremdserver" -#: sql_help.c:6472 +#: sql_help.c:6470 msgid "remove a view" msgstr "entfernt eine Sicht" -#: sql_help.c:6484 +#: sql_help.c:6482 msgid "execute a prepared statement" msgstr "führt einen vorbereiteten Befehl aus" -#: sql_help.c:6490 +#: sql_help.c:6488 msgid "show the execution plan of a statement" msgstr "zeigt den Ausführungsplan eines Befehls" -#: sql_help.c:6496 +#: sql_help.c:6494 msgid "retrieve rows from a query using a cursor" msgstr "liest Zeilen aus einer Anfrage mit einem Cursor" -#: sql_help.c:6502 +#: sql_help.c:6500 msgid "define access privileges" msgstr "definiert Zugriffsprivilegien" -#: sql_help.c:6508 +#: sql_help.c:6506 msgid "import table definitions from a foreign server" msgstr "importiert Tabellendefinitionen von einem Fremdserver" -#: sql_help.c:6514 +#: sql_help.c:6512 msgid "create new rows in a table" msgstr "erzeugt neue Zeilen in einer Tabelle" -#: sql_help.c:6520 +#: sql_help.c:6518 msgid "listen for a notification" msgstr "hört auf eine Benachrichtigung" -#: sql_help.c:6526 +#: sql_help.c:6524 msgid "load a shared library file" msgstr "lädt eine dynamische Bibliotheksdatei" -#: sql_help.c:6532 +#: sql_help.c:6530 msgid "lock a table" msgstr "sperrt eine Tabelle" -#: sql_help.c:6538 +#: sql_help.c:6536 msgid "conditionally insert, update, or delete rows of a table" msgstr "fügt Zeilen in eine Tabelle ein oder ändert oder löscht Zeilen einer Tabelle, abhängig von Bedingungen" -#: sql_help.c:6544 +#: sql_help.c:6542 msgid "position a cursor" msgstr "positioniert einen Cursor" -#: sql_help.c:6550 +#: sql_help.c:6548 msgid "generate a notification" msgstr "erzeugt eine Benachrichtigung" -#: sql_help.c:6556 +#: sql_help.c:6554 msgid "prepare a statement for execution" msgstr "bereitet einen Befehl zur Ausführung vor" -#: sql_help.c:6562 +#: sql_help.c:6560 msgid "prepare the current transaction for two-phase commit" msgstr "bereitet die aktuelle Transaktion für Two-Phase-Commit vor" -#: sql_help.c:6568 +#: sql_help.c:6566 msgid "change the ownership of database objects owned by a database role" msgstr "ändert den Eigentümer der der Rolle gehörenden Datenbankobjekte" -#: sql_help.c:6574 +#: sql_help.c:6572 msgid "replace the contents of a materialized view" msgstr "ersetzt den Inhalt einer materialisierten Sicht" -#: sql_help.c:6580 +#: sql_help.c:6578 msgid "rebuild indexes" msgstr "baut Indexe neu" -#: sql_help.c:6586 +#: sql_help.c:6584 msgid "release a previously defined savepoint" msgstr "gibt einen zuvor definierten Sicherungspunkt frei" -#: sql_help.c:6592 +#: sql_help.c:6590 msgid "rewrite a table to reclaim disk space" msgstr "" -#: sql_help.c:6598 +#: sql_help.c:6596 msgid "restore the value of a run-time parameter to the default value" msgstr "setzt einen Konfigurationsparameter auf die Voreinstellung zurück" -#: sql_help.c:6604 +#: sql_help.c:6602 msgid "remove access privileges" msgstr "entfernt Zugriffsprivilegien" -#: sql_help.c:6616 +#: sql_help.c:6614 msgid "cancel a transaction that was earlier prepared for two-phase commit" msgstr "storniert eine Transaktion, die vorher für Two-Phase-Commit vorbereitet worden war" -#: sql_help.c:6622 +#: sql_help.c:6620 msgid "roll back to a savepoint" msgstr "rollt eine Transaktion bis zu einem Sicherungspunkt zurück" -#: sql_help.c:6628 +#: sql_help.c:6626 msgid "define a new savepoint within the current transaction" msgstr "definiert einen neuen Sicherungspunkt in der aktuellen Transaktion" -#: sql_help.c:6634 +#: sql_help.c:6632 msgid "define or change a security label applied to an object" msgstr "definiert oder ändert ein Security-Label eines Objektes" -#: sql_help.c:6640 sql_help.c:6694 sql_help.c:6736 +#: sql_help.c:6638 sql_help.c:6692 sql_help.c:6734 msgid "retrieve rows from a table or view" msgstr "liest Zeilen aus einer Tabelle oder Sicht" -#: sql_help.c:6652 +#: sql_help.c:6650 msgid "change a run-time parameter" msgstr "ändert einen Konfigurationsparameter" -#: sql_help.c:6658 +#: sql_help.c:6656 msgid "set constraint check timing for the current transaction" msgstr "setzt die Zeitsteuerung für Check-Constraints in der aktuellen Transaktion" -#: sql_help.c:6664 +#: sql_help.c:6662 msgid "set the current user identifier of the current session" msgstr "setzt den aktuellen Benutzernamen der aktuellen Sitzung" -#: sql_help.c:6670 +#: sql_help.c:6668 msgid "set the session user identifier and the current user identifier of the current session" msgstr "setzt den Sitzungsbenutzernamen und den aktuellen Benutzernamen der aktuellen Sitzung" -#: sql_help.c:6676 +#: sql_help.c:6674 msgid "set the characteristics of the current transaction" msgstr "setzt die Charakteristika der aktuellen Transaktion" -#: sql_help.c:6682 +#: sql_help.c:6680 msgid "show the value of a run-time parameter" msgstr "zeigt den Wert eines Konfigurationsparameters" -#: sql_help.c:6700 +#: sql_help.c:6698 msgid "empty a table or set of tables" msgstr "leert eine oder mehrere Tabellen" -#: sql_help.c:6706 +#: sql_help.c:6704 msgid "stop listening for a notification" msgstr "beendet das Hören auf eine Benachrichtigung" -#: sql_help.c:6712 +#: sql_help.c:6710 msgid "update rows of a table" msgstr "aktualisiert Zeilen einer Tabelle" -#: sql_help.c:6718 +#: sql_help.c:6716 msgid "garbage-collect and optionally analyze a database" msgstr "säubert und analysiert eine Datenbank" -#: sql_help.c:6724 +#: sql_help.c:6722 msgid "compute a set of rows" msgstr "berechnet eine Zeilenmenge" -#: sql_help.c:6730 +#: sql_help.c:6728 msgid "wait for WAL to reach a target LSN" msgstr "" @@ -7828,7 +7820,7 @@ msgstr "überflüssiges Kommandozeilenargument »%s« ignoriert" msgid "could not find own program executable" msgstr "konnte eigene Programmdatei nicht finden" -#: tab-complete.in.c:7031 +#: tab-complete.in.c:7058 #, c-format msgid "" "tab completion query failed: %s\n" @@ -7864,22 +7856,22 @@ msgstr "ungültiger Wert »%s« für Variable »%s«: muss größer als %.2f sei msgid "invalid value \"%s\" for variable \"%s\": must be less than %.2f" msgstr "ungültiger Wert »%s« für Variable »%s«: muss kleiner als %.2f sein" -#: variables.c:241 +#: variables.c:242 #, c-format msgid "value \"%s\" is out of range for variable \"%s\"" msgstr "Wert »%s« ist außerhalb des gültigen Bereichs für Variable »%s«" -#: variables.c:247 +#: variables.c:248 #, c-format msgid "invalid value \"%s\" for variable \"%s\"" msgstr "ungültiger Wert »%s« für Variable »%s«" -#: variables.c:294 +#: variables.c:295 #, c-format msgid "invalid variable name: \"%s\"" msgstr "ungültiger Variablenname: »%s«" -#: variables.c:488 +#: variables.c:489 #, c-format msgid "" "unrecognized value \"%s\" for \"%s\"\n" @@ -7888,19 +7880,8 @@ msgstr "" "unbekannter Wert »%s« für »%s«\n" "Verfügbare Werte sind: %s." -#~ msgid "" -#~ " \\pset [NAME [VALUE]] set table output option\n" -#~ " (border|columns|csv_fieldsep|expanded|fieldsep|\n" -#~ " fieldsep_zero|footer|format|linestyle|null|\n" -#~ " numericlocale|pager|pager_min_lines|recordsep|\n" -#~ " recordsep_zero|tableattr|title|tuples_only|\n" -#~ " unicode_border_linestyle|unicode_column_linestyle|\n" -#~ " unicode_header_linestyle|xheader_width)\n" -#~ msgstr "" -#~ " \\pset [NAME [WERT]] Tabellenausgabeoption setzen\n" -#~ " (border|columns|csv_fieldsep|expanded|fieldsep|\n" -#~ " fieldsep_zero|footer|format|linestyle|null|\n" -#~ " numericlocale|pager|pager_min_lines|recordsep|\n" -#~ " recordsep_zero|tableattr|title|tuples_only|\n" -#~ " unicode_border_linestyle|unicode_column_linestyle|\n" -#~ " unicode_header_linestyle|xheader_width)\n" +#~ msgid ", " +#~ msgstr ", " + +#~ msgid "Publications:" +#~ msgstr "Publikationen:" diff --git a/src/bin/psql/po/ja.po b/src/bin/psql/po/ja.po index be73be2ada3..3249b1e1b10 100644 --- a/src/bin/psql/po/ja.po +++ b/src/bin/psql/po/ja.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: psql (PostgreSQL 19)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-15 18:10+0900\n" -"PO-Revision-Date: 2026-05-20 11:53+0900\n" +"POT-Creation-Date: 2026-07-06 09:46+0900\n" +"PO-Revision-Date: 2026-07-06 15:11+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" @@ -168,42 +168,42 @@ msgid "(%lu row)" msgid_plural "(%lu rows)" msgstr[0] "(%lu 行)" -#: ../../fe_utils/print.c:3173 +#: ../../fe_utils/print.c:3191 #, c-format msgid "Interrupted\n" msgstr "割り込み\n" -#: ../../fe_utils/print.c:3207 +#: ../../fe_utils/print.c:3225 #, c-format msgid "Cannot print table contents: number of cells % is equal to or exceeds maximum %zu.\n" msgstr "テーブルの内容を表示できません: セル数%が上限値%zu以上です。\n" -#: ../../fe_utils/print.c:3248 +#: ../../fe_utils/print.c:3266 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "テーブルの内容にヘッダーを追加できません: 列数の上限値%dを超えています。\n" -#: ../../fe_utils/print.c:3291 +#: ../../fe_utils/print.c:3309 #, c-format msgid "Cannot add cell to table content: total cell count of % exceeded.\n" msgstr "テーブルの内容にセルを追加できません: セルの総数%を超過しています。\n" -#: ../../fe_utils/print.c:3719 +#: ../../fe_utils/print.c:3737 #, c-format msgid "invalid output format (internal error): %d" msgstr "出力フォーマットが無効(内部エラー):%d" -#: ../../fe_utils/psqlscan.l:729 +#: ../../fe_utils/psqlscan.l:736 #, c-format msgid "skipping recursive expansion of variable \"%s\"" msgstr "変数\"%s\"の再帰展開をスキップしています" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "シェルコマンドの引数に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "データベース名に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" @@ -259,15 +259,15 @@ msgstr "現在データベースに接続していません。\n" msgid "Connection Information" msgstr "接続情報" -#: command.c:840 describe.c:4972 +#: command.c:840 describe.c:4794 msgid "Parameter" msgstr "パラメータ" -#: command.c:841 describe.c:4973 +#: command.c:841 describe.c:4795 msgid "Value" msgstr "値" -#: command.c:844 describe.c:4102 +#: command.c:844 describe.c:3937 msgid "Database" msgstr "データベース" @@ -291,7 +291,7 @@ msgstr "ホスト" msgid "Server Port" msgstr "サーバーポート" -#: command.c:882 describe.c:250 describe.c:3839 describe.c:4184 +#: command.c:882 describe.c:240 describe.c:3679 describe.c:4019 msgid "Options" msgstr "オプション" @@ -361,7 +361,7 @@ msgstr "なし" msgid "no query buffer" msgstr "問い合わせバッファがありません" -#: command.c:1390 command.c:6462 +#: command.c:1390 command.c:6446 #, c-format msgid "invalid line number: %s" msgstr "不正な行番号です: %s" @@ -375,9 +375,9 @@ msgstr "変更されていません" msgid "%s: invalid encoding name or conversion procedure not found" msgstr "%s: エンコーディング名が不正であるか、または変換プロシージャが見つかりません。" -#: command.c:1657 command.c:2597 command.c:4076 command.c:4274 command.c:6568 +#: command.c:1657 command.c:2597 command.c:4076 command.c:4274 command.c:6552 #: common.c:233 common.c:282 common.c:457 common.c:1180 common.c:1198 -#: common.c:1266 common.c:1378 common.c:1416 common.c:1707 common.c:1787 +#: common.c:1266 common.c:1378 common.c:1416 common.c:1720 common.c:1800 #: copy.c:486 copy.c:731 large_obj.c:157 large_obj.c:192 large_obj.c:254 #: startup.c:310 #, c-format @@ -959,16 +959,16 @@ msgstr "ビューのOID取得" msgid "Get function's definition" msgstr "関数の定義を取得" -#: command.c:6287 +#: command.c:6286 msgid "Get view's definition and details" msgstr "ビューの定義と詳細を取得" -#: command.c:6357 +#: command.c:6341 #, c-format msgid "\"%s.%s\" is not a view" msgstr "\"%s.%s\"はビューではありません" -#: command.c:6373 +#: command.c:6357 #, c-format msgid "could not parse reloptions array" msgstr "reloptions配列をパースできませんでした" @@ -1028,7 +1028,7 @@ msgstr "時間: %.3f ミリ秒 (%02d:%02d:%06.3f)\n" msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" msgstr "時間: %.3f ミリ秒 (%.0f 日 %02d:%02d:%06.3f)\n" -#: common.c:663 common.c:720 common.c:1132 describe.c:6659 +#: common.c:663 common.c:720 common.c:1132 describe.c:6456 #, c-format msgid "You are currently not connected to a database." msgstr "現在データベースに接続していません。" @@ -1097,14 +1097,13 @@ msgstr "文: %s" msgid "unexpected transaction status (%d)" msgstr "想定外のトランザクション状態(%d)" -#: common.c:1400 describe.c:2198 +#: common.c:1400 describe.c:2063 msgid "Column" msgstr "列" -#: common.c:1401 describe.c:179 describe.c:368 describe.c:386 describe.c:1094 -#: describe.c:1258 describe.c:1794 describe.c:1818 describe.c:2199 -#: describe.c:4292 describe.c:4566 describe.c:4815 describe.c:4979 -#: describe.c:6283 +#: common.c:1401 describe.c:169 describe.c:355 describe.c:373 describe.c:1072 +#: describe.c:1204 describe.c:1686 describe.c:2064 describe.c:4127 +#: describe.c:4388 describe.c:4637 describe.c:4801 describe.c:6080 msgid "Type" msgstr "タイプ" @@ -1113,22 +1112,22 @@ msgstr "タイプ" msgid "The command has no result, or the result has no columns.\n" msgstr "このコマンドは結果を返却しないか、結果にカラムが含まれません。\n" -#: common.c:1672 +#: common.c:1685 #, c-format msgid "No pending results to get" msgstr "取得すべき保留中の結果はありません" -#: common.c:1750 +#: common.c:1763 #, c-format msgid "fetching results in chunked mode failed" msgstr "チャンクモードでの結果の取得に失敗しました" -#: common.c:1799 +#: common.c:1812 #, c-format msgid "Pipeline aborted, command did not run" msgstr "パイプラインが中断され、コマンドは実行されませんでした" -#: common.c:1895 +#: common.c:1908 #, c-format msgid "COPY in a pipeline is not supported, aborting connection" msgstr "パイプライン中のCOPYはサポートされていません、接続を中断します" @@ -1193,47 +1192,47 @@ msgstr "読み取りエラーのため中止" msgid "trying to exit copy mode" msgstr "コピーモードを終了しようとしています。" -#: crosstabview.c:124 +#: crosstabview.c:127 #, c-format msgid "\\crosstabview: statement did not return a result set" msgstr "\\crosstabview: 文は結果セットを返しませんでした" -#: crosstabview.c:130 +#: crosstabview.c:133 #, c-format msgid "\\crosstabview: query must return at least three columns" msgstr "\\crosstabview: 問い合わせは、少なくとも3つの列を返す必要があります" -#: crosstabview.c:157 +#: crosstabview.c:160 #, c-format msgid "\\crosstabview: vertical and horizontal headers must be different columns" msgstr "\\crosstabview: 垂直方向と水平方向のヘッダーは異なった列にする必要があります" -#: crosstabview.c:173 +#: crosstabview.c:176 #, c-format msgid "\\crosstabview: data column must be specified when query returns more than three columns" msgstr "\\crosstabview: 問い合わせが 4 つ以上の列を返す場合、データ列を指定する必要があります" -#: crosstabview.c:229 +#: crosstabview.c:232 #, c-format msgid "\\crosstabview: maximum number of columns (%d) exceeded" msgstr "列数が制限値(%d)を超えています" -#: crosstabview.c:396 +#: crosstabview.c:399 #, c-format msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" msgstr "\\crosstabview: 問い合わせ結果の中の\"%s\"行 \"%s\"列に複数のデータ値が含まれています" -#: crosstabview.c:643 +#: crosstabview.c:670 #, c-format msgid "\\crosstabview: column number %d is out of range 1..%d" msgstr "\\crosstabview: 列番号%dが範囲外です(1..%d)" -#: crosstabview.c:668 +#: crosstabview.c:695 #, c-format msgid "\\crosstabview: ambiguous column name: \"%s\"" msgstr "\\crosstabview: 列名があいまいです: \"%s\"" -#: crosstabview.c:676 +#: crosstabview.c:703 #, c-format msgid "\\crosstabview: column name not found: \"%s\"" msgstr "\\crosstabview: 列名が見つかりませんでした: \"%s\"" @@ -1242,41 +1241,41 @@ msgstr "\\crosstabview: 列名が見つかりませんでした: \"%s\"" msgid "Get matching aggregates" msgstr "対象の集約を取得" -#: describe.c:96 describe.c:348 describe.c:656 describe.c:834 describe.c:1085 -#: describe.c:1245 describe.c:1322 describe.c:4280 describe.c:4553 -#: describe.c:4813 describe.c:4895 describe.c:5133 describe.c:5352 -#: describe.c:5606 describe.c:5852 describe.c:5922 describe.c:5933 -#: describe.c:5990 describe.c:6399 describe.c:6481 +#: describe.c:96 describe.c:335 describe.c:634 describe.c:812 describe.c:1063 +#: describe.c:1191 describe.c:1268 describe.c:4115 describe.c:4375 +#: describe.c:4635 describe.c:4717 describe.c:4935 describe.c:5154 +#: describe.c:5403 describe.c:5649 describe.c:5719 describe.c:5730 +#: describe.c:5787 describe.c:6196 describe.c:6278 msgid "Schema" msgstr "スキーマ" -#: describe.c:97 describe.c:176 describe.c:238 describe.c:349 describe.c:657 -#: describe.c:835 describe.c:967 describe.c:1086 describe.c:1323 -#: describe.c:4281 describe.c:4554 describe.c:4729 describe.c:4814 -#: describe.c:4896 describe.c:5061 describe.c:5134 describe.c:5353 -#: describe.c:5476 describe.c:5607 describe.c:5853 describe.c:5923 -#: describe.c:5934 describe.c:5991 describe.c:6192 describe.c:6264 -#: describe.c:6478 describe.c:6708 describe.c:7116 +#: describe.c:97 describe.c:166 describe.c:228 describe.c:336 describe.c:635 +#: describe.c:813 describe.c:945 describe.c:1064 describe.c:1269 +#: describe.c:4116 describe.c:4376 describe.c:4551 describe.c:4636 +#: describe.c:4718 describe.c:4873 describe.c:4936 describe.c:5155 +#: describe.c:5273 describe.c:5404 describe.c:5650 describe.c:5720 +#: describe.c:5731 describe.c:5788 describe.c:5989 describe.c:6061 +#: describe.c:6275 describe.c:6495 describe.c:6883 msgid "Name" msgstr "名前" -#: describe.c:98 describe.c:361 describe.c:379 +#: describe.c:98 describe.c:348 describe.c:366 msgid "Result data type" msgstr "結果のデータ型" -#: describe.c:99 describe.c:362 describe.c:380 +#: describe.c:99 describe.c:349 describe.c:367 msgid "Argument data types" msgstr "引数のデータ型" -#: describe.c:107 describe.c:114 describe.c:187 describe.c:252 describe.c:438 -#: describe.c:688 describe.c:854 describe.c:1019 describe.c:1325 -#: describe.c:2219 describe.c:4001 describe.c:4340 describe.c:4607 -#: describe.c:4753 describe.c:4827 describe.c:4905 describe.c:5074 -#: describe.c:5176 describe.c:5264 describe.c:5411 describe.c:5485 -#: describe.c:5608 describe.c:5760 describe.c:5803 describe.c:5869 -#: describe.c:5926 describe.c:5935 describe.c:5992 describe.c:6210 -#: describe.c:6286 describe.c:6413 describe.c:6482 describe.c:6972 -#: describe.c:7203 describe.c:7685 +#: describe.c:107 describe.c:114 describe.c:177 describe.c:242 describe.c:424 +#: describe.c:666 describe.c:832 describe.c:997 describe.c:1271 describe.c:2084 +#: describe.c:3837 describe.c:4175 describe.c:4429 describe.c:4575 +#: describe.c:4649 describe.c:4727 describe.c:4886 describe.c:4978 +#: describe.c:5066 describe.c:5208 describe.c:5282 describe.c:5405 +#: describe.c:5557 describe.c:5600 describe.c:5666 describe.c:5723 +#: describe.c:5732 describe.c:5789 describe.c:6007 describe.c:6083 +#: describe.c:6210 describe.c:6279 describe.c:6749 describe.c:6970 +#: describe.c:7452 msgid "Description" msgstr "説明" @@ -1284,1501 +1283,1478 @@ msgstr "説明" msgid "List of aggregate functions" msgstr "集約関数一覧" -#: describe.c:161 -#, c-format -msgid "The server (version %s) does not support access methods." -msgstr "このサーバー(バージョン%s)はアクセスメソッドをサポートしていません。" - -#: describe.c:169 +#: describe.c:159 msgid "Get matching access methods" msgstr "該当アクセスメソッドを取得" -#: describe.c:177 +#: describe.c:167 msgid "Index" msgstr "インデックス" -#: describe.c:178 describe.c:4300 describe.c:4579 describe.c:6400 +#: describe.c:168 describe.c:4135 describe.c:4401 describe.c:6197 msgid "Table" msgstr "テーブル" -#: describe.c:186 describe.c:6194 +#: describe.c:176 describe.c:5991 msgid "Handler" msgstr "ハンドラ" -#: describe.c:209 +#: describe.c:199 msgid "List of access methods" msgstr "アクセスメソッド一覧" -#: describe.c:233 +#: describe.c:223 msgid "Get matching tablespaces" msgstr "該当テーブル空間を取得" -#: describe.c:239 describe.c:421 describe.c:681 describe.c:968 describe.c:1244 -#: describe.c:4293 describe.c:4555 describe.c:4730 describe.c:5063 -#: describe.c:5477 describe.c:6193 describe.c:6265 describe.c:6709 -#: describe.c:6959 describe.c:7117 describe.c:7315 describe.c:7401 -#: describe.c:7673 +#: describe.c:229 describe.c:407 describe.c:659 describe.c:946 describe.c:1190 +#: describe.c:4128 describe.c:4377 describe.c:4552 describe.c:4875 +#: describe.c:5274 describe.c:5990 describe.c:6062 describe.c:6496 +#: describe.c:6736 describe.c:6884 describe.c:7082 describe.c:7168 +#: describe.c:7440 msgid "Owner" msgstr "所有者" -#: describe.c:240 +#: describe.c:230 msgid "Location" msgstr "場所" -#: describe.c:251 describe.c:679 describe.c:1017 describe.c:4339 +#: describe.c:241 describe.c:657 describe.c:995 describe.c:4174 msgid "Size" msgstr "サイズ" -#: describe.c:274 +#: describe.c:264 msgid "List of tablespaces" msgstr "テーブル空間一覧" -#: describe.c:320 +#: describe.c:307 #, c-format msgid "\\df only takes [%s] as options" msgstr "\\dfで指定できるオプションは [%s] のみです" -#: describe.c:328 +#: describe.c:315 #, c-format msgid "\\df does not take a \"%c\" option with server version %s" msgstr "\\dfはこのサーバーバージョン%2$sでは\"%1$c\"オプションは指定できません" -#: describe.c:344 +#: describe.c:331 msgid "Get matching functions" msgstr "該当関数を取得" #. translator: "agg" is short for "aggregate" -#: describe.c:364 describe.c:382 +#: describe.c:351 describe.c:369 msgid "agg" msgstr "集約" -#: describe.c:365 describe.c:383 +#: describe.c:352 describe.c:370 msgid "window" msgstr "ウィンドウ" -#: describe.c:366 +#: describe.c:353 msgid "proc" msgstr "プロシージャ" -#: describe.c:367 describe.c:385 +#: describe.c:354 describe.c:372 msgid "func" msgstr "関数" -#: describe.c:384 describe.c:1455 +#: describe.c:371 describe.c:1401 msgid "trigger" msgstr "トリガー" -#: describe.c:399 +#: describe.c:386 msgid "immutable" msgstr "IMMUTABLE" -#: describe.c:400 +#: describe.c:387 msgid "stable" msgstr "STABLE" -#: describe.c:401 +#: describe.c:388 msgid "volatile" msgstr "VOLATILE" -#: describe.c:402 +#: describe.c:389 msgid "Volatility" msgstr "関数の変動性分類" -#: describe.c:413 +#: describe.c:399 msgid "restricted" msgstr "制限付き" -#: describe.c:414 +#: describe.c:400 msgid "safe" msgstr "安全" -#: describe.c:415 +#: describe.c:401 msgid "unsafe" msgstr "危険" -#: describe.c:416 +#: describe.c:402 msgid "Parallel" msgstr "並列実行" -#: describe.c:422 +#: describe.c:408 msgid "definer" msgstr "定義ロール" -#: describe.c:423 +#: describe.c:409 msgid "invoker" msgstr "起動ロール" -#: describe.c:424 +#: describe.c:410 msgid "Security" msgstr "セキュリティ" -#: describe.c:425 describe.c:845 describe.c:1799 describe.c:1823 -#: describe.c:2066 describe.c:4899 describe.c:5252 describe.c:5261 -#: describe.c:5400 describe.c:5405 describe.c:7303 describe.c:7504 +#: describe.c:411 describe.c:823 describe.c:1691 describe.c:1931 +#: describe.c:4721 describe.c:5054 describe.c:5063 describe.c:5197 +#: describe.c:5202 describe.c:7070 describe.c:7271 msgid "yes" msgstr "はい" -#: describe.c:426 describe.c:846 describe.c:1800 describe.c:1824 -#: describe.c:2067 describe.c:4899 describe.c:5249 describe.c:5262 -#: describe.c:5400 describe.c:7304 describe.c:7505 +#: describe.c:412 describe.c:824 describe.c:1692 describe.c:1932 +#: describe.c:4721 describe.c:5051 describe.c:5064 describe.c:5197 +#: describe.c:7071 describe.c:7272 msgid "no" msgstr "いいえ" -#: describe.c:427 describe.c:847 describe.c:5263 describe.c:7506 +#: describe.c:413 describe.c:825 describe.c:5065 describe.c:7273 msgid "Leakproof?" msgstr "無漏洩?" -#: describe.c:432 +#: describe.c:418 msgid "Language" msgstr "手続き言語" -#: describe.c:435 describe.c:678 +#: describe.c:421 describe.c:656 msgid "Internal name" msgstr "内部名" -#: describe.c:614 +#: describe.c:600 msgid "List of functions" msgstr "関数一覧" -#: describe.c:652 +#: describe.c:630 msgid "Get matching types" msgstr "該当型を取得" -#: describe.c:680 +#: describe.c:658 msgid "Elements" msgstr "構成要素" -#: describe.c:731 +#: describe.c:709 msgid "List of data types" msgstr "データ型一覧" -#: describe.c:827 +#: describe.c:805 msgid "Get matching operators" msgstr "該当演算子を取得" -#: describe.c:836 +#: describe.c:814 msgid "Left arg type" msgstr "左辺の型" -#: describe.c:837 +#: describe.c:815 msgid "Right arg type" msgstr "右辺の型" -#: describe.c:838 +#: describe.c:816 msgid "Result type" msgstr "結果の型" -#: describe.c:844 describe.c:5069 describe.c:5241 describe.c:5759 -#: describe.c:7602 describe.c:7606 +#: describe.c:822 describe.c:4881 describe.c:5043 describe.c:5556 +#: describe.c:7369 describe.c:7373 msgid "Function" msgstr "関数" -#: describe.c:931 +#: describe.c:909 msgid "List of operators" msgstr "演算子一覧" -#: describe.c:961 +#: describe.c:939 msgid "Get matching databases" msgstr "該当データベースを取得" -#: describe.c:969 +#: describe.c:947 msgid "Encoding" msgstr "エンコーディング" -#: describe.c:977 describe.c:981 +#: describe.c:955 describe.c:959 msgid "Locale Provider" msgstr "ロケールプロバイダー" -#: describe.c:985 describe.c:5372 +#: describe.c:963 describe.c:5169 msgid "Collate" msgstr "照合順序" -#: describe.c:986 describe.c:5373 +#: describe.c:964 describe.c:5170 msgid "Ctype" msgstr "Ctype(変換演算子)" -#: describe.c:990 describe.c:994 describe.c:998 describe.c:5378 describe.c:5382 -#: describe.c:5386 +#: describe.c:968 describe.c:972 describe.c:976 describe.c:5175 describe.c:5179 +#: describe.c:5183 msgid "Locale" msgstr "ロケール" -#: describe.c:1002 describe.c:1006 describe.c:5391 describe.c:5395 +#: describe.c:980 describe.c:984 describe.c:5188 describe.c:5192 msgid "ICU Rules" msgstr "ICUルール:" -#: describe.c:1018 +#: describe.c:996 msgid "Tablespace" msgstr "テーブル空間" -#: describe.c:1043 +#: describe.c:1021 msgid "List of databases" msgstr "データベース一覧" -#: describe.c:1071 +#: describe.c:1049 msgid "Get access privileges of matching relations" msgstr "該当リレーションのアクセス権限を取得" -#: describe.c:1087 describe.c:1247 describe.c:4282 +#: describe.c:1065 describe.c:1193 describe.c:4117 msgid "table" msgstr "テーブル" -#: describe.c:1088 describe.c:4283 +#: describe.c:1066 describe.c:4118 msgid "view" msgstr "ビュー" -#: describe.c:1089 describe.c:4284 +#: describe.c:1067 describe.c:4119 msgid "materialized view" msgstr "実体化ビュー" -#: describe.c:1090 describe.c:1249 describe.c:4286 +#: describe.c:1068 describe.c:1195 describe.c:4121 msgid "sequence" msgstr "シーケンス" -#: describe.c:1091 describe.c:4288 +#: describe.c:1069 describe.c:4123 msgid "foreign table" msgstr "外部テーブル" -#: describe.c:1092 describe.c:4291 +#: describe.c:1070 describe.c:4126 msgid "property graph" msgstr "プロパティ・グラフ" -#: describe.c:1093 describe.c:4289 describe.c:4564 +#: describe.c:1071 describe.c:4124 describe.c:4386 msgid "partitioned table" msgstr "パーティションテーブル" -#: describe.c:1109 +#: describe.c:1087 msgid "Column privileges" msgstr "列の権限" -#: describe.c:1140 describe.c:1174 +#: describe.c:1120 msgid "Policies" msgstr "ポリシー" -#: describe.c:1203 describe.c:4985 describe.c:7259 +#: describe.c:1149 describe.c:4807 describe.c:7026 msgid "Access privileges" msgstr "アクセス権限" -#: describe.c:1236 +#: describe.c:1182 msgid "Get matching default ACLs" msgstr "対象のデフォルトACLを取得" -#: describe.c:1251 +#: describe.c:1197 msgid "function" msgstr "関数" -#: describe.c:1253 +#: describe.c:1199 msgid "type" msgstr "型" -#: describe.c:1255 +#: describe.c:1201 msgid "schema" msgstr "スキーマ" -#: describe.c:1257 +#: describe.c:1203 msgid "large object" msgstr "ラージオブジェクト" -#: describe.c:1279 +#: describe.c:1225 msgid "Default access privileges" msgstr "デフォルトのアクセス権限" -#: describe.c:1318 +#: describe.c:1264 msgid "Get matching object comments" msgstr "オブジェクトコメントを取得" -#: describe.c:1324 +#: describe.c:1270 msgid "Object" msgstr "オブジェクト" -#: describe.c:1338 +#: describe.c:1284 msgid "table constraint" msgstr "テーブル制約" -#: describe.c:1362 +#: describe.c:1308 msgid "domain constraint" msgstr "ドメイン制約" -#: describe.c:1386 +#: describe.c:1332 msgid "operator class" msgstr "演算子クラス" -#: describe.c:1410 +#: describe.c:1356 msgid "operator family" msgstr "演算子族" -#: describe.c:1433 +#: describe.c:1379 msgid "rule" msgstr "ルール" -#: describe.c:1478 +#: describe.c:1424 msgid "Object descriptions" msgstr "オブジェクトの説明" -#: describe.c:1512 +#: describe.c:1458 msgid "Get matching relations to describe" msgstr "表示対象リレーションを取得" -#: describe.c:1545 +#: describe.c:1491 #, c-format msgid "Did not find any relation named \"%s\"." msgstr "\"%s\"という名前のリレーションは見つかりませんでした。" -#: describe.c:1548 describe.c:4446 +#: describe.c:1494 describe.c:4281 #, c-format msgid "Did not find any relations." msgstr "リレーションが見つかりませんでした。" -#: describe.c:1650 +#: describe.c:1596 msgid "Get general information about one relation" msgstr "単一リレーションの概要を取得" -#: describe.c:1746 +#: describe.c:1641 #, c-format msgid "Did not find any relation with OID %s." msgstr "OID %sを持つリレーションが見つかりませんでした。" -#: describe.c:1783 +#: describe.c:1677 msgid "Get sequence information" msgstr "シーケンスの情報を取得" -#: describe.c:1795 describe.c:1819 +#: describe.c:1687 msgid "Start" msgstr "開始" -#: describe.c:1796 describe.c:1820 +#: describe.c:1688 msgid "Minimum" msgstr "最小" -#: describe.c:1797 describe.c:1821 +#: describe.c:1689 msgid "Maximum" msgstr "最大" -#: describe.c:1798 describe.c:1822 +#: describe.c:1690 msgid "Increment" msgstr "増分" -#: describe.c:1801 describe.c:1825 +#: describe.c:1693 msgid "Cycles?" msgstr "循環?" -#: describe.c:1802 describe.c:1826 +#: describe.c:1694 msgid "Cache" msgstr "キャッシュ" -#: describe.c:1838 +#: describe.c:1706 msgid "Get the column that owns this sequence" msgstr "対象シーケンスの所有元の列の取得" -#: describe.c:1869 +#: describe.c:1737 #, c-format msgid "Owned by: %s" msgstr "所有者: %s" -#: describe.c:1873 +#: describe.c:1741 #, c-format msgid "Sequence for identity column: %s" msgstr "識別列のシーケンス: %s" -#: describe.c:1884 +#: describe.c:1752 msgid "Get publications containing this sequence" msgstr "対象シーケンスを含むパブリケーションの取得" -#: describe.c:1898 describe.c:3266 describe.c:5540 +#: describe.c:1766 describe.c:3115 describe.c:5337 msgid "Included in publications:" msgstr "対象リレーション:" -#: describe.c:1916 +#: describe.c:1784 #, c-format msgid "Unlogged sequence \"%s.%s\"" msgstr "ログ出力なしのシーケンス\"%s.%s\"" -#: describe.c:1919 +#: describe.c:1787 #, c-format msgid "Sequence \"%s.%s\"" msgstr "シーケンス \"%s.%s\"" -#: describe.c:1944 +#: describe.c:1812 msgid "Get property graph information" msgstr "プロパティグラフ情報の取得" -#: describe.c:1960 +#: describe.c:1828 msgid "Element Alias" msgstr "要素別名" -#: describe.c:1961 +#: describe.c:1829 msgid "Element Table" msgstr "要素テーブル" -#: describe.c:1962 +#: describe.c:1830 msgid "Element Kind" msgstr "要素種別" -#: describe.c:1963 +#: describe.c:1831 msgid "Source Vertex Alias" msgstr "始点頂点別名" -#: describe.c:1964 +#: describe.c:1832 msgid "Destination Vertex Alias" msgstr "終点頂点別名" -#: describe.c:1971 +#: describe.c:1839 #, c-format msgid "Property Graph \"%s.%s\"" msgstr "プロパティ・グラフ\"%s.%s\"" -#: describe.c:1979 +#: describe.c:1847 msgid "Get property graph definition" msgstr "プロパティグラフ定義の取得" -#: describe.c:1989 +#: describe.c:1857 msgid "Property graph definition:" msgstr "プロパティ・グラフの定義:" -#: describe.c:2029 +#: describe.c:1897 msgid "Get per-column information for one relation" msgstr "単一リレーションのカラム毎情報の取得" -#: describe.c:2139 +#: describe.c:2004 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "ログ出力なしのテーブル\"%s.%s\"" -#: describe.c:2142 +#: describe.c:2007 #, c-format msgid "Table \"%s.%s\"" msgstr "テーブル\"%s.%s\"" -#: describe.c:2146 +#: describe.c:2011 #, c-format msgid "View \"%s.%s\"" msgstr "ビュー\"%s.%s\"" -#: describe.c:2150 +#: describe.c:2015 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "実体化ビュー\"%s.%s\"" -#: describe.c:2155 +#: describe.c:2020 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "ログ出力なしのインデックス\"%s.%s\"" -#: describe.c:2158 +#: describe.c:2023 #, c-format msgid "Index \"%s.%s\"" msgstr "インデックス\"%s.%s\"" -#: describe.c:2163 +#: describe.c:2028 #, c-format msgid "Unlogged partitioned index \"%s.%s\"" msgstr "ログ出力なしのパーティション親インデックス\"%s.%s\"" -#: describe.c:2166 +#: describe.c:2031 #, c-format msgid "Partitioned index \"%s.%s\"" msgstr "パーティションインデックス\"%s.%s\"" -#: describe.c:2170 +#: describe.c:2035 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "TOAST テーブル\"%s.%s\"" -#: describe.c:2174 +#: describe.c:2039 #, c-format msgid "Composite type \"%s.%s\"" msgstr "複合型\"%s.%s\"" -#: describe.c:2178 +#: describe.c:2043 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "外部テーブル\"%s.%s\"" -#: describe.c:2183 +#: describe.c:2048 #, c-format msgid "Unlogged partitioned table \"%s.%s\"" msgstr "ログ出力なしのパーティション親テーブル\"%s.%s\"" -#: describe.c:2186 +#: describe.c:2051 #, c-format msgid "Partitioned table \"%s.%s\"" msgstr "パーティションテーブル\"%s.%s\"" -#: describe.c:2202 describe.c:4816 +#: describe.c:2067 describe.c:4638 msgid "Collation" msgstr "照合順序" -#: describe.c:2203 describe.c:4817 +#: describe.c:2068 describe.c:4639 msgid "Nullable" msgstr "Null 値を許容" -#: describe.c:2204 describe.c:4818 +#: describe.c:2069 describe.c:4640 msgid "Default" msgstr "デフォルト" -#: describe.c:2207 +#: describe.c:2072 msgid "Key?" msgstr "キー?" -#: describe.c:2209 describe.c:5141 describe.c:5152 +#: describe.c:2074 describe.c:4943 describe.c:4954 msgid "Definition" msgstr "定義" -#: describe.c:2211 describe.c:6209 describe.c:6285 describe.c:6352 -#: describe.c:6412 +#: describe.c:2076 describe.c:6006 describe.c:6082 describe.c:6149 +#: describe.c:6209 msgid "FDW options" msgstr "FDW オプション" -#: describe.c:2213 +#: describe.c:2078 msgid "Storage" msgstr "ストレージ" -#: describe.c:2215 +#: describe.c:2080 msgid "Compression" msgstr "圧縮" -#: describe.c:2217 +#: describe.c:2082 msgid "Stats target" msgstr "統計目標" -#: describe.c:2333 +#: describe.c:2198 msgid "Get partitioning information for this partition" msgstr "対象パーティションの定義を取得" -#: describe.c:2361 +#: describe.c:2226 #, c-format msgid "Partition of: %s %s%s" msgstr "親パーティション: %s %s%s" -#: describe.c:2374 +#: describe.c:2239 msgid "No partition constraint" msgstr "パーティション制約なし" -#: describe.c:2376 +#: describe.c:2241 #, c-format msgid "Partition constraint: %s" msgstr "パーティションの制約: %s" -#: describe.c:2390 +#: describe.c:2255 msgid "Get partitioning information for this table" msgstr "対象テーブルのパーティション情報を取得" -#: describe.c:2402 +#: describe.c:2267 #, c-format msgid "Partition key: %s" msgstr "パーティションキー: %s" -#: describe.c:2414 +#: describe.c:2279 msgid "Get the table that owns this TOAST table" msgstr "対象TOASTテーブルの親テーブルの取得" -#: describe.c:2430 +#: describe.c:2295 #, c-format msgid "Owning table: \"%s.%s\"" msgstr "所属先テーブル\"%s.%s\"" -#: describe.c:2443 +#: describe.c:2308 msgid "Get index details" msgstr "インデックス詳細の取得" -#: describe.c:2504 +#: describe.c:2366 msgid "primary key, " msgstr "プライマリキー, " -#: describe.c:2507 -msgid "unique" -msgstr "ユニーク" +#: describe.c:2370 +msgid "unique nulls not distinct, " +msgstr "NULL値非区別、" -#: describe.c:2509 -msgid " nulls not distinct" -msgstr " nulls not distinct" +#: describe.c:2372 +msgid "unique, " +msgstr "ユニーク、" -#: describe.c:2510 -msgid ", " -msgstr ", " - -#: describe.c:2517 +#. translator: the first %s is an index AM name (eg. btree) +#: describe.c:2379 #, c-format -msgid "for table \"%s.%s\"" -msgstr "テーブル\"%s.%s\"用" +msgid "%s, for table \"%s.%s\"" +msgstr "%s、テーブル\"%s.%s\"用" -#: describe.c:2521 +#: describe.c:2383 #, c-format msgid ", predicate (%s)" msgstr "、述語 (%s)" -#: describe.c:2524 +#: describe.c:2386 msgid ", clustered" msgstr "、クラスター化" -#: describe.c:2527 +#: describe.c:2389 msgid ", invalid" msgstr "無効" -#: describe.c:2530 +#: describe.c:2392 msgid ", deferrable" msgstr "、遅延可能" -#: describe.c:2533 +#: describe.c:2395 msgid ", initially deferred" msgstr "、最初から遅延中" -#: describe.c:2536 +#: describe.c:2398 msgid ", replica identity" msgstr "、レプリカの id" -#: describe.c:2565 +#: describe.c:2427 msgid "Get indexes for this table" msgstr "対象テーブルのインデックスを取得" -#: describe.c:2598 +#: describe.c:2457 msgid "Indexes:" msgstr "インデックス:" -#: describe.c:2671 +#: describe.c:2530 msgid "Get check constraints for this table" msgstr "対象テーブルの検査制約を取得" -#: describe.c:2688 +#: describe.c:2547 msgid "Check constraints:" msgstr "Check 制約:" -#: describe.c:2704 +#: describe.c:2563 msgid "Get foreign key constraints for this table" msgstr "対象テーブルの外部キー制約を取得" -#: describe.c:2751 +#: describe.c:2610 msgid "Foreign-key constraints:" msgstr "外部キー制約:" -#: describe.c:2776 +#: describe.c:2635 msgid "Get foreign keys referencing this table" msgstr "対象テーブルを参照する外部キーの取得" -#: describe.c:2812 +#: describe.c:2671 msgid "Referenced by:" msgstr "参照元:" -#: describe.c:2829 +#: describe.c:2686 msgid "Get row-level policies for this table" msgstr "対象テーブルの行レベルポリシーを取得" -#: describe.c:2863 +#: describe.c:2715 msgid "Policies:" msgstr "ポリシー:" -#: describe.c:2866 +#: describe.c:2718 msgid "Policies (forced row security enabled):" msgstr "ポリシー(行セキュリティを強制的に有効化):" -#: describe.c:2869 +#: describe.c:2721 msgid "Policies (row security enabled): (none)" msgstr "ポリシー(行セキュリティ有効化): (なし)" -#: describe.c:2872 +#: describe.c:2724 msgid "Policies (forced row security enabled): (none)" msgstr "ポリシー(行セキュリティを強制的に有効化): (なし)" -#: describe.c:2875 +#: describe.c:2727 msgid "Policies (row security disabled):" msgstr "ポリシー(行セキュリティを無効化):" -#: describe.c:2913 describe.c:3013 +#: describe.c:2764 describe.c:2864 msgid "Get extended statistics for this table" msgstr "対象テーブルの拡張統計を取得" -#: describe.c:2937 describe.c:3044 +#: describe.c:2788 describe.c:2895 msgid "Statistics objects:" msgstr "統計オブジェクト:" -#: describe.c:3094 +#: describe.c:2945 msgid "Get rules for this relation" msgstr "対象リレーションのルールを取得" -#: describe.c:3148 describe.c:3414 +#: describe.c:2999 describe.c:3262 msgid "Rules:" msgstr "ルール:" -#: describe.c:3151 +#: describe.c:3002 msgid "Disabled rules:" msgstr "無効化されたルール:" -#: describe.c:3154 +#: describe.c:3005 msgid "Rules firing always:" msgstr "常に適用するルール:" -#: describe.c:3157 +#: describe.c:3008 msgid "Rules firing on replica only:" msgstr "レプリカ上でのみ適用するルール:" -#: describe.c:3179 +#: describe.c:3028 msgid "Get publications that publish this table" msgstr "対象テーブルを発行するパブリケーションの取得" -#: describe.c:3293 +#: describe.c:3141 msgid "Get publications that exclude this table" msgstr "このテーブルを除外しているパブリケーションの取得" -#: describe.c:3309 +#: describe.c:3157 msgid "Excluded from publications:" msgstr "除外しているパブリケーション一覧:" -#: describe.c:3327 +#: describe.c:3175 msgid "Get not-null constraints for this table" msgstr "対象テーブルの非NULL制約を取得" -#: describe.c:3347 +#: describe.c:3195 msgid "Not-null constraints:" msgstr "非NULL制約:" -#: describe.c:3361 +#: describe.c:3209 msgid " (local, inherited)" msgstr "(ローカル、継承)" -#: describe.c:3362 +#: describe.c:3210 msgid " (inherited)" msgstr "(継承)" -#: describe.c:3377 +#: describe.c:3225 msgid "Get view's definition" msgstr "ビューの定義を取得" -#: describe.c:3396 +#: describe.c:3244 msgid "View definition:" msgstr "ビューの定義:" -#: describe.c:3402 +#: describe.c:3250 msgid "Get rules for this view" msgstr "対象ビューのルールを取得" -#: describe.c:3441 +#: describe.c:3289 msgid "Get triggers for this relation" msgstr "対象テーブルのトリガーを取得" -#: describe.c:3562 +#: describe.c:3410 msgid "Triggers:" msgstr "トリガー:" -#: describe.c:3565 +#: describe.c:3413 msgid "Disabled user triggers:" msgstr "無効化されたユーザートリガ:" -#: describe.c:3568 +#: describe.c:3416 msgid "Disabled internal triggers:" msgstr "無効化された内部トリガー:" -#: describe.c:3571 +#: describe.c:3419 msgid "Triggers firing always:" msgstr "常に適用するするトリガー:" -#: describe.c:3574 +#: describe.c:3422 msgid "Triggers firing on replica only:" msgstr "レプリカ上でのみ適用するトリガー:" -#: describe.c:3626 +#: describe.c:3474 msgid "Get foreign server for this table" msgstr "対象テーブルの外部サーバーを取得" -#: describe.c:3647 +#: describe.c:3495 #, c-format msgid "Server: %s" msgstr "サーバー: %s" -#: describe.c:3655 +#: describe.c:3503 #, c-format msgid "FDW options: (%s)" msgstr "FDW オプション: (%s)" -#: describe.c:3663 +#: describe.c:3511 msgid "Get inheritance parent tables" msgstr "継承親テーブルを取得" -#: describe.c:3678 +#: describe.c:3526 msgid "Inherits" msgstr "継承元" -#: describe.c:3698 +#: describe.c:3546 msgid "Get child tables" msgstr "子テーブルの取得" -#: describe.c:3741 +#: describe.c:3581 #, c-format msgid "Number of partitions: %d" msgstr "パーティション数: %d" -#: describe.c:3750 +#: describe.c:3590 #, c-format msgid "Number of partitions: %d (Use \\d+ to list them.)" msgstr "パーティション数: %d (\\d+ で一覧を表示)。" -#: describe.c:3752 +#: describe.c:3592 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "子テーブル数: %d (\\d+ で一覧を表示)" -#: describe.c:3759 +#: describe.c:3599 msgid "Child tables" msgstr "子テーブル" -#: describe.c:3759 +#: describe.c:3599 msgid "Partitions" msgstr "パーティション" -#: describe.c:3790 +#: describe.c:3630 #, c-format msgid "Typed table of type: %s" msgstr "%s 型の型付きテーブル" -#: describe.c:3808 +#: describe.c:3648 msgid "Replica Identity" msgstr "レプリカ識別" -#: describe.c:3821 +#: describe.c:3661 msgid "Has OIDs: yes" msgstr "OID あり: はい" -#: describe.c:3830 +#: describe.c:3670 #, c-format msgid "Access method: %s" msgstr "アクセスメソッド: %s" -#: describe.c:3893 +#: describe.c:3733 msgid "Get tablespace information for this relation" msgstr "対象リレーションのテーブル空間情報を取得" -#: describe.c:3909 +#: describe.c:3749 #, c-format msgid "Tablespace: \"%s\"" msgstr "テーブル空間: \"%s\"" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:3921 +#: describe.c:3761 #, c-format msgid ", tablespace \"%s\"" msgstr "、テーブル空間\"%s\"" -#: describe.c:3955 +#: describe.c:3795 msgid "Get matching roles" msgstr "対象ロールを取得" -#: describe.c:3995 +#: describe.c:3831 msgid "List of roles" msgstr "ロール一覧" -#: describe.c:3997 describe.c:4167 +#: describe.c:3833 describe.c:4002 msgid "Role name" msgstr "ロール名" -#: describe.c:3998 +#: describe.c:3834 msgid "Attributes" msgstr "属性" -#: describe.c:4009 +#: describe.c:3845 msgid "Superuser" msgstr "スーパーユーザー" -#: describe.c:4012 +#: describe.c:3848 msgid "No inheritance" msgstr "継承なし" -#: describe.c:4015 +#: describe.c:3851 msgid "Create role" msgstr "ロール作成可" -#: describe.c:4018 +#: describe.c:3854 msgid "Create DB" msgstr "DB作成可" -#: describe.c:4021 +#: describe.c:3857 msgid "Cannot login" msgstr "ログインできません" -#: describe.c:4024 +#: describe.c:3860 msgid "Replication" msgstr "レプリケーション可" -#: describe.c:4028 +#: describe.c:3863 msgid "Bypass RLS" msgstr "RLS のバイパス" -#: describe.c:4037 +#: describe.c:3872 msgid "No connections" msgstr "接続なし" -#: describe.c:4039 +#: describe.c:3874 #, c-format msgid "%d connection" msgid_plural "%d connections" msgstr[0] "%d 個の接続" -#: describe.c:4049 +#: describe.c:3884 msgid "Password valid until " msgstr "パスワードの有効期限 " -#: describe.c:4095 +#: describe.c:3930 msgid "Get per-database and per-role settings" msgstr "DB毎およびロール毎との設定を取得" -#: describe.c:4101 +#: describe.c:3936 msgid "Role" msgstr "ロール" -#: describe.c:4103 +#: describe.c:3938 msgid "Settings" msgstr "設定" -#: describe.c:4127 +#: describe.c:3962 #, c-format msgid "Did not find any settings for role \"%s\" and database \"%s\"." msgstr "ロール\"%s\"とデータベース\"%s\"の設定が見つかりませんでした。" -#: describe.c:4130 +#: describe.c:3965 #, c-format msgid "Did not find any settings for role \"%s\"." msgstr "ロール\"%s\"の設定が見つかりませんでした。" -#: describe.c:4133 +#: describe.c:3968 #, c-format msgid "Did not find any settings." msgstr "設定が見つかりませんでした。" -#: describe.c:4137 +#: describe.c:3972 msgid "List of settings" msgstr "設定一覧" -#: describe.c:4163 +#: describe.c:3998 msgid "Get matching role grants" msgstr "対象ロールの権限付与を取得" -#: describe.c:4168 +#: describe.c:4003 msgid "Member of" msgstr "所属グループ" -#: describe.c:4185 +#: describe.c:4020 msgid "Grantor" msgstr "付与者" -#: describe.c:4211 +#: describe.c:4046 msgid "List of role grants" msgstr "ロール権限付与一覧" -#: describe.c:4263 +#: describe.c:4098 msgid "Get matching relations" msgstr "対象リレーションを取得" -#: describe.c:4285 +#: describe.c:4120 msgid "index" msgstr "インデックス" -#: describe.c:4287 +#: describe.c:4122 msgid "TOAST table" msgstr "TOAST テーブル" -#: describe.c:4290 describe.c:4565 +#: describe.c:4125 describe.c:4387 msgid "partitioned index" msgstr "パーティションインデックス" -#: describe.c:4315 +#: describe.c:4150 msgid "permanent" msgstr "永続" -#: describe.c:4316 +#: describe.c:4151 msgid "temporary" msgstr "一時" -#: describe.c:4317 +#: describe.c:4152 msgid "unlogged" msgstr "ログなし" -#: describe.c:4318 +#: describe.c:4153 msgid "Persistence" msgstr "永続性" -#: describe.c:4334 describe.c:4588 +#: describe.c:4169 describe.c:4410 msgid "Access method" msgstr "アクセスメソッド" -#: describe.c:4416 +#: describe.c:4251 #, c-format msgid "Did not find any relations named \"%s\"." msgstr "\"%s\"という名前のリレーションは見つかりませんでした。" -#: describe.c:4419 +#: describe.c:4254 #, c-format msgid "Did not find any tables named \"%s\"." msgstr "\"%s\"という名前のテーブルは見つかりませんでした。" -#: describe.c:4422 +#: describe.c:4257 #, c-format msgid "Did not find any indexes named \"%s\"." msgstr "\"%s\"という名前のインデックスは見つかりませんでした。" -#: describe.c:4425 +#: describe.c:4260 #, c-format msgid "Did not find any views named \"%s\"." msgstr "\"%s\"という名前のビューは見つかりませんでした。" -#: describe.c:4428 +#: describe.c:4263 #, c-format msgid "Did not find any materialized views named \"%s\"." msgstr "\"%s\"という名前の実体化ビューは見つかりませんでした。" -#: describe.c:4431 +#: describe.c:4266 #, c-format msgid "Did not find any sequences named \"%s\"." msgstr "\"%s\"という名前のシーケンスは見つかりませんでした。" -#: describe.c:4434 +#: describe.c:4269 #, c-format msgid "Did not find any foreign tables named \"%s\"." msgstr "\"%s\"という名前の外部テーブルは見つかりませんでした。" -#: describe.c:4437 +#: describe.c:4272 #, c-format msgid "Did not find any property graphs named \"%s\"." msgstr "\"%s\"という名前のプロパティ・グラフは見つかりませんでした。" -#: describe.c:4448 +#: describe.c:4283 #, c-format msgid "Did not find any tables." msgstr "テーブルが見つかりませんでした。" -#: describe.c:4450 +#: describe.c:4285 #, c-format msgid "Did not find any indexes." msgstr "インデックスが見つかりませんでした。" -#: describe.c:4452 +#: describe.c:4287 #, c-format msgid "Did not find any views." msgstr "ビューが見つかりませんでした。" -#: describe.c:4454 +#: describe.c:4289 #, c-format msgid "Did not find any materialized views." msgstr "実体化ビューが見つかりませんでした。" -#: describe.c:4456 +#: describe.c:4291 #, c-format msgid "Did not find any sequences." msgstr "シーケンスが見つかりませんでした。" -#: describe.c:4458 +#: describe.c:4293 #, c-format msgid "Did not find any foreign tables." msgstr "外部テーブルが見つかりませんでした。" -#: describe.c:4460 +#: describe.c:4295 #, c-format msgid "Did not find any property graphs." msgstr "プロパティ・グラフが見つかりませんでした。" -#: describe.c:4468 +#: describe.c:4303 msgid "List of relations" msgstr "リレーション一覧" -#: describe.c:4469 +#: describe.c:4304 msgid "List of tables" msgstr "テーブル一覧" -#: describe.c:4470 +#: describe.c:4305 msgid "List of indexes" msgstr "インデックス一覧" -#: describe.c:4471 +#: describe.c:4306 msgid "List of views" msgstr "ビュー一覧" -#: describe.c:4472 +#: describe.c:4307 msgid "List of materialized views" msgstr "実体化ビュー一覧" -#: describe.c:4473 +#: describe.c:4308 msgid "List of sequences" msgstr "シーケンス一覧" -#: describe.c:4474 describe.c:6445 +#: describe.c:4309 describe.c:6242 msgid "List of foreign tables" msgstr "外部テーブル一覧" -#: describe.c:4475 +#: describe.c:4310 msgid "List of property graphs" msgstr "プロパティ・グラフ一覧" -#: describe.c:4524 -#, c-format -msgid "The server (version %s) does not support declarative table partitioning." -msgstr "このサーバー(バージョン%s)は宣言的テーブルパーティショニングをサポートしていません。" - -#: describe.c:4535 +#: describe.c:4357 msgid "List of partitioned indexes" msgstr "パーティションインデックスの一覧" -#: describe.c:4537 +#: describe.c:4359 msgid "List of partitioned tables" msgstr "パーティションテーブルの一覧" -#: describe.c:4541 +#: describe.c:4363 msgid "List of partitioned relations" msgstr "パーティションリレーションの一覧" -#: describe.c:4548 +#: describe.c:4370 msgid "Get matching partitioned relations" msgstr "対象のパーティション親リレーションを取得" -#: describe.c:4574 +#: describe.c:4396 msgid "Parent name" msgstr "親の名前" -#: describe.c:4594 +#: describe.c:4416 msgid "Leaf partition size" msgstr "末端パーティションのサイズ" -#: describe.c:4597 describe.c:4603 +#: describe.c:4419 describe.c:4425 msgid "Total size" msgstr "トータルサイズ" -#: describe.c:4724 +#: describe.c:4546 msgid "Get matching procedural languages" msgstr "対象の手続き言語を取得" -#: describe.c:4731 +#: describe.c:4553 msgid "Trusted" msgstr "信頼済み" -#: describe.c:4740 +#: describe.c:4562 msgid "Internal language" msgstr "内部言語" -#: describe.c:4741 +#: describe.c:4563 msgid "Call handler" msgstr "呼び出しハンドラー" -#: describe.c:4742 describe.c:6195 +#: describe.c:4564 describe.c:5992 msgid "Validator" msgstr "バリデーター" -#: describe.c:4743 +#: describe.c:4565 msgid "Inline handler" msgstr "インラインハンドラー" -#: describe.c:4777 +#: describe.c:4599 msgid "List of languages" msgstr "手続き言語一覧" -#: describe.c:4801 +#: describe.c:4623 msgid "Get matching domains" msgstr "対象ドメインを取得" -#: describe.c:4819 +#: describe.c:4641 msgid "Check" msgstr "CHECK制約" -#: describe.c:4862 +#: describe.c:4684 msgid "List of domains" msgstr "ドメイン一覧" -#: describe.c:4887 +#: describe.c:4709 msgid "Get matching conversions" msgstr "対象のエンコーディング変換を取得" -#: describe.c:4897 +#: describe.c:4719 msgid "Source" msgstr "変換元" -#: describe.c:4898 +#: describe.c:4720 msgid "Destination" msgstr "変換先" -#: describe.c:4900 describe.c:7305 +#: describe.c:4722 describe.c:7072 msgid "Default?" msgstr "デフォルト?" -#: describe.c:4941 +#: describe.c:4763 msgid "List of conversions" msgstr "符号化方式一覧" -#: describe.c:4968 +#: describe.c:4790 msgid "Get matching configuration parameters" msgstr "対象の設定パラメータを取得" -#: describe.c:4980 +#: describe.c:4802 msgid "Context" msgstr "コンテクスト" -#: describe.c:5012 +#: describe.c:4834 msgid "List of configuration parameters" msgstr "設定パラメータの一覧" -#: describe.c:5014 +#: describe.c:4836 msgid "List of non-default configuration parameters" msgstr "非デフォルトの設定パラメータの一覧" -#: describe.c:5041 -#, c-format -msgid "The server (version %s) does not support event triggers." -msgstr "このサーバー(バージョン%s)はイベントトリガーをサポートしていません。" - -#: describe.c:5049 +#: describe.c:4861 msgid "Get matching event triggers" msgstr "対象のイベントトリガーを取得" -#: describe.c:5062 +#: describe.c:4874 msgid "Event" msgstr "イベント" -#: describe.c:5064 +#: describe.c:4876 msgid "enabled" msgstr "有効" -#: describe.c:5065 +#: describe.c:4877 msgid "replica" msgstr "レプリカ" -#: describe.c:5066 +#: describe.c:4878 msgid "always" msgstr "常時" -#: describe.c:5067 +#: describe.c:4879 msgid "disabled" msgstr "無効" -#: describe.c:5068 describe.c:7118 +#: describe.c:4880 describe.c:6885 msgid "Enabled" msgstr "有効状態" -#: describe.c:5070 +#: describe.c:4882 msgid "Tags" msgstr "タグ" -#: describe.c:5093 +#: describe.c:4905 msgid "List of event triggers" msgstr "イベントトリガー一覧" -#: describe.c:5120 -#, c-format -msgid "The server (version %s) does not support extended statistics." -msgstr "このサーバー(バージョン%s)は拡張統計情報をサポートしていません。" - -#: describe.c:5128 +#: describe.c:4930 msgid "Get matching extended statistics" msgstr "対象の拡張統計を取得" -#: describe.c:5159 +#: describe.c:4961 msgid "Ndistinct" msgstr "Ndistinct" -#: describe.c:5160 +#: describe.c:4962 msgid "Dependencies" msgstr "Dependencies" -#: describe.c:5170 +#: describe.c:4972 msgid "MCV" msgstr "MCV" -#: describe.c:5198 +#: describe.c:5000 msgid "List of extended statistics" msgstr "拡張統計情報の一覧" -#: describe.c:5222 +#: describe.c:5024 msgid "Get matching casts" msgstr "対象キャストを取得" -#: describe.c:5226 +#: describe.c:5028 msgid "Source type" msgstr "変換元の型" -#: describe.c:5227 +#: describe.c:5029 msgid "Target type" msgstr "変換先の型" -#: describe.c:5251 +#: describe.c:5053 msgid "in assignment" msgstr "代入時のみ" -#: describe.c:5253 +#: describe.c:5055 msgid "Implicit?" msgstr "暗黙的に適用 ?" -#: describe.c:5317 +#: describe.c:5119 msgid "List of casts" msgstr "キャスト一覧" -#: describe.c:5347 +#: describe.c:5149 msgid "Get matching collations" msgstr "対象の照合順序を取得" -#: describe.c:5363 describe.c:5367 +#: describe.c:5164 msgid "Provider" msgstr "プロバイダー" -#: describe.c:5401 describe.c:5406 +#: describe.c:5198 describe.c:5203 msgid "Deterministic?" msgstr "確定的?" -#: describe.c:5445 +#: describe.c:5242 msgid "List of collations" msgstr "照合順序一覧" -#: describe.c:5472 +#: describe.c:5269 msgid "Get matching schemas" msgstr "対象のスキーマを取得" -#: describe.c:5508 +#: describe.c:5305 msgid "List of schemas" msgstr "スキーマ一覧" -#: describe.c:5517 +#: describe.c:5314 msgid "Get publications that publish this schema" msgstr "対象スキーマを発行するパブリケーションを取得" -#: describe.c:5598 describe.c:5648 +#: describe.c:5395 describe.c:5445 msgid "Get matching text search parsers" msgstr "対象のテキスト検索パーサーを取得" -#: describe.c:5627 +#: describe.c:5424 msgid "List of text search parsers" msgstr "テキスト検索用パーサ一覧" -#: describe.c:5678 +#: describe.c:5475 #, c-format msgid "Did not find any text search parser named \"%s\"." msgstr "テキスト検索用パーサ\"%s\"が見つかりませんでした。" -#: describe.c:5681 +#: describe.c:5478 #, c-format msgid "Did not find any text search parsers." msgstr "テキスト検索パーサが見つかりませんでした。" -#: describe.c:5726 +#: describe.c:5523 msgid "Get text search parser details" msgstr "対象のテキスト検索パーサー詳細を取得" -#: describe.c:5757 +#: describe.c:5554 msgid "Start parse" msgstr "パース開始" -#: describe.c:5758 +#: describe.c:5555 msgid "Method" msgstr "メソッド" -#: describe.c:5762 +#: describe.c:5559 msgid "Get next token" msgstr "次のトークンを取得" -#: describe.c:5764 +#: describe.c:5561 msgid "End parse" msgstr "パース終了" -#: describe.c:5766 +#: describe.c:5563 msgid "Get headline" msgstr "見出しを取得" -#: describe.c:5768 +#: describe.c:5565 msgid "Get token types" msgstr "トークンタイプを取得" -#: describe.c:5778 +#: describe.c:5575 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "テキスト検索パーサ\"%s.%s\"" -#: describe.c:5781 +#: describe.c:5578 #, c-format msgid "Text search parser \"%s\"" msgstr "テキスト検索パーサ\"%s\"" -#: describe.c:5796 +#: describe.c:5593 msgid "Get text search parser token types" msgstr "対象のテキスト検索パーサーのトークン種別を取得" -#: describe.c:5802 +#: describe.c:5599 msgid "Token name" msgstr "トークン名" -#: describe.c:5815 +#: describe.c:5612 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "パーサ\"%s.%s\"のトークンタイプ" -#: describe.c:5818 +#: describe.c:5615 #, c-format msgid "Token types for parser \"%s\"" msgstr "パーサ\"%s\"のトークンタイプ" -#: describe.c:5847 +#: describe.c:5644 msgid "Get matching text search dictionaries" msgstr "対象のテキスト検索辞書を取得" -#: describe.c:5863 +#: describe.c:5660 msgid "Template" msgstr "テンプレート" -#: describe.c:5864 +#: describe.c:5661 msgid "Init options" msgstr "初期化オプション" -#: describe.c:5890 +#: describe.c:5687 msgid "List of text search dictionaries" msgstr "テキスト検索用辞書一覧" -#: describe.c:5913 +#: describe.c:5710 msgid "Get matching text search templates" msgstr "対象のテキスト検索テンプレートを取得" -#: describe.c:5924 +#: describe.c:5721 msgid "Init" msgstr "初期化" -#: describe.c:5925 +#: describe.c:5722 msgid "Lexize" msgstr "Lex 処理" -#: describe.c:5956 +#: describe.c:5753 msgid "List of text search templates" msgstr "テキスト検索テンプレート一覧" -#: describe.c:5982 describe.c:6029 +#: describe.c:5779 describe.c:5826 msgid "Get matching text search configurations" msgstr "対象のテキスト検索設定を取得" -#: describe.c:6011 +#: describe.c:5808 msgid "List of text search configurations" msgstr "テキスト検索設定一覧" -#: describe.c:6063 +#: describe.c:5860 #, c-format msgid "Did not find any text search configuration named \"%s\"." msgstr "テキスト検索用設定\"%s\"が見つかりませんでした。" -#: describe.c:6066 +#: describe.c:5863 #, c-format msgid "Did not find any text search configurations." msgstr "テキスト検索設定が見つかりませんでした。" -#: describe.c:6116 +#: describe.c:5913 msgid "Get text search configuration details" msgstr "テキスト検索設定詳細を取得" -#: describe.c:6133 +#: describe.c:5930 msgid "Token" msgstr "トークン" -#: describe.c:6134 +#: describe.c:5931 msgid "Dictionaries" msgstr "辞書" -#: describe.c:6145 +#: describe.c:5942 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "テキスト検索設定\"%s.%s\"" -#: describe.c:6148 +#: describe.c:5945 #, c-format msgid "Text search configuration \"%s\"" msgstr "テキスト検索設定\"%s\"" -#: describe.c:6152 +#: describe.c:5949 #, c-format msgid "" "\n" @@ -2787,7 +2763,7 @@ msgstr "" "\n" "パーサ: \"%s.%s\"" -#: describe.c:6155 +#: describe.c:5952 #, c-format msgid "" "\n" @@ -2796,365 +2772,355 @@ msgstr "" "\n" "パーサ: \"%s\"" -#: describe.c:6186 +#: describe.c:5983 msgid "Get matching foreign-data wrappers" msgstr "対象の外部データラッパーを取得" -#: describe.c:6236 +#: describe.c:6033 msgid "List of foreign-data wrappers" msgstr "外部データラッパ一覧" -#: describe.c:6259 +#: describe.c:6056 msgid "Get matching foreign servers" msgstr "対象の外部サーバーを取得" -#: describe.c:6266 +#: describe.c:6063 msgid "Foreign-data wrapper" msgstr "外部データラッパ" -#: describe.c:6284 describe.c:6479 +#: describe.c:6081 describe.c:6276 msgid "Version" msgstr "バージョン" -#: describe.c:6314 +#: describe.c:6111 msgid "List of foreign servers" msgstr "外部サーバー一覧" -#: describe.c:6337 +#: describe.c:6134 msgid "Get matching user mappings" msgstr "対象のユーザーマッピングを取得" -#: describe.c:6341 describe.c:6401 describe.c:7169 +#: describe.c:6138 describe.c:6198 describe.c:6936 msgid "Server" msgstr "サーバー" -#: describe.c:6342 +#: describe.c:6139 msgid "User name" msgstr "ユーザー名" -#: describe.c:6371 +#: describe.c:6168 msgid "List of user mappings" msgstr "ユーザーマッピング一覧" -#: describe.c:6394 +#: describe.c:6191 msgid "Get matching foreign tables" msgstr "対象の外部テーブルを取得" -#: describe.c:6468 describe.c:6524 +#: describe.c:6265 describe.c:6321 msgid "Get matching installed extensions" msgstr "対象のインストール済み機能拡張を取得" -#: describe.c:6480 +#: describe.c:6277 msgid "Default version" msgstr "デフォルトバージョン" -#: describe.c:6501 +#: describe.c:6298 msgid "List of installed extensions" msgstr "インストール済みの拡張一覧" -#: describe.c:6551 +#: describe.c:6348 #, c-format msgid "Did not find any extension named \"%s\"." msgstr "\"%s\"という名前の機能拡張が見つかりませんでした。" -#: describe.c:6554 +#: describe.c:6351 #, c-format msgid "Did not find any extensions." msgstr "機能拡張が見つかりませんでした。" -#: describe.c:6594 +#: describe.c:6391 msgid "Get installed extension's contents" msgstr "インストール済み機能拡張の内容を取得" -#: describe.c:6600 +#: describe.c:6397 msgid "Object description" msgstr "オブジェクトの説明" -#: describe.c:6609 +#: describe.c:6406 #, c-format msgid "Objects in extension \"%s\"" msgstr "機能拡張\"%s\"内のオブジェクト" -#: describe.c:6650 +#: describe.c:6447 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "修飾名が不適切です(ドット区切りの名前が多すぎます): %s" -#: describe.c:6664 +#: describe.c:6461 #, c-format msgid "cross-database references are not implemented: %s" msgstr "データベース間の参照は実装されていません: %s" -#: describe.c:6695 describe.c:6842 -#, c-format -msgid "The server (version %s) does not support publications." -msgstr "このサーバー(バージョン%s)はパブリケーションをサポートしていません。" - -#: describe.c:6703 +#: describe.c:6490 msgid "Get matching publications" msgstr "対象のパブリケーションを取得" -#: describe.c:6710 describe.c:6960 +#: describe.c:6497 describe.c:6737 msgid "All tables" msgstr "全テーブル" -#: describe.c:6715 describe.c:6962 +#: describe.c:6502 describe.c:6739 msgid "All sequences" msgstr "全シーケンス" -#: describe.c:6721 describe.c:6963 +#: describe.c:6508 describe.c:6740 msgid "Inserts" msgstr "Insert文" -#: describe.c:6722 describe.c:6964 +#: describe.c:6509 describe.c:6741 msgid "Updates" msgstr "Update文" -#: describe.c:6723 describe.c:6965 +#: describe.c:6510 describe.c:6742 msgid "Deletes" msgstr "Delete文" -#: describe.c:6727 describe.c:6967 +#: describe.c:6514 describe.c:6744 msgid "Truncates" msgstr "Truncate文" -#: describe.c:6736 describe.c:6886 describe.c:6969 +#: describe.c:6523 describe.c:6663 describe.c:6746 msgid "Generated columns" msgstr "生成列" -#: describe.c:6740 describe.c:6971 +#: describe.c:6527 describe.c:6748 msgid "Via root" msgstr "最上位パーティションテーブル経由" -#: describe.c:6761 +#: describe.c:6548 msgid "List of publications" msgstr "パブリケーション一覧" -#: describe.c:6855 +#: describe.c:6632 msgid "Get details about matching publications" msgstr "対象パブリケーションの詳細を取得" -#: describe.c:6927 +#: describe.c:6704 #, c-format msgid "Did not find any publication named \"%s\"." msgstr "\"%s\"という名前のパブリケーションが見つかりませんでした。" -#: describe.c:6930 +#: describe.c:6707 #, c-format msgid "Did not find any publications." msgstr "パブリケーションが見つかりませんでした。" -#: describe.c:6956 +#: describe.c:6733 #, c-format msgid "Publication %s" msgstr "パブリケーション %s" -#: describe.c:6993 +#: describe.c:6770 msgid "Get tables published by this publication" msgstr "対象パブリケーションによる発行テーブルの取得" -#: describe.c:7024 +#: describe.c:6801 msgid "Tables:" msgstr "テーブル:" -#: describe.c:7031 +#: describe.c:6808 msgid "Get schemas published by this publication" msgstr "対象パブリケーションが発行するスキーマを取得" -#: describe.c:7038 +#: describe.c:6815 msgid "Tables from schemas:" msgstr "以下のスキーマ内のテーブル:" -#: describe.c:7049 +#: describe.c:6826 msgid "Get tables excluded by this publication" msgstr "対象パブリケーションでの除外テーブルの取得" -#: describe.c:7057 +#: describe.c:6834 msgid "Except tables:" msgstr "EXCEPT句のテーブル:" -#: describe.c:7102 -#, c-format -msgid "The server (version %s) does not support subscriptions." -msgstr "このサーバー(バージョン%s)はサブスクリプションをサポートしていません。" - -#: describe.c:7110 +#: describe.c:6877 msgid "Get matching subscriptions" msgstr "対象のサブスクリプションを取得" -#: describe.c:7119 +#: describe.c:6886 msgid "Publication" msgstr "パブリケーション" -#: describe.c:7128 +#: describe.c:6895 msgid "Binary" msgstr "バイナリ" -#: describe.c:7137 describe.c:7141 +#: describe.c:6904 describe.c:6908 msgid "Streaming" msgstr "ストリーミング" -#: describe.c:7149 +#: describe.c:6916 msgid "Two-phase commit" msgstr "2相コミット" -#: describe.c:7150 +#: describe.c:6917 msgid "Disable on error" msgstr "エラー時無効化" -#: describe.c:7157 +#: describe.c:6924 msgid "Origin" msgstr "起点" -#: describe.c:7158 +#: describe.c:6925 msgid "Password required" msgstr "パスワード必須" -#: describe.c:7159 +#: describe.c:6926 msgid "Run as owner?" msgstr "所有者として実行?" -#: describe.c:7164 +#: describe.c:6931 msgid "Failover" msgstr "フェイルオーバー" -#: describe.c:7173 +#: describe.c:6940 msgid "Retain dead tuples" msgstr "削除済みタプル保持" -#: describe.c:7177 +#: describe.c:6944 msgid "Max retention duration" msgstr "最大保持時間" -#: describe.c:7181 +#: describe.c:6948 msgid "Retention active" msgstr "保持有効" -#: describe.c:7187 +#: describe.c:6954 msgid "Synchronous commit" msgstr "同期コミット" -#: describe.c:7188 +#: describe.c:6955 msgid "Conninfo" msgstr "接続情報" -#: describe.c:7193 +#: describe.c:6960 msgid "Receiver timeout" msgstr "受信タイムアウト" -#: describe.c:7199 +#: describe.c:6966 msgid "Skip LSN" msgstr "スキップLSN" -#: describe.c:7229 +#: describe.c:6996 msgid "List of subscriptions" msgstr "サブスクリプション一覧" -#: describe.c:7258 +#: describe.c:7025 msgid "(none)" msgstr "(権限なし)" -#: describe.c:7280 +#: describe.c:7047 msgid "Get matching operator classes" msgstr "対象の演算子クラスを取得" -#: describe.c:7299 describe.c:7395 describe.c:7488 describe.c:7593 +#: describe.c:7066 describe.c:7162 describe.c:7255 describe.c:7360 msgid "AM" msgstr "AM" -#: describe.c:7300 +#: describe.c:7067 msgid "Input type" msgstr "入力の型" -#: describe.c:7301 +#: describe.c:7068 msgid "Storage type" msgstr "ストレージタイプ" -#: describe.c:7302 +#: describe.c:7069 msgid "Operator class" msgstr "演算子クラス" -#: describe.c:7314 describe.c:7396 describe.c:7489 describe.c:7594 +#: describe.c:7081 describe.c:7163 describe.c:7256 describe.c:7361 msgid "Operator family" msgstr "演算子族" -#: describe.c:7349 +#: describe.c:7116 msgid "List of operator classes" msgstr "演算子クラス一覧" -#: describe.c:7382 +#: describe.c:7149 msgid "Get matching operator families" msgstr "対象の演算子族を取得" -#: describe.c:7397 +#: describe.c:7164 msgid "Applicable types" msgstr "適用可能型" -#: describe.c:7438 +#: describe.c:7205 msgid "List of operator families" msgstr "演算子族一覧" -#: describe.c:7473 +#: describe.c:7240 msgid "Get operators of matching operator families" msgstr "対象演算子族の演算子を取得" -#: describe.c:7490 +#: describe.c:7257 msgid "Operator" msgstr "演算子" -#: describe.c:7491 +#: describe.c:7258 msgid "Strategy" msgstr "ストラテジ" -#: describe.c:7492 +#: describe.c:7259 msgid "ordering" msgstr "順序付け" -#: describe.c:7493 +#: describe.c:7260 msgid "search" msgstr "検索" -#: describe.c:7494 +#: describe.c:7261 msgid "Purpose" msgstr "目的" -#: describe.c:7503 +#: describe.c:7270 msgid "Sort opfamily" msgstr "ソート演算子族" -#: describe.c:7546 +#: describe.c:7313 msgid "List of operators of operator families" msgstr "演算子族の演算子一覧" -#: describe.c:7581 +#: describe.c:7348 msgid "Get support functions of matching operator families" msgstr "対象演算子族のサポート関数を取得" -#: describe.c:7595 +#: describe.c:7362 msgid "Registered left type" msgstr "登録左辺型" -#: describe.c:7596 +#: describe.c:7363 msgid "Registered right type" msgstr "登録右辺型" -#: describe.c:7597 +#: describe.c:7364 msgid "Number" msgstr "番号" -#: describe.c:7640 +#: describe.c:7407 msgid "List of support functions of operator families" msgstr "演算子族のサポート関数一覧" -#: describe.c:7668 +#: describe.c:7435 msgid "Get large objects" msgstr "ラージオブジェクトを取得" -#: describe.c:7672 +#: describe.c:7439 msgid "ID" msgstr "ID" -#: describe.c:7692 +#: describe.c:7459 msgid "Large objects" msgstr "ラージ オブジェクト" @@ -7601,7 +7567,7 @@ msgstr "余分なコマンドライン引数\"%s\"は無視されました" msgid "could not find own program executable" msgstr "実行可能ファイルが見つかりませんでした" -#: tab-complete.in.c:7056 +#: tab-complete.in.c:7046 #, c-format msgid "" "tab completion query failed: %s\n" @@ -7637,22 +7603,22 @@ msgstr "変数\"%2$s\"の値\"%1$s\"が不正です: %3$.2f より大きい必 msgid "invalid value \"%s\" for variable \"%s\": must be less than %.2f" msgstr "変数\"%2$s\"の値\"%1$s\"が不正です: %3$.2f より小さい必要があります" -#: variables.c:241 +#: variables.c:242 #, c-format msgid "value \"%s\" is out of range for variable \"%s\"" msgstr "値\"%s\"は変数%sの範囲外です" -#: variables.c:247 +#: variables.c:248 #, c-format msgid "invalid value \"%s\" for variable \"%s\"" msgstr "変数\"%2$s\"に対する不正な値\"%1$s\"" -#: variables.c:294 +#: variables.c:295 #, c-format msgid "invalid variable name: \"%s\"" msgstr "変数名が不正です: \"%s\"" -#: variables.c:488 +#: variables.c:489 #, c-format msgid "" "unrecognized value \"%s\" for \"%s\"\n" @@ -7678,9 +7644,30 @@ msgstr "" #~ " unicode_border_linestyle|unicode_column_linestyle|\n" #~ " unicode_header_linestyle|xheader_width)\n" +#~ msgid ", " +#~ msgstr ", " + #~ msgid "Publications:" #~ msgstr "パブリケーション:" +#~ msgid "The server (version %s) does not support access methods." +#~ msgstr "このサーバー(バージョン%s)はアクセスメソッドをサポートしていません。" + +#~ msgid "The server (version %s) does not support declarative table partitioning." +#~ msgstr "このサーバー(バージョン%s)は宣言的テーブルパーティショニングをサポートしていません。" + +#~ msgid "The server (version %s) does not support event triggers." +#~ msgstr "このサーバー(バージョン%s)はイベントトリガーをサポートしていません。" + +#~ msgid "The server (version %s) does not support extended statistics." +#~ msgstr "このサーバー(バージョン%s)は拡張統計情報をサポートしていません。" + +#~ msgid "The server (version %s) does not support publications." +#~ msgstr "このサーバー(バージョン%s)はパブリケーションをサポートしていません。" + +#~ msgid "The server (version %s) does not support subscriptions." +#~ msgstr "このサーバー(バージョン%s)はサブスクリプションをサポートしていません。" + #~ msgid "all_publication_object" #~ msgstr "全体発行オブジェクト" diff --git a/src/bin/psql/po/ka.po b/src/bin/psql/po/ka.po index c84fe04b9cb..dce4b1daaf5 100644 --- a/src/bin/psql/po/ka.po +++ b/src/bin/psql/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: psql (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-13 06:22+0000\n" -"PO-Revision-Date: 2026-05-13 09:22+0200\n" +"POT-Creation-Date: 2026-06-30 04:21+0000\n" +"PO-Revision-Date: 2026-07-02 06:14+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -165,42 +165,42 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu მწკრივი)" msgstr[1] "(%lu მწკრივი)" -#: ../../fe_utils/print.c:3173 +#: ../../fe_utils/print.c:3174 #, c-format msgid "Interrupted\n" msgstr "შეწყვეტილია\n" -#: ../../fe_utils/print.c:3207 +#: ../../fe_utils/print.c:3208 #, c-format msgid "Cannot print table contents: number of cells % is equal to or exceeds maximum %zu.\n" msgstr "ვერ გამოვიტანე ცხრილის შემცველობა: უჯრედების რაოდენობა % მაქსიმუმის %zu ტოლი ან მასზე მეტია.\n" -#: ../../fe_utils/print.c:3248 +#: ../../fe_utils/print.c:3249 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "ცხრილის შემცველობაზე თავსართის დამატება შეუძლებელია: სვეტების რაოდენობა %d გადაჭარბებულია.\n" -#: ../../fe_utils/print.c:3291 +#: ../../fe_utils/print.c:3292 #, c-format msgid "Cannot add cell to table content: total cell count of % exceeded.\n" msgstr "ცხრილის შემცველობაზე უჯრედის დამატება შეუძლებელია: უჯრედების ჯამური რაოდენობა %-ზე მეტია.\n" -#: ../../fe_utils/print.c:3719 +#: ../../fe_utils/print.c:3720 #, c-format msgid "invalid output format (internal error): %d" msgstr "გამოტანის არასწორი ფორმატი (შიდა შეცდომა): %d" -#: ../../fe_utils/psqlscan.l:729 +#: ../../fe_utils/psqlscan.l:736 #, c-format msgid "skipping recursive expansion of variable \"%s\"" msgstr "რეკურსიული გაფართოების გამოტოვება ცვლადისთვის \"%s\"" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "გარსის ბრძანების არგუმენტი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "მონაცემთა ბაზის სახელი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" @@ -373,8 +373,8 @@ msgid "%s: invalid encoding name or conversion procedure not found" msgstr "%s: კოდირების არასწორი სახელი ან გადაყვანის პროცედურა არ არსებობს" #: command.c:1657 command.c:2597 command.c:4076 command.c:4274 command.c:6568 -#: common.c:233 common.c:282 common.c:455 common.c:1178 common.c:1196 -#: common.c:1264 common.c:1376 common.c:1414 common.c:1705 common.c:1785 +#: common.c:233 common.c:282 common.c:457 common.c:1180 common.c:1198 +#: common.c:1266 common.c:1378 common.c:1416 common.c:1720 common.c:1800 #: copy.c:486 copy.c:731 large_obj.c:157 large_obj.c:192 large_obj.c:254 #: startup.c:310 #, c-format @@ -932,7 +932,7 @@ msgstr "%s (ყოველ %g-ში)\n" msgid "could not wait for signals: %m" msgstr "სიგნალებისთვის დალოდება შეუძლებელია: %m" -#: command.c:6167 command.c:6174 common.c:667 common.c:674 +#: command.c:6167 command.c:6174 common.c:669 common.c:676 #, c-format msgid "" "/**** INTERNAL QUERY ****/\n" @@ -981,87 +981,87 @@ msgstr "გაქცევა აქტიური შეერთებს გ msgid "shell command argument contains a newline or carriage return: \"%s\"" msgstr "გარსის ბრძანება ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"" -#: common.c:363 +#: common.c:365 #, c-format msgid "connection to server was lost" msgstr "სერვერთან კავშირი დაკარგულია" -#: common.c:367 +#: common.c:369 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "სერვერთან კავშირი დაკარგულია. ვეცდები თავიდან დავიწყო: " -#: common.c:373 +#: common.c:375 #, c-format msgid "Failed.\n" msgstr "ჩავარდა.\n" -#: common.c:390 +#: common.c:392 #, c-format msgid "Succeeded.\n" msgstr "წარმატებულია.\n" -#: common.c:445 common.c:1097 +#: common.c:447 common.c:1099 #, c-format msgid "unexpected PQresultStatus: %d" msgstr "მოულოდნელი PQresultStatus: %d" -#: common.c:606 +#: common.c:608 #, c-format msgid "Time: %.3f ms\n" msgstr "დრო: %.3f მწმ\n" -#: common.c:621 +#: common.c:623 #, c-format msgid "Time: %.3f ms (%02d:%06.3f)\n" msgstr "დრო: %.3f მწმ (%02d:%06.3f)\n" -#: common.c:630 +#: common.c:632 #, c-format msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" msgstr "დრო: %.3f მწმ (%02d:%02d:%06.3f)\n" -#: common.c:637 +#: common.c:639 #, c-format msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" msgstr "დრო: %.3f მწმ (%.0f დღე %02d:%02d:%06.3f)\n" -#: common.c:661 common.c:718 common.c:1130 describe.c:6659 +#: common.c:663 common.c:720 common.c:1132 describe.c:6659 #, c-format msgid "You are currently not connected to a database." msgstr "ამჟამად მონაცემთა ბაზასთან მიერთებული არ ბრძანდებით." -#: common.c:749 +#: common.c:751 #, c-format msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" msgstr "მიღებულია ასინქრონული გაფრთხილება \"%s\" შემცველობით \"%s\" სერვერის პროცესისგან PID-ით %d.\n" -#: common.c:752 +#: common.c:754 #, c-format msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "მიღებულია ასინქრონული გაფრთხილება \"%s\" სერვერის პროცესისგან PID-ით %d.\n" -#: common.c:783 +#: common.c:785 #, c-format msgid "could not print result table: %m" msgstr "შედეგების ცხრილის გამოტანის შეცდომა: %m" -#: common.c:803 +#: common.c:805 #, c-format msgid "no rows returned for \\gset" msgstr "\\gset -სთვის მწკრივები არ დაბრუნებულა" -#: common.c:808 +#: common.c:810 #, c-format msgid "more than one row returned for \\gset" msgstr "\\gset -სთვის ერთზე მეტი მწკრივი დაბრუნდა" -#: common.c:826 +#: common.c:828 #, c-format msgid "attempt to \\gset into specially treated variable \"%s\" ignored" msgstr "მცდელობა, \\gset-ი სპეციალურ ცვლადზე (\"%s\") ყოფილიყო გამოყენებული, იგნორირებულია" -#: common.c:1139 +#: common.c:1141 #, c-format msgid "" "/**(Single step mode: verify command)******************************************/\n" @@ -1072,7 +1072,7 @@ msgstr "" "%s\n" "***(დააწექით Enter-ს გასაგრძელებლად. გასაუქმებლად კი x-ს და შემდეგ Enter-ს )********************\n" -#: common.c:1159 +#: common.c:1161 #, c-format msgid "" "/******** QUERY *********/\n" @@ -1085,48 +1085,48 @@ msgstr "" "**************************\n" "\n" -#: common.c:1216 +#: common.c:1218 #, c-format msgid "STATEMENT: %s" msgstr "ოპერატორი: %s" -#: common.c:1252 +#: common.c:1254 #, c-format msgid "unexpected transaction status (%d)" msgstr "ტრანზაქციის მოულოდნელი სტატუსი (%d)" -#: common.c:1398 describe.c:2198 +#: common.c:1400 describe.c:2198 msgid "Column" msgstr "სვეტი" -#: common.c:1399 describe.c:179 describe.c:368 describe.c:386 describe.c:1094 +#: common.c:1401 describe.c:179 describe.c:368 describe.c:386 describe.c:1094 #: describe.c:1258 describe.c:1794 describe.c:1818 describe.c:2199 #: describe.c:4292 describe.c:4566 describe.c:4815 describe.c:4979 #: describe.c:6283 msgid "Type" msgstr "ტიპი" -#: common.c:1448 +#: common.c:1450 #, c-format msgid "The command has no result, or the result has no columns.\n" msgstr "ბრძანებას შედეგები არ აქვს, ან შედეგებში სვეტები არაა.\n" -#: common.c:1670 +#: common.c:1685 #, c-format msgid "No pending results to get" msgstr "მისაღები შედეგები დარჩენილი არაა" -#: common.c:1748 +#: common.c:1763 #, c-format msgid "fetching results in chunked mode failed" msgstr "ნაგლეჯების რეჟიმში შედეგების გამოთხოვა ჩავარდა" -#: common.c:1797 +#: common.c:1812 #, c-format msgid "Pipeline aborted, command did not run" msgstr "კომუნიკაციის არხი გაუქმდა. ბრძანება არ გაშვებულა" -#: common.c:1893 +#: common.c:1908 #, c-format msgid "COPY in a pipeline is not supported, aborting connection" msgstr "COPY კომუნიკაციის არხში მხარდაჭერილი არაა. კავშირი გაუქმდება" @@ -1191,47 +1191,47 @@ msgstr "დასრულდა კითხვის შეცდომის msgid "trying to exit copy mode" msgstr "კოპირების რეჟიმიდან გამოსვლის მცდელობა" -#: crosstabview.c:124 +#: crosstabview.c:127 #, c-format msgid "\\crosstabview: statement did not return a result set" msgstr "\\crosstabview: ოპერატორმა შედეგების სეტი არ დააბრუნა" -#: crosstabview.c:130 +#: crosstabview.c:133 #, c-format msgid "\\crosstabview: query must return at least three columns" msgstr "\\crosstabview: მოთხოვნამ სულ ცოტა, სამი სვეტი უნდა დააბრუნოს" -#: crosstabview.c:157 +#: crosstabview.c:160 #, c-format msgid "\\crosstabview: vertical and horizontal headers must be different columns" msgstr "\\crosstabview: ვერტიკალური და ჰორიზონტალური თავსართები სხვადასხვა სვეტებში უნდა იყოს" -#: crosstabview.c:173 +#: crosstabview.c:176 #, c-format msgid "\\crosstabview: data column must be specified when query returns more than three columns" msgstr "\\crosstabview: როცა მოთხოვნა სამზე მეტ სვეტს აბრუნებს, ასევე საჭიროა მონაცემების სვეტის მითითება" -#: crosstabview.c:229 +#: crosstabview.c:232 #, c-format msgid "\\crosstabview: maximum number of columns (%d) exceeded" msgstr "\\crosstabview: გადაჭარბებულია სვეტების მაქსიმალური რაოდენობა (%d)" -#: crosstabview.c:396 +#: crosstabview.c:399 #, c-format msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" msgstr "\\crosstabview: მოთხოვნის შედეგი მონაცემების მრავალ მნიშვნელობას შეიცავს მწკრივისთვის \"%s\", სვეტი \"%s\"" -#: crosstabview.c:643 +#: crosstabview.c:670 #, c-format msgid "\\crosstabview: column number %d is out of range 1..%d" msgstr "\\crosstabview: სვეტის რიცხვი %d დიაპაზონს 1..%d გარეთაა" -#: crosstabview.c:668 +#: crosstabview.c:695 #, c-format msgid "\\crosstabview: ambiguous column name: \"%s\"" msgstr "\\crosstabview: სვეტის არასწორი სახელი: \"%s\"" -#: crosstabview.c:676 +#: crosstabview.c:703 #, c-format msgid "\\crosstabview: column name not found: \"%s\"" msgstr "\\crosstabview: სვეტის სახელი არ არსებობს: \"%s\"" @@ -1882,22 +1882,19 @@ msgstr "ინდექსის დეტალების მიღება" msgid "primary key, " msgstr "ძირითადი გასაღები. " -#: describe.c:2507 -msgid "unique" -msgstr "უნიკალური" - -#: describe.c:2509 -msgid " nulls not distinct" -msgstr " ნულები განსხვავებული არაა" +#: describe.c:2508 +msgid "unique nulls not distinct, " +msgstr "უნიკალური ნულები განსხვავებული არაა, " #: describe.c:2510 -msgid ", " -msgstr ", " +msgid "unique, " +msgstr "უნიკალური, " +#. translator: the first %s is an index AM name (eg. btree) #: describe.c:2517 #, c-format -msgid "for table \"%s.%s\"" -msgstr "ცხრილისთვის \"%s.%s\"" +msgid "%s, for table \"%s.%s\"" +msgstr "%s, ცხრილისთვის \"%s.%s\"" #: describe.c:2521 #, c-format @@ -7569,7 +7566,7 @@ msgstr "ბრძანების სტრიქონის დამატ msgid "could not find own program executable" msgstr "საკუთარი პროგრამის გამშვები ფაილის პოვნა შეუძლებელია" -#: tab-complete.in.c:7055 +#: tab-complete.in.c:7060 #, c-format msgid "" "tab completion query failed: %s\n" @@ -7605,22 +7602,22 @@ msgstr "არასწორი მნიშვნელობა \"%s\" ცვ msgid "invalid value \"%s\" for variable \"%s\": must be less than %.2f" msgstr "არასწორი მნიშვნელობა \"%s\" ცვლადისთვის \"%s\"-სთვის: უნდა იყოს %.2f-ზე ნაკლები" -#: variables.c:241 +#: variables.c:242 #, c-format msgid "value \"%s\" is out of range for variable \"%s\"" msgstr "მნიშვნელობა \"%s\" დიაპაზონს გარეთაა ცვლადისთვის \"%s\"" -#: variables.c:247 +#: variables.c:248 #, c-format msgid "invalid value \"%s\" for variable \"%s\"" msgstr "არასწორი მნიშვნელობა \"%s\" ცვლადისთვის \"%s\"" -#: variables.c:294 +#: variables.c:295 #, c-format msgid "invalid variable name: \"%s\"" msgstr "ცვლადის არასწორი სახელი: \"%s\"" -#: variables.c:488 +#: variables.c:489 #, c-format msgid "" "unrecognized value \"%s\" for \"%s\"\n" @@ -7629,145 +7626,5 @@ msgstr "" "\"%s\" არასწორი მნიშვნელობაა \"%s\"-სთვის\n" "შესაძლო მნიშვნელობებია: %s." -#, c-format -#~ msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" -#~ msgstr " -U, --username=მომხმარებელი ბაზის მომხმარებლის სახელი (ნაგულისხმები: \"%s\")\n" - -#, c-format -#~ msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" -#~ msgstr " -d, --dbname=ბაზისსახელი მისაერთებელი ბაზის სახელი (ნაგულისხმები: \"%s\")\n" - -#, c-format -#~ msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" -#~ msgstr " -h, --host=HOSTNAME მონაცემთა ბაზის სერვერის ჰოსტის ან სოკეტის საქაღალდე (ნაგულისხმები: \"%s\")\n" - -#, c-format -#~ msgid " -p, --port=PORT database server port (default: \"%s\")\n" -#~ msgstr " -p, --port=PORT მონაცემთა ბაზის სერვერის პორტი (ნაგულისხმები: \"%s\")\n" - -#~ msgid "" -#~ " WATCH_INTERVAL\n" -#~ " if set to a number, overrides the default two second \\watch interval\n" -#~ msgstr "" -#~ " WATCH_INTERVAL\n" -#~ " თუ დაყენებულია რიცხვზე, გადაფარავს ნაგულისხმევ ორწამიან ინტერვალს \\watch-სთვის\n" - -#~ msgid "" -#~ " \\pset [NAME [VALUE]] set table output option\n" -#~ " (border|columns|csv_fieldsep|expanded|fieldsep|\n" -#~ " fieldsep_zero|footer|format|linestyle|null|\n" -#~ " numericlocale|pager|pager_min_lines|recordsep|\n" -#~ " recordsep_zero|tableattr|title|tuples_only|\n" -#~ " unicode_border_linestyle|unicode_column_linestyle|\n" -#~ " unicode_header_linestyle|xheader_width)\n" -#~ msgstr "" -#~ " \\pset [სახელი [მნიშვნელობა]] ცხრილის გამოტანის პარამეტრის დაყენება\n" -#~ " (border|columns|csv_fieldsep|expanded|fieldsep|\n" -#~ " fieldsep_zero|footer|format|linestyle|null|\n" -#~ " numericlocale|pager|pager_min_lines|recordsep|\n" -#~ " recordsep_zero|tableattr|title|tuples_only|\n" -#~ " unicode_border_linestyle|unicode_column_linestyle|\n" -#~ " unicode_header_linestyle|xheader_width)\n" - -#~ msgid " \\watch [[i=]SEC] [c=N] execute query every SEC seconds, up to N times\n" -#~ msgstr " \\watch [[i=]SEC] [c=N] მოთხოვნის ყოველ SEC წამში ერთხელ გაშვება, N-ჯერ\n" - -#, c-format -#~ msgid "Expanded header width is 'column'.\n" -#~ msgstr "გაფართოებული თავსართის სიგანეა 'column'.\n" - -#, c-format -#~ msgid "Expanded header width is 'full'.\n" -#~ msgstr "გაფართოებული თავსართის სიგანეა 'full'.\n" - -#, c-format -#~ msgid "Expanded header width is 'page'.\n" -#~ msgstr "გაფართოებული თავსართის სიგანეა 'page'.\n" - -#~ msgid "ICU Locale" -#~ msgstr "ICU ენა" - -#~ msgid "Publications:" -#~ msgstr "გამოცემები:" - -#~ msgid "Source code" -#~ msgstr "საწყისი კოდი" - -#, c-format -#~ msgid "Unlogged materialized view \"%s.%s\"" -#~ msgstr "ჟურნალში არ-ჩაწერილი მატერიალიზებული ხედი \"%s.%s\"" - -#~ msgid "User set" -#~ msgstr "მომხმარებელი დაყენებულია" - -#, c-format -#~ msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" -#~ msgstr "ახლა მიერთებული ბრძანდებით ბაზასთან \"%s\" როგორც მომხმარებელი \"%s\" მისამართზე \"%s\" და პორტზე \"%s\".\n" - -#, c-format -#~ msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" -#~ msgstr "ახლა მიერთებული ბრძანდებით ბაზასთან \"%s\" როგორც მომხმარებელი \"%s\" ჰოსტზე \"%s\" (მისამართით \"%s\") და პორტზე \"%s\".\n" - -#, c-format -#~ msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" -#~ msgstr "ახლა მიერთებული ბრძანდებით ბაზასთან \"%s\" როგორც მომხმარებელი \"%s\" ჰოსტზე \"%s\" და პორტზე \"%s\".\n" - -#, c-format -#~ msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" -#~ msgstr "ახლა მიერთებული ბრძანდებით ბაზასთან \"%s\" როგორც მომხმარებელი \"%s\" სოკეტით \"%s\" და პორტზე \"%s\".\n" - -#, c-format -#~ msgid "\\gexec not allowed in pipeline mode" -#~ msgstr "\\gexec კომუნიკაციის რეჟიმში დაშვებული არაა" - -#, c-format -#~ msgid "\\gset not allowed in pipeline mode" -#~ msgstr "\\gset კომუნიკაციის რეჟიმში დაშვებული არაა" - -#, c-format -#~| msgid "%s not allowed in pipeline mode" -#~ msgid "\\gx not allowed in pipeline mode" -#~ msgstr "\\gx კომუნიკაციის რეჟიმში დაშვებული არაა" - -#, c-format -#~ msgid "\\watch cannot be used with COPY" -#~ msgstr "\\watch -ს COPY-სთან ერთად ვერ გამოყენებთ" - -#, c-format -#~ msgid "\\watch not allowed in pipeline mode" -#~ msgstr "\\watch კომუნიკაციის არხის რეჟიმში დაშვებული არაა" - -#~ msgid "constraint" -#~ msgstr "შეზღუდვა" - -#, c-format -#~ msgid "could not change directory to \"%s\": %m" -#~ msgstr "საქაღალდის %s-ზე შეცვლის შეცდომა: %m" - -#, c-format -#~ msgid "could not identify current directory: %m" -#~ msgstr "მიმდინარე საქაღალდის იდენტიფიკაციის პრობლემა: %m" - -#, c-format -#~ msgid "could not look up local user ID %d: %s" -#~ msgstr "ლოკალური მომხმარებლის ID-ის (%d) ამოხსნა შეუძლებელია: %s" - -#, c-format -#~ msgid "could not read symbolic link \"%s\": %m" -#~ msgstr "სიმბოლური ბმის \"%s\" წაკითხვის შეცდომა: %m" - -#~ msgid "local socket" -#~ msgstr "ლოკალური სოკეტი" - -#, c-format -#~ msgid "local user with ID %d does not exist" -#~ msgstr "ლოკალური მომხმარებელი ID-ით %d არ არსებობს" - -#~ msgid "text" -#~ msgstr "ტექსტი" - -#~ msgid "where constraint is:" -#~ msgstr "სადაც constraint არის:" - -#~ msgid "where direction can be empty or one of:" -#~ msgstr "სადაც direction შეიძლება იყოს ცარიელი, ან ერთ-ერთი სიიდან::" +#~ msgid ", " +#~ msgstr ", " diff --git a/src/bin/scripts/po/de.po b/src/bin/scripts/po/de.po index db60f0f67ce..32a88862cde 100644 --- a/src/bin/scripts/po/de.po +++ b/src/bin/scripts/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-28 19:24+0000\n" -"PO-Revision-Date: 2026-05-29 07:50+0200\n" +"POT-Creation-Date: 2026-07-04 06:25+0000\n" +"PO-Revision-Date: 2026-07-04 12:59+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -183,27 +183,27 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu Zeile)" msgstr[1] "(%lu Zeilen)" -#: ../../fe_utils/print.c:3173 +#: ../../fe_utils/print.c:3174 #, c-format msgid "Interrupted\n" msgstr "Unterbrochen\n" -#: ../../fe_utils/print.c:3207 +#: ../../fe_utils/print.c:3208 #, c-format msgid "Cannot print table contents: number of cells % is equal to or exceeds maximum %zu.\n" msgstr "Kann Tabelleninhalt nicht ausgeben: Anzahl der Zellen % ist gleich oder überschreitet Maximum %zu.\n" -#: ../../fe_utils/print.c:3248 +#: ../../fe_utils/print.c:3249 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "Kann keinen weiteren Spaltenkopf zur Tabelle hinzufügen: Spaltenzahl %d überschritten.\n" -#: ../../fe_utils/print.c:3291 +#: ../../fe_utils/print.c:3292 #, c-format msgid "Cannot add cell to table content: total cell count of % exceeded.\n" msgstr "Kann keine weitere Zelle zur Tabelle hinzufügen: Zellengesamtzahl % überschritten.\n" -#: ../../fe_utils/print.c:3719 +#: ../../fe_utils/print.c:3720 #, c-format msgid "invalid output format (internal error): %d" msgstr "ungültiges Ausgabeformat (interner Fehler): %d" @@ -218,12 +218,12 @@ msgstr "Anfrage fehlgeschlagen: %s" msgid "Query was: %s" msgstr "Anfrage war: %s" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "Argument des Shell-Befehls enthält Newline oder Carriage Return: »%s«\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "Datenbankname enthält Newline oder Carriage Return: »%s«\n" @@ -272,18 +272,18 @@ msgstr "" "\n" #: clusterdb.c:274 createdb.c:300 createuser.c:417 dropdb.c:171 dropuser.c:171 -#: pg_isready.c:226 reindexdb.c:898 vacuumdb.c:349 +#: pg_isready.c:226 reindexdb.c:898 vacuumdb.c:351 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" -#: clusterdb.c:275 reindexdb.c:899 vacuumdb.c:350 +#: clusterdb.c:275 reindexdb.c:899 vacuumdb.c:352 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [OPTION]... [DBNAME]\n" #: clusterdb.c:276 createdb.c:302 createuser.c:419 dropdb.c:173 dropuser.c:173 -#: pg_isready.c:229 reindexdb.c:900 vacuumdb.c:351 +#: pg_isready.c:229 reindexdb.c:900 vacuumdb.c:353 #, c-format msgid "" "\n" @@ -335,7 +335,7 @@ msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" #: clusterdb.c:285 createdb.c:319 createuser.c:450 dropdb.c:180 dropuser.c:180 -#: pg_isready.c:235 reindexdb.c:915 vacuumdb.c:382 +#: pg_isready.c:235 reindexdb.c:915 vacuumdb.c:384 #, c-format msgid "" "\n" @@ -344,32 +344,32 @@ msgstr "" "\n" "Verbindungsoptionen:\n" -#: clusterdb.c:286 createuser.c:451 dropdb.c:181 dropuser.c:181 vacuumdb.c:383 +#: clusterdb.c:286 createuser.c:451 dropdb.c:181 dropuser.c:181 vacuumdb.c:385 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=HOSTNAME Name des Datenbankservers oder Socket-Verzeichnis\n" -#: clusterdb.c:287 createuser.c:452 dropdb.c:182 dropuser.c:182 vacuumdb.c:384 +#: clusterdb.c:287 createuser.c:452 dropdb.c:182 dropuser.c:182 vacuumdb.c:386 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PORT Port des Datenbankservers\n" -#: clusterdb.c:288 dropdb.c:183 vacuumdb.c:385 +#: clusterdb.c:288 dropdb.c:183 vacuumdb.c:387 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=NAME Datenbankbenutzername\n" -#: clusterdb.c:289 createuser.c:454 dropdb.c:184 dropuser.c:184 vacuumdb.c:386 +#: clusterdb.c:289 createuser.c:454 dropdb.c:184 dropuser.c:184 vacuumdb.c:388 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password niemals nach Passwort fragen\n" -#: clusterdb.c:290 createuser.c:455 dropdb.c:185 dropuser.c:185 vacuumdb.c:387 +#: clusterdb.c:290 createuser.c:455 dropdb.c:185 dropuser.c:185 vacuumdb.c:389 #, c-format msgid " -W, --password force password prompt\n" msgstr " -W, --password Passwortfrage erzwingen\n" -#: clusterdb.c:291 dropdb.c:186 vacuumdb.c:388 +#: clusterdb.c:291 dropdb.c:186 vacuumdb.c:390 #, c-format msgid " --maintenance-db=DBNAME alternate maintenance database\n" msgstr " --maintenance-db=DBNAME alternative Wartungsdatenbank\n" @@ -385,7 +385,7 @@ msgstr "" "SQL-Befehls CLUSTER.\n" #: clusterdb.c:293 createdb.c:327 createuser.c:456 dropdb.c:187 dropuser.c:186 -#: pg_isready.c:240 reindexdb.c:923 vacuumdb.c:390 +#: pg_isready.c:240 reindexdb.c:923 vacuumdb.c:392 #, c-format msgid "" "\n" @@ -395,7 +395,7 @@ msgstr "" "Berichten Sie Fehler an <%s>.\n" #: clusterdb.c:294 createdb.c:328 createuser.c:457 dropdb.c:188 dropuser.c:187 -#: pg_isready.c:241 reindexdb.c:924 vacuumdb.c:391 +#: pg_isready.c:241 reindexdb.c:924 vacuumdb.c:393 #, c-format msgid "%s home page: <%s>\n" msgstr "%s Homepage: <%s>\n" @@ -1101,36 +1101,37 @@ msgstr "kann Option »%s« nicht mit der Option »%s« verwenden" msgid "cannot use the \"%s\" option without \"%s\" or \"%s\"" msgstr "kann Option »%s« nicht ohne »%s« oder »%s« verwenden" -#: vacuumdb.c:311 +#: vacuumdb.c:312 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"No commands will be sent to the server." -msgstr "" -"Ausführen im Probelaufmodus.\n" -"Keine Befehle werden an den Server gesendet werden." +msgid "executing in dry-run mode" +msgstr "Ausführen im Probelaufmodus" + +#: vacuumdb.c:313 +#, c-format +msgid "No commands will be sent to the server." +msgstr "Keine Befehle werden an den Server gesendet werden." -#: vacuumdb.c:329 +#: vacuumdb.c:331 #, c-format msgid "cannot vacuum all databases and a specific one at the same time" msgstr "kann nicht alle Datenbanken und eine bestimmte gleichzeitig vacuumen" -#: vacuumdb.c:333 +#: vacuumdb.c:335 #, c-format msgid "cannot vacuum all tables in schema(s) and specific table(s) at the same time" msgstr "kann nicht alle Tabellen in Schemas und bestimmte Tabellen gleichzeitig vacuumen" -#: vacuumdb.c:337 +#: vacuumdb.c:339 #, c-format msgid "cannot vacuum specific table(s) and exclude schema(s) at the same time" msgstr "kann nicht bestimmte Tabelle(n) vacuumen und gleichzeitig Schemas ausschließen" -#: vacuumdb.c:341 +#: vacuumdb.c:343 #, c-format msgid "cannot vacuum all tables in schema(s) and exclude schema(s) at the same time" msgstr "kann nicht alle Tabellen in Schemas vacuumen und gleichzeitig Schemas ausschließen" -#: vacuumdb.c:348 +#: vacuumdb.c:350 #, c-format msgid "" "%s cleans and analyzes a PostgreSQL database.\n" @@ -1139,160 +1140,160 @@ msgstr "" "%s säubert und analysiert eine PostgreSQL-Datenbank.\n" "\n" -#: vacuumdb.c:352 +#: vacuumdb.c:354 #, c-format msgid " -a, --all vacuum all databases\n" msgstr " -a, --all führe Vacuum in allen Datenbanken aus\n" -#: vacuumdb.c:353 +#: vacuumdb.c:355 #, c-format msgid " --buffer-usage-limit=SIZE size of ring buffer used for vacuum\n" msgstr " --buffer-usage-limit=GRÖSSE Größe des für Vacuum verwendeten Ringpuffers\n" -#: vacuumdb.c:354 +#: vacuumdb.c:356 #, c-format msgid " -d, --dbname=DBNAME database to vacuum\n" msgstr " -d, --dbname=DBNAME führe Vacuum in dieser Datenbank aus\n" -#: vacuumdb.c:355 +#: vacuumdb.c:357 #, c-format msgid " --disable-page-skipping disable all page-skipping behavior\n" msgstr " --disable-page-skipping Page-Skipping-Verhalten abschalten\n" -#: vacuumdb.c:356 +#: vacuumdb.c:358 #, c-format msgid " --dry-run show the commands that would be sent to the server\n" msgstr "" " --dry-run zeige die Befehle, die an den Server gesendet\n" " werden würden\n" -#: vacuumdb.c:357 +#: vacuumdb.c:359 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr "" " -e, --echo zeige die Befehle, die an den Server\n" " gesendet werden\n" -#: vacuumdb.c:358 +#: vacuumdb.c:360 #, c-format msgid " -f, --full do full vacuuming\n" msgstr " -f, --full führe volles Vacuum durch\n" -#: vacuumdb.c:359 +#: vacuumdb.c:361 #, c-format msgid " -F, --freeze freeze row transaction information\n" msgstr " -F, --freeze Zeilentransaktionsinformationen einfrieren\n" -#: vacuumdb.c:360 +#: vacuumdb.c:362 #, c-format msgid " --force-index-cleanup always remove index entries that point to dead tuples\n" msgstr " --force-index-cleanup Indexeinträge, die auf tote Tupel zeigen, immer entfernen\n" -#: vacuumdb.c:361 +#: vacuumdb.c:363 #, c-format msgid " -j, --jobs=NUM use this many concurrent connections to vacuum\n" msgstr "" " -j, --jobs=NUM so viele parallele Verbindungen zum Vacuum\n" " verwenden\n" -#: vacuumdb.c:362 +#: vacuumdb.c:364 #, c-format msgid " --min-mxid-age=MXID_AGE minimum multixact ID age of tables to vacuum\n" msgstr "" " --min-mxid-age=MXID-ALTER minimales Multixact-ID-Alter zu bearbeitender\n" " Tabellen\n" -#: vacuumdb.c:363 +#: vacuumdb.c:365 #, c-format msgid " --min-xid-age=XID_AGE minimum transaction ID age of tables to vacuum\n" msgstr "" " --min-xid-age=XID-ALTER minimales Transaktions-ID-Alter zu bearbeitender\n" " Tabellen\n" -#: vacuumdb.c:364 +#: vacuumdb.c:366 #, c-format msgid " --missing-stats-only only analyze relations with missing statistics\n" msgstr " --missing-stats-only nur Relationen mit fehlenden Statistiken analysieren\n" -#: vacuumdb.c:365 +#: vacuumdb.c:367 #, c-format msgid " --no-index-cleanup don't remove index entries that point to dead tuples\n" msgstr " --no-index-cleanup Indexeinträge, die auf tote Tupel zeigen, nicht entfernen\n" -#: vacuumdb.c:366 +#: vacuumdb.c:368 #, c-format msgid " --no-process-main skip the main relation\n" msgstr " --no-process-main die Hauptrelation überspringen\n" -#: vacuumdb.c:367 +#: vacuumdb.c:369 #, c-format msgid " --no-process-toast skip the TOAST table associated with the table to vacuum\n" msgstr " --no-process-toast zur Tabelle gehörige TOAST-Tabelle überspringen\n" -#: vacuumdb.c:368 +#: vacuumdb.c:370 #, c-format msgid " --no-truncate don't truncate empty pages at the end of the table\n" msgstr " --no-truncate leere Seiten am Ende der Tabelle nicht abschneiden\n" -#: vacuumdb.c:369 +#: vacuumdb.c:371 #, c-format msgid " -n, --schema=SCHEMA vacuum tables in the specified schema(s) only\n" msgstr " -n, --schema=SCHEMA nur Tabellen in den angegebenen Schemas vacuumen\n" -#: vacuumdb.c:370 +#: vacuumdb.c:372 #, c-format msgid " -N, --exclude-schema=SCHEMA do not vacuum tables in the specified schema(s)\n" msgstr " -N, --exclude-schema=SCHEMA Tabellen in den angegebenen Schemas nicht vacuumen\n" -#: vacuumdb.c:371 +#: vacuumdb.c:373 #, c-format msgid " -P, --parallel=PARALLEL_WORKERS use this many background workers for vacuum, if available\n" msgstr "" " -P, --parallel=PARALLEL-PROZ so viele Background-Worker für Vacuum verwenden,\n" " wenn verfügbar\n" -#: vacuumdb.c:372 +#: vacuumdb.c:374 #, c-format msgid " -q, --quiet don't write any messages\n" msgstr " -q, --quiet unterdrücke alle Mitteilungen\n" -#: vacuumdb.c:373 +#: vacuumdb.c:375 #, c-format msgid " --skip-locked skip relations that cannot be immediately locked\n" msgstr "" " --skip-locked Relationen überspringen, die nicht sofort\n" " gesperrt werden können\n" -#: vacuumdb.c:374 +#: vacuumdb.c:376 #, c-format msgid " -t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only\n" msgstr "" " -t, --table='TABELLE[(SPALTEN)]'\n" " führe Vacuum für bestimmte Tabelle(n) aus\n" -#: vacuumdb.c:375 +#: vacuumdb.c:377 #, c-format msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose erzeuge viele Meldungen\n" -#: vacuumdb.c:376 +#: vacuumdb.c:378 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: vacuumdb.c:377 +#: vacuumdb.c:379 #, c-format msgid " -z, --analyze update optimizer statistics\n" msgstr " -z, --analyze aktualisiere Statistiken für den Optimierer\n" -#: vacuumdb.c:378 +#: vacuumdb.c:380 #, c-format msgid " -Z, --analyze-only only update optimizer statistics; no vacuum\n" msgstr "" " -Z, --analyze-only aktualisiere nur Statistiken für den Optimierer;\n" " kein Vacuum\n" -#: vacuumdb.c:379 +#: vacuumdb.c:381 #, c-format msgid "" " --analyze-in-stages only update optimizer statistics, in multiple\n" @@ -1302,12 +1303,12 @@ msgstr "" " in mehreren Phasen für schnellere Ergebnisse;\n" " kein Vacuum\n" -#: vacuumdb.c:381 +#: vacuumdb.c:383 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: vacuumdb.c:389 +#: vacuumdb.c:391 #, c-format msgid "" "\n" @@ -1339,17 +1340,17 @@ msgstr "%s: bearbeite Datenbank »%s«: %s\n" msgid "%s: vacuuming database \"%s\"\n" msgstr "%s: führe Vacuum in Datenbank »%s« aus\n" -#: vacuuming.c:1027 +#: vacuuming.c:1029 #, c-format msgid "vacuuming of table \"%s\" in database \"%s\" failed: %s" msgstr "Vacuum der Tabelle »%s« in Datenbank »%s« fehlgeschlagen: %s" -#: vacuuming.c:1032 +#: vacuuming.c:1034 #, c-format msgid "vacuuming of database \"%s\" failed: %s" msgstr "Vacuum der Datenbank »%s« fehlgeschlagen: %s" -#: vacuuming.c:1048 +#: vacuuming.c:1050 #, c-format msgid "out of memory" msgstr "Speicher aufgebraucht" diff --git a/src/bin/scripts/po/ja.po b/src/bin/scripts/po/ja.po index 22e65b78ad3..c21c425d03f 100644 --- a/src/bin/scripts/po/ja.po +++ b/src/bin/scripts/po/ja.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: scripts (PostgreSQL 19)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-15 13:38+0900\n" -"PO-Revision-Date: 2026-05-15 15:02+0900\n" +"POT-Creation-Date: 2026-07-06 09:46+0900\n" +"PO-Revision-Date: 2026-07-06 15:12+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: jpug-doc \n" "Language: ja\n" @@ -185,27 +185,27 @@ msgid "(%lu row)" msgid_plural "(%lu rows)" msgstr[0] "(%lu 行)" -#: ../../fe_utils/print.c:3173 +#: ../../fe_utils/print.c:3191 #, c-format msgid "Interrupted\n" msgstr "中断されました\n" -#: ../../fe_utils/print.c:3207 +#: ../../fe_utils/print.c:3225 #, c-format msgid "Cannot print table contents: number of cells % is equal to or exceeds maximum %zu.\n" msgstr "テーブルの内容を表示できません: セル数%が上限値%zu以上です。\n" -#: ../../fe_utils/print.c:3248 +#: ../../fe_utils/print.c:3266 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "テーブルの内容に見出しを追加できませんでした:列数の上限値%dを越えています。\n" -#: ../../fe_utils/print.c:3291 +#: ../../fe_utils/print.c:3309 #, c-format msgid "Cannot add cell to table content: total cell count of % exceeded.\n" msgstr "テーブルの内容にセルを追加できません: セルの総数%を超過しています。\n" -#: ../../fe_utils/print.c:3719 +#: ../../fe_utils/print.c:3737 #, c-format msgid "invalid output format (internal error): %d" msgstr "出力フォーマットが無効(内部エラー):%d" @@ -220,12 +220,12 @@ msgstr "問い合わせが失敗しました: %s" msgid "Query was: %s" msgstr "問い合わせ: %s" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "シェルコマンドの引数に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "データベース名に改行(LF)または復帰(CR)が含まれています: \"%s\"\n" @@ -272,18 +272,18 @@ msgid "" msgstr "%sはデータベース内で事前にクラスタ化されているすべてのテーブルをクラスタ化します。\n" #: clusterdb.c:274 createdb.c:300 createuser.c:417 dropdb.c:171 dropuser.c:171 -#: pg_isready.c:226 reindexdb.c:898 vacuumdb.c:349 +#: pg_isready.c:226 reindexdb.c:898 vacuumdb.c:351 #, c-format msgid "Usage:\n" msgstr "使用方法:\n" -#: clusterdb.c:275 reindexdb.c:899 vacuumdb.c:350 +#: clusterdb.c:275 reindexdb.c:899 vacuumdb.c:352 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [オプション]... [データベース名]\n" #: clusterdb.c:276 createdb.c:302 createuser.c:419 dropdb.c:173 dropuser.c:173 -#: pg_isready.c:229 reindexdb.c:900 vacuumdb.c:351 +#: pg_isready.c:229 reindexdb.c:900 vacuumdb.c:353 #, c-format msgid "" "\n" @@ -333,7 +333,7 @@ msgid " -?, --help show this help, then exit\n" msgstr " -?, --help このヘルプを表示して終了\n" #: clusterdb.c:285 createdb.c:319 createuser.c:450 dropdb.c:180 dropuser.c:180 -#: pg_isready.c:235 reindexdb.c:915 vacuumdb.c:382 +#: pg_isready.c:235 reindexdb.c:915 vacuumdb.c:384 #, c-format msgid "" "\n" @@ -342,34 +342,34 @@ msgstr "" "\n" "接続オプション:\n" -#: clusterdb.c:286 createuser.c:451 dropdb.c:181 dropuser.c:181 vacuumdb.c:383 +#: clusterdb.c:286 createuser.c:451 dropdb.c:181 dropuser.c:181 vacuumdb.c:385 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr "" " -h, --host=HOSTNAME データベースサーバーのホストまたはソケット\n" " ディレクトリ\n" -#: clusterdb.c:287 createuser.c:452 dropdb.c:182 dropuser.c:182 vacuumdb.c:384 +#: clusterdb.c:287 createuser.c:452 dropdb.c:182 dropuser.c:182 vacuumdb.c:386 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PORT データベースサーバーのポート番号\n" -#: clusterdb.c:288 dropdb.c:183 vacuumdb.c:385 +#: clusterdb.c:288 dropdb.c:183 vacuumdb.c:387 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=USERNAME このユーザー名で接続\n" -#: clusterdb.c:289 createuser.c:454 dropdb.c:184 dropuser.c:184 vacuumdb.c:386 +#: clusterdb.c:289 createuser.c:454 dropdb.c:184 dropuser.c:184 vacuumdb.c:388 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password パスワード入力を要求しない\n" -#: clusterdb.c:290 createuser.c:455 dropdb.c:185 dropuser.c:185 vacuumdb.c:387 +#: clusterdb.c:290 createuser.c:455 dropdb.c:185 dropuser.c:185 vacuumdb.c:389 #, c-format msgid " -W, --password force password prompt\n" msgstr " -W, --password パスワードプロンプトを強制表示\n" -#: clusterdb.c:291 dropdb.c:186 vacuumdb.c:388 +#: clusterdb.c:291 dropdb.c:186 vacuumdb.c:390 #, c-format msgid " --maintenance-db=DBNAME alternate maintenance database\n" msgstr " --maintenance-db=DBNAME 別の保守用データベースを指定\n" @@ -384,7 +384,7 @@ msgstr "" "詳細は SQL コマンドの CLUSTER の説明を参照してください。\n" #: clusterdb.c:293 createdb.c:327 createuser.c:456 dropdb.c:187 dropuser.c:186 -#: pg_isready.c:240 reindexdb.c:923 vacuumdb.c:390 +#: pg_isready.c:240 reindexdb.c:923 vacuumdb.c:392 #, c-format msgid "" "\n" @@ -394,7 +394,7 @@ msgstr "" "バグは<%s>に報告してください。\n" #: clusterdb.c:294 createdb.c:328 createuser.c:457 dropdb.c:188 dropuser.c:187 -#: pg_isready.c:241 reindexdb.c:924 vacuumdb.c:391 +#: pg_isready.c:241 reindexdb.c:924 vacuumdb.c:393 #, c-format msgid "%s home page: <%s>\n" msgstr "%s ホームページ: <%s>\n" @@ -1086,190 +1086,191 @@ msgstr "\"%s\"オプションは\"%s\"と同時には使えません" msgid "cannot use the \"%s\" option without \"%s\" or \"%s\"" msgstr "\"%s\"オプションは、\"%s\"または\"%s\"がないと使用できません。" -#: vacuumdb.c:311 +#: vacuumdb.c:312 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"No commands will be sent to the server." -msgstr "" -"ドライランモードで実行します。\n" -"コマンドは一切サーバーへは送信されません。" +msgid "executing in dry-run mode" +msgstr "ドライランモードで実行します" + +#: vacuumdb.c:313 +#, c-format +msgid "No commands will be sent to the server." +msgstr "サーバーへコマンドは一切送信されません。" -#: vacuumdb.c:329 +#: vacuumdb.c:331 #, c-format msgid "cannot vacuum all databases and a specific one at the same time" msgstr "全データベースと特定のデータベースを同時にVACUUMすることはできません" -#: vacuumdb.c:333 +#: vacuumdb.c:335 #, c-format msgid "cannot vacuum all tables in schema(s) and specific table(s) at the same time" msgstr "スキーマ(群)に属するすべてのテーブルと、特定のテーブル(群)とを同時にVACUUMすることはできません" -#: vacuumdb.c:337 +#: vacuumdb.c:339 #, c-format msgid "cannot vacuum specific table(s) and exclude schema(s) at the same time" msgstr "特定のテーブル(群)のVACUUMと同時にスキーマ(群)の除外を行うことはできません" -#: vacuumdb.c:341 +#: vacuumdb.c:343 #, c-format msgid "cannot vacuum all tables in schema(s) and exclude schema(s) at the same time" msgstr "スキーマ(群)のすべてのテーブルのVACUUMと同時にスキーマ(群)の除外を行うことはできません" -#: vacuumdb.c:348 +#: vacuumdb.c:350 #, c-format msgid "" "%s cleans and analyzes a PostgreSQL database.\n" "\n" msgstr "%sはPostgreSQLデータベースのゴミ回収および分析を行います。\n" -#: vacuumdb.c:352 +#: vacuumdb.c:354 #, c-format msgid " -a, --all vacuum all databases\n" msgstr " -a, --all 全データベースをVACUUM\n" -#: vacuumdb.c:353 +#: vacuumdb.c:355 #, c-format msgid " --buffer-usage-limit=SIZE size of ring buffer used for vacuum\n" msgstr " --buffer-usage-limit=SIZE VACUUMで使用するリングバッファのサイズ\n" -#: vacuumdb.c:354 +#: vacuumdb.c:356 #, c-format msgid " -d, --dbname=DBNAME database to vacuum\n" msgstr " -d, --dbname=DBNAME VACUUMするデータベース名\n" -#: vacuumdb.c:355 +#: vacuumdb.c:357 #, c-format msgid " --disable-page-skipping disable all page-skipping behavior\n" msgstr " --disable-page-skipping すべてのページスキップ動作を禁止\n" -#: vacuumdb.c:356 +#: vacuumdb.c:358 #, c-format msgid " --dry-run show the commands that would be sent to the server\n" msgstr " --dry-run サーバーへ送信されることになるコマンドを表示\n" -#: vacuumdb.c:357 +#: vacuumdb.c:359 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr " -e, --echo サーバーへ送信されるコマンドを表示\n" -#: vacuumdb.c:358 +#: vacuumdb.c:360 #, c-format msgid " -f, --full do full vacuuming\n" msgstr " -f, --full VACUUM FULLを実行\n" -#: vacuumdb.c:359 +#: vacuumdb.c:361 #, c-format msgid " -F, --freeze freeze row transaction information\n" msgstr " -F, --freeze 行トランザクション情報を凍結\n" -#: vacuumdb.c:360 +#: vacuumdb.c:362 #, c-format msgid " --force-index-cleanup always remove index entries that point to dead tuples\n" msgstr "" " --force-index-cleanup デッドタプルを指すインデックスエントリを常に\n" " 除去する\n" -#: vacuumdb.c:361 +#: vacuumdb.c:363 #, c-format msgid " -j, --jobs=NUM use this many concurrent connections to vacuum\n" msgstr " -j, --jobs=NUM バキューム時に指定した同時接続数を使用\n" -#: vacuumdb.c:362 +#: vacuumdb.c:364 #, c-format msgid " --min-mxid-age=MXID_AGE minimum multixact ID age of tables to vacuum\n" msgstr "" " --min-mxid-age=MXID_AGE VACUUM対象とするテーブルの最小のマルチ\n" " トランザクションID差分\n" -#: vacuumdb.c:363 +#: vacuumdb.c:365 #, c-format msgid " --min-xid-age=XID_AGE minimum transaction ID age of tables to vacuum\n" msgstr "" " --min-xid-age=XID_AGE VACUUM対象とするテーブルの最小の\n" " トランザクションID差分\n" -#: vacuumdb.c:364 +#: vacuumdb.c:366 #, c-format msgid " --missing-stats-only only analyze relations with missing statistics\n" msgstr " --missing-stats-only 統計情報がないリレーションのみをANALYZEする\n" -#: vacuumdb.c:365 +#: vacuumdb.c:367 #, c-format msgid " --no-index-cleanup don't remove index entries that point to dead tuples\n" msgstr "" " --no-index-cleanup デッドタプルを指すインデックスエントリを\n" " 削除しない\n" -#: vacuumdb.c:366 +#: vacuumdb.c:368 #, c-format msgid " --no-process-main skip the main relation\n" msgstr " --no-process-main メインリレーションをスキップ\n" -#: vacuumdb.c:367 +#: vacuumdb.c:369 #, c-format msgid " --no-process-toast skip the TOAST table associated with the table to vacuum\n" msgstr "" " --no-process-toast テーブルに関連づくTOASTテーブルのVACUUMを\n" " スキップ\n" -#: vacuumdb.c:368 +#: vacuumdb.c:370 #, c-format msgid " --no-truncate don't truncate empty pages at the end of the table\n" msgstr " --no-truncate テーブル終端の空ページの切り詰めを行わない\n" -#: vacuumdb.c:369 +#: vacuumdb.c:371 #, c-format msgid " -n, --schema=SCHEMA vacuum tables in the specified schema(s) only\n" msgstr " - -n, --schema=SCHEMA 指定したスキーマ(群)のテーブルのみをVACUUMする\n" -#: vacuumdb.c:370 +#: vacuumdb.c:372 #, c-format msgid " -N, --exclude-schema=SCHEMA do not vacuum tables in the specified schema(s)\n" msgstr " -N, --exclude-schema=SCHEMA 指定したスキーマ(群)のテーブルをVACUUMしない\n" -#: vacuumdb.c:371 +#: vacuumdb.c:373 #, c-format msgid " -P, --parallel=PARALLEL_WORKERS use this many background workers for vacuum, if available\n" msgstr "" " -P, --parallel=PARALLEL_WORKERS 可能であればVACUUMで指定の数のバックグラウンド\n" " ワーカーを使用\n" -#: vacuumdb.c:372 +#: vacuumdb.c:374 #, c-format msgid " -q, --quiet don't write any messages\n" msgstr " -q, --quiet メッセージを出力しない\n" -#: vacuumdb.c:373 +#: vacuumdb.c:375 #, c-format msgid " --skip-locked skip relations that cannot be immediately locked\n" msgstr " --skip-locked 直ちにロックできなかったリレーションをスキップ\n" -#: vacuumdb.c:374 +#: vacuumdb.c:376 #, c-format msgid " -t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only\n" msgstr " -t, --table='TABLE[(COLUMNS)]' 指定したテーブル(複数可)のみをVACUUM\n" -#: vacuumdb.c:375 +#: vacuumdb.c:377 #, c-format msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose 多量のメッセージを出力\n" -#: vacuumdb.c:376 +#: vacuumdb.c:378 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version バージョン情報を表示して終了\n" -#: vacuumdb.c:377 +#: vacuumdb.c:379 #, c-format msgid " -z, --analyze update optimizer statistics\n" msgstr " -z, --analyze 最適化用統計情報を更新\n" -#: vacuumdb.c:378 +#: vacuumdb.c:380 #, c-format msgid " -Z, --analyze-only only update optimizer statistics; no vacuum\n" msgstr " -Z, --analyze-only 最適化用統計情報のみ更新; バキュームは行わない\n" -#: vacuumdb.c:379 +#: vacuumdb.c:381 #, c-format msgid "" " --analyze-in-stages only update optimizer statistics, in multiple\n" @@ -1278,12 +1279,12 @@ msgstr "" " --analyze-in-stages 高速化のため最適化用統計情報のみを複数段階で\n" " 更新; VACUUMは行わない\n" -#: vacuumdb.c:381 +#: vacuumdb.c:383 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help このヘルプを表示して終了\n" -#: vacuumdb.c:389 +#: vacuumdb.c:391 #, c-format msgid "" "\n" @@ -1314,17 +1315,17 @@ msgstr "%s: データベース\"%s\"の処理中です: %s\n" msgid "%s: vacuuming database \"%s\"\n" msgstr "%s: データベース\"%s\"をVACUUMしています\n" -#: vacuuming.c:1027 +#: vacuuming.c:1029 #, c-format msgid "vacuuming of table \"%s\" in database \"%s\" failed: %s" msgstr "データベース \"%2$s\"のテーブル\"%1$sのVACUUMに失敗しました: %3$s" -#: vacuuming.c:1032 +#: vacuuming.c:1034 #, c-format msgid "vacuuming of database \"%s\" failed: %s" msgstr "データベース\"%s\"のVACUUMに失敗しました: %s" -#: vacuuming.c:1048 +#: vacuuming.c:1050 #, c-format msgid "out of memory" msgstr "メモリ不足です" diff --git a/src/bin/scripts/po/ka.po b/src/bin/scripts/po/ka.po index 57f17a79acb..d42d43f5005 100644 --- a/src/bin/scripts/po/ka.po +++ b/src/bin/scripts/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pgscripts (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-13 06:25+0000\n" -"PO-Revision-Date: 2026-05-13 09:21+0200\n" +"POT-Creation-Date: 2026-07-04 00:24+0000\n" +"PO-Revision-Date: 2026-07-04 07:34+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -184,27 +184,27 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu მწკრივი)" msgstr[1] "(%lu მწკრივი)" -#: ../../fe_utils/print.c:3173 +#: ../../fe_utils/print.c:3174 #, c-format msgid "Interrupted\n" msgstr "შეწყვეტილია\n" -#: ../../fe_utils/print.c:3207 +#: ../../fe_utils/print.c:3208 #, c-format msgid "Cannot print table contents: number of cells % is equal to or exceeds maximum %zu.\n" msgstr "ვერ გამოვიტანე ცხრილის შემცველობა: უჯრედების რაოდენობა % მაქსიმუმის %zu ტოლი ან მასზე მეტია.\n" -#: ../../fe_utils/print.c:3248 +#: ../../fe_utils/print.c:3249 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "ცხრილის შემცველობაზე თავსართის დამატება შეუძლებელია: სვეტების რაოდენობა %d გადაჭარბებულია.\n" -#: ../../fe_utils/print.c:3291 +#: ../../fe_utils/print.c:3292 #, c-format msgid "Cannot add cell to table content: total cell count of % exceeded.\n" msgstr "ცხრილის შემცველობაზე უჯრედის დამატება შეუძლებელია: უჯრედების ჯამური რაოდენობა %-ზე მეტია.\n" -#: ../../fe_utils/print.c:3719 +#: ../../fe_utils/print.c:3720 #, c-format msgid "invalid output format (internal error): %d" msgstr "გამოტანის არასწორი ფორმატი (შიდა შეცდომა): %d" @@ -219,12 +219,12 @@ msgstr "მოთხოვნის შეცდომა: %s" msgid "Query was: %s" msgstr "მოთხოვნის შინაარსი: %s" -#: ../../fe_utils/string_utils.c:581 +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "გარსის ბრძანების არგუმენტი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" -#: ../../fe_utils/string_utils.c:754 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "მონაცემთა ბაზის სახელი ხაზის გადატანას ან კარეტის დაბრუნებას შეიცავს: \"%s\"\n" @@ -273,18 +273,18 @@ msgstr "" "\n" #: clusterdb.c:274 createdb.c:300 createuser.c:417 dropdb.c:171 dropuser.c:171 -#: pg_isready.c:226 reindexdb.c:898 vacuumdb.c:349 +#: pg_isready.c:226 reindexdb.c:898 vacuumdb.c:351 #, c-format msgid "Usage:\n" msgstr "გამოყენება:\n" -#: clusterdb.c:275 reindexdb.c:899 vacuumdb.c:350 +#: clusterdb.c:275 reindexdb.c:899 vacuumdb.c:352 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [პარამეტრი]... [ბაზისსახელი]\n" #: clusterdb.c:276 createdb.c:302 createuser.c:419 dropdb.c:173 dropuser.c:173 -#: pg_isready.c:229 reindexdb.c:900 vacuumdb.c:351 +#: pg_isready.c:229 reindexdb.c:900 vacuumdb.c:353 #, c-format msgid "" "\n" @@ -334,7 +334,7 @@ msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ამ დახმარების ჩვენება და გასვლა\n" #: clusterdb.c:285 createdb.c:319 createuser.c:450 dropdb.c:180 dropuser.c:180 -#: pg_isready.c:235 reindexdb.c:915 vacuumdb.c:382 +#: pg_isready.c:235 reindexdb.c:915 vacuumdb.c:384 #, c-format msgid "" "\n" @@ -343,32 +343,32 @@ msgstr "" "\n" "შეერთების პარამეტრები:\n" -#: clusterdb.c:286 createuser.c:451 dropdb.c:181 dropuser.c:181 vacuumdb.c:383 +#: clusterdb.c:286 createuser.c:451 dropdb.c:181 dropuser.c:181 vacuumdb.c:385 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=HOSTNAME მონაცემთა ბაზის სერვერის ჰოსტის ან სოკეტის საქაღალდე\n" -#: clusterdb.c:287 createuser.c:452 dropdb.c:182 dropuser.c:182 vacuumdb.c:384 +#: clusterdb.c:287 createuser.c:452 dropdb.c:182 dropuser.c:182 vacuumdb.c:386 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PORT მონაცემთა ბაზის სერვერის პორტი\n" -#: clusterdb.c:288 dropdb.c:183 vacuumdb.c:385 +#: clusterdb.c:288 dropdb.c:183 vacuumdb.c:387 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=მომხმარებ. ბაზის მომხმარებლის სახელი\n" -#: clusterdb.c:289 createuser.c:454 dropdb.c:184 dropuser.c:184 vacuumdb.c:386 +#: clusterdb.c:289 createuser.c:454 dropdb.c:184 dropuser.c:184 vacuumdb.c:388 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password არასოდეს მკითხო პაროლი\n" -#: clusterdb.c:290 createuser.c:455 dropdb.c:185 dropuser.c:185 vacuumdb.c:387 +#: clusterdb.c:290 createuser.c:455 dropdb.c:185 dropuser.c:185 vacuumdb.c:389 #, c-format msgid " -W, --password force password prompt\n" msgstr " -W, --password პაროლის ყოველთვის კითხვა\n" -#: clusterdb.c:291 dropdb.c:186 vacuumdb.c:388 +#: clusterdb.c:291 dropdb.c:186 vacuumdb.c:390 #, c-format msgid " --maintenance-db=DBNAME alternate maintenance database\n" msgstr " --maintenance-db=ბაზისსახელი ალტერნატიული საავარიო ბაზა\n" @@ -383,7 +383,7 @@ msgstr "" "დაკლასტერების შესახებ მეტი ინფორმაციის მიღება SQL ბრძანების, CLUSTER, დეტალებში შეგიძლიათ.\n" #: clusterdb.c:293 createdb.c:327 createuser.c:456 dropdb.c:187 dropuser.c:186 -#: pg_isready.c:240 reindexdb.c:923 vacuumdb.c:390 +#: pg_isready.c:240 reindexdb.c:923 vacuumdb.c:392 #, c-format msgid "" "\n" @@ -393,7 +393,7 @@ msgstr "" "შეცდომების შესახებ მიწერეთ: %s\n" #: clusterdb.c:294 createdb.c:328 createuser.c:457 dropdb.c:188 dropuser.c:187 -#: pg_isready.c:241 reindexdb.c:924 vacuumdb.c:391 +#: pg_isready.c:241 reindexdb.c:924 vacuumdb.c:393 #, c-format msgid "%s home page: <%s>\n" msgstr "%s-ის საწყისი გვერდია: <%s>\n" @@ -1083,36 +1083,37 @@ msgstr "\"%s\" პარამეტრთან ერთად \"%s\"-ის msgid "cannot use the \"%s\" option without \"%s\" or \"%s\"" msgstr "\"%s\" პარამეტრთან ერთად \"%s\"-ის, ან \"%s\"-ის გამოყენება შეუძლებელია" -#: vacuumdb.c:311 +#: vacuumdb.c:312 #, c-format -msgid "" -"Executing in dry-run mode.\n" -"No commands will be sent to the server." -msgstr "" -"შესრულება მშრალი გაშვების რეჟიმში.\n" -"სერვერზე ბრძანებები არ გაიგზავნება." +msgid "executing in dry-run mode" +msgstr "შესრულება მშრალი გაშვების რეჟიმში" + +#: vacuumdb.c:313 +#, c-format +msgid "No commands will be sent to the server." +msgstr "სერვერზე ბრძანებები არ გაიგზავნება." -#: vacuumdb.c:329 +#: vacuumdb.c:331 #, c-format msgid "cannot vacuum all databases and a specific one at the same time" msgstr "ყველა და მითითებული ბაზების ერთდროული დამტვერსასრუტება შეუძლებელია" -#: vacuumdb.c:333 +#: vacuumdb.c:335 #, c-format msgid "cannot vacuum all tables in schema(s) and specific table(s) at the same time" msgstr "სქემებში ყველა ცხრილის და მითითებული ცხრილების ერთდროული მომტვერსასრუტება შეუძლებელია" -#: vacuumdb.c:337 +#: vacuumdb.c:339 #, c-format msgid "cannot vacuum specific table(s) and exclude schema(s) at the same time" msgstr "მითითებულ ცხრილების მომტვერსასრუტება და სქემების გამორიცხვა ერთდროულად შეუძლებელია" -#: vacuumdb.c:341 +#: vacuumdb.c:343 #, c-format msgid "cannot vacuum all tables in schema(s) and exclude schema(s) at the same time" msgstr "სქემებში ყველა ცხრილის მომტვერსასრუტება და ამავე დროს სქემების გამორიცხვა შეუძლებელია" -#: vacuumdb.c:348 +#: vacuumdb.c:350 #, c-format msgid "" "%s cleans and analyzes a PostgreSQL database.\n" @@ -1121,142 +1122,142 @@ msgstr "" "%s PostgreSQL ბაზის გასუფთავება და ოპტიმიზაცია.\n" "\n" -#: vacuumdb.c:352 +#: vacuumdb.c:354 #, c-format msgid " -a, --all vacuum all databases\n" msgstr " -a, --all ყველა ბაზის დამტვერსასრუტება\n" -#: vacuumdb.c:353 +#: vacuumdb.c:355 #, c-format msgid " --buffer-usage-limit=SIZE size of ring buffer used for vacuum\n" msgstr " --buffer-usage-limit=ზომა მომტვერსასრუტებისთვის გამოყენებული რგოლის ბაფერის ზომა\n" -#: vacuumdb.c:354 +#: vacuumdb.c:356 #, c-format msgid " -d, --dbname=DBNAME database to vacuum\n" msgstr " -d, --dbname=ბაზისსახელი დასამტვერსასრუტებელი ბაზები\n" -#: vacuumdb.c:355 +#: vacuumdb.c:357 #, c-format msgid " --disable-page-skipping disable all page-skipping behavior\n" msgstr " --disable-page-skipping გვერდის გამოტოვების ყველა ვარიანტის გამორთვა\n" -#: vacuumdb.c:356 +#: vacuumdb.c:358 #, c-format msgid " --dry-run show the commands that would be sent to the server\n" msgstr " --dry-run ბრძანებების ჩვენება, რომლებიც გაიგზავნებოდა სერვერზე\n" -#: vacuumdb.c:357 +#: vacuumdb.c:359 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr " -e, --echo-queries სერვერზე გაგზავნილი ბრძანებების გამოტანა\n" -#: vacuumdb.c:358 +#: vacuumdb.c:360 #, c-format msgid " -f, --full do full vacuuming\n" msgstr " -f, --full სრული დამტვერსასრუტება\n" -#: vacuumdb.c:359 +#: vacuumdb.c:361 #, c-format msgid " -F, --freeze freeze row transaction information\n" msgstr " -F, --freeze მწკრივის ტრანზაქციის ინფორმაციის გაყინვა\n" -#: vacuumdb.c:360 +#: vacuumdb.c:362 #, c-format msgid " --force-index-cleanup always remove index entries that point to dead tuples\n" msgstr " --force-index-cleanup ინდექსის ჩანაწერები, რომლებიც მკვდარ მონაცემებზე მიუთითებენ, ყოველთვის წაიშლება\n" -#: vacuumdb.c:361 +#: vacuumdb.c:363 #, c-format msgid " -j, --jobs=NUM use this many concurrent connections to vacuum\n" msgstr " -j, --jobs=რიცხვი დამტვერსასრუტებისას მითითებული რაოდენობის შეერთებების გამოყენება\n" -#: vacuumdb.c:362 +#: vacuumdb.c:364 #, c-format msgid " --min-mxid-age=MXID_AGE minimum multixact ID age of tables to vacuum\n" msgstr " --min-mxid-age=MXID_AGE დასამტვერსასრუტებელი ცხრილების მულტიტრანზაქციის ID-ის მინიმალური ასაკი\n" -#: vacuumdb.c:363 +#: vacuumdb.c:365 #, c-format msgid " --min-xid-age=XID_AGE minimum transaction ID age of tables to vacuum\n" msgstr " --min-xid-age=XID_AGE დასამტვერსასრუტებელი ცხრილების ტრანზაქციების ID-ის მინიმალური ასაკი\n" -#: vacuumdb.c:364 +#: vacuumdb.c:366 #, c-format msgid " --missing-stats-only only analyze relations with missing statistics\n" msgstr " --missing-stats-only მხოლოდ, იმ ურთიერთობების ანალიზი, რომლებსაც სტატისტიკა აკლია\n" -#: vacuumdb.c:365 +#: vacuumdb.c:367 #, c-format msgid " --no-index-cleanup don't remove index entries that point to dead tuples\n" msgstr " --no-index-cleanup ინდექსის ჩანაწერები, რომლებიც მკვდარ მონაცემებზე მიუთითებენ, არ წაიშლება\n" -#: vacuumdb.c:366 +#: vacuumdb.c:368 #, c-format msgid " --no-process-main skip the main relation\n" msgstr " --no-process-main მთავარი ურთიერთობის გამოტოვება\n" -#: vacuumdb.c:367 +#: vacuumdb.c:369 #, c-format msgid " --no-process-toast skip the TOAST table associated with the table to vacuum\n" msgstr " --no-process-toast მომტვერსასრუტებისას ცხრილთან ასოცირებული TOAST cxrilis gamotoveba\n" -#: vacuumdb.c:368 +#: vacuumdb.c:370 #, c-format msgid " --no-truncate don't truncate empty pages at the end of the table\n" msgstr " --no-truncate ცხრილის ბოლოში ცარიელი გვერდები არ მოიკვეთება\n" -#: vacuumdb.c:369 +#: vacuumdb.c:371 #, c-format msgid " -n, --schema=SCHEMA vacuum tables in the specified schema(s) only\n" msgstr " -n, --schema=სქემა ცხრილების, მხოლოდ, მითითებულ სქემებში მომტვერსასრუტება\n" -#: vacuumdb.c:370 +#: vacuumdb.c:372 #, c-format msgid " -N, --exclude-schema=SCHEMA do not vacuum tables in the specified schema(s)\n" msgstr " -N, --exclude-schema=სქემა მითითებული სქემებში ცხრილები მომტვერსასრუტებული არ იქნება\n" -#: vacuumdb.c:371 +#: vacuumdb.c:373 #, c-format msgid " -P, --parallel=PARALLEL_WORKERS use this many background workers for vacuum, if available\n" msgstr " -P, --parallel=პარალელური_დამხმარე_პროცესი დასამტვერსასრუტებლად მითითებული რაოდენობის დამხმარე პროცესის გამოყენება, თუ ეს შესაძლებელია\n" -#: vacuumdb.c:372 +#: vacuumdb.c:374 #, c-format msgid " -q, --quiet don't write any messages\n" msgstr " -q, --quiet არ გამოიტანო შეტყობინებები\n" -#: vacuumdb.c:373 +#: vacuumdb.c:375 #, c-format msgid " --skip-locked skip relations that cannot be immediately locked\n" msgstr " --skip-locked გამოტოვებული იქნება ურთიერთობები, რომლის მაშინვე ჩაკეტვაც შეუძლებელია\n" -#: vacuumdb.c:374 +#: vacuumdb.c:376 #, c-format msgid " -t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only\n" msgstr " -t, --table='ცხრილი[(სვეტები)]' მხოლოდ მითითებული ცხრილების დამტვერსასრუტება\n" -#: vacuumdb.c:375 +#: vacuumdb.c:377 #, c-format msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose დამატებითი ინფორმაციის გამოტანა\n" -#: vacuumdb.c:376 +#: vacuumdb.c:378 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version ვერსიის ინფორმაციის გამოტანა და გასვლა\n" -#: vacuumdb.c:377 +#: vacuumdb.c:379 #, c-format msgid " -z, --analyze update optimizer statistics\n" msgstr " -z, --analyze ოპტიმიზატორის სტატისტიკის განახლება\n" -#: vacuumdb.c:378 +#: vacuumdb.c:380 #, c-format msgid " -Z, --analyze-only only update optimizer statistics; no vacuum\n" msgstr " -Z, --analyze-only მხოლოდ ოპტიმიზატორის სტატისტიკის განახლება; დამტვერსასრუტების გარეშე\n" -#: vacuumdb.c:379 +#: vacuumdb.c:381 #, c-format msgid "" " --analyze-in-stages only update optimizer statistics, in multiple\n" @@ -1265,12 +1266,12 @@ msgstr "" " --analyze-in-stages უკეთესი შედეგებისთვის ოპტიმიზატორის სტატისტიკის\n" " მრავალსაფეხურიანი რეჟიმი; დამტვერსასრუტების გარეშე\n" -#: vacuumdb.c:381 +#: vacuumdb.c:383 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ამ დახმარების ჩვენება და გასვლა\n" -#: vacuumdb.c:389 +#: vacuumdb.c:391 #, c-format msgid "" "\n" @@ -1301,77 +1302,17 @@ msgstr "%s: ბაზის დამუშავება \"%s\": %s\n" msgid "%s: vacuuming database \"%s\"\n" msgstr "%s: ბაზის \"%s\" დამტვერასრუტება\n" -#: vacuuming.c:1027 +#: vacuuming.c:1029 #, c-format msgid "vacuuming of table \"%s\" in database \"%s\" failed: %s" msgstr "ცხრილის (\"%s\") (ბაზაში \"%s\") დამტვერსასრუტების პრობლემა: %s" -#: vacuuming.c:1032 +#: vacuuming.c:1034 #, c-format msgid "vacuuming of database \"%s\" failed: %s" msgstr "ბაზის (\"%s\") დამტვერსასრუტების პრობლემა: %s" -#: vacuuming.c:1048 +#: vacuuming.c:1050 #, c-format msgid "out of memory" msgstr "არასაკმარისი მეხსიერება" - -#, c-format -#~ msgid "cannot cluster specific table(s) in all databases" -#~ msgstr "მითითებული ცხრილების ყველა ბაზაში დაკლასტერება შეუძლებელია" - -#, c-format -#~ msgid "cannot exclude specific schema(s) in all databases" -#~ msgstr "ყველა ბაზიდან მითითებულ სქემებს ვერ ამოვიღებ" - -#, c-format -#~ msgid "cannot reindex all databases and system catalogs at the same time" -#~ msgstr "ყველა ბაზის და სისტემური კატალოგების ერთდროული რეინდექსი შეუძლებელია" - -#, c-format -#~ msgid "cannot reindex specific index(es) and system catalogs at the same time" -#~ msgstr "მითითებული ინდექსის და სისტემური კატალოგების ერთდროული რეინდექსი შეუძლებელია" - -#, c-format -#~ msgid "cannot reindex specific index(es) in all databases" -#~ msgstr "მითითებული ინდექსის ყველა ბაზაში რეინდექსი შეუძლებელია" - -#, c-format -#~ msgid "cannot reindex specific schema(s) and system catalogs at the same time" -#~ msgstr "მითითებული სქემის და სისტემური კატალოგების ერთდროული რეინდექსი შეუძლებელია" - -#, c-format -#~ msgid "cannot reindex specific schema(s) in all databases" -#~ msgstr "მითითებული სქემის ყველა ბაზაში რეინდექსი შეუძლებელია" - -#, c-format -#~ msgid "cannot reindex specific table(s) and system catalogs at the same time" -#~ msgstr "მითითებული ცხრილის და სისტემური კატალოგების ერთდროული რეინდექსი შეუძლებელია" - -#, c-format -#~ msgid "cannot reindex specific table(s) in all databases" -#~ msgstr "მითითებული ცხრილის ყველა ბაზაში რეინდექსი შეუძლებელია" - -#, c-format -#~ msgid "cannot reindex system catalogs concurrently, skipping all" -#~ msgstr "სისტემური კატალოგების ერთდროული რეინდექსი შეუძლებელია. ყველას გამოტოვება" - -#, c-format -#~ msgid "cannot use multiple jobs to reindex indexes" -#~ msgstr "ინდექსების რეინდექსისთვის ბევრი დავალების გამოყენება შეუძლებელია" - -#, c-format -#~ msgid "cannot vacuum specific schema(s) in all databases" -#~ msgstr "ყველა ბაზაში მითითებულ სქემებს ვერ მოვამტვერსასრუტებ" - -#, c-format -#~ msgid "cannot vacuum specific table(s) in all databases" -#~ msgstr "მითითებული ცხრილების ყველა ბაზაში დამტვერსასრუტება შეუძლებელია" - -#, c-format -#~ msgid "only one of --locale and --lc-collate can be specified" -#~ msgstr "--locale და --lc-collate მხოლოდ ერთ ერთი შეიძლება იყოს მითითებული" - -#, c-format -#~ msgid "only one of --locale and --lc-ctype can be specified" -#~ msgstr "--locale და --lc-ctype მხოლოდ ერთ ერთი შეიძლება იყოს მითითებული" diff --git a/src/interfaces/ecpg/preproc/po/ka.po b/src/interfaces/ecpg/preproc/po/ka.po index 488d014a14d..671a85f57b4 100644 --- a/src/interfaces/ecpg/preproc/po/ka.po +++ b/src/interfaces/ecpg/preproc/po/ka.po @@ -713,6 +713,3 @@ msgstr "მონაცემების ამ ტიპისთვის მ msgid "multidimensional arrays for structures are not supported" msgstr "სტრუქტურების მრავალგანზომილებიანი მასივები მხარდაუჭერელია" -#, c-format -#~ msgid "subquery in FROM must have an alias" -#~ msgstr "ქვემოთხოვნას \"FROM\"-ში მეტსახელი უნდა ჰქონდეს" diff --git a/src/interfaces/libpq/po/de.po b/src/interfaces/libpq/po/de.po index 6acbb11b551..cc35e8389e3 100644 --- a/src/interfaces/libpq/po/de.po +++ b/src/interfaces/libpq/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-28 13:10+0000\n" -"PO-Revision-Date: 2026-05-28 17:26+0200\n" +"POT-Creation-Date: 2026-06-30 04:10+0000\n" +"PO-Revision-Date: 2026-07-04 01:02+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -30,7 +30,7 @@ msgstr "WARNUNG: libcurl-Multi-Handle-Cleanup fehlgeschlagen: %s\n" #: ../libpq-oauth/oauth-curl.c:393 ../libpq-oauth/oauth-curl.c:1857 #: ../libpq-oauth/oauth-curl.c:1898 ../libpq-oauth/oauth-curl.c:2216 #: ../libpq-oauth/oauth-curl.c:2377 ../libpq-oauth/oauth-curl.c:2437 -#: ../libpq-oauth/oauth-curl.c:2525 ../libpq-oauth/oauth-curl.c:3161 +#: ../libpq-oauth/oauth-curl.c:2525 ../libpq-oauth/oauth-curl.c:3178 #: fe-auth-oauth.c:153 fe-auth-oauth.c:496 fe-auth-oauth.c:568 #: fe-auth-oauth.c:776 fe-auth-oauth.c:1065 fe-auth-oauth.c:1077 #: fe-auth-oauth.c:1163 fe-auth-oauth.c:1176 fe-auth-oauth.c:1312 @@ -40,19 +40,19 @@ msgstr "WARNUNG: libcurl-Multi-Handle-Cleanup fehlgeschlagen: %s\n" #: fe-auth.c:382 fe-auth.c:416 fe-auth.c:694 fe-auth.c:827 fe-auth.c:1330 #: fe-auth.c:1493 fe-cancel.c:178 fe-connect.c:1022 fe-connect.c:1062 #: fe-connect.c:2189 fe-connect.c:2351 fe-connect.c:3744 fe-connect.c:5236 -#: fe-connect.c:5550 fe-connect.c:5828 fe-connect.c:5946 fe-connect.c:6207 -#: fe-connect.c:6250 fe-connect.c:6314 fe-connect.c:6412 fe-connect.c:6663 -#: fe-connect.c:6690 fe-connect.c:6766 fe-connect.c:6789 fe-connect.c:6813 -#: fe-connect.c:6848 fe-connect.c:6934 fe-connect.c:6942 fe-connect.c:7299 -#: fe-connect.c:7481 fe-connect.c:8094 fe-connect.c:8135 fe-exec.c:531 +#: fe-connect.c:5550 fe-connect.c:5828 fe-connect.c:5946 fe-connect.c:6219 +#: fe-connect.c:6262 fe-connect.c:6326 fe-connect.c:6424 fe-connect.c:6675 +#: fe-connect.c:6702 fe-connect.c:6778 fe-connect.c:6801 fe-connect.c:6825 +#: fe-connect.c:6860 fe-connect.c:6946 fe-connect.c:6954 fe-connect.c:7311 +#: fe-connect.c:7493 fe-connect.c:8106 fe-connect.c:8147 fe-exec.c:531 #: fe-exec.c:1332 fe-exec.c:3285 fe-exec.c:4340 fe-exec.c:4533 -#: fe-gssapi-common.c:109 fe-lobj.c:870 fe-protocol3.c:213 fe-protocol3.c:236 -#: fe-protocol3.c:259 fe-protocol3.c:276 fe-protocol3.c:297 fe-protocol3.c:371 -#: fe-protocol3.c:752 fe-protocol3.c:992 fe-protocol3.c:1606 -#: fe-protocol3.c:1660 fe-protocol3.c:1706 fe-protocol3.c:1727 -#: fe-protocol3.c:1984 fe-protocol3.c:2396 fe-secure-common.c:110 +#: fe-gssapi-common.c:109 fe-lobj.c:870 fe-protocol3.c:214 fe-protocol3.c:237 +#: fe-protocol3.c:260 fe-protocol3.c:277 fe-protocol3.c:298 fe-protocol3.c:372 +#: fe-protocol3.c:753 fe-protocol3.c:993 fe-protocol3.c:1608 +#: fe-protocol3.c:1662 fe-protocol3.c:1708 fe-protocol3.c:1729 +#: fe-protocol3.c:1986 fe-protocol3.c:2398 fe-secure-common.c:110 #: fe-secure-gssapi.c:508 fe-secure-gssapi.c:699 fe-secure-openssl.c:405 -#: fe-secure-openssl.c:1135 +#: fe-secure-openssl.c:1136 #, c-format msgid "out of memory" msgstr "Speicher aufgebraucht" @@ -240,15 +240,15 @@ msgstr "Besuchen Sie %s und geben Sie den Code ein: %s\n" msgid "device prompt failed" msgstr "Device-Prompt fehlgeschlagen" -#: ../libpq-oauth/oauth-curl.c:2724 +#: ../libpq-oauth/oauth-curl.c:2722 msgid "curl_global_init previously failed during OAuth setup" msgstr "curl_global_init zuvor beim OAuth-Setup fehlgeschlagen" -#: ../libpq-oauth/oauth-curl.c:2742 +#: ../libpq-oauth/oauth-curl.c:2740 msgid "curl_global_init failed during OAuth setup" msgstr "curl_global_init beim OAuth-Setup fehlgeschlagen" -#: ../libpq-oauth/oauth-curl.c:2763 +#: ../libpq-oauth/oauth-curl.c:2762 msgid "" "libcurl is no longer thread-safe\n" "\tCurl initialization was reported thread-safe when libpq\n" @@ -262,19 +262,19 @@ msgstr "" "\tberichtet, dass sie nicht thread-safe ist. Kompilieren Sie libpq neu\n" "\tmit der installierten Version von libcurl." -#: ../libpq-oauth/oauth-curl.c:2887 +#: ../libpq-oauth/oauth-curl.c:2902 msgid "could not fetch OpenID discovery document" msgstr "konnte OpenID-Discovery-Dokument nicht holen" -#: ../libpq-oauth/oauth-curl.c:2901 +#: ../libpq-oauth/oauth-curl.c:2916 msgid "cannot run OAuth device authorization" msgstr "kann OAuth-Device-Authorization nicht ausführen" -#: ../libpq-oauth/oauth-curl.c:2905 +#: ../libpq-oauth/oauth-curl.c:2920 msgid "could not obtain device authorization" msgstr "konnte Device-Authorization nicht erhalten" -#: ../libpq-oauth/oauth-curl.c:2916 ../libpq-oauth/oauth-curl.c:2967 +#: ../libpq-oauth/oauth-curl.c:2931 ../libpq-oauth/oauth-curl.c:2982 msgid "could not obtain access token" msgstr "konnte Access-Token nicht erhalten" @@ -741,7 +741,7 @@ msgstr "fehlerhafte Angabe: %d Hostnamen und %d hostaddr-Angaben" msgid "could not match %d port numbers to %d hosts" msgstr "fehlerhafte Angabe: %d Portnummern und %d Hosts" -#: fe-connect.c:1480 fe-exec.c:532 fe-protocol3.c:2190 +#: fe-connect.c:1480 fe-exec.c:532 fe-protocol3.c:2192 #, c-format msgid "%s" msgstr "%s" @@ -758,7 +758,7 @@ msgstr "require_auth-Methode »%s« kann nicht mit negativen Methoden vermischt #: fe-connect.c:1625 fe-connect.c:1754 fe-connect.c:1796 fe-connect.c:1839 #: fe-connect.c:1942 fe-connect.c:1988 fe-connect.c:2028 fe-connect.c:2095 -#: fe-connect.c:8378 +#: fe-connect.c:8390 #, c-format msgid "invalid %s value: \"%s\"" msgstr "ungültiger %s-Wert: »%s«" @@ -1157,126 +1157,126 @@ msgstr "Attribut hat keine Werte bei LDAP-Suche" msgid "connection info string size exceeds the maximum allowed (%d)" msgstr "Größe der Verbindungsinfo-Zeichenkette überschreitet erlaubtes Maximum (%d)" -#: fe-connect.c:5867 fe-connect.c:5886 fe-connect.c:6451 +#: fe-connect.c:5867 fe-connect.c:5886 fe-connect.c:6463 #, c-format msgid "missing \"=\" after \"%s\" in connection info string" msgstr "fehlendes »=« nach »%s« in der Zeichenkette der Verbindungsdaten" -#: fe-connect.c:5957 fe-connect.c:6634 fe-connect.c:7464 +#: fe-connect.c:5957 fe-connect.c:6646 fe-connect.c:7476 #, c-format msgid "invalid connection option \"%s\"" msgstr "ungültige Verbindungsoption »%s«" -#: fe-connect.c:5972 fe-connect.c:6499 +#: fe-connect.c:5972 fe-connect.c:6511 #, c-format msgid "unterminated quoted string in connection info string" msgstr "fehlendes schließendes Anführungszeichen (\") in der Zeichenkette der Verbindungsdaten" -#: fe-connect.c:6056 +#: fe-connect.c:6068 #, c-format msgid "definition of service \"%s\" not found" msgstr "Definition von Service »%s« nicht gefunden" -#: fe-connect.c:6082 +#: fe-connect.c:6094 #, c-format msgid "service file \"%s\" not found" msgstr "Servicedatei »%s« nicht gefunden" -#: fe-connect.c:6095 +#: fe-connect.c:6107 #, c-format msgid "line %d too long in service file \"%s\"" msgstr "Zeile %d zu lang in Servicedatei »%s«" -#: fe-connect.c:6166 fe-connect.c:6219 +#: fe-connect.c:6178 fe-connect.c:6231 #, c-format msgid "syntax error in service file \"%s\", line %d" msgstr "Syntaxfehler in Servicedatei »%s«, Zeile %d" -#: fe-connect.c:6177 +#: fe-connect.c:6189 #, c-format msgid "nested \"service\" specifications not supported in service file \"%s\", line %d" msgstr "geschachtelte »service«-Angaben werden nicht unterstützt in Servicedatei »%s«, Zeile %d" -#: fe-connect.c:6187 +#: fe-connect.c:6199 #, c-format msgid "nested \"servicefile\" specifications not supported in service file \"%s\", line %d" msgstr "geschachtelte »servicefile«-Angaben werden nicht unterstützt in Servicedatei »%s«, Zeile %d" -#: fe-connect.c:6953 +#: fe-connect.c:6965 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"" msgstr "ungültige URI an interne Parserroutine weitergeleitet: »%s«" -#: fe-connect.c:7030 +#: fe-connect.c:7042 #, c-format msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"" msgstr "Ende der Eingabezeichenkette gefunden beim Suchen nach passendem »]« in IPv6-Hostadresse in URI: »%s«" -#: fe-connect.c:7037 +#: fe-connect.c:7049 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"" msgstr "IPv6-Hostadresse darf nicht leer sein in URI: »%s«" -#: fe-connect.c:7052 +#: fe-connect.c:7064 #, c-format msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"" msgstr "unerwartetes Zeichen »%c« an Position %d in URI (»:« oder »/« erwartet): »%s«" -#: fe-connect.c:7181 +#: fe-connect.c:7193 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"" msgstr "zusätzliches Schlüssel/Wert-Trennzeichen »=« in URI-Query-Parameter: »%s«" -#: fe-connect.c:7201 +#: fe-connect.c:7213 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"" msgstr "fehlendes Schlüssel/Wert-Trennzeichen »=« in URI-Query-Parameter: »%s«" -#: fe-connect.c:7253 +#: fe-connect.c:7265 #, c-format msgid "invalid URI query parameter: \"%s\"" msgstr "ungültiger URI-Query-Parameter: »%s«" -#: fe-connect.c:7337 +#: fe-connect.c:7349 #, c-format msgid "invalid percent-encoded token: \"%s\"" msgstr "ungültiges Prozent-kodiertes Token: »%s«" -#: fe-connect.c:7347 +#: fe-connect.c:7359 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"" msgstr "verbotener Wert %%00 in Prozent-kodiertem Wert: »%s«" -#: fe-connect.c:7369 +#: fe-connect.c:7381 #, c-format msgid "unexpected spaces found in \"%s\", use percent-encoded spaces (%%20) instead" msgstr "unerwartete Leerzeichen in »%s« gefunden, verwenden Sie stattdessen Prozent-kodierte Leerzeichen (%%20)" -#: fe-connect.c:7745 +#: fe-connect.c:7757 msgid "connection pointer is NULL\n" msgstr "Verbindung ist ein NULL-Zeiger\n" -#: fe-connect.c:7753 fe-exec.c:719 fe-exec.c:981 fe-exec.c:3490 -#: fe-protocol3.c:1007 fe-protocol3.c:1040 +#: fe-connect.c:7765 fe-exec.c:719 fe-exec.c:981 fe-exec.c:3490 +#: fe-protocol3.c:1008 fe-protocol3.c:1041 msgid "out of memory\n" msgstr "Speicher aufgebraucht\n" -#: fe-connect.c:8063 +#: fe-connect.c:8075 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "WARNUNG: Passwortdatei »%s« ist keine normale Datei\n" -#: fe-connect.c:8073 +#: fe-connect.c:8085 #, c-format msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "WARNUNG: Passwortdatei »%s« erlaubt Lesezugriff für Gruppe oder Andere; Rechte sollten u=rw (0600) oder weniger sein\n" -#: fe-connect.c:8180 +#: fe-connect.c:8192 #, c-format msgid "password retrieved from file \"%s\"" msgstr "Passwort wurde aus Datei »%s« gelesen" -#: fe-connect.c:8346 +#: fe-connect.c:8358 #, c-format msgid "invalid integer value \"%s\" for connection option \"%s\"" msgstr "ungültiger Zahlenwert »%s« für Verbindungsoption »%s«" @@ -1372,7 +1372,7 @@ msgstr "PQexec ist während COPY BOTH nicht erlaubt" msgid "unrecognized message type \"%c\"" msgstr "unbekannter Message-Typ »%c«" -#: fe-exec.c:2719 fe-exec.c:2773 fe-exec.c:2841 fe-protocol3.c:2121 +#: fe-exec.c:2719 fe-exec.c:2773 fe-exec.c:2841 fe-protocol3.c:2123 #, c-format msgid "no COPY in progress" msgstr "keine COPY in Ausführung" @@ -1554,211 +1554,211 @@ msgstr "" "\twerden kann, besuchen Sie\n" "\t\t%s" -#: fe-protocol3.c:191 +#: fe-protocol3.c:192 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "Nachricht vom Typ 0x%02x kam vom Server im Ruhezustand" -#: fe-protocol3.c:404 +#: fe-protocol3.c:405 #, c-format msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" msgstr "Server sendete Daten (»D«-Nachricht) ohne vorherige Zeilenbeschreibung (»T«-Nachricht)" -#: fe-protocol3.c:446 +#: fe-protocol3.c:447 #, c-format msgid "unexpected response from server; first received character was \"%c\"" msgstr "unerwartete Antwort vom Server; erstes empfangenes Zeichen war »%c«" -#: fe-protocol3.c:470 +#: fe-protocol3.c:471 #, c-format msgid "message contents do not agree with length in message type \"%c\"" msgstr "Nachrichteninhalt stimmt nicht mit Länge in Nachrichtentyp »%c« überein" -#: fe-protocol3.c:505 +#: fe-protocol3.c:506 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d" msgstr "Synchronisation mit Server verloren: Nachrichtentyp »%c« empfangen, Länge %d" -#: fe-protocol3.c:552 fe-protocol3.c:592 +#: fe-protocol3.c:553 fe-protocol3.c:593 msgid "insufficient data in \"T\" message" msgstr "nicht genug Daten in »T«-Nachricht" -#: fe-protocol3.c:663 fe-protocol3.c:869 +#: fe-protocol3.c:664 fe-protocol3.c:870 msgid "out of memory for query result" msgstr "Speicher für Anfrageergebnis aufgebraucht" -#: fe-protocol3.c:732 +#: fe-protocol3.c:733 msgid "insufficient data in \"t\" message" msgstr "nicht genug Daten in »t«-Nachricht" -#: fe-protocol3.c:791 fe-protocol3.c:823 fe-protocol3.c:841 +#: fe-protocol3.c:792 fe-protocol3.c:824 fe-protocol3.c:842 msgid "insufficient data in \"D\" message" msgstr "nicht genug Daten in »D«-Nachricht" -#: fe-protocol3.c:797 +#: fe-protocol3.c:798 msgid "unexpected field count in \"D\" message" msgstr "unerwartete Feldzahl in »D«-Nachricht" -#: fe-protocol3.c:1053 +#: fe-protocol3.c:1054 msgid "no error message available\n" msgstr "keine Fehlermeldung verfügbar\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1101 fe-protocol3.c:1120 +#: fe-protocol3.c:1102 fe-protocol3.c:1121 #, c-format msgid " at character %s" msgstr " bei Zeichen %s" -#: fe-protocol3.c:1133 +#: fe-protocol3.c:1134 #, c-format msgid "DETAIL: %s\n" msgstr "DETAIL: %s\n" -#: fe-protocol3.c:1136 +#: fe-protocol3.c:1137 #, c-format msgid "HINT: %s\n" msgstr "TIP: %s\n" -#: fe-protocol3.c:1139 +#: fe-protocol3.c:1140 #, c-format msgid "QUERY: %s\n" msgstr "ANFRAGE: %s\n" -#: fe-protocol3.c:1146 +#: fe-protocol3.c:1147 #, c-format msgid "CONTEXT: %s\n" msgstr "KONTEXT: %s\n" -#: fe-protocol3.c:1155 +#: fe-protocol3.c:1156 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "SCHEMANAME: %s\n" -#: fe-protocol3.c:1159 +#: fe-protocol3.c:1160 #, c-format msgid "TABLE NAME: %s\n" msgstr "TABELLENNAME: %s\n" -#: fe-protocol3.c:1163 +#: fe-protocol3.c:1164 #, c-format msgid "COLUMN NAME: %s\n" msgstr "SPALTENNAME: %s\n" -#: fe-protocol3.c:1167 +#: fe-protocol3.c:1168 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "DATENTYPNAME: %s\n" -#: fe-protocol3.c:1171 +#: fe-protocol3.c:1172 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "CONSTRAINT-NAME: %s\n" -#: fe-protocol3.c:1183 +#: fe-protocol3.c:1184 msgid "LOCATION: " msgstr "ORT: " -#: fe-protocol3.c:1185 +#: fe-protocol3.c:1186 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1187 +#: fe-protocol3.c:1188 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1395 +#: fe-protocol3.c:1396 #, c-format msgid "LINE %d: " msgstr "ZEILE %d: " -#: fe-protocol3.c:1472 +#: fe-protocol3.c:1473 #, c-format msgid "received invalid protocol negotiation message: server requested \"grease\" protocol version 3.9999" msgstr "ungültige Protokollverhandlungsnachricht empfangen: Server verlangte »Grease«-Protokollversion 3.9999" -#: fe-protocol3.c:1478 +#: fe-protocol3.c:1479 #, c-format msgid "received invalid protocol negotiation message: server requested downgrade to a higher-numbered version" msgstr "ungültige Protokollverhandlungsnachricht empfangen: Server verlangte Herabstufung auf eine Version mit einer höheren Nummer" -#: fe-protocol3.c:1484 +#: fe-protocol3.c:1485 #, c-format msgid "received invalid protocol negotiation message: server requested downgrade to pre-3.0 protocol version" msgstr "ungültige Protokollverhandlungsnachricht empfangen: Server verlangte Herabstufung auf eine Protokollversion vor 3.0" -#: fe-protocol3.c:1491 +#: fe-protocol3.c:1492 #, c-format msgid "received invalid protocol negotiation message: server requested downgrade to non-existent 3.1 protocol version" msgstr "ungültige Protokollverhandlungsnachricht empfangen: Server verlangte Herabstufung auf nicht existierende Protokollversion 3.1" -#: fe-protocol3.c:1497 +#: fe-protocol3.c:1498 #, c-format msgid "received invalid protocol negotiation message: server reported negative number of unsupported parameters" msgstr "ungültige Protokollverhandlungsnachricht empfangen: Server berichtete eine negative Anzahl nicht unterstützter Parameter" -#: fe-protocol3.c:1503 +#: fe-protocol3.c:1504 #, c-format msgid "received invalid protocol negotiation message: server negotiated but asks for no changes" msgstr "ungültige Protokollverhandlungsnachricht empfangen: Server hat verhandelt aber keine Änderungen verlangt" -#: fe-protocol3.c:1509 +#: fe-protocol3.c:1510 #, c-format msgid "server only supports protocol version %d.%d, but \"%s\" was set to %d.%d" msgstr "Server unterstützt nur Protokollversion %d.%d, aber »%s« war auf %d.%d gesetzt" -#: fe-protocol3.c:1538 +#: fe-protocol3.c:1539 #, c-format msgid "received invalid protocol negotiation message: server reported unsupported parameter name without a \"%s\" prefix (\"%s\")" msgstr "ungültige Protokollverhandlungsnachricht empfangen: Server sendete nicht unterstützten Parameter ohne Präfix »%s« (»%s«)" -#: fe-protocol3.c:1550 +#: fe-protocol3.c:1551 #, c-format msgid "received invalid protocol negotiation message: server reported an unsupported parameter that was not requested (\"%s\")" msgstr "ungültige Protokollverhandlungsnachricht empfangen: Server sendete nicht unterstützten Parameter, der nicht angefordert war (»%s«)" -#: fe-protocol3.c:1563 +#: fe-protocol3.c:1564 #, c-format -msgid "server did not report the unsupported `_pq_.test_protocol_negotiation` parameter in its protocol negotiation message" -msgstr "Server hat den nicht unterstützten Parameter »_pq_.test_protocol_negotiation« in seiner Protokollverhandlungsnachricht nicht gemeldet" +msgid "server did not report the unsupported \"%s\" parameter in its protocol negotiation message" +msgstr "Server hat den nicht unterstützten Parameter »%s« in seiner Protokollverhandlungsnachricht nicht gemeldet" -#: fe-protocol3.c:1570 +#: fe-protocol3.c:1572 #, c-format msgid "received invalid protocol negotiation message: message too short" msgstr "ungültige Protokollverhandlungsnachricht empfangen: Nachricht zu kurz" -#: fe-protocol3.c:1638 +#: fe-protocol3.c:1640 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d not allowed in protocol version 3.0 (must be 4 bytes)" msgstr "ungültige BackendKeyData-Nachricht empfangen: Stornierungsschlüssel mit Länge %d nicht erlaubt in Protokoll 3.0 (muss 4 Bytes sein)" -#: fe-protocol3.c:1645 +#: fe-protocol3.c:1647 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d is too short (minimum 4 bytes)" msgstr "ungültige BackendKeyData-Nachricht empfangen: Stornierungsschlüssel mit Länge %d ist zu kurz (Minimum 4 Bytes)" -#: fe-protocol3.c:1652 +#: fe-protocol3.c:1654 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d is too long (maximum 256 bytes)" msgstr "ungültige BackendKeyData-Nachricht empfangen: Stornierungsschlüssel mit Länge %d ist zu lang (Maximum 256 Bytes)" -#: fe-protocol3.c:2016 +#: fe-protocol3.c:2018 #, c-format msgid "PQgetline: not doing text COPY OUT" msgstr "PQgetline: Text COPY OUT nicht ausgeführt" -#: fe-protocol3.c:2347 +#: fe-protocol3.c:2349 #, c-format msgid "server returned too much data" msgstr "Server hat zu viele Daten zurückgesendet" -#: fe-protocol3.c:2402 +#: fe-protocol3.c:2404 #, c-format msgid "protocol error: no function result" msgstr "Protokollfehler: kein Funktionsergebnis" -#: fe-protocol3.c:2414 +#: fe-protocol3.c:2416 #, c-format msgid "protocol error: id=0x%x" msgstr "Protokollfehler: id=0x%x" @@ -1836,17 +1836,17 @@ msgstr "konnte GSSAPI-Sicherheitskontext nicht initiieren" msgid "GSSAPI size check error" msgstr "GSSAPI-Fehler bei der Größenprüfung" -#: fe-secure-openssl.c:185 fe-secure-openssl.c:291 fe-secure-openssl.c:1382 +#: fe-secure-openssl.c:185 fe-secure-openssl.c:291 fe-secure-openssl.c:1383 #, c-format msgid "SSL SYSCALL error: %s" msgstr "SSL-SYSCALL-Fehler: %s" -#: fe-secure-openssl.c:191 fe-secure-openssl.c:297 fe-secure-openssl.c:1385 +#: fe-secure-openssl.c:191 fe-secure-openssl.c:297 fe-secure-openssl.c:1386 #, c-format msgid "SSL SYSCALL error: EOF detected" msgstr "SSL-SYSCALL-Fehler: Dateiende entdeckt" -#: fe-secure-openssl.c:201 fe-secure-openssl.c:307 fe-secure-openssl.c:1393 +#: fe-secure-openssl.c:201 fe-secure-openssl.c:307 fe-secure-openssl.c:1394 #, c-format msgid "SSL error: %s" msgstr "SSL-Fehler: %s" @@ -1856,7 +1856,7 @@ msgstr "SSL-Fehler: %s" msgid "SSL connection has been closed unexpectedly" msgstr "SSL-Verbindung wurde unerwartet geschlossen" -#: fe-secure-openssl.c:220 fe-secure-openssl.c:326 fe-secure-openssl.c:1440 +#: fe-secure-openssl.c:220 fe-secure-openssl.c:326 fe-secure-openssl.c:1441 #, c-format msgid "unrecognized SSL error code: %d" msgstr "unbekannter SSL-Fehlercode: %d" @@ -1876,62 +1876,62 @@ msgstr "konnte Digest für NID %s nicht finden" msgid "could not generate peer certificate hash" msgstr "konnte Hash des Zertifikats der Gegenstelle nicht erzeugen" -#: fe-secure-openssl.c:479 +#: fe-secure-openssl.c:480 #, c-format msgid "SSL certificate's name entry is missing" msgstr "Namenseintrag fehlt im SSL-Zertifikat" -#: fe-secure-openssl.c:509 +#: fe-secure-openssl.c:510 #, c-format msgid "SSL certificate's address entry is missing" msgstr "Adresseintrag fehlt im SSL-Zertifikat" -#: fe-secure-openssl.c:715 +#: fe-secure-openssl.c:716 #, c-format msgid "WARNING: could not open SSL key logging file \"%s\": %m\n" msgstr "WARNUNG: konnte SSL-Key-Logging-Datei »%s« nicht öffnen: %m\n" -#: fe-secure-openssl.c:723 +#: fe-secure-openssl.c:724 #, c-format msgid "WARNING: could not write to SSL key logging file \"%s\": %m\n" msgstr "WARNUNG: konnte nicht in SSL-Key-Logging-Datei »%s «schreiben: %m\n" -#: fe-secure-openssl.c:776 +#: fe-secure-openssl.c:777 #, c-format msgid "could not create SSL context: %s" msgstr "konnte SSL-Kontext nicht erzeugen: %s" -#: fe-secure-openssl.c:818 +#: fe-secure-openssl.c:819 #, c-format msgid "invalid value \"%s\" for minimum SSL protocol version" msgstr "ungültiger Wert »%s« für minimale SSL-Protokollversion" -#: fe-secure-openssl.c:828 +#: fe-secure-openssl.c:829 #, c-format msgid "could not set minimum SSL protocol version: %s" msgstr "konnte minimale SSL-Protokollversion nicht setzen: %s" -#: fe-secure-openssl.c:844 +#: fe-secure-openssl.c:845 #, c-format msgid "invalid value \"%s\" for maximum SSL protocol version" msgstr "ungültiger Wert »%s« für maximale SSL-Protokollversion" -#: fe-secure-openssl.c:854 +#: fe-secure-openssl.c:855 #, c-format msgid "could not set maximum SSL protocol version: %s" msgstr "konnte maximale SSL-Protokollversion nicht setzen: %s" -#: fe-secure-openssl.c:892 +#: fe-secure-openssl.c:893 #, c-format msgid "could not load system root certificate paths: %s" msgstr "konnte System-Root-Zertifikat-Pfade nicht laden: %s" -#: fe-secure-openssl.c:909 +#: fe-secure-openssl.c:910 #, c-format msgid "could not read root certificate file \"%s\": %s" msgstr "konnte Root-Zertifikat-Datei »%s« nicht lesen: %s" -#: fe-secure-openssl.c:961 +#: fe-secure-openssl.c:962 #, c-format msgid "" "could not get home directory to locate root certificate file\n" @@ -1940,7 +1940,7 @@ msgstr "" "konnte Home-Verzeichnis nicht ermitteln, um Root-Zertifikat-Datei zu finden\n" "Legen Sie entweder die Datei an, verwenden Sie die vertrauenswürdigen Roots des Systems mit sslrootcert=system, oder ändern Sie sslmode, um die Überprüfung der Serverzertifikate abzuschalten." -#: fe-secure-openssl.c:964 +#: fe-secure-openssl.c:965 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -1949,127 +1949,127 @@ msgstr "" "Root-Zertifikat-Datei »%s« existiert nicht\n" "Legen Sie entweder die Datei an, verwenden Sie die vertrauenswürdigen Roots des Systems mit sslrootcert=system, oder ändern Sie sslmode, um die Überprüfung der Serverzertifikate abzuschalten." -#: fe-secure-openssl.c:999 +#: fe-secure-openssl.c:1000 #, c-format msgid "could not open certificate file \"%s\": %s" msgstr "konnte Zertifikatdatei »%s« nicht öffnen: %s" -#: fe-secure-openssl.c:1017 +#: fe-secure-openssl.c:1018 #, c-format msgid "could not read certificate file \"%s\": %s" msgstr "konnte Zertifikatdatei »%s« nicht lesen: %s" -#: fe-secure-openssl.c:1041 +#: fe-secure-openssl.c:1042 #, c-format msgid "could not establish SSL connection: %s" msgstr "konnte SSL-Verbindung nicht aufbauen: %s" -#: fe-secure-openssl.c:1058 +#: fe-secure-openssl.c:1059 #, c-format msgid "WARNING: sslkeylogfile support requires OpenSSL\n" msgstr "WARNUNG: Unterstützung für sslkeylogfile benötigt OpenSSL\n" -#: fe-secure-openssl.c:1060 +#: fe-secure-openssl.c:1061 #, c-format msgid "WARNING: libpq was not built with sslkeylogfile support\n" msgstr "WARNUNG: libpq wurde ohne Unterstützung für sslkeylogfile gebaut\n" -#: fe-secure-openssl.c:1090 +#: fe-secure-openssl.c:1091 #, c-format msgid "could not set SSL Server Name Indication (SNI): %s" msgstr "konnte SSL-Server-Name-Indication (SNI) nicht setzen: %s" -#: fe-secure-openssl.c:1107 +#: fe-secure-openssl.c:1108 #, c-format msgid "could not set SSL ALPN extension: %s" msgstr "konnte SSL-ALPN-Erweiterung nicht setzen: %s" -#: fe-secure-openssl.c:1150 +#: fe-secure-openssl.c:1151 #, c-format msgid "could not load SSL engine \"%s\": %s" msgstr "konnte SSL-Engine »%s« nicht laden: %s" -#: fe-secure-openssl.c:1161 +#: fe-secure-openssl.c:1162 #, c-format msgid "could not initialize SSL engine \"%s\": %s" msgstr "konnte SSL-Engine »%s« nicht initialisieren: %s" -#: fe-secure-openssl.c:1176 +#: fe-secure-openssl.c:1177 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s" msgstr "konnte privaten SSL-Schlüssel »%s« nicht von Engine »%s« lesen: %s" -#: fe-secure-openssl.c:1189 +#: fe-secure-openssl.c:1190 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s" msgstr "konnte privaten SSL-Schlüssel »%s« nicht von Engine »%s« laden: %s" -#: fe-secure-openssl.c:1226 +#: fe-secure-openssl.c:1227 #, c-format msgid "certificate present, but not private key file \"%s\"" msgstr "Zertifikat vorhanden, aber keine private Schlüsseldatei »%s«" -#: fe-secure-openssl.c:1229 +#: fe-secure-openssl.c:1230 #, c-format msgid "could not stat private key file \"%s\": %m" msgstr "konnte »stat« für private Schlüsseldatei »%s« nicht ausführen: %m" -#: fe-secure-openssl.c:1237 +#: fe-secure-openssl.c:1238 #, c-format msgid "private key file \"%s\" is not a regular file" msgstr "private Schlüsseldatei »%s« ist keine normale Datei" -#: fe-secure-openssl.c:1270 +#: fe-secure-openssl.c:1271 #, c-format msgid "private key file \"%s\" has group or world access; file must have permissions u=rw (0600) or less if owned by the current user, or permissions u=rw,g=r (0640) or less if owned by root" msgstr "private Schlüsseldatei »%s« erlaubt Lesezugriff für Gruppe oder Andere; Dateirechte müssen u=rw (0600) oder weniger sein, wenn der Eigentümer der aktuelle Benutzer ist, oder u=rw,g=r (0640) oder weniger, wenn der Eigentümer »root« ist" -#: fe-secure-openssl.c:1294 +#: fe-secure-openssl.c:1295 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "konnte private Schlüsseldatei »%s« nicht laden: %s" -#: fe-secure-openssl.c:1310 +#: fe-secure-openssl.c:1311 #, c-format msgid "certificate does not match private key file \"%s\": %s" msgstr "Zertifikat passt nicht zur privaten Schlüsseldatei »%s«: %s" -#: fe-secure-openssl.c:1379 +#: fe-secure-openssl.c:1380 #, c-format msgid "SSL error: certificate verify failed: %s" msgstr "SSL-Fehler: Zertifikatsüberprüfung fehlgeschlagen: %s" -#: fe-secure-openssl.c:1424 +#: fe-secure-openssl.c:1425 #, c-format msgid "This may indicate that the server does not support any SSL protocol version between %s and %s." msgstr "Das zeigt möglicherweise an, dass der Server keine SSL-Protokollversion zwischen %s und %s unterstützt." -#: fe-secure-openssl.c:1456 +#: fe-secure-openssl.c:1457 #, c-format msgid "direct SSL connection was established without ALPN protocol negotiation extension" msgstr "direkte SSL-Verbindung wurde ohne ALPN-Erweiterung zur Protokollverhandlung aufgebaut" -#: fe-secure-openssl.c:1468 +#: fe-secure-openssl.c:1469 #, c-format msgid "SSL connection was established with unexpected ALPN protocol" msgstr "SSL-Verbindung wurde mit unerwartetem ALPN-Protokoll aufgebaut" -#: fe-secure-openssl.c:1485 +#: fe-secure-openssl.c:1486 #, c-format msgid "certificate could not be obtained: %s" msgstr "Zertifikat konnte nicht ermittelt werden: %s" -#: fe-secure-openssl.c:1564 +#: fe-secure-openssl.c:1565 #, c-format msgid "no SSL error reported" msgstr "kein SSL-Fehler berichtet" -#: fe-secure-openssl.c:1607 +#: fe-secure-openssl.c:1608 #, c-format msgid "SSL error code %lu" msgstr "SSL-Fehlercode %lu" -#: fe-secure-openssl.c:1909 +#: fe-secure-openssl.c:1910 #, c-format msgid "WARNING: sslpassword truncated\n" msgstr "WARNUNG: sslpassword abgeschnitten\n" diff --git a/src/interfaces/libpq/po/ja.po b/src/interfaces/libpq/po/ja.po index 91423e59e19..6b067b95804 100644 --- a/src/interfaces/libpq/po/ja.po +++ b/src/interfaces/libpq/po/ja.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: libpq (PostgreSQL 19)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-15 13:37+0900\n" -"PO-Revision-Date: 2026-05-15 17:13+0900\n" +"POT-Creation-Date: 2026-07-03 14:12+0900\n" +"PO-Revision-Date: 2026-07-06 15:13+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" @@ -33,7 +33,7 @@ msgstr "警告: libcurl の multi handle のクリーンアップに失敗しま #: ../libpq-oauth/oauth-curl.c:393 ../libpq-oauth/oauth-curl.c:1857 #: ../libpq-oauth/oauth-curl.c:1898 ../libpq-oauth/oauth-curl.c:2216 #: ../libpq-oauth/oauth-curl.c:2377 ../libpq-oauth/oauth-curl.c:2437 -#: ../libpq-oauth/oauth-curl.c:2525 ../libpq-oauth/oauth-curl.c:3161 +#: ../libpq-oauth/oauth-curl.c:2525 ../libpq-oauth/oauth-curl.c:3178 #: fe-auth-oauth.c:153 fe-auth-oauth.c:496 fe-auth-oauth.c:568 #: fe-auth-oauth.c:776 fe-auth-oauth.c:1065 fe-auth-oauth.c:1077 #: fe-auth-oauth.c:1163 fe-auth-oauth.c:1176 fe-auth-oauth.c:1312 @@ -43,19 +43,19 @@ msgstr "警告: libcurl の multi handle のクリーンアップに失敗しま #: fe-auth.c:382 fe-auth.c:416 fe-auth.c:694 fe-auth.c:827 fe-auth.c:1330 #: fe-auth.c:1493 fe-cancel.c:178 fe-connect.c:1022 fe-connect.c:1062 #: fe-connect.c:2189 fe-connect.c:2351 fe-connect.c:3744 fe-connect.c:5236 -#: fe-connect.c:5550 fe-connect.c:5828 fe-connect.c:5946 fe-connect.c:6207 -#: fe-connect.c:6250 fe-connect.c:6314 fe-connect.c:6412 fe-connect.c:6663 -#: fe-connect.c:6690 fe-connect.c:6766 fe-connect.c:6789 fe-connect.c:6813 -#: fe-connect.c:6848 fe-connect.c:6934 fe-connect.c:6942 fe-connect.c:7299 -#: fe-connect.c:7481 fe-connect.c:8094 fe-connect.c:8135 fe-exec.c:531 +#: fe-connect.c:5550 fe-connect.c:5828 fe-connect.c:5946 fe-connect.c:6219 +#: fe-connect.c:6262 fe-connect.c:6326 fe-connect.c:6424 fe-connect.c:6675 +#: fe-connect.c:6702 fe-connect.c:6778 fe-connect.c:6801 fe-connect.c:6825 +#: fe-connect.c:6860 fe-connect.c:6946 fe-connect.c:6954 fe-connect.c:7311 +#: fe-connect.c:7493 fe-connect.c:8106 fe-connect.c:8147 fe-exec.c:531 #: fe-exec.c:1332 fe-exec.c:3285 fe-exec.c:4340 fe-exec.c:4533 -#: fe-gssapi-common.c:109 fe-lobj.c:870 fe-protocol3.c:213 fe-protocol3.c:236 -#: fe-protocol3.c:259 fe-protocol3.c:276 fe-protocol3.c:297 fe-protocol3.c:371 -#: fe-protocol3.c:752 fe-protocol3.c:992 fe-protocol3.c:1606 -#: fe-protocol3.c:1660 fe-protocol3.c:1706 fe-protocol3.c:1727 -#: fe-protocol3.c:1984 fe-protocol3.c:2396 fe-secure-common.c:110 +#: fe-gssapi-common.c:109 fe-lobj.c:870 fe-protocol3.c:214 fe-protocol3.c:237 +#: fe-protocol3.c:260 fe-protocol3.c:277 fe-protocol3.c:298 fe-protocol3.c:372 +#: fe-protocol3.c:753 fe-protocol3.c:993 fe-protocol3.c:1608 +#: fe-protocol3.c:1662 fe-protocol3.c:1708 fe-protocol3.c:1729 +#: fe-protocol3.c:1986 fe-protocol3.c:2398 fe-secure-common.c:110 #: fe-secure-gssapi.c:508 fe-secure-gssapi.c:699 fe-secure-openssl.c:405 -#: fe-secure-openssl.c:1135 +#: fe-secure-openssl.c:1136 #, c-format msgid "out of memory" msgstr "メモリ不足です" @@ -243,15 +243,15 @@ msgstr "%sにアクセスしてコードを入力してください: %s\n" msgid "device prompt failed" msgstr "デバイス認証の開始に失敗しました" -#: ../libpq-oauth/oauth-curl.c:2724 +#: ../libpq-oauth/oauth-curl.c:2722 msgid "curl_global_init previously failed during OAuth setup" msgstr "curl_global_init は過去の OAuth セットアップ中に失敗しています" -#: ../libpq-oauth/oauth-curl.c:2742 +#: ../libpq-oauth/oauth-curl.c:2740 msgid "curl_global_init failed during OAuth setup" msgstr "curl_global_init が OAuth セットアップ中に失敗しました" -#: ../libpq-oauth/oauth-curl.c:2763 +#: ../libpq-oauth/oauth-curl.c:2762 msgid "" "libcurl is no longer thread-safe\n" "\tCurl initialization was reported thread-safe when libpq\n" @@ -264,19 +264,19 @@ msgstr "" "現在インストールされている libcurl はそうではないと報告しています。 libpq を\n" "このインストールされているバージョンの libcurl でコンパイルしてください。" -#: ../libpq-oauth/oauth-curl.c:2887 +#: ../libpq-oauth/oauth-curl.c:2902 msgid "could not fetch OpenID discovery document" msgstr "OpenIDディスカバリードキュメントを取得できませんでした" -#: ../libpq-oauth/oauth-curl.c:2901 +#: ../libpq-oauth/oauth-curl.c:2916 msgid "cannot run OAuth device authorization" msgstr "OAuthデバイス認証を実行できません" -#: ../libpq-oauth/oauth-curl.c:2905 +#: ../libpq-oauth/oauth-curl.c:2920 msgid "could not obtain device authorization" msgstr "デバイス認可を取得できませんでした" -#: ../libpq-oauth/oauth-curl.c:2916 ../libpq-oauth/oauth-curl.c:2967 +#: ../libpq-oauth/oauth-curl.c:2931 ../libpq-oauth/oauth-curl.c:2982 msgid "could not obtain access token" msgstr "アクセストークンを取得できませんでした" @@ -743,7 +743,7 @@ msgstr "%d個のホスト名と%d個のhostaddrの値との突き合せはでき msgid "could not match %d port numbers to %d hosts" msgstr "%d個のポート番号と%d個のホストとの突き合せはできません" -#: fe-connect.c:1480 fe-exec.c:532 fe-protocol3.c:2190 +#: fe-connect.c:1480 fe-exec.c:532 fe-protocol3.c:2192 #, c-format msgid "%s" msgstr "%s" @@ -760,7 +760,7 @@ msgstr "require_authの方式要求\"%s\"は方式否定と同時に指定する #: fe-connect.c:1625 fe-connect.c:1754 fe-connect.c:1796 fe-connect.c:1839 #: fe-connect.c:1942 fe-connect.c:1988 fe-connect.c:2028 fe-connect.c:2095 -#: fe-connect.c:8378 +#: fe-connect.c:8390 #, c-format msgid "invalid %s value: \"%s\"" msgstr "%s の値が不正: \"%s\"" @@ -1159,126 +1159,126 @@ msgstr "LDAP参照で属性に値がありません" msgid "connection info string size exceeds the maximum allowed (%d)" msgstr "接続情報文字列の長さが上限値(%d)を超えています" -#: fe-connect.c:5867 fe-connect.c:5886 fe-connect.c:6451 +#: fe-connect.c:5867 fe-connect.c:5886 fe-connect.c:6463 #, c-format msgid "missing \"=\" after \"%s\" in connection info string" msgstr "接続情報文字列において\"%s\"の後に\"=\"がありませんでした" -#: fe-connect.c:5957 fe-connect.c:6634 fe-connect.c:7464 +#: fe-connect.c:5957 fe-connect.c:6646 fe-connect.c:7476 #, c-format msgid "invalid connection option \"%s\"" msgstr "不正な接続オプション\"%s\"" -#: fe-connect.c:5972 fe-connect.c:6499 +#: fe-connect.c:5972 fe-connect.c:6511 #, c-format msgid "unterminated quoted string in connection info string" msgstr "接続情報文字列内の閉じていない引用符" -#: fe-connect.c:6056 +#: fe-connect.c:6068 #, c-format msgid "definition of service \"%s\" not found" msgstr "サービス定義\"%s\"がみつかりません" -#: fe-connect.c:6082 +#: fe-connect.c:6094 #, c-format msgid "service file \"%s\" not found" msgstr "サービスファイル\"%s\"がみつかりません" -#: fe-connect.c:6095 +#: fe-connect.c:6107 #, c-format msgid "line %d too long in service file \"%s\"" msgstr "サービスファイル\"%2$s\"の行%1$dが長すぎます" -#: fe-connect.c:6166 fe-connect.c:6219 +#: fe-connect.c:6178 fe-connect.c:6231 #, c-format msgid "syntax error in service file \"%s\", line %d" msgstr "サービスファイル\"%s\"の行%dで構文エラー" -#: fe-connect.c:6177 +#: fe-connect.c:6189 #, c-format msgid "nested \"service\" specifications not supported in service file \"%s\", line %d" msgstr "サービスファイル\"%s\"、行%dでのネストした\"service\"指定はサポートされていません" -#: fe-connect.c:6187 +#: fe-connect.c:6199 #, c-format msgid "nested \"servicefile\" specifications not supported in service file \"%s\", line %d" msgstr "サービスファイル\"%s\"、行%dでのネストした\"servicefile\"指定はサポートされていません" -#: fe-connect.c:6953 +#: fe-connect.c:6965 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"" msgstr "内部パーサ処理へ伝播した不正なURI: \"%s\"" -#: fe-connect.c:7030 +#: fe-connect.c:7042 #, c-format msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"" msgstr "URI \"%s\"内のIPv6ホストアドレスにおいて対応する\"]\"を探している間に文字列が終わりました" -#: fe-connect.c:7037 +#: fe-connect.c:7049 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"" msgstr "URI内ではIPv6ホストアドレスは空であってはなりません: \"%s\"" -#: fe-connect.c:7052 +#: fe-connect.c:7064 #, c-format msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"" msgstr "URI内の位置%2$dに想定外の文字\"%1$c\"があります(\":\"または\"/\"を期待していました): \"%3$s\"" -#: fe-connect.c:7181 +#: fe-connect.c:7193 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"" msgstr "URI問い合わせパラメータ内にキーと値を分ける\"=\"が余分にあります: \"%s\"" -#: fe-connect.c:7201 +#: fe-connect.c:7213 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"" msgstr "URI問い合わせパラメータ内にキーと値を分ける\\\"=\\\"がありません: \"%s\"" -#: fe-connect.c:7253 +#: fe-connect.c:7265 #, c-format msgid "invalid URI query parameter: \"%s\"" msgstr "不正なURI問い合わせパラメータ:\"%s\"" -#: fe-connect.c:7337 +#: fe-connect.c:7349 #, c-format msgid "invalid percent-encoded token: \"%s\"" msgstr "不正なパーセント符号化トークン: \"%s\"" -#: fe-connect.c:7347 +#: fe-connect.c:7359 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"" msgstr "パーセント符号化された値では値%%00は許されません: \"%s\"" -#: fe-connect.c:7369 +#: fe-connect.c:7381 #, c-format msgid "unexpected spaces found in \"%s\", use percent-encoded spaces (%%20) instead" msgstr "\"%s\"に予期しない空白文字があります、代わりにパーセントエンコードされた空白文字(%%20)を使用してください" -#: fe-connect.c:7745 +#: fe-connect.c:7757 msgid "connection pointer is NULL\n" msgstr "接続ポインタはNULLです\n" -#: fe-connect.c:7753 fe-exec.c:719 fe-exec.c:981 fe-exec.c:3490 -#: fe-protocol3.c:1007 fe-protocol3.c:1040 +#: fe-connect.c:7765 fe-exec.c:719 fe-exec.c:981 fe-exec.c:3490 +#: fe-protocol3.c:1008 fe-protocol3.c:1041 msgid "out of memory\n" msgstr "メモリ不足\n" -#: fe-connect.c:8063 +#: fe-connect.c:8075 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "WARNING: パスワードファイル\"%s\"がテキストファイルではありません\n" -#: fe-connect.c:8073 +#: fe-connect.c:8085 #, c-format msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "警告: パスワードファイル \"%s\" がグループメンバもしくは他のユーザーから読める状態になっています。この権限はu=rw (0600)以下にすべきです\n" -#: fe-connect.c:8180 +#: fe-connect.c:8192 #, c-format msgid "password retrieved from file \"%s\"" msgstr "パスワードはファイル\"%s\"から取り出しました" -#: fe-connect.c:8346 +#: fe-connect.c:8358 #, c-format msgid "invalid integer value \"%s\" for connection option \"%s\"" msgstr "接続オプション\"%2$s\"に対する不正な整数値\"%1$s\"" @@ -1374,7 +1374,7 @@ msgstr "COPY BOTH 実行中の PQexec は許可されていません" msgid "unrecognized message type \"%c\"" msgstr "認識できないメッセージタイプ\"%c\"" -#: fe-exec.c:2719 fe-exec.c:2773 fe-exec.c:2841 fe-protocol3.c:2121 +#: fe-exec.c:2719 fe-exec.c:2773 fe-exec.c:2841 fe-protocol3.c:2123 #, c-format msgid "no COPY in progress" msgstr "実行中のCOPYはありません" @@ -1556,211 +1556,211 @@ msgstr "" "\tを参照してください\n" "\t\t%s" -#: fe-protocol3.c:191 +#: fe-protocol3.c:192 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "待機中にサーバーからメッセージ種類0x%02xが届きました" -#: fe-protocol3.c:404 +#: fe-protocol3.c:405 #, c-format msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" msgstr "サーバーが先行の行記述(\"T\"メッセージ)なしでデータ(\"D\"メッセージ)を送信しました" -#: fe-protocol3.c:446 +#: fe-protocol3.c:447 #, c-format msgid "unexpected response from server; first received character was \"%c\"" msgstr "サーバーから想定外の応答がありました。受け付けた先頭文字は\"%c\"です" -#: fe-protocol3.c:470 +#: fe-protocol3.c:471 #, c-format msgid "message contents do not agree with length in message type \"%c\"" msgstr "メッセージの内容がメッセージタイプ\"%c\"での長さと合っていません" -#: fe-protocol3.c:505 +#: fe-protocol3.c:506 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d" msgstr "サーバーとの同期が失われました。受信したメッセージタイプは\"%c\"、長さは%d" -#: fe-protocol3.c:552 fe-protocol3.c:592 +#: fe-protocol3.c:553 fe-protocol3.c:593 msgid "insufficient data in \"T\" message" msgstr "\"T\"メッセージ内のデータが不十分です" -#: fe-protocol3.c:663 fe-protocol3.c:869 +#: fe-protocol3.c:664 fe-protocol3.c:870 msgid "out of memory for query result" msgstr "問い合わせ結果用のメモリが不足しています" -#: fe-protocol3.c:732 +#: fe-protocol3.c:733 msgid "insufficient data in \"t\" message" msgstr "\"t\"メッセージ内のデータが足りません" -#: fe-protocol3.c:791 fe-protocol3.c:823 fe-protocol3.c:841 +#: fe-protocol3.c:792 fe-protocol3.c:824 fe-protocol3.c:842 msgid "insufficient data in \"D\" message" msgstr "\"D\"\"メッセージ内のデータが不十分です" -#: fe-protocol3.c:797 +#: fe-protocol3.c:798 msgid "unexpected field count in \"D\" message" msgstr "\"D\"メッセージ内のフィールド数が想定外です。" -#: fe-protocol3.c:1053 +#: fe-protocol3.c:1054 msgid "no error message available\n" msgstr "エラーメッセージがありません\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1101 fe-protocol3.c:1120 +#: fe-protocol3.c:1102 fe-protocol3.c:1121 #, c-format msgid " at character %s" msgstr "(文字位置: %s)" -#: fe-protocol3.c:1133 +#: fe-protocol3.c:1134 #, c-format msgid "DETAIL: %s\n" msgstr "DETAIL: %s\n" -#: fe-protocol3.c:1136 +#: fe-protocol3.c:1137 #, c-format msgid "HINT: %s\n" msgstr "HINT: %s\n" -#: fe-protocol3.c:1139 +#: fe-protocol3.c:1140 #, c-format msgid "QUERY: %s\n" msgstr "QUERY: %s\n" -#: fe-protocol3.c:1146 +#: fe-protocol3.c:1147 #, c-format msgid "CONTEXT: %s\n" msgstr "CONTEXT: %s\n" -#: fe-protocol3.c:1155 +#: fe-protocol3.c:1156 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "SCHEMA NAME: %s\n" -#: fe-protocol3.c:1159 +#: fe-protocol3.c:1160 #, c-format msgid "TABLE NAME: %s\n" msgstr "TABLE NAME: %s\n" -#: fe-protocol3.c:1163 +#: fe-protocol3.c:1164 #, c-format msgid "COLUMN NAME: %s\n" msgstr "COLUMN NAME: %s\n" -#: fe-protocol3.c:1167 +#: fe-protocol3.c:1168 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "DATATYPE NAME: %s\n" -#: fe-protocol3.c:1171 +#: fe-protocol3.c:1172 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "CONSTRAINT NAME: %s\n" -#: fe-protocol3.c:1183 +#: fe-protocol3.c:1184 msgid "LOCATION: " msgstr "LOCATION: " -#: fe-protocol3.c:1185 +#: fe-protocol3.c:1186 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1187 +#: fe-protocol3.c:1188 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1395 +#: fe-protocol3.c:1396 #, c-format msgid "LINE %d: " msgstr "行 %d: " -#: fe-protocol3.c:1472 +#: fe-protocol3.c:1473 #, c-format msgid "received invalid protocol negotiation message: server requested \"grease\" protocol version 3.9999" msgstr "不正なプロトコルネゴシエーションメッセージを受信: サーバーが\"grease\"プロトコルバージョン 3.9999 を要求しました" -#: fe-protocol3.c:1478 +#: fe-protocol3.c:1479 #, c-format msgid "received invalid protocol negotiation message: server requested downgrade to a higher-numbered version" msgstr "不正なプロトコルネゴシエーションメッセージを受信: サーバーがより大きなバージョン番号へのダウングレードを要求しました" -#: fe-protocol3.c:1484 +#: fe-protocol3.c:1485 #, c-format msgid "received invalid protocol negotiation message: server requested downgrade to pre-3.0 protocol version" msgstr "不正なプロトコルネゴシエーションメッセージを受信: サーバーが3.0より前のプロトコルバージョンへのダウングレードを要求しました" -#: fe-protocol3.c:1491 +#: fe-protocol3.c:1492 #, c-format msgid "received invalid protocol negotiation message: server requested downgrade to non-existent 3.1 protocol version" msgstr "不正なプロトコルネゴシエーションメッセージを受信: サーバーが、存在しない 3.1 プロトコルバージョンへのダウングレードを要求しました" -#: fe-protocol3.c:1497 +#: fe-protocol3.c:1498 #, c-format msgid "received invalid protocol negotiation message: server reported negative number of unsupported parameters" msgstr "不正なプロトコルネゴシエーションメッセージを受信: サーバーがサポート外パラメータの数として負数を通知しました" -#: fe-protocol3.c:1503 +#: fe-protocol3.c:1504 #, c-format msgid "received invalid protocol negotiation message: server negotiated but asks for no changes" msgstr "不正なプロトコルネゴシエーションメッセージを受信: サーバーがネゴシエーションを行いましたが、変更要求がありませんでした" -#: fe-protocol3.c:1509 +#: fe-protocol3.c:1510 #, c-format msgid "server only supports protocol version %d.%d, but \"%s\" was set to %d.%d" msgstr "サーバーはプロトコルバージョン %d.%d のみサポートしていますが、\"%s\"は %d.%d に設定されています" -#: fe-protocol3.c:1538 +#: fe-protocol3.c:1539 #, c-format msgid "received invalid protocol negotiation message: server reported unsupported parameter name without a \"%s\" prefix (\"%s\")" msgstr "不正なプロトコルネゴシエーションメッセージを受信: サーバーが\"%s\"プレフィクスのないサポートされていないパラメータ名(\"%s\")を報告しました" -#: fe-protocol3.c:1550 +#: fe-protocol3.c:1551 #, c-format msgid "received invalid protocol negotiation message: server reported an unsupported parameter that was not requested (\"%s\")" msgstr "不正なプロトコルネゴシエーションメッセージを受信: サーバーが要求されていないサポート外のパラメータ(\"%s\")を通知しました" -#: fe-protocol3.c:1563 +#: fe-protocol3.c:1564 #, c-format -msgid "server did not report the unsupported `_pq_.test_protocol_negotiation` parameter in its protocol negotiation message" -msgstr "サーバーはプロトコルネゴシエーションメッセージ内で、サポートされていない \"_pq_.test_protocol_negotiation\" パラメータを報告しませんでした" +msgid "server did not report the unsupported \"%s\" parameter in its protocol negotiation message" +msgstr "サーバーはプロトコルネゴシエーションメッセージ内で、サポートされていない \"%s\" パラメータを報告しませんでした" -#: fe-protocol3.c:1570 +#: fe-protocol3.c:1572 #, c-format msgid "received invalid protocol negotiation message: message too short" msgstr "不正なプロトコルネゴシエーションメッセージを受信: メッセージが短すぎます" -#: fe-protocol3.c:1638 +#: fe-protocol3.c:1640 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d not allowed in protocol version 3.0 (must be 4 bytes)" msgstr "不正なBackendKeyDataデータを受信しました: 長さ%dのキャンセルキーはプロトコルバージョン3.0では許可されません(4バイトでなければなりません)" -#: fe-protocol3.c:1645 +#: fe-protocol3.c:1647 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d is too short (minimum 4 bytes)" msgstr "不正なBackendKeyDataデータを受信しました: 長さ%dのキャンセルキーは短すぎます (最低4バイト)" -#: fe-protocol3.c:1652 +#: fe-protocol3.c:1654 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d is too long (maximum 256 bytes)" msgstr "不正なBackendKeyDataデータを受信しました: 長さ%dのキャンセルキーは長すぎます (最高256バイト)" -#: fe-protocol3.c:2016 +#: fe-protocol3.c:2018 #, c-format msgid "PQgetline: not doing text COPY OUT" msgstr "PQgetline: テキストのCOPY OUTを行っていません" -#: fe-protocol3.c:2347 +#: fe-protocol3.c:2349 #, c-format msgid "server returned too much data" msgstr "サーバーが返却したデータが多すぎます" -#: fe-protocol3.c:2402 +#: fe-protocol3.c:2404 #, c-format msgid "protocol error: no function result" msgstr "プロトコルエラー: 関数の結果がありません" -#: fe-protocol3.c:2414 +#: fe-protocol3.c:2416 #, c-format msgid "protocol error: id=0x%x" msgstr "プロトコルエラー: id=0x%x" @@ -1837,17 +1837,17 @@ msgstr "GSSAPIセキュリティコンテキストを開始できませんでし msgid "GSSAPI size check error" msgstr "GSSAPIサイズチェックエラー" -#: fe-secure-openssl.c:185 fe-secure-openssl.c:291 fe-secure-openssl.c:1382 +#: fe-secure-openssl.c:185 fe-secure-openssl.c:291 fe-secure-openssl.c:1383 #, c-format msgid "SSL SYSCALL error: %s" msgstr "SSL SYSCALLエラー: %s" -#: fe-secure-openssl.c:191 fe-secure-openssl.c:297 fe-secure-openssl.c:1385 +#: fe-secure-openssl.c:191 fe-secure-openssl.c:297 fe-secure-openssl.c:1386 #, c-format msgid "SSL SYSCALL error: EOF detected" msgstr "SSL SYSCALLエラー: EOFを検出" -#: fe-secure-openssl.c:201 fe-secure-openssl.c:307 fe-secure-openssl.c:1393 +#: fe-secure-openssl.c:201 fe-secure-openssl.c:307 fe-secure-openssl.c:1394 #, c-format msgid "SSL error: %s" msgstr "SSLエラー: %s" @@ -1857,7 +1857,7 @@ msgstr "SSLエラー: %s" msgid "SSL connection has been closed unexpectedly" msgstr "SSL接続が意図せずにクローズされました" -#: fe-secure-openssl.c:220 fe-secure-openssl.c:326 fe-secure-openssl.c:1440 +#: fe-secure-openssl.c:220 fe-secure-openssl.c:326 fe-secure-openssl.c:1441 #, c-format msgid "unrecognized SSL error code: %d" msgstr "認識できないSSLエラーコード: %d" @@ -1877,62 +1877,62 @@ msgstr "NID %sのダイジェストが見つかりませんでした" msgid "could not generate peer certificate hash" msgstr "接続先の証明書ハッシュの生成に失敗しました" -#: fe-secure-openssl.c:479 +#: fe-secure-openssl.c:480 #, c-format msgid "SSL certificate's name entry is missing" msgstr "SSL証明書に名前のエントリがありません" -#: fe-secure-openssl.c:509 +#: fe-secure-openssl.c:510 #, c-format msgid "SSL certificate's address entry is missing" msgstr "SSL証明書のアドレスのエントリがありません" -#: fe-secure-openssl.c:715 +#: fe-secure-openssl.c:716 #, c-format msgid "WARNING: could not open SSL key logging file \"%s\": %m\n" msgstr "警告: SSLキー記録ファイル\"%s\"をオープンできませんでした: %m\n" -#: fe-secure-openssl.c:723 +#: fe-secure-openssl.c:724 #, c-format msgid "WARNING: could not write to SSL key logging file \"%s\": %m\n" msgstr "警告: SSLキー記録ファイル\"%s\"に書き込めませんでした: %m\n" -#: fe-secure-openssl.c:776 +#: fe-secure-openssl.c:777 #, c-format msgid "could not create SSL context: %s" msgstr "SSLコンテキストを作成できませんでした: %s" -#: fe-secure-openssl.c:818 +#: fe-secure-openssl.c:819 #, c-format msgid "invalid value \"%s\" for minimum SSL protocol version" msgstr "SSLプロトコル最小バージョンに対する不正な値\"%s\"" -#: fe-secure-openssl.c:828 +#: fe-secure-openssl.c:829 #, c-format msgid "could not set minimum SSL protocol version: %s" msgstr "SSLプロトコル最小バージョンを設定できませんでした: %s" -#: fe-secure-openssl.c:844 +#: fe-secure-openssl.c:845 #, c-format msgid "invalid value \"%s\" for maximum SSL protocol version" msgstr "SSLプロトコル最大バージョンに対する不正な値\"%s\"" -#: fe-secure-openssl.c:854 +#: fe-secure-openssl.c:855 #, c-format msgid "could not set maximum SSL protocol version: %s" msgstr "SSLプロトコル最大バージョンを設定できませんでした: %s" -#: fe-secure-openssl.c:892 +#: fe-secure-openssl.c:893 #, c-format msgid "could not load system root certificate paths: %s" msgstr "システムルート証明書パスをロードできませんでした: %s" -#: fe-secure-openssl.c:909 +#: fe-secure-openssl.c:910 #, c-format msgid "could not read root certificate file \"%s\": %s" msgstr "ルート証明書ファイル\"%s\"を読み取れませんでした: %s" -#: fe-secure-openssl.c:961 +#: fe-secure-openssl.c:962 #, c-format msgid "" "could not get home directory to locate root certificate file\n" @@ -1941,7 +1941,7 @@ msgstr "" "ルート証明書ファイルを特定するためのホームディレクトリが取得できませんでした\n" "ファイルを用意する、 sslrootcert=systemでシステムの信頼済みルート証明書を使用する、または sslmode を変更してサーバー証明書の検証を無効にしてください。" -#: fe-secure-openssl.c:964 +#: fe-secure-openssl.c:965 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -1950,127 +1950,127 @@ msgstr "" "ルート証明書ファイル\"%s\"が存在しません\n" "ファイルを用意する、sslrootcert=systemでシステムの信頼済みルート証明書を使用する、またはsslmodeを変更してサーバー証明書の検証を無効にしてください。" -#: fe-secure-openssl.c:999 +#: fe-secure-openssl.c:1000 #, c-format msgid "could not open certificate file \"%s\": %s" msgstr "証明書ファイル\"%s\"をオープンできませんでした: %s" -#: fe-secure-openssl.c:1017 +#: fe-secure-openssl.c:1018 #, c-format msgid "could not read certificate file \"%s\": %s" msgstr "証明書ファイル\"%s\"を読み込めませんでした: %s" -#: fe-secure-openssl.c:1041 +#: fe-secure-openssl.c:1042 #, c-format msgid "could not establish SSL connection: %s" msgstr "SSL接続を確立できませんでした: %s" -#: fe-secure-openssl.c:1058 +#: fe-secure-openssl.c:1059 #, c-format msgid "WARNING: sslkeylogfile support requires OpenSSL\n" msgstr "警告: sslkeylogfile をサポートするにはOpenSSLが必要です\n" -#: fe-secure-openssl.c:1060 +#: fe-secure-openssl.c:1061 #, c-format msgid "WARNING: libpq was not built with sslkeylogfile support\n" msgstr "警告: libpq は sslkeylogfile のサポート無しでビルドされています\n" -#: fe-secure-openssl.c:1090 +#: fe-secure-openssl.c:1091 #, c-format msgid "could not set SSL Server Name Indication (SNI): %s" msgstr "SSLサーバー名表示(SNI)を設定できませんでした: %s" -#: fe-secure-openssl.c:1107 +#: fe-secure-openssl.c:1108 #, c-format msgid "could not set SSL ALPN extension: %s" msgstr "SSL ALPN拡張を設定できませんでした: %s" -#: fe-secure-openssl.c:1150 +#: fe-secure-openssl.c:1151 #, c-format msgid "could not load SSL engine \"%s\": %s" msgstr "SSLエンジン\"%s\"を読み込みできませんでした: %s" -#: fe-secure-openssl.c:1161 +#: fe-secure-openssl.c:1162 #, c-format msgid "could not initialize SSL engine \"%s\": %s" msgstr "SSLエンジン\"%s\"を初期化できませんでした: %s" -#: fe-secure-openssl.c:1176 +#: fe-secure-openssl.c:1177 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s" msgstr "SSL秘密鍵\"%s\"をエンジン\"%s\"から読み取れませんでした: %s" -#: fe-secure-openssl.c:1189 +#: fe-secure-openssl.c:1190 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s" msgstr "SSL秘密鍵\"%s\"をエンジン\"%s\"から読み取れませんでした: %s" -#: fe-secure-openssl.c:1226 +#: fe-secure-openssl.c:1227 #, c-format msgid "certificate present, but not private key file \"%s\"" msgstr "証明書はありますが、秘密鍵ファイル\"%s\"はありません" -#: fe-secure-openssl.c:1229 +#: fe-secure-openssl.c:1230 #, c-format msgid "could not stat private key file \"%s\": %m" msgstr "秘密鍵ファイル\"%s\"をstatできませんでした: %m" -#: fe-secure-openssl.c:1237 +#: fe-secure-openssl.c:1238 #, c-format msgid "private key file \"%s\" is not a regular file" msgstr "秘密鍵ファイル\"%s\"は通常のファイルではありません" -#: fe-secure-openssl.c:1270 +#: fe-secure-openssl.c:1271 #, c-format msgid "private key file \"%s\" has group or world access; file must have permissions u=rw (0600) or less if owned by the current user, or permissions u=rw,g=r (0640) or less if owned by root" msgstr "秘密鍵ファイル\"%s\"はグループに対して、もしくは無制限にアクセスを許可しています; ファイルのパーミッションは u=rw (0600) かそれよりも狭い必要があります、rootが所有している場合は u=rw,g=r (0640) かそれよりも狭い必要があります" -#: fe-secure-openssl.c:1294 +#: fe-secure-openssl.c:1295 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "秘密鍵ファイル\"%s\"をロードできませんでした: %s" -#: fe-secure-openssl.c:1310 +#: fe-secure-openssl.c:1311 #, c-format msgid "certificate does not match private key file \"%s\": %s" msgstr "証明書と秘密鍵ファイル\"%s\"が一致しません: %s" -#: fe-secure-openssl.c:1379 +#: fe-secure-openssl.c:1380 #, c-format msgid "SSL error: certificate verify failed: %s" msgstr "SSLエラー: 証明書の検証に失敗しました: %s" -#: fe-secure-openssl.c:1424 +#: fe-secure-openssl.c:1425 #, c-format msgid "This may indicate that the server does not support any SSL protocol version between %s and %s." msgstr "このことは、クライアントがSSLプロトコルのバージョン%sから%sの間のいずれもサポートしていないことを示唆しているかもしれません。" -#: fe-secure-openssl.c:1456 +#: fe-secure-openssl.c:1457 #, c-format msgid "direct SSL connection was established without ALPN protocol negotiation extension" msgstr "直接SSL接続がALPNプロトコルネゴシエーション拡張なしで確立されました" -#: fe-secure-openssl.c:1468 +#: fe-secure-openssl.c:1469 #, c-format msgid "SSL connection was established with unexpected ALPN protocol" msgstr "SSL接続が想定外のALPNプロトコルで確立されました" -#: fe-secure-openssl.c:1485 +#: fe-secure-openssl.c:1486 #, c-format msgid "certificate could not be obtained: %s" msgstr "証明書を取得できませんでした: %s" -#: fe-secure-openssl.c:1564 +#: fe-secure-openssl.c:1565 #, c-format msgid "no SSL error reported" msgstr "SSLエラーはありませんでした" -#: fe-secure-openssl.c:1607 +#: fe-secure-openssl.c:1608 #, c-format msgid "SSL error code %lu" msgstr "SSLエラーコード: %lu" -#: fe-secure-openssl.c:1909 +#: fe-secure-openssl.c:1910 #, c-format msgid "WARNING: sslpassword truncated\n" msgstr "警告: sslpasswordが切り詰められました\n" diff --git a/src/interfaces/libpq/po/ka.po b/src/interfaces/libpq/po/ka.po index 9ae360a7ee9..dd3ea1120e8 100644 --- a/src/interfaces/libpq/po/ka.po +++ b/src/interfaces/libpq/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: libpq (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-13 06:10+0000\n" -"PO-Revision-Date: 2026-05-13 09:03+0200\n" +"POT-Creation-Date: 2026-06-11 12:10+0000\n" +"PO-Revision-Date: 2026-06-11 15:57+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -41,19 +41,19 @@ msgstr "გაფრთხილება: libcurl-ის დამმუშა #: fe-auth.c:382 fe-auth.c:416 fe-auth.c:694 fe-auth.c:827 fe-auth.c:1330 #: fe-auth.c:1493 fe-cancel.c:178 fe-connect.c:1022 fe-connect.c:1062 #: fe-connect.c:2189 fe-connect.c:2351 fe-connect.c:3744 fe-connect.c:5236 -#: fe-connect.c:5550 fe-connect.c:5828 fe-connect.c:5946 fe-connect.c:6207 -#: fe-connect.c:6250 fe-connect.c:6314 fe-connect.c:6412 fe-connect.c:6663 -#: fe-connect.c:6690 fe-connect.c:6766 fe-connect.c:6789 fe-connect.c:6813 -#: fe-connect.c:6848 fe-connect.c:6934 fe-connect.c:6942 fe-connect.c:7299 -#: fe-connect.c:7481 fe-connect.c:8094 fe-connect.c:8135 fe-exec.c:531 -#: fe-exec.c:1332 fe-exec.c:3285 fe-exec.c:4335 fe-exec.c:4528 +#: fe-connect.c:5550 fe-connect.c:5828 fe-connect.c:5946 fe-connect.c:6219 +#: fe-connect.c:6262 fe-connect.c:6326 fe-connect.c:6424 fe-connect.c:6675 +#: fe-connect.c:6702 fe-connect.c:6778 fe-connect.c:6801 fe-connect.c:6825 +#: fe-connect.c:6860 fe-connect.c:6946 fe-connect.c:6954 fe-connect.c:7311 +#: fe-connect.c:7493 fe-connect.c:8106 fe-connect.c:8147 fe-exec.c:531 +#: fe-exec.c:1332 fe-exec.c:3285 fe-exec.c:4340 fe-exec.c:4533 #: fe-gssapi-common.c:109 fe-lobj.c:870 fe-protocol3.c:213 fe-protocol3.c:236 #: fe-protocol3.c:259 fe-protocol3.c:276 fe-protocol3.c:297 fe-protocol3.c:371 -#: fe-protocol3.c:752 fe-protocol3.c:992 fe-protocol3.c:1606 -#: fe-protocol3.c:1660 fe-protocol3.c:1706 fe-protocol3.c:1727 -#: fe-protocol3.c:1984 fe-protocol3.c:2396 fe-secure-common.c:110 +#: fe-protocol3.c:752 fe-protocol3.c:992 fe-protocol3.c:1607 +#: fe-protocol3.c:1661 fe-protocol3.c:1707 fe-protocol3.c:1728 +#: fe-protocol3.c:1985 fe-protocol3.c:2397 fe-secure-common.c:110 #: fe-secure-gssapi.c:508 fe-secure-gssapi.c:699 fe-secure-openssl.c:405 -#: fe-secure-openssl.c:1135 +#: fe-secure-openssl.c:1136 #, c-format msgid "out of memory" msgstr "არასაკმარისი მეხსიერება" @@ -742,7 +742,7 @@ msgstr "%d ჰოსტის სახელები %d ჰოსტის მ msgid "could not match %d port numbers to %d hosts" msgstr "%d პორტის ნომრები %d ჰოსტს არ ემთხვევა" -#: fe-connect.c:1480 fe-exec.c:532 fe-protocol3.c:2190 +#: fe-connect.c:1480 fe-exec.c:532 fe-protocol3.c:2191 #, c-format msgid "%s" msgstr "%s" @@ -759,7 +759,7 @@ msgstr "require_auth-ის მეთოდს \"%s\" უარყოფით #: fe-connect.c:1625 fe-connect.c:1754 fe-connect.c:1796 fe-connect.c:1839 #: fe-connect.c:1942 fe-connect.c:1988 fe-connect.c:2028 fe-connect.c:2095 -#: fe-connect.c:8378 +#: fe-connect.c:8390 #, c-format msgid "invalid %s value: \"%s\"" msgstr "%s-ის არასწორი მნიშვნელობა: \"%s\"" @@ -1158,126 +1158,126 @@ msgstr "'LDAP' ძებნის ატრიბუტს მნიშვნე msgid "connection info string size exceeds the maximum allowed (%d)" msgstr "დაკავშირების ინფორმაციის სტრიქონის ზომა მაქსიმალურ დასაშვებს (%d) აღემატება" -#: fe-connect.c:5867 fe-connect.c:5886 fe-connect.c:6451 +#: fe-connect.c:5867 fe-connect.c:5886 fe-connect.c:6463 #, c-format msgid "missing \"=\" after \"%s\" in connection info string" msgstr "შეერთების სტრიქონში \"%s\"-ის შემდეგ \"=\" აკლია" -#: fe-connect.c:5957 fe-connect.c:6634 fe-connect.c:7464 +#: fe-connect.c:5957 fe-connect.c:6646 fe-connect.c:7476 #, c-format msgid "invalid connection option \"%s\"" msgstr "შეერთების არასწორი პარამეტრი: \"%s\"" -#: fe-connect.c:5972 fe-connect.c:6499 +#: fe-connect.c:5972 fe-connect.c:6511 #, c-format msgid "unterminated quoted string in connection info string" msgstr "შეერთების ინფორმაციის სტრიქონში ბრჭყალებში ჩასმული სტრიქონი დაუსრულებელია" -#: fe-connect.c:6056 +#: fe-connect.c:6068 #, c-format msgid "definition of service \"%s\" not found" msgstr "სერვისის აღწერა არ არსებობს: \"%s\"" -#: fe-connect.c:6082 +#: fe-connect.c:6094 #, c-format msgid "service file \"%s\" not found" msgstr "სერვისის ფაილი არ არსებობს: \"%s\"" -#: fe-connect.c:6095 +#: fe-connect.c:6107 #, c-format msgid "line %d too long in service file \"%s\"" msgstr "ძალიან გრძელი ხაზი (%d) სერვისის ფაილში \"%s\"" -#: fe-connect.c:6166 fe-connect.c:6219 +#: fe-connect.c:6178 fe-connect.c:6231 #, c-format msgid "syntax error in service file \"%s\", line %d" msgstr "სინტაქსის შეცდომა სერვისის ფაილში \"%s\" ხაზზე %d" -#: fe-connect.c:6177 +#: fe-connect.c:6189 #, c-format msgid "nested \"service\" specifications not supported in service file \"%s\", line %d" msgstr "ჩადგმული \"სერვისის\" სპეციფიკაციები მხარდაჭერილი არაა სერვისის ფაილში \"%s\" ხაზზე %d" -#: fe-connect.c:6187 +#: fe-connect.c:6199 #, c-format msgid "nested \"servicefile\" specifications not supported in service file \"%s\", line %d" msgstr "ჩადგმული \"სერვისისფაილის\" სპეციფიკაციები მხარდაუჭერელია სერვისის ფაილში \"%s\" ხაზზე %d" -#: fe-connect.c:6953 +#: fe-connect.c:6965 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"" msgstr "დამუშავებს შიდა ფუნქციაში გადაცემული URI არასწორია: %s" -#: fe-connect.c:7030 +#: fe-connect.c:7042 #, c-format msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"" msgstr "სტრიქონის დასასრული \"]\"-ს IPv6 ჰოსტის მისამართში URI-ში ძებნისას: \"%s\"" -#: fe-connect.c:7037 +#: fe-connect.c:7049 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"" msgstr "ჰოსტის IPv6 მისამართი URI-ში ცარიელი ვერ იქნება: \"%s\"" -#: fe-connect.c:7052 +#: fe-connect.c:7064 #, c-format msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"" msgstr "უცნობი სიმბოლო (\"%c\") URI-ში პოზიციაზე %d (მოველოდი \":\"-ს ან \"/\"-ს): \"%s\"" -#: fe-connect.c:7181 +#: fe-connect.c:7193 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"" msgstr "მოთხოვნის URI არამეტრში მითითებულია გასაღები/მნიშვნელობის ზედმეტი \"=\": \"%s\"" -#: fe-connect.c:7201 +#: fe-connect.c:7213 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"" msgstr "მოთხოვნის URI პარამეტრში მითითებულია გასაღები/მნიშვნელობის წყვილს \"=\" აკლია: \"%s\"" -#: fe-connect.c:7253 +#: fe-connect.c:7265 #, c-format msgid "invalid URI query parameter: \"%s\"" msgstr "მოთხოვნის არასწორი პარამეტრი: \"%s\"" -#: fe-connect.c:7337 +#: fe-connect.c:7349 #, c-format msgid "invalid percent-encoded token: \"%s\"" msgstr "არასწორი პროცენტულად-კოდირებული კოდი: \"%s\"" -#: fe-connect.c:7347 +#: fe-connect.c:7359 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"" msgstr "პროცენტში კოდირებული მნიშვნელობის აკრძალული მნიშვნელობა %%00: \"%s\"" -#: fe-connect.c:7369 +#: fe-connect.c:7381 #, c-format msgid "unexpected spaces found in \"%s\", use percent-encoded spaces (%%20) instead" msgstr "\"%s\"-ში აღმოჩენილია მოულოდნელი ჰარეები. მათ მაგიერ გამოიყენეთ პროცენტით კოდირებული (%%20)" -#: fe-connect.c:7745 +#: fe-connect.c:7757 msgid "connection pointer is NULL\n" msgstr "შეერთების მაჩვენებელი ნულოვანია\n" -#: fe-connect.c:7753 fe-exec.c:719 fe-exec.c:981 fe-exec.c:3490 +#: fe-connect.c:7765 fe-exec.c:719 fe-exec.c:981 fe-exec.c:3490 #: fe-protocol3.c:1007 fe-protocol3.c:1040 msgid "out of memory\n" msgstr "არასაკმარისი მეხსიერება\n" -#: fe-connect.c:8063 +#: fe-connect.c:8075 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "გაფრთხილება. პაროლის ფაილი \"%s\" უბრალოდ ფაილს არ წარმოადგენს\n" -#: fe-connect.c:8073 +#: fe-connect.c:8085 #, c-format msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "გაფრთხილება: პაროლების ფაილს \"%s\" ჯგუფზე ან დანარჩენ ყველაზე წვდომა გააჩნია. წვდომა 0600 ან ნაკლები უნდა იყოს\n" -#: fe-connect.c:8180 +#: fe-connect.c:8192 #, c-format msgid "password retrieved from file \"%s\"" msgstr "პაროლი მიღებულია ფაილიდან \"%s\"" -#: fe-connect.c:8346 +#: fe-connect.c:8358 #, c-format msgid "invalid integer value \"%s\" for connection option \"%s\"" msgstr "არასწორი მნიშვნელობა: \"%s\" (უნდა იყოს მთელი რიცხვი) შეერთების პარამეტრისთვის \"%s\"" @@ -1373,7 +1373,7 @@ msgstr "COPY BOTH-ის დროს PQexec დაუშვებელია" msgid "unrecognized message type \"%c\"" msgstr "შეტყობინების უცნობი ტიპი: \"%c\"" -#: fe-exec.c:2719 fe-exec.c:2773 fe-exec.c:2841 fe-protocol3.c:2121 +#: fe-exec.c:2719 fe-exec.c:2773 fe-exec.c:2841 fe-protocol3.c:2122 #, c-format msgid "no COPY in progress" msgstr "ბრძანება COPY გაშვებული არაა" @@ -1431,22 +1431,22 @@ msgstr "პარამეტრების რაოდენობა %d ზ msgid "could not interpret result from server: %s" msgstr "სერვერის პასუხის გაურკვეველია: %s" -#: fe-exec.c:4172 fe-exec.c:4286 +#: fe-exec.c:4177 fe-exec.c:4291 #, c-format msgid "incomplete multibyte character" msgstr "დაუსრულებელი მრავალბაიტიანი სიმბოლო" -#: fe-exec.c:4174 fe-exec.c:4305 +#: fe-exec.c:4179 fe-exec.c:4310 #, c-format msgid "invalid multibyte character" msgstr "არასწორი მრავალბაიტიანი სიმბოლო" -#: fe-exec.c:4407 +#: fe-exec.c:4412 #, c-format msgid "escaped string size exceeds the maximum allowed (%zu)" msgstr "სპეცსიმბოლოების შემცველი სტრიქონის ზომა მაქსიმალურად დასაშვებს (%zu) აღემატება" -#: fe-exec.c:4584 +#: fe-exec.c:4589 #, c-format msgid "escaped bytea size exceeds the maximum allowed (%zu)" msgstr "სპეცსიმბოლოების bytea სტრიქონის ზომა მაქსიმალურად დასაშვებს (%zu) აღემატება" @@ -1721,45 +1721,45 @@ msgstr "მიღებულია არასწორი პროტოკ #: fe-protocol3.c:1563 #, c-format -msgid "server did not report the unsupported `_pq_.test_protocol_negotiation` parameter in its protocol negotiation message" -msgstr "სერვერმა არ შეგვატყობინა მხარდაუჭერელი პარამეტრის '_pq_.test_protocol_negotiation' არსებობის შესახებ პროტოკოლის მოლაპარაკების შეტყობინებაში" +msgid "server did not report the unsupported \"%s\" parameter in its protocol negotiation message" +msgstr "სერვერმა არ შეგვატყობინა მხარდაუჭერელი პარამეტრის '%s' არსებობის შესახებ პროტოკოლის მოლაპარაკების შეტყობინებაში" -#: fe-protocol3.c:1570 +#: fe-protocol3.c:1571 #, c-format msgid "received invalid protocol negotiation message: message too short" msgstr "მიღებულია არასწორი პროტოკოლის მიმოცვლის შეტყობინება; შეტყობინება მეტისმეტად მოკლეა" -#: fe-protocol3.c:1638 +#: fe-protocol3.c:1639 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d not allowed in protocol version 3.0 (must be 4 bytes)" msgstr "მიღებულია არასწორი შეტყობინება BackendKeyData: გაუქმების გასაღები სიგრძით %d დაუშვებელია პროტოკოლის ვერსიაში 3.0 (უნდა იყო 4 ბაიტი)" -#: fe-protocol3.c:1645 +#: fe-protocol3.c:1646 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d is too short (minimum 4 bytes)" msgstr "მიღებულია არასწორი შეტყობინება BackendKeyData: გაუქმების გასაღები სიგრძით %d ძალიან მოკლეა (უნდა იყო 4 ბაიტი)" -#: fe-protocol3.c:1652 +#: fe-protocol3.c:1653 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d is too long (maximum 256 bytes)" msgstr "მიღებულია არასწორი შეტყობინება BackendKeyData: გაუქმების გასაღები სიგრძით %d ძალიან გრძელია (მაქს 256 ბაიტი)" -#: fe-protocol3.c:2016 +#: fe-protocol3.c:2017 #, c-format msgid "PQgetline: not doing text COPY OUT" msgstr "PQgetline: ტექსტის COPY OUT-ს არ გავაკეთებ" -#: fe-protocol3.c:2347 +#: fe-protocol3.c:2348 #, c-format msgid "server returned too much data" msgstr "სერვერმა მეტისმეტად ბევრი მონაცემები გამოაგზავნა" -#: fe-protocol3.c:2402 +#: fe-protocol3.c:2403 #, c-format msgid "protocol error: no function result" msgstr "პროტოკოლის შეცდომა: ფუნქციის შედეგის გარეშე" -#: fe-protocol3.c:2414 +#: fe-protocol3.c:2415 #, c-format msgid "protocol error: id=0x%x" msgstr "პროტოკოლის შეცდომა: id=0x%x" @@ -1837,17 +1837,17 @@ msgstr "'GSSAPI' უსაფრთხოების კონტექსტ msgid "GSSAPI size check error" msgstr "GSSAPI-ის ზომის შემოწმების შეცდომა" -#: fe-secure-openssl.c:185 fe-secure-openssl.c:291 fe-secure-openssl.c:1382 +#: fe-secure-openssl.c:185 fe-secure-openssl.c:291 fe-secure-openssl.c:1383 #, c-format msgid "SSL SYSCALL error: %s" msgstr "SSL SYSCALL-ის შეცდომა: %s" -#: fe-secure-openssl.c:191 fe-secure-openssl.c:297 fe-secure-openssl.c:1385 +#: fe-secure-openssl.c:191 fe-secure-openssl.c:297 fe-secure-openssl.c:1386 #, c-format msgid "SSL SYSCALL error: EOF detected" msgstr "SSL SYSCALL -ის შეცდომა: ნაპოვნია EOF" -#: fe-secure-openssl.c:201 fe-secure-openssl.c:307 fe-secure-openssl.c:1393 +#: fe-secure-openssl.c:201 fe-secure-openssl.c:307 fe-secure-openssl.c:1394 #, c-format msgid "SSL error: %s" msgstr "SSL-ის შეცდომა: %s" @@ -1857,7 +1857,7 @@ msgstr "SSL-ის შეცდომა: %s" msgid "SSL connection has been closed unexpectedly" msgstr "SSL შეერთება მოულოდნელად დაიხურა" -#: fe-secure-openssl.c:220 fe-secure-openssl.c:326 fe-secure-openssl.c:1440 +#: fe-secure-openssl.c:220 fe-secure-openssl.c:326 fe-secure-openssl.c:1441 #, c-format msgid "unrecognized SSL error code: %d" msgstr "უცნობი SSL-ის შეცდომის კოდი: %d" @@ -1877,62 +1877,62 @@ msgstr "'NID'-ისთვის (%s) დაიჯესტის პოვნ msgid "could not generate peer certificate hash" msgstr "პარტნიორის სერტიფიკატის ჰეშის გენერირების შეცდომა" -#: fe-secure-openssl.c:479 +#: fe-secure-openssl.c:480 #, c-format msgid "SSL certificate's name entry is missing" msgstr "SSL სერტიფიკატის სახელის ჩანაწერი არ არსებობს" -#: fe-secure-openssl.c:509 +#: fe-secure-openssl.c:510 #, c-format msgid "SSL certificate's address entry is missing" msgstr "SSL სერტიფიკატის მისამართის ჩანაწერი არ არსებობს" -#: fe-secure-openssl.c:715 +#: fe-secure-openssl.c:716 #, c-format msgid "WARNING: could not open SSL key logging file \"%s\": %m\n" msgstr "გაფრთხილება: ვერ გავხსენი SSL გასაღების ჟურნალის ფაილი \"%s\": %m\n" -#: fe-secure-openssl.c:723 +#: fe-secure-openssl.c:724 #, c-format msgid "WARNING: could not write to SSL key logging file \"%s\": %m\n" msgstr "გაფრთხილება: SSL გასაღების ჟურნალის ფაილში \"%s\" ჩაწერის შეცდომა: %m\n" -#: fe-secure-openssl.c:776 +#: fe-secure-openssl.c:777 #, c-format msgid "could not create SSL context: %s" msgstr "შეცდომა SSL კონტექსტის შექმნისას: %s" -#: fe-secure-openssl.c:818 +#: fe-secure-openssl.c:819 #, c-format msgid "invalid value \"%s\" for minimum SSL protocol version" msgstr "'SSL' პროტოკოლის ვერსიის არასწორი მინიმალური მნიშვნელობა: %s" -#: fe-secure-openssl.c:828 +#: fe-secure-openssl.c:829 #, c-format msgid "could not set minimum SSL protocol version: %s" msgstr "'SSL' პროტოკოლის ვერსიის მინიმალური მნიშვნელობის დაყენების შეცდომა: %s" -#: fe-secure-openssl.c:844 +#: fe-secure-openssl.c:845 #, c-format msgid "invalid value \"%s\" for maximum SSL protocol version" msgstr "'SSL' პროტოკოლის ვერსიის არასწორი მაქსიმალური მნიშვნელობა: %s" -#: fe-secure-openssl.c:854 +#: fe-secure-openssl.c:855 #, c-format msgid "could not set maximum SSL protocol version: %s" msgstr "'SSL' პროტოკოლის ვერსიის მაქსიმალური მნიშვნელობის დაყენების შეცდომა: %s" -#: fe-secure-openssl.c:892 +#: fe-secure-openssl.c:893 #, c-format msgid "could not load system root certificate paths: %s" msgstr "სისტემური root სერტიფიკატების ბილიკების ჩატვირთვის შეცდომა: %s" -#: fe-secure-openssl.c:909 +#: fe-secure-openssl.c:910 #, c-format msgid "could not read root certificate file \"%s\": %s" msgstr "root სერტიფიკატის ფაილის (\"%s\") წაკითხვის შეცდომა: %s" -#: fe-secure-openssl.c:961 +#: fe-secure-openssl.c:962 #, c-format msgid "" "could not get home directory to locate root certificate file\n" @@ -1941,7 +1941,7 @@ msgstr "" "root სერტიფიკატის ფაილის მოსაძებნად საწყისი საქაღალდის მიღება შეუძლებელია\n" "ამ წარმოადგინეთ ფაილი, ან გამოიყენეთ სისტემის სანდო root-ები პარამეტრით sslrootcert=system, ან sslmode სერვერის სერტიფიკატის შემოწმება გამორთეთ." -#: fe-secure-openssl.c:964 +#: fe-secure-openssl.c:965 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -1950,127 +1950,127 @@ msgstr "" "root სერტიფიკატის ფაილი \"%s\" არ არსებობს\n" "წარმოადგინეთ ფაილი ან გამორთეთ sslmode სერვერის სერტიფიკატის შემოწმება." -#: fe-secure-openssl.c:999 +#: fe-secure-openssl.c:1000 #, c-format msgid "could not open certificate file \"%s\": %s" msgstr "სერტიფიკატის ფაილის გახსნის შეცდომა \"%s\": %s" -#: fe-secure-openssl.c:1017 +#: fe-secure-openssl.c:1018 #, c-format msgid "could not read certificate file \"%s\": %s" msgstr "სერტიფიკატის ფაილის წაკითხვის შეცდომა \"%s\": %s" -#: fe-secure-openssl.c:1041 +#: fe-secure-openssl.c:1042 #, c-format msgid "could not establish SSL connection: %s" msgstr "'SSL' შეერთების დამყარების შეცდომა: %s" -#: fe-secure-openssl.c:1058 +#: fe-secure-openssl.c:1059 #, c-format msgid "WARNING: sslkeylogfile support requires OpenSSL\n" msgstr "გაფრთხილება: sslkeylogfile-ის მხარდაჭერას OpenSSL სჭირდება\n" -#: fe-secure-openssl.c:1060 +#: fe-secure-openssl.c:1061 #, c-format msgid "WARNING: libpq was not built with sslkeylogfile support\n" msgstr "გაფრთხილება: libpq არ იყო აგებული sslkeylogfile-ის მხარდაჭერით\n" -#: fe-secure-openssl.c:1090 +#: fe-secure-openssl.c:1091 #, c-format msgid "could not set SSL Server Name Indication (SNI): %s" msgstr "'SSL' სერვერის სახელის ინდიკაციის (SNI) დაყენების შეცდომა: %s" -#: fe-secure-openssl.c:1107 +#: fe-secure-openssl.c:1108 #, c-format msgid "could not set SSL ALPN extension: %s" msgstr "\"SSL ALPN\" გაფართოების დაყენების შეცდომა: %s" -#: fe-secure-openssl.c:1150 +#: fe-secure-openssl.c:1151 #, c-format msgid "could not load SSL engine \"%s\": %s" msgstr "'SSL' ძრავის (\"%s\") ჩატვირთვის შეცდომა: %s" -#: fe-secure-openssl.c:1161 +#: fe-secure-openssl.c:1162 #, c-format msgid "could not initialize SSL engine \"%s\": %s" msgstr "'SSL' ძრავის (\"%s\") ინიციალიზაციის შეცდომა: %s" -#: fe-secure-openssl.c:1176 +#: fe-secure-openssl.c:1177 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s" msgstr "'SSL'-ის პირადი გასაღების (\"%s\") ძრავიდან (\"%s\") წაკითხვის შეცდომა: %s" -#: fe-secure-openssl.c:1189 +#: fe-secure-openssl.c:1190 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s" msgstr "'SSL'-ის პირადი გასაღების (\"%s\") ძრავიდან (\"%s\") წაკითხვის შეცდომა: %s" -#: fe-secure-openssl.c:1226 +#: fe-secure-openssl.c:1227 #, c-format msgid "certificate present, but not private key file \"%s\"" msgstr "სერტიფიკატისგან განსხვავებით, პირადი გასაღების ფაილი \"%s\" არ არსებობს" -#: fe-secure-openssl.c:1229 +#: fe-secure-openssl.c:1230 #, c-format msgid "could not stat private key file \"%s\": %m" msgstr "პირადი გასაღების ფაილი \"%s\" არ არსებობს: %m" -#: fe-secure-openssl.c:1237 +#: fe-secure-openssl.c:1238 #, c-format msgid "private key file \"%s\" is not a regular file" msgstr "პირადი გასაღების ფაილი \"%s\" ჩვეულებრივი ფაილი არაა" -#: fe-secure-openssl.c:1270 +#: fe-secure-openssl.c:1271 #, c-format msgid "private key file \"%s\" has group or world access; file must have permissions u=rw (0600) or less if owned by the current user, or permissions u=rw,g=r (0640) or less if owned by root" msgstr "პირადი გასაღების ფაილს \"%s\" აქვს ჯგუფური ან ყველა სხვაზე წვდომა; ფაილს უნდა ჰქონდეს ნებართვები u=rw (0600) ან ნაკლები, თუ ეკუთვნის ამჟამინდელ მომხმარებელს, ან ნებართვები u=rw,g=r (0640) ან ნაკლები, თუ ეკუთვნის root-ს" -#: fe-secure-openssl.c:1294 +#: fe-secure-openssl.c:1295 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "პირადი გასაღების ფაილის \"%s\" ჩატვირთვის შეცდომა: %s" -#: fe-secure-openssl.c:1310 +#: fe-secure-openssl.c:1311 #, c-format msgid "certificate does not match private key file \"%s\": %s" msgstr "სერტიფიკატი პირადი გასაღების ფაილს (\"%s\") არ ემთხვევა: %s" -#: fe-secure-openssl.c:1379 +#: fe-secure-openssl.c:1380 #, c-format msgid "SSL error: certificate verify failed: %s" msgstr "SSL-ის შეცდომა: სერტიფიკატის გადამოწმების შეცდომა: %s" -#: fe-secure-openssl.c:1424 +#: fe-secure-openssl.c:1425 #, c-format msgid "This may indicate that the server does not support any SSL protocol version between %s and %s." msgstr "ეს შეიძლება ნიშნავდეს, რომ სერვერს SSL პროტოკოლის %s-სა და %s-ს შორის ვერსიების მხარდაჭერა არ გააჩნია." -#: fe-secure-openssl.c:1456 +#: fe-secure-openssl.c:1457 #, c-format msgid "direct SSL connection was established without ALPN protocol negotiation extension" msgstr "პირდაპირი SSL მიერთება დამყარდა ALPN პროტოკოლის მიმოცვლის გაფართოების გარეშე" -#: fe-secure-openssl.c:1468 +#: fe-secure-openssl.c:1469 #, c-format msgid "SSL connection was established with unexpected ALPN protocol" msgstr "SSL შეერთება დამყარდა მოულოდნელი ALPN პროტოკოლით" -#: fe-secure-openssl.c:1485 +#: fe-secure-openssl.c:1486 #, c-format msgid "certificate could not be obtained: %s" msgstr "სერტიფიკატის მიღების შეცდომა: %s" -#: fe-secure-openssl.c:1564 +#: fe-secure-openssl.c:1565 #, c-format msgid "no SSL error reported" msgstr "'SSL'-ის შეცდომების გარეშე" -#: fe-secure-openssl.c:1607 +#: fe-secure-openssl.c:1608 #, c-format msgid "SSL error code %lu" msgstr "SSL-ის შეცდომის კოდი %lu" -#: fe-secure-openssl.c:1909 +#: fe-secure-openssl.c:1910 #, c-format msgid "WARNING: sslpassword truncated\n" msgstr "გაფრთხილება: sslpasswrord შეკვეცილია\n" @@ -2090,204 +2090,3 @@ msgstr "სერვერისთვის მონაცემების msgid "unrecognized socket error: 0x%08X/%d" msgstr "სოკეტის უცნობი შეცდომა: 0x%08X/%d" -#, c-format -#~ msgid "%s(%s) failed: error code %d\n" -#~ msgstr "%s(%s) -ის შეცდომა: შეცდომის კოდი %d\n" - -#~ msgid "GSSAPI context establishment error" -#~ msgstr "GSSAPI-ის კონტექსტის დამყარებულობის შეცდომა" - -#, c-format -#~ msgid "GSSAPI encryption required but it is not supported over a local socket)" -#~ msgstr "GSSAPI დაშიფვრა მოთხოვნილია, მაგრამ შეუძლებელია ლოკალური სოკეტის გამოყენებით)" - -#~ msgid "SCM_CRED authentication method not supported\n" -#~ msgstr "SCM_CRED ავთენტიკაციის მეთოდი მხარდაუჭერელია\n" - -#, c-format -#~ msgid "SSL error: %s\n" -#~ msgstr "SSL-ის შეცდომა: %s\n" - -#, c-format -#~ msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" -#~ msgstr "Unix-დომენის სოკეტის მისამართი \"%s\" ძალიან გრძელია (დასაშვებია %d ბაიტი)\n" - -#, c-format -#~ msgid "adding kqueue timer to multiplexer: %m" -#~ msgstr "kqueue-ის ტაიმერის დამატება მულტიპლექსერზე: %m" - -#, c-format -#~ msgid "could not add to epoll set: %m" -#~ msgstr "epoll-ის ნაკრებში ჩამატება შეუძლებელია: %m" - -#, c-format -#~ msgid "could not add to kqueue: %m" -#~ msgstr "kqueue-ში ჩამატება შეუძლებელია: %m" - -#, c-format -#~ msgid "could not comb kqueue: %m" -#~ msgstr "kqueue-ის კომბინგი შეუძლებელია: %m" - -#, c-format -#~ msgid "could not create SSL context: %s\n" -#~ msgstr "შეცდომა SSL კონტექსტის შექმნისას: %s\n" - -#, c-format -#~ msgid "could not delete from epoll set: %m" -#~ msgstr "epoll-ის ნაკრებიდან წაშლა შეუძლებელია: %m" - -#, c-format -#~ msgid "could not delete from kqueue: %m" -#~ msgstr "kqueue-დან წაშლა შეუძლებელია: %m" - -#, c-format -#~ msgid "could not load private key file \"%s\": %s\n" -#~ msgstr "პირადი გასაღების ფაილის \"%s\" ჩატვირთვის შეცდომა: %s\n" - -#, c-format -#~ msgid "could not look up local user ID %d: %s" -#~ msgstr "ლოკალური მომხმარებლის ID-ის (%d) ამოხსნა შეუძლებელია: %s" - -#, c-format -#~ msgid "could not modify kqueue: %m" -#~ msgstr "kqueue-ის შეცვლა შეუძლებელია: %m" - -#, c-format -#~ msgid "could not open file \"%s\": %s\n" -#~ msgstr "ფაილის გახსნის შეცდომა \"%s\": %s\n" - -#, c-format -#~ msgid "could not update epoll set: %m" -#~ msgstr "epoll-ების ნაკრების განახლება ჩავარდა: %m" - -#, c-format -#~ msgid "deleting kqueue timer: %m" -#~ msgstr "kqueue-ის ტაიმერის წაშლა: %m" - -#, c-format -#~ msgid "failed to add timerfd to epoll set: %m" -#~ msgstr "epoll-ის ნაკრებში timerfd-ის ჩამატება ჩავარდა; %m" - -#, c-format -#~ msgid "failed to create epoll set: %m" -#~ msgstr "epoll-ის ნაკრების შექმნა ჩავარდა: %m" - -#, c-format -#~ msgid "failed to create timer kqueue: %m" -#~ msgstr "ტაიმერის kqueue-ის შექმნა ჩავარდა: %m" - -#, c-format -#~ msgid "failed to create timerfd: %m" -#~ msgstr "timerfd-ის შექმნა ჩავარდა: %m" - -#, c-format -#~ msgid "failed to lock mutex (%d)" -#~ msgstr "მუტექსის დაბლოკვა ჩავარდა (%d)" - -#, c-format -#~ msgid "getting timerfd value: %m" -#~ msgstr "timerfd-ის მნიშვნელობის მიღება: %m" - -#~ msgid "incoming GSSAPI message did not use confidentiality\n" -#~ msgstr "შემომავალი GSSAPI შეტყობინება კონფიდენციალობას არ იყენებს\n" - -#, c-format -#~ msgid "internal error: array member found at nesting level %d" -#~ msgstr "შიდა შეცდომა: ერთმანეთში ჩალაგების დონეზე %d აღმოჩენილია მასივის წევრი" - -#, c-format -#~ msgid "internal error: field '%s' still active at end of object" -#~ msgstr "შიდა შეცდომა: ველი '%s' ჯერ კიდევ აქტიურია ობიექტის ბოლოში" - -#, c-format -#~ msgid "internal error: found unexpected array end while parsing field '%s'" -#~ msgstr "შიდა შეცდომა: აღმოჩენილია მოულოდნელი მასივის დასასრული '%s' ველის დამუშავებისას" - -#, c-format -#~ msgid "internal error: scalar field '%s' would be assigned twice" -#~ msgstr "შიდა შეცდომა: შეიძლება, სკალარული ველი '%s' ორჯერაა მინიჭებული" - -#, c-format -#~ msgid "internal error: scalar target found at nesting level %d" -#~ msgstr "შიდა შეცდომა: აღმოჩენილია სკალარული სამიზნე ერთმანეთში ჩალაგების დონეზე %d" - -#, c-format -#~ msgid "internal error: started field '%s' before field '%s' was finished" -#~ msgstr "შიდა შეცდომა: დაიწყო ველი '%s' მანამდე, სანამ დასრულდა ველი '%s'" - -#, c-format -#~ msgid "invalid %s message" -#~ msgstr "არასწორი %s შეტყობინება" - -#, c-format -#~ msgid "invalid require_auth method: \"%s\"" -#~ msgstr "require_auth-ის არასწორი მეთოდი: \"%s\"" - -#, c-format -#~ msgid "keepalives parameter must be an integer" -#~ msgstr "პარამეტრი keepalives მთელი რიცხვი უნდა იყოს" - -#, c-format -#~ msgid "min_protocol_version is greater than max_protocol_version" -#~ msgstr "min_protocol_version უფრო დიდია, ვიდრე max_protocol_version" - -#, c-format -#~ msgid "no application protocol" -#~ msgstr "აპლიკაციის პროტოკოლის გარეშე" - -#~ msgid "outgoing GSSAPI message would not use confidentiality\n" -#~ msgstr "გამავალი GSSAPI შეტყობინება კონფიდენციალობას არ იყენებს\n" - -#, c-format -#~ msgid "passed connection is not open" -#~ msgstr "გადაცემული მიერთება ღია არაა" - -#, c-format -#~ msgid "passed connection was NULL" -#~ msgstr "გადაცემული მიერთება ნულოვანია" - -#, c-format -#~ msgid "private key file \"%s\" is not a regular file\n" -#~ msgstr "პირადი გასაღების ფაილი \"%s\" ჩვეულებრივი ფაილი არაა\n" - -#, c-format -#~ msgid "protocol extension not supported by server: %s" -#~ msgid_plural "protocol extensions not supported by server: %s" -#~ msgstr[0] "პროტოკოლის გაფართოება სერვერის მიერ მხარდაჭერილი არაა: %s" -#~ msgstr[1] "პროტოკოლის გაფართოებები სერვერის მიერ მხარდაჭერილი არაა: %s" - -#, c-format -#~ msgid "protocol version not supported by server: client uses %u.%u, server supports up to %u.%u" -#~ msgstr "პროტოკოლის ვერსია სერვერის მიერ მხარდაჭერილი არაა: კლიენტი იყენებს %u.%u, სერვერის მხარდაჭერილი ვერსიის მაქსიმუმია %u.%u" - -#, c-format -#~ msgid "removing kqueue timer from multiplexer: %m" -#~ msgstr "kqueue-ის ტაიმერის წაშლა მულტიპლექსერიდან: %m" - -#, c-format -#~ msgid "setting kqueue timer to %ld: %m" -#~ msgstr "kqueue-ის ტაიმერის დაყენება %ld-ზე: %m" - -#, c-format -#~ msgid "setting timerfd to %ld: %m" -#~ msgstr "%ld-ზე timerfd-ის დაყენება: %m" - -#, c-format -#~ msgid "sslnegotiation value \"%s\" invalid when SSL support is not compiled in" -#~ msgstr "sslnegotiation-ის მნიშვნელობა \"%s\" არასწორია, როცა SSL-ის მხარდაჭერა გამორთული იყო აგების დროს" - -#, c-format -#~ msgid "unknown command type provided" -#~ msgstr "მითითებულია უცნობი ბრძანების ტიპი" - -#, c-format -#~ msgid "unknown libcurl socket operation: %d" -#~ msgstr "libcurl-ის სოკეტის უცნობი ოპერაცია: %d" - -#, c-format -#~ msgid "unrecognized SSL error code: %d\n" -#~ msgstr "უცნობი SSL-ის შეცდომის კოდი: %d\n" - -#, c-format -#~ msgid "user name lookup failure: error code %lu\n" -#~ msgstr "მომხარებლის სახელის ამოხსნის პრობლემა: შეცდომის კოდი: %lu\n" diff --git a/src/pl/plperl/po/ka.po b/src/pl/plperl/po/ka.po index 330c62c61a3..a249ee82f26 100644 --- a/src/pl/plperl/po/ka.po +++ b/src/pl/plperl/po/ka.po @@ -226,6 +226,3 @@ msgstr "\"PL/Perl\" ფუნქციის \"%s\" კომპილაცი msgid "PL/Perl anonymous code block" msgstr "PL/Perl ანონიმური კოდის ბლოკი" -#, c-format -#~ msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" -#~ msgstr "მასივის ზომების რაოდენობა (%d) მაქსიმუმ დასაშვებზე (%d) დიდია" diff --git a/src/pl/plpgsql/src/po/ka.po b/src/pl/plpgsql/src/po/ka.po index 344f0bec724..d76c4f63b5d 100644 --- a/src/pl/plpgsql/src/po/ka.po +++ b/src/pl/plpgsql/src/po/ka.po @@ -872,6 +872,3 @@ msgstr "%s შეყვანის ბოლოს" msgid "%s at or near \"%s\"" msgstr "%s \"%s\"-სთან ან ახლოს" -#, c-format -#~ msgid "could not determine actual argument type for polymorphic function \"%s\"" -#~ msgstr "პოლიმორფული ფუნქციისთვის (%s) მიმდინარე არგუმენტის ტიპის დადგენა შეუძლებელია" diff --git a/src/pl/plpython/po/de.po b/src/pl/plpython/po/de.po index acda50e4597..1446cf63de3 100644 --- a/src/pl/plpython/po/de.po +++ b/src/pl/plpython/po/de.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-04-10 13:39+0000\n" -"PO-Revision-Date: 2026-04-10 16:15+0200\n" +"POT-Creation-Date: 2026-06-30 04:09+0000\n" +"PO-Revision-Date: 2026-07-04 01:18+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -29,39 +29,45 @@ msgstr "plpy.cursor hat eine Anfrage oder einen Plan erwartet" msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor nimmt eine Sequenz als zweites Argument" -#: plpy_cursorobject.c:193 plpy_spi.c:200 +#: plpy_cursorobject.c:193 plpy_spi.c:207 #, c-format msgid "could not execute plan" msgstr "konnte Plan nicht ausführen" -#: plpy_cursorobject.c:196 plpy_spi.c:203 +#: plpy_cursorobject.c:196 plpy_spi.c:210 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" msgstr[0] "Sequenz aus %d Argument erwartet, aber %d erhalten: %s" msgstr[1] "Sequenz aus %d Argumenten erwartet, aber %d erhalten: %s" -#: plpy_cursorobject.c:349 +#: plpy_cursorobject.c:264 plpy_spi.c:93 plpy_spi.c:261 plpy_typeio.c:1215 +#: plpy_typeio.c:1466 +#, c-format +msgid "could not get element %d from sequence" +msgstr "konnte Element %d der Sequenz nicht ermitteln" + +#: plpy_cursorobject.c:354 #, c-format msgid "iterating a closed cursor" msgstr "Iteration mit einem geschlossenen Cursor" -#: plpy_cursorobject.c:357 plpy_cursorobject.c:423 +#: plpy_cursorobject.c:362 plpy_cursorobject.c:428 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "Iteration mit einem Cursor in einer abgebrochenen Transaktionen" -#: plpy_cursorobject.c:415 +#: plpy_cursorobject.c:420 #, c-format msgid "fetch from a closed cursor" msgstr "Lesen aus einem geschlossenen Cursor" -#: plpy_cursorobject.c:458 plpy_spi.c:389 +#: plpy_cursorobject.c:463 plpy_spi.c:401 #, c-format msgid "query result has too many rows to fit in a Python list" msgstr "Anfrageergebnis hat zu viele Zeilen, um in eine Python-Liste zu passen" -#: plpy_cursorobject.c:510 +#: plpy_cursorobject.c:515 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "Schließen eines Cursors in einer abgebrochenen Subtransaktion" @@ -71,142 +77,142 @@ msgstr "Schließen eines Cursors in einer abgebrochenen Subtransaktion" msgid "%s" msgstr "%s" -#: plpy_exec.c:138 +#: plpy_exec.c:77 #, c-format msgid "unsupported set function return mode" msgstr "nicht unterstützter Rückgabemodus für Funktion mit Mengenergebnis" -#: plpy_exec.c:139 +#: plpy_exec.c:78 #, c-format msgid "PL/Python set-returning functions only support returning one value per call." msgstr "PL/Python unterstützt für Funktionen mit Mengenergebnis nur das Zurückgeben von einem Wert pro Aufruf." -#: plpy_exec.c:152 +#: plpy_exec.c:142 #, c-format msgid "returned object cannot be iterated" msgstr "zurückgegebenes Objekt kann nicht iteriert werden" -#: plpy_exec.c:153 +#: plpy_exec.c:143 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "PL/Python-Funktionen mit Mengenergebnis müssen ein iterierbares Objekt zurückgeben." -#: plpy_exec.c:167 +#: plpy_exec.c:157 #, c-format msgid "error fetching next item from iterator" msgstr "Fehler beim Auslesen des nächsten Elements vom Iterator" -#: plpy_exec.c:210 +#: plpy_exec.c:200 #, c-format msgid "PL/Python procedure did not return None" msgstr "PL/Python-Prozedur hat nicht None zurückgegeben" -#: plpy_exec.c:214 +#: plpy_exec.c:204 #, c-format msgid "PL/Python function with return type \"void\" did not return None" msgstr "PL/Python-Funktion mit Rückgabetyp »void« hat nicht None zurückgegeben" -#: plpy_exec.c:245 +#: plpy_exec.c:235 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "Funktion, die einen Record zurückgibt, in einem Zusammenhang aufgerufen, der Typ record nicht verarbeiten kann" -#: plpy_exec.c:391 plpy_exec.c:415 +#: plpy_exec.c:460 plpy_exec.c:484 #, c-format msgid "unexpected return value from trigger procedure" msgstr "unerwarteter Rückgabewert von Triggerprozedur" -#: plpy_exec.c:392 +#: plpy_exec.c:461 #, c-format msgid "Expected None or a string." msgstr "Erwartete None oder eine Zeichenkette." -#: plpy_exec.c:405 +#: plpy_exec.c:474 #, c-format msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" msgstr "PL/Python-Funktion gab in einem DELETE-Trigger \"MODIFY\" zurück -- ignoriert" -#: plpy_exec.c:416 +#: plpy_exec.c:485 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "Erwartete None, \"OK\", \"SKIP\" oder \"MODIFY\"." -#: plpy_exec.c:508 +#: plpy_exec.c:577 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "PyList_SetItem() fehlgeschlagen, beim Einrichten der Argumente" -#: plpy_exec.c:512 +#: plpy_exec.c:581 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "PyDict_SetItemString() fehlgeschlagen, beim Einrichten der Argumente" -#: plpy_exec.c:741 +#: plpy_exec.c:791 #, c-format msgid "while creating return value" msgstr "beim Erzeugen des Rückgabewerts" -#: plpy_exec.c:992 +#: plpy_exec.c:1042 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "TD[\"new\"] wurde gelöscht, kann Zeile nicht ändern" -#: plpy_exec.c:997 +#: plpy_exec.c:1047 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] ist kein Dictionary" -#: plpy_exec.c:1022 +#: plpy_exec.c:1072 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "Dictionary-Schlüssel auf Position %d in TD[\"new\"] ist keine Zeichenkette" -#: plpy_exec.c:1029 +#: plpy_exec.c:1079 #, c-format msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" msgstr "in TD[\"new\"] gefundener Schlüssel »%s« existiert nicht als Spalte in der den Trigger auslösenden Zeile" -#: plpy_exec.c:1034 +#: plpy_exec.c:1084 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "Systemattribut »%s« kann nicht gesetzt werden" -#: plpy_exec.c:1039 +#: plpy_exec.c:1089 #, c-format msgid "cannot set generated column \"%s\"" msgstr "kann generierte Spalte »%s« nicht setzen" -#: plpy_exec.c:1097 +#: plpy_exec.c:1147 #, c-format msgid "while modifying trigger row" msgstr "beim Ändern der Triggerzeile" -#: plpy_exec.c:1149 +#: plpy_exec.c:1199 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "Abbruch einer Subtransaktion, die nicht beendet wurde, wird erzwungen" -#: plpy_main.c:74 plpy_main.c:94 +#: plpy_main.c:70 plpy_main.c:90 #, c-format msgid "could not import \"%s\" module" msgstr "konnte Modul »%s« nicht importieren" -#: plpy_main.c:99 +#: plpy_main.c:95 #, c-format msgid "untrapped error in initialization" msgstr "nicht abgefangener Fehler bei der Initialisierung" -#: plpy_main.c:321 +#: plpy_main.c:368 #, c-format msgid "PL/Python procedure \"%s\"" msgstr "PL/Python-Prozedur »%s«" -#: plpy_main.c:324 +#: plpy_main.c:371 #, c-format msgid "PL/Python function \"%s\"" msgstr "PL/Python-Funktion »%s«" -#: plpy_main.c:332 +#: plpy_main.c:379 #, c-format msgid "PL/Python anonymous code block" msgstr "anonymer PL/Python-Codeblock" @@ -255,27 +261,27 @@ msgstr "»%s« ist ein ungültiges Schlüsselwortargument für diese Funktion" msgid "invalid SQLSTATE code" msgstr "ungültiger SQLSTATE-Code" -#: plpy_procedure.c:239 +#: plpy_procedure.c:237 #, c-format msgid "trigger functions can only be called as triggers" msgstr "Triggerfunktionen können nur als Trigger aufgerufen werden" -#: plpy_procedure.c:243 +#: plpy_procedure.c:241 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "PL/Python-Funktionen können keinen Rückgabetyp %s haben" -#: plpy_procedure.c:321 +#: plpy_procedure.c:319 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "PL/Python-Funktionen können Typ %s nicht annehmen" -#: plpy_procedure.c:412 +#: plpy_procedure.c:409 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "konnte PL/Python-Funktion »%s« nicht kompilieren" -#: plpy_procedure.c:415 +#: plpy_procedure.c:412 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "konnte anonymen PL/Python-Codeblock nicht kompilieren" @@ -285,32 +291,32 @@ msgstr "konnte anonymen PL/Python-Codeblock nicht kompilieren" msgid "command did not produce a result set" msgstr "Befehl hat keine Ergebnismenge erzeugt" -#: plpy_spi.c:53 +#: plpy_spi.c:54 #, c-format msgid "second argument of plpy.prepare must be a sequence" msgstr "zweites Argument von plpy.prepare muss eine Sequenz sein" -#: plpy_spi.c:94 +#: plpy_spi.c:100 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: Typname auf Position %d ist keine Zeichenkette" -#: plpy_spi.c:166 +#: plpy_spi.c:173 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute hat eine Anfrage oder einen Plan erwartet" -#: plpy_spi.c:184 +#: plpy_spi.c:191 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute nimmt eine Sequenz als zweites Argument" -#: plpy_spi.c:285 +#: plpy_spi.c:297 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "SPI_execute_plan fehlgeschlagen: %s" -#: plpy_spi.c:327 +#: plpy_spi.c:339 #, c-format msgid "SPI_execute failed: %s" msgstr "SPI_execute fehlgeschlagen: %s" @@ -375,52 +381,52 @@ msgstr "Rückgabewert von Funktion mit Array-Rückgabetyp ist keine Python-Seque msgid "could not determine sequence length for function return value" msgstr "konnte Sequenzlänge für Funktionsrückgabewert nicht ermitteln" -#: plpy_typeio.c:1226 plpy_typeio.c:1241 plpy_typeio.c:1257 +#: plpy_typeio.c:1230 plpy_typeio.c:1245 plpy_typeio.c:1261 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "mehrdimensionale Arrays müssen Arraysausdrücke mit gleicher Anzahl Dimensionen haben" -#: plpy_typeio.c:1231 +#: plpy_typeio.c:1235 #, c-format msgid "number of array dimensions exceeds the maximum allowed (%d)" msgstr "Anzahl der Arraydimensionen überschreitet erlaubtes Maximum (%d)" -#: plpy_typeio.c:1333 +#: plpy_typeio.c:1337 #, c-format msgid "malformed record literal: \"%s\"" msgstr "fehlerhafte Record-Konstante: »%s«" -#: plpy_typeio.c:1334 +#: plpy_typeio.c:1338 #, c-format msgid "Missing left parenthesis." msgstr "Linke Klammer fehlt." -#: plpy_typeio.c:1335 plpy_typeio.c:1536 +#: plpy_typeio.c:1339 plpy_typeio.c:1543 #, c-format msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." msgstr "Um einen zusammengesetzten Typ in einem Array zurückzugeben, geben Sie den zusammengesetzten Typ als ein Python-Tupel zurück, z.B. »[('foo',)]«." -#: plpy_typeio.c:1382 +#: plpy_typeio.c:1386 #, c-format msgid "key \"%s\" not found in mapping" msgstr "Schlüssel »%s« nicht in Mapping gefunden" -#: plpy_typeio.c:1383 +#: plpy_typeio.c:1387 #, c-format msgid "To return null in a column, add the value None to the mapping with the key named after the column." msgstr "Um einen NULL-Wert in einer Spalte zurückzugeben, muss der Wert None mit einem nach der Spalte benannten Schlüssel in das Mapping eingefügt werden." -#: plpy_typeio.c:1436 +#: plpy_typeio.c:1440 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "Länge der zurückgegebenen Sequenz hat nicht mit der Anzahl der Spalten in der Zeile übereingestimmt" -#: plpy_typeio.c:1534 +#: plpy_typeio.c:1541 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "Attribut »%s« existiert nicht in Python-Objekt" -#: plpy_typeio.c:1537 +#: plpy_typeio.c:1544 #, c-format msgid "To return null in a column, let the returned object have an attribute named after column with value None." msgstr "Um einen NULL-Wert in einer Spalte zurückzugeben, muss das zurückzugebende Objekt ein nach der Spalte benanntes Attribut mit dem Wert None haben." diff --git a/src/pl/plpython/po/ja.po b/src/pl/plpython/po/ja.po index 7b9d6957100..14506d71aa4 100644 --- a/src/pl/plpython/po/ja.po +++ b/src/pl/plpython/po/ja.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: plpython (PostgreSQL 15)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-15 13:38+0900\n" -"PO-Revision-Date: 2026-05-15 15:02+0900\n" +"POT-Creation-Date: 2026-07-03 14:13+0900\n" +"PO-Revision-Date: 2026-07-06 15:14+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" @@ -28,38 +28,44 @@ msgstr "plpy.cursor は問い合わせもしくは実行計画を期待してい msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor は第二引数としてシーケンスを取ります" -#: plpy_cursorobject.c:193 plpy_spi.c:202 +#: plpy_cursorobject.c:193 plpy_spi.c:207 #, c-format msgid "could not execute plan" msgstr "実行計画を実行できませんでした" -#: plpy_cursorobject.c:196 plpy_spi.c:205 +#: plpy_cursorobject.c:196 plpy_spi.c:210 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" msgstr[0] "%d 個の引数のシーケンスを期待していましたが、個数は %d でした:%s" -#: plpy_cursorobject.c:349 +#: plpy_cursorobject.c:264 plpy_spi.c:93 plpy_spi.c:261 plpy_typeio.c:1215 +#: plpy_typeio.c:1466 +#, c-format +msgid "could not get element %d from sequence" +msgstr "シーケンスから要素%dを取得できませんでした" + +#: plpy_cursorobject.c:354 #, c-format msgid "iterating a closed cursor" msgstr "反復利用しようとしているカーソルは、すでにクローズされています" -#: plpy_cursorobject.c:357 plpy_cursorobject.c:423 +#: plpy_cursorobject.c:362 plpy_cursorobject.c:428 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "中断されたサブトランザクションの中でカーソルを反復利用しようとしています" -#: plpy_cursorobject.c:415 +#: plpy_cursorobject.c:420 #, c-format msgid "fetch from a closed cursor" msgstr "クローズされたカーソルからのフェッチ" -#: plpy_cursorobject.c:458 plpy_spi.c:391 +#: plpy_cursorobject.c:463 plpy_spi.c:401 #, c-format msgid "query result has too many rows to fit in a Python list" msgstr "問い合わせの結果に含まれる行数が、Pythonのリストに対して多すぎます" -#: plpy_cursorobject.c:510 +#: plpy_cursorobject.c:515 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "中断されたサブトランザクションの中でカーソルをクローズしようとしています" @@ -69,142 +75,142 @@ msgstr "中断されたサブトランザクションの中でカーソルをク msgid "%s" msgstr "%s" -#: plpy_exec.c:138 +#: plpy_exec.c:77 #, c-format msgid "unsupported set function return mode" msgstr "非サポートの集合関数リターンモードです。" -#: plpy_exec.c:139 +#: plpy_exec.c:78 #, c-format msgid "PL/Python set-returning functions only support returning one value per call." msgstr "集合を返却するPL/Python関数では、1回の呼び出しに対して1つの値を返すことのみがサポートされています。" -#: plpy_exec.c:152 +#: plpy_exec.c:142 #, c-format msgid "returned object cannot be iterated" msgstr "返されたオブジェクトは反復利用できません" -#: plpy_exec.c:153 +#: plpy_exec.c:143 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "PL/Pythonの集合を返す関数は、反復処理可能なオブジェクトを返さなければなりません。" -#: plpy_exec.c:167 +#: plpy_exec.c:157 #, c-format msgid "error fetching next item from iterator" msgstr "反復子から次の項目を取り出せませんでした" -#: plpy_exec.c:210 +#: plpy_exec.c:200 #, c-format msgid "PL/Python procedure did not return None" msgstr "PL/Python プロシージャが None を返しませんでした" -#: plpy_exec.c:214 +#: plpy_exec.c:204 #, c-format msgid "PL/Python function with return type \"void\" did not return None" msgstr "戻り値が\"void\"型である PL/Python関数がNoneを返しませんでした" -#: plpy_exec.c:245 +#: plpy_exec.c:235 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "レコード型を受け付けられないコンテキストでレコードを返す関数が呼び出されました" -#: plpy_exec.c:392 plpy_exec.c:416 +#: plpy_exec.c:460 plpy_exec.c:484 #, c-format msgid "unexpected return value from trigger procedure" msgstr "トリガプロシージャから期待しない戻り値が返されました" -#: plpy_exec.c:393 +#: plpy_exec.c:461 #, c-format msgid "Expected None or a string." msgstr "None もしくは文字列を期待していました。" -#: plpy_exec.c:406 +#: plpy_exec.c:474 #, c-format msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" msgstr "PL/Python トリガ関数が、DELETE トリガで \"MODIFY\" を返しました-- 無視します" -#: plpy_exec.c:417 +#: plpy_exec.c:485 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "None, \"OK\", \"SKIP\", \"MODIFY\" のいずれかを期待していました。" -#: plpy_exec.c:509 +#: plpy_exec.c:577 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "引数を設定する際に、PyList_SetItem() に失敗しました" -#: plpy_exec.c:513 +#: plpy_exec.c:581 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "引数を設定する際に、PyDict_SetItemString() に失敗しました" -#: plpy_exec.c:742 +#: plpy_exec.c:791 #, c-format msgid "while creating return value" msgstr "戻り値を生成する際に" -#: plpy_exec.c:993 +#: plpy_exec.c:1042 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "TD[\"new\"] は削除されました。行を変更できません。" -#: plpy_exec.c:998 +#: plpy_exec.c:1047 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] は辞書ではありません" -#: plpy_exec.c:1023 +#: plpy_exec.c:1072 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "TD[\"new\"] 辞書の%d番目のキーが文字列ではありません" -#: plpy_exec.c:1030 +#: plpy_exec.c:1079 #, c-format msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" msgstr "TD[\"new\"] で見つかったキー \"%s\" は、行レベルトリガにおけるカラムとしては存在しません" -#: plpy_exec.c:1035 +#: plpy_exec.c:1084 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "システム属性\"%s\"は設定できません" -#: plpy_exec.c:1040 +#: plpy_exec.c:1089 #, c-format msgid "cannot set generated column \"%s\"" msgstr "生成列\"%s\"は設定できません" -#: plpy_exec.c:1098 +#: plpy_exec.c:1147 #, c-format msgid "while modifying trigger row" msgstr "トリガ行を変更する際に" -#: plpy_exec.c:1150 +#: plpy_exec.c:1199 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "終了していないサブトランザクションを強制的にアボートしています" -#: plpy_main.c:74 plpy_main.c:94 +#: plpy_main.c:70 plpy_main.c:90 #, c-format msgid "could not import \"%s\" module" msgstr "\"%s\"モジュールをインポートできませんでした" -#: plpy_main.c:99 +#: plpy_main.c:95 #, c-format msgid "untrapped error in initialization" msgstr "初期化中に捕捉できないエラーがありました" -#: plpy_main.c:321 +#: plpy_main.c:368 #, c-format msgid "PL/Python procedure \"%s\"" msgstr "PL/Pythonプロシージャ\"%s\"" -#: plpy_main.c:324 +#: plpy_main.c:371 #, c-format msgid "PL/Python function \"%s\"" msgstr "PL/Python関数\"%s\"" -#: plpy_main.c:332 +#: plpy_main.c:379 #, c-format msgid "PL/Python anonymous code block" msgstr "PL/Pythonの無名コードブロック" @@ -253,27 +259,27 @@ msgstr "この関数に対して'%s'は無効なキーワード引数です" msgid "invalid SQLSTATE code" msgstr "無効なSQLSTATEコードです" -#: plpy_procedure.c:239 +#: plpy_procedure.c:237 #, c-format msgid "trigger functions can only be called as triggers" msgstr "トリガー関数はトリガーとしてのみ呼び出せます" -#: plpy_procedure.c:243 +#: plpy_procedure.c:241 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "PL/Python関数は%s型を返せません" -#: plpy_procedure.c:321 +#: plpy_procedure.c:319 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "PL/Python関数は%s型を受け付けられません" -#: plpy_procedure.c:412 +#: plpy_procedure.c:409 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "PL/Python関数\"%s\"をコンパイルできませんでした" -#: plpy_procedure.c:415 +#: plpy_procedure.c:412 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "PL/Python無名コードブロックをコンパイルできませんでした" @@ -288,27 +294,27 @@ msgstr "コマンドは結果セットを生成しませんでした" msgid "second argument of plpy.prepare must be a sequence" msgstr "plpy.prepareの第二引数はシーケンスでなければなりません" -#: plpy_spi.c:95 +#: plpy_spi.c:100 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: %d 番目の型名が文字列ではありません" -#: plpy_spi.c:168 +#: plpy_spi.c:173 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute は問い合わせもしくは実行計画を期待していました" -#: plpy_spi.c:186 +#: plpy_spi.c:191 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute は第二引数としてシーケンスを取ります" -#: plpy_spi.c:287 +#: plpy_spi.c:297 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "SPI_execute_plan が失敗しました: %s" -#: plpy_spi.c:329 +#: plpy_spi.c:339 #, c-format msgid "SPI_execute failed: %s" msgstr "SPI_execute が失敗しました: %s" @@ -373,52 +379,52 @@ msgstr "配列型を返す関数の戻り値がPythonのシーケンスではあ msgid "could not determine sequence length for function return value" msgstr "関数の戻り値について、シーケンスの長さを決定できませんでした" -#: plpy_typeio.c:1226 plpy_typeio.c:1241 plpy_typeio.c:1257 +#: plpy_typeio.c:1230 plpy_typeio.c:1245 plpy_typeio.c:1261 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "多次元配列の配列式の次数があっていなければなりません" -#: plpy_typeio.c:1231 +#: plpy_typeio.c:1235 #, c-format msgid "number of array dimensions exceeds the maximum allowed (%d)" msgstr "配列の次元数が制限値(%d)を超えています" -#: plpy_typeio.c:1333 +#: plpy_typeio.c:1337 #, c-format msgid "malformed record literal: \"%s\"" msgstr "不正な形式のレコードリテラル: \"%s\"" -#: plpy_typeio.c:1334 +#: plpy_typeio.c:1338 #, c-format msgid "Missing left parenthesis." msgstr "左括弧がありません。" -#: plpy_typeio.c:1335 plpy_typeio.c:1536 +#: plpy_typeio.c:1339 plpy_typeio.c:1543 #, c-format msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." msgstr "複合型を配列に入れて返したい場合、 \"[('foo',)]\" のように複合型を Pythonのタプルとして返すようにしてください。" -#: plpy_typeio.c:1382 +#: plpy_typeio.c:1386 #, c-format msgid "key \"%s\" not found in mapping" msgstr "マッピング上にキー\"%s\"が見つかりません" -#: plpy_typeio.c:1383 +#: plpy_typeio.c:1387 #, c-format msgid "To return null in a column, add the value None to the mapping with the key named after the column." msgstr "カラムにnullを入れて返す場合、カラム名をキーとして値がNoneのエントリをマッピングに追加してください。" -#: plpy_typeio.c:1436 +#: plpy_typeio.c:1440 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "返されたシーケンスの長さが行のカラム数とマッチしませんでした" -#: plpy_typeio.c:1534 +#: plpy_typeio.c:1541 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "属性\"%s\"がPythonオブジェクト中に存在しません" -#: plpy_typeio.c:1537 +#: plpy_typeio.c:1544 #, c-format msgid "To return null in a column, let the returned object have an attribute named after column with value None." msgstr "カラムにnullを入れて返す場合、カラム名をキーとして値がNoneである属性を持つオブジェクトを返すようにしてください。" diff --git a/src/pl/plpython/po/ka.po b/src/pl/plpython/po/ka.po index aa55f7b0b31..7eb783dde99 100644 --- a/src/pl/plpython/po/ka.po +++ b/src/pl/plpython/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: plpython (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-03-09 11:09+0000\n" -"PO-Revision-Date: 2026-03-09 16:41+0100\n" +"POT-Creation-Date: 2026-06-30 04:09+0000\n" +"PO-Revision-Date: 2026-07-02 06:14+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.8\n" +"X-Generator: Poedit 3.9\n" #: plpy_cursorobject.c:91 #, c-format @@ -28,39 +28,45 @@ msgstr "plpy.cursor გეგმას ან მოთხოვნას მო msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor მეორე არგუმენტად მიმდევრობას იღებს" -#: plpy_cursorobject.c:193 plpy_spi.c:200 +#: plpy_cursorobject.c:193 plpy_spi.c:207 #, c-format msgid "could not execute plan" msgstr "გეგმის შესრულება ვერ მოხერხდა" -#: plpy_cursorobject.c:196 plpy_spi.c:203 +#: plpy_cursorobject.c:196 plpy_spi.c:210 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" msgstr[0] "მოველოდი %d არგუმენტის მიმდევრობას. მივიღე %d: %s" msgstr[1] "მოველოდი %d არგუმენტის მიმდევრობას. მივიღე %d: %s" -#: plpy_cursorobject.c:349 +#: plpy_cursorobject.c:264 plpy_spi.c:93 plpy_spi.c:261 plpy_typeio.c:1215 +#: plpy_typeio.c:1466 +#, c-format +msgid "could not get element %d from sequence" +msgstr "ელემენტის %d მიღება შეუძლებელია მიმდევრობიდან" + +#: plpy_cursorobject.c:354 #, c-format msgid "iterating a closed cursor" msgstr "დახურული კურსორის იტერაცია" -#: plpy_cursorobject.c:357 plpy_cursorobject.c:423 +#: plpy_cursorobject.c:362 plpy_cursorobject.c:428 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "კურსორის იტერაცია გაუქმებულ ტრანზაქციაში" -#: plpy_cursorobject.c:415 +#: plpy_cursorobject.c:420 #, c-format msgid "fetch from a closed cursor" msgstr "დახურული კურსორიდან გამოთხოვა" -#: plpy_cursorobject.c:458 plpy_spi.c:389 +#: plpy_cursorobject.c:463 plpy_spi.c:401 #, c-format msgid "query result has too many rows to fit in a Python list" msgstr "მოთხოვნის პასუხს Python-ის სიაში ჩასატევად მეტისმეტად ბევრი მწკრივი გააჩნია" -#: plpy_cursorobject.c:510 +#: plpy_cursorobject.c:515 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "გაუქმებულ ქვეტრანზაქციაში კურსორის დახურვა" @@ -70,142 +76,142 @@ msgstr "გაუქმებულ ქვეტრანზაქციაშ msgid "%s" msgstr "%s" -#: plpy_exec.c:138 +#: plpy_exec.c:77 #, c-format msgid "unsupported set function return mode" msgstr "სეტების დამბრუნებელი ფუნქციის მხარდაუჭერელი რეჟიმი" -#: plpy_exec.c:139 +#: plpy_exec.c:78 #, c-format msgid "PL/Python set-returning functions only support returning one value per call." msgstr "PL/Python -ის ფუნქციებს, რომლების სეტებს აბრუნებენ, თითოეულ გამოძახებაზე მხოლოდ ერთი მნიშვნელობის მხარდაჭერა გააჩნიათ." -#: plpy_exec.c:152 +#: plpy_exec.c:142 #, c-format msgid "returned object cannot be iterated" msgstr "დაბრუნებული ობიექტის იტერაცია შეუძლებელია" -#: plpy_exec.c:153 +#: plpy_exec.c:143 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "PL/Python-ის ფუნქციებმა, რომლებიც სეტებს აბრუნებენ, იტერირებადი ობიექტი უნდა დააბრუნონ." -#: plpy_exec.c:167 +#: plpy_exec.c:157 #, c-format msgid "error fetching next item from iterator" msgstr "იტერატორიდან შემდეგი ჩანაწერის მოთხოვის შეცდომა" -#: plpy_exec.c:210 +#: plpy_exec.c:200 #, c-format msgid "PL/Python procedure did not return None" msgstr "PL/Python -ის პროცედურამ None არ დააბრუნა" -#: plpy_exec.c:214 +#: plpy_exec.c:204 #, c-format msgid "PL/Python function with return type \"void\" did not return None" msgstr "PL/Python -ის ფუნქციამ, რომელიც აბრუნებს ტიპს \"void\", რაღაც დააბრუნა" -#: plpy_exec.c:245 +#: plpy_exec.c:235 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "ფუნქცია, რომელიც ჩანაწერს აბრუნებს, გამოძახებულია კონტექსტში, რომელსაც ჩანაწერის მიღება არ შეუძლია" -#: plpy_exec.c:391 plpy_exec.c:415 +#: plpy_exec.c:460 plpy_exec.c:484 #, c-format msgid "unexpected return value from trigger procedure" msgstr "ტრიგერის პროცედურის მოულოდნელი დაბრუნებული მნიშვნელობა" -#: plpy_exec.c:392 +#: plpy_exec.c:461 #, c-format msgid "Expected None or a string." msgstr "ველოდებოდი არაფერს ან სტრიქონს." -#: plpy_exec.c:405 +#: plpy_exec.c:474 #, c-format msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" msgstr "PL/Python -ის ტრიგერმა ფუნქციამ DELETE ტრიგერში \"MODIFY\" დააბრუნა. -- იგნორირებულია" -#: plpy_exec.c:416 +#: plpy_exec.c:485 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "მოსალოდნელია არცერთი, \"OK\", \"SKIP\", ან \"MODIFY\"." -#: plpy_exec.c:508 +#: plpy_exec.c:577 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "PyList_SetItem() -ის შეცდომა არგუმენტების მორგებისას" -#: plpy_exec.c:512 +#: plpy_exec.c:581 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "PyDict_SetItemString() -ის შეცდომა არგუმენტების მორგებისას" -#: plpy_exec.c:741 +#: plpy_exec.c:791 #, c-format msgid "while creating return value" msgstr "დასაბრუნებელი მნიშვნელობის შექმნისას" -#: plpy_exec.c:992 +#: plpy_exec.c:1042 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "TD[\"new\"] წაშლილია, მწკრივის შეცვლა შეუძლებელია" -#: plpy_exec.c:997 +#: plpy_exec.c:1047 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] ლექსიკონი არაა" -#: plpy_exec.c:1022 +#: plpy_exec.c:1072 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "TD[\"new\"] ლექსიკონის გასაღები ორდინალურ მდებარეობაზე %d სტრიქონს არ წარმოადგენს" -#: plpy_exec.c:1029 +#: plpy_exec.c:1079 #, c-format msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" msgstr "\"TD[\"new\"]-ში ნაპოვნი გასაღები (%s) დამატრიგერებელი მწკრივის სვეტად არ არსებობს" -#: plpy_exec.c:1034 +#: plpy_exec.c:1084 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "სისტემური ატრიბუტის დაყენების შეცდომა: \"%s\"" -#: plpy_exec.c:1039 +#: plpy_exec.c:1089 #, c-format msgid "cannot set generated column \"%s\"" msgstr "გენერირებული სვეტის დაყენება შეუძლებელია: %s" -#: plpy_exec.c:1097 +#: plpy_exec.c:1147 #, c-format msgid "while modifying trigger row" msgstr "ტრიგერის მწკრივის შეცვლისას" -#: plpy_exec.c:1149 +#: plpy_exec.c:1199 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "ქვეტრანზაქცია, რომელიც ჯერ არ დასრულებულა, ძალით დასრულდება" -#: plpy_main.c:74 plpy_main.c:94 +#: plpy_main.c:70 plpy_main.c:90 #, c-format msgid "could not import \"%s\" module" msgstr "\"%s\" მოდულის შემოტანის შეცდომა" -#: plpy_main.c:99 +#: plpy_main.c:95 #, c-format msgid "untrapped error in initialization" msgstr "დაუჭერელი შეცდომა ინიციალიზაციისას" -#: plpy_main.c:321 +#: plpy_main.c:368 #, c-format msgid "PL/Python procedure \"%s\"" msgstr "PL/Python -ის პროცედურა \"%s\"" -#: plpy_main.c:324 +#: plpy_main.c:371 #, c-format msgid "PL/Python function \"%s\"" msgstr "PL/Python -ის ფუნქცია \"%s\"" -#: plpy_main.c:332 +#: plpy_main.c:379 #, c-format msgid "PL/Python anonymous code block" msgstr "PL/Python -ის ანონიმური კოდის ბლოკი" @@ -254,27 +260,27 @@ msgstr "%s ამ ფუნქციის არასწორი არგუ msgid "invalid SQLSTATE code" msgstr "არასწორი SQLSTATE კოდი" -#: plpy_procedure.c:239 +#: plpy_procedure.c:237 #, c-format msgid "trigger functions can only be called as triggers" msgstr "ტრიგერის ფუნქციების გამოძახება მხოლოდ ტრიგერებად შეიძლება" -#: plpy_procedure.c:243 +#: plpy_procedure.c:241 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "PL/Python ფუნქციებს ამ ტიპის დაბრუნება არ შეუძლიათ: %s" -#: plpy_procedure.c:321 +#: plpy_procedure.c:319 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "PL/Python ფუნქციებს ამ ტიპის მიღება არ შეუძლიათ: %s" -#: plpy_procedure.c:412 +#: plpy_procedure.c:409 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "\"PL/Python\"-ის ფუნქციის კომპილაციის შეცდომა: \"%s\"" -#: plpy_procedure.c:415 +#: plpy_procedure.c:412 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "\"PL/Python\"-ის კოდის ანონიმური ბლოკის კომპილაციის შეცდომა" @@ -284,32 +290,32 @@ msgstr "\"PL/Python\"-ის კოდის ანონიმური ბლ msgid "command did not produce a result set" msgstr "ბრძანებამ შედეგი არ გამოიღო" -#: plpy_spi.c:53 +#: plpy_spi.c:54 #, c-format msgid "second argument of plpy.prepare must be a sequence" msgstr "plpy.prepare -ის მეორე არგუმენტი მიმდევრობა უნდა იყოს" -#: plpy_spi.c:94 +#: plpy_spi.c:100 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: ტიპის სახელი ორდინალურ მდგომარეობაში %d სტრიქონს არ წარმოადგენს" -#: plpy_spi.c:166 +#: plpy_spi.c:173 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute გეგმას ან მოთხოვნას მოელოდა" -#: plpy_spi.c:184 +#: plpy_spi.c:191 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute მეორე არგუმენტად მიმდევრობას იღებს" -#: plpy_spi.c:285 +#: plpy_spi.c:297 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "SPI_execute_plan -ის შეცდომა: %s" -#: plpy_spi.c:327 +#: plpy_spi.c:339 #, c-format msgid "SPI_execute failed: %s" msgstr "SPI_execute -ის შეცდომა: %s" @@ -374,52 +380,52 @@ msgstr "ფუნქციის დაბრულების მნიშვ msgid "could not determine sequence length for function return value" msgstr "ფუნქციის დაბრუნებული მნიშვნელობის მიმდევრობის სიგრძის განსაზღვრა შეუძლებელია" -#: plpy_typeio.c:1226 plpy_typeio.c:1241 plpy_typeio.c:1257 +#: plpy_typeio.c:1230 plpy_typeio.c:1245 plpy_typeio.c:1261 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "მრავალგანზომილებიან მასივებს უნდა ჰქონდეთ მასივის გამოსახულებები შესაბამისი ზომებით" -#: plpy_typeio.c:1231 +#: plpy_typeio.c:1235 #, c-format msgid "number of array dimensions exceeds the maximum allowed (%d)" msgstr "მასივის ზომების რაოდენობა მაქსიმუმ დასაშვებზე (%d) დიდია" -#: plpy_typeio.c:1333 +#: plpy_typeio.c:1337 #, c-format msgid "malformed record literal: \"%s\"" msgstr "ჩანაწერის არასწორი სტრიქონი: %s" -#: plpy_typeio.c:1334 +#: plpy_typeio.c:1338 #, c-format msgid "Missing left parenthesis." msgstr "აკლია მარჯვენა ფრჩხილი." -#: plpy_typeio.c:1335 plpy_typeio.c:1536 +#: plpy_typeio.c:1339 plpy_typeio.c:1543 #, c-format msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." msgstr "მასივში კომპოზიტური ტიპის დასაბრუნებლად კომპოზიტური ტიპი, როგორც Python-ის კოლაჟი, ისე დააბრუნეთ. მაგ: \"[('foo',)]\"." -#: plpy_typeio.c:1382 +#: plpy_typeio.c:1386 #, c-format msgid "key \"%s\" not found in mapping" msgstr "ბმაში გასაღები %s ნაპოვნი არაა" -#: plpy_typeio.c:1383 +#: plpy_typeio.c:1387 #, c-format msgid "To return null in a column, add the value None to the mapping with the key named after the column." msgstr "სვეტში ნულის დასაბრუნებლად ამ სვეტის სახელის მქონე გასაღების მიბმას მნიშვნელობა None დაამატეთ." -#: plpy_typeio.c:1436 +#: plpy_typeio.c:1440 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "დაბრუნებული მიმდევრობის სიგრძე მწკრივში სვეტების რაოდენობას არ ემთხვევა" -#: plpy_typeio.c:1534 +#: plpy_typeio.c:1541 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "ატრიბუტი \"%s\" Python -ის ობიექტში არ არსებობს" -#: plpy_typeio.c:1537 +#: plpy_typeio.c:1544 #, c-format msgid "To return null in a column, let the returned object have an attribute named after column with value None." msgstr "სვეტში ნულის დასაბრუნებლად დასაბრუნებელ ობიექტს მიანიჭეთ სვეტის სახელის მქონე ატრიბუტი , მნიშვნელობით \"None\"." @@ -433,31 +439,3 @@ msgstr "\"Python Unicode\" ტიპის ობიექტის ბაიტ #, c-format msgid "could not extract bytes from encoded string" msgstr "ბაიტების ამოღების შეცდომა კოდირებული სტრიქონიდან" - -#, c-format -#~ msgid "Only one Python major version can be used in one session." -#~ msgstr "ერთ სესიაში Python-ის მხოლოდ ერთი ძირითადი ვერსია შეგიძლიათ გამოიყენოთ." - -#, c-format -#~ msgid "To construct a multidimensional array, the inner sequences must all have the same length." -#~ msgstr "მრავალგანზომილებიანი მასივის ასაშენებლად ყველა შიდა მიმდევრობის სიგრძე ტოლი უნდა იყოს." - -#, c-format -#~ msgid "array size exceeds the maximum allowed" -#~ msgstr "მასივის ზომა მაქსიმალურ დასაშვებს აჭარბებს" - -#, c-format -#~ msgid "could not import \"__main__\" module" -#~ msgstr "\"__main__\" მოდულის შემოტანის შეცდომა" - -#, c-format -#~ msgid "could not initialize globals" -#~ msgstr "გლობალების ინიციალიზაციის შეცდომა" - -#, c-format -#~ msgid "multiple Python libraries are present in session" -#~ msgstr "სესია Python-ის ერთზე მეტ ბიბლიოთეკას შეიცავს" - -#, c-format -#~ msgid "wrong length of inner sequence: has length %d, but %d was expected" -#~ msgstr "შიდა მიმდევრობის არასწორი სიგრძე: სიგრძე: %d. უნდა იყოს: %d" diff --git a/src/pl/tcl/po/ka.po b/src/pl/tcl/po/ka.po index 724a7263372..4e49ded020f 100644 --- a/src/pl/tcl/po/ka.po +++ b/src/pl/tcl/po/ka.po @@ -121,6 +121,3 @@ msgstr "სისტემური ატრიბუტის დაყენ msgid "cannot set generated column \"%s\"" msgstr "გენერირებული სვეტის დაყენება შეუძლებელია: %s" -#, c-format -#~ msgid "could not split return value from trigger: %s" -#~ msgstr "ტრიგერიდან დაბრუნებული მნიშვნელობის დაყოფა შეუძლებელია: %s" From 7873db5369b967dd53984df34fd800003410d04f Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 13 Jul 2026 16:03:24 -0400 Subject: [PATCH 144/481] Stamp 19beta2. --- configure | 18 +++++++++--------- configure.ac | 2 +- meson.build | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/configure b/configure index 5f77f3cac29..33f11dbc8fe 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for PostgreSQL 19beta1. +# Generated by GNU Autoconf 2.69 for PostgreSQL 19beta2. # # Report bugs to . # @@ -582,8 +582,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='PostgreSQL' PACKAGE_TARNAME='postgresql' -PACKAGE_VERSION='19beta1' -PACKAGE_STRING='PostgreSQL 19beta1' +PACKAGE_VERSION='19beta2' +PACKAGE_STRING='PostgreSQL 19beta2' PACKAGE_BUGREPORT='pgsql-bugs@lists.postgresql.org' PACKAGE_URL='https://www.postgresql.org/' @@ -1468,7 +1468,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures PostgreSQL 19beta1 to adapt to many kinds of systems. +\`configure' configures PostgreSQL 19beta2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1533,7 +1533,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of PostgreSQL 19beta1:";; + short | recursive ) echo "Configuration of PostgreSQL 19beta2:";; esac cat <<\_ACEOF @@ -1724,7 +1724,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -PostgreSQL configure 19beta1 +PostgreSQL configure 19beta2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2477,7 +2477,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by PostgreSQL $as_me 19beta1, which was +It was created by PostgreSQL $as_me 19beta2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -20348,7 +20348,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by PostgreSQL $as_me 19beta1, which was +This file was extended by PostgreSQL $as_me 19beta2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20419,7 +20419,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -PostgreSQL config.status 19beta1 +PostgreSQL config.status 19beta2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 61cee42daa7..1f3869e994f 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Read the Autoconf manual for details. dnl m4_pattern_forbid(^PGAC_)dnl to catch undefined macros -AC_INIT([PostgreSQL], [19beta1], [pgsql-bugs@lists.postgresql.org], [], [https://www.postgresql.org/]) +AC_INIT([PostgreSQL], [19beta2], [pgsql-bugs@lists.postgresql.org], [], [https://www.postgresql.org/]) m4_if(m4_defn([m4_PACKAGE_VERSION]), [2.69], [], [m4_fatal([Autoconf version 2.69 is required. Untested combinations of 'autoconf' and PostgreSQL versions are not diff --git a/meson.build b/meson.build index 568e0e150bf..1a807981e11 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project('postgresql', ['c'], - version: '19beta1', + version: '19beta2', license: 'PostgreSQL', # We want < 0.62 for python 3.6 compatibility on old platforms. From 2349b106b6661c084dc1171654146c730ecb048f Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Wed, 15 Jul 2026 01:39:33 +0300 Subject: [PATCH 145/481] postgres_fdw: don't push down non-relabeling ArrayCoerceExpr Commit 62c3b4cd9ddc taught postgres_fdw to push down ArrayCoerceExpr, but foreign_expr_walker() only recursed into the input array expression and never examined elemexpr, the per-element conversion that gives the coercion its semantics. deparseArrayCoerceExpr() then shipped a bare "arg::resulttype" cast, or nothing at all for an implicit-format coercion, leaving the remote server to re-resolve the element conversion against its own catalogs and session state. This produced wrong results or remote errors whenever the element conversion was not a plain relabeling, and it was inconsistent with how postgres_fdw treats the equivalent scalar coercions. An ArrayCoerceExpr was shipped even when its elemexpr was a cast function (whose shippability was never checked), a CoerceViaIO (e.g. float8out or byteaout, which depend on extra_float_digits / bytea_output that postgres_fdw sets differently on the remote session), or a CoerceToDomain (which pushes domain enforcement to the remote catalog). By contrast, a scalar CoerceViaIO is never shipped, and a scalar cast function is shipped only when it is shippable. Restrict pushdown to element coercions that are a plain relabeling, that is, elemexpr is a RelabelType or a bare CaseTestExpr. Any other element coercion is now evaluated locally. This keeps the common binary-coercible case pushed down, including "col = ANY($1)" with a varchar[]-to-text[] relabeling, which is the case 62c3b4cd9ddc set out to optimize. Pushing down shippable element cast functions, to reach parity with the scalar case, is left out here for simplicity. Reported-by: Noah Misch Discussion: https://postgr.es/m/20260711024234.43.noahmisch%40microsoft.com Backpatch-through: 19 --- contrib/postgres_fdw/deparse.c | 20 +++++ .../postgres_fdw/expected/postgres_fdw.out | 75 +++++++++++++++++++ contrib/postgres_fdw/sql/postgres_fdw.sql | 35 +++++++++ 3 files changed, 130 insertions(+) diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c index 2dcc6c8af1b..9d1932230e7 100644 --- a/contrib/postgres_fdw/deparse.c +++ b/contrib/postgres_fdw/deparse.c @@ -707,6 +707,26 @@ foreign_expr_walker(Node *node, { ArrayCoerceExpr *e = (ArrayCoerceExpr *) node; + /* + * Push down only when the per-element coercion is a plain + * relabeling, that is, elemexpr is a RelabelType or a bare + * CaseTestExpr. Any other element coercion -- a cast + * function, an I/O conversion (CoerceViaIO), or a domain + * coercion -- is kept local. We ship only a bare + * "arg::resulttype" cast (nothing at all for an + * implicit-format coercion), so a non-relabeling conversion + * would be re-resolved against the remote server's catalogs + * and session state and could silently change the result. + * This matches the handling of the scalar coercions for the + * I/O and domain cases (never shipped); an element cast + * function is kept local too, which is more conservative than + * the scalar case (a scalar cast function is shipped when it + * is shippable). + */ + if (!IsA(e->elemexpr, RelabelType) && + !IsA(e->elemexpr, CaseTestExpr)) + return false; + /* * Recurse to input subexpression. */ diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 048f624ba0c..991501245f9 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -1219,6 +1219,81 @@ EXECUTE s(ARRAY['1','2']); DEALLOCATE s; RESET plan_cache_mode; +-- An ArrayCoerceExpr is pushed down only when its per-element coercion is +-- a plain relabeling. An element cast function, an I/O conversion, or a +-- domain coercion is instead evaluated locally. +CREATE TABLE loct_acx (id int, ta text[], f8 float8[], txt text[], t text, ia int[], vc varchar[]); +INSERT INTO loct_acx VALUES (1, '{12345}', '{0.30000000000000004}', '{0.3}', '5', '{5}', '{5}'); +CREATE FOREIGN TABLE ft_acx (id int, ta text[], f8 float8[], txt text[], t text, ia int[], vc varchar[]) + SERVER loopback OPTIONS (table_name 'loct_acx'); +-- element coercion via a cast function: not shippable, stays local +CREATE FUNCTION acx_text2int(text) RETURNS int + LANGUAGE plpgsql IMMUTABLE STRICT AS 'BEGIN RETURN length($1); END'; +CREATE CAST (text AS integer) WITH FUNCTION acx_text2int(text); +EXPLAIN (VERBOSE, COSTS OFF) +SELECT id FROM ft_acx WHERE ta::int[] = ARRAY[5]; + QUERY PLAN +------------------------------------------------------- + Foreign Scan on public.ft_acx + Output: id + Filter: ((ft_acx.ta)::integer[] = '{5}'::integer[]) + Remote SQL: SELECT id, ta FROM public.loct_acx +(4 rows) + +DROP CAST (text AS integer); +DROP FUNCTION acx_text2int(text); +-- implicit-format element coercion (a cast function): stays local, and the +-- coercion is not silently dropped from an otherwise pushed-down qual +CREATE CAST (integer AS text) WITH FUNCTION pg_catalog.to_hex(integer) AS IMPLICIT; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT id FROM ft_acx WHERE t = ANY (ia); + QUERY PLAN +----------------------------------------------------- + Foreign Scan on public.ft_acx + Output: id + Filter: (ft_acx.t = ANY ((ft_acx.ia)::text[])) + Remote SQL: SELECT id, t, ia FROM public.loct_acx +(4 rows) + +DROP CAST (integer AS text); +-- element coercion via a GUC-sensitive I/O conversion: stays local, so the +-- result matches local evaluation despite the forced remote extra_float_digits +SET extra_float_digits = 0; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT id FROM ft_acx WHERE f8::text[] = txt; + QUERY PLAN +------------------------------------------------------- + Foreign Scan on public.ft_acx + Output: id + Filter: ((ft_acx.f8)::text[] = ft_acx.txt) + Remote SQL: SELECT id, f8, txt FROM public.loct_acx +(4 rows) + +SELECT id FROM ft_acx WHERE f8::text[] = txt; + id +---- + 1 +(1 row) + +RESET extra_float_digits; +-- a plain relabeling element coercion (varchar[] to text[]) is still pushed down +EXPLAIN (VERBOSE, COSTS OFF) +SELECT id FROM ft_acx WHERE t = ANY (vc); + QUERY PLAN +--------------------------------------------------------------------- + Foreign Scan on public.ft_acx + Output: id + Remote SQL: SELECT id FROM public.loct_acx WHERE ((t = ANY (vc))) +(3 rows) + +SELECT id FROM ft_acx WHERE t = ANY (vc); + id +---- + 1 +(1 row) + +DROP FOREIGN TABLE ft_acx; +DROP TABLE loct_acx; -- a regconfig constant referring to this text search configuration -- is initially unshippable CREATE TEXT SEARCH CONFIGURATION public.custom_search diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index ed2c8b58e60..454deb03d69 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -485,6 +485,41 @@ EXECUTE s(ARRAY['1','2']); DEALLOCATE s; RESET plan_cache_mode; +-- An ArrayCoerceExpr is pushed down only when its per-element coercion is +-- a plain relabeling. An element cast function, an I/O conversion, or a +-- domain coercion is instead evaluated locally. +CREATE TABLE loct_acx (id int, ta text[], f8 float8[], txt text[], t text, ia int[], vc varchar[]); +INSERT INTO loct_acx VALUES (1, '{12345}', '{0.30000000000000004}', '{0.3}', '5', '{5}', '{5}'); +CREATE FOREIGN TABLE ft_acx (id int, ta text[], f8 float8[], txt text[], t text, ia int[], vc varchar[]) + SERVER loopback OPTIONS (table_name 'loct_acx'); +-- element coercion via a cast function: not shippable, stays local +CREATE FUNCTION acx_text2int(text) RETURNS int + LANGUAGE plpgsql IMMUTABLE STRICT AS 'BEGIN RETURN length($1); END'; +CREATE CAST (text AS integer) WITH FUNCTION acx_text2int(text); +EXPLAIN (VERBOSE, COSTS OFF) +SELECT id FROM ft_acx WHERE ta::int[] = ARRAY[5]; +DROP CAST (text AS integer); +DROP FUNCTION acx_text2int(text); +-- implicit-format element coercion (a cast function): stays local, and the +-- coercion is not silently dropped from an otherwise pushed-down qual +CREATE CAST (integer AS text) WITH FUNCTION pg_catalog.to_hex(integer) AS IMPLICIT; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT id FROM ft_acx WHERE t = ANY (ia); +DROP CAST (integer AS text); +-- element coercion via a GUC-sensitive I/O conversion: stays local, so the +-- result matches local evaluation despite the forced remote extra_float_digits +SET extra_float_digits = 0; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT id FROM ft_acx WHERE f8::text[] = txt; +SELECT id FROM ft_acx WHERE f8::text[] = txt; +RESET extra_float_digits; +-- a plain relabeling element coercion (varchar[] to text[]) is still pushed down +EXPLAIN (VERBOSE, COSTS OFF) +SELECT id FROM ft_acx WHERE t = ANY (vc); +SELECT id FROM ft_acx WHERE t = ANY (vc); +DROP FOREIGN TABLE ft_acx; +DROP TABLE loct_acx; + -- a regconfig constant referring to this text search configuration -- is initially unshippable CREATE TEXT SEARCH CONFIGURATION public.custom_search From b464e498cebe34da006575672caeabced1718927 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 15 Jul 2026 08:05:08 +0900 Subject: [PATCH 146/481] Revert "Rename routines for write/read of pgstats file" This reverts commit ed823da1289, that has made pgstat_write_chunk() and pgstat_read_chunk() available for public use. These routines do not have a symmetric API definition across reads and writes, with the write part returning a void status, deferring an error detection once all the stats entries have been processed with an ferror(), and the read part returning a boolean status. These routines are just tiny wrappers around fread() and fwrite(), and extensions can just define they own routines instead of relying on the same facilities as the core pgstat.c. This commit removes their declaration from the public headers, to reduce the confusion. test_custom_stats is updated to use its own read/write routines. Perhaps something better could be designed in the future; trying to do so for v19 is not feasable during beta. Reported-by: Peter Eisentraut Author: Sami Imseih Discussion: https://postgr.es/m/a4a8e9af-3eaf-4bbf-9b21-21620f3fc434@eisentraut.org Backpatch-through: 19 --- src/backend/utils/activity/pgstat.c | 55 ++++++++++--------- src/include/utils/pgstat_internal.h | 5 -- .../test_custom_stats/test_custom_var_stats.c | 28 ++++++---- 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c index c4fa14f138f..9c82081f4c5 100644 --- a/src/backend/utils/activity/pgstat.c +++ b/src/backend/utils/activity/pgstat.c @@ -1595,15 +1595,18 @@ pgstat_assert_is_up(void) * ------------------------------------------------------------ */ -/* helper for pgstat_write_statsfile() */ -void -pgstat_write_chunk(FILE *fpout, void *ptr, size_t len) +#define write_chunk_s(fpout, ptr) write_chunk(fpout, ptr, sizeof(*ptr)) +#define read_chunk_s(fpin, ptr) read_chunk(fpin, ptr, sizeof(*ptr)) + +/* helpers for pgstat_write_statsfile() */ +static void +write_chunk(FILE *fpout, void *ptr, size_t len) { int rc; rc = fwrite(ptr, len, 1, fpout); - /* We check for errors with ferror() when done writing the stats. */ + /* we'll check for errors with ferror once at the end */ (void) rc; } @@ -1648,7 +1651,7 @@ pgstat_write_statsfile(void) * Write the file header --- currently just a format ID. */ format_id = PGSTAT_FILE_FORMAT_ID; - pgstat_write_chunk_s(fpout, &format_id); + write_chunk_s(fpout, &format_id); /* Write various stats structs for fixed number of objects */ for (PgStat_Kind kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++) @@ -1673,8 +1676,8 @@ pgstat_write_statsfile(void) ptr = pgStatLocal.snapshot.custom_data[kind - PGSTAT_KIND_CUSTOM_MIN]; fputc(PGSTAT_FILE_ENTRY_FIXED, fpout); - pgstat_write_chunk_s(fpout, &kind); - pgstat_write_chunk(fpout, ptr, info->shared_data_len); + write_chunk_s(fpout, &kind); + write_chunk(fpout, ptr, info->shared_data_len); } /* @@ -1728,7 +1731,7 @@ pgstat_write_statsfile(void) { /* normal stats entry, identified by PgStat_HashKey */ fputc(PGSTAT_FILE_ENTRY_HASH, fpout); - pgstat_write_chunk_s(fpout, &ps->key); + write_chunk_s(fpout, &ps->key); } else { @@ -1738,14 +1741,14 @@ pgstat_write_statsfile(void) kind_info->to_serialized_name(&ps->key, shstats, &name); fputc(PGSTAT_FILE_ENTRY_NAME, fpout); - pgstat_write_chunk_s(fpout, &ps->key.kind); - pgstat_write_chunk_s(fpout, &name); + write_chunk_s(fpout, &ps->key.kind); + write_chunk_s(fpout, &name); } /* Write except the header part of the entry */ - pgstat_write_chunk(fpout, - pgstat_get_entry_data(ps->key.kind, shstats), - pgstat_get_entry_len(ps->key.kind)); + write_chunk(fpout, + pgstat_get_entry_data(ps->key.kind, shstats), + pgstat_get_entry_len(ps->key.kind)); /* Write more data for the entry, if required */ if (kind_info->to_serialized_data) @@ -1756,7 +1759,7 @@ pgstat_write_statsfile(void) /* * No more output to be done. Close the temp file and replace the old * pgstat.stat with it. The ferror() check replaces testing for error - * after each individual fputc or fwrite (in pgstat_write_chunk()) above. + * after each individual fputc or fwrite (in write_chunk()) above. */ fputc(PGSTAT_FILE_ENTRY_END, fpout); @@ -1793,9 +1796,9 @@ pgstat_write_statsfile(void) } } -/* helper for pgstat_read_statsfile() */ -bool -pgstat_read_chunk(FILE *fpin, void *ptr, size_t len) +/* helpers for pgstat_read_statsfile() */ +static bool +read_chunk(FILE *fpin, void *ptr, size_t len) { return fread(ptr, 1, len, fpin) == len; } @@ -1843,7 +1846,7 @@ pgstat_read_statsfile(void) /* * Verify it's of the expected format. */ - if (!pgstat_read_chunk_s(fpin, &format_id)) + if (!read_chunk_s(fpin, &format_id)) { elog(WARNING, "could not read format ID"); goto error; @@ -1873,7 +1876,7 @@ pgstat_read_statsfile(void) char *ptr; /* entry for fixed-numbered stats */ - if (!pgstat_read_chunk_s(fpin, &kind)) + if (!read_chunk_s(fpin, &kind)) { elog(WARNING, "could not read stats kind for entry of type %c", t); goto error; @@ -1913,7 +1916,7 @@ pgstat_read_statsfile(void) info->shared_data_off; } - if (!pgstat_read_chunk(fpin, ptr, info->shared_data_len)) + if (!read_chunk(fpin, ptr, info->shared_data_len)) { elog(WARNING, "could not read data of stats kind %u for entry of type %c with size %u", kind, t, info->shared_data_len); @@ -1935,7 +1938,7 @@ pgstat_read_statsfile(void) if (t == PGSTAT_FILE_ENTRY_HASH) { /* normal stats entry, identified by PgStat_HashKey */ - if (!pgstat_read_chunk_s(fpin, &key)) + if (!read_chunk_s(fpin, &key)) { elog(WARNING, "could not read key for entry of type %c", t); goto error; @@ -1964,12 +1967,12 @@ pgstat_read_statsfile(void) PgStat_Kind kind; NameData name; - if (!pgstat_read_chunk_s(fpin, &kind)) + if (!read_chunk_s(fpin, &kind)) { elog(WARNING, "could not read stats kind for entry of type %c", t); goto error; } - if (!pgstat_read_chunk_s(fpin, &name)) + if (!read_chunk_s(fpin, &name)) { elog(WARNING, "could not read name of stats kind %u for entry of type %c", kind, t); @@ -2044,9 +2047,9 @@ pgstat_read_statsfile(void) key.objid, t); } - if (!pgstat_read_chunk(fpin, - pgstat_get_entry_data(key.kind, header), - pgstat_get_entry_len(key.kind))) + if (!read_chunk(fpin, + pgstat_get_entry_data(key.kind, header), + pgstat_get_entry_len(key.kind))) { elog(WARNING, "could not read data for entry %u/%u/%" PRIu64 " of type %c", key.kind, key.dboid, diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h index 3ca4f454895..cb73ec1f8e4 100644 --- a/src/include/utils/pgstat_internal.h +++ b/src/include/utils/pgstat_internal.h @@ -885,11 +885,6 @@ extern PGDLLIMPORT bool pgstat_report_fixed; /* Backend-local stats state */ extern PGDLLIMPORT PgStat_LocalState pgStatLocal; -/* Helper functions for reading and writing of on-disk stats file */ -extern void pgstat_write_chunk(FILE *fpout, void *ptr, size_t len); -extern bool pgstat_read_chunk(FILE *fpin, void *ptr, size_t len); -#define pgstat_read_chunk_s(fpin, ptr) pgstat_read_chunk(fpin, ptr, sizeof(*ptr)) -#define pgstat_write_chunk_s(fpout, ptr) pgstat_write_chunk(fpout, ptr, sizeof(*ptr)) /* * Implementation of inline functions declared above. diff --git a/src/test/modules/test_custom_stats/test_custom_var_stats.c b/src/test/modules/test_custom_stats/test_custom_var_stats.c index 024dae85a45..34d474be604 100644 --- a/src/test/modules/test_custom_stats/test_custom_var_stats.c +++ b/src/test/modules/test_custom_stats/test_custom_var_stats.c @@ -25,6 +25,12 @@ PG_MODULE_MAGIC_EXT( .version = PG_VERSION ); +/* Local helpers for stats file I/O */ +#define write_chunk(fpout, ptr, len) ((void) fwrite(ptr, len, 1, fpout)) +#define write_chunk_s(fpout, ptr) write_chunk(fpout, ptr, sizeof(*ptr)) +#define read_chunk(fpin, ptr, len) (fread(ptr, 1, len, fpin) == (len)) +#define read_chunk_s(fpin, ptr) read_chunk(fpin, ptr, sizeof(*ptr)) + #define TEST_CUSTOM_VAR_MAGIC_NUMBER (0xBEEFBEEF) /*-------------------------------------------------------------------------- @@ -202,7 +208,7 @@ test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, * First mark the main file with a magic number, keeping a trace that some * auxiliary data will exist in the secondary statistics file. */ - pgstat_write_chunk_s(statfile, &magic_number); + write_chunk_s(statfile, &magic_number); /* Open statistics file for writing. */ if (!fd_description) @@ -222,14 +228,14 @@ test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, } /* Write offset to the main data file */ - pgstat_write_chunk_s(statfile, &fd_description_offset); + write_chunk_s(statfile, &fd_description_offset); /* * First write the entry key to the secondary statistics file. This will * be cross-checked with the key read from main stats file at loading * time. */ - pgstat_write_chunk_s(fd_description, (PgStat_HashKey *) key); + write_chunk_s(fd_description, (PgStat_HashKey *) key); fd_description_offset += sizeof(PgStat_HashKey); if (!custom_stats_description_dsa) @@ -240,7 +246,7 @@ test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, { /* length to description file */ len = 0; - pgstat_write_chunk_s(fd_description, &len); + write_chunk_s(fd_description, &len); fd_description_offset += sizeof(size_t); return; } @@ -252,8 +258,8 @@ test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, description = dsa_get_address(custom_stats_description_dsa, entry->description); len = strlen(description) + 1; - pgstat_write_chunk_s(fd_description, &len); - pgstat_write_chunk(fd_description, description, len); + write_chunk_s(fd_description, &len); + write_chunk(fd_description, description, len); /* * Update offset for next entry, counting for the length (size_t) of the @@ -287,7 +293,7 @@ test_custom_stats_var_from_serialized_data(const PgStat_HashKey *key, PgStat_HashKey file_key; /* Check the magic number first, in the main file. */ - if (!pgstat_read_chunk_s(statfile, &magic_number)) + if (!read_chunk_s(statfile, &magic_number)) { elog(WARNING, "failed to read magic number from statistics file"); return false; @@ -304,7 +310,7 @@ test_custom_stats_var_from_serialized_data(const PgStat_HashKey *key, * Read the offset from the main stats file, to be able to read the * auxiliary data from the secondary statistics file. */ - if (!pgstat_read_chunk_s(statfile, &offset)) + if (!read_chunk_s(statfile, &offset)) { elog(WARNING, "failed to read metadata offset from statistics file"); return false; @@ -335,7 +341,7 @@ test_custom_stats_var_from_serialized_data(const PgStat_HashKey *key, } /* Read the hash key from the secondary statistics file */ - if (!pgstat_read_chunk_s(fd_description, &file_key)) + if (!read_chunk_s(fd_description, &file_key)) { elog(WARNING, "failed to read hash key from file"); return false; @@ -355,7 +361,7 @@ test_custom_stats_var_from_serialized_data(const PgStat_HashKey *key, entry = (PgStatShared_CustomVarEntry *) header; /* Read the description length and its data */ - if (!pgstat_read_chunk_s(fd_description, &len)) + if (!read_chunk_s(fd_description, &len)) { elog(WARNING, "failed to read metadata length from statistics file"); return false; @@ -379,7 +385,7 @@ test_custom_stats_var_from_serialized_data(const PgStat_HashKey *key, } buffer = palloc(len); - if (!pgstat_read_chunk(fd_description, buffer, len)) + if (!read_chunk(fd_description, buffer, len)) { pfree(buffer); elog(WARNING, "failed to read description from file"); From aae47813a14d1f5638469bda146d7839e39b7097 Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Wed, 15 Jul 2026 09:20:35 +0900 Subject: [PATCH 147/481] Strip removed-relation references from PHVs in join clauses Commit 9a60f295b stripped the stale PlaceHolderVars left behind by left-join removal from the surviving rels' baserestrictinfo and from EquivalenceClass member expressions, but it overlooked join clauses. A PlaceHolderVar embedded in a join clause can likewise retain the removed rel and join in its phrels, since remove_rel_from_query() fixes up the RestrictInfo's own relid sets but not the PHVs inside its expression. As before, this is normally harmless, because later processing consults those relid sets rather than the embedded PHVs. However, a restriction clause derived from such an OR join clause inherits the stale PlaceHolderVar, and when the derived clause is translated for an appendrel child, pull_varnos() recomputes its relids and folds the removed relation back in. The rebuilt clause then references a no-longer-existent relation, tripping an assertion during path generation. Fix by also stripping the removed relation from the PlaceHolderVars in the surviving rels' join clauses, including the sub-clauses of any OR clause. Like 9a60f295b, this is only reachable on v18 and later, where match_index_to_operand() began ignoring PlaceHolderVars. Author: Arne Roland Reviewed-by: Tender Wang Reviewed-by: Richard Guo Discussion: https://postgr.es/m/27a44087-3d65-473e-8d88-7c12228e0d7e@malkut.net Backpatch-through: 18 --- src/backend/optimizer/plan/analyzejoins.c | 78 +++++++++++++++++++++-- src/test/regress/expected/join.out | 12 ++++ src/test/regress/sql/join.sql | 7 ++ 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c index f109af25d72..881950e5264 100644 --- a/src/backend/optimizer/plan/analyzejoins.c +++ b/src/backend/optimizer/plan/analyzejoins.c @@ -64,6 +64,8 @@ static void remove_rel_from_restrictinfo(RestrictInfo *rinfo, int relid, int ojrelid); static void remove_rel_from_eclass(PlannerInfo *root, EquivalenceClass *ec, int relid, int ojrelid); +static void remove_rel_from_restrictinfo_phvs(RestrictInfo *rinfo, + int relid, int ojrelid); static Node *remove_rel_from_phvs(Node *node, int relid, int ojrelid); static Node *remove_rel_from_phvs_mutator(Node *node, Relids removable); static List *remove_rel_from_joinlist(List *joinlist, int relid, int *nremoved); @@ -457,6 +459,7 @@ remove_rel_from_query(PlannerInfo *root, int relid, ListCell *l; bool is_outer_join = (sjinfo != NULL); bool is_self_join = (!is_outer_join && subst > 0); + Bitmapset *seen_serials = NULL; Assert(is_outer_join || is_self_join); Assert(!is_outer_join || ojrelid > 0); @@ -644,9 +647,9 @@ remove_rel_from_query(PlannerInfo *root, int relid, * lateral_vars lists. * * Also, for left-join removal, we strip the removed rel and join from any - * PlaceHolderVar embedded in the surviving rels' restriction clauses (see - * remove_rel_from_phvs); we needn't bother with the rel being removed, - * nor when the query has no PlaceHolderVars. + * PlaceHolderVar embedded in the surviving rels' restriction clauses and + * join clauses; we needn't bother with the rel being removed, nor when + * the query has no PlaceHolderVars. */ for (rti = 1; rti < root->simple_rel_array_size; rti++) { @@ -676,9 +679,27 @@ remove_rel_from_query(PlannerInfo *root, int relid, if (is_outer_join && rti != relid && root->glob->lastPHId != 0) { foreach_node(RestrictInfo, rinfo, otherrel->baserestrictinfo) + remove_rel_from_restrictinfo_phvs(rinfo, relid, ojrelid); + + /* + * Join clauses need the same treatment, but there's no value in + * processing any join clause more than once. So it's slightly + * annoying that we have to find them via the per-base-relation + * joininfo lists. Avoid duplicate processing by tracking the + * rinfo_serial numbers of join clauses we've already seen. (This + * doesn't work for is_clone clauses, so we must waste effort on + * them.) + */ + foreach_node(RestrictInfo, rinfo, otherrel->joininfo) { - rinfo->clause = (Expr *) - remove_rel_from_phvs((Node *) rinfo->clause, relid, ojrelid); + if (!rinfo->is_clone) /* else serial number is not unique */ + { + if (bms_is_member(rinfo->rinfo_serial, seen_serials)) + continue; /* saw it already */ + seen_serials = bms_add_member(seen_serials, + rinfo->rinfo_serial); + } + remove_rel_from_restrictinfo_phvs(rinfo, relid, ojrelid); } } } @@ -844,6 +865,53 @@ remove_rel_from_eclass(PlannerInfo *root, EquivalenceClass *ec, ec_clear_derived_clauses(ec); } +/* + * Remove any references to relid or ojrelid from the PlaceHolderVars embedded + * in a RestrictInfo's clause. + * + * If it's an OR clause, we must also fix up the orclause, which is a parallel + * representation built from its own sub-RestrictInfos. We recurse into the + * sub-clauses for that, mirroring remove_rel_from_restrictinfo. + */ +static void +remove_rel_from_restrictinfo_phvs(RestrictInfo *rinfo, int relid, int ojrelid) +{ + rinfo->clause = (Expr *) + remove_rel_from_phvs((Node *) rinfo->clause, relid, ojrelid); + + /* If it's an OR, recurse to clean up sub-clauses */ + if (restriction_is_or_clause(rinfo)) + { + ListCell *lc; + + Assert(is_orclause(rinfo->orclause)); + foreach(lc, ((BoolExpr *) rinfo->orclause)->args) + { + Node *orarg = (Node *) lfirst(lc); + + /* OR arguments should be ANDs or sub-RestrictInfos */ + if (is_andclause(orarg)) + { + List *andargs = ((BoolExpr *) orarg)->args; + ListCell *lc2; + + foreach(lc2, andargs) + { + RestrictInfo *rinfo2 = lfirst_node(RestrictInfo, lc2); + + remove_rel_from_restrictinfo_phvs(rinfo2, relid, ojrelid); + } + } + else + { + RestrictInfo *rinfo2 = castNode(RestrictInfo, orarg); + + remove_rel_from_restrictinfo_phvs(rinfo2, relid, ojrelid); + } + } + } +} + /* * Remove any references to the specified RT index(es) from the phrels (and * phnullingrels) of every PlaceHolderVar in the given expression. diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index ed946abed7f..83bd5649d5c 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -6586,6 +6586,18 @@ group by (); Replaces: Aggregate (2 rows) +-- likewise for a PHV embedded in an OR join clause +explain (costs off) +select 1 from parted_b t1 + join (select t2.id from parted_b t2 left join parted_b t3 on t2.id = t3.id) s + on (t1.id = 1 and s.id = 2) or (t1.id = 3 and s.id = 4) +group by (); + QUERY PLAN +----------------------- + Result + Replaces: Aggregate +(2 rows) + rollback; create temp table parent (k int primary key, pd int); create temp table child (k int unique, cd int); diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index 78f7b4f544d..32d4a5a677e 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -2432,6 +2432,13 @@ select 1 from parted_b t1 on t1.id = s.id group by (); +-- likewise for a PHV embedded in an OR join clause +explain (costs off) +select 1 from parted_b t1 + join (select t2.id from parted_b t2 left join parted_b t3 on t2.id = t3.id) s + on (t1.id = 1 and s.id = 2) or (t1.id = 3 and s.id = 4) +group by (); + rollback; create temp table parent (k int primary key, pd int); From 31d04313c1163497f4c6f4f64fad2359cbbab149 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 15 Jul 2026 10:03:38 +0900 Subject: [PATCH 148/481] Include check on polpermissive relcache for policies equalPolicy() is used in the relation cache to check if two policy definitions are equivalent, but missed to check for polpermissive. ALTER POLICY cannot switch a policy to be PERMISSIVE or RESTRICTIVE, so this would need a dropped and then re-created policy, which would trigger a relcache invalidation. Anyway, there is no harm in being consistent in the check, and if one decides to add an ALTER POLICY to switch PERMISSIVE or RESTRICTIVE, we would be silently in trouble. Author: Andreas Lind Reviewed-by: Laurenz Albe Discussion: https://postgr.es/m/CAMxA3rv1CS6R7JR5ojz-3CmCEnZEFrqu+XXTnGbLRWrjJRH7sA@mail.gmail.com Backpatch-through: 14 --- src/backend/utils/cache/relcache.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index fb4e042be8a..19c4ff6e75e 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -980,6 +980,8 @@ equalPolicy(RowSecurityPolicy *policy1, RowSecurityPolicy *policy2) if (policy1->polcmd != policy2->polcmd) return false; + if (policy1->permissive != policy2->permissive) + return false; if (policy1->hassublinks != policy2->hassublinks) return false; if (strcmp(policy1->policy_name, policy2->policy_name) != 0) From 0892319c65e7d7458ee8fb902618491aaa0e4734 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 15 Jul 2026 10:35:19 +0900 Subject: [PATCH 149/481] Rework pgstat_write_statsfile() in combination with to_serialized_data Contrary to the from_serialized_data callback used by the pgstats reads at startup, the to_serialized_data callback used for the pgstats writes matched with pgstat_write_statsfile(), by not returning a boolean status, expecting a ferror() failure to deal with the discard of the stats file should an error happen while writing the stats. This was slightly confusing designed this way. Things are changed in this commit with: - to_serialized_data now returns a boolean status on a write failure. pgstat_write_statsfile() detects that and switches to failure mode instead of continuing to process the entries to write, speeding up the shutdown. - pgstat_write_statsfile() now uses STATS_DISCARD if a failure happens, to let the registered callbacks directly know that something is wrong, and that things need to be cleaned up. This gives a better error path detection for custom stats kinds. For example, they do not have to rely solely on the expectation of an ferror() for an auxiliary file. This new set of behaviors matches with what is already done in pgstat_read_statsfile() for the finish() callback (DISCARD on failure, READ on success) and the from_serialized_data with a status returned. Author: Sami Imseih Discussion: https://postgr.es/m/CAA5RZ0sMgOvuhpb2P=KSJOjgjC6AfUu+GYcu9mHar-y_Xtd=Pg@mail.gmail.com Backpatch-through: 19 --- src/backend/utils/activity/pgstat.c | 34 +++++++++++++++---- src/include/utils/pgstat_internal.h | 5 +-- .../test_custom_stats/test_custom_var_stats.c | 29 ++++++++++------ 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c index 9c82081f4c5..5926c0c8b9c 100644 --- a/src/backend/utils/activity/pgstat.c +++ b/src/backend/utils/activity/pgstat.c @@ -1623,6 +1623,7 @@ pgstat_write_statsfile(void) const char *statfile = PGSTAT_STAT_PERMANENT_FILENAME; dshash_seq_status hstat; PgStatShared_HashEntry *ps; + PgStat_StatsFileOp status = STATS_WRITE; pgstat_assert_is_up(); @@ -1751,8 +1752,12 @@ pgstat_write_statsfile(void) pgstat_get_entry_len(ps->key.kind)); /* Write more data for the entry, if required */ - if (kind_info->to_serialized_data) - kind_info->to_serialized_data(&ps->key, shstats, fpout); + if (kind_info->to_serialized_data && + !kind_info->to_serialized_data(&ps->key, shstats, fpout)) + { + status = STATS_DISCARD; + break; + } } dshash_seq_term(&hstat); @@ -1763,7 +1768,17 @@ pgstat_write_statsfile(void) */ fputc(PGSTAT_FILE_ENTRY_END, fpout); - if (ferror(fpout)) + if (status == STATS_DISCARD) + { + /* + * A to_serialized_data callback failed. DEBUG2 because the callback + * already logged the reason. + */ + elog(DEBUG2, "discarding temporary statistics file \"%s\"", tmpfile); + FreeFile(fpout); + unlink(tmpfile); + } + else if (ferror(fpout)) { ereport(LOG, (errcode_for_file_access(), @@ -1771,6 +1786,7 @@ pgstat_write_statsfile(void) tmpfile))); FreeFile(fpout); unlink(tmpfile); + status = STATS_DISCARD; } else if (FreeFile(fpout) < 0) { @@ -1779,11 +1795,13 @@ pgstat_write_statsfile(void) errmsg("could not close temporary statistics file \"%s\": %m", tmpfile))); unlink(tmpfile); + status = STATS_DISCARD; } else if (durable_rename(tmpfile, statfile, LOG) < 0) { /* durable_rename already emitted log message */ unlink(tmpfile); + status = STATS_DISCARD; } /* Finish callbacks, if required */ @@ -1792,7 +1810,7 @@ pgstat_write_statsfile(void) const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind); if (kind_info && kind_info->finish) - kind_info->finish(STATS_WRITE); + kind_info->finish(status); } } @@ -1815,6 +1833,7 @@ pgstat_read_statsfile(void) FILE *fpin; int32 format_id; bool found; + PgStat_StatsFileOp status = STATS_READ; const char *statfile = PGSTAT_STAT_PERMANENT_FILENAME; PgStat_ShmemControl *shmem = pgStatLocal.shmem; @@ -1840,7 +1859,8 @@ pgstat_read_statsfile(void) errmsg("could not open statistics file \"%s\": %m", statfile))); pgstat_reset_after_failure(); - return; + status = STATS_DISCARD; + goto finish; } /* @@ -2098,13 +2118,14 @@ pgstat_read_statsfile(void) elog(DEBUG2, "removing permanent stats file \"%s\"", statfile); unlink(statfile); +finish: /* Finish callbacks, if required */ for (PgStat_Kind kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++) { const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind); if (kind_info && kind_info->finish) - kind_info->finish(STATS_READ); + kind_info->finish(status); } return; @@ -2114,6 +2135,7 @@ pgstat_read_statsfile(void) (errmsg("corrupted statistics file \"%s\"", statfile))); pgstat_reset_after_failure(); + status = STATS_DISCARD; goto done; } diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h index cb73ec1f8e4..14aeb710291 100644 --- a/src/include/utils/pgstat_internal.h +++ b/src/include/utils/pgstat_internal.h @@ -322,7 +322,8 @@ typedef struct PgStat_KindInfo * an entry, in the stats file or optionally in a different file. * Optional. * - * to_serialized_data: write auxiliary data for an entry. + * to_serialized_data: write auxiliary data for an entry. Returns true on + * success, false on write error. * * from_serialized_data: read auxiliary data for an entry. Returns true * on success, false on read error. @@ -332,7 +333,7 @@ typedef struct PgStat_KindInfo * just written or read. "header" is a pointer to the stats data; it may * be modified only in from_serialized_data to reconstruct an entry. */ - void (*to_serialized_data) (const PgStat_HashKey *key, + bool (*to_serialized_data) (const PgStat_HashKey *key, const PgStatShared_Common *header, FILE *statfile); bool (*from_serialized_data) (const PgStat_HashKey *key, diff --git a/src/test/modules/test_custom_stats/test_custom_var_stats.c b/src/test/modules/test_custom_stats/test_custom_var_stats.c index 34d474be604..a39ada0b67c 100644 --- a/src/test/modules/test_custom_stats/test_custom_var_stats.c +++ b/src/test/modules/test_custom_stats/test_custom_var_stats.c @@ -26,7 +26,7 @@ PG_MODULE_MAGIC_EXT( ); /* Local helpers for stats file I/O */ -#define write_chunk(fpout, ptr, len) ((void) fwrite(ptr, len, 1, fpout)) +#define write_chunk(fpout, ptr, len) (fwrite(ptr, len, 1, fpout) == 1) #define write_chunk_s(fpout, ptr) write_chunk(fpout, ptr, sizeof(*ptr)) #define read_chunk(fpin, ptr, len) (fread(ptr, 1, len, fpin) == (len)) #define read_chunk_s(fpin, ptr) read_chunk(fpin, ptr, sizeof(*ptr)) @@ -94,7 +94,7 @@ static bool test_custom_stats_var_flush_pending_cb(PgStat_EntryRef *entry_ref, bool nowait); /* Serialization callback: write auxiliary entry data */ -static void test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, +static bool test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, const PgStatShared_Common *header, FILE *statfile); @@ -193,7 +193,7 @@ test_custom_stats_var_flush_pending_cb(PgStat_EntryRef *entry_ref, bool nowait) * - The length of the description. * - The description data itself. */ -static void +static bool test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, const PgStatShared_Common *header, FILE *statfile) @@ -208,7 +208,8 @@ test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, * First mark the main file with a magic number, keeping a trace that some * auxiliary data will exist in the secondary statistics file. */ - write_chunk_s(statfile, &magic_number); + if (!write_chunk_s(statfile, &magic_number)) + return false; /* Open statistics file for writing. */ if (!fd_description) @@ -220,7 +221,7 @@ test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, (errcode_for_file_access(), errmsg("could not open statistics file \"%s\" for writing: %m", TEST_CUSTOM_AUX_DATA_DESC))); - return; + return false; } /* Initialize offset for secondary statistics file. */ @@ -228,14 +229,16 @@ test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, } /* Write offset to the main data file */ - write_chunk_s(statfile, &fd_description_offset); + if (!write_chunk_s(statfile, &fd_description_offset)) + return false; /* * First write the entry key to the secondary statistics file. This will * be cross-checked with the key read from main stats file at loading * time. */ - write_chunk_s(fd_description, (PgStat_HashKey *) key); + if (!write_chunk_s(fd_description, (PgStat_HashKey *) key)) + return false; fd_description_offset += sizeof(PgStat_HashKey); if (!custom_stats_description_dsa) @@ -246,9 +249,10 @@ test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, { /* length to description file */ len = 0; - write_chunk_s(fd_description, &len); + if (!write_chunk_s(fd_description, &len)) + return false; fd_description_offset += sizeof(size_t); - return; + return true; } /* @@ -258,14 +262,17 @@ test_custom_stats_var_to_serialized_data(const PgStat_HashKey *key, description = dsa_get_address(custom_stats_description_dsa, entry->description); len = strlen(description) + 1; - write_chunk_s(fd_description, &len); - write_chunk(fd_description, description, len); + if (!write_chunk_s(fd_description, &len)) + return false; + if (!write_chunk(fd_description, description, len)) + return false; /* * Update offset for next entry, counting for the length (size_t) of the * description and the description contents. */ fd_description_offset += len + sizeof(size_t); + return true; } /* From 49d250b3d6884a693eacaefb3e08799e7c25f7f0 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 15 Jul 2026 05:13:39 -0400 Subject: [PATCH 150/481] doc PG 19 relnotes: remove duplicate word Backpatch-through: 19 --- doc/src/sgml/release-19.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/release-19.sgml b/doc/src/sgml/release-19.sgml index d8d3758d5ba..463015cf881 100644 --- a/doc/src/sgml/release-19.sgml +++ b/doc/src/sgml/release-19.sgml @@ -2360,7 +2360,7 @@ Author: Jacob Champion -Allow custom OAUTH validators to register custom pg_hba.conf authentication options (Jacob Champion) +Allow OAUTH validators to register custom pg_hba.conf authentication options (Jacob Champion) § From aa9787e325df8a864cd29dac2fcfdaaf02b6b8ed Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 15 Jul 2026 05:36:00 -0400 Subject: [PATCH 151/481] doc PG 19 relnotes: "OAUTH validators to supply failure item" Moved to source code section. Reported-by: Andreas Karlsson Discussion: https://postgr.es/m/f5f129c3-88fa-43dc-a23a-75155fa10be3@proxel.se Backpatch-through: 19 only --- doc/src/sgml/release-19.sgml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/doc/src/sgml/release-19.sgml b/doc/src/sgml/release-19.sgml index 463015cf881..238ff10226f 100644 --- a/doc/src/sgml/release-19.sgml +++ b/doc/src/sgml/release-19.sgml @@ -2365,22 +2365,6 @@ Allow OAUTH validators to register custom § - - - -This is done by setting the ValidatorModuleResult structure member error_detail. - - - + + + +Allow OAUTH validators to supply failure details (Jacob Champion) +§ + + + +This is done by setting the ValidatorModuleResult structure member error_detail. + + + -Add a new OAUTH flow hook PQAUTHDATA_OAUTH_BEARER_TOKEN_V2 (Jacob Champion) -§ -§ +Allow OAUTH validators to supply failure details (Jacob Champion) +§ -This is an improved version of PQAUTHDATA_OAUTH_BEARER_TOKEN by adding the issuer identifier and error message specification. +This is done by setting the ValidatorModuleResult structure member error_detail. @@ -2961,17 +2958,20 @@ Allow extensions to replace se -Allow OAUTH validators to supply failure details (Jacob Champion) -§ +Add a new OAUTH flow hook PQAUTHDATA_OAUTH_BEARER_TOKEN_V2 (Jacob Champion) +§ +§ -This is done by setting the ValidatorModuleResult structure member error_detail. +This is an improved version of PQAUTHDATA_OAUTH_BEARER_TOKEN by adding the issuer identifier and error message specification. From 928ed9b653e968ddb559a3fde7ff9a84b08f1196 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Wed, 15 Jul 2026 15:47:35 +0530 Subject: [PATCH 153/481] Reject concurrent sequence refreshes. 'ALTER SUBSCRIPTION ... REFRESH SEQUENCES' can race with an already running sequence synchronization worker. If a second refresh request resets the synchronization state while the worker has already fetched sequence values from the publisher but has not yet applied them to the subscriber, the worker can overwrite the subscriber with stale values and mark the synchronization as complete. Avoid this race by rejecting 'ALTER SUBSCRIPTION ... REFRESH SEQUENCES' when a sequence synchronization worker is already running for the subscription. The command reports an error asking the user to rerun it after the current synchronization completes. Also add a wait for the re-added 'regress_s4' sequence to finish synchronizing in 036_sequences.pl, so the subsequent test does not race against its sequencesync worker. Reported-by: Noah Misch Author: vignesh C Reviewed-by: Shveta Malik Reviewed-by: Hayato Kuroda Reviewed-by: Amit Kapila Backpatch-through: 19, where it was introduced Discussion: https://postgr.es/m/20260710045217.f0.noahmisch@microsoft.com --- src/backend/commands/subscriptioncmds.c | 27 ++++++++++++++++++++++++ src/test/subscription/t/036_sequences.pl | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index ee06a726f42..94b163cccc9 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -1304,6 +1304,33 @@ AlterSubscription_refresh_seq(Subscription *sub) WalReceiverConn *wrconn; bool must_use_password; + /* + * Disallow a concurrent REFRESH SEQUENCES while a sequence sync worker + * for this subscription is still running. This avoids a race where the + * publisher's sequence advances after the current worker has fetched its + * value but before it marks the sequence READY. A user may then issue + * another REFRESH SEQUENCES to synchronize the updated value. Since the + * affected sequences are already in the INIT state, the running worker + * has no indication that a new synchronization has been requested. It + * would then apply the stale value it already fetched and mark the + * sequence READY, causing the new synchronization request to be lost and + * preventing the updated publisher values from being synchronized. + */ + LWLockAcquire(LogicalRepWorkerLock, LW_SHARED); + if (logicalrep_worker_find(WORKERTYPE_SEQUENCESYNC, sub->oid, InvalidOid, + true)) + { + LWLockRelease(LogicalRepWorkerLock); + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + /* translator: %s is an SQL ALTER command */ + errmsg("cannot execute %s while a sequence synchronization worker is running", + "ALTER SUBSCRIPTION ... REFRESH SEQUENCES"), + errhint("Try again after the current synchronization completes.")); + } + + LWLockRelease(LogicalRepWorkerLock); + /* Load the library providing us libpq calls. */ load_file("libpqwalreceiver", false); diff --git a/src/test/subscription/t/036_sequences.pl b/src/test/subscription/t/036_sequences.pl index 2a0819aaf01..8b02b24a7e9 100644 --- a/src/test/subscription/t/036_sequences.pl +++ b/src/test/subscription/t/036_sequences.pl @@ -232,6 +232,10 @@ CREATE SEQUENCE regress_s4 START 10 INCREMENT 2; )); +# Wait for the missing sequence added to be synced +$node_subscriber->poll_query_until('postgres', $synced_query) + or die "Timed out while waiting for subscriber to synchronize data"; + ########## # Ensure that insufficient privileges on the publisher for a sequence # are reported correctly as a permission issue, not as a missing sequence. From 173ea84dfdc96390ce37a3918aa660a15c4734a9 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 15 Jul 2026 21:22:38 +0900 Subject: [PATCH 154/481] Fix argument names in pg_clear_attribute_stats() errors pg_clear_attribute_stats() checks its required arguments manually because the function is not strict. Previously, when schemaname or relname was passed as NULL, the error incorrectly reported the argument name as "relation" in both cases: ERROR: argument "relation" must not be null This was misleading, especially for schemaname, and inconsistent with the function's SQL-visible argument names. The cause is that cleararginfo[] in attribute_stats.c used "relation" for both the schema-name and relation-name arguments. This commit fixes the issue by using "schemaname" and "relname" instead, matching the function's declared argument names so that the error reports the correct argument name. Backpatch to v18, where pg_clear_attribute_stats() was introduced. Author: Ilia Evdokimov Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/4bf66c5e-8dd7-4ef3-8691-db67ecff6f16@tantorlabs.com Backpatch-through: 18 --- src/backend/statistics/attribute_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c index c47df5adab3..c133b8ad6c9 100644 --- a/src/backend/statistics/attribute_stats.c +++ b/src/backend/statistics/attribute_stats.c @@ -97,8 +97,8 @@ enum clear_attribute_stats_argnum static struct StatsArgInfo cleararginfo[] = { - [C_ATTRELSCHEMA_ARG] = {"relation", TEXTOID}, - [C_ATTRELNAME_ARG] = {"relation", TEXTOID}, + [C_ATTRELSCHEMA_ARG] = {"schemaname", TEXTOID}, + [C_ATTRELNAME_ARG] = {"relname", TEXTOID}, [C_ATTNAME_ARG] = {"attname", TEXTOID}, [C_INHERITED_ARG] = {"inherited", BOOLOID}, [C_NUM_ATTRIBUTE_STATS_ARGS] = {0} From 95c1b8ec7773817d8626d0aad6e7424b3c5ef04d Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Wed, 15 Jul 2026 13:04:32 -0400 Subject: [PATCH 155/481] Add additional sanity checks when reading a blkreftable. Code elsewhere in the system assumes that fork numbers and chunk sizes are within bounds, so the code that reads those quantities from disk should validate that they are. Without these additional checks, a corrupted file can cause us to index off the end of fork number or chunk entry arrays, potentially resulting in a crash. Reported-by: oxsignal (chunk sizes) Reported-by: Robert Haas (fork numbers) Reviewed-by: Daniel Gustafsson Discussion: http://postgr.es/m/CA+TgmoYP8RKoBGosS7C6Fdr-GNCfyz_W1zmK=Tx1Fe0ZvzGh0g@mail.gmail.com Backpatch-through: 17 --- src/common/blkreftable.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/common/blkreftable.c b/src/common/blkreftable.c index 2bb91e39128..a166fcc0067 100644 --- a/src/common/blkreftable.c +++ b/src/common/blkreftable.c @@ -657,6 +657,15 @@ BlockRefTableReaderNextRelation(BlockRefTableReader *reader, return false; } + /* Sanity-check the fork number. */ + if (sentry.forknum < 0 || sentry.forknum > MAX_FORKNUM) + { + reader->error_callback(reader->error_callback_arg, + "file \"%s\" has invalid fork number %d", + reader->error_filename, sentry.forknum); + return false; + } + /* * Sanity-check the nchunks value. In the backend, palloc_array would * enforce this anyway (with a more generic error message); but in @@ -678,6 +687,19 @@ BlockRefTableReaderNextRelation(BlockRefTableReader *reader, BlockRefTableRead(reader, reader->chunk_size, sentry.nchunks * sizeof(uint16)); + /* Sanity-check the chunk sizes. */ + for (unsigned i = 0; i < sentry.nchunks; ++i) + { + if (reader->chunk_size[i] > MAX_ENTRIES_PER_CHUNK) + { + reader->error_callback(reader->error_callback_arg, + "file \"%s\" chunk %u has invalid size %u", + reader->error_filename, i, + (unsigned) reader->chunk_size[i]); + return false; + } + } + /* Set up for chunk scan. */ reader->total_chunks = sentry.nchunks; reader->consumed_chunks = 0; From 94e1b104f8db88837e5ef13a6692dad746e3690f Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 15 Jul 2026 12:34:20 -0700 Subject: [PATCH 156/481] Fix like_fixed_prefix_ci() selectivity. A wrong calculation introduced by 9c8de15969 could cause trailing characters from the prefix to be passed to like_selectivity() rather than just the "rest". Discussion: https://postgr.es/m/c7334a7a44243d2e4ec5e83747589908b3787491.camel@j-davis.com Backpatch-through: 19 --- src/backend/utils/adt/like_support.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/like_support.c b/src/backend/utils/adt/like_support.c index 4c8db9147ee..e354360a8e6 100644 --- a/src/backend/utils/adt/like_support.c +++ b/src/backend/utils/adt/like_support.c @@ -1150,12 +1150,12 @@ like_fixed_prefix_ci(Const *patt_const, Oid collation, Const **prefix_const, if (rest_selec != NULL) { - int wrestlen = wpattlen - wmatch_pos; + int wrestlen = wpattlen - wpos; char *rest; int rest_mblen; rest = palloc(pg_database_encoding_max_length() * wrestlen + 1); - rest_mblen = pg_wchar2mb_with_len(&wpatt[wmatch_pos], rest, wrestlen); + rest_mblen = pg_wchar2mb_with_len(&wpatt[wpos], rest, wrestlen); *rest_selec = like_selectivity(rest, rest_mblen, true); pfree(rest); From 04a6d65a763312fecae866e7240d3ea895bad329 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Wed, 15 Jul 2026 21:40:09 +0200 Subject: [PATCH 157/481] pgbench: Fix incorrect parameter name in error message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 6f164e6d17616 accidentally mistyped --client as --clients in the error message. Backpatch down to v15 where the it was introduced. Author: Semih Doğan Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CALOtZ7tuWisV=v0cUY_q6PLHJ-fOiQ7ZN476JwmM0PyV0t5i7Q@mail.gmail.com Backpatch-through: 15 --- src/bin/pgbench/pgbench.c | 2 +- src/bin/pgbench/t/002_pgbench_no_server.pl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index 0b2bb9340b5..a7dc9b0f75a 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -6871,7 +6871,7 @@ main(int argc, char **argv) break; case 'c': benchmarking_option_set = true; - if (!option_parse_int(optarg, "-c/--clients", 1, INT_MAX, + if (!option_parse_int(optarg, "-c/--client", 1, INT_MAX, &nclients)) { exit(1); diff --git a/src/bin/pgbench/t/002_pgbench_no_server.pl b/src/bin/pgbench/t/002_pgbench_no_server.pl index e694e9ef0f8..0e8d92f8abd 100644 --- a/src/bin/pgbench/t/002_pgbench_no_server.pl +++ b/src/bin/pgbench/t/002_pgbench_no_server.pl @@ -92,7 +92,7 @@ sub pgbench_scripts [ 'too many scripts', '-S ' x 129, [qr{at most 128 SQL scripts}] ], [ 'bad #clients', '-c three', - [qr{invalid value "three" for option -c/--clients}] + [qr{invalid value "three" for option -c/--client}] ], [ 'bad #threads', '-j eleven', From 7a103928a0986c6f9308a3bc476176fa6e1dd0c9 Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Wed, 15 Jul 2026 15:49:59 -0400 Subject: [PATCH 158/481] Include last block in FSM vacuum of bulk extended relation When bulk-extending a relation, we add the newly-added blocks that we won't immediately use to the free space map and then call FreeSpaceMapVacuumRange() to propagate that free space up the FSM tree, so other backends can find and reuse it. However, the end block argument to FreeSpaceMapVacuumRange() is exclusive, and we passed the number of the last added block (since 00d1e02be24). If that block was the first one covered by a new FSM page, its free space wasn't propagated up the tree and was therefore invisible to FSM searches until the next FSM vacuum. Fix by passing the block number one past the last added block, so the full range is vacuumed. Author: Jingtang Zhang Reviewed-by: Melanie Plageman Discussion: https://postgr.es/m/flat/CAPsk3_Bx_vdybN%3D-DZu8HLStf%2BXnuFUBkLwxouONSMkWuO9oug%40mail.gmail.com Backpatch-through: 16 --- src/backend/access/heap/hio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index e96e0f77d92..fb4ffb97592 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -401,7 +401,7 @@ RelationAddBlocks(Relation relation, BulkInsertState bistate, { BlockNumber first_fsm_block = first_block + not_in_fsm_pages; - FreeSpaceMapVacuumRange(relation, first_fsm_block, last_block); + FreeSpaceMapVacuumRange(relation, first_fsm_block, last_block + 1); } if (bistate) From 56bf5fa5d67a0cea97a8b456a3834749b3146f95 Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Wed, 15 Jul 2026 17:32:17 -0400 Subject: [PATCH 159/481] Introduce macros for WAL block reference IDs of some heap record types When registering a buffer with the WAL machinery, the caller assigns it a block reference ID, and replay must read each block back by that same ID. Today these IDs are bare integers assigned by convention (0, 1, 2, ...), which is easy to follow when a record registers a single block, or when the blocks are handled during replay in their registration order. An upcoming bug fix registers up to two visibility map blocks in addition to the heap block(s) when clearing the VM, and these are not handled during replay in a straightforward 1:1, in-registration-order fashion. Relying on bare integers for the block IDs in that case is error-prone. Introduce macros naming the block reference IDs for the heap record types that the upcoming commit extends to register visibility map blocks, so the registration and replay sites refer to the same block by a meaningful name. Author: Melanie Plageman Reviewed-by: Robert Haas Discussion: https://postgr.es/m/66mqpfyti3qhfttcsv6r2lbvqqd32rrmpn6i47ovrsnvguts46%40gou54xc> Backpatch through: 17 --- src/backend/access/heap/heapam.c | 45 ++++++++++++--------- src/backend/access/heap/heapam_xlog.c | 56 +++++++++++++++++---------- src/include/access/heapam_xlog.h | 29 ++++++++++---- 3 files changed, 84 insertions(+), 46 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 4f373b86028..4594e746c67 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2149,10 +2149,12 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, * write the whole page to the xlog, we don't need to store * xl_heap_header in the xlog. */ - XLogRegisterBuffer(0, buffer, REGBUF_STANDARD | bufflags); - XLogRegisterBufData(0, &xlhdr, SizeOfHeapHeader); + XLogRegisterBuffer(HEAP_INSERT_BLKREF_HEAP, buffer, + REGBUF_STANDARD | bufflags); + XLogRegisterBufData(HEAP_INSERT_BLKREF_HEAP, &xlhdr, + SizeOfHeapHeader); /* PG73FORMAT: write bitmap [+ padding] [+ oid] + data */ - XLogRegisterBufData(0, + XLogRegisterBufData(HEAP_INSERT_BLKREF_HEAP, (char *) heaptup->t_data + SizeofHeapTupleHeader, heaptup->t_len - SizeofHeapTupleHeader); @@ -2573,11 +2575,13 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, XLogBeginInsert(); XLogRegisterData(xlrec, tupledata - scratch.data); - XLogRegisterBuffer(0, buffer, REGBUF_STANDARD | bufflags); + XLogRegisterBuffer(HEAP_MULTI_INSERT_BLKREF_HEAP, buffer, + REGBUF_STANDARD | bufflags); if (all_frozen_set) - XLogRegisterBuffer(1, vmbuffer, 0); + XLogRegisterBuffer(HEAP_MULTI_INSERT_BLKREF_VM, vmbuffer, 0); - XLogRegisterBufData(0, tupledata, totaldatalen); + XLogRegisterBufData(HEAP_MULTI_INSERT_BLKREF_HEAP, tupledata, + totaldatalen); /* filtering by origin on a row level is much more efficient */ XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN); @@ -3069,7 +3073,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, XLogBeginInsert(); XLogRegisterData(&xlrec, SizeOfHeapDelete); - XLogRegisterBuffer(0, buffer, REGBUF_STANDARD); + XLogRegisterBuffer(HEAP_DELETE_BLKREF_HEAP, buffer, REGBUF_STANDARD); /* * Log replica identity of the deleted tuple if there is one @@ -3844,7 +3848,7 @@ heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, XLogRecPtr recptr; XLogBeginInsert(); - XLogRegisterBuffer(0, buffer, REGBUF_STANDARD); + XLogRegisterBuffer(HEAP_LOCK_BLKREF_HEAP, buffer, REGBUF_STANDARD); xlrec.offnum = ItemPointerGetOffsetNumber(&oldtup.t_self); xlrec.xmax = xmax_lock_old_tuple; @@ -5183,7 +5187,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, XLogRecPtr recptr; XLogBeginInsert(); - XLogRegisterBuffer(0, *buffer, REGBUF_STANDARD); + XLogRegisterBuffer(HEAP_LOCK_BLKREF_HEAP, *buffer, REGBUF_STANDARD); xlrec.offnum = ItemPointerGetOffsetNumber(&tuple->t_self); xlrec.xmax = xid; @@ -5935,7 +5939,7 @@ heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, Page page = BufferGetPage(buf); XLogBeginInsert(); - XLogRegisterBuffer(0, buf, REGBUF_STANDARD); + XLogRegisterBuffer(HEAP_LOCK_BLKREF_HEAP, buf, REGBUF_STANDARD); xlrec.offnum = ItemPointerGetOffsetNumber(&mytup.t_self); xlrec.xmax = new_xmax; @@ -8901,9 +8905,9 @@ log_heap_update(Relation reln, Buffer oldbuf, if (need_tuple_data) bufflags |= REGBUF_KEEP_DATA; - XLogRegisterBuffer(0, newbuf, bufflags); + XLogRegisterBuffer(HEAP_UPDATE_BLKREF_HEAP_NEW, newbuf, bufflags); if (oldbuf != newbuf) - XLogRegisterBuffer(1, oldbuf, REGBUF_STANDARD); + XLogRegisterBuffer(HEAP_UPDATE_BLKREF_HEAP_OLD, oldbuf, REGBUF_STANDARD); XLogRegisterData(&xlrec, SizeOfHeapUpdate); @@ -8916,15 +8920,18 @@ log_heap_update(Relation reln, Buffer oldbuf, { prefix_suffix[0] = prefixlen; prefix_suffix[1] = suffixlen; - XLogRegisterBufData(0, &prefix_suffix, sizeof(uint16) * 2); + XLogRegisterBufData(HEAP_UPDATE_BLKREF_HEAP_NEW, &prefix_suffix, + sizeof(uint16) * 2); } else if (prefixlen > 0) { - XLogRegisterBufData(0, &prefixlen, sizeof(uint16)); + XLogRegisterBufData(HEAP_UPDATE_BLKREF_HEAP_NEW, &prefixlen, + sizeof(uint16)); } else { - XLogRegisterBufData(0, &suffixlen, sizeof(uint16)); + XLogRegisterBufData(HEAP_UPDATE_BLKREF_HEAP_NEW, &suffixlen, + sizeof(uint16)); } } @@ -8938,10 +8945,10 @@ log_heap_update(Relation reln, Buffer oldbuf, * * The 'data' doesn't include the common prefix or suffix. */ - XLogRegisterBufData(0, &xlhdr, SizeOfHeapHeader); + XLogRegisterBufData(HEAP_UPDATE_BLKREF_HEAP_NEW, &xlhdr, SizeOfHeapHeader); if (prefixlen == 0) { - XLogRegisterBufData(0, + XLogRegisterBufData(HEAP_UPDATE_BLKREF_HEAP_NEW, (char *) newtup->t_data + SizeofHeapTupleHeader, newtup->t_len - SizeofHeapTupleHeader - suffixlen); } @@ -8954,13 +8961,13 @@ log_heap_update(Relation reln, Buffer oldbuf, /* bitmap [+ padding] [+ oid] */ if (newtup->t_data->t_hoff - SizeofHeapTupleHeader > 0) { - XLogRegisterBufData(0, + XLogRegisterBufData(HEAP_UPDATE_BLKREF_HEAP_NEW, (char *) newtup->t_data + SizeofHeapTupleHeader, newtup->t_data->t_hoff - SizeofHeapTupleHeader); } /* data after common prefix */ - XLogRegisterBufData(0, + XLogRegisterBufData(HEAP_UPDATE_BLKREF_HEAP_NEW, (char *) newtup->t_data + newtup->t_data->t_hoff + prefixlen, newtup->t_len - newtup->t_data->t_hoff - prefixlen - suffixlen); } diff --git a/src/backend/access/heap/heapam_xlog.c b/src/backend/access/heap/heapam_xlog.c index 9ed7024e814..963a886a1b3 100644 --- a/src/backend/access/heap/heapam_xlog.c +++ b/src/backend/access/heap/heapam_xlog.c @@ -299,7 +299,8 @@ heap_xlog_delete(XLogReaderState *record) RelFileLocator target_locator; ItemPointerData target_tid; - XLogRecGetBlockTag(record, 0, &target_locator, NULL, &blkno); + XLogRecGetBlockTag(record, HEAP_DELETE_BLKREF_HEAP, &target_locator, NULL, + &blkno); ItemPointerSetBlockNumber(&target_tid, blkno); ItemPointerSetOffsetNumber(&target_tid, xlrec->offnum); @@ -318,7 +319,8 @@ heap_xlog_delete(XLogReaderState *record) FreeFakeRelcacheEntry(reln); } - if (XLogReadBufferForRedo(record, 0, &buffer) == BLK_NEEDS_REDO) + if (XLogReadBufferForRedo(record, HEAP_DELETE_BLKREF_HEAP, + &buffer) == BLK_NEEDS_REDO) { page = BufferGetPage(buffer); @@ -383,7 +385,8 @@ heap_xlog_insert(XLogReaderState *record) ItemPointerData target_tid; XLogRedoAction action; - XLogRecGetBlockTag(record, 0, &target_locator, NULL, &blkno); + XLogRecGetBlockTag(record, HEAP_INSERT_BLKREF_HEAP, &target_locator, NULL, + &blkno); ItemPointerSetBlockNumber(&target_tid, blkno); ItemPointerSetOffsetNumber(&target_tid, xlrec->offnum); @@ -411,13 +414,14 @@ heap_xlog_insert(XLogReaderState *record) */ if (XLogRecGetInfo(record) & XLOG_HEAP_INIT_PAGE) { - buffer = XLogInitBufferForRedo(record, 0); + buffer = XLogInitBufferForRedo(record, HEAP_INSERT_BLKREF_HEAP); page = BufferGetPage(buffer); PageInit(page, BufferGetPageSize(buffer), 0); action = BLK_NEEDS_REDO; } else - action = XLogReadBufferForRedo(record, 0, &buffer); + action = XLogReadBufferForRedo(record, HEAP_INSERT_BLKREF_HEAP, + &buffer); if (action == BLK_NEEDS_REDO) { Size datalen; @@ -428,7 +432,7 @@ heap_xlog_insert(XLogReaderState *record) if (PageGetMaxOffsetNumber(page) + 1 < xlrec->offnum) elog(PANIC, "invalid max offset number"); - data = XLogRecGetBlockData(record, 0, &datalen); + data = XLogRecGetBlockData(record, HEAP_INSERT_BLKREF_HEAP, &datalen); newlen = datalen - SizeOfHeapHeader; Assert(datalen > SizeOfHeapHeader && newlen <= MaxHeapTupleSize); @@ -516,7 +520,8 @@ heap_xlog_multi_insert(XLogReaderState *record) */ xlrec = (xl_heap_multi_insert *) XLogRecGetData(record); - XLogRecGetBlockTag(record, 0, &rlocator, NULL, &blkno); + XLogRecGetBlockTag(record, HEAP_MULTI_INSERT_BLKREF_HEAP, &rlocator, NULL, + &blkno); /* check that the mutually exclusive flags are not both set */ Assert(!((xlrec->flags & XLH_INSERT_ALL_VISIBLE_CLEARED) && @@ -539,13 +544,14 @@ heap_xlog_multi_insert(XLogReaderState *record) if (isinit) { - buffer = XLogInitBufferForRedo(record, 0); + buffer = XLogInitBufferForRedo(record, HEAP_MULTI_INSERT_BLKREF_HEAP); page = BufferGetPage(buffer); PageInit(page, BufferGetPageSize(buffer), 0); action = BLK_NEEDS_REDO; } else - action = XLogReadBufferForRedo(record, 0, &buffer); + action = XLogReadBufferForRedo(record, HEAP_MULTI_INSERT_BLKREF_HEAP, + &buffer); if (action == BLK_NEEDS_REDO) { char *tupdata; @@ -553,7 +559,8 @@ heap_xlog_multi_insert(XLogReaderState *record) Size len; /* Tuples are stored as block data */ - tupdata = XLogRecGetBlockData(record, 0, &len); + tupdata = XLogRecGetBlockData(record, HEAP_MULTI_INSERT_BLKREF_HEAP, + &len); endptr = tupdata + len; page = BufferGetPage(buffer); @@ -728,8 +735,10 @@ heap_xlog_update(XLogReaderState *record, bool hot_update) oldtup.t_data = NULL; oldtup.t_len = 0; - XLogRecGetBlockTag(record, 0, &rlocator, NULL, &newblk); - if (XLogRecGetBlockTagExtended(record, 1, NULL, NULL, &oldblk, NULL)) + XLogRecGetBlockTag(record, HEAP_UPDATE_BLKREF_HEAP_NEW, &rlocator, NULL, + &newblk); + if (XLogRecGetBlockTagExtended(record, HEAP_UPDATE_BLKREF_HEAP_OLD, NULL, NULL, + &oldblk, NULL)) { /* HOT updates are never done across pages */ Assert(!hot_update); @@ -765,7 +774,8 @@ heap_xlog_update(XLogReaderState *record, bool hot_update) */ /* Deal with old tuple version */ - oldaction = XLogReadBufferForRedo(record, (oldblk == newblk) ? 0 : 1, + oldaction = XLogReadBufferForRedo(record, (oldblk == newblk) ? + HEAP_UPDATE_BLKREF_HEAP_NEW : HEAP_UPDATE_BLKREF_HEAP_OLD, &obuffer); if (oldaction == BLK_NEEDS_REDO) { @@ -815,13 +825,14 @@ heap_xlog_update(XLogReaderState *record, bool hot_update) } else if (XLogRecGetInfo(record) & XLOG_HEAP_INIT_PAGE) { - nbuffer = XLogInitBufferForRedo(record, 0); + nbuffer = XLogInitBufferForRedo(record, HEAP_UPDATE_BLKREF_HEAP_NEW); npage = BufferGetPage(nbuffer); PageInit(npage, BufferGetPageSize(nbuffer), 0); newaction = BLK_NEEDS_REDO; } else - newaction = XLogReadBufferForRedo(record, 0, &nbuffer); + newaction = XLogReadBufferForRedo(record, HEAP_UPDATE_BLKREF_HEAP_NEW, + &nbuffer); /* * The visibility map may need to be fixed even if the heap page is @@ -846,7 +857,8 @@ heap_xlog_update(XLogReaderState *record, bool hot_update) Size datalen; Size tuplen; - recdata = XLogRecGetBlockData(record, 0, &datalen); + recdata = XLogRecGetBlockData(record, HEAP_UPDATE_BLKREF_HEAP_NEW, + &datalen); recdata_end = recdata + datalen; npage = BufferGetPage(nbuffer); @@ -1033,7 +1045,8 @@ heap_xlog_lock(XLogReaderState *record) BlockNumber block; Relation reln; - XLogRecGetBlockTag(record, 0, &rlocator, NULL, &block); + XLogRecGetBlockTag(record, HEAP_LOCK_BLKREF_HEAP, &rlocator, NULL, + &block); reln = CreateFakeRelcacheEntry(rlocator); visibilitymap_pin(reln, block, &vmbuffer); @@ -1043,7 +1056,8 @@ heap_xlog_lock(XLogReaderState *record) FreeFakeRelcacheEntry(reln); } - if (XLogReadBufferForRedo(record, 0, &buffer) == BLK_NEEDS_REDO) + if (XLogReadBufferForRedo(record, HEAP_LOCK_BLKREF_HEAP, + &buffer) == BLK_NEEDS_REDO) { page = BufferGetPage(buffer); @@ -1109,7 +1123,8 @@ heap_xlog_lock_updated(XLogReaderState *record) BlockNumber block; Relation reln; - XLogRecGetBlockTag(record, 0, &rlocator, NULL, &block); + XLogRecGetBlockTag(record, HEAP_LOCK_BLKREF_HEAP, &rlocator, NULL, + &block); reln = CreateFakeRelcacheEntry(rlocator); visibilitymap_pin(reln, block, &vmbuffer); @@ -1119,7 +1134,8 @@ heap_xlog_lock_updated(XLogReaderState *record) FreeFakeRelcacheEntry(reln); } - if (XLogReadBufferForRedo(record, 0, &buffer) == BLK_NEEDS_REDO) + if (XLogReadBufferForRedo(record, HEAP_LOCK_BLKREF_HEAP, + &buffer) == BLK_NEEDS_REDO) { page = BufferGetPage(buffer); diff --git a/src/include/access/heapam_xlog.h b/src/include/access/heapam_xlog.h index fdca7d821c8..fedee7f3501 100644 --- a/src/include/access/heapam_xlog.h +++ b/src/include/access/heapam_xlog.h @@ -112,6 +112,8 @@ (XLH_DELETE_CONTAINS_OLD_TUPLE | XLH_DELETE_CONTAINS_OLD_KEY) /* This is what we need to know about delete */ +#define HEAP_DELETE_BLKREF_HEAP 0 + typedef struct xl_heap_delete { TransactionId xmax; /* xmax of the deleted tuple */ @@ -159,12 +161,14 @@ typedef struct xl_heap_header #define SizeOfHeapHeader (offsetof(xl_heap_header, t_hoff) + sizeof(uint8)) /* This is what we need to know about insert */ +#define HEAP_INSERT_BLKREF_HEAP 0 + typedef struct xl_heap_insert { OffsetNumber offnum; /* inserted tuple's offset */ uint8 flags; - /* xl_heap_header & TUPLE DATA in backup block 0 */ + /* xl_heap_header & TUPLE DATA in HEAP_INSERT_BLKREF_HEAP */ } xl_heap_insert; #define SizeOfHeapInsert (offsetof(xl_heap_insert, flags) + sizeof(uint8)) @@ -175,10 +179,14 @@ typedef struct xl_heap_insert * The main data of the record consists of this xl_heap_multi_insert header. * 'offsets' array is omitted if the whole page is reinitialized * (XLOG_HEAP_INIT_PAGE). - * - * In block 0's data portion, there is an xl_multi_insert_tuple struct, - * followed by the tuple data for each tuple. There is padding to align - * each xl_multi_insert_tuple struct. + */ +#define HEAP_MULTI_INSERT_BLKREF_HEAP 0 +#define HEAP_MULTI_INSERT_BLKREF_VM 1 + +/* + * In HEAP_MULTI_INSERT_BLKREF_HEAP's data portion, there is an + * xl_multi_insert_tuple struct, followed by the tuple data for each tuple. + * There is padding to align each xl_multi_insert_tuple struct. */ typedef struct xl_heap_multi_insert { @@ -203,7 +211,7 @@ typedef struct xl_multi_insert_tuple /* * This is what we need to know about update|hot_update * - * Backup blk 0: new page + * HEAP_UPDATE_BLKREF_HEAP_NEW: new page * * If XLH_UPDATE_PREFIX_FROM_OLD or XLH_UPDATE_SUFFIX_FROM_OLD flags are set, * the prefix and/or suffix come first, as one or two uint16s. @@ -215,8 +223,13 @@ typedef struct xl_multi_insert_tuple * If XLH_UPDATE_CONTAINS_NEW_TUPLE flag is given, the tuple data is * included even if a full-page image was taken. * - * Backup blk 1: old page, if different. (no data, just a reference to the blk) + * HEAP_UPDATE_BLKREF_HEAP_OLD: old page, if different. (no data, just a reference + * to the block) */ + +#define HEAP_UPDATE_BLKREF_HEAP_NEW 0 +#define HEAP_UPDATE_BLKREF_HEAP_OLD 1 + typedef struct xl_heap_update { TransactionId old_xmax; /* xmax of the old tuple */ @@ -403,6 +416,8 @@ typedef struct xlhp_prune_items #define XLH_LOCK_ALL_FROZEN_CLEARED 0x01 /* This is what we need to know about lock */ +#define HEAP_LOCK_BLKREF_HEAP 0 + typedef struct xl_heap_lock { TransactionId xmax; /* might be a MultiXactId */ From b01c31eef9c3a83d0bd9f30656cedaa6722890ee Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Wed, 15 Jul 2026 17:32:17 -0400 Subject: [PATCH 160/481] Fix VM clear WAL logging by registering VM blocks Heap WAL records that clear bits on the visibility map (like inserts and deletes) did not register the visibility map blocks they modified. Because the WAL summarizer only records registered blocks, an incremental backup taken over such operations would omit the changed VM pages. On restore, the VM would retain stale all-visible/all-frozen bits, which can cause wrong results from index-only scans and incorrect relfrozenxid advancement due to vacuum page skipping. Not registering the VM buffer also meant we never emitted FPIs of VM pages when clearing bits. A torn VM page won't raise an error because the VM is read with ZERO_ON_ERROR; with checksums on, it would be detected and zeroed, but with checksums off, it is accepted as-is and can lead to data corruption. Fix this by registering the VM buffer in the WAL record when clearing VM bits. The VM buffer must now be locked throughout the critical section that modifies the VM and heap pages and emits the WAL record. This can slow down operations that clear the VM, since the VM lock is held longer and VM FPIs may be emitted, but it is required for correctness. Note that this fix does not repair existing incremental backups. Bumps XLOG_PAGE_MAGIC. Though it is late in the cycle (post-beta 2) to be doing so, that seemed better than maintaining the backwards compatability code in yet another branch. Author: Melanie Plageman Author: Andres Freund Reviewed-by: Robert Haas Reviewed-by: Andrey Borodin Discussion: https://postgr.es/m/flat/CAAKRu_bn%2Be7F4yPFBgFbnP%2BsyJRKyNK092bjD2LKvZW7O4Svag> Backpatch-through: 17 --- contrib/pg_surgery/heap_surgery.c | 40 ++- src/backend/access/heap/heapam.c | 371 ++++++++++++++++++++---- src/backend/access/heap/heapam_xlog.c | 202 ++++++++----- src/backend/access/heap/pruneheap.c | 2 + src/backend/access/heap/visibilitymap.c | 24 +- src/bin/pg_walsummary/t/002_blocks.pl | 7 +- src/include/access/heapam_xlog.h | 17 +- src/include/access/xlog_internal.h | 2 +- 8 files changed, 508 insertions(+), 157 deletions(-) diff --git a/contrib/pg_surgery/heap_surgery.c b/contrib/pg_surgery/heap_surgery.c index b8ce1095782..a10876cb800 100644 --- a/contrib/pg_surgery/heap_surgery.c +++ b/contrib/pg_surgery/heap_surgery.c @@ -17,6 +17,7 @@ #include "access/visibilitymap.h" #include "access/xloginsert.h" #include "catalog/pg_am_d.h" +#include "catalog/pg_control.h" #include "miscadmin.h" #include "storage/bufmgr.h" #include "utils/acl.h" @@ -146,6 +147,7 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt) { Buffer buf; Buffer vmbuf = InvalidBuffer; + bool unlock_vmbuf = false; Page page; BlockNumber blkno; OffsetNumber curoff; @@ -233,11 +235,15 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt) } /* - * Before entering the critical section, pin the visibility map page - * if it appears to be necessary. + * Before entering the critical section, pin and lock the visibility + * map page if it appears to be necessary. */ if (heap_force_opt == HEAP_FORCE_KILL && PageIsAllVisible(page)) + { visibilitymap_pin(rel, blkno, &vmbuf); + LockBuffer(vmbuf, BUFFER_LOCK_EXCLUSIVE); + unlock_vmbuf = true; + } /* No ereport(ERROR) from here until all the changes are logged. */ START_CRIT_SECTION(); @@ -266,10 +272,11 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt) */ if (PageIsAllVisible(page)) { + if (visibilitymap_clear(rel, blkno, vmbuf, + VISIBILITYMAP_VALID_BITS)) + did_modify_vm = true; + PageClearAllVisible(page); - visibilitymap_clear(rel, blkno, vmbuf, - VISIBILITYMAP_VALID_BITS); - did_modify_vm = true; } } else @@ -320,18 +327,29 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt) /* XLOG stuff */ if (RelationNeedsWAL(rel)) - log_newpage_buffer(buf, true); + { + XLogRecPtr recptr; + + XLogBeginInsert(); + XLogRegisterBuffer(0, buf, REGBUF_STANDARD | REGBUF_FORCE_IMAGE); + /* Include the VM page if it was modified */ + if (did_modify_vm) + XLogRegisterBuffer(1, vmbuf, REGBUF_FORCE_IMAGE); + recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI); + if (did_modify_vm) + PageSetLSN(BufferGetPage(vmbuf), recptr); + PageSetLSN(BufferGetPage(buf), recptr); + } } - /* WAL log the VM page if it was modified. */ - if (did_modify_vm && RelationNeedsWAL(rel)) - log_newpage_buffer(vmbuf, false); - END_CRIT_SECTION(); UnlockReleaseBuffer(buf); - if (vmbuf != InvalidBuffer) + if (unlock_vmbuf) + LockBuffer(vmbuf, BUFFER_LOCK_UNLOCK); + + if (BufferIsValid(vmbuf)) ReleaseBuffer(vmbuf); /* Update the current_start_ptr before moving to the next page. */ diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 4594e746c67..182740c8183 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -60,7 +60,8 @@ static HeapTuple heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid, CommandId cid, uint32 options); static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf, - Buffer newbuf, HeapTuple oldtup, + Buffer vmbuffer_old, Buffer newbuf, + Buffer vmbuffer_new, HeapTuple oldtup, HeapTuple newtup, HeapTuple old_key_tuple, bool all_visible_cleared, bool new_all_visible_cleared, bool walLogical); @@ -2009,7 +2010,8 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, Buffer buffer; Page page; Buffer vmbuffer = InvalidBuffer; - bool all_visible_cleared = false; + bool clear_all_visible = false; + bool vmbuffer_modified = false; /* Cheap, simplistic check that the tuple matches the rel's rowtype. */ Assert(HeapTupleHeaderGetNatts(tup->t_data) <= @@ -2053,19 +2055,28 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, */ CheckForSerializableConflictIn(relation, NULL, InvalidBlockNumber); + /* Lock the vmbuffer before the critical section */ + if (PageIsAllVisible(page)) + { + LockBuffer(vmbuffer, BUFFER_LOCK_EXCLUSIVE); + clear_all_visible = true; + } + /* NO EREPORT(ERROR) from here till changes are logged */ START_CRIT_SECTION(); RelationPutHeapTuple(relation, buffer, heaptup, (options & HEAP_INSERT_SPECULATIVE) != 0); - if (PageIsAllVisible(page)) + if (clear_all_visible) { - all_visible_cleared = true; + /* It's possible the VM bits were already clear */ + if (visibilitymap_clear(relation, + ItemPointerGetBlockNumber(&(heaptup->t_self)), + vmbuffer, VISIBILITYMAP_VALID_BITS)) + vmbuffer_modified = true; + PageClearAllVisible(page); - visibilitymap_clear(relation, - ItemPointerGetBlockNumber(&(heaptup->t_self)), - vmbuffer, VISIBILITYMAP_VALID_BITS); } /* @@ -2116,7 +2127,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, xlrec.offnum = ItemPointerGetOffsetNumber(&heaptup->t_self); xlrec.flags = 0; - if (all_visible_cleared) + if (clear_all_visible) xlrec.flags |= XLH_INSERT_ALL_VISIBLE_CLEARED; if (options & HEAP_INSERT_SPECULATIVE) xlrec.flags |= XLH_INSERT_IS_SPECULATIVE; @@ -2161,15 +2172,28 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, /* filtering by origin on a row level is much more efficient */ XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN); + if (vmbuffer_modified) + XLogRegisterBuffer(HEAP_INSERT_BLKREF_VM, vmbuffer, 0); + recptr = XLogInsert(RM_HEAP_ID, info); PageSetLSN(page, recptr); + + if (vmbuffer_modified) + PageSetLSN(BufferGetPage(vmbuffer), recptr); } END_CRIT_SECTION(); UnlockReleaseBuffer(buffer); - if (vmbuffer != InvalidBuffer) + + /* + * We locked vmbuffer if clear_all_visible was true regardless of whether + * or not we ended up modifying the vmbuffer. + */ + if (clear_all_visible) + LockBuffer(vmbuffer, BUFFER_LOCK_UNLOCK); + if (BufferIsValid(vmbuffer)) ReleaseBuffer(vmbuffer); /* @@ -2350,8 +2374,9 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, while (ndone < ntuples) { Buffer buffer; - bool all_visible_cleared = false; + bool clear_all_visible = false; bool all_frozen_set = false; + bool vmbuffer_modified = false; int nthispage; CHECK_FOR_INTERRUPTS(); @@ -2396,6 +2421,12 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, /* Lock the vmbuffer before entering the critical section */ LockBuffer(vmbuffer, BUFFER_LOCK_EXCLUSIVE); } + else if (PageIsAllVisible(page) && !(options & HEAP_INSERT_FROZEN)) + { + clear_all_visible = true; + /* Lock the vmbuffer before entering the critical section */ + LockBuffer(vmbuffer, BUFFER_LOCK_EXCLUSIVE); + } /* NO EREPORT(ERROR) from here till changes are logged */ START_CRIT_SECTION(); @@ -2438,13 +2469,16 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, * page, mark it as all-frozen and update the visibility map. We're * already holding a pin on the vmbuffer. */ - if (PageIsAllVisible(page) && !(options & HEAP_INSERT_FROZEN)) + if (clear_all_visible) { - all_visible_cleared = true; + Assert(!(options & HEAP_INSERT_FROZEN)); + /* It's possible the VM bits were already clear */ + if (visibilitymap_clear(relation, + BufferGetBlockNumber(buffer), + vmbuffer, VISIBILITYMAP_VALID_BITS)) + vmbuffer_modified = true; + PageClearAllVisible(page); - visibilitymap_clear(relation, - BufferGetBlockNumber(buffer), - vmbuffer, VISIBILITYMAP_VALID_BITS); } else if (all_frozen_set) { @@ -2502,10 +2536,10 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, tupledata = scratchptr; /* check that the mutually exclusive flags are not both set */ - Assert(!(all_visible_cleared && all_frozen_set)); + Assert(!(clear_all_visible && all_frozen_set)); xlrec->flags = 0; - if (all_visible_cleared) + if (clear_all_visible) xlrec->flags = XLH_INSERT_ALL_VISIBLE_CLEARED; /* @@ -2577,7 +2611,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, XLogRegisterData(xlrec, tupledata - scratch.data); XLogRegisterBuffer(HEAP_MULTI_INSERT_BLKREF_HEAP, buffer, REGBUF_STANDARD | bufflags); - if (all_frozen_set) + if (all_frozen_set || vmbuffer_modified) XLogRegisterBuffer(HEAP_MULTI_INSERT_BLKREF_VM, vmbuffer, 0); XLogRegisterBufData(HEAP_MULTI_INSERT_BLKREF_HEAP, tupledata, @@ -2589,7 +2623,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, recptr = XLogInsert(RM_HEAP2_ID, info); PageSetLSN(page, recptr); - if (all_frozen_set) + if (all_frozen_set || vmbuffer_modified) { Assert(BufferIsDirty(vmbuffer)); PageSetLSN(BufferGetPage(vmbuffer), recptr); @@ -2598,7 +2632,11 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, END_CRIT_SECTION(); - if (all_frozen_set) + /* + * We locked vmbuffer if clear_all_visible was true regardless of + * whether or not we ended up modifying the vmbuffer. + */ + if (all_frozen_set || clear_all_visible) LockBuffer(vmbuffer, BUFFER_LOCK_UNLOCK); UnlockReleaseBuffer(buffer); @@ -2730,6 +2768,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, BlockNumber block; Buffer buffer; Buffer vmbuffer = InvalidBuffer; + bool vmbuffer_modified = false; TransactionId new_xmax; uint16 new_infomask, new_infomask2; @@ -2737,7 +2776,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, bool walLogical = (options & TABLE_DELETE_NO_LOGICAL) == 0; bool have_tuple_lock = false; bool iscombo; - bool all_visible_cleared = false; + bool clear_all_visible = false; HeapTuple old_key_tuple = NULL; /* replica identity of the tuple */ bool old_key_copied = false; @@ -2987,6 +3026,13 @@ heap_delete(Relation relation, const ItemPointerData *tid, xid, LockTupleExclusive, true, &new_xmax, &new_infomask, &new_infomask2); + /* Lock the VM before entering the critical section */ + if (PageIsAllVisible(page)) + { + clear_all_visible = true; + LockBuffer(vmbuffer, BUFFER_LOCK_EXCLUSIVE); + } + START_CRIT_SECTION(); /* @@ -2998,12 +3044,14 @@ heap_delete(Relation relation, const ItemPointerData *tid, */ PageSetPrunable(page, xid); - if (PageIsAllVisible(page)) + if (clear_all_visible) { - all_visible_cleared = true; + /* It's possible the VM bits were already clear */ + if (visibilitymap_clear(relation, BufferGetBlockNumber(buffer), + vmbuffer, VISIBILITYMAP_VALID_BITS)) + vmbuffer_modified = true; + PageClearAllVisible(page); - visibilitymap_clear(relation, BufferGetBlockNumber(buffer), - vmbuffer, VISIBILITYMAP_VALID_BITS); } /* store transaction information of xact deleting the tuple */ @@ -3043,7 +3091,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, log_heap_new_cid(relation, &tp); xlrec.flags = 0; - if (all_visible_cleared) + if (clear_all_visible) xlrec.flags |= XLH_DELETE_ALL_VISIBLE_CLEARED; if (changingPart) xlrec.flags |= XLH_DELETE_IS_PARTITION_MOVE; @@ -3094,13 +3142,27 @@ heap_delete(Relation relation, const ItemPointerData *tid, /* filtering by origin on a row level is much more efficient */ XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN); + if (vmbuffer_modified) + XLogRegisterBuffer(HEAP_DELETE_BLKREF_VM, vmbuffer, 0); + recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE); PageSetLSN(page, recptr); + + if (vmbuffer_modified) + PageSetLSN(BufferGetPage(vmbuffer), recptr); } END_CRIT_SECTION(); + /* + * Release VM lock first, since it covers many heap blocks. We locked + * vmbuffer if clear_all_visible was true regardless of whether or not we + * ended up modifying the vmbuffer. + */ + if (clear_all_visible) + LockBuffer(vmbuffer, BUFFER_LOCK_UNLOCK); + LockBuffer(buffer, BUFFER_LOCK_UNLOCK); if (vmbuffer != InvalidBuffer) @@ -3229,6 +3291,8 @@ heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, newbuf, vmbuffer = InvalidBuffer, vmbuffer_new = InvalidBuffer; + bool unlock_vmbuffer = false; + bool unlock_vmbuffer_new = false; bool need_toast; Size newtupsize, pagefree; @@ -3237,8 +3301,10 @@ heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, bool use_hot_update = false; bool summarized_update = false; bool key_intact; - bool all_visible_cleared = false; - bool all_visible_cleared_new = false; + bool clear_all_visible = false; + bool clear_all_visible_new = false; + bool vmbuffer_modified = false; + bool vmbuffer_new_modified = false; bool checked_lockers; bool locker_remains; bool id_has_external = false; @@ -3813,6 +3879,12 @@ heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, Assert(HEAP_XMAX_IS_LOCKED_ONLY(infomask_lock_old_tuple)); + if (PageIsAllVisible(page)) + { + LockBuffer(vmbuffer, BUFFER_LOCK_EXCLUSIVE); + unlock_vmbuffer = true; + } + START_CRIT_SECTION(); /* Clear obsolete visibility flags ... */ @@ -3835,10 +3907,13 @@ heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, * overhead would be unchanged, that doesn't seem necessarily * worthwhile. */ - if (PageIsAllVisible(page) && - visibilitymap_clear(relation, block, vmbuffer, - VISIBILITYMAP_ALL_FROZEN)) - cleared_all_frozen = true; + if (PageIsAllVisible(page)) + { + /* It's possible all-frozen was already clear */ + if (visibilitymap_clear(relation, block, vmbuffer, + VISIBILITYMAP_ALL_FROZEN)) + cleared_all_frozen = true; + } MarkBufferDirty(buffer); @@ -3857,12 +3932,24 @@ heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, xlrec.flags = cleared_all_frozen ? XLH_LOCK_ALL_FROZEN_CLEARED : 0; XLogRegisterData(&xlrec, SizeOfHeapLock); + + if (cleared_all_frozen) + XLogRegisterBuffer(HEAP_LOCK_BLKREF_VM, vmbuffer, 0); + recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK); PageSetLSN(page, recptr); + + if (cleared_all_frozen) + PageSetLSN(BufferGetPage(vmbuffer), recptr); } END_CRIT_SECTION(); + /* release VM lock first, since it covers many heap blocks */ + if (unlock_vmbuffer) + LockBuffer(vmbuffer, BUFFER_LOCK_UNLOCK); + unlock_vmbuffer = false; + LockBuffer(buffer, BUFFER_LOCK_UNLOCK); /* @@ -4013,6 +4100,69 @@ heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, id_has_external, &old_key_copied); + clear_all_visible = PageIsAllVisible(page); + clear_all_visible_new = newbuf != buffer && PageIsAllVisible(newpage); + + /* + * Clear PD_ALL_VISIBLE flags and reset visibility map bits for any heap + * pages that were all-visible. If there are two heap pages, we may need + * to clear VM bits for both. + */ + if (clear_all_visible && clear_all_visible_new && + vmbuffer_new == vmbuffer) + { + /* + * This is the more complicated case: both the new and old heap pages + * are all-visible and both their VM bits are on the same page of the + * VM, so we register a single VM buffer as HEAP_UPDATE_BLKREF_VM_NEW + * in the WAL record. We must be careful to only lock and register one + * buffer, even though we modify it twice -- once for each heap + * block's VM bits. + */ + LockBuffer(vmbuffer_new, BUFFER_LOCK_EXCLUSIVE); + unlock_vmbuffer_new = true; + + /* We will not lock or attempt to modify old VM buffer */ + } + else + { + /* + * In all the remaining cases, we will clear at most one heap block's + * VM bits per VM page. + */ + Buffer vmbuffers[2] = { + clear_all_visible ? vmbuffer : InvalidBuffer, + clear_all_visible_new ? vmbuffer_new : InvalidBuffer + }; + + /* + * When both pages need different VM pages cleared, acquire the VM + * buffer locks in VM block order to avoid deadlocks between backends + * updating tuples in opposite directions across VM pages. + */ + if (clear_all_visible && clear_all_visible_new && + BufferGetBlockNumber(vmbuffers[0]) > BufferGetBlockNumber(vmbuffers[1])) + { + Buffer swap = vmbuffers[0]; + + vmbuffers[0] = vmbuffers[1]; + vmbuffers[1] = swap; + } + + Assert((!BufferIsValid(vmbuffers[0]) && !BufferIsValid(vmbuffers[1])) || + vmbuffers[0] != vmbuffers[1]); + + if (BufferIsValid(vmbuffers[0])) + LockBuffer(vmbuffers[0], BUFFER_LOCK_EXCLUSIVE); + if (BufferIsValid(vmbuffers[1])) + LockBuffer(vmbuffers[1], BUFFER_LOCK_EXCLUSIVE); + + if (clear_all_visible) + unlock_vmbuffer = true; + if (clear_all_visible_new) + unlock_vmbuffer_new = true; + } + /* NO EREPORT(ERROR) from here till changes are logged */ START_CRIT_SECTION(); @@ -4063,20 +4213,42 @@ heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, /* record address of new tuple in t_ctid of old one */ oldtup.t_data->t_ctid = heaptup->t_self; - /* clear PD_ALL_VISIBLE flags, reset all visibilitymap bits */ - if (PageIsAllVisible(page)) + /* + * Clear PD_ALL_VISIBLE flags and reset all visibilitymap bits. In all + * cases, it's possible that PD_ALL_VISIBLE was set but the corresponding + * visibility map bits were already clear. + */ + if (clear_all_visible) { - all_visible_cleared = true; + if (visibilitymap_clear(relation, block, + vmbuffer, VISIBILITYMAP_VALID_BITS)) + { + /* + * When old and new heap blocks' VM bits are on the same VM page, + * that page is registered in the WAL record only once. If both + * heap pages were PD_ALL_VISIBLE and either VM bit needs + * clearing, we register the VM buffer as + * HEAP_UPDATE_BLKREF_VM_NEW. + */ + if (clear_all_visible_new && vmbuffer == vmbuffer_new) + vmbuffer_new_modified = true; + else + vmbuffer_modified = true; + } + PageClearAllVisible(page); - visibilitymap_clear(relation, BufferGetBlockNumber(buffer), - vmbuffer, VISIBILITYMAP_VALID_BITS); } - if (newbuf != buffer && PageIsAllVisible(newpage)) + if (clear_all_visible_new) { - all_visible_cleared_new = true; + /* + * If both heap blocks' VM bits are on the same VM buffer, this will + * clear the new heap block's VM bits from the shared vmbuffer. + */ + if (visibilitymap_clear(relation, BufferGetBlockNumber(newbuf), + vmbuffer_new, VISIBILITYMAP_VALID_BITS)) + vmbuffer_new_modified = true; + PageClearAllVisible(newpage); - visibilitymap_clear(relation, BufferGetBlockNumber(newbuf), - vmbuffer_new, VISIBILITYMAP_VALID_BITS); } if (newbuf != buffer) @@ -4099,20 +4271,33 @@ heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, } recptr = log_heap_update(relation, buffer, - newbuf, &oldtup, heaptup, + vmbuffer_modified ? vmbuffer : InvalidBuffer, + newbuf, + vmbuffer_new_modified ? vmbuffer_new : InvalidBuffer, + &oldtup, heaptup, old_key_tuple, - all_visible_cleared, - all_visible_cleared_new, + clear_all_visible, + clear_all_visible_new, walLogical); if (newbuf != buffer) { PageSetLSN(newpage, recptr); } PageSetLSN(page, recptr); + + if (vmbuffer_modified) + PageSetLSN(BufferGetPage(vmbuffer), recptr); + if (vmbuffer_new_modified) + PageSetLSN(BufferGetPage(vmbuffer_new), recptr); } END_CRIT_SECTION(); + if (unlock_vmbuffer) + LockBuffer(vmbuffer, BUFFER_LOCK_UNLOCK); + if (unlock_vmbuffer_new) + LockBuffer(vmbuffer_new, BUFFER_LOCK_UNLOCK); + if (newbuf != buffer) LockBuffer(newbuf, BUFFER_LOCK_UNLOCK); LockBuffer(buffer, BUFFER_LOCK_UNLOCK); @@ -4550,6 +4735,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, ItemId lp; Page page; Buffer vmbuffer = InvalidBuffer; + bool unlock_vmbuffer = false; BlockNumber block; TransactionId xid, xmax; @@ -4563,6 +4749,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid)); block = ItemPointerGetBlockNumber(tid); + page = BufferGetPage(*buffer); /* * Before locking the buffer, pin the visibility map page if it appears to @@ -4570,12 +4757,11 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, * in the middle of changing this, so we'll need to recheck after we have * the lock. */ - if (PageIsAllVisible(BufferGetPage(*buffer))) + if (PageIsAllVisible(page)) visibilitymap_pin(relation, block, &vmbuffer); LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE); - page = BufferGetPage(*buffer); lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid)); Assert(ItemIdIsNormal(lp)); @@ -5130,6 +5316,13 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, GetCurrentTransactionId(), mode, false, &xid, &new_infomask, &new_infomask2); + /* Lock VM buffer before entering critical section */ + if (PageIsAllVisible(page)) + { + LockBuffer(vmbuffer, BUFFER_LOCK_EXCLUSIVE); + unlock_vmbuffer = true; + } + START_CRIT_SECTION(); /* @@ -5161,11 +5354,12 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, tuple->t_data->t_ctid = *tid; /* Clear only the all-frozen bit on visibility map if needed */ - if (PageIsAllVisible(page) && - visibilitymap_clear(relation, block, vmbuffer, - VISIBILITYMAP_ALL_FROZEN)) - cleared_all_frozen = true; - + if (PageIsAllVisible(page)) + { + if (visibilitymap_clear(relation, block, vmbuffer, + VISIBILITYMAP_ALL_FROZEN)) + cleared_all_frozen = true; + } MarkBufferDirty(*buffer); @@ -5196,19 +5390,33 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, xlrec.flags = cleared_all_frozen ? XLH_LOCK_ALL_FROZEN_CLEARED : 0; XLogRegisterData(&xlrec, SizeOfHeapLock); + if (cleared_all_frozen) + XLogRegisterBuffer(HEAP_LOCK_BLKREF_VM, vmbuffer, 0); + /* we don't decode row locks atm, so no need to log the origin */ recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK); PageSetLSN(page, recptr); + + if (cleared_all_frozen) + PageSetLSN(BufferGetPage(vmbuffer), recptr); } END_CRIT_SECTION(); + /* release VM lock first, since it covers many heap blocks */ + if (unlock_vmbuffer) + { + LockBuffer(vmbuffer, BUFFER_LOCK_UNLOCK); + unlock_vmbuffer = false; + } + result = TM_Ok; out_locked: LockBuffer(*buffer, BUFFER_LOCK_UNLOCK); + Assert(!unlock_vmbuffer); out_unlocked: if (BufferIsValid(vmbuffer)) @@ -5671,6 +5879,7 @@ heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, ItemPointerData tupid; HeapTupleData mytup; Buffer buf; + Page page; uint16 new_infomask, new_infomask2, old_infomask, @@ -5680,6 +5889,7 @@ heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, bool cleared_all_frozen = false; bool pinned_desired_page; Buffer vmbuffer = InvalidBuffer; + bool unlock_vmbuffer = false; BlockNumber block; ItemPointerCopy(tid, &tupid); @@ -5688,6 +5898,7 @@ heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, { new_infomask = 0; new_xmax = InvalidTransactionId; + cleared_all_frozen = false; block = ItemPointerGetBlockNumber(&tupid); ItemPointerCopy(&tupid, &(mytup.t_self)); @@ -5707,13 +5918,15 @@ heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, l4: CHECK_FOR_INTERRUPTS(); + page = BufferGetPage(buf); + /* * Before locking the buffer, pin the visibility map page if it * appears to be necessary. Since we haven't got the lock yet, * someone else might be in the middle of changing this, so we'll need * to recheck after we have the lock. */ - if (PageIsAllVisible(BufferGetPage(buf))) + if (PageIsAllVisible(page)) { visibilitymap_pin(rel, block, &vmbuffer); pinned_desired_page = true; @@ -5734,7 +5947,7 @@ heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, * this page. If this page isn't all-visible, we won't use the vm * page, but we hold onto such a pin till the end of the function. */ - if (!pinned_desired_page && PageIsAllVisible(BufferGetPage(buf))) + if (!pinned_desired_page && PageIsAllVisible(page)) { LockBuffer(buf, BUFFER_LOCK_UNLOCK); visibilitymap_pin(rel, block, &vmbuffer); @@ -5915,10 +6128,11 @@ heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, xid, mode, false, &new_xmax, &new_infomask, &new_infomask2); - if (PageIsAllVisible(BufferGetPage(buf)) && - visibilitymap_clear(rel, block, vmbuffer, - VISIBILITYMAP_ALL_FROZEN)) - cleared_all_frozen = true; + if (PageIsAllVisible(page)) + { + LockBuffer(vmbuffer, BUFFER_LOCK_EXCLUSIVE); + unlock_vmbuffer = true; + } START_CRIT_SECTION(); @@ -5931,12 +6145,19 @@ heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, MarkBufferDirty(buf); + if (PageIsAllVisible(page)) + { + /* It's possible all-frozen was already clear */ + if (visibilitymap_clear(rel, block, vmbuffer, + VISIBILITYMAP_ALL_FROZEN)) + cleared_all_frozen = true; + } + /* XLOG stuff */ if (RelationNeedsWAL(rel)) { xl_heap_lock_updated xlrec; XLogRecPtr recptr; - Page page = BufferGetPage(buf); XLogBeginInsert(); XLogRegisterBuffer(HEAP_LOCK_BLKREF_HEAP, buf, REGBUF_STANDARD); @@ -5949,13 +6170,26 @@ heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, XLogRegisterData(&xlrec, SizeOfHeapLockUpdated); + if (cleared_all_frozen) + XLogRegisterBuffer(HEAP_LOCK_BLKREF_VM, vmbuffer, 0); + recptr = XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_LOCK_UPDATED); PageSetLSN(page, recptr); + + if (cleared_all_frozen) + PageSetLSN(BufferGetPage(vmbuffer), recptr); } END_CRIT_SECTION(); + /* release VM lock first, since it covers many heap blocks */ + if (unlock_vmbuffer) + { + LockBuffer(vmbuffer, BUFFER_LOCK_UNLOCK); + unlock_vmbuffer = false; + } + next: /* if we find the end of update chain, we're done. */ if (mytup.t_data->t_infomask & HEAP_XMAX_INVALID || @@ -5981,6 +6215,7 @@ heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, out_unlocked: if (vmbuffer != InvalidBuffer) ReleaseBuffer(vmbuffer); + Assert(!unlock_vmbuffer); return result; } @@ -8776,8 +9011,9 @@ bottomup_sort_and_shrink(TM_IndexDeleteOp *delstate) * have modified the buffer(s) and marked them dirty. */ static XLogRecPtr -log_heap_update(Relation reln, Buffer oldbuf, - Buffer newbuf, HeapTuple oldtup, HeapTuple newtup, +log_heap_update(Relation reln, Buffer oldbuf, Buffer vmbuffer_old, + Buffer newbuf, Buffer vmbuffer_new, + HeapTuple oldtup, HeapTuple newtup, HeapTuple old_key_tuple, bool all_visible_cleared, bool new_all_visible_cleared, bool walLogical) @@ -8987,6 +9223,21 @@ log_heap_update(Relation reln, Buffer oldbuf, old_key_tuple->t_len - SizeofHeapTupleHeader); } + /* + * Register VM buffers. If the old and new heap pages' VM bits are on the + * same VM page and both their VM bits were cleared, the caller passes + * only vmbuffer_new (mirroring the heap page convention where block 0 = + * new is always registered). + */ + Assert((BufferIsInvalid(vmbuffer_old) && BufferIsInvalid(vmbuffer_new)) || + (vmbuffer_old != vmbuffer_new)); + + if (BufferIsValid(vmbuffer_new)) + XLogRegisterBuffer(HEAP_UPDATE_BLKREF_VM_NEW, vmbuffer_new, 0); + + if (BufferIsValid(vmbuffer_old)) + XLogRegisterBuffer(HEAP_UPDATE_BLKREF_VM_OLD, vmbuffer_old, 0); + /* filtering by origin on a row level is much more efficient */ XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN); diff --git a/src/backend/access/heap/heapam_xlog.c b/src/backend/access/heap/heapam_xlog.c index 963a886a1b3..fbda931522c 100644 --- a/src/backend/access/heap/heapam_xlog.c +++ b/src/backend/access/heap/heapam_xlog.c @@ -22,6 +22,49 @@ #include "storage/freespace.h" #include "storage/standby.h" +/* + * Clear visibility map bits for a single heap block during heap redo. + * + * Used by records that modify one heap block and, at most, its corresponding + * VM block (insert, delete, multi_insert, lock). Records that can touch + * multiple heap or VM blocks (e.g. updates) replay the VM changes inline + * instead. + * + * 'record' is the WAL record being replayed + * 'target_locator' identifies the relation whose VM is being updated + * 'heap_blkno' is the heap block whose VM bits should be cleared + * 'wal_vm_block_id' is the WAL block reference id of the VM page + * 'flags' specifies which visibility map bits to clear + */ +static void +heap_xlog_vm_clear(XLogReaderState *record, + RelFileLocator target_locator, + BlockNumber heap_blkno, + uint8 wal_vm_block_id, uint8 flags) +{ + XLogRecPtr lsn = record->EndRecPtr; + Relation reln = CreateFakeRelcacheEntry(target_locator); + Buffer vmbuffer = InvalidBuffer; + + /* + * If the vmbuffer was registered, use the recovery-specific routines to + * read it. These will either apply an FPI or indicate that we should + * clear the requested bits ourselves. + */ + if (XLogRecHasBlockRef(record, wal_vm_block_id)) + { + if (XLogReadBufferForRedo(record, wal_vm_block_id, + &vmbuffer) == BLK_NEEDS_REDO) + { + if (visibilitymap_clear(reln, heap_blkno, vmbuffer, flags)) + PageSetLSN(BufferGetPage(vmbuffer), lsn); + } + if (BufferIsValid(vmbuffer)) + UnlockReleaseBuffer(vmbuffer); + } + + FreeFakeRelcacheEntry(reln); +} /* * Replay XLOG_HEAP2_PRUNE_* records. @@ -309,15 +352,9 @@ heap_xlog_delete(XLogReaderState *record) * already up-to-date. */ if (xlrec->flags & XLH_DELETE_ALL_VISIBLE_CLEARED) - { - Relation reln = CreateFakeRelcacheEntry(target_locator); - Buffer vmbuffer = InvalidBuffer; - - visibilitymap_pin(reln, blkno, &vmbuffer); - visibilitymap_clear(reln, blkno, vmbuffer, VISIBILITYMAP_VALID_BITS); - ReleaseBuffer(vmbuffer); - FreeFakeRelcacheEntry(reln); - } + heap_xlog_vm_clear(record, target_locator, + blkno, HEAP_DELETE_BLKREF_VM, + VISIBILITYMAP_VALID_BITS); if (XLogReadBufferForRedo(record, HEAP_DELETE_BLKREF_HEAP, &buffer) == BLK_NEEDS_REDO) @@ -398,15 +435,9 @@ heap_xlog_insert(XLogReaderState *record) * already up-to-date. */ if (xlrec->flags & XLH_INSERT_ALL_VISIBLE_CLEARED) - { - Relation reln = CreateFakeRelcacheEntry(target_locator); - Buffer vmbuffer = InvalidBuffer; - - visibilitymap_pin(reln, blkno, &vmbuffer); - visibilitymap_clear(reln, blkno, vmbuffer, VISIBILITYMAP_VALID_BITS); - ReleaseBuffer(vmbuffer); - FreeFakeRelcacheEntry(reln); - } + heap_xlog_vm_clear(record, target_locator, + blkno, HEAP_INSERT_BLKREF_VM, + VISIBILITYMAP_VALID_BITS); /* * If we inserted the first and only tuple on the page, re-initialize the @@ -530,17 +561,15 @@ heap_xlog_multi_insert(XLogReaderState *record) /* * The visibility map may need to be fixed even if the heap page is * already up-to-date. + * + * Clear the VM (if needed) before clearing the heap page-level visibility + * flag (PD_ALL_VISIBLE) to prevent the heap page from being marked + * all-visible in the VM while its PD_ALL_VISIBLE is clear. */ if (xlrec->flags & XLH_INSERT_ALL_VISIBLE_CLEARED) - { - Relation reln = CreateFakeRelcacheEntry(rlocator); - - visibilitymap_pin(reln, blkno, &vmbuffer); - visibilitymap_clear(reln, blkno, vmbuffer, VISIBILITYMAP_VALID_BITS); - ReleaseBuffer(vmbuffer); - vmbuffer = InvalidBuffer; - FreeFakeRelcacheEntry(reln); - } + heap_xlog_vm_clear(record, rlocator, + blkno, HEAP_MULTI_INSERT_BLKREF_VM, + VISIBILITYMAP_VALID_BITS); if (isinit) { @@ -640,7 +669,7 @@ heap_xlog_multi_insert(XLogReaderState *record) buffer = InvalidBuffer; /* - * Read and update the visibility map (VM) block. + * Read and update the visibility map (VM) block to set it frozen. * * We must always redo VM changes, even if the corresponding heap page * update was skipped due to the LSN interlock. Each VM block covers @@ -713,6 +742,8 @@ heap_xlog_update(XLogReaderState *record, bool hot_update) nbuffer; Page opage, npage; + bool has_vm_old, + has_vm_new; OffsetNumber offnum; ItemId lp; HeapTupleData oldtup; @@ -730,6 +761,7 @@ heap_xlog_update(XLogReaderState *record, bool hot_update) Size freespace = 0; XLogRedoAction oldaction; XLogRedoAction newaction; + Relation reln = NULL; /* initialize to keep the compiler quiet */ oldtup.t_data = NULL; @@ -752,25 +784,80 @@ heap_xlog_update(XLogReaderState *record, bool hot_update) * The visibility map may need to be fixed even if the heap page is * already up-to-date. */ - if (xlrec->flags & XLH_UPDATE_OLD_ALL_VISIBLE_CLEARED) + has_vm_old = XLogRecHasBlockRef(record, HEAP_UPDATE_BLKREF_VM_OLD); + has_vm_new = XLogRecHasBlockRef(record, HEAP_UPDATE_BLKREF_VM_NEW); + + if (has_vm_new || has_vm_old) + reln = CreateFakeRelcacheEntry(rlocator); + + if (has_vm_new) { - Relation reln = CreateFakeRelcacheEntry(rlocator); - Buffer vmbuffer = InvalidBuffer; + Buffer vmbuffer_new = InvalidBuffer; - visibilitymap_pin(reln, oldblk, &vmbuffer); - visibilitymap_clear(reln, oldblk, vmbuffer, VISIBILITYMAP_VALID_BITS); - ReleaseBuffer(vmbuffer); - FreeFakeRelcacheEntry(reln); + Assert(xlrec->flags & XLH_UPDATE_NEW_ALL_VISIBLE_CLEARED); + + if (XLogReadBufferForRedo(record, HEAP_UPDATE_BLKREF_VM_NEW, + &vmbuffer_new) == BLK_NEEDS_REDO) + { + /* + * If both the old and new heap pages were all-visible and their + * VM bits are on the same VM page, that single VM page is + * registered as HEAP_UPDATE_BLKREF_VM_NEW. Clear both heap + * blocks' VM bits from the single provided VM buffer. It's + * possible that one of the page's VM bits were already clear, but + * visibilitymap_clear() is harmless as long as we provide it the + * correct bits. + * + * We must verify that oldblk's VM bits really are on this VM + * page, rather than relying on the absence of a separate VM_OLD + * block reference: VM_OLD is also omitted when oldblk is on a + * different VM page but its bit was already clear. + */ + if (xlrec->flags & XLH_UPDATE_OLD_ALL_VISIBLE_CLEARED && + visibilitymap_pin_ok(oldblk, vmbuffer_new)) + { + if (visibilitymap_clear(reln, oldblk, vmbuffer_new, + VISIBILITYMAP_VALID_BITS)) + PageSetLSN(BufferGetPage(vmbuffer_new), lsn); + } + /* If VM_NEW is registered, we are sure newblk is on VM_NEW */ + if (visibilitymap_clear(reln, newblk, vmbuffer_new, + VISIBILITYMAP_VALID_BITS)) + PageSetLSN(BufferGetPage(vmbuffer_new), lsn); + } + if (BufferIsValid(vmbuffer_new)) + UnlockReleaseBuffer(vmbuffer_new); } + if (has_vm_old) + { + Buffer vmbuffer_old = InvalidBuffer; + + Assert(xlrec->flags & XLH_UPDATE_OLD_ALL_VISIBLE_CLEARED); + + if (XLogReadBufferForRedo(record, HEAP_UPDATE_BLKREF_VM_OLD, + &vmbuffer_old) == BLK_NEEDS_REDO) + { + if (visibilitymap_clear(reln, oldblk, vmbuffer_old, + VISIBILITYMAP_VALID_BITS)) + PageSetLSN(BufferGetPage(vmbuffer_old), lsn); + } + if (BufferIsValid(vmbuffer_old)) + UnlockReleaseBuffer(vmbuffer_old); + } + + if (reln) + FreeFakeRelcacheEntry(reln); /* * In normal operation, it is important to lock the two pages in * page-number order, to avoid possible deadlocks against other update * operations going the other way. However, during WAL replay there can - * be no other update happening, so we don't need to worry about that. But - * we *do* need to worry that we don't expose an inconsistent state to Hot - * Standby queries --- so the original page can't be unlocked before we've - * added the new tuple to the new page. + * be no other update happening, so we don't need to worry about that. + * Notice we also don't worry about this when locking VM buffers above. + * + * But we *do* need to worry that we don't expose an inconsistent state to + * Hot Standby queries --- so the original page can't be unlocked before + * we've added the new tuple to the new page. */ /* Deal with old tuple version */ @@ -834,21 +921,6 @@ heap_xlog_update(XLogReaderState *record, bool hot_update) newaction = XLogReadBufferForRedo(record, HEAP_UPDATE_BLKREF_HEAP_NEW, &nbuffer); - /* - * The visibility map may need to be fixed even if the heap page is - * already up-to-date. - */ - if (xlrec->flags & XLH_UPDATE_NEW_ALL_VISIBLE_CLEARED) - { - Relation reln = CreateFakeRelcacheEntry(rlocator); - Buffer vmbuffer = InvalidBuffer; - - visibilitymap_pin(reln, newblk, &vmbuffer); - visibilitymap_clear(reln, newblk, vmbuffer, VISIBILITYMAP_VALID_BITS); - ReleaseBuffer(vmbuffer); - FreeFakeRelcacheEntry(reln); - } - /* Deal with new tuple */ if (newaction == BLK_NEEDS_REDO) { @@ -1041,19 +1113,14 @@ heap_xlog_lock(XLogReaderState *record) if (xlrec->flags & XLH_LOCK_ALL_FROZEN_CLEARED) { RelFileLocator rlocator; - Buffer vmbuffer = InvalidBuffer; BlockNumber block; - Relation reln; XLogRecGetBlockTag(record, HEAP_LOCK_BLKREF_HEAP, &rlocator, NULL, &block); - reln = CreateFakeRelcacheEntry(rlocator); - - visibilitymap_pin(reln, block, &vmbuffer); - visibilitymap_clear(reln, block, vmbuffer, VISIBILITYMAP_ALL_FROZEN); - ReleaseBuffer(vmbuffer); - FreeFakeRelcacheEntry(reln); + heap_xlog_vm_clear(record, rlocator, + block, HEAP_LOCK_BLKREF_VM, + VISIBILITYMAP_ALL_FROZEN); } if (XLogReadBufferForRedo(record, HEAP_LOCK_BLKREF_HEAP, @@ -1119,19 +1186,14 @@ heap_xlog_lock_updated(XLogReaderState *record) if (xlrec->flags & XLH_LOCK_ALL_FROZEN_CLEARED) { RelFileLocator rlocator; - Buffer vmbuffer = InvalidBuffer; BlockNumber block; - Relation reln; XLogRecGetBlockTag(record, HEAP_LOCK_BLKREF_HEAP, &rlocator, NULL, &block); - reln = CreateFakeRelcacheEntry(rlocator); - visibilitymap_pin(reln, block, &vmbuffer); - visibilitymap_clear(reln, block, vmbuffer, VISIBILITYMAP_ALL_FROZEN); - - ReleaseBuffer(vmbuffer); - FreeFakeRelcacheEntry(reln); + heap_xlog_vm_clear(record, rlocator, + block, HEAP_LOCK_BLKREF_VM, + VISIBILITYMAP_ALL_FROZEN); } if (XLogReadBufferForRedo(record, HEAP_LOCK_BLKREF_HEAP, diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index 6f3ba9113b5..f00c9b81c1a 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -947,9 +947,11 @@ heap_page_fix_vm_corruption(PruneState *prstate, OffsetNumber offnum, if (do_clear_vm) { + LockBuffer(prstate->vmbuffer, BUFFER_LOCK_EXCLUSIVE); visibilitymap_clear(prstate->relation, prstate->block, prstate->vmbuffer, VISIBILITYMAP_VALID_BITS); + LockBuffer(prstate->vmbuffer, BUFFER_LOCK_UNLOCK); prstate->old_vmbits = 0; } } diff --git a/src/backend/access/heap/visibilitymap.c b/src/backend/access/heap/visibilitymap.c index 4fd470702aa..c382b25e192 100644 --- a/src/backend/access/heap/visibilitymap.c +++ b/src/backend/access/heap/visibilitymap.c @@ -139,21 +139,25 @@ static Buffer vm_readbuf(Relation rel, BlockNumber blkno, bool extend); static Buffer vm_extend(Relation rel, BlockNumber vm_nblocks); - /* * visibilitymap_clear - clear specified bits for one page in visibility map * - * You must pass a buffer containing the correct map page to this function. - * Call visibilitymap_pin first to pin the right one. This function doesn't do - * any I/O. Returns true if any bits have been cleared and false otherwise. + * You must pass a buffer containing the correct map page to this function, + * which already needs to be pinned and locked exclusively. + * + * This function doesn't do any I/O. Returns true if any bits have been + * cleared and false otherwise. */ bool visibilitymap_clear(Relation rel, BlockNumber heapBlk, Buffer vmbuf, uint8 flags) { - BlockNumber mapBlock = HEAPBLK_TO_MAPBLOCK(heapBlk); int mapByte = HEAPBLK_TO_MAPBYTE(heapBlk); int mapOffset = HEAPBLK_TO_OFFSET(heapBlk); +#ifdef USE_ASSERT_CHECKING + BlockNumber mapBlock = HEAPBLK_TO_MAPBLOCK(heapBlk); +#endif uint8 mask = flags << mapOffset; + Page page; char *map; bool cleared = false; @@ -165,11 +169,11 @@ visibilitymap_clear(Relation rel, BlockNumber heapBlk, Buffer vmbuf, uint8 flags elog(DEBUG1, "vm_clear %s %d", RelationGetRelationName(rel), heapBlk); #endif - if (!BufferIsValid(vmbuf) || BufferGetBlockNumber(vmbuf) != mapBlock) - elog(ERROR, "wrong buffer passed to visibilitymap_clear"); + Assert(BufferIsValid(vmbuf) && BufferGetBlockNumber(vmbuf) == mapBlock); + Assert(BufferIsLockedByMeInMode(vmbuf, BUFFER_LOCK_EXCLUSIVE)); - LockBuffer(vmbuf, BUFFER_LOCK_EXCLUSIVE); - map = PageGetContents(BufferGetPage(vmbuf)); + page = BufferGetPage(vmbuf); + map = PageGetContents(page); if (map[mapByte] & mask) { @@ -179,8 +183,6 @@ visibilitymap_clear(Relation rel, BlockNumber heapBlk, Buffer vmbuf, uint8 flags cleared = true; } - LockBuffer(vmbuf, BUFFER_LOCK_UNLOCK); - return cleared; } diff --git a/src/bin/pg_walsummary/t/002_blocks.pl b/src/bin/pg_walsummary/t/002_blocks.pl index f5fe94f9f15..bebc1137c0f 100644 --- a/src/bin/pg_walsummary/t/002_blocks.pl +++ b/src/bin/pg_walsummary/t/002_blocks.pl @@ -93,13 +93,14 @@ split(m@/@, $end_lsn); ok(-f $filename, "WAL summary file exists"); -# Run pg_walsummary on it. We expect exactly two blocks to be modified, -# block 0 and one other. +# Run pg_walsummary on it. We expect exactly three blocks to be modified, +# block 0 (old tuple), another block (new tuple), and the block for the VM. my ($stdout, $stderr) = run_command([ 'pg_walsummary', '-i', $filename ]); note($stdout); @lines = split(/\n/, $stdout); like($stdout, qr/FORK main: block 0$/m, "stdout shows block 0 modified"); +like($stdout, qr/FORK vm: block 0$/m, "stdout shows VM block 0 modified"); is($stderr, '', 'stderr is empty'); -is(0 + @lines, 2, "UPDATE modified 2 blocks"); +is(0 + @lines, 3, "UPDATE modified 3 blocks"); done_testing(); diff --git a/src/include/access/heapam_xlog.h b/src/include/access/heapam_xlog.h index fedee7f3501..3f79c389a90 100644 --- a/src/include/access/heapam_xlog.h +++ b/src/include/access/heapam_xlog.h @@ -113,6 +113,7 @@ /* This is what we need to know about delete */ #define HEAP_DELETE_BLKREF_HEAP 0 +#define HEAP_DELETE_BLKREF_VM 1 typedef struct xl_heap_delete { @@ -162,6 +163,7 @@ typedef struct xl_heap_header /* This is what we need to know about insert */ #define HEAP_INSERT_BLKREF_HEAP 0 +#define HEAP_INSERT_BLKREF_VM 1 typedef struct xl_heap_insert { @@ -225,10 +227,22 @@ typedef struct xl_multi_insert_tuple * * HEAP_UPDATE_BLKREF_HEAP_OLD: old page, if different. (no data, just a reference * to the block) + * + * HEAP_UPDATE_BLKREF_VM_NEW: VM page covering the new heap page. Registered + * when XLH_UPDATE_NEW_ALL_VISIBLE_CLEARED is set and the new heap page's VM bit + * was actually cleared. Also covers the old heap page's VM bits when both heap + * pages map to the same VM page and both blocks' VM bits were actually cleared. + * + * HEAP_UPDATE_BLKREF_VM_OLD: VM page covering the old heap page. Only + * registered when XLH_UPDATE_OLD_ALL_VISIBLE_CLEARED is set and the old heap + * page's VM bits were actually cleared. Also only registered when the old heap + * page's VM bits are on a different VM page than the new heap page's or they + * are on the same VM page and only the old block's VM bits are cleared. */ - #define HEAP_UPDATE_BLKREF_HEAP_NEW 0 #define HEAP_UPDATE_BLKREF_HEAP_OLD 1 +#define HEAP_UPDATE_BLKREF_VM_NEW 2 +#define HEAP_UPDATE_BLKREF_VM_OLD 3 typedef struct xl_heap_update { @@ -417,6 +431,7 @@ typedef struct xlhp_prune_items /* This is what we need to know about lock */ #define HEAP_LOCK_BLKREF_HEAP 0 +#define HEAP_LOCK_BLKREF_VM 1 typedef struct xl_heap_lock { diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index 55663e6f4af..be718993401 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -32,7 +32,7 @@ /* * Each page of XLOG file has a header like this: */ -#define XLOG_PAGE_MAGIC 0xD120 /* can be used as WAL version indicator */ +#define XLOG_PAGE_MAGIC 0xD121 /* can be used as WAL version indicator */ typedef struct XLogPageHeaderData { From 9171f77db2326c65fc69ab81d156622d19163b6a Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Wed, 15 Jul 2026 17:32:17 -0400 Subject: [PATCH 161/481] Test that VM clear registers VM buffers The WAL summarizer only tracks registered buffers, so unregistered VM clears are ommitted from incremental backups, corrupting the restored visibility map. Test those cases are now fixed. Author: Melanie Plageman Reviewed-by: Andrey Borodin Discussion: https://postgr.es/m/oqcsevg35xjan2327x5kdfth6q4fgeqboxfo3v3imeyih2uiny%406sez5dzxl6nt Backpatch-through: 17 --- src/bin/pg_combinebackup/Makefile | 2 + src/bin/pg_combinebackup/meson.build | 1 + .../pg_combinebackup/t/012_vm_consistency.pl | 258 ++++++++++++++++++ 3 files changed, 261 insertions(+) create mode 100644 src/bin/pg_combinebackup/t/012_vm_consistency.pl diff --git a/src/bin/pg_combinebackup/Makefile b/src/bin/pg_combinebackup/Makefile index 0d0089472e8..7a6c44d67c8 100644 --- a/src/bin/pg_combinebackup/Makefile +++ b/src/bin/pg_combinebackup/Makefile @@ -12,6 +12,8 @@ PGFILEDESC = "pg_combinebackup - combine incremental backups" PGAPPICON=win32 +EXTRA_INSTALL=contrib/pg_visibility + subdir = src/bin/pg_combinebackup top_builddir = ../../.. include $(top_builddir)/src/Makefile.global diff --git a/src/bin/pg_combinebackup/meson.build b/src/bin/pg_combinebackup/meson.build index a35b86f3f59..ba1c8cfa3d0 100644 --- a/src/bin/pg_combinebackup/meson.build +++ b/src/bin/pg_combinebackup/meson.build @@ -39,6 +39,7 @@ tests += { 't/009_no_full_file.pl', 't/010_hardlink.pl', 't/011_ib_truncation.pl', + 't/012_vm_consistency.pl', ], } } diff --git a/src/bin/pg_combinebackup/t/012_vm_consistency.pl b/src/bin/pg_combinebackup/t/012_vm_consistency.pl new file mode 100644 index 00000000000..6bf47ebec37 --- /dev/null +++ b/src/bin/pg_combinebackup/t/012_vm_consistency.pl @@ -0,0 +1,258 @@ +# Copyright (c) 2026, PostgreSQL Global Development Group +# +# Test that heap operations clearing visibility map bits (INSERT, UPDATE, +# DELETE, SELECT FOR UPDATE, COPY) correctly register visibility map buffers, +# since incremental backups rely on the WAL summarizer, which only tracks +# registered buffers. + +use strict; +use warnings FATAL => 'all'; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +my $tempdir = PostgreSQL::Test::Utils::tempdir_short(); +my $mode = $ENV{PG_TEST_PG_COMBINEBACKUP_MODE} || '--copy'; + +# Set up primary with WAL summarization enabled. +my $primary = PostgreSQL::Test::Cluster->new('primary'); +$primary->init(allows_streaming => 1); +$primary->append_conf('postgresql.conf', <start; + +$primary->safe_psql('postgres', q{CREATE EXTENSION pg_visibility}); + +my @tests = ( + { + label => 'INSERT', + table => 'vm_insert_test', + setup => q{CREATE TABLE vm_insert_test (id int); + INSERT INTO vm_insert_test DEFAULT VALUES;}, + modify => q{INSERT INTO vm_insert_test VALUES (1)}, + visible_op => '<', + frozen_op => '<', + }, + { + label => 'DELETE', + table => 'vm_delete_test', + setup => q{CREATE TABLE vm_delete_test (id int); + INSERT INTO vm_delete_test VALUES (1), (2);}, + modify => q{DELETE FROM vm_delete_test WHERE id = 1}, + visible_op => '<', + frozen_op => '<', + }, + { + label => 'UPDATE', + table => 'vm_update_test', + # Include both same-page and cross-page updates. val is stored PLAIN + # so the large update stays inline. + setup => q{CREATE TABLE vm_update_test (id INT, val TEXT); + ALTER TABLE vm_update_test ALTER COLUMN val SET STORAGE PLAIN; + INSERT INTO vm_update_test VALUES (1, 'same page'), (2, 'cross page'); + INSERT INTO vm_update_test SELECT i, repeat('a', 200) + FROM generate_series(3, 70) i;}, + modify => q{UPDATE vm_update_test SET id = 0 WHERE id = 1; + UPDATE vm_update_test SET val = repeat('b', 4000) WHERE id = 2;}, + # Confirm the small update stays on the same heap page while the large + # update relocates the tuple to a different heap page. + ctid_checks => [ + { + before => 'id = 1', + after => 'id = 0', + same => 1, + desc => 'small update stays on the same heap page', + }, + { + before => 'id = 2', + after => 'id = 2', + same => 0, + desc => 'large update moves the tuple to a different heap page', + }, + ], + visible_op => '<', + frozen_op => '<', + }, + { + label => 'LOCK', + table => 'vm_lock_test', + setup => q{CREATE TABLE vm_lock_test (id int); + INSERT INTO vm_lock_test VALUES (1), (2);}, + modify => q{SELECT * FROM vm_lock_test WHERE id = 1 FOR UPDATE}, + visible_op => '==', + frozen_op => '<', + }, + { + label => 'COPY', + table => 'vm_copy_test', + setup => q{CREATE TABLE vm_copy_test (id int); + INSERT INTO vm_copy_test DEFAULT VALUES;}, + modify => q{COPY vm_copy_test FROM PROGRAM 'echo 42'}, + visible_op => '<', + frozen_op => '<', + }, +); + +sub get_vm_summary +{ + my ($node, $table) = @_; + my $result = $node->safe_psql('postgres', + "SELECT all_visible, all_frozen FROM pg_visibility_map_summary('$table')"); + my @vals = split(/\|/, $result); + return @vals; +} + +# Return the heap block number of the (single) row matching $where. The ctid +# is "(block,offset)"; casting it through point lets us pull out the block. +sub heap_block +{ + my ($node, $table, $where) = @_; + return $node->safe_psql('postgres', + "SELECT (ctid::text::point)[0]::int FROM $table WHERE $where"); +} + +# Confirm VACUUM (FREEZE) set VM bits before testing whether later heap +# modifications clear those bits and are captured by incremental backup. We +# could perhaps be more exact than > 0, but the coarseness attempts to avoid +# test flakes. +sub check_vacuumed_vm +{ + my ($node, $test) = @_; + my ($all_visible, $all_frozen) = get_vm_summary($node, $test->{table}); + + cmp_ok($all_visible, '>', 0, + "$test->{label} test: pages are all-visible after vacuum"); + cmp_ok($all_frozen, '>', 0, + "$test->{label} test: pages are all-frozen after vacuum"); + + return ($all_visible, $all_frozen); +} + +# Check the VM bit counts after a heap modification against the post-vacuum +# baseline. Most operations clear both bits; tuple locking clears all-frozen +# without clearing all-visible. +sub check_modified_vm +{ + my ($node, $test) = @_; + my ($post_visible, $post_frozen) = get_vm_summary($node, $test->{table}); + + cmp_ok($post_visible, $test->{visible_op}, $test->{pre_visible}, + "$test->{label} test: all-visible state after modification"); + cmp_ok($post_frozen, $test->{frozen_op}, $test->{pre_frozen}, + "$test->{label} test: all-frozen state after modification"); + + return ($post_visible, $post_frozen); +} + +# Verify the combined backup restored VM state exactly as it exists on the +# primary, and ask pg_visibility to check that visible tuples are consistent. +sub validate_restored_vm +{ + my ($restored, $test) = @_; + + my ($primary_visible, $primary_frozen) = + get_vm_summary($primary, $test->{table}); + my ($restored_visible, $restored_frozen) = + get_vm_summary($restored, $test->{table}); + + is($restored_visible, $primary_visible, + "$test->{label} test: restored all_visible count matches primary"); + is($restored_frozen, $primary_frozen, + "$test->{label} test: restored all_frozen count matches primary"); + + my $corrupt_tids = $restored->safe_psql('postgres', + "SELECT count(*) FROM pg_check_visible('$test->{table}')"); + is($corrupt_tids, '0', + "$test->{label} test: no VM corruption detected by pg_check_visible"); +} + +# Create and populate the tables, then vacuum freeze them to set the VM bits +foreach my $test (@tests) +{ + $primary->safe_psql('postgres', $test->{setup}); + $primary->safe_psql('postgres', "VACUUM (FREEZE) $test->{table}"); + ($test->{pre_visible}, $test->{pre_frozen}) = + check_vacuumed_vm($primary, $test); +} + +# Take a full backup +my $full_name = 'full'; +my $full_path = $primary->backup_dir . "/$full_name"; +$primary->command_ok( + [ + 'pg_basebackup', '--no-sync', + '--pgdata' => $full_path, + '--checkpoint' => 'fast', + ], + 'full backup'); + +# Modify the tables and check that the VM bits are as expected for that test +# after the specified modification. +foreach my $test (@tests) +{ + # Record the heap block of any rows whose same-/cross-page movement we + # want to verify, before the modification relocates them. + foreach my $check (@{ $test->{ctid_checks} // [] }) + { + $check->{before_blk} = + heap_block($primary, $test->{table}, $check->{before}); + } + + $primary->safe_psql('postgres', $test->{modify}); + ($test->{post_visible}, $test->{post_frozen}) = + check_modified_vm($primary, $test); + + # Confirm each checked row did (or did not) move to a different heap page. + foreach my $check (@{ $test->{ctid_checks} // [] }) + { + my $after_blk = heap_block($primary, $test->{table}, $check->{after}); + if ($check->{same}) + { + is($after_blk, $check->{before_blk}, + "$test->{label} test: $check->{desc}"); + } + else + { + isnt($after_blk, $check->{before_blk}, + "$test->{label} test: $check->{desc}"); + } + } +} + +# Take an incremental backup. This will have the changes made in the +# modification step. +my $incr_name = 'incr'; +my $incr_path = $primary->backup_dir . "/$incr_name"; +$primary->command_ok( + [ + 'pg_basebackup', '--no-sync', + '--pgdata' => $incr_path, + '--checkpoint' => 'fast', + '--incremental' => $full_path . '/backup_manifest', + ], + 'incremental backup'); + +# Start a server from a combined backup composed of the incremental and full +# backup. +my $restored = PostgreSQL::Test::Cluster->new('restored'); +$restored->init_from_backup($primary, $incr_name, + combine_with_prior => [$full_name], + combine_mode => $mode); +$restored->append_conf('postgresql.conf', <start; +$restored->safe_psql('postgres', q{CREATE EXTENSION IF NOT EXISTS pg_visibility}); + +# Confirm that the restored server's visibility map matches the original server +foreach my $test (@tests) +{ + validate_restored_vm($restored, $test); +} + +$restored->stop; +$primary->stop; + +done_testing(); From 54bf009052edadf85658a94eeece2ea355480b23 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Thu, 16 Jul 2026 13:35:36 +0900 Subject: [PATCH 162/481] doc: Fix log_parameter_max_length docs to reference log_min_duration_statement The documentation for log_parameter_max_length said it affects messages generated by log_duration. However, log_duration alone does not log bind parameter values, so this is misleading. This commit updates the documentation to reference log_min_duration_statement, which can log bind parameters, to better reflect actual behavior. Backpatch to all supported versions. Author: Fujii Masao Reviewed-by: Surya Poondla Discussion: https://postgr.es/m/CAHGQGwGnCVMVz8-LU9F8Sh57bkQX3jMZzx7age7M0LFEz5=Fog@mail.gmail.com Backpatch-through: 14 --- doc/src/sgml/config.sgml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 45827687b9c..f0f95d7be03 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -8427,9 +8427,10 @@ log_line_prefix = '%m [%p] %q%u@%d/%a ' This setting only affects log messages printed as a result of , - , and related settings. Non-zero - values of this setting add some overhead, particularly if parameters - are sent in binary form, since then conversion to text is required. + , and related settings. + Non-zero values of this setting add some overhead, particularly + if parameters are sent in binary form, since then conversion to + text is required. From 8a84ddd8c63289e14e1e1cc2c8a4a9c41f652e1a Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Thu, 16 Jul 2026 13:37:28 +0900 Subject: [PATCH 163/481] doc: Mention REPACK in MAINTAIN privilege descriptions REPACK requires the MAINTAIN privilege, but it was omitted from the lists of commands covered by that privilege in ddl.sgml and the description of the predefined pg_maintain role in user-manag.sgml. This was an oversight in commit ac58465e061, which introduced REPACK. Add REPACK to both documentation lists, and update the corresponding comment in aclchk.c. Author: Shinya Kato Reviewed-by: Ewan Young Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CAOzEurRJOVokiB2J8nrF569nX-ZMb0oRSB0C=yZQ17mZxd4_BQ@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/ddl.sgml | 3 ++- doc/src/sgml/user-manag.sgml | 1 + src/backend/catalog/aclchk.c | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index f9b0a43ad59..3f3869df44e 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -2538,7 +2538,8 @@ REVOKE ALL ON accounts FROM PUBLIC; Allows VACUUM, ANALYZE, - CLUSTER, REFRESH MATERIALIZED VIEW, + CLUSTER, REPACK, + REFRESH MATERIALIZED VIEW, REINDEX, LOCK TABLE, and database object statistics manipulation functions (see ) on a relation. diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml index 0ec32700bd4..d68dd261012 100644 --- a/doc/src/sgml/user-manag.sgml +++ b/doc/src/sgml/user-manag.sgml @@ -660,6 +660,7 @@ GRANT pg_signal_backend TO admin_user; VACUUM, ANALYZE, CLUSTER, + REPACK, REFRESH MATERIALIZED VIEW, REINDEX, and LOCK TABLE on all diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 007ede997c5..a6e8073d02e 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -3419,8 +3419,8 @@ pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, /* * Check if ACL_MAINTAIN is being checked and, if so, and not already set * as part of the result, then check if the user is a member of the - * pg_maintain role, which allows VACUUM, ANALYZE, CLUSTER, REFRESH - * MATERIALIZED VIEW, REINDEX, and LOCK TABLE on all relations. + * pg_maintain role, which allows VACUUM, ANALYZE, CLUSTER, REPACK, + * REFRESH MATERIALIZED VIEW, REINDEX, and LOCK TABLE on all relations. */ if (mask & ACL_MAINTAIN && !(result & ACL_MAINTAIN) && From 0231fa2c3a8621450e51044d335725dae2338abb Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Thu, 16 Jul 2026 13:38:34 +0900 Subject: [PATCH 164/481] Check CREATE_REPLICATION_SLOT response shape in libpqwalreceiver Previously, libpqrcv_create_slot() checked only that CREATE_REPLICATION_SLOT returned PGRES_TUPLES_OK before reading values from the first row. If the server unexpectedly returned an invalid result, such as zero rows, PQgetvalue() could return NULL, leading to a crash while parsing the LSN. Other replication commands, such as IDENTIFY_SYSTEM, already validate the response shape before accessing result values, but CREATE_REPLICATION_SLOT did not. Fix this by verifying that CREATE_REPLICATION_SLOT response contains exactly one row with four fields, and report a protocol violation otherwise. Backpatch to all supported versions. Bug: #19547 Reported-by: Yuelin Wang <1217816127@qq.com> Author: Kenny Chen Reviewed-by: Hayato Kuroda Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/19547-f7986f668f71e788@postgresql.org Discussion: https://postgr.es/m/CAPXstDtW2iqe+DJAOTQTX+rRziJp2UhZSo1+HRj1COAtbu+nKw@mail.gmail.com Backpatch-through: 14 --- .../replication/libpqwalreceiver/libpqwalreceiver.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index 5376519fea5..b56f069a73b 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -1000,6 +1000,14 @@ libpqrcv_create_slot(WalReceiverConn *conn, const char *slotname, errmsg("could not create replication slot \"%s\": %s", slotname, pchomp(PQerrorMessage(conn->streamConn))))); + /* CREATE_REPLICATION_SLOT returns a single row with four columns */ + if (PQnfields(res) != 4 || PQntuples(res) != 1) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("invalid response from primary server"), + errdetail("Could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields.", + slotname, PQntuples(res), PQnfields(res), 1, 4))); + if (lsn) *lsn = DatumGetLSN(DirectFunctionCall1Coll(pg_lsn_in, InvalidOid, CStringGetDatum(PQgetvalue(res, 0, 1)))); From e3a27cad462f08716312e692b426747d840803c6 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Thu, 16 Jul 2026 16:05:36 +0200 Subject: [PATCH 165/481] doc: Fix link text for data checksums Commit 67846550dc6d removed the xreflabels for initdb options, which turned the sentence "The second field contains the page checksum if data checksums are enabled" into "The second field contains the page checksum if -k are enabled", as well "Only has effect if data checksums are enabled" into "Only has effect if -k are enabled". Fix by setting an explicit link text, and while there also change the link to point to the data checksum page which has more information than just the initdb option. The original report was for one instance, further inspection turned up quite a few more cases. Also redirect the link in the amcheck docs which albeit was reading right, but will be more helpful if linking to the main page on data checksums. Backpatch to v18 where the xreflabels were removed. Author: Daniel Gustafsson Reported-by: y.saburov@gmail.com Reviewed-by: Laurenz Albe Discussion: https://postgr.es/m/178350739237.73862.4549076173872335741@wrigleys.postgresql.org Backpatch-through: 18 --- doc/src/sgml/amcheck.sgml | 5 ++--- doc/src/sgml/config.sgml | 2 +- doc/src/sgml/storage.sgml | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/amcheck.sgml b/doc/src/sgml/amcheck.sgml index 08006856579..13a6bb18897 100644 --- a/doc/src/sgml/amcheck.sgml +++ b/doc/src/sgml/amcheck.sgml @@ -421,9 +421,8 @@ SET client_min_messages = DEBUG1; amcheck can be effective at detecting various types of - failure modes that data - checksums will fail to catch. These include: + failure modes that data checksums will fail + to catch. These include: diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index f0f95d7be03..124f62e6e8f 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -13183,7 +13183,7 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) - Only has effect if are enabled. + Only has effect if data checksums are enabled. Detection of a checksum failure during a read normally causes diff --git a/doc/src/sgml/storage.sgml b/doc/src/sgml/storage.sgml index 6b6377503bf..19924b98d71 100644 --- a/doc/src/sgml/storage.sgml +++ b/doc/src/sgml/storage.sgml @@ -797,7 +797,7 @@ data. Empty in ordinary tables. (PageHeaderData). Its format is detailed in . The first field tracks the most recent WAL entry related to this page. The second field contains - the page checksum if are + the page checksum if data checksums are enabled. Next is a 2-byte field containing flag bits. This is followed by three 2-byte integer fields (pd_lower, pd_upper, and From ee8f123da72d9e23e35848bfe3c2f49c02d7756c Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 17 Jul 2026 00:49:26 +0900 Subject: [PATCH 166/481] postgres_fdw: stabilize terminated-connection regression tests The regression test for postgres_fdw_get_connections(true) assumed that a terminated remote connection would still remain visible in the FDW connection cache long enough to be reported as closed with a nonzero remote_backend_pid. That assumption is not always valid. postgres_fdw_get_connections() reports only entries that are still present in ConnectionHash, while pgfdw_inval_callback() may immediately discard an idle cached connection (xact_depth == 0) when a relevant invalidation arrives. In CI, that can happen between terminating the remote backend and querying postgres_fdw_get_connections(true), causing the function to return no rows. Adjust the idle-connection test to accept either outcome: if the cache entry is still present, verify that it reports the expected server name, closed status, and nonzero remote backend PID; otherwise treat zero rows as a legitimate result. To preserve coverage of the terminated-backend reporting path, add a separate check inside an explicit transaction. In that case, concurrent invalidation may mark the connection invalid but cannot discard it before transaction end, so postgres_fdw_get_connections(true) should still report the terminated connection as in-use, closed, and associated with a nonzero remote backend PID. Backpatch to v18, where the affected postgres_fdw_get_connections(true) test was introduced. Reported-by: Robert Haas Author: Fujii Masao Reviewed-by: Robert Haas Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CA+Tgmoax3cHXHsm9OidN4F-xiu16y8q2W8T5dTNFic1Zoo2cOw@mail.gmail.com Backpatch-through: 18 --- .../postgres_fdw/expected/postgres_fdw.out | 60 ++++++++++++++++--- contrib/postgres_fdw/sql/postgres_fdw.sql | 40 +++++++++++-- 2 files changed, 87 insertions(+), 13 deletions(-) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 991501245f9..9303de98b62 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -13221,23 +13221,67 @@ SELECT server_name, loopback | f | t (1 row) --- After terminating the remote backend, since the connection is closed, --- "closed" should be TRUE, or NULL if the connection status check --- is not available. Despite the termination, remote_backend_pid should --- still show the non-zero PID of the terminated remote backend. +-- After terminating the remote backend, if the connection entry is still in +-- the cache, "closed" should be TRUE, or NULL if the connection status check +-- is not available, and remote_backend_pid should still show the non-zero PID +-- of the terminated remote backend. Concurrent invalidation can remove the +-- idle cached connection before the next statement, in which case +-- postgres_fdw_get_connections(true) can legitimately return no rows. DO $$ BEGIN PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity WHERE application_name = 'fdw_conn_check'; END $$; -SELECT server_name, +WITH terminated_conn AS ( + SELECT server_name, + CASE WHEN closed IS NOT false THEN true ELSE false END AS closed, + remote_backend_pid <> 0 AS remote_backend_pid + FROM postgres_fdw_get_connections(true) +) +SELECT CASE + WHEN count(*) = 0 THEN true + WHEN count(*) = 1 THEN bool_and(server_name = 'loopback' + AND closed + AND remote_backend_pid) + ELSE false +END AS ok +FROM terminated_conn; + ok +---- + t +(1 row) + +-- In an explicit transaction, concurrent invalidation may mark the +-- connection invalid but cannot discard it before transaction end, so the +-- terminated connection should remain visible in the cache. +SELECT 1 FROM postgres_fdw_disconnect_all(); + ?column? +---------- + 1 +(1 row) + +SET client_min_messages = 'ERROR'; +BEGIN; +SELECT 1 FROM ft1 LIMIT 1; + ?column? +---------- + 1 +(1 row) + +DO $$ BEGIN +PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_conn_check'; +END $$; +SELECT server_name, used_in_xact, CASE WHEN closed IS NOT false THEN true ELSE false END AS closed, remote_backend_pid <> 0 AS remote_backend_pid FROM postgres_fdw_get_connections(true); - server_name | closed | remote_backend_pid --------------+--------+-------------------- - loopback | t | t + server_name | used_in_xact | closed | remote_backend_pid +-------------+--------------+--------+-------------------- + loopback | t | t | t (1 row) +ABORT; +RESET client_min_messages; -- Clean up \set VERBOSITY default RESET debug_discard_caches; diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index 454deb03d69..e7019952173 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -4748,18 +4748,48 @@ SELECT server_name, WHERE application_name = 'fdw_conn_check') AS remote_backend_pid FROM postgres_fdw_get_connections(true); --- After terminating the remote backend, since the connection is closed, --- "closed" should be TRUE, or NULL if the connection status check --- is not available. Despite the termination, remote_backend_pid should --- still show the non-zero PID of the terminated remote backend. +-- After terminating the remote backend, if the connection entry is still in +-- the cache, "closed" should be TRUE, or NULL if the connection status check +-- is not available, and remote_backend_pid should still show the non-zero PID +-- of the terminated remote backend. Concurrent invalidation can remove the +-- idle cached connection before the next statement, in which case +-- postgres_fdw_get_connections(true) can legitimately return no rows. DO $$ BEGIN PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity WHERE application_name = 'fdw_conn_check'; END $$; -SELECT server_name, +WITH terminated_conn AS ( + SELECT server_name, + CASE WHEN closed IS NOT false THEN true ELSE false END AS closed, + remote_backend_pid <> 0 AS remote_backend_pid + FROM postgres_fdw_get_connections(true) +) +SELECT CASE + WHEN count(*) = 0 THEN true + WHEN count(*) = 1 THEN bool_and(server_name = 'loopback' + AND closed + AND remote_backend_pid) + ELSE false +END AS ok +FROM terminated_conn; + +-- In an explicit transaction, concurrent invalidation may mark the +-- connection invalid but cannot discard it before transaction end, so the +-- terminated connection should remain visible in the cache. +SELECT 1 FROM postgres_fdw_disconnect_all(); +SET client_min_messages = 'ERROR'; +BEGIN; +SELECT 1 FROM ft1 LIMIT 1; +DO $$ BEGIN +PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_conn_check'; +END $$; +SELECT server_name, used_in_xact, CASE WHEN closed IS NOT false THEN true ELSE false END AS closed, remote_backend_pid <> 0 AS remote_backend_pid FROM postgres_fdw_get_connections(true); +ABORT; +RESET client_min_messages; -- Clean up \set VERBOSITY default From 24a2b541bd450a2db9d8f3ddefc92ace58ef9a42 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 17 Jul 2026 00:50:54 +0900 Subject: [PATCH 167/481] Handle concurrent sequence drops during synchronization Commit d4a657b0a4d added a call to has_sequence_privilege() while fetching sequence information from the publisher, so that publisher-side permission failures could be distinguished from missing sequences. It also assumed that has_sequence_privilege() could never return NULL, and asserted accordingly. However, that assumption was incorrect. If a sequence is dropped after the synchronization worker collects its metadata but while fetching the sequence information, has_sequence_privilege() can return NULL. This can trigger the assertion failure. This was also reported in a buildfarm failure on member culicidae. Fix this by treating a NULL result from has_sequence_privilege() as indicating that the sequence was dropped concurrently, and report it as a missing sequence instead of asserting that the result is never NULL. Reported-by: Noah Misch Author: Vignesh C Reviewed-by: Hayato Kuroda Reviewed-by: Zsolt Parragi Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/20260710045217.f0.noahmisch@microsoft.com Discussion: https://postgr.es/m/CALDaNm2fHGLeiQKj0r6OG7N9QeayxSmpLrWYJRyt4dL_m3VRWw@mail.gmail.com Backpatch-through: 19 --- .../replication/logical/sequencesync.c | 15 ++++- src/test/subscription/t/036_sequences.pl | 56 ++++++++++++++++++- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/backend/replication/logical/sequencesync.c b/src/backend/replication/logical/sequencesync.c index 770fa5de10b..63ad46d7fd7 100644 --- a/src/backend/replication/logical/sequencesync.c +++ b/src/backend/replication/logical/sequencesync.c @@ -289,14 +289,23 @@ get_and_validate_seq_info(TupleTableSlot *slot, Relation *sequence_rel, *seqinfo = seqinfo_local = (LogicalRepSequenceInfo *) list_nth(seqinfos, *seqidx); + /* + * has_sequence_privilege() itself returns NULL, rather than false, when + * the sequence has been dropped concurrently after it was identified in + * the catalog snapshot (see has_sequence_privilege_id()). Treat that as a + * missing sequence on the publisher. + */ + datum = slot_getattr(slot, ++col, &isnull); + if (isnull) + return COPYSEQ_SKIPPED; + + remote_has_select_priv = DatumGetBool(datum); + /* * The remote sequence state can be NULL if the publisher lacks the * required privileges or if the sequence was dropped concurrently after * it was identified in the catalog snapshot (see pg_get_sequence_data()). */ - remote_has_select_priv = DatumGetBool(slot_getattr(slot, ++col, &isnull)); - Assert(!isnull); - datum = slot_getattr(slot, ++col, &isnull); if (isnull) return remote_has_select_priv ? COPYSEQ_SKIPPED : diff --git a/src/test/subscription/t/036_sequences.pl b/src/test/subscription/t/036_sequences.pl index 8b02b24a7e9..b3b3b20f82b 100644 --- a/src/test/subscription/t/036_sequences.pl +++ b/src/test/subscription/t/036_sequences.pl @@ -188,6 +188,60 @@ 'REFRESH PUBLICATION will not sync newly published sequence with copy_data as false' ); +########## +# A sequence dropped concurrently on the publisher, while the sequencesync +# worker's batch query is executing, must be treated the same as any other +# concurrently-dropped sequence (reported as "missing sequence on publisher"). +########## + +my $log_offset = -s $node_subscriber->logfile; + +# Block the sequencesync worker's batch query on the publisher: an +# uncommitted DROP SEQUENCE holds AccessExclusiveLock, on which the +# pg_get_sequence_data() call in the batch query will wait. +my $pub_session = $node_publisher->background_psql('postgres'); +$pub_session->query_safe( + qq( + BEGIN; + DROP SEQUENCE regress_s3; +)); + +$node_subscriber->safe_psql('postgres', + "ALTER SUBSCRIPTION regress_seq_sub REFRESH SEQUENCES"); + +# Wait until the worker's batch query is blocked on the still uncommitted +# DROP. +$node_publisher->poll_query_until( + 'postgres', qq( + SELECT EXISTS ( + SELECT 1 FROM pg_locks + WHERE relation = 'regress_s3'::regclass + AND mode = 'AccessShareLock' + AND NOT granted); +)) or die "timed out waiting for sequencesync worker to block on publisher"; + +# Commit the DROP while the batch query is blocked inside it, so the query +# resumes against a sequence that no longer exists. +# After pg_get_sequence_data() is unblocked, the batch query evaluates +# has_sequence_privilege(c.oid, 'SELECT') in the target list. Since the DROP +# has been committed by then, has_sequence_privilege() observes the missing +# sequence and returns NULL. +$pub_session->query_safe("COMMIT"); +$pub_session->quit; + +$node_subscriber->wait_for_log( + qr/WARNING: ( [A-Z0-9]+:)? missing sequence on publisher \("public.regress_s3"\)/, + $log_offset); + +$node_publisher->safe_psql( + 'postgres', qq( + CREATE SEQUENCE regress_s3; +)); + +# Wait for the recreated sequence to be synced. +$node_subscriber->poll_query_until('postgres', $synced_query) + or die "Timed out while waiting for subscriber to synchronize data"; + ########## # ALTER SUBSCRIPTION ... REFRESH PUBLICATION should report an error when: # a) sequence definitions differ between the publisher and subscriber, or @@ -206,7 +260,7 @@ CREATE SEQUENCE regress_s4 START 10 INCREMENT 2; )); -my $log_offset = -s $node_subscriber->logfile; +$log_offset = -s $node_subscriber->logfile; # Do ALTER SUBSCRIPTION ... REFRESH PUBLICATION $node_subscriber->safe_psql('postgres', From 2a933deaa23bff4245c327bc8e9f4676095d0f6c Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 16 Jul 2026 11:50:16 -0700 Subject: [PATCH 168/481] Reject infinite and out-of-range interval shifts in uuidv7(). uuidv7(interval) shifts the current time by the given interval before encoding it into the 48-bit Unix-millisecond timestamp field of the generated UUID. Two cases were mishandled: An infinite interval ('infinity' or '-infinity') produced an infinite timestamp, which overflowed during the conversion to Unix-epoch microseconds and yielded a garbage UUID. Reject infinite intervals up front, before any timestamp arithmetic. A shift that moved the timestamp outside the range representable by the 48-bit field was silently accepted. Timestamps before the Unix epoch wrapped when cast to unsigned, and timestamps beyond approximately year 10889 overflowed the field; both produced UUIDs with bogus timestamps that break sort ordering. Reject any shifted timestamp outside the supported range. Also document that infinite intervals and out-of-range shifts are rejected. Although raising a new error changes behavior in a stable branch, this is back-patched to 18 (where uuidv7(interval) was introduced) because the previous behavior can silently corrupt data. Failing loudly is far safer than silently accepting the wraparound; otherwise users may not discover that their UUIDv7 values are no longer sortable until years later, when recovery is painful. It also matches how PostgreSQL already handles timestamp + interval overflow, which raises an error. The change only affects applications passing an interval large enough to push the result outside the representable range. Backpatch to 18, where uuidv7(interval) was introduced. Reported-by: Christophe Pettus Author: Baji Shaik Reviewed-by: Masahiko Sawada Reviewed-by: Zsolt Parragi Reviewed-by: Tristan Partin Reviewed-by: Kyotaro Horiguchi Discussion: https://www.postgresql.org/message-id/799A70FA-6E5C-4118-99EB-2FBBE1CBAC54@thebuild.com Backpatch-through: 18 --- doc/src/sgml/func/func-uuid.sgml | 6 ++++ src/backend/utils/adt/uuid.c | 45 ++++++++++++++++++++++++++---- src/test/regress/expected/uuid.out | 22 +++++++++++++++ src/test/regress/sql/uuid.sql | 13 +++++++++ 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/func/func-uuid.sgml b/doc/src/sgml/func/func-uuid.sgml index 2638e2bf855..89fd5781bcc 100644 --- a/doc/src/sgml/func/func-uuid.sgml +++ b/doc/src/sgml/func/func-uuid.sgml @@ -82,6 +82,12 @@ sub-millisecond timestamp + random. The optional parameter shift will shift the computed timestamp by the given interval. + Infinite interval values are not accepted. + The shifted timestamp must fall within the range supported by + UUID version 7's 48-bit millisecond timestamp field: from + 1970-01-01 00:00:00 UTC to approximately year 10889. + An error is raised if the resulting timestamp is outside this + range. uuidv7() diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c index 6ee3752ac78..4b9a75ce217 100644 --- a/src/backend/utils/adt/uuid.c +++ b/src/backend/utils/adt/uuid.c @@ -33,6 +33,23 @@ #define NS_PER_US INT64CONST(1000) #define US_PER_MS INT64CONST(1000) +/* + * The offset between the PostgreSQL epoch (2000-01-01) and the Unix epoch + * (1970-01-01) in microseconds. Subtract this from a Unix-epoch microseconds + * to get a TimestampTz. + */ +#define PG_UNIX_EPOCH_OFFSET_US \ + ((int64) (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY * USECS_PER_SEC) + +/* + * Valid timestamp range for UUID version 7, expressed in PostgreSQL-epoch + * microseconds. UUIDv7 uses a 48-bit unsigned millisecond field relative + * to the Unix epoch, so the representable window is [1970-01-01, ~10889]. + */ +#define UUIDV7_MIN_TIMESTAMP (-PG_UNIX_EPOCH_OFFSET_US) +#define UUIDV7_MAX_TIMESTAMP \ + (((INT64CONST(1) << 48) - 1) * US_PER_MS - PG_UNIX_EPOCH_OFFSET_US) + /* * UUID version 7 uses 12 bits in "rand_a" to store 1/4096 (or 2^12) fractions of * sub-millisecond. While most Unix-like platforms provide nanosecond-precision @@ -672,6 +689,13 @@ uuidv7_interval(PG_FUNCTION_ARGS) int64 ns = get_real_time_ns_ascending(); int64 us; + /* Reject infinite intervals before any arithmetic */ + if (INTERVAL_NOT_FINITE(shift)) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("interval out of range for UUID version 7"), + errdetail("UUID version 7 does not support infinite intervals."))); + /* * Shift the current timestamp by the given interval. To calculate time * shift correctly, we convert the UNIX epoch to TimestampTz and use @@ -679,16 +703,26 @@ uuidv7_interval(PG_FUNCTION_ARGS) * precision. */ - ts = (TimestampTz) (ns / NS_PER_US) - - (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY * USECS_PER_SEC; + ts = (TimestampTz) (ns / NS_PER_US) - PG_UNIX_EPOCH_OFFSET_US; /* Compute time shift */ ts = DatumGetTimestampTz(DirectFunctionCall2(timestamptz_pl_interval, TimestampTzGetDatum(ts), IntervalPGetDatum(shift))); - /* Convert a TimestampTz value back to an UNIX epoch timestamp */ - us = ts + (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY * USECS_PER_SEC; + /* + * Reject timestamps outside the range representable by UUID version 7's + * 48-bit millisecond field. We compare in PostgreSQL-epoch units so that + * the subsequent conversion to Unix-epoch microseconds cannot overflow. + */ + if (ts < UUIDV7_MIN_TIMESTAMP || ts > UUIDV7_MAX_TIMESTAMP) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("timestamp out of range for UUID version 7"), + errdetail("UUID version 7 supports timestamps from 1970-01-01 to approximately year 10889."))); + + /* Convert the TimestampTz value to a Unix-epoch timestamp in usec */ + us = ts + PG_UNIX_EPOCH_OFFSET_US; /* Generate an UUIDv7 */ uuid = generate_uuidv7(us / US_PER_MS, (us % US_PER_MS) * NS_PER_US + ns % NS_PER_US); @@ -748,8 +782,7 @@ uuid_extract_timestamp(PG_FUNCTION_ARGS) + (((uint64) uuid->data[0]) << 40); /* convert ms to us, then adjust */ - ts = (TimestampTz) (tms * US_PER_MS) - - (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY * USECS_PER_SEC; + ts = (TimestampTz) (tms * US_PER_MS) - PG_UNIX_EPOCH_OFFSET_US; PG_RETURN_TIMESTAMPTZ(ts); } diff --git a/src/test/regress/expected/uuid.out b/src/test/regress/expected/uuid.out index 9c5dda9e9ab..e10cacbd6b9 100644 --- a/src/test/regress/expected/uuid.out +++ b/src/test/regress/expected/uuid.out @@ -261,6 +261,28 @@ SELECT y, ts, prev_ts FROM uuidts WHERE ts < prev_ts; ---+----+--------- (0 rows) +-- uuidv7: infinite intervals are rejected +SELECT uuidv7('infinity'::interval); +ERROR: interval out of range for UUID version 7 +DETAIL: UUID version 7 does not support infinite intervals. +SELECT uuidv7('-infinity'::interval); +ERROR: interval out of range for UUID version 7 +DETAIL: UUID version 7 does not support infinite intervals. +-- uuidv7: timestamps before Unix epoch are rejected +SELECT uuidv7('-1000 years'::interval); +ERROR: timestamp out of range for UUID version 7 +DETAIL: UUID version 7 supports timestamps from 1970-01-01 to approximately year 10889. +-- uuidv7: timestamps beyond 48-bit ms field (~year 10889) are rejected +SELECT uuidv7('9000 years'::interval); +ERROR: timestamp out of range for UUID version 7 +DETAIL: UUID version 7 supports timestamps from 1970-01-01 to approximately year 10889. +-- uuidv7: a large but in-range forward shift is accepted +SELECT uuid_extract_timestamp(uuidv7('1000 years'::interval)) > now() + '999 years'::interval; + ?column? +---------- + t +(1 row) + -- extract functions -- version SELECT uuid_extract_version('11111111-1111-5111-8111-111111111111'); -- 5 diff --git a/src/test/regress/sql/uuid.sql b/src/test/regress/sql/uuid.sql index 8cc2ad40614..debf84d9349 100644 --- a/src/test/regress/sql/uuid.sql +++ b/src/test/regress/sql/uuid.sql @@ -140,6 +140,19 @@ WITH uuidts AS ( ) SELECT y, ts, prev_ts FROM uuidts WHERE ts < prev_ts; +-- uuidv7: infinite intervals are rejected +SELECT uuidv7('infinity'::interval); +SELECT uuidv7('-infinity'::interval); + +-- uuidv7: timestamps before Unix epoch are rejected +SELECT uuidv7('-1000 years'::interval); + +-- uuidv7: timestamps beyond 48-bit ms field (~year 10889) are rejected +SELECT uuidv7('9000 years'::interval); + +-- uuidv7: a large but in-range forward shift is accepted +SELECT uuid_extract_timestamp(uuidv7('1000 years'::interval)) > now() + '999 years'::interval; + -- extract functions -- version From baf0ec4652c2c42c76cf108bb95860b61c1eff16 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 16 Jul 2026 12:13:16 -0700 Subject: [PATCH 169/481] Correct logical decoding status at end of recovery with minimal WAL level. Crash recovery running with wal_level='minimal' can replay an XLOG_LOGICAL_DECODING_STATUS_CHANGE record that activates logical decoding, if the server previously ran with a higher wal_level and crashed after the last logical slot was dropped but before the checkpointer deactivated logical decoding. Replaying such a record is correct since it reflects the status at the time it was written. However, UpdateLogicalDecodingStatusEndOfRecovery() asserted that logical decoding is never active with wal_level='minimal', causing an assertion failure at the end of recovery. In production builds, logical decoding would remain active while running with wal_level='minimal'. Instead of special-casing wal_level='minimal', recompute the status at the end of recovery as usual: no logical slot can exist with wal_level='minimal' as RestoreSlotFromDisk() would have rejected it, so the recomputation always deactivates logical decoding in this case, also writing the corresponding status change record. Oversight in 67c20979ce7. Reviewed-by: Guoqing Yang Reviewed-by: Hayato Kuroda Discussion: https://postgr.es/m/CAD21AoAnPAugUnDic+ESvrfXjXHk2bss9eHAD7zP0-Chy2UabA@mail.gmail.com Backpatch-through: 19 --- src/backend/replication/logical/logicalctl.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/backend/replication/logical/logicalctl.c b/src/backend/replication/logical/logicalctl.c index c11d1316450..624965ef95d 100644 --- a/src/backend/replication/logical/logicalctl.c +++ b/src/backend/replication/logical/logicalctl.c @@ -561,19 +561,17 @@ UpdateLogicalDecodingStatusEndOfRecovery(void) Assert(RecoveryInProgress()); - /* - * With 'minimal' WAL level, there are no logical replication slots during - * recovery. Logical decoding is always disabled, so there is no need to - * synchronize XLogLogicalInfo. - */ - if (wal_level == WAL_LEVEL_MINIMAL) - { - Assert(!IsXLogLogicalInfoEnabled() && !IsLogicalDecodingEnabled()); - return; - } - LWLockAcquire(LogicalDecodingControlLock, LW_EXCLUSIVE); + /* + * With 'minimal' WAL level, no logical replication slot can exist (see + * RestoreSlotFromDisk()), so the new status is always false. However, + * logical decoding could have been enabled during recovery by replaying + * an XLOG_LOGICAL_DECODING_STATUS_CHANGE record from WAL generated with a + * higher wal_level, e.g. if the server crashed right after the last + * logical slot was dropped and then restarted with wal_level='minimal'. + * The code below disables logical decoding in that case. + */ if (wal_level == WAL_LEVEL_LOGICAL || CheckLogicalSlotExists()) new_status = true; From 8e93e0c72b8aa225b0a66d4afdfb69e38d8b2424 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 16 Jul 2026 12:20:45 -0700 Subject: [PATCH 170/481] pg_controldata: Show logical decoding status. The logical decoding status is stored in checkpoint records and used to restore the status at server startup, but pg_controldata did not show it. This information is useful for diagnosing issues around the dynamic activation and deactivation of logical decoding. Oversight in 67c20979ce7. Reviewed-by: Guoqing Yang Reviewed-by: Hayato Kuroda Discussion: https://postgr.es/m/CAD21AoAnPAugUnDic+ESvrfXjXHk2bss9eHAD7zP0-Chy2UabA@mail.gmail.com Backpatch-through: 19 --- src/bin/pg_controldata/pg_controldata.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index fe5fc5ec133..6fc87ed114d 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -264,6 +264,8 @@ main(int argc, char *argv[]) ControlFile->checkPointCopy.PrevTimeLineID); printf(_("Latest checkpoint's full_page_writes: %s\n"), ControlFile->checkPointCopy.fullPageWrites ? _("on") : _("off")); + printf(_("Latest checkpoint's logical decoding: %s\n"), + ControlFile->checkPointCopy.logicalDecodingEnabled ? _("on") : _("off")); printf(_("Latest checkpoint's NextXID: %u:%u\n"), EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid), XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid)); From 048067c04c6c0c0862f0e00c4ebe158ac41bda19 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Thu, 16 Jul 2026 18:08:41 -0400 Subject: [PATCH 171/481] Use fake LSNs consistently in hash index AM. Defensively make sure that all hash index atomic actions use a fake LSN with an unlogged relation. Oversight in commit e5836f7b, which added fake LSN support to the hash index AM, but missed log_split_page. Author: Peter Geoghegan Reviewed-by: Ewan Young Discussion: https://postgr.es/m/CAH2-WzkC-opX8iS6X=a470DDC31er_x5rzPw=HjRxha9N8brZw@mail.gmail.com Backpatch-through: 19 --- src/backend/access/hash/hashpage.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/backend/access/hash/hashpage.c b/src/backend/access/hash/hashpage.c index 8099b0d021f..c50f9a48520 100644 --- a/src/backend/access/hash/hashpage.c +++ b/src/backend/access/hash/hashpage.c @@ -1477,18 +1477,20 @@ _hash_finish_split(Relation rel, Buffer metabuf, Buffer obuf, Bucket obucket, static void log_split_page(Relation rel, Buffer buf) { + XLogRecPtr recptr; + if (RelationNeedsWAL(rel)) { - XLogRecPtr recptr; - XLogBeginInsert(); XLogRegisterBuffer(0, buf, REGBUF_FORCE_IMAGE | REGBUF_STANDARD); recptr = XLogInsert(RM_HASH_ID, XLOG_HASH_SPLIT_PAGE); - - PageSetLSN(BufferGetPage(buf), recptr); } + else + recptr = XLogGetFakeLSN(rel); + + PageSetLSN(BufferGetPage(buf), recptr); } /* From 64542957b44cce7e29f1979bcfbf04477234ea3c Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Thu, 16 Jul 2026 18:55:35 -0400 Subject: [PATCH 172/481] Fix wrong variable offset sanity check. Commit c7aeb775 rewrote the HOT-chain offset sanity checks in three places, but in heap_get_root_tuples it accidentally tested offnum -- the outer loop variable, which is already bounded by the loop condition -- instead of nextoffnum, the offset actually passed to PageGetItemId. The pre-c7aeb775 check tested nextoffnum. With the check ineffective, a stale t_ctid could make PageGetItemId read past the end of the line pointer array (which is data corruption that we expect to be able to catch here). Author: Peter Geoghegan Reported-by: Konstantin Knizhnik Discussion: https://postgr.es/m/87c7d8a4-3a82-4334-bee6-e8c2ad3f3293@garret.ru Backpatch-through: 15 --- src/backend/access/heap/pruneheap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index f00c9b81c1a..704187a7268 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -2374,14 +2374,14 @@ heap_get_root_tuples(Page page, OffsetNumber *root_offsets) for (;;) { /* Sanity check (pure paranoia) */ - if (offnum < FirstOffsetNumber) + if (nextoffnum < FirstOffsetNumber) break; /* * An offset past the end of page's line pointer array is possible * when the array was truncated */ - if (offnum > maxoff) + if (nextoffnum > maxoff) break; lp = PageGetItemId(page, nextoffnum); From 2572fc53128cdbd262bf91fb2e302e0c4459be6f Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Fri, 17 Jul 2026 09:41:07 +0530 Subject: [PATCH 173/481] Doc: Clarify DROP SUBSCRIPTION behavior after SET (slot_name = NONE). The previous text claimed that once the slot is disassociated with ALTER SUBSCRIPTION ... SET (slot_name = NONE), DROP SUBSCRIPTION "will no longer attempt any actions on a remote host". That is inaccurate: DROP SUBSCRIPTION may still connect to the publisher to drop internally-created table synchronization slots when some table synchronization is left unfinished. Reword to describe this, and note that if the publisher is unreachable those slots (and the main slot, if it still exists) must be dropped manually to avoid indefinitely reserving WAL. Reported-by: Jeff Davis Author: Amit Kapila Backpatch-through: 14 Discussion: https://postgr.es/m/CAA4eK1+tyYSpPxMBy1974kjivuGeR7YY=yopwRGrK3+vCTysdg@mail.gmail.com Discussion: https://postgr.es/m/D908370F-2695-4231-851D-17179A6A6F2A@gmail.com --- doc/src/sgml/ref/drop_subscription.sgml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/ref/drop_subscription.sgml b/doc/src/sgml/ref/drop_subscription.sgml index 6e84bb0a256..209416756e5 100644 --- a/doc/src/sgml/ref/drop_subscription.sgml +++ b/doc/src/sgml/ref/drop_subscription.sgml @@ -102,12 +102,14 @@ DROP SUBSCRIPTION [ IF EXISTS ] name ALTER SUBSCRIPTION ... SET (slot_name = NONE). - After that, DROP SUBSCRIPTION will no longer attempt any - actions on a remote host. Note that if the remote replication slot still - exists, it (and any related table synchronization slots) should then be - dropped manually; otherwise it/they will continue to - reserve WAL and might eventually cause the disk to fill up. See - also . + After that, DROP SUBSCRIPTION will not attempt to drop + the subscription's own replication slot. It may still connect to the publisher + to drop internally-created table synchronization slots if some table + synchronization is left unfinished; if the publisher is unreachable, those + slots (and the main slot, if it still exists) must be dropped manually. Otherwise + it/they will continue to reserve WAL and might eventually cause the disk to + fill up. See also + . From 3aa54433b0cdce48facb610a5b720208cc760654 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 17 Jul 2026 20:16:34 +0900 Subject: [PATCH 174/481] Restrict pg_stat_io entries for data checksum processes The data checksums launcher and workers were exposed in pg_stat_io with the same broad set of object/context combinations as general background workers. However, several of those entries can never accumulate I/O statistics for these processes, such as bulkwrite, relation init, temporary relation, and launcher vacuum entries. Teach pgstat_tracks_io_object() and pgstat_tracks_io_op() about the actual I/O performed by the data checksum processes. Keep the entries needed for catalog scans, including bulkread catalog scans, worker relation processing with a vacuum access strategy, and WAL writes and initialization, while excluding WAL reads and other object/context combinations that can never be used. Author: Fujii Masao Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CAHGQGwHz_-nt+YkHDMRZNBZrnoHro8cMOgSwuXEmSYT6vxgQ=w@mail.gmail.com Backpatch-through: 19 --- src/backend/utils/activity/pgstat_io.c | 33 ++++++++++++++++++++++++++ src/test/regress/expected/stats.out | 9 +------ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/backend/utils/activity/pgstat_io.c b/src/backend/utils/activity/pgstat_io.c index 38bae7b15d2..4f7a39aaa0e 100644 --- a/src/backend/utils/activity/pgstat_io.c +++ b/src/backend/utils/activity/pgstat_io.c @@ -464,6 +464,37 @@ pgstat_tracks_io_object(BackendType bktype, IOObject io_object, io_context == IOCONTEXT_BULKWRITE) return false; + /* + * The data checksums launcher scans catalogs and emits WAL records for + * checksum state changes. Catalog scans can use a bulkread strategy. + */ + if (bktype == B_DATACHECKSUMSWORKER_LAUNCHER) + { + if (io_object == IOOBJECT_WAL || + (io_object == IOOBJECT_RELATION && + (io_context == IOCONTEXT_BULKREAD || + io_context == IOCONTEXT_NORMAL))) + return true; + + return false; + } + + /* + * The worker also scans catalogs, then processes relations using a vacuum + * access strategy. Catalog scans can use a bulkread strategy. + */ + if (bktype == B_DATACHECKSUMSWORKER_WORKER) + { + if (io_object == IOOBJECT_WAL || + (io_object == IOOBJECT_RELATION && + (io_context == IOCONTEXT_BULKREAD || + io_context == IOCONTEXT_NORMAL || + io_context == IOCONTEXT_VACUUM))) + return true; + + return false; + } + return true; } @@ -507,6 +538,8 @@ pgstat_tracks_io_op(BackendType bktype, IOObject io_object, if (io_object == IOOBJECT_WAL && io_op == IOOP_READ && (bktype == B_WAL_RECEIVER || bktype == B_BG_WRITER || bktype == B_AUTOVAC_LAUNCHER || bktype == B_AUTOVAC_WORKER || + bktype == B_DATACHECKSUMSWORKER_LAUNCHER || + bktype == B_DATACHECKSUMSWORKER_WORKER || bktype == B_WAL_WRITER)) return false; diff --git a/src/test/regress/expected/stats.out b/src/test/regress/expected/stats.out index bbb1db3c433..eb11aacfe5a 100644 --- a/src/test/regress/expected/stats.out +++ b/src/test/regress/expected/stats.out @@ -52,19 +52,12 @@ client backend|temp relation|normal client backend|wal|init client backend|wal|normal datachecksums launcher|relation|bulkread -datachecksums launcher|relation|bulkwrite -datachecksums launcher|relation|init datachecksums launcher|relation|normal -datachecksums launcher|relation|vacuum -datachecksums launcher|temp relation|normal datachecksums launcher|wal|init datachecksums launcher|wal|normal datachecksums worker|relation|bulkread -datachecksums worker|relation|bulkwrite -datachecksums worker|relation|init datachecksums worker|relation|normal datachecksums worker|relation|vacuum -datachecksums worker|temp relation|normal datachecksums worker|wal|init datachecksums worker|wal|normal io worker|relation|bulkread @@ -111,7 +104,7 @@ walsummarizer|wal|init walsummarizer|wal|normal walwriter|wal|init walwriter|wal|normal -(95 rows) +(88 rows) \a -- ensure that both seqscan and indexscan plans are allowed SET enable_seqscan TO on; From 5f57f58179bf48805558ac0494851e93fe0eca76 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Fri, 17 Jul 2026 15:40:16 +0200 Subject: [PATCH 175/481] Fix truncation rules for base64 encoding Commit e1d917182 added support for base64url encoding, a base64 variant intended to be safe for usage in URLs and filenames. The padding rules for base64url and base64 differ in that base64url require no extra '=' padding, but the commit unintentionally relaxed this requirement for base64 as well. Fix by making sure that the truncation logic check for the encoding and add a test to make sure. Backpatch down to v19 where support for base64url was introduced. Author: Daniel Gustafsson Reviewed-by: David E. Wheeler Discussion: https://postgr.es/m/3258FC72-F5E1-40B9-B5D7-64478CAF7728@yesql.se Backpatch-through: 19 --- src/backend/utils/adt/encode.c | 4 ++-- src/test/regress/expected/strings.out | 4 ++++ src/test/regress/sql/strings.sql | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/encode.c b/src/backend/utils/adt/encode.c index 9ea3ddb49ec..b9d4f2811d7 100644 --- a/src/backend/utils/adt/encode.c +++ b/src/backend/utils/adt/encode.c @@ -583,12 +583,12 @@ pg_base64_decode_internal(const char *src, size_t len, char *dst, bool url) } } - if (pos == 2) + if (url && pos == 2) { buf <<= 12; *p++ = (buf >> 16) & 0xFF; } - else if (pos == 3) + else if (url && pos == 3) { buf <<= 6; *p++ = (buf >> 16) & 0xFF; diff --git a/src/test/regress/expected/strings.out b/src/test/regress/expected/strings.out index a49b75fa1f9..313c5039465 100644 --- a/src/test/regress/expected/strings.out +++ b/src/test/regress/expected/strings.out @@ -2810,6 +2810,10 @@ SELECT decode('AQ', 'base64url'); -- \x01 \x01 (1 row) +-- Make sure the same 1 byte input isn't accepted as base64 +SELECT decode('AQ', 'base64'); -- \x01 +ERROR: invalid base64 end sequence +HINT: Input data is missing padding, is truncated, or is otherwise corrupted. -- 2 byte input SELECT encode('\x0102'::bytea, 'base64url'); -- AQI encode diff --git a/src/test/regress/sql/strings.sql b/src/test/regress/sql/strings.sql index 5ae0e7da31a..38946e8954d 100644 --- a/src/test/regress/sql/strings.sql +++ b/src/test/regress/sql/strings.sql @@ -909,6 +909,9 @@ SELECT decode('', 'base64url'); -- '' SELECT encode('\x01', 'base64url'); -- AQ SELECT decode('AQ', 'base64url'); -- \x01 +-- Make sure the same 1 byte input isn't accepted as base64 +SELECT decode('AQ', 'base64'); -- \x01 + -- 2 byte input SELECT encode('\x0102'::bytea, 'base64url'); -- AQI SELECT decode('AQI', 'base64url'); -- \x0102 From 5ccbcbdbb7df508d4d57cf24ced189e15bc6601e Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 17 Jul 2026 15:45:30 +0200 Subject: [PATCH 176/481] doc: Fix SQL quoting in example The identifier "order" needs to be quoted, just like in the example a little bit earlier. Author: Thom Brown Discussion: https://www.postgresql.org/message-id/CAA-aLv4xyAaxm8vq5LEhznh-SGphs4wUAGC6Vpas%2B1hHZzzD7A%40mail.gmail.com --- doc/src/sgml/ddl.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index 3f3869df44e..19fa5d5fda8 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -5902,7 +5902,7 @@ CREATE PROPERTY GRAPH myshop VERTEX TABLES ( products LABEL product, customers LABEL customer LABEL person PROPERTIES (name), - orders LABEL order, + orders LABEL "order", employees LABEL employee LABEL person PROPERTIES (employee_name AS name) ) EDGE TABLES ( From 6a90e70415efe1137d58072331f9101e0a00a4e6 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Fri, 17 Jul 2026 11:23:18 -0400 Subject: [PATCH 177/481] meson: Fix ccache issues when using precompiled headers with gcc Unfortunately the combination of gcc, precompiled headers, ccache and meson currently is not safe without further options. The dependencies emitted by gcc are insufficient to trigger rebuilds when headers "below" the precompiled headers are changed. Whether that's a ccache, gcc or meson bug is debatable. Luckily gcc's -fpch-deps option fixes the issue. This problem occasionally leads to build failures, e.g. if only c.h, postgres.h or pg_config_manual.h change. That's e.g. the case when creating a new major version branch. Reviewed-by: Nazir Bilal Yavuz Reviewed-by: Jelte Fennema-Nio Discussion: https://postgr.es/m/CAN55FZ0tqR6Xz%3DiVFLc1BBoLOEHU775ARhcGYwggHA3XLA%3DoQg%40mail.gmail.com Discussion: https://postgr.es/m/CA+hUKG+s7Yvt0PUnSQUEjCjysV-7-51n9B1h468Le3VJi0x4ZQ@mail.gmail.com Discussion: https://postgr.es/m/phsrssp75npoyalqsolcd7fmnmlbzbmquc2p7w7mqjlw7432jk@bzskz3luyjvb Discussion: https://github.com/ccache/ccache/issues/1686 Backpatch-through: 16, where meson support was added --- meson.build | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/meson.build b/meson.build index 1a807981e11..d4986ef9a23 100644 --- a/meson.build +++ b/meson.build @@ -2200,6 +2200,12 @@ common_functional_flags = [ # Disable optimizations that assume no overflow; needed for gcc 4.3+ '-fwrapv', '-fexcess-precision=standard', + # Without -fpch-deps gcc emits dependencies that are insufficient for ccache + # to trigger a rebuild when the precompiled header changes. We could make + # this depend on using gcc and precompiled headers being enabled, but that's + # probably not worth it. See also + # https://github.com/ccache/ccache/issues/1686 + '-fpch-deps', ] cflags += cc.get_supported_arguments(common_functional_flags) From cce2bbbfd3cb8df4844013d20c3e08cef6d29084 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Fri, 17 Jul 2026 11:43:52 -0400 Subject: [PATCH 178/481] ci: Use optimized build for mingw The test runtime dominates over the compile time on GHA. Note that we just need to remove options, as postgres's default is debugoptimized. Reviewed-by: Nazir Bilal Yavuz Discussion: https://postgr.es/m/a2ejn7lfqolutzz7kozalbhy3bixdrujb4buc3pgbtlk4am2ba@wbv6v7riia33 Backpatch-through: 19, where GHA CI was added --- .github/workflows/pg-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pg-ci.yml b/.github/workflows/pg-ci.yml index 5bc5292d2a5..b1731cf40cd 100644 --- a/.github/workflows/pg-ci.yml +++ b/.github/workflows/pg-ci.yml @@ -1123,7 +1123,7 @@ jobs: run: | meson setup \ ${{env.MESON_COMMON_PG_CONFIG_ARGS}} \ - -Ddebug=true -Doptimization=g -Db_pch=true \ + -Db_pch=true \ ${{env.MESON_COMMON_FEATURES}} \ ${{env.MESON_FEATURES}} \ -DTAR=${{env.TAR}} \ From 3601be26b3fa076e1aa03e9f1e0ad0e6077ce759 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Fri, 17 Jul 2026 11:43:52 -0400 Subject: [PATCH 179/481] ci: Generate crashlogs on Windows This configures cdb.exe to log all crashes to "\crashlogs\crashlog-.txt" (as it was previously set up for cirrus-ci based CI). The upload logs step already collects these logs. The logic is copied from the generation of Postgres CI Windows images for cirrus-ci [1]. Since this would be too long to include inline in pg-ci.yml, it is implemented as 'src/tools/ci/gha_setup_windows_debugger.ps1' script. [1] https://github.com/anarazel/pg-vm-images/blob/main/scripts/windows_install_dbg.ps1 Author: Nazir Bilal Yavuz Reviewed-by: Andres Freund Discussion: https://postgr.es/m/CAN55FZ1BgsXSTzOpehnMa4NzWL8Aivsxx-di7-VT6bZ3j2Omow%40mail.gmail.com Discussion: https://postgr.es/m/iggjozfshwbqpv33x5jqwtju5k5zrkyu3257dlifxkhtpg7eoq@k2ccyrdi5dtu Backpatch-through: 19, where GHA CI was added --- .github/workflows/pg-ci.yml | 13 ++-- src/tools/ci/gha_setup_windows_debugger.ps1 | 75 +++++++++++++++++++++ 2 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 src/tools/ci/gha_setup_windows_debugger.ps1 diff --git a/.github/workflows/pg-ci.yml b/.github/workflows/pg-ci.yml index b1731cf40cd..a2629c8335a 100644 --- a/.github/workflows/pg-ci.yml +++ b/.github/workflows/pg-ci.yml @@ -990,6 +990,11 @@ jobs: shell: cmd run: mkdir ${{env.PG_REGRESS_SOCK_DIR}} + - &windows_setup_debugger_step + name: Setup Windows debugger + shell: pwsh + run: src/tools/ci/gha_setup_windows_debugger.ps1 + - name: Configure run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 @@ -1019,9 +1024,6 @@ jobs: call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 run: *meson_test_world_cmd - # TODO: We need to collect crashlogs but for them to be generated, we'd - # have to configure the JIT Debugger to do so. cdb.exe is installed on - # the runner so that is possible. - *upload_logs_step @@ -1116,6 +1118,8 @@ jobs: shell: cmd run: mkdir ${{env.PG_REGRESS_SOCK_DIR}} + - *windows_setup_debugger_step + - *ccache_restore_default_step - *ccache_restore_branch_step @@ -1138,9 +1142,6 @@ jobs: - name: Test world run: *meson_test_world_cmd - # TODO: We want to include crashlogs, but they are not yet - # collected. cdb.exe is installed on the runner, so we can configure it - # appropriately. - *upload_logs_step diff --git a/src/tools/ci/gha_setup_windows_debugger.ps1 b/src/tools/ci/gha_setup_windows_debugger.ps1 new file mode 100644 index 00000000000..babfbe76278 --- /dev/null +++ b/src/tools/ci/gha_setup_windows_debugger.ps1 @@ -0,0 +1,75 @@ +# Setup Windows debugger to log all crashes to +# \crashlogs\crashlog-.txt + +$ErrorActionPreference = 'Stop' + +$crashdir = "$env:GITHUB_WORKSPACE/crashlogs" +New-Item -ItemType Directory -Force -Path $crashdir + +# Ensure restricted child processes can write the log file +icacls $crashdir /grant "${env:USERNAME}:(OI)(CI)F" /Q + +# Prevent windows error handling dialog from causing hangs +New-ItemProperty -Force -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting' ` + -Name 'DontShowUI' -Value 1 -PropertyType DWord +New-ItemProperty -Force -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting' ` + -Name 'Disabled' -Value 1 -PropertyType DWord + +### Fallback minidumps if the JIT debugger below doesn't run +New-Item -Force -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting' ` + -Name 'LocalDumps' +New-ItemProperty -Force -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps' ` + -Name 'DumpFolder' -Value $crashdir -PropertyType ExpandString +New-ItemProperty -Force -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps' ` + -Name 'DumpCount' -Value 5 -PropertyType DWord +New-ItemProperty -Force -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps' ` + -Name 'DumpType' -Value 1 -PropertyType DWord +### + +$cdb64 = @( + 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe', + 'C:\Program Files\Windows Kits\10\Debuggers\x64\cdb.exe' + ) | Where-Object { Test-Path $_ } | Select-Object -First 1 +$cdb86 = $cdb64.Replace('\x64\', '\x86\') + +### +# -p PID: +# Specifies the decimal process ID to be debugged. This is used to debug a +# process that is already running. +# -e Event: +# Signals the debugger that the specified event has occurred. This option is +# only used when starting the debugger programmatically. +# -g: +# Ignores the initial breakpoint in target application. This option will +# cause the target application to continue running after it is started or +# CDB attaches to it, unless another breakpoint has been set. +# -kqm: +# Starts CDB/NTSD in quiet mode. +# -c "command": +# Specifies the initial debugger command to run at start-up. This command +# must be surrounded with quotation marks. Multiple commands can be +# separated with semicolons. +### +$debuggerArgs = ' -p %ld -e %ld -g -kqm -c ".lines -e; .symfix+ ; aS /x proc $tpid ; .block {.logappend ' + "$crashdir/crashlog-" + '${proc}.txt} ; lsa $ip ; ~*kP ; !peb ; .logclose ; q "' + +Write-Host "Using cdb (x64): $cdb64" +Set-ItemProperty ` + -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug' ` + -Name 'Debugger' -Value ('"' + $cdb64 + '"' + $debuggerArgs) +New-ItemProperty -Force -PropertyType DWord -Value 1 ` + -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug' ` + -Name 'Auto' + +Write-Host "Using cdb (x86): $cdb86" +Set-ItemProperty ` + -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug' ` + -Name 'Debugger' -Value ('"' + $cdb86 + '"' + $debuggerArgs) +New-ItemProperty -Force -PropertyType DWord -Value 1 ` + -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug' ` + -Name 'Auto' + +# Show registered AeDebug values for diagnostics +Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug' | + Format-List Debugger,Auto +Get-ItemProperty 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug' | + Format-List Debugger,Auto From 1d4c81ad6266fb2e534fe2e6de8d0050041a4ad6 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Fri, 17 Jul 2026 15:53:07 -0400 Subject: [PATCH 180/481] Fix GiST index-only scan column alignment issue. An index-only scan filled its result slot from the HeapTuple an index AM returns in scan->xs_hitup by deforming it with the virtual slot's own tuple descriptor (during GiST and SP-GiST index-only scans). But index AMs form that heap tuple using their own descriptor, scan->xs_hitupdesc. The AM's descriptor may disagree with the IoS virtual slot's descriptor about each column's precise alignment, leading to "can't happen" errors in certain rare edge cases. Hard crashes were possible but much less likely. To fix, deform the tuple with the descriptor it was formed with. This is simpler, and makes xs_hitup handling (used by GiST and SP-GiST) uniform with the nearby existing xs_itup handling (used by nbtree). In practice this issue was very unlikely to be hit (it was found during testing of a patch that will change the table AM API used during index scans). The only currently affected core opclass is GiST's range_ops. It was only possible for the datum to be accessed at an incorrectly aligned offset when reading the second or subsequent column from a multicolumn GiST index. This couldn't happen in the common case where the datum used an unaligned short varlena header. Moreover, an earlier column had to leave the range datum at an offset where the two alignments actually disagree (e.g., an odd-length varlena datum). Author: Peter Geoghegan Reviewed-by: Tomas Vondra Discussion: https://postgr.es/m/CAH2-WzkGXa2SKnebdW29RT1hCcQBo_p03v3iqif2u9bjzLB-aQ@mail.gmail.com Backpatch-through: 14 --- src/backend/executor/nodeIndexonlyscan.c | 113 ++++++++++++----------- src/test/regress/expected/gist.out | 36 ++++++++ src/test/regress/sql/gist.sql | 29 ++++++ 3 files changed, 124 insertions(+), 54 deletions(-) diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c index d52012e8a69..8afcbde6b97 100644 --- a/src/backend/executor/nodeIndexonlyscan.c +++ b/src/backend/executor/nodeIndexonlyscan.c @@ -31,6 +31,7 @@ #include "postgres.h" #include "access/genam.h" +#include "access/htup_details.h" #include "access/relscan.h" #include "access/tableam.h" #include "access/tupdesc.h" @@ -49,7 +50,7 @@ static TupleTableSlot *IndexOnlyNext(IndexOnlyScanState *node); static void StoreIndexTuple(IndexOnlyScanState *node, TupleTableSlot *slot, - IndexTuple itup, TupleDesc itupdesc); + IndexScanDesc scandesc); /* ---------------------------------------------------------------- @@ -193,27 +194,8 @@ IndexOnlyNext(IndexOnlyScanState *node) tuple_from_heap = true; } - /* - * Fill the scan tuple slot with data from the index. This might be - * provided in either HeapTuple or IndexTuple format. Conceivably an - * index AM might fill both fields, in which case we prefer the heap - * format, since it's probably a bit cheaper to fill a slot from. - */ - if (scandesc->xs_hitup) - { - /* - * We don't take the trouble to verify that the provided tuple has - * exactly the slot's format, but it seems worth doing a quick - * check on the number of fields. - */ - Assert(slot->tts_tupleDescriptor->natts == - scandesc->xs_hitupdesc->natts); - ExecForceStoreHeapTuple(scandesc->xs_hitup, slot, false); - } - else if (scandesc->xs_itup) - StoreIndexTuple(node, slot, scandesc->xs_itup, scandesc->xs_itupdesc); - else - elog(ERROR, "no data returned for index-only scan"); + /* Fill the scan tuple slot with data from the index */ + StoreIndexTuple(node, slot, scandesc); /* * If the index was lossy, we have to recheck the index quals. @@ -263,56 +245,79 @@ IndexOnlyNext(IndexOnlyScanState *node) /* * StoreIndexTuple - * Fill the slot with data from the index tuple. + * Fill the slot with the data the index AM returned. + * + * The data might be provided in either HeapTuple (xs_hitup) or IndexTuple + * (xs_itup) format. Conceivably an index AM might fill both fields, in which + * case we prefer the heap format, since it's probably a bit cheaper to fill a + * slot from. * * At some point this might be generally-useful functionality, but * right now we don't need it elsewhere. */ static void StoreIndexTuple(IndexOnlyScanState *node, TupleTableSlot *slot, - IndexTuple itup, TupleDesc itupdesc) + IndexScanDesc scandesc) { - /* - * Note: we must use the tupdesc supplied by the AM in index_deform_tuple, - * not the slot's tupdesc, in case the latter has different datatypes - * (this happens for btree name_ops in particular). They'd better have - * the same number of columns though, as well as being datatype-compatible - * which is something we can't so easily check. - */ - Assert(slot->tts_tupleDescriptor->natts == itupdesc->natts); - ExecClearTuple(slot); - index_deform_tuple(itup, itupdesc, slot->tts_values, slot->tts_isnull); /* - * Copy all name columns stored as cstrings back into a NAMEDATALEN byte - * sized allocation. We mark this branch as unlikely as generally "name" - * is used only for the system catalogs and this would have to be a user - * query running on those or some other user table with an index on a name - * column. + * We must deform the tuple using the tupdesc the index AM formed it with + * (xs_hitupdesc or xs_itupdesc), not the slot's tupdesc. The datums + * returned by the index AM must be binary compatible, but the descriptors + * may align each column differently in certain rare cases. (Actually, + * btree's "name" opclass stores cstring tuples that _aren't_ even binary + * compatible, in the strictest sense. We directly handle that here.) */ - if (unlikely(node->ioss_NameCStringAttNums != NULL)) + if (scandesc->xs_hitup) { - int attcount = node->ioss_NameCStringCount; + Assert(slot->tts_tupleDescriptor->natts == scandesc->xs_hitupdesc->natts); - for (int idx = 0; idx < attcount; idx++) - { - int attnum = node->ioss_NameCStringAttNums[idx]; - Name name; + heap_deform_tuple(scandesc->xs_hitup, scandesc->xs_hitupdesc, + slot->tts_values, slot->tts_isnull); + } + else if (scandesc->xs_itup) + { + Assert(slot->tts_tupleDescriptor->natts == scandesc->xs_itupdesc->natts); - /* skip null Datums */ - if (slot->tts_isnull[attnum]) - continue; + index_deform_tuple(scandesc->xs_itup, scandesc->xs_itupdesc, + slot->tts_values, slot->tts_isnull); - /* allocate the NAMEDATALEN and copy the datum into that memory */ - name = (Name) MemoryContextAlloc(node->ss.ps.ps_ExprContext->ecxt_per_tuple_memory, - NAMEDATALEN); + /* + * Copy all name columns stored as cstrings back into a NAMEDATALEN + * byte sized allocation. We mark this branch as unlikely as + * generally "name" is used only for the system catalogs and this + * would have to be a user query running on those or some other user + * table with an index on a name column. + */ + if (unlikely(node->ioss_NameCStringAttNums != NULL)) + { + int attcount = node->ioss_NameCStringCount; - /* use namestrcpy to zero-pad all trailing bytes */ - namestrcpy(name, DatumGetCString(slot->tts_values[attnum])); - slot->tts_values[attnum] = NameGetDatum(name); + for (int idx = 0; idx < attcount; idx++) + { + int attnum = node->ioss_NameCStringAttNums[idx]; + Name name; + + /* skip null Datums */ + if (slot->tts_isnull[attnum]) + continue; + + /* + * allocate the NAMEDATALEN and copy the datum into that + * memory + */ + name = (Name) MemoryContextAlloc(node->ss.ps.ps_ExprContext->ecxt_per_tuple_memory, + NAMEDATALEN); + + /* use namestrcpy to zero-pad all trailing bytes */ + namestrcpy(name, DatumGetCString(slot->tts_values[attnum])); + slot->tts_values[attnum] = NameGetDatum(name); + } } } + else + elog(ERROR, "no data returned for index-only scan"); ExecStoreVirtualTuple(slot); } diff --git a/src/test/regress/expected/gist.out b/src/test/regress/expected/gist.out index c75bbb23b6e..ae5b522b3c6 100644 --- a/src/test/regress/expected/gist.out +++ b/src/test/regress/expected/gist.out @@ -387,6 +387,42 @@ select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1; select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1; ERROR: lossy distance functions are not supported in index-only scans +-- Test that an index-only scan deforms the tuple it reconstructs with the +-- descriptor the AM formed it with, not the scan slot's descriptor. +create temp table gist_ios_tupdesc (a inet, r numrange); +-- range_ops forms its tuples using the opclass input type, the polymorphic +-- anyrange (alignment 'd'), while the scan slot uses the actual range type +-- numrange (alignment 'i'). A buggy implementation will incorrectly access +-- the r/numrange column at the wrong offset. +-- +-- The range bounds are made long so the value needs a four-byte varlena +-- header; shorter values get a one-byte header and are stored without +-- alignment padding, which would mask the problem. +insert into gist_ios_tupdesc +values ( + '::1', -- shifts "r" datum value to differing offset + numrange(repeat('7', 200)::numeric, repeat('8', 200)::numeric)); +create index on gist_ios_tupdesc using gist (a inet_ops, r); +vacuum analyze gist_ios_tupdesc; +explain (costs off) +select lower(r) = repeat('7', 200)::numeric as lower_ok, + upper(r) = repeat('8', 200)::numeric as upper_ok + from gist_ios_tupdesc where r && numrange(null, null); + QUERY PLAN +-------------------------------------------------------------------- + Index Only Scan using gist_ios_tupdesc_a_r_idx on gist_ios_tupdesc + Index Cond: (r && '(,)'::numrange) +(2 rows) + +select lower(r) = repeat('7', 200)::numeric as lower_ok, + upper(r) = repeat('8', 200)::numeric as upper_ok + from gist_ios_tupdesc where r && numrange(null, null); + lower_ok | upper_ok +----------+---------- + t | t +(1 row) + +drop table gist_ios_tupdesc; -- Force an index build using buffering. create index gist_tbl_box_index_forcing_buffering on gist_tbl using gist (p) with (buffering=on, fillfactor=50); diff --git a/src/test/regress/sql/gist.sql b/src/test/regress/sql/gist.sql index 6f1fc65f128..1ebb1d9ee43 100644 --- a/src/test/regress/sql/gist.sql +++ b/src/test/regress/sql/gist.sql @@ -169,6 +169,35 @@ explain (verbose, costs off) select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1; select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1; +-- Test that an index-only scan deforms the tuple it reconstructs with the +-- descriptor the AM formed it with, not the scan slot's descriptor. +create temp table gist_ios_tupdesc (a inet, r numrange); + +-- range_ops forms its tuples using the opclass input type, the polymorphic +-- anyrange (alignment 'd'), while the scan slot uses the actual range type +-- numrange (alignment 'i'). A buggy implementation will incorrectly access +-- the r/numrange column at the wrong offset. +-- +-- The range bounds are made long so the value needs a four-byte varlena +-- header; shorter values get a one-byte header and are stored without +-- alignment padding, which would mask the problem. +insert into gist_ios_tupdesc +values ( + '::1', -- shifts "r" datum value to differing offset + numrange(repeat('7', 200)::numeric, repeat('8', 200)::numeric)); +create index on gist_ios_tupdesc using gist (a inet_ops, r); +vacuum analyze gist_ios_tupdesc; + +explain (costs off) +select lower(r) = repeat('7', 200)::numeric as lower_ok, + upper(r) = repeat('8', 200)::numeric as upper_ok + from gist_ios_tupdesc where r && numrange(null, null); +select lower(r) = repeat('7', 200)::numeric as lower_ok, + upper(r) = repeat('8', 200)::numeric as upper_ok + from gist_ios_tupdesc where r && numrange(null, null); + +drop table gist_ios_tupdesc; + -- Force an index build using buffering. create index gist_tbl_box_index_forcing_buffering on gist_tbl using gist (p) with (buffering=on, fillfactor=50); From 3b5a3cfb903eca6dfc87319e0ac29e3e23430e08 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 17 Jul 2026 15:56:54 -0400 Subject: [PATCH 181/481] doc PG 19 relnote: move Oauth items Reported-by: Jacob Champion Author: Jacob Champion Discussion: https://postgr.es/m/CAOYmi+k5h_w5p6HsVJF5k+bNGmChMAhpGU_1gjJMxHg080XibA@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/release-19.sgml | 92 +++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/doc/src/sgml/release-19.sgml b/doc/src/sgml/release-19.sgml index cc47c190c9c..75f0ea04fda 100644 --- a/doc/src/sgml/release-19.sgml +++ b/doc/src/sgml/release-19.sgml @@ -1341,17 +1341,13 @@ New configuration file PGDATA/pg_hosts. -Allow OAUTH validators to supply failure details (Jacob Champion) -§ - - - -This is done by setting the ValidatorModuleResult structure member error_detail. +Allow OAuth validators to register custom pg_hba.conf authentication options (Jacob Champion, Zsolt Parragi) +§ @@ -2317,20 +2313,12 @@ Author: Jacob Champion -Add special libpq protocol version 3.9999 for version testing (Jelte Fennema-Nio) +Add special libpq protocol parameters for compatibility testing (Jelte Fennema-Nio, Jacob Champion) § - - - - -Add libpq function PQgetThreadLock() to retrieve the current locking callback (Jacob Champion) -§ +Otherwise known as protocol grease, which was active during the 19 beta period. These will no longer be sent as of the PostgreSQL 19 official release, but the parameter reservations will remain for potential use in the future. @@ -2341,7 +2329,7 @@ Author: Jacob Champion -Add libpq connection parameter oauth_ca_file to specify the OAUTH certificate authority file (Jonathan Gonzalez V., Jacob Champion) +Add libpq connection parameter oauth_ca_file to specify an alternate certificate authority when communicating with OAuth providers (Jonathan Gonzalez V., Jacob Champion) § @@ -2352,29 +2340,48 @@ This can also be set via the PGOAUTHCAFILE -2026-04-07 [b977bd308] oauth: Allow validators to register custom HBA options +2026-04-07 [6d00fb904] libpq: Split PGOAUTHDEBUG=UNSAFE into multiple options --> -Allow OAUTH validators to register custom pg_hba.conf authentication options (Jacob Champion) -§ +Allow libpq environment variable PGOAUTHDEBUG to specify particular debug options (Zsolt Parragi, Jacob Champion) +§ + + + +The UNSAFE option still generates all debugging output. -Allow libpq environment variable PGOAUTHDEBUG to specify particular debug options (Zsolt Parragi, Jacob Champion) -§ +Improve custom OAuth client flows (Jacob Champion) +§ +§ -The UNSAFE option still generates all debugging output. +Previously, libpq reported only a generic error message during custom flow failures, and each flow implementation was required to calculate the issuer identifier independently. Add a new authdata hook type PQAUTHDATA_OAUTH_BEARER_TOKEN_V2 that precomputes the issuer ID and lets hooks provide error details. + + + + + + + +Add libpq function PQgetThreadLock() to retrieve the current locking callback (Jacob Champion) +§ @@ -2956,25 +2963,6 @@ Allow extensions to replace se - - - - -Add a new OAUTH flow hook PQAUTHDATA_OAUTH_BEARER_TOKEN_V2 (Jacob Champion) -§ -§ - - - -This is an improved version of PQAUTHDATA_OAUTH_BEARER_TOKEN by adding the issuer identifier and error message specification. - - - + + + +Allow OAuth validators to supply failure details (Jacob Champion) +§ + + + +This is done by setting the ValidatorModuleResult structure member error_detail. + + + + + + +Change psql's \crosstab command to honor the \pset null setting (Chao Li) +§ + + + - - - -Add GROUP BY ALL syntax to SELECT to automatically group all non-aggregate and non-window-function target list parameters (David Christensen) -§ - - - + + + +Allow pg_dump to include restorable extended statistics (Corey Huinker) +§ + + + - - - -Allow pg_dump to include restorable extended statistics (Corey Huinker) -§ - - - <link linkend="app-pgcreatesubscriber"><application>pg_createsubscriber</application></link> From f7bc98156e1170c60a03dfbeee7871e59888de82 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Sat, 18 Jul 2026 20:43:24 -0400 Subject: [PATCH 191/481] doc PG 19 relnotes: \crosstab to \crosstabview Backpatch-through: 19 only --- doc/src/sgml/release-19.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/release-19.sgml b/doc/src/sgml/release-19.sgml index 7e93f7a8b95..21f1be994d0 100644 --- a/doc/src/sgml/release-19.sgml +++ b/doc/src/sgml/release-19.sgml @@ -314,7 +314,7 @@ Author: Álvaro Herrera -Change psql's \crosstab command to honor the \pset null setting (Chao Li) +Change psql's \crosstabview command to honor the \pset null setting (Chao Li) § From 829bacaeb323e4811eb804b5e4e29f643a0c619d Mon Sep 17 00:00:00 2001 From: Tatsuo Ishii Date: Sun, 19 Jul 2026 10:47:29 +0900 Subject: [PATCH 192/481] Remove redundant null-treatment check in window function dedup. Commit 25a30bbd423 (IGNORE NULLS / RESPECT NULLS for window functions) made ExecInitWindowAgg() treat two otherwise-equal window functions as duplicates only when their ignore_nulls settings also matched: if (i <= wfuncno && wfunc->ignore_nulls == perfunc[i].ignore_nulls) That extra term reads WindowStatePerFuncData.ignore_nulls, but the field was never populated when a per-function entry was filled in, so it stayed zero from palloc0_array(). Consequently a duplicate call carrying IGNORE NULLS or an explicit RESPECT NULLS never matched an identical earlier entry and was needlessly given its own per-function slot and evaluated twice. (Results stayed correct; this was a missed sharing, not a wrong answer.) The extra term is in fact redundant. WindowFunc.ignore_nulls is a plain scalar field with no pg_node_attr, so _equalWindowFunc() already compares it; the preceding equal() call therefore never matches two WindowFuncs that differ only in null treatment. If equal() matches, ignore_nulls necessarily matched too, so the term can never change the outcome, and WindowStatePerFuncData.ignore_nulls existed only to feed it. Rather than populate the shadow field, drop the redundant term and the field (and adjust the now-stale comment) and let equal() do the work. That fixes the same bug while removing the hand-maintained duplicate state that caused it, so it cannot silently drift again. Author: Chao Li Co-authored-by: Ewan Young Reviewed-by: Tatsuo Ishii Discussion: https://postgr.es/m/5D2C9081-5DFE-4E27-AB14-7358238EA1BC%40gmail.com Backpatch-through: 19 --- src/backend/executor/nodeWindowAgg.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index f1c524d00df..7d6ec2dfc4b 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -110,7 +110,6 @@ typedef struct WindowStatePerFuncData bool plain_agg; /* is it just a plain aggregate function? */ int aggno; /* if so, index of its WindowStatePerAggData */ - uint8 ignore_nulls; /* ignore nulls */ WindowObject winobj; /* object used in window function API */ } WindowStatePerFuncData; @@ -2737,17 +2736,14 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) elog(ERROR, "WindowFunc with winref %u assigned to WindowAgg with winref %u", wfunc->winref, node->winref); - /* - * Look for a previous duplicate window function, which needs the same - * ignore_nulls value - */ + /* Look for a previous duplicate window function */ for (i = 0; i <= wfuncno; i++) { if (equal(wfunc, perfunc[i].wfunc) && !contain_volatile_functions((Node *) wfunc)) break; } - if (i <= wfuncno && wfunc->ignore_nulls == perfunc[i].ignore_nulls) + if (i <= wfuncno) { /* Found a match to an existing entry, so just mark it */ wfuncstate->wfuncno = i; From dfde93581dcfab7509b6b28863c5270eb8d94754 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Sun, 19 Jul 2026 23:27:52 +0200 Subject: [PATCH 193/481] Fix parsing of underscores in pg_plan_advice occurrence numbers The pg_plan_advice scanner recognizes underscores as digit separators just like the core parser, but used strtoint() to convert occurrence numbers which does not support underscores. Consequently, advice such as SEQ_SCAN(x#1_0) failed to parse. Fix by using pg_strtoint32_safe() like the core scanner, and also add regression test coverage. This bug was independently found and reported by Lukas Fittl and Chao Li. Backpatch down to v19 where pg_plan_advice was introduced. Author: Chao Li Co-authored-by: Daniel Gustafsson Reported-by: Lukas Fittl Reported-by: Chao Li Reviewed-by: Daniel Gustafsson Reviewed-by: Lukas Fittl Discussion: https://postgr.es/m/22E2ECE0-B768-43D5-8575-61C3EBC2E4E8@gmail.com Discussion: https://postgr.es/m/CAP53PkzKeD=t90OfeMsniYrcRe2THQbUx3g6wV17Y=ZtiwmWTQ@mail.gmail.com Backpatch-through: 19 --- contrib/pg_plan_advice/expected/syntax.out | 16 ++++++++++++++++ contrib/pg_plan_advice/pgpa_scanner.l | 17 ++++++++++++----- contrib/pg_plan_advice/sql/syntax.sql | 6 ++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/contrib/pg_plan_advice/expected/syntax.out b/contrib/pg_plan_advice/expected/syntax.out index c61fd73a385..3b57bb2bf57 100644 --- a/contrib/pg_plan_advice/expected/syntax.out +++ b/contrib/pg_plan_advice/expected/syntax.out @@ -65,6 +65,15 @@ EXPLAIN (COSTS OFF) SELECT 1; SEQ_SCAN(x#2) /* not matched */ (3 rows) +SET pg_plan_advice.advice = 'SEQ_SCAN(x#1_0)'; +EXPLAIN (COSTS OFF) SELECT 1; + QUERY PLAN +------------------------------------ + Result + Supplied Plan Advice: + SEQ_SCAN(x#10) /* not matched */ +(3 rows) + SET pg_plan_advice.advice = 'SEQ_SCAN (x/y)'; EXPLAIN (COSTS OFF) SELECT 1; QUERY PLAN @@ -114,12 +123,19 @@ DETAIL: Could not parse advice: syntax error at end of input SET pg_plan_advice.advice = 'SEQ_SCAN(#'; ERROR: invalid value for parameter "pg_plan_advice.advice": "SEQ_SCAN(#" DETAIL: Could not parse advice: syntax error at or near "#" +SET pg_plan_advice.advice = 'SEQ_SCAN(x#1_0_)'; +ERROR: invalid value for parameter "pg_plan_advice.advice": "SEQ_SCAN(x#1_0_)" +DETAIL: Could not parse advice: trailing junk after numeric literal at or near "1_0_" SET pg_plan_advice.advice = '()'; ERROR: invalid value for parameter "pg_plan_advice.advice": "()" DETAIL: Could not parse advice: syntax error at or near "(" SET pg_plan_advice.advice = '123'; ERROR: invalid value for parameter "pg_plan_advice.advice": "123" DETAIL: Could not parse advice: syntax error at or near "123" +-- Out of range values. +SET pg_plan_advice.advice = 'SEQ_SCAN(x#99999999999_99)'; +ERROR: invalid value for parameter "pg_plan_advice.advice": "SEQ_SCAN(x#99999999999_99)" +DETAIL: Could not parse advice: integer out of range at or near "99999999999_99" -- Tags like SEQ_SCAN and NO_GATHER don't allow sublists at all; other tags, -- except for JOIN_ORDER, allow at most one level of sublist. Hence, these -- examples should error out. diff --git a/contrib/pg_plan_advice/pgpa_scanner.l b/contrib/pg_plan_advice/pgpa_scanner.l index e6d60f57e1e..15d67cd4896 100644 --- a/contrib/pg_plan_advice/pgpa_scanner.l +++ b/contrib/pg_plan_advice/pgpa_scanner.l @@ -8,9 +8,9 @@ */ #include "postgres.h" -#include "common/string.h" #include "nodes/miscnodes.h" #include "parser/scansup.h" +#include "utils/builtins.h" #include "pgpa_ast.h" #include "pgpa_parser.h" @@ -82,6 +82,7 @@ identifier {ident_start}{ident_cont}* decdigit [0-9] decinteger {decdigit}(_?{decdigit})* +integer_junk {decinteger}{identifier} space [ \t\n\r\f\v] whitespace {space}+ @@ -136,16 +137,22 @@ xcinside [^*/]+ } {decinteger} { - char *endptr; + ErrorSaveContext escontext = {T_ErrorSaveContext}; - errno = 0; - yylval->integer = strtoint(yytext, &endptr, 10); - if (*endptr != '\0' || errno == ERANGE) + yylval->integer = pg_strtoint32_safe(yytext, + (Node *) &escontext); + if (escontext.error_occurred) pgpa_yyerror(result, parse_error_msg_p, yyscanner, "integer out of range"); return TOK_INTEGER; } +{integer_junk} { + BEGIN(INITIAL); + pgpa_yyerror(result, parse_error_msg_p, yyscanner, + "trailing junk after numeric literal"); + } + {xcstart} { BEGIN(xc); } diff --git a/contrib/pg_plan_advice/sql/syntax.sql b/contrib/pg_plan_advice/sql/syntax.sql index 3f94b5f8bf3..5af7607db42 100644 --- a/contrib/pg_plan_advice/sql/syntax.sql +++ b/contrib/pg_plan_advice/sql/syntax.sql @@ -19,6 +19,8 @@ SET pg_plan_advice.advice = 'seq_scan(x@y)'; EXPLAIN (COSTS OFF) SELECT 1; SET pg_plan_advice.advice = 'SEQ_scan(x#2)'; EXPLAIN (COSTS OFF) SELECT 1; +SET pg_plan_advice.advice = 'SEQ_SCAN(x#1_0)'; +EXPLAIN (COSTS OFF) SELECT 1; SET pg_plan_advice.advice = 'SEQ_SCAN (x/y)'; EXPLAIN (COSTS OFF) SELECT 1; SET pg_plan_advice.advice = ' SEQ_SCAN ( x / y . z ) '; @@ -34,9 +36,13 @@ SET pg_plan_advice.advice = 'SEQ_SCAN("'; SET pg_plan_advice.advice = 'SEQ_SCAN("")'; SET pg_plan_advice.advice = 'SEQ_SCAN("a"'; SET pg_plan_advice.advice = 'SEQ_SCAN(#'; +SET pg_plan_advice.advice = 'SEQ_SCAN(x#1_0_)'; SET pg_plan_advice.advice = '()'; SET pg_plan_advice.advice = '123'; +-- Out of range values. +SET pg_plan_advice.advice = 'SEQ_SCAN(x#99999999999_99)'; + -- Tags like SEQ_SCAN and NO_GATHER don't allow sublists at all; other tags, -- except for JOIN_ORDER, allow at most one level of sublist. Hence, these -- examples should error out. From bd6ca6f852694a8a0f52db748ff8badec4223c8f Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Sun, 19 Jul 2026 22:15:36 -0400 Subject: [PATCH 194/481] Run nbtree test module tests under autoconf builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 1e4e5783e added the src/test/modules/nbtree test module, but only registered it in the meson build, not in the module list in src/test/modules/Makefile. As a result, autoconf builds never ran the module's tests. To fix, add the module to the Makefile's lists of injection-point-dependent modules. Oversight in commit 1e4e5783e. Author: Peter Geoghegan Reviewed-by: Michael Paquiër Discussion: https://postgr.es/m/CAH2-Wz=JchiD5ksiT35p8Ar02gaNv8_y6w2wBAST+Zzen-eNjw@mail.gmail.com Backpatch-through: 19 --- src/test/modules/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 0a74ab5c86f..098bb8142ae 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -59,9 +59,9 @@ SUBDIRS = \ ifeq ($(enable_injection_points),yes) -SUBDIRS += injection_points gin typcache +SUBDIRS += injection_points gin nbtree typcache else -ALWAYS_SUBDIRS += injection_points gin typcache +ALWAYS_SUBDIRS += injection_points gin nbtree typcache endif ifeq ($(with_ssl),openssl) From 72457f1df803bba077b338d5ed3fb8418e69967d Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Mon, 20 Jul 2026 12:13:11 +0900 Subject: [PATCH 195/481] Skip unnecessary get_relids_in_jointree() when there are no PHVs Commit 1df9e8d96 made remove_useless_result_rtes() compute the set of baserels in the jointree, to pass down to the find_dependent_phvs() checks. But those checks are no-ops when the query contains no PHVs, since find_dependent_phvs() and find_dependent_phvs_in_jointree() both return early in that case. So we can avoid the get_relids_in_jointree() scan altogether when root->glob->lastPHId is zero, leaving baserels as NULL. Author: Richard Guo Reviewed-by: Tom Lane Discussion: https://postgr.es/m/CAMbWs49H275KzgZr3Cd1Hy+6Lmwp35bZ+5PrVc62k3HDLj6hNQ@mail.gmail.com Backpatch-through: 16 --- src/backend/optimizer/prep/prepjointree.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 2b7c9a17136..3c384579ee7 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -3888,16 +3888,18 @@ has_notnull_forced_var(PlannerInfo *root, List *forced_null_vars, void remove_useless_result_rtes(PlannerInfo *root) { - Relids baserels; + Relids baserels = NULL; Relids dropped_outer_joins = NULL; ListCell *cell; /* * We'll need the set of baserels in the jointree to perform - * find_dependent_phvs() checks. + * find_dependent_phvs() checks. But if there are no PHVs anywhere in the + * query, those checks are no-ops, so we can skip the work. */ - baserels = get_relids_in_jointree((Node *) root->parse->jointree, - false, false); + if (root->glob->lastPHId != 0) + baserels = get_relids_in_jointree((Node *) root->parse->jointree, + false, false); /* Top level of jointree must always be a FromExpr */ Assert(IsA(root->parse->jointree, FromExpr)); @@ -3967,7 +3969,8 @@ remove_useless_result_rtes(PlannerInfo *root) * (Note that in some cases, parent_quals points to the quals of a parent * more than one level up in the tree.) * - * baserels is the set of base (non-join) RT indexes in the whole jointree. + * baserels is the set of base (non-join) RT indexes in the whole jointree; + * it can be NULL if the query contains no PHVs. */ static Node * remove_useless_results_recurse(PlannerInfo *root, Node *jtnode, @@ -4308,7 +4311,9 @@ remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc) * already decided to remove those joins in remove_useless_result_rtes * and not yet have cleaned their relid bits out of upper PHVs. * But in general, it's the set of baserels that identify possible places - * to evaluate a PHV, and we mustn't let that go to empty. + * to evaluate a PHV, and we mustn't let that go to empty. (The caller is + * allowed to pass baserels as NULL if the query contains no PHVs at all, + * since then there is no work to do anyway.) * * find_dependent_phvs should be used when we want to see if there are * any such PHVs anywhere in the Query. Another use-case is to see if @@ -4320,7 +4325,7 @@ remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc) typedef struct { Relids relids; /* target relid, represented as a relid set */ - Relids baserels; /* set of base (non-OJ) RT indexes in query */ + Relids baserels; /* base RT indexes in query, NULL if no PHVs */ int sublevels_up; /* current nesting level */ } find_dependent_phvs_context; From a8c9d2be280443956cf2740017bf869ccdc562c3 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Mon, 20 Jul 2026 11:06:45 +0530 Subject: [PATCH 196/481] Handle concurrent sequence refreshes. 'ALTER SUBSCRIPTION ... REFRESH SEQUENCES' can race with a running sequence synchronization worker. If the worker has fetched a sequence's value from the publisher but not yet marked it READY, a concurrent refresh that resets the sequence to INIT can be overwritten by the worker's stale value, silently losing the refresh request. Handle this by stopping any running sequence sync worker before resetting the sequences to INIT. This is race-free because AlterSubscription() already holds AccessExclusiveLock on the subscription object. That lock blocks a running worker's UpdateSubscriptionRelState(), which takes AccessShareLock on the object, and also any worker the apply worker re-launches, because a new worker takes AccessShareLock on the object in InitializeLogRepWorker() before it reads pg_subscription_rel. Such a worker cannot act on the sequence states until the refresh commits, by which time they are reset to INIT and it will synchronize the latest publisher values. Reported-by: Noah Misch Author: Amit Kapila Reviewed-by: vignesh C Reviewed-by: Shveta Malik Reviewed-by: Hayato Kuroda Backpatch-through: 19 Discussion: https://postgr.es/m/20260710045217.f0.noahmisch@microsoft.com --- src/backend/commands/subscriptioncmds.c | 67 ++++++++++++++++++------- 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 1284d410790..a2c079fcb5a 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -48,6 +48,7 @@ #include "replication/walsender.h" #include "replication/worker_internal.h" #include "storage/lmgr.h" +#include "storage/lock.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/guc.h" @@ -1303,6 +1304,7 @@ AlterSubscription_refresh_seq(Subscription *sub) char *err = NULL; WalReceiverConn *wrconn; bool must_use_password; + List *subrel_states; /* Load the library providing us libpq calls. */ load_file("libpqwalreceiver", false); @@ -1317,33 +1319,64 @@ AlterSubscription_refresh_seq(Subscription *sub) errmsg("subscription \"%s\" could not connect to the publisher: %s", sub->name, err)); + /* The publisher connection is only needed for the origin check. */ PG_TRY(); { - List *subrel_states; - check_publications_origin_sequences(wrconn, sub->publications, true, sub->origin, NULL, 0, sub->name); - - /* Get local sequence list. */ - subrel_states = GetSubscriptionRelations(sub->oid, false, true, false); - foreach_ptr(SubscriptionRelState, subrel, subrel_states) - { - Oid relid = subrel->relid; - - UpdateSubscriptionRelState(sub->oid, relid, SUBREL_STATE_INIT, - InvalidXLogRecPtr, false); - ereport(DEBUG1, - errmsg_internal("sequence \"%s.%s\" of subscription \"%s\" set to INIT state", - get_namespace_name(get_rel_namespace(relid)), - get_rel_name(relid), - sub->name)); - } } PG_FINALLY(); { walrcv_disconnect(wrconn); } PG_END_TRY(); + + /* + * Reset the sequences to INIT so they get re-synchronized with the latest + * publisher values. + * + * A sequence sync worker may already be running. If it has fetched a + * sequence's value from the publisher but not yet marked it READY, it + * must not be allowed to complete that update, as it would overwrite the + * reset below with a stale value and silently lose this refresh request. + * So we stop any running sequence sync worker before resetting the + * states. + * + * This is race-free because AlterSubscription() already holds + * AccessExclusiveLock on the subscription object. That lock blocks a + * running worker's update of sequence state to READY, see + * UpdateSubscriptionRelState() which takes AccessShareLock on the object. + * It also blocks any worker the apply worker re-launches, because a new + * worker takes AccessShareLock on the object before it reads + * pg_subscription_rel, see InitializeLogRepWorker(). Such a worker cannot + * act on the states until we commit, by which time they are reset to INIT + * and it will sync the latest values. + */ +#ifdef USE_ASSERT_CHECKING + { + LOCKTAG tag; + + SET_LOCKTAG_OBJECT(tag, InvalidOid, SubscriptionRelationId, sub->oid, 0); + Assert(LockHeldByMe(&tag, AccessExclusiveLock, true)); + } +#endif + + logicalrep_worker_stop(WORKERTYPE_SEQUENCESYNC, sub->oid, InvalidOid); + + /* Reset every local sequence of this subscription to INIT. */ + subrel_states = GetSubscriptionRelations(sub->oid, false, true, false); + foreach_ptr(SubscriptionRelState, subrel, subrel_states) + { + Oid relid = subrel->relid; + + UpdateSubscriptionRelState(sub->oid, relid, SUBREL_STATE_INIT, + InvalidXLogRecPtr, false); + ereport(DEBUG1, + errmsg_internal("sequence \"%s.%s\" of subscription \"%s\" set to INIT state", + get_namespace_name(get_rel_namespace(relid)), + get_rel_name(relid), + sub->name)); + } } /* From c58c83ce50cf65ee45bd60910f710a2bd251cc36 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 20 Jul 2026 08:38:08 +0200 Subject: [PATCH 197/481] Fix RLS checks for FOR PORTION OF leftover rows UPDATE/DELETE FOR PORTION OF may insert leftover rows to preserve the parts of the old row that are outside the target range. Those inserts go through ExecInsert(), which checks RLS policies using WCO_RLS_INSERT_CHECK. However, the rewriter only added RLS WITH CHECK options for the original statement command. For UPDATE, that meant only WCO_RLS_UPDATE_CHECK options were available, so ExecInsert() skipped them. For DELETE, no RLS WITH CHECK options were added at all. As a result, leftover rows could be inserted even when they violated INSERT RLS policies. Fix this by adding INSERT RLS WITH CHECK options for UPDATE/DELETE FOR PORTION OF target relations. Also add regression coverage for both UPDATE and DELETE, including cases where allowed leftovers still succeed and disallowed leftovers are rejected. Author: Chao Li Co-authored-by: Paul A Jungwirth Reviewed-by: Paul A Jungwirth Reviewed-by: Ayush Tiwari Reviewed-by: Dean Rasheed Discussion: https://www.postgresql.org/message-id/flat/6C34A987-AC50-4477-BD71-2D4AFEE1A589%40gmail.com Discussion: https://www.postgresql.org/message-id/flat/CAJTYsWWdeBkoH5g8D-k9LDw9ciqsMxb21EJSiFXAzP4J%3DXyxOQ%40mail.gmail.com --- doc/src/sgml/ref/create_policy.sgml | 32 +++++++++ doc/src/sgml/ref/delete.sgml | 3 +- doc/src/sgml/ref/update.sgml | 3 +- src/backend/rewrite/rowsecurity.c | 25 +++++++ src/test/regress/expected/for_portion_of.out | 75 ++++++++++++++++++++ src/test/regress/expected/rowsecurity.out | 39 +++++++++- src/test/regress/sql/for_portion_of.sql | 58 +++++++++++++++ src/test/regress/sql/rowsecurity.sql | 33 ++++++++- 8 files changed, 264 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/ref/create_policy.sgml b/doc/src/sgml/ref/create_policy.sgml index d8a036739c0..0a1699185c9 100644 --- a/doc/src/sgml/ref/create_policy.sgml +++ b/doc/src/sgml/ref/create_policy.sgml @@ -530,6 +530,26 @@ CREATE POLICY name ON Check new row + + UPDATE ... FOR PORTION OF + + Filter existing row & check new row + + + Check leftover rows  + + FOR PORTION OF re-inserts the portions of the + affected row that fall outside the targeted range, to preserve them. + These leftover rows are checked against the INSERT + policy's WITH CHECK expression, even though no + INSERT privilege is required to store them. + + + + Filter existing row + Check new row + + DELETE @@ -540,6 +560,18 @@ CREATE POLICY name ON Filter existing row + + DELETE ... FOR PORTION OF + + Filter existing row + + + Check leftover rows  + + + + Filter existing row + INSERT ... ON CONFLICT diff --git a/doc/src/sgml/ref/delete.sgml b/doc/src/sgml/ref/delete.sgml index ffdcd7fc4fa..3ab1f60525a 100644 --- a/doc/src/sgml/ref/delete.sgml +++ b/doc/src/sgml/ref/delete.sgml @@ -97,7 +97,8 @@ DELETE FROM [ ONLY ] table_name [ * When FOR PORTION OF is used, the secondary inserts do not require INSERT privilege on the table. (This is because conceptually no new information is being added; the inserted rows - only preserve existing data about the untargeted time period.) + only preserve existing data about the untargeted time period.) Row-level + security INSERT policies are still checked for these leftover inserts. diff --git a/doc/src/sgml/ref/update.sgml b/doc/src/sgml/ref/update.sgml index 21a8fd8b037..3175671d475 100644 --- a/doc/src/sgml/ref/update.sgml +++ b/doc/src/sgml/ref/update.sgml @@ -101,7 +101,8 @@ UPDATE [ ONLY ] table_name [ * ] When FOR PORTION OF is used, the secondary inserts do not require INSERT privilege on the table. (This is because conceptually no new information is being added; the inserted rows - only preserve existing data about the untargeted time period.) + only preserve existing data about the untargeted time period.) Row-level + security INSERT policies are still checked for these leftover inserts. diff --git a/src/backend/rewrite/rowsecurity.c b/src/backend/rewrite/rowsecurity.c index e88a1bc1a89..46d88f79894 100644 --- a/src/backend/rewrite/rowsecurity.c +++ b/src/backend/rewrite/rowsecurity.c @@ -393,6 +393,31 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, } } + /* + * UPDATE/DELETE FOR PORTION OF may insert leftover rows to preserve the + * portions of the old row not covered by the target range. Those hidden + * inserts go through ExecInsert(), so they need the same INSERT RLS WITH + * CHECK options as ordinary INSERTs. SELECT rights are never needed for + * the leftover rows, because they are not considered by RETURNING. + */ + if (root->forPortionOf != NULL && rt_index == root->resultRelation && + (commandType == CMD_UPDATE || commandType == CMD_DELETE)) + { + List *insert_permissive_policies; + List *insert_restrictive_policies; + + get_policies_for_relation(rel, CMD_INSERT, user_id, + &insert_permissive_policies, + &insert_restrictive_policies); + add_with_check_options(rel, rt_index, + WCO_RLS_INSERT_CHECK, + insert_permissive_policies, + insert_restrictive_policies, + withCheckOptions, + hasSubLinks, + false); + } + /* * FOR MERGE, we fetch policies for UPDATE, DELETE and INSERT (and ALL) * and set them up so that we can enforce the appropriate policy depending diff --git a/src/test/regress/expected/for_portion_of.out b/src/test/regress/expected/for_portion_of.out index a050fc2dadf..271282c2d3b 100644 --- a/src/test/regress/expected/for_portion_of.out +++ b/src/test/regress/expected/for_portion_of.out @@ -2561,4 +2561,79 @@ SELECT * FROM fpo_cursed; (1 row) DROP TABLE fpo_cursed; +-- UPDATE/DELETE FOR PORTION OF leftover rows must satisfy RLS INSERT checks. +CREATE ROLE regress_fpo_rls; +CREATE TABLE fpo_rls ( + id int, + valid_at int4range +); +ALTER TABLE fpo_rls ENABLE ROW LEVEL SECURITY; +CREATE POLICY fpo_rls_select ON fpo_rls + FOR SELECT TO regress_fpo_rls + USING (true); +CREATE POLICY fpo_rls_update ON fpo_rls + FOR UPDATE TO regress_fpo_rls + USING (lower(valid_at) < 50) + WITH CHECK (lower(valid_at) < 50); +CREATE POLICY fpo_rls_delete ON fpo_rls + FOR DELETE TO regress_fpo_rls + USING (lower(valid_at) < 50); +CREATE POLICY fpo_rls_insert ON fpo_rls + FOR INSERT TO regress_fpo_rls + WITH CHECK (lower(valid_at) < 50); +GRANT SELECT, UPDATE, DELETE ON fpo_rls TO regress_fpo_rls; +INSERT INTO fpo_rls VALUES (1, '[10,100)'); +SET ROLE regress_fpo_rls; +UPDATE fpo_rls + FOR PORTION OF valid_at FROM 30 TO 100 + SET id = 2; +RESET ROLE; +SELECT * FROM fpo_rls ORDER BY valid_at; + id | valid_at +----+---------- + 1 | [10,30) + 2 | [30,100) +(2 rows) + +TRUNCATE fpo_rls; +INSERT INTO fpo_rls VALUES (1, '[10,100)'); +SET ROLE regress_fpo_rls; +DELETE FROM fpo_rls + FOR PORTION OF valid_at FROM 30 TO 100; +RESET ROLE; +SELECT * FROM fpo_rls ORDER BY valid_at; + id | valid_at +----+---------- + 1 | [10,30) +(1 row) + +TRUNCATE fpo_rls; +INSERT INTO fpo_rls VALUES (1, '[10,100)'); +SET ROLE regress_fpo_rls; +UPDATE fpo_rls + FOR PORTION OF valid_at FROM 30 TO 70 + SET id = 2; +ERROR: new row violates row-level security policy for table "fpo_rls" +RESET ROLE; +SELECT * FROM fpo_rls ORDER BY valid_at; + id | valid_at +----+---------- + 1 | [10,100) +(1 row) + +TRUNCATE fpo_rls; +INSERT INTO fpo_rls VALUES (1, '[10,100)'); +SET ROLE regress_fpo_rls; +DELETE FROM fpo_rls + FOR PORTION OF valid_at FROM 30 TO 70; +ERROR: new row violates row-level security policy for table "fpo_rls" +RESET ROLE; +SELECT * FROM fpo_rls ORDER BY valid_at; + id | valid_at +----+---------- + 1 | [10,100) +(1 row) + +DROP TABLE fpo_rls; +DROP ROLE regress_fpo_rls; RESET datestyle; diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out index 3a5e82c35bd..f42085e53a0 100644 --- a/src/test/regress/expected/rowsecurity.out +++ b/src/test/regress/expected/rowsecurity.out @@ -68,6 +68,20 @@ CREATE POLICY upd_pol ON rls_test_tgt FOR UPDATE WITH CHECK (rls_test_policy_fn('UPDATE CHECK on rls_test_tgt', rls_test_tgt)); CREATE POLICY del_pol ON rls_test_tgt FOR DELETE USING (rls_test_policy_fn('DELETE USING on rls_test_tgt', rls_test_tgt)); +-- setup temporal target table (for FOR PORTION OF operations) +CREATE TABLE rls_test_fpo_tgt (a int, b text, valid_at int4range); +ALTER TABLE rls_test_fpo_tgt ENABLE ROW LEVEL SECURITY; +GRANT SELECT, UPDATE, DELETE ON rls_test_fpo_tgt TO public; +INSERT INTO rls_test_fpo_tgt VALUES (1, 'fpo a', '[1,10)'); +CREATE POLICY sel_pol ON rls_test_fpo_tgt FOR SELECT + USING (rls_test_policy_fn('SELECT USING on rls_test_fpo_tgt', rls_test_fpo_tgt)); +CREATE POLICY ins_pol ON rls_test_fpo_tgt FOR INSERT + WITH CHECK (rls_test_policy_fn('INSERT CHECK on rls_test_fpo_tgt', rls_test_fpo_tgt)); +CREATE POLICY upd_pol ON rls_test_fpo_tgt FOR UPDATE + USING (rls_test_policy_fn('UPDATE USING on rls_test_fpo_tgt', rls_test_fpo_tgt)) + WITH CHECK (rls_test_policy_fn('UPDATE CHECK on rls_test_fpo_tgt', rls_test_fpo_tgt)); +CREATE POLICY del_pol ON rls_test_fpo_tgt FOR DELETE + USING (rls_test_policy_fn('DELETE USING on rls_test_fpo_tgt', rls_test_fpo_tgt)); -- test policies applied to regress_rls_bob SET SESSION AUTHORIZATION regress_rls_bob; -- SELECT, COPY ... TO, and TABLE should only apply SELECT USING policy clause @@ -155,6 +169,19 @@ NOTICE: SELECT USING on rls_test_tgt.(1,"tgt d","TGT D") 1 | tgt d | TGT D (1 row) +-- UPDATE ... FOR PORTION OF should also apply SELECT USING policy clauses to +-- the old and new rows, and INSERT CHECK policy clauses to leftover rows. +BEGIN; +UPDATE rls_test_fpo_tgt + FOR PORTION OF valid_at FROM 3 TO 7 + SET b = 'fpo b'; +NOTICE: UPDATE USING on rls_test_fpo_tgt.(1,"fpo a","[1,10)") +NOTICE: SELECT USING on rls_test_fpo_tgt.(1,"fpo a","[1,10)") +NOTICE: UPDATE CHECK on rls_test_fpo_tgt.(1,"fpo b","[3,7)") +NOTICE: SELECT USING on rls_test_fpo_tgt.(1,"fpo b","[3,7)") +NOTICE: INSERT CHECK on rls_test_fpo_tgt.(1,"fpo a","[1,3)") +NOTICE: INSERT CHECK on rls_test_fpo_tgt.(1,"fpo a","[7,10)") +ROLLBACK; -- DELETE without WHERE or RETURNING should only apply DELETE USING policy clause BEGIN; DELETE FROM rls_test_tgt; ROLLBACK; NOTICE: DELETE USING on rls_test_tgt.(1,"tgt d","TGT D") @@ -170,6 +197,16 @@ NOTICE: SELECT USING on rls_test_tgt.(1,"tgt d","TGT D") 1 | tgt d | TGT D (1 row) +-- DELETE ... FOR PORTION OF should also apply SELECT USING policy clauses to +-- the old row, and INSERT CHECK policy clauses to leftover rows. +BEGIN; +DELETE FROM rls_test_fpo_tgt + FOR PORTION OF valid_at FROM 3 TO 7; +NOTICE: DELETE USING on rls_test_fpo_tgt.(1,"fpo a","[1,10)") +NOTICE: SELECT USING on rls_test_fpo_tgt.(1,"fpo a","[1,10)") +NOTICE: INSERT CHECK on rls_test_fpo_tgt.(1,"fpo a","[1,3)") +NOTICE: INSERT CHECK on rls_test_fpo_tgt.(1,"fpo a","[7,10)") +ROLLBACK; -- INSERT ... ON CONFLICT DO NOTHING with an arbiter clause should apply -- INSERT CHECK and SELECT USING policy clauses (to new value, whether it -- conflicts or not) @@ -332,7 +369,7 @@ NOTICE: DELETE USING on rls_test_tgt.(1,"tgt c","TGT C") -- Tidy up RESET SESSION AUTHORIZATION; -DROP TABLE rls_test_src, rls_test_tgt; +DROP TABLE rls_test_src, rls_test_tgt, rls_test_fpo_tgt; DROP FUNCTION rls_test_tgt_set_c; DROP FUNCTION rls_test_policy_fn; -- BASIC Row-Level Security Scenario diff --git a/src/test/regress/sql/for_portion_of.sql b/src/test/regress/sql/for_portion_of.sql index a1ee1d5e501..f48644347d1 100644 --- a/src/test/regress/sql/for_portion_of.sql +++ b/src/test/regress/sql/for_portion_of.sql @@ -1676,4 +1676,62 @@ ROLLBACK; SELECT * FROM fpo_cursed; DROP TABLE fpo_cursed; +-- UPDATE/DELETE FOR PORTION OF leftover rows must satisfy RLS INSERT checks. +CREATE ROLE regress_fpo_rls; +CREATE TABLE fpo_rls ( + id int, + valid_at int4range +); +ALTER TABLE fpo_rls ENABLE ROW LEVEL SECURITY; +CREATE POLICY fpo_rls_select ON fpo_rls + FOR SELECT TO regress_fpo_rls + USING (true); +CREATE POLICY fpo_rls_update ON fpo_rls + FOR UPDATE TO regress_fpo_rls + USING (lower(valid_at) < 50) + WITH CHECK (lower(valid_at) < 50); +CREATE POLICY fpo_rls_delete ON fpo_rls + FOR DELETE TO regress_fpo_rls + USING (lower(valid_at) < 50); +CREATE POLICY fpo_rls_insert ON fpo_rls + FOR INSERT TO regress_fpo_rls + WITH CHECK (lower(valid_at) < 50); +GRANT SELECT, UPDATE, DELETE ON fpo_rls TO regress_fpo_rls; + +INSERT INTO fpo_rls VALUES (1, '[10,100)'); +SET ROLE regress_fpo_rls; +UPDATE fpo_rls + FOR PORTION OF valid_at FROM 30 TO 100 + SET id = 2; +RESET ROLE; +SELECT * FROM fpo_rls ORDER BY valid_at; + +TRUNCATE fpo_rls; +INSERT INTO fpo_rls VALUES (1, '[10,100)'); +SET ROLE regress_fpo_rls; +DELETE FROM fpo_rls + FOR PORTION OF valid_at FROM 30 TO 100; +RESET ROLE; +SELECT * FROM fpo_rls ORDER BY valid_at; + +TRUNCATE fpo_rls; +INSERT INTO fpo_rls VALUES (1, '[10,100)'); +SET ROLE regress_fpo_rls; +UPDATE fpo_rls + FOR PORTION OF valid_at FROM 30 TO 70 + SET id = 2; +RESET ROLE; +SELECT * FROM fpo_rls ORDER BY valid_at; + +TRUNCATE fpo_rls; +INSERT INTO fpo_rls VALUES (1, '[10,100)'); +SET ROLE regress_fpo_rls; +DELETE FROM fpo_rls + FOR PORTION OF valid_at FROM 30 TO 70; +RESET ROLE; +SELECT * FROM fpo_rls ORDER BY valid_at; + +DROP TABLE fpo_rls; +DROP ROLE regress_fpo_rls; + RESET datestyle; diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql index 6b3566271df..0bd24d1028b 100644 --- a/src/test/regress/sql/rowsecurity.sql +++ b/src/test/regress/sql/rowsecurity.sql @@ -85,6 +85,22 @@ CREATE POLICY upd_pol ON rls_test_tgt FOR UPDATE CREATE POLICY del_pol ON rls_test_tgt FOR DELETE USING (rls_test_policy_fn('DELETE USING on rls_test_tgt', rls_test_tgt)); +-- setup temporal target table (for FOR PORTION OF operations) +CREATE TABLE rls_test_fpo_tgt (a int, b text, valid_at int4range); +ALTER TABLE rls_test_fpo_tgt ENABLE ROW LEVEL SECURITY; +GRANT SELECT, UPDATE, DELETE ON rls_test_fpo_tgt TO public; +INSERT INTO rls_test_fpo_tgt VALUES (1, 'fpo a', '[1,10)'); + +CREATE POLICY sel_pol ON rls_test_fpo_tgt FOR SELECT + USING (rls_test_policy_fn('SELECT USING on rls_test_fpo_tgt', rls_test_fpo_tgt)); +CREATE POLICY ins_pol ON rls_test_fpo_tgt FOR INSERT + WITH CHECK (rls_test_policy_fn('INSERT CHECK on rls_test_fpo_tgt', rls_test_fpo_tgt)); +CREATE POLICY upd_pol ON rls_test_fpo_tgt FOR UPDATE + USING (rls_test_policy_fn('UPDATE USING on rls_test_fpo_tgt', rls_test_fpo_tgt)) + WITH CHECK (rls_test_policy_fn('UPDATE CHECK on rls_test_fpo_tgt', rls_test_fpo_tgt)); +CREATE POLICY del_pol ON rls_test_fpo_tgt FOR DELETE + USING (rls_test_policy_fn('DELETE USING on rls_test_fpo_tgt', rls_test_fpo_tgt)); + -- test policies applied to regress_rls_bob SET SESSION AUTHORIZATION regress_rls_bob; @@ -114,6 +130,14 @@ UPDATE rls_test_tgt SET b = 'tgt b'; UPDATE rls_test_tgt SET b = 'tgt c' WHERE a = 1; UPDATE rls_test_tgt SET b = 'tgt d' RETURNING *; +-- UPDATE ... FOR PORTION OF should also apply SELECT USING policy clauses to +-- the old and new rows, and INSERT CHECK policy clauses to leftover rows. +BEGIN; +UPDATE rls_test_fpo_tgt + FOR PORTION OF valid_at FROM 3 TO 7 + SET b = 'fpo b'; +ROLLBACK; + -- DELETE without WHERE or RETURNING should only apply DELETE USING policy clause BEGIN; DELETE FROM rls_test_tgt; ROLLBACK; @@ -121,6 +145,13 @@ BEGIN; DELETE FROM rls_test_tgt; ROLLBACK; BEGIN; DELETE FROM rls_test_tgt WHERE a = 1; ROLLBACK; DELETE FROM rls_test_tgt RETURNING *; +-- DELETE ... FOR PORTION OF should also apply SELECT USING policy clauses to +-- the old row, and INSERT CHECK policy clauses to leftover rows. +BEGIN; +DELETE FROM rls_test_fpo_tgt + FOR PORTION OF valid_at FROM 3 TO 7; +ROLLBACK; + -- INSERT ... ON CONFLICT DO NOTHING with an arbiter clause should apply -- INSERT CHECK and SELECT USING policy clauses (to new value, whether it -- conflicts or not) @@ -192,7 +223,7 @@ MERGE INTO rls_test_tgt t USING rls_test_src s ON t.a = s.a -- Tidy up RESET SESSION AUTHORIZATION; -DROP TABLE rls_test_src, rls_test_tgt; +DROP TABLE rls_test_src, rls_test_tgt, rls_test_fpo_tgt; DROP FUNCTION rls_test_tgt_set_c; DROP FUNCTION rls_test_policy_fn; From 69fe2514fdd829cc4aebcd084f6f300f60e84f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Mon, 20 Jul 2026 12:12:13 +0200 Subject: [PATCH 198/481] Move code to get_tables_to_repack_partitioned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some of its code was pointlessly in its caller. This makes it better contained and clearer. Backpatch to 19, to avoid having two different copies in case we have to modify it again later. Author: Álvaro Herrera Reviewed-by: Bharath Rupireddy Reviewed-by: ChangAo Chen Discussion: https://postgr.es/m/alD9l-XlCuu3eUEe@alvherre.pgsql --- src/backend/commands/repack.c | 137 +++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 62 deletions(-) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 02883fe34a4..dde56fb1e8d 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -169,8 +169,8 @@ static void copy_table_data(Relation NewHeap, Relation OldHeap, Relation OldInde MultiXactId *pCutoffMulti); static List *get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt); -static List *get_tables_to_repack_partitioned(RepackCommand cmd, - Oid relid, bool rel_is_index, +static List *get_tables_to_repack_partitioned(RepackStmt *stmt, + Relation rel, MemoryContext permcxt); static bool repack_is_permitted_for_relation(RepackCommand cmd, Oid relid, Oid userid); @@ -387,58 +387,8 @@ ExecRepack(ParseState *pstate, RepackStmt *stmt, bool isTopLevel) } else { - Oid relid; - bool rel_is_index; - - Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); - - /* - * If USING INDEX was specified, resolve the index name now and pass - * it down. - */ - if (stmt->usingindex) - { - /* - * If no index name was specified when repacking a partitioned - * table, punt for now. Maybe we can improve this later. - */ - if (!stmt->indexname) - { - if (stmt->command == REPACK_COMMAND_CLUSTER) - ereport(ERROR, - errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("there is no previously clustered index for table \"%s\"", - RelationGetRelationName(rel))); - else - ereport(ERROR, - errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - /*- translator: first %s is name of a SQL command, eg. REPACK */ - errmsg("cannot execute %s on partitioned table \"%s\" USING INDEX with no index name", - RepackCommandAsString(stmt->command), - RelationGetRelationName(rel))); - } - - relid = determine_clustered_index(rel, stmt->usingindex, - stmt->indexname); - if (!OidIsValid(relid)) - elog(ERROR, "unable to determine index to cluster on"); - check_index_is_clusterable(rel, relid, AccessExclusiveLock); - - rel_is_index = true; - } - else - { - relid = RelationGetRelid(rel); - rel_is_index = false; - } - - rtcs = get_tables_to_repack_partitioned(stmt->command, - relid, rel_is_index, - repack_context); - - /* close parent relation, releasing lock on it */ - table_close(rel, AccessExclusiveLock); - rel = NULL; + rtcs = get_tables_to_repack_partitioned(stmt, rel, repack_context); + rel = NULL; /* clobber no longer valid pointer */ } /* Commit to get out of starting transaction */ @@ -2255,19 +2205,71 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt) } /* - * Given a partitioned table or its index, return a list of RelToCluster for - * all the leaf child tables/indexes. + * Determine relations to process, when REPACK/CLUSTER is called with a + * partitioning table; that is, a list of its leaf partitions. That table has + * already been opened by caller and is passed as 'rel'. It is closed and + * unlocked here before return, so caller should clobber its pointer to avoid + * confusion. + * + * Return it as a list of RelToCluster. * - * 'rel_is_index' tells whether 'relid' is that of an index (true) or of the - * owning relation. + * XXX we don't support CONCURRENTLY for partitioned tables yet. */ static List * -get_tables_to_repack_partitioned(RepackCommand cmd, Oid relid, - bool rel_is_index, MemoryContext permcxt) +get_tables_to_repack_partitioned(RepackStmt *stmt, Relation rel, + MemoryContext permcxt) { + Oid relid; + bool rel_is_index; List *inhoids; List *rtcs = NIL; + Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); + Assert(CheckRelationLockedByMe(rel, AccessExclusiveLock, false)); + + /* + * We find the list of tables by looking for inheritors. If USING INDEX + * was given, look for inheritors of that index, whose name we resolve + * now. + * + * Otherwise we look for inheritors of the table itself. + */ + if (stmt->usingindex) + { + /* + * If no index name was specified when repacking a partitioned table, + * punt for now. Maybe we can improve this later. + */ + if (!stmt->indexname) + { + if (stmt->command == REPACK_COMMAND_CLUSTER) + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("there is no previously clustered index for table \"%s\"", + RelationGetRelationName(rel))); + else + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + /*- translator: first %s is name of a SQL command, eg. REPACK */ + errmsg("cannot execute %s on partitioned table \"%s\" USING INDEX with no index name", + RepackCommandAsString(stmt->command), + RelationGetRelationName(rel))); + } + + relid = determine_clustered_index(rel, stmt->usingindex, + stmt->indexname); + if (!OidIsValid(relid)) + elog(ERROR, "unable to determine index to cluster on"); + check_index_is_clusterable(rel, relid, AccessExclusiveLock); + + rel_is_index = true; + } + else + { + relid = RelationGetRelid(rel); + rel_is_index = false; + } + /* * Do not lock the children until they're processed. Note that we do hold * a lock on the parent partitioned table. @@ -2286,7 +2288,14 @@ get_tables_to_repack_partitioned(RepackCommand cmd, Oid relid, if (get_rel_relkind(child_oid) != RELKIND_INDEX) continue; - table_oid = IndexGetRelation(child_oid, false); + /* + * Although we do have a lock on some ancestor partitioned index, + * we may not have one on the immediate parent, so this lookup may + * still return invalid. + */ + table_oid = IndexGetRelation(child_oid, true); + if (!OidIsValid(table_oid)) + continue; index_oid = child_oid; } else @@ -2304,7 +2313,8 @@ get_tables_to_repack_partitioned(RepackCommand cmd, Oid relid, * leaf partition despite having them on the partitioned table. Skip * if so. */ - if (!repack_is_permitted_for_relation(cmd, table_oid, GetUserId())) + if (!repack_is_permitted_for_relation(stmt->command, table_oid, + GetUserId())) continue; /* Use a permanent memory context for the result list */ @@ -2316,6 +2326,9 @@ get_tables_to_repack_partitioned(RepackCommand cmd, Oid relid, MemoryContextSwitchTo(oldcxt); } + /* close parent relation, releasing lock on it */ + table_close(rel, AccessExclusiveLock); + return rtcs; } From 10389a7e15e0ed0214e19c6560edd4dc6bb07a35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Mon, 20 Jul 2026 13:50:45 +0200 Subject: [PATCH 199/481] Fix LSN format in REPACK worker debug message Commit 6f6f284c7ee4 introduced use of LSN_FORMAT_ARGS across the whole tree to remove use of manual bit-shifting, and commit 2633dae2e487 changed the printf format to be %X/%08X; however commit 28d534e2ae0a violated both conventions by reintroducing the old manual-shift style with the deprecated %X/%X format in one debug message. Make that new message conform to our style. Author: kenny Backpatch-through: 19 Discussion: https://postgr.es/m/CAPXstDuWD8jg0=C8PXTXGSTTsZcjqJ+u+xKCrMpN99CXsxQzCg@mail.gmail.com --- src/backend/commands/repack_worker.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/repack_worker.c b/src/backend/commands/repack_worker.c index db9ff057cc6..af7e2a94764 100644 --- a/src/backend/commands/repack_worker.c +++ b/src/backend/commands/repack_worker.c @@ -397,8 +397,8 @@ decode_concurrent_changes(LogicalDecodingContext *ctx, { LogicalIncreaseRestartDecodingForSlot(end_lsn, end_lsn); LogicalConfirmReceivedLocation(end_lsn); - elog(DEBUG1, "REPACK: confirmed receive location %X/%X", - (uint32) (end_lsn >> 32), (uint32) end_lsn); + elog(DEBUG1, "REPACK: confirmed receive location %X/%08X", + LSN_FORMAT_ARGS(end_lsn)); repack_current_segment = segno_new; } } From 2b2c2492c2b053a5d7b347abfb2e80127841b9bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Mon, 20 Jul 2026 17:21:20 +0200 Subject: [PATCH 200/481] Fix restore of partitions with exclusion constraints Commit 8c852ba9a4 allowed exclusion constraints to be added to partitioned tables, but wasn't careful to verify that pg_restore worked correctly for them. Fix that by making CompareIndexInfo() more selective about what needs to be rejected. Author: Japin Li Reported-by: Keith Paskett Discussion: https://postgr.es/m/2A40921D-83AB-411E-ADA6-7E509A46F1E4@logansw.com --- src/backend/catalog/index.c | 16 ++++++++++++++-- src/test/regress/expected/indexing.out | 15 +++++++++++++++ src/test/regress/sql/indexing.sql | 14 ++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 9407c357f27..336757ea699 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -2663,9 +2663,21 @@ CompareIndexInfo(const IndexInfo *info1, const IndexInfo *info2, return false; } - /* No support currently for comparing exclusion indexes. */ - if (info1->ii_ExclusionOps != NULL || info2->ii_ExclusionOps != NULL) + /* If they're exclusion indexes, their properties must be identical */ + if ((info1->ii_ExclusionOps == NULL) != (info2->ii_ExclusionOps == NULL)) return false; + if (info1->ii_ExclusionOps != NULL) + { + for (i = 0; i < info1->ii_NumIndexKeyAttrs; i++) + { + if (info1->ii_ExclusionOps[i] != info2->ii_ExclusionOps[i]) + return false; + if (info1->ii_ExclusionProcs[i] != info2->ii_ExclusionProcs[i]) + return false; + if (info1->ii_ExclusionStrats[i] != info2->ii_ExclusionStrats[i]) + return false; + } + } return true; } diff --git a/src/test/regress/expected/indexing.out b/src/test/regress/expected/indexing.out index 929feda6fa3..c387c9078ac 100644 --- a/src/test/regress/expected/indexing.out +++ b/src/test/regress/expected/indexing.out @@ -1785,3 +1785,18 @@ insert into test_pg_wholerow_index values (2, 'addition', 0); drop index row_image_index; drop function row_image(test_pg_wholerow_index); drop table test_pg_wholerow_index; +-- Test of a partitioned index attach, when there are exclusion constraints. +create table idx_excl_part (a int4range, b int4range) partition by list (a); +create table idx_excl_part_1 (a int4range, b int4range); +alter table only idx_excl_part attach partition idx_excl_part_1 for values in ('[0,1)'::int4range); +alter table only idx_excl_part add constraint idxpart_id_data_excl exclude using gist (a with =, b with &&); +alter table idx_excl_part_1 add constraint idxpart_1_id_data_excl exclude using gist (a with &&, b with &&); +-- This should be disallowed, because the constraints don't match. +alter index idxpart_id_data_excl attach partition idxpart_1_id_data_excl; +ERROR: cannot attach index "idxpart_1_id_data_excl" as a partition of index "idxpart_id_data_excl" +DETAIL: The index definitions do not match. +-- but if we recreate the constraint differently, it's allowed: +alter table idx_excl_part_1 drop constraint idxpart_1_id_data_excl; +alter table idx_excl_part_1 add constraint idxpart_1_id_data_excl exclude using gist (a with =, b with &&); +alter index idxpart_id_data_excl attach partition idxpart_1_id_data_excl; +-- leave these tables around, for pg_upgrade testing diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql index 3d43af3323c..285d61936c0 100644 --- a/src/test/regress/sql/indexing.sql +++ b/src/test/regress/sql/indexing.sql @@ -1005,3 +1005,17 @@ insert into test_pg_wholerow_index values (2, 'addition', 0); drop index row_image_index; drop function row_image(test_pg_wholerow_index); drop table test_pg_wholerow_index; + +-- Test of a partitioned index attach, when there are exclusion constraints. +create table idx_excl_part (a int4range, b int4range) partition by list (a); +create table idx_excl_part_1 (a int4range, b int4range); +alter table only idx_excl_part attach partition idx_excl_part_1 for values in ('[0,1)'::int4range); +alter table only idx_excl_part add constraint idxpart_id_data_excl exclude using gist (a with =, b with &&); +alter table idx_excl_part_1 add constraint idxpart_1_id_data_excl exclude using gist (a with &&, b with &&); +-- This should be disallowed, because the constraints don't match. +alter index idxpart_id_data_excl attach partition idxpart_1_id_data_excl; +-- but if we recreate the constraint differently, it's allowed: +alter table idx_excl_part_1 drop constraint idxpart_1_id_data_excl; +alter table idx_excl_part_1 add constraint idxpart_1_id_data_excl exclude using gist (a with =, b with &&); +alter index idxpart_id_data_excl attach partition idxpart_1_id_data_excl; +-- leave these tables around, for pg_upgrade testing From a649138d8558a97880d3ba1d1f41f66320debf7f Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 20 Jul 2026 13:36:39 -0400 Subject: [PATCH 201/481] doc: Granting TRIGGER or REFERENCES on table is dangerous. It's always been the case that granting these privileges to users that you don't fully trust was a bad idea, but it hasn't always been obvious to people reading the documentation that this is the case. To prevent confusion, and also repeated reports to pgsql-security, mention it explicitly. Discussion: http://postgr.es/m/CA+TgmobrjCHBuWHrvX3=2vndUCO2thUOdevrCcMDFW86cqCYvw@mail.gmail.com Reviewed-by: Nathan Bossart Backpatch-through: 14 --- doc/src/sgml/ddl.sgml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index 19fa5d5fda8..82176945bc2 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -2396,7 +2396,11 @@ REVOKE ALL ON accounts FROM PUBLIC; Allows creation of a foreign key constraint referencing a - table, or specific column(s) of a table. + table, or specific column(s) of a table. Great care should be taken when + granting this privilege, since a user who creates a foreign key can arrange + for enforcement of that foreign key to call an arbitrary function, such as + a cast function, and such functions will be called with the privileges of + the table owner. @@ -2405,7 +2409,9 @@ REVOKE ALL ON accounts FROM PUBLIC; TRIGGER - Allows creation of a trigger on a table, view, etc. + Allows creation of a trigger on a table, view, etc. Great care should be + taken when granting this privilege, since any triggers added to a table + or view will be executed with the privileges of users who modify it. From 4ca78f292de7b86495cec0a416dc047d94df96c4 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Mon, 20 Jul 2026 17:11:21 -0700 Subject: [PATCH 202/481] Add logical decoding status to pg_control_checkpoint(). Commit 8108765f04b added the logical decoding status to the pg_controldata output, but overlooked the pg_control_checkpoint() SQL function, which reports the same checkpoint information. This commit adds a logical_decoding column to pg_control_checkpoint(), placed after full_page_writes to match the pg_controldata output order. Oversight in 8108765f04b. Bump catalog version. Reported-by: Fujii Masao Discussion: https://postgr.es/m/CAHGQGwEkp1-1n5iC38+yHSNh955+KshwtCL6DzA0vk_vuUF_Eg@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/func/func-info.sgml | 5 ++++ src/backend/utils/misc/pg_controldata.c | 35 ++++++++++++++----------- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 6 ++--- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml index 69ef3857cfa..122fc740f1a 100644 --- a/doc/src/sgml/func/func-info.sgml +++ b/doc/src/sgml/func/func-info.sgml @@ -3436,6 +3436,11 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} boolean + + logical_decoding + boolean + + next_xid text diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c index c6d9cbb1577..d229ae35209 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -69,8 +69,8 @@ pg_control_system(PG_FUNCTION_ARGS) Datum pg_control_checkpoint(PG_FUNCTION_ARGS) { - Datum values[18]; - bool nulls[18]; + Datum values[19]; + bool nulls[19]; TupleDesc tupdesc; HeapTuple htup; ControlFileData *ControlFile; @@ -116,44 +116,47 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) values[5] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites); nulls[5] = false; - values[6] = CStringGetTextDatum(psprintf("%u:%u", - EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid), - XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid))); + values[6] = BoolGetDatum(ControlFile->checkPointCopy.logicalDecodingEnabled); nulls[6] = false; - values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid); + values[7] = CStringGetTextDatum(psprintf("%u:%u", + EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid), + XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid))); nulls[7] = false; - values[8] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti); + values[8] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid); nulls[8] = false; - values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset); + values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti); nulls[9] = false; - values[10] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid); + values[10] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset); nulls[10] = false; - values[11] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestXidDB); + values[11] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid); nulls[11] = false; - values[12] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestActiveXid); + values[12] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestXidDB); nulls[12] = false; - values[13] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestMulti); + values[13] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestActiveXid); nulls[13] = false; - values[14] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestMultiDB); + values[14] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestMulti); nulls[14] = false; - values[15] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestCommitTsXid); + values[15] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestMultiDB); nulls[15] = false; - values[16] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid); + values[16] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestCommitTsXid); nulls[16] = false; - values[17] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time)); + values[17] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid); nulls[17] = false; + values[18] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time)); + nulls[18] = false; + htup = heap_form_tuple(tupdesc, values, nulls); PG_RETURN_DATUM(HeapTupleGetDatum(htup)); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 2471ccb96a3..d0399cc1cbe 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202607172 +#define CATALOG_VERSION_NO 202607201 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index efe13b7866a..aa5ac43aff0 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -12346,9 +12346,9 @@ descr => 'pg_controldata checkpoint state information as a function', proname => 'pg_control_checkpoint', provolatile => 'v', prorettype => 'record', proargtypes => '', - proallargtypes => '{pg_lsn,pg_lsn,text,int4,int4,bool,text,oid,xid,xid,xid,oid,xid,xid,oid,xid,xid,timestamptz}', - proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', - proargnames => '{checkpoint_lsn,redo_lsn,redo_wal_file,timeline_id,prev_timeline_id,full_page_writes,next_xid,next_oid,next_multixact_id,next_multi_offset,oldest_xid,oldest_xid_dbid,oldest_active_xid,oldest_multi_xid,oldest_multi_dbid,oldest_commit_ts_xid,newest_commit_ts_xid,checkpoint_time}', + proallargtypes => '{pg_lsn,pg_lsn,text,int4,int4,bool,bool,text,oid,xid,xid,xid,oid,xid,xid,oid,xid,xid,timestamptz}', + proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', + proargnames => '{checkpoint_lsn,redo_lsn,redo_wal_file,timeline_id,prev_timeline_id,full_page_writes,logical_decoding,next_xid,next_oid,next_multixact_id,next_multi_offset,oldest_xid,oldest_xid_dbid,oldest_active_xid,oldest_multi_xid,oldest_multi_dbid,oldest_commit_ts_xid,newest_commit_ts_xid,checkpoint_time}', prosrc => 'pg_control_checkpoint' }, { oid => '3443', From 4cd02d552263ed8d4b148aaefd24cd9dd8af57ed Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Tue, 21 Jul 2026 09:12:52 +0530 Subject: [PATCH 203/481] Allow logical replication workers to ignore default_transaction_read_only. Sequence synchronization updates sequence state via setval(), which explicitly calls PreventCommandIfReadOnly(). If default_transaction_read_only is enabled on the subscriber, this causes sequencesync workers to fail with "cannot execute setval() in a read-only transaction". Apply and tablesync workers are not affected, since they write via direct heap access rather than through these read-only-checked functions. Rather than special-casing sequencesync, override default_transaction_read_only to "off" for all logical replication workers in InitializeLogRepWorker(), the same way session_replication_role and search_path are already forced there. This keeps the initialization uniform. For PG-19, we kept the fix narrow by overriding default_transaction_read_only to "off" only for sequencesync workers. Reported-by: Noah Misch Author: vignesh C Reviewed-by: Amit Kapila Backpatch-through: 19 Discussion: https://postgr.es/m/20260710045217.f0.noahmisch@microsoft.com --- .../replication/logical/sequencesync.c | 8 +++ src/test/subscription/t/036_sequences.pl | 51 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/backend/replication/logical/sequencesync.c b/src/backend/replication/logical/sequencesync.c index 63ad46d7fd7..82f503f1c00 100644 --- a/src/backend/replication/logical/sequencesync.c +++ b/src/backend/replication/logical/sequencesync.c @@ -835,6 +835,14 @@ SequenceSyncWorkerMain(Datum main_arg) { int worker_slot = DatumGetInt32(main_arg); + /* + * Ignore default_transaction_read_only for sequence synchronization + * workers, as they need to be able to modify sequences regardless of that + * setting. + */ + SetConfigOption("default_transaction_read_only", "off", PGC_SUSET, + PGC_S_OVERRIDE); + SetupApplyOrSyncWorker(worker_slot); start_sequence_sync(); diff --git a/src/test/subscription/t/036_sequences.pl b/src/test/subscription/t/036_sequences.pl index 77ac9386cd8..dd6fa515df3 100644 --- a/src/test/subscription/t/036_sequences.pl +++ b/src/test/subscription/t/036_sequences.pl @@ -188,6 +188,57 @@ 'REFRESH PUBLICATION will not sync newly published sequence with copy_data as false' ); +########## +# Ensure that ALTER SUBSCRIPTION ... REFRESH SEQUENCES can still update +# sequence values and mark the sequence as ready even when +# default_transaction_read_only is enabled on the subscriber. +########## + +$node_subscriber->safe_psql( + 'postgres', qq( + ALTER SYSTEM SET default_transaction_read_only = on; + SELECT pg_reload_conf(); +)); + +# Update the existing sequence 'regress_s3' on the publisher +$node_publisher->safe_psql( + 'postgres', qq( + INSERT INTO regress_seq_test SELECT nextval('regress_s3') FROM generate_series(1,100); +)); + +$node_subscriber->safe_psql( + 'postgres', qq( + set default_transaction_read_only = off; + ALTER SUBSCRIPTION regress_seq_sub REFRESH SEQUENCES; +)); +$node_subscriber->poll_query_until('postgres', $synced_query) + or die "Timed out while waiting for subscriber to synchronize data"; + +# Check - sequence value is updated despite default_transaction_read_only +# being enabled on the subscriber +$result = $node_subscriber->safe_psql( + 'postgres', qq( + SELECT last_value, is_called FROM regress_s3; +)); +is($result, '200|t', + 'REFRESH SEQUENCES updates sequence value with default_transaction_read_only enabled' +); + +# Check - sequence is marked as ready ('r') +$result = $node_subscriber->safe_psql( + 'postgres', qq( + SELECT srsubstate FROM pg_subscription_rel WHERE srrelid = 'regress_s3'::regclass; +)); +is($result, 'r', + 'sequence is marked as ready after REFRESH SEQUENCES with default_transaction_read_only enabled' +); + +$node_subscriber->safe_psql( + 'postgres', qq( + ALTER SYSTEM SET default_transaction_read_only = off; + SELECT pg_reload_conf(); +)); + ########## # A sequence dropped concurrently on the publisher, while the sequencesync # worker's batch query is executing, must be treated the same as any other From 5454fe4a6e77661384a9766e6d760bf3ec1c9b0f Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 21 Jul 2026 08:33:25 +0200 Subject: [PATCH 204/481] Test what BEFORE UPDATE triggers do to FOR PORTION OF If a BEFORE trigger changes NEW.valid_at, what is the interaction with FOR PORTION OF? This commit gives a test to capture our current behavior: The trigger's change replaces the value we computed automatically, but it does not change the bounds of the temporal leftovers. This matches the behavior of MariaDB. On the other hand, DB2 rejects changing the start/end columns of a PERIOD. Since we don't have PERIODs, we can't reject the change at trigger definition time as DB2 does, but we could reject it at run time by comparing the values before and after running triggers. Author: Paul A. Jungwirth Discussion: https://www.postgresql.org/message-id/CA%2BrenyV3Cr9BvWsPeb1t8b%3DPk24apuzyGbubAEs_YsgLUTfXpg%40mail.gmail.com --- src/test/regress/expected/for_portion_of.out | 47 ++++++++++++++++++++ src/test/regress/sql/for_portion_of.sql | 47 ++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/src/test/regress/expected/for_portion_of.out b/src/test/regress/expected/for_portion_of.out index 271282c2d3b..0e217f104ef 100644 --- a/src/test/regress/expected/for_portion_of.out +++ b/src/test/regress/expected/for_portion_of.out @@ -1843,6 +1843,53 @@ SELECT * FROM for_portion_of_test ORDER BY valid_at; DROP FUNCTION fpo_append_name_suffix CASCADE; NOTICE: drop cascades to trigger fpo_before_insert_row on table for_portion_of_test DROP TABLE for_portion_of_test; +-- A BEFORE UPDATE trigger that changes the application-time column is allowed, +-- even if the results are senseless. +-- Note this is likely to cause a primary key violation. +CREATE TABLE for_portion_of_test ( + id int4range, + valid_at daterange, + name text +); +CREATE FUNCTION trg_fpo_change_valid_at() +RETURNS TRIGGER LANGUAGE plpgsql AS +$$ +BEGIN + NEW.valid_at = daterange('2018-01-01', '2019-01-01'); + RETURN NEW; +END; +$$; +CREATE TRIGGER fpo_before_update_row + BEFORE UPDATE ON for_portion_of_test + FOR EACH ROW EXECUTE PROCEDURE trg_fpo_change_valid_at(); +INSERT INTO for_portion_of_test VALUES ('[1,2)', '[2010-01-01,2020-01-01)', 'foo'); +UPDATE for_portion_of_test + FOR PORTION OF valid_at FROM '2018-05-01' TO '2018-06-01' + SET name = CONCAT(name, '!') + WHERE id = '[1,2)'; +SELECT * FROM for_portion_of_test ORDER BY id, valid_at; + id | valid_at | name +-------+-------------------------+------ + [1,2) | [2010-01-01,2018-05-01) | foo + [1,2) | [2018-01-01,2019-01-01) | foo! + [1,2) | [2018-06-01,2020-01-01) | foo +(3 rows) + +-- A primary key should reject anything invalid: +TRUNCATE for_portion_of_test; +ALTER TABLE for_portion_of_test + ADD CONSTRAINT for_portion_of_test_key + PRIMARY KEY (id, valid_at WITHOUT OVERLAPS); +INSERT INTO for_portion_of_test VALUES ('[1,2)', '[2010-01-01,2020-01-01)', 'foo'); +UPDATE for_portion_of_test + FOR PORTION OF valid_at FROM '2018-05-01' TO '2018-06-01' + SET name = CONCAT(name, '!') + WHERE id = '[1,2)'; +ERROR: conflicting key value violates exclusion constraint "for_portion_of_test_key" +DETAIL: Key (id, valid_at)=([1,2), [2010-01-01,2018-05-01)) conflicts with existing key (id, valid_at)=([1,2), [2018-01-01,2019-01-01)). +DROP TRIGGER fpo_before_update_row ON for_portion_of_test; +DROP FUNCTION trg_fpo_change_valid_at(); +DROP TABLE for_portion_of_test; -- Test with multiranges CREATE TABLE for_portion_of_test2 ( id int4range NOT NULL, diff --git a/src/test/regress/sql/for_portion_of.sql b/src/test/regress/sql/for_portion_of.sql index f48644347d1..a8d29a76b22 100644 --- a/src/test/regress/sql/for_portion_of.sql +++ b/src/test/regress/sql/for_portion_of.sql @@ -1215,6 +1215,53 @@ SELECT * FROM for_portion_of_test ORDER BY valid_at; DROP FUNCTION fpo_append_name_suffix CASCADE; DROP TABLE for_portion_of_test; +-- A BEFORE UPDATE trigger that changes the application-time column is allowed, +-- even if the results are senseless. +-- Note this is likely to cause a primary key violation. + +CREATE TABLE for_portion_of_test ( + id int4range, + valid_at daterange, + name text +); + +CREATE FUNCTION trg_fpo_change_valid_at() +RETURNS TRIGGER LANGUAGE plpgsql AS +$$ +BEGIN + NEW.valid_at = daterange('2018-01-01', '2019-01-01'); + RETURN NEW; +END; +$$; + +CREATE TRIGGER fpo_before_update_row + BEFORE UPDATE ON for_portion_of_test + FOR EACH ROW EXECUTE PROCEDURE trg_fpo_change_valid_at(); + +INSERT INTO for_portion_of_test VALUES ('[1,2)', '[2010-01-01,2020-01-01)', 'foo'); + +UPDATE for_portion_of_test + FOR PORTION OF valid_at FROM '2018-05-01' TO '2018-06-01' + SET name = CONCAT(name, '!') + WHERE id = '[1,2)'; + +SELECT * FROM for_portion_of_test ORDER BY id, valid_at; + +-- A primary key should reject anything invalid: +TRUNCATE for_portion_of_test; +ALTER TABLE for_portion_of_test + ADD CONSTRAINT for_portion_of_test_key + PRIMARY KEY (id, valid_at WITHOUT OVERLAPS); +INSERT INTO for_portion_of_test VALUES ('[1,2)', '[2010-01-01,2020-01-01)', 'foo'); +UPDATE for_portion_of_test + FOR PORTION OF valid_at FROM '2018-05-01' TO '2018-06-01' + SET name = CONCAT(name, '!') + WHERE id = '[1,2)'; + +DROP TRIGGER fpo_before_update_row ON for_portion_of_test; +DROP FUNCTION trg_fpo_change_valid_at(); +DROP TABLE for_portion_of_test; + -- Test with multiranges CREATE TABLE for_portion_of_test2 ( From 4d529d77f8f0e2bdbd6bc2119bb09eebffd23583 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 21 Jul 2026 15:27:02 +0200 Subject: [PATCH 205/481] Message style fixes Change DETAIL messages to conform to the style guide by capitalizing the first word of sentences and ending sentences with a period. Author: Peter Smith Reviewed-by: Chao Li Reviewed-by: vignesh C Reviewed-by: Xiaopeng Wang Reviewed-by: Peter Eisentraut Discussion: https://www.postgresql.org/message-id/flat/CAHut%2BPszSntkUgN%2BQa9matGY6MLEoFGSuVbuKDgnnTdZ7YPRwg%40mail.gmail.com --- contrib/dblink/dblink.c | 2 +- contrib/passwordcheck/expected/passwordcheck.out | 2 +- contrib/passwordcheck/expected/passwordcheck_1.out | 2 +- contrib/passwordcheck/passwordcheck.c | 2 +- contrib/pg_stash_advice/expected/pg_stash_advice.out | 2 +- .../pg_stash_advice/expected/pg_stash_advice_utf8.out | 2 +- contrib/pg_stash_advice/pg_stash_advice.c | 8 ++++---- contrib/postgres_fdw/expected/postgres_fdw.out | 2 +- src/backend/commands/copyto.c | 2 +- src/backend/commands/extension.c | 2 +- src/backend/commands/tablecmds.c | 10 +++++----- src/backend/libpq/be-secure-openssl.c | 2 +- .../test_extensions/expected/test_extensions.out | 2 +- src/test/regress/expected/create_view.out | 2 +- src/test/regress/expected/rangefuncs.out | 2 +- 15 files changed, 22 insertions(+), 22 deletions(-) diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c index 3329f9ac0cc..fd19e8b1480 100644 --- a/contrib/dblink/dblink.c +++ b/contrib/dblink/dblink.c @@ -2714,7 +2714,7 @@ dblink_security_check(PGconn *conn, const char *connname, const char *connstr) ereport(ERROR, (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED), errmsg("password or GSSAPI delegated credentials required"), - errdetail("Non-superusers may only connect using credentials they provide, eg: password in connection string or delegated GSSAPI credentials"), + errdetail("Non-superusers may only connect using credentials they provide, eg: password in connection string or delegated GSSAPI credentials."), errhint("Ensure provided credentials match target server's authentication method."))); } diff --git a/contrib/passwordcheck/expected/passwordcheck.out b/contrib/passwordcheck/expected/passwordcheck.out index 83472c76d27..9d02129e936 100644 --- a/contrib/passwordcheck/expected/passwordcheck.out +++ b/contrib/passwordcheck/expected/passwordcheck.out @@ -6,7 +6,7 @@ ALTER USER regress_passwordcheck_user1 PASSWORD 'a_nice_long_password'; -- error: too short ALTER USER regress_passwordcheck_user1 PASSWORD 'tooshrt'; ERROR: password is too short -DETAIL: password must be at least "passwordcheck.min_password_length" (8) bytes long +DETAIL: Password must be at least "passwordcheck.min_password_length" (8) bytes long. -- ok SET passwordcheck.min_password_length = 6; ALTER USER regress_passwordcheck_user1 PASSWORD 'v_shrt'; diff --git a/contrib/passwordcheck/expected/passwordcheck_1.out b/contrib/passwordcheck/expected/passwordcheck_1.out index fb12ec45cc4..a334720431d 100644 --- a/contrib/passwordcheck/expected/passwordcheck_1.out +++ b/contrib/passwordcheck/expected/passwordcheck_1.out @@ -6,7 +6,7 @@ ALTER USER regress_passwordcheck_user1 PASSWORD 'a_nice_long_password'; -- error: too short ALTER USER regress_passwordcheck_user1 PASSWORD 'tooshrt'; ERROR: password is too short -DETAIL: password must be at least "passwordcheck.min_password_length" (8) bytes long +DETAIL: Password must be at least "passwordcheck.min_password_length" (8) bytes long. -- ok SET passwordcheck.min_password_length = 6; ALTER USER regress_passwordcheck_user1 PASSWORD 'v_shrt'; diff --git a/contrib/passwordcheck/passwordcheck.c b/contrib/passwordcheck/passwordcheck.c index 13fd5c976a0..b45187cce9e 100644 --- a/contrib/passwordcheck/passwordcheck.c +++ b/contrib/passwordcheck/passwordcheck.c @@ -101,7 +101,7 @@ check_password(const char *username, ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("password is too short"), - errdetail("password must be at least \"passwordcheck.min_password_length\" (%d) bytes long", + errdetail("Password must be at least \"passwordcheck.min_password_length\" (%d) bytes long.", min_password_length))); /* check if the password contains the username */ diff --git a/contrib/pg_stash_advice/expected/pg_stash_advice.out b/contrib/pg_stash_advice/expected/pg_stash_advice.out index 788da854aa7..8c24a21295e 100644 --- a/contrib/pg_stash_advice/expected/pg_stash_advice.out +++ b/contrib/pg_stash_advice/expected/pg_stash_advice.out @@ -315,7 +315,7 @@ SELECT pg_create_advice_stash(' '); ERROR: advice stash name must begin with a letter or underscore and contain only letters, digits, and underscores SET pg_stash_advice.stash_name = '99bottles'; ERROR: invalid value for parameter "pg_stash_advice.stash_name": "99bottles" -DETAIL: advice stash name must begin with a letter or underscore and contain only letters, digits, and underscores +DETAIL: Advice stash name must begin with a letter or underscore and contain only letters, digits, and underscores. -- Clean up state in dynamic shared memory. SELECT pg_drop_advice_stash('regress_stash'); pg_drop_advice_stash diff --git a/contrib/pg_stash_advice/expected/pg_stash_advice_utf8.out b/contrib/pg_stash_advice/expected/pg_stash_advice_utf8.out index 7c532571ed5..c4bc93c8efb 100644 --- a/contrib/pg_stash_advice/expected/pg_stash_advice_utf8.out +++ b/contrib/pg_stash_advice/expected/pg_stash_advice_utf8.out @@ -13,4 +13,4 @@ SELECT pg_create_advice_stash('café'); ERROR: advice stash name must not contain non-ASCII characters SET pg_stash_advice.stash_name = 'café'; ERROR: invalid value for parameter "pg_stash_advice.stash_name": "café" -DETAIL: advice stash name must not contain non-ASCII characters +DETAIL: Advice stash name must not contain non-ASCII characters. diff --git a/contrib/pg_stash_advice/pg_stash_advice.c b/contrib/pg_stash_advice/pg_stash_advice.c index 777ff374599..79048329f61 100644 --- a/contrib/pg_stash_advice/pg_stash_advice.c +++ b/contrib/pg_stash_advice/pg_stash_advice.c @@ -388,7 +388,7 @@ pgsa_check_stash_name_guc(char **newval, void **extra, GucSource source) if (strlen(stash_name) + 1 > NAMEDATALEN) { GUC_check_errcode(ERRCODE_INVALID_PARAMETER_VALUE); - GUC_check_errdetail("advice stash names may not be longer than %d bytes", + GUC_check_errdetail("Advice stash names may not be longer than %d bytes.", NAMEDATALEN - 1); return false; } @@ -400,7 +400,7 @@ pgsa_check_stash_name_guc(char **newval, void **extra, GucSource source) if (!pg_is_ascii(stash_name)) { GUC_check_errcode(ERRCODE_INVALID_PARAMETER_VALUE); - GUC_check_errdetail("advice stash name must not contain non-ASCII characters"); + GUC_check_errdetail("Advice stash name must not contain non-ASCII characters."); return false; } @@ -412,7 +412,7 @@ pgsa_check_stash_name_guc(char **newval, void **extra, GucSource source) if (!pgsa_is_identifier(stash_name)) { GUC_check_errcode(ERRCODE_INVALID_PARAMETER_VALUE); - GUC_check_errdetail("advice stash name must begin with a letter or underscore and contain only letters, digits, and underscores"); + GUC_check_errdetail("Advice stash name must begin with a letter or underscore and contain only letters, digits, and underscores."); return false; } @@ -701,7 +701,7 @@ pgsa_set_advice_string(char *stash_name, int64 queryId, char *advice_string) ereport(ERROR, errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"), - errdetail("could not insert advice string into shared hash table")); + errdetail("Could not insert advice string into shared hash table.")); } /* Update the entry and release the lock. */ diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 9303de98b62..d19121b05da 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -11839,7 +11839,7 @@ DELETE FROM result_tbl; -- Test COPY TO when foreign table is partition COPY async_pt TO stdout; --error ERROR: cannot copy from foreign table "async_p1" -DETAIL: Partition "async_p1" is a foreign table in partitioned table "async_pt" +DETAIL: Partition "async_p1" is a foreign table in partitioned table "async_pt". HINT: Try the COPY (SELECT ...) TO variant. DROP FOREIGN TABLE async_p3; DROP TABLE base_tbl3; diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c index f9bc617ddb1..b0bdfb58104 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -856,7 +856,7 @@ BeginCopyTo(ParseState *pstate, ereport(ERROR, errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot copy from foreign table \"%s\"", relation_name), - errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\"", + errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\".", relation_name, RelationGetRelationName(rel)), errhint("Try the COPY (SELECT ...) TO variant.")); } diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index d073585c421..ae03f20c343 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -3433,7 +3433,7 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("extension \"%s\" does not support SET SCHEMA", NameStr(extForm->extname)), - errdetail("%s is not in the extension's schema \"%s\"", + errdetail("%s is not in the extension's schema \"%s\".", getObjectDescription(&dep, false), get_namespace_name(oldNspOid)))); } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index de1afb60bbc..ed212f5af5c 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -15609,7 +15609,7 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter type of a column used by a function or procedure"), - errdetail("%s depends on column \"%s\"", + errdetail("%s depends on column \"%s\".", getObjectDescription(&foundObject, false), colName))); break; @@ -15624,7 +15624,7 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter type of a column used by a view or rule"), - errdetail("%s depends on column \"%s\"", + errdetail("%s depends on column \"%s\".", getObjectDescription(&foundObject, false), colName))); break; @@ -15644,7 +15644,7 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter type of a column used in a trigger definition"), - errdetail("%s depends on column \"%s\"", + errdetail("%s depends on column \"%s\".", getObjectDescription(&foundObject, false), colName))); break; @@ -15663,7 +15663,7 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter type of a column used in a policy definition"), - errdetail("%s depends on column \"%s\"", + errdetail("%s depends on column \"%s\".", getObjectDescription(&foundObject, false), colName))); break; @@ -15722,7 +15722,7 @@ RememberAllDependentForRebuilding(AlteredTableInfo *tab, AlterTableType subtype, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter type of a column used by a publication WHERE clause"), - errdetail("%s depends on column \"%s\"", + errdetail("%s depends on column \"%s\".", getObjectDescription(&foundObject, false), colName))); break; diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 4ce2a92b964..2fb61db00d0 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -471,7 +471,7 @@ be_tls_init(bool isServerStart) ereport(isServerStart ? FATAL : LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("could not set SSL protocol version range"), - errdetail("\"%s\" cannot be higher than \"%s\"", + errdetail("\"%s\" cannot be higher than \"%s\".", "ssl_min_protocol_version", "ssl_max_protocol_version"))); goto error; diff --git a/src/test/modules/test_extensions/expected/test_extensions.out b/src/test/modules/test_extensions/expected/test_extensions.out index fdae52d6ab2..1b5debdeeb1 100644 --- a/src/test/modules/test_extensions/expected/test_extensions.out +++ b/src/test/modules/test_extensions/expected/test_extensions.out @@ -566,7 +566,7 @@ SELECT pg_describe_object(classid, objid, objsubid) as obj, -- fails, as function dep_req1 is not in the same schema as the extension. ALTER EXTENSION test_ext_req_schema1 SET SCHEMA test_func_dep3; ERROR: extension "test_ext_req_schema1" does not support SET SCHEMA -DETAIL: function test_func_dep2.dep_req1() is not in the extension's schema "test_func_dep1" +DETAIL: function test_func_dep2.dep_req1() is not in the extension's schema "test_func_dep1". -- Move back the function, and the extension can be moved. ALTER FUNCTION test_func_dep2.dep_req1() SET SCHEMA test_func_dep1; ALTER EXTENSION test_ext_req_schema1 SET SCHEMA test_func_dep3; diff --git a/src/test/regress/expected/create_view.out b/src/test/regress/expected/create_view.out index 63cf4b4371d..053fa56573f 100644 --- a/src/test/regress/expected/create_view.out +++ b/src/test/regress/expected/create_view.out @@ -1720,7 +1720,7 @@ rollback; -- likewise, altering a referenced column's type is prohibited ... alter table tt14t alter column f4 type integer using f4::integer; -- fail ERROR: cannot alter type of a column used by a view or rule -DETAIL: rule _RETURN on view tt14v depends on column "f4" +DETAIL: rule _RETURN on view tt14v depends on column "f4". -- ... but some bug might let it happen, so check defenses begin; -- destroy the dependency entry that prevents the ALTER: diff --git a/src/test/regress/expected/rangefuncs.out b/src/test/regress/expected/rangefuncs.out index 5cc94011e97..a7cb1b5611d 100644 --- a/src/test/regress/expected/rangefuncs.out +++ b/src/test/regress/expected/rangefuncs.out @@ -2279,7 +2279,7 @@ ERROR: attribute 5 of type record has been dropped rollback; alter table users alter column seq type numeric; -- fail, view has reference ERROR: cannot alter type of a column used by a view or rule -DETAIL: rule _RETURN on view usersview depends on column "seq" +DETAIL: rule _RETURN on view usersview depends on column "seq". -- likewise, check we don't crash if the dependency goes wrong begin; -- destroy the dependency entry that prevents the ALTER: From 2b6e7c0a7dbf36b39ce923373e65ac9e3b6ad7d9 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 21 Jul 2026 16:56:37 +0200 Subject: [PATCH 206/481] pg_upgrade: Message wording fix For internally consistent terminology --- src/bin/pg_upgrade/controldata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c index cffcd4b0eba..fd772ba4f38 100644 --- a/src/bin/pg_upgrade/controldata.c +++ b/src/bin/pg_upgrade/controldata.c @@ -743,7 +743,7 @@ check_control_data(ControlData *oldctrl, * data checksums, before retrying. */ if (oldctrl->data_checksum_version > PG_DATA_CHECKSUM_VERSION) - pg_fatal("checksums are being enabled in the old cluster"); + pg_fatal("data checksums are being enabled in the old cluster"); /* * We might eventually allow upgrades from checksum to no-checksum From 7d1b39fc3d9aca1175d00b2859d896f6e81ecad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Tue, 21 Jul 2026 17:18:06 +0200 Subject: [PATCH 207/481] Remove assertion added by commit 7dcea51c2a4d MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We've got no reports of problems. Get rid of it. Author: Álvaro Herrera Backpatch-through: 19 Discussion: https://postgr.es/m/alewd1f2G0kKeM1i@alvherre.pgsql --- src/backend/replication/logical/logical.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c index 3541fc793e4..c30d40a8641 100644 --- a/src/backend/replication/logical/logical.c +++ b/src/backend/replication/logical/logical.c @@ -2103,7 +2103,6 @@ LogicalSlotAdvanceAndCheckSnapState(XLogRecPtr moveto, bool *found_consistent_snapshot) { LogicalDecodingContext *ctx; - ResourceOwner old_resowner PG_USED_FOR_ASSERTS_ONLY = CurrentResourceOwner; XLogRecPtr retlsn; Assert(XLogRecPtrIsValid(moveto)); @@ -2162,18 +2161,8 @@ LogicalSlotAdvanceAndCheckSnapState(XLogRecPtr moveto, * might still have critical updates to do. */ if (record) - { LogicalDecodingProcessRecord(ctx, ctx->reader); - /* - * We used to have bugs where logical decoding would fail to - * preserve the resource owner. That's important here, so - * verify that that doesn't happen anymore. XXX this could be - * removed once it's been battle-tested. - */ - Assert(CurrentResourceOwner == old_resowner); - } - CHECK_FOR_INTERRUPTS(); } From d972ead131cc11463a5ce02433cc994b5b817558 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 21 Jul 2026 17:18:41 +0200 Subject: [PATCH 208/481] Fix typo from commit c1fe2d1a383 --- src/bin/pg_upgrade/check.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index f8f31382835..184379c52af 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -1859,7 +1859,7 @@ check_for_gist_inet_ops(ClusterInfo *cluster) { fclose(report.file); pg_log(PG_REPORT, "fatal"); - pg_fatal("Your installation contains indexes that use btree_gist extension's\n" + pg_fatal("Your installation contains indexes that use the btree_gist extension's\n" "gist_inet_ops or gist_cidr_ops operator classes, which cannot be\n" "binary-upgraded. Replace them with indexes that use the built-in GiST\n" "inet_ops operator class.\n" From d9d235510e10fb61457744fc7798852c46260f29 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Tue, 21 Jul 2026 11:59:37 -0400 Subject: [PATCH 209/481] doc: clarify to_char("OF") HH/MM doesn't represent actual chars Change formatting and chars to be less of a match against actual formatting characters. Reported-by: Phil Discussion: https://postgr.es/m/177801333530.795.16999885814007014333@wrigleys.postgresql.org Backpatch-through: 19 --- doc/src/sgml/func/func-formatting.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/func/func-formatting.sgml b/doc/src/sgml/func/func-formatting.sgml index af9e2223998..e4edaf4f42c 100644 --- a/doc/src/sgml/func/func-formatting.sgml +++ b/doc/src/sgml/func/func-formatting.sgml @@ -424,8 +424,8 @@ OF - time-zone offset from UTC (HH - or HH:MM) + time-zone offset from UTC (hh + or hh:mi) From 9fa107f07f06d8b0281f729931512ee896aa3440 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Tue, 21 Jul 2026 12:06:10 -0400 Subject: [PATCH 210/481] doc: clarify how TIMESTAMP WITH TIME ZONE behaves Mention "time zone conversion" as a way to clarify the time zone is not stored in the database. Reported-by: Richard Neill Discussion: https://postgr.es/m/ddf41f033a8add84e1f28a095defafae@richardneill.org Backpatch-through: 19 --- doc/src/sgml/datatype.sgml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index d8d91678e86..339fec8ac08 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -264,13 +264,13 @@ timestamp [ (p) ] [ without time zone ] - date and time (no time zone) + date and time (no time zone conversion) timestamp [ (p) ] with time zone timestamptz - date and time, including time zone + date and time, including time zone conversion @@ -1768,7 +1768,7 @@ SELECT 'abc \153\154\155 \052\251\124'::bytea; timestamp [ (p) ] [ without time zone ] 8 bytes - both date and time (no time zone) + both date and time (no time zone conversion) 4713 BC 294276 AD 1 microsecond @@ -1776,7 +1776,7 @@ SELECT 'abc \153\154\155 \052\251\124'::bytea; timestamp [ (p) ] with time zone 8 bytes - both date and time, with time zone + both date and time, with time zone conversion 4713 BC 294276 AD 1 microsecond @@ -2263,8 +2263,9 @@ TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02' then it is assumed to be in the time zone indicated by the system's parameter, and is converted to UTC using the offset for the timezone zone. - In either case, the value is stored internally as UTC, and the - originally stated or assumed time zone is not retained. + In either case, the value is stored internally as UTC. The + originally stated or assumed time zone is not retained and + cannot be retrieved later. From bdcea66f0f3b2f16c51d6c95bb9d0bb317fdfd99 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Wed, 22 Jul 2026 08:47:44 -0400 Subject: [PATCH 211/481] walsummarizer: Guard against WAL files whose tail ends are not valid. SummarizeWAL documents that maximum_lsn should be passed as "the switch point when reading a historic timeline, or the most-recently-measured end of WAL when reading the current timeline." But the caller always passed the most recently measured end-of-WAL even when reading from a historic timeline, due to an oversight on my part. Fix that. As far as I can determine, for this to become an issue in practice, it's necessary to have a corrupted WAL file in the archive. SummarizeWAL checks that every record it processes both starts and ends before switch_lsn; so if all the WAL files in the archive are valid, SummarizeWAL will still discover where it should stop summarizing and do the right thing. However, if there's a corrupted file in the WAL archive, and if it is also the case that the end of the current timeline has advanced past the switch point, then the incorrect maximum_lsn value can result in trying to read an invalid record and erroring out, which leads repeatedly retrying and failing with an error every time. One way this could occur is if a new primary is promoted and creates a .partial file, and the user manually renames that file to remove the suffix, and it is then archived. In that situation, the tail end of the file need not be valid WAL, and that could lead to a stuck WAL summarizer. Reported-by: Fabrice Chapuis Analyzed-by: Thom Brown (using claude) Discussion: http://postgr.es/m/CAA5-nLDdvGMkN6Z-GaHGHG5T7QWEgv4YoHO7XvOJbeD00cghNg@mail.gmail.com Backpatch-through: 17 --- src/backend/postmaster/walsummarizer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/postmaster/walsummarizer.c b/src/backend/postmaster/walsummarizer.c index 4f12eaf2c85..8b429cb51d7 100644 --- a/src/backend/postmaster/walsummarizer.c +++ b/src/backend/postmaster/walsummarizer.c @@ -349,6 +349,7 @@ WalSummarizerMain(const void *startup_data, size_t startup_data_len) { XLogRecPtr latest_lsn; TimeLineID latest_tli; + XLogRecPtr maximum_lsn; XLogRecPtr end_of_summary_lsn; /* Flush any leaked data in the top-level context */ @@ -413,9 +414,10 @@ WalSummarizerMain(const void *startup_data, size_t startup_data_len) } /* Summarize WAL. */ + maximum_lsn = XLogRecPtrIsValid(switch_lsn) ? switch_lsn : latest_lsn; end_of_summary_lsn = SummarizeWAL(current_tli, current_lsn, exact, - switch_lsn, latest_lsn); + switch_lsn, maximum_lsn); Assert(XLogRecPtrIsValid(end_of_summary_lsn)); Assert(end_of_summary_lsn >= current_lsn); From 57e7c52c0fe43fff36d0f4440eea13cf5668b160 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Thu, 23 Jul 2026 10:39:03 +0530 Subject: [PATCH 212/481] Reject sequence synchronization against pre-PostgreSQL 19 publishers. Sequence synchronization requires the page_lsn field returned by pg_get_sequence_data(), which was added in PostgreSQL 19. Previously, requesting sequence synchronization against an older publisher (via ALTER SUBSCRIPTION ... REFRESH SEQUENCES or by running ALTER SUBSCRIPTION ... CONNECTION on a disabled subscription with sequences in the INIT state and subsequently enabling the subscription) would cause the sequence synchronization worker to repeatedly fail with a confusing "invalid query response" error. Check the publisher's server version up front in both AlterSubscription_refresh_seq() and copy_sequences(), and error out immediately when it predates PostgreSQL 19. Also document the PostgreSQL 19 publisher requirement for sequence replication in the logical replication documentation and in ALTER SUBSCRIPTION ... REFRESH SEQUENCES. Reported-by: Noah Misch Author: vignesh C Reviewed-by: Shveta Malik Reviewed-by: Hayato Kuroda Reviewed-by: Amit Kapila Backpatch-through: 19 Discussion: https://postgr.es/m/20260710045217.f0.noahmisch@microsoft.com --- doc/src/sgml/logical-replication.sgml | 18 +++++++++++++++++- doc/src/sgml/ref/alter_subscription.sgml | 6 ++++++ src/backend/commands/subscriptioncmds.c | 10 ++++++++++ src/backend/replication/logical/sequencesync.c | 10 ++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index 2edf65af66e..efbed7b3bcb 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -1803,6 +1803,13 @@ Included in publications: configuration. + + + Sequence synchronization requires the publisher to be running + PostgreSQL 19 or later. + + + Sequence Definition Mismatches @@ -2353,7 +2360,16 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER ALTER SUBSCRIPTION ... REFRESH SEQUENCES or by copying the current data from the publisher (perhaps using pg_dump) or by determining a sufficiently high value - from the tables themselves. + from the tables themselves. Note that + + ALTER SUBSCRIPTION ... REFRESH SEQUENCES only + re-synchronizes sequences that are already known to the subscription + (see ); in particular, it + requires the publisher to be running PostgreSQL + 19 or later. Before relying on it to prepare for a switchover or + failover, confirm that the publisher's version supports sequence + replication and that the sequences of interest are already known to the + subscription. diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml index 51081ef369e..ec6d5f1dcf6 100644 --- a/doc/src/sgml/ref/alter_subscription.sgml +++ b/doc/src/sgml/ref/alter_subscription.sgml @@ -245,6 +245,12 @@ ALTER SUBSCRIPTION name RENAME TO < sequences are subscribed. Run REFRESH PUBLICATION first if the publication's set of sequences has changed. + + + Sequence replication requires the publisher to be running + PostgreSQL 19 or later. + + See for recommendations on how to handle any warnings about sequence definition diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index a2c079fcb5a..de62ec49514 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -1322,6 +1322,16 @@ AlterSubscription_refresh_seq(Subscription *sub) /* The publisher connection is only needed for the origin check. */ PG_TRY(); { + /* + * Sequence synchronization depends on publisher-side functionality + * introduced in PostgreSQL 19, so it cannot work against an older + * publisher. + */ + if (walrcv_server_version(wrconn) < 190000) + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot synchronize sequences if the publisher is running a version earlier than PostgreSQL 19")); + check_publications_origin_sequences(wrconn, sub->publications, true, sub->origin, NULL, 0, sub->name); } diff --git a/src/backend/replication/logical/sequencesync.c b/src/backend/replication/logical/sequencesync.c index 82f503f1c00..06946afe683 100644 --- a/src/backend/replication/logical/sequencesync.c +++ b/src/backend/replication/logical/sequencesync.c @@ -444,6 +444,16 @@ copy_sequences(WalReceiverConn *conn) StringInfoData cmd; MemoryContext oldctx; + /* + * Sequence synchronization depends on publisher-side functionality + * introduced in PostgreSQL 19, so it cannot work against an older + * publisher. + */ + if (walrcv_server_version(conn) < 190000) + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot synchronize sequences if the publisher is running a version earlier than PostgreSQL 19")); + initStringInfo(&seqstr); initStringInfo(&cmd); From 703859d7c649fc44da94fe1f1b9c24dcd58d9372 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Thu, 23 Jul 2026 14:37:42 +0900 Subject: [PATCH 213/481] injection_points: Clear waiter slot on error and exit injection_wait() only clears its slot in the waiter array after the wait loop finishes. When the waiting query is canceled or the backend is terminated (wait look has a CHECK_FOR_INTERRUPS), the slot leaks. Later wakeups of the same point then bump the counter of the leaked slot instead of the real waiter, that sleeps forever. Repeated leaks can exhaust all the slots. The code is changed so as the waiting loop is wrapped with PG_ENSURE_ERROR_CLEANUP, so as the injection point slots, that are shared resources, can be cleaned up on ERROR as much as a FATAL. An isolation test is added: cancel one waiter, terminate another waiter, then check that a later waiter still receives a wakeup. Without the fixed code, the test would fail on timeout. Author: Zsolt Parragi Discussion: https://postgr.es/m/CAN4CZFO+KF=cc0-iEg28RhqRBp_fTs6D4b8b7D7DB-pGYP3Ccg@mail.gmail.com Backpatch-through: 17 --- src/test/modules/injection_points/Makefile | 1 + .../expected/wait_cleanup.out | 87 +++++++++++++++++++ .../injection_points/injection_points.c | 39 ++++++--- src/test/modules/injection_points/meson.build | 1 + .../injection_points/specs/wait_cleanup.spec | 50 +++++++++++ 5 files changed, 166 insertions(+), 12 deletions(-) create mode 100644 src/test/modules/injection_points/expected/wait_cleanup.out create mode 100644 src/test/modules/injection_points/specs/wait_cleanup.spec diff --git a/src/test/modules/injection_points/Makefile b/src/test/modules/injection_points/Makefile index c01d2fb095c..fac80f3a4a7 100644 --- a/src/test/modules/injection_points/Makefile +++ b/src/test/modules/injection_points/Makefile @@ -19,6 +19,7 @@ ISOLATION = basic \ repack_temporal_multirange \ repack_toast \ syscache-update-pruned \ + wait_cleanup \ heap_lock_update # some isolation tests require wal_level=replica diff --git a/src/test/modules/injection_points/expected/wait_cleanup.out b/src/test/modules/injection_points/expected/wait_cleanup.out new file mode 100644 index 00000000000..c5be17428fc --- /dev/null +++ b/src/test/modules/injection_points/expected/wait_cleanup.out @@ -0,0 +1,87 @@ +Parsed test spec with 3 sessions + +starting permutation: wait1 cancel3 noop3 wait2 wakeup3 noop2 detach3 +injection_points_attach +----------------------- + +(1 row) + +step wait1: SELECT injection_points_run('injection-points-wait'); +step cancel3: + SELECT pg_cancel_backend(pid) FROM pg_stat_activity + WHERE wait_event = 'injection-points-wait'; + +step wait1: <... completed> +ERROR: canceling statement due to user request +step cancel3: <... completed> +pg_cancel_backend +----------------- +t +(1 row) + +step noop3: +step wait2: SELECT injection_points_run('injection-points-wait'); +step wakeup3: SELECT injection_points_wakeup('injection-points-wait'); +injection_points_wakeup +----------------------- + +(1 row) + +step wait2: <... completed> +injection_points_run +-------------------- + +(1 row) + +step noop2: +step detach3: SELECT injection_points_detach('injection-points-wait'); +injection_points_detach +----------------------- + +(1 row) + + +starting permutation: wait1 terminate3 noop3 wait2 wakeup3 noop2 detach3 +injection_points_attach +----------------------- + +(1 row) + +step wait1: SELECT injection_points_run('injection-points-wait'); +step terminate3: + SELECT pg_terminate_backend(pid) FROM pg_stat_activity + WHERE wait_event = 'injection-points-wait'; + +step wait1: <... completed> +FATAL: terminating connection due to administrator command +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. + +step terminate3: <... completed> +pg_terminate_backend +-------------------- +t +(1 row) + +step noop3: +step wait2: SELECT injection_points_run('injection-points-wait'); +step wakeup3: SELECT injection_points_wakeup('injection-points-wait'); +injection_points_wakeup +----------------------- + +(1 row) + +step wait2: <... completed> +injection_points_run +-------------------- + +(1 row) + +step noop2: +step detach3: SELECT injection_points_detach('injection-points-wait'); +injection_points_detach +----------------------- + +(1 row) + diff --git a/src/test/modules/injection_points/injection_points.c b/src/test/modules/injection_points/injection_points.c index ba282e3dcab..1683498e733 100644 --- a/src/test/modules/injection_points/injection_points.c +++ b/src/test/modules/injection_points/injection_points.c @@ -222,6 +222,19 @@ injection_notice(const char *name, const void *private_data, void *arg) elog(NOTICE, "notice triggered for injection point %s", name); } +/* + * Error cleanup callback for injection point waits. + */ +static void +injection_wait_cleanup(int code, Datum arg) +{ + int index = DatumGetInt32(arg); + + SpinLockAcquire(&inj_state->lock); + inj_state->name[index][0] = '\0'; + SpinLockRelease(&inj_state->lock); +} + /* Wait on a condition variable, awaken by injection_points_wakeup() */ void injection_wait(const char *name, const void *private_data, void *arg) @@ -266,24 +279,26 @@ injection_wait(const char *name, const void *private_data, void *arg) /* And sleep.. */ ConditionVariablePrepareToSleep(&inj_state->wait_point); - for (;;) + PG_ENSURE_ERROR_CLEANUP(injection_wait_cleanup, Int32GetDatum(index)); { - uint32 new_wait_counts; + for (;;) + { + uint32 new_wait_counts; - SpinLockAcquire(&inj_state->lock); - new_wait_counts = inj_state->wait_counts[index]; - SpinLockRelease(&inj_state->lock); + SpinLockAcquire(&inj_state->lock); + new_wait_counts = inj_state->wait_counts[index]; + SpinLockRelease(&inj_state->lock); - if (old_wait_counts != new_wait_counts) - break; - ConditionVariableSleep(&inj_state->wait_point, injection_wait_event); + if (old_wait_counts != new_wait_counts) + break; + ConditionVariableSleep(&inj_state->wait_point, injection_wait_event); + } + ConditionVariableCancelSleep(); } - ConditionVariableCancelSleep(); + PG_END_ENSURE_ERROR_CLEANUP(injection_wait_cleanup, Int32GetDatum(index)); /* Remove this injection point from the waiters. */ - SpinLockAcquire(&inj_state->lock); - inj_state->name[index][0] = '\0'; - SpinLockRelease(&inj_state->lock); + injection_wait_cleanup(0, Int32GetDatum(index)); } /* diff --git a/src/test/modules/injection_points/meson.build b/src/test/modules/injection_points/meson.build index 59dba1cb023..163b6374ebc 100644 --- a/src/test/modules/injection_points/meson.build +++ b/src/test/modules/injection_points/meson.build @@ -50,6 +50,7 @@ tests += { 'repack_temporal_multirange', 'repack_toast', 'syscache-update-pruned', + 'wait_cleanup', 'heap_lock_update', ], 'runningcheck': false, # see syscache-update-pruned diff --git a/src/test/modules/injection_points/specs/wait_cleanup.spec b/src/test/modules/injection_points/specs/wait_cleanup.spec new file mode 100644 index 00000000000..ed7d21c4de4 --- /dev/null +++ b/src/test/modules/injection_points/specs/wait_cleanup.spec @@ -0,0 +1,50 @@ +# Check that a canceled or terminated waiter does not leave a stale slot +# behind in the waiter array. A leaked slot would make later wakeups of +# the same injection point bump the leaked slot's counter instead of the +# real waiter's, leaving the real waiter stuck. + +setup +{ + CREATE EXTENSION injection_points; +} +teardown +{ + DROP EXTENSION injection_points; +} + +# The first waiter, that gets canceled or terminated. This does not +# use injection_points_set_local() on purpose: the injection point +# must survive s1's termination so that s3 can still detach it. +session s1 +setup { + SELECT injection_points_attach('injection-points-wait', 'wait'); +} +step wait1 { SELECT injection_points_run('injection-points-wait'); } + +# The second waiter, that receives a wakeup. +session s2 +step wait2 { SELECT injection_points_run('injection-points-wait'); } +step noop2 { } + +# Control session. The blocker annotations on cancel3/terminate3, +# together with noop3, make the tester wait until wait1 has fully +# completed before starting wait2. Otherwise, wait2 could register a +# new waiter slot while s1 still owns the previous one. +session s3 +step cancel3 { + SELECT pg_cancel_backend(pid) FROM pg_stat_activity + WHERE wait_event = 'injection-points-wait'; +} +step terminate3 { + SELECT pg_terminate_backend(pid) FROM pg_stat_activity + WHERE wait_event = 'injection-points-wait'; +} +step wakeup3 { SELECT injection_points_wakeup('injection-points-wait'); } +step detach3 { SELECT injection_points_detach('injection-points-wait'); } +step noop3 { } + +permutation wait1 cancel3(wait1) noop3 wait2 wakeup3 noop2 detach3 + +# The terminate permutation has to stay last: s1's connection is dead +# afterwards, and the tester never reconnects a session. +permutation wait1 terminate3(wait1) noop3 wait2 wakeup3 noop2 detach3 From 42b480d286828f94e476ab45a752321602b12c75 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Thu, 23 Jul 2026 19:22:36 +0900 Subject: [PATCH 214/481] doc: Improve pg_stat_recovery documentation Improve the documentation for pg_stat_recovery in several ways: - Mention the view in high-availability.sgml as a way to monitor recovery state and replay progress, alongside the existing recovery information functions. - Clarify that the view returns at most one row, not exactly one row, and no rows to users who lack the pg_read_all_stats privilege. - Correct the description of last_replayed_end_lsn to clarify that it is the end LSN of the last replayed record plus one. - Document that replay_end_tli equals last_replayed_tli when no WAL record is currently being replayed. - Clarify that current_chunk_start_time is NULL until streaming WAL has been received. Backpatch to v19, where pg_stat_recovery was introduced. Author: Fujii Masao Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/CAHGQGwGRavm18HqnQn_f68QB96qk6arhjET1V93OJH09Mgojkg@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/high-availability.sgml | 13 ++++++++---- doc/src/sgml/monitoring.sgml | 33 +++++++++++++++++------------ src/include/access/xlogrecovery.h | 4 ++-- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/doc/src/sgml/high-availability.sgml b/doc/src/sgml/high-availability.sgml index 6d9636bd125..fd338ab1540 100644 --- a/doc/src/sgml/high-availability.sgml +++ b/doc/src/sgml/high-availability.sgml @@ -920,7 +920,10 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' pg_stat_wal_receiver view. A large difference between pg_last_wal_replay_lsn and the view's flushed_lsn indicates that WAL is being - received faster than it can be replayed. + received faster than it can be replayed. Recovery state and replay + progress can also be monitored via the + + pg_stat_recovery view. @@ -1801,9 +1804,11 @@ postgres=# WAIT FOR LSN '0/306EE20'; (In server versions before 14, the in_hot_standby parameter did not exist; a workable substitute method for older servers is SHOW transaction_read_only.) In addition, a set of - functions () allow users to - access information about the standby server. These allow you to write - programs that are aware of the current state of the database. These + functions () and the + + pg_stat_recovery view allow users to + access information about the standby server. These facilities allow you to + write programs that are aware of the current state of the database. They can be used to monitor the progress of recovery, or to allow you to write complex programs that restore the database to particular states. diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 9eeda36001f..1d8094c55d4 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -340,7 +340,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser pg_stat_recoverypg_stat_recovery - Only one row, showing statistics about the state of recovery. + At most one row, showing statistics about the recovery state. See pg_stat_recovery for details. @@ -1965,9 +1965,11 @@ description | Waiting for a newly initialized WAL file to reach durable storage - The pg_stat_recovery view will contain only + The pg_stat_recovery view will contain at most one row, showing statistics about the recovery state of the startup - process. This view returns no row when the server is not in recovery. + process. This view returns no rows when the server is not in recovery + or the user does not have privileges of the + pg_read_all_stats role.
    @@ -2009,8 +2011,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_replayed_end_lsnpg_lsn - End write-ahead log location of the last successfully replayed - WAL record. + End write-ahead log location, plus one, of the last successfully + replayed WAL record. @@ -2039,18 +2041,20 @@ description | Waiting for a newly initialized WAL file to reach durable storage replay_end_tliinteger - Timeline of the WAL record currently being replayed. + Timeline of the WAL record currently being replayed. When no record + is being actively replayed, equals + last_replayed_tli. - recovery_last_xact_time timestamp with time zone - - - Timestamp of the last transaction commit or abort replayed during - recovery. This is the time at which the commit or abort WAL record - for that transaction was generated on the primary. + recovery_last_xact_time timestamp with time zone + + + Timestamp of the last transaction commit or abort record replayed + during recovery. This is the time at which the commit or abort WAL + record for that transaction was generated on the primary. @@ -2060,8 +2064,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage Time when the startup process observed that replay had caught up - with the latest received WAL chunk. Used in recovery-conflict - timing and replay/apply-lag diagnostics. NULL if not yet + with the latest WAL chunk received from streaming replication. + Used in recovery-conflict timing and replay/apply-lag diagnostics. + NULL if streaming WAL has not yet been received or the time is not available. diff --git a/src/include/access/xlogrecovery.h b/src/include/access/xlogrecovery.h index ba7750dca0b..61877f9c45c 100644 --- a/src/include/access/xlogrecovery.h +++ b/src/include/access/xlogrecovery.h @@ -112,8 +112,8 @@ typedef struct XLogRecoveryCtlData TimestampTz recoveryLastXTime; /* - * timestamp of when we started replaying the current chunk of WAL data, - * only relevant for replication or archive recovery + * timestamp of when we caught up with the latest WAL chunk received from + * streaming replication */ TimestampTz currentChunkStartTime; /* Recovery pause state */ From 41be67e534ffccd055922482c17b874fb7a74f30 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Thu, 23 Jul 2026 19:24:55 +0900 Subject: [PATCH 215/481] Validate subscription conninfo on owner change For subscriptions using SERVER, changing the owner can change the effective connection string. However, ALTER SUBSCRIPTION ... OWNER TO did not validate the generated conninfo for the new owner. As a result, ownership could be transferred to a non-superuser whose generated connection string did not satisfy password_required=true. The ownership change succeeded, but the subscription would fail later when the worker or another command tried to connect. Fix this by making ALTER SUBSCRIPTION ... OWNER TO validate the new owner's generated conninfo with walrcv_check_conninfo(). Backpatch to v19, where SERVER subscriptions were introduced. Author: Fujii Masao Reviewed-by: Yuanchao Zhang <145zhangyc@gmail.com> Reviewed-by: Hayato Kuroda Discussion: https://postgr.es/m/CAHGQGwFGa6+wWVgUmZPFwN=fBY59mYPkMK3=TxT=Pv5C1mNNRQ@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/ref/alter_subscription.sgml | 7 +++++++ src/backend/commands/subscriptioncmds.c | 14 ++++++++++++-- src/test/regress/expected/subscription.out | 17 +++++++++++++++++ src/test/regress/regress.c | 9 +++++++++ src/test/regress/sql/subscription.sql | 16 ++++++++++++++++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml index ec6d5f1dcf6..33c78aef748 100644 --- a/doc/src/sgml/ref/alter_subscription.sgml +++ b/doc/src/sgml/ref/alter_subscription.sgml @@ -53,6 +53,13 @@ ALTER SUBSCRIPTION name RENAME TO < to alter the owner, you must be able to SET ROLE to the new owning role. If the subscription has password_required=false, only superusers can modify it. + If the subscription uses a foreign server, the new owner must have + USAGE privilege on the foreign server, a user mapping + for the new owner or for PUBLIC must exist, and the + connection string generated for the new owner must be valid. If the new + owner is not a superuser and the subscription has + password_required=true, the generated connection string + must include a password. diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index de62ec49514..c05f7c5de4c 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -2746,11 +2746,12 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) /* * If the subscription uses a server, check that the new owner has USAGE - * privileges on the server and that a user mapping exists. Note: does not - * re-check the resulting connection string. + * privileges on the server, that a user mapping exists, and that the + * resulting connection string is valid for the new owner. */ if (OidIsValid(form->subserver)) { + char *conninfo; ForeignServer *server = GetForeignServer(form->subserver); aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, newOwnerId, ACL_USAGE); @@ -2763,6 +2764,15 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) /* make sure a user mapping exists */ GetUserMapping(newOwnerId, server->serverid); + + conninfo = ForeignServerConnectionString(newOwnerId, server); + + /* Load the library providing us libpq calls. */ + load_file("libpqwalreceiver", false); + /* Check the connection info string. */ + walrcv_check_conninfo(conninfo, + form->subpasswordrequired && + !superuser_arg(newOwnerId)); } form->subowner = newOwnerId; diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index 8dbfac66326..6d89cec1503 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -9,6 +9,10 @@ CREATE FUNCTION test_fdw_connection(oid, oid, internal) RETURNS text AS :'regresslib', 'test_fdw_connection' LANGUAGE C; +CREATE FUNCTION test_fdw_connection_no_password(oid, oid, internal) + RETURNS text + AS :'regresslib', 'test_fdw_connection_no_password' + LANGUAGE C; CREATE ROLE regress_subscription_user LOGIN SUPERUSER; CREATE ROLE regress_subscription_user2; CREATE ROLE regress_subscription_user3 IN ROLE pg_create_subscription; @@ -189,6 +193,18 @@ CREATE SUBSCRIPTION regress_testsub6 SERVER test_server WARNING: subscription was created, but is not connected HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. RESET SESSION AUTHORIZATION; +GRANT USAGE ON FOREIGN SERVER test_server TO regress_subscription_user2; +CREATE USER MAPPING FOR regress_subscription_user2 SERVER test_server OPTIONS(user 'foo'); +ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection_no_password; +WARNING: changing the foreign-data wrapper connection function can cause the options for dependent objects to become invalid +-- fail, new owner's generated conninfo must satisfy password_required +ALTER SUBSCRIPTION regress_testsub6 OWNER TO regress_subscription_user2; +ERROR: password is required +DETAIL: Non-superusers must provide a password in the connection string. +ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection; +WARNING: changing the foreign-data wrapper connection function can cause the options for dependent objects to become invalid +DROP USER MAPPING FOR regress_subscription_user2 SERVER test_server; +REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user2; REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user3; SET SESSION AUTHORIZATION regress_subscription_user3; -- ok, lacks USAGE on test_server, but replacing connection anyway @@ -231,6 +247,7 @@ HINT: Use DROP ... CASCADE to drop the dependent objects too. ALTER FOREIGN DATA WRAPPER test_fdw NO CONNECTION; WARNING: removing the foreign-data wrapper connection function will cause dependent subscriptions to fail DROP FUNCTION test_fdw_connection(oid, oid, internal); +DROP FUNCTION test_fdw_connection_no_password(oid, oid, internal); DROP FOREIGN DATA WRAPPER test_fdw; -- fail - invalid connection string during ALTER ALTER SUBSCRIPTION regress_testsub CONNECTION 'foobar'; diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 90bb2a7e881..3cc3756a81a 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -742,6 +742,15 @@ test_fdw_connection(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(cstring_to_text("dbname=regress_doesnotexist user=doesnotexist password=secret")); } +PG_FUNCTION_INFO_V1(test_fdw_connection_no_password); +Datum +test_fdw_connection_no_password(PG_FUNCTION_ARGS) +{ + /* Ensure the test fails if no valid user mapping exists. */ + GetUserMapping(PG_GETARG_OID(0), PG_GETARG_OID(1)); + PG_RETURN_TEXT_P(cstring_to_text("dbname=regress_doesnotexist user=doesnotexist")); +} + PG_FUNCTION_INFO_V1(is_catalog_text_unique_index_oid); Datum is_catalog_text_unique_index_oid(PG_FUNCTION_ARGS) diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql index 05533d66675..cfee0b41224 100644 --- a/src/test/regress/sql/subscription.sql +++ b/src/test/regress/sql/subscription.sql @@ -12,6 +12,10 @@ CREATE FUNCTION test_fdw_connection(oid, oid, internal) RETURNS text AS :'regresslib', 'test_fdw_connection' LANGUAGE C; +CREATE FUNCTION test_fdw_connection_no_password(oid, oid, internal) + RETURNS text + AS :'regresslib', 'test_fdw_connection_no_password' + LANGUAGE C; CREATE ROLE regress_subscription_user LOGIN SUPERUSER; CREATE ROLE regress_subscription_user2; @@ -136,6 +140,17 @@ CREATE SUBSCRIPTION regress_testsub6 SERVER test_server PUBLICATION testpub WITH (slot_name = 'dummy', connect = false); RESET SESSION AUTHORIZATION; +GRANT USAGE ON FOREIGN SERVER test_server TO regress_subscription_user2; +CREATE USER MAPPING FOR regress_subscription_user2 SERVER test_server OPTIONS(user 'foo'); +ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection_no_password; + +-- fail, new owner's generated conninfo must satisfy password_required +ALTER SUBSCRIPTION regress_testsub6 OWNER TO regress_subscription_user2; + +ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection; +DROP USER MAPPING FOR regress_subscription_user2 SERVER test_server; +REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user2; + REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user3; SET SESSION AUTHORIZATION regress_subscription_user3; @@ -182,6 +197,7 @@ DROP FUNCTION test_fdw_connection(oid, oid, internal); ALTER FOREIGN DATA WRAPPER test_fdw NO CONNECTION; DROP FUNCTION test_fdw_connection(oid, oid, internal); +DROP FUNCTION test_fdw_connection_no_password(oid, oid, internal); DROP FOREIGN DATA WRAPPER test_fdw; From 72207b17daa328d83b1609b4bc5cc4047fe4ba01 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 24 Jul 2026 15:44:56 +0900 Subject: [PATCH 216/481] Fix EXCEPT publication test to check subscriber Commit fd366065e06 added tests intended to verify that rows inserted on the publisher are replicated to the subscriber when using multiple publications, with one excluding the target table via EXCEPT and another including it. However, the tests queried the publisher instead of the subscriber. Since the rows were inserted directly into the publisher, the checks would always succeed, providing no coverage of replication. Fix this by querying the subscriber so the tests verify the replicated state. Author: Fujii Masao Reviewed-by: Ayush Tiwari Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/CAHGQGwGfXUO7f4t6KNGurYwg6QsnLtpP0K3EACbAwYWtxGfKfQ@mail.gmail.com Backpatch-through: 19 --- src/test/subscription/t/037_except.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/subscription/t/037_except.pl b/src/test/subscription/t/037_except.pl index 8c58d282eee..43b51c8ff71 100644 --- a/src/test/subscription/t/037_except.pl +++ b/src/test/subscription/t/037_except.pl @@ -244,7 +244,7 @@ sub test_except_root_partition $node_publisher->wait_for_catchup('tap_sub'); $result = - $node_publisher->safe_psql('postgres', "SELECT * FROM tab1 ORDER BY a"); + $node_subscriber->safe_psql('postgres', "SELECT * FROM tab1 ORDER BY a"); is( $result, qq(1 2), "check replication of a table in the EXCEPT clause of one publication but included by another" @@ -272,7 +272,7 @@ sub test_except_root_partition $node_publisher->wait_for_catchup('tap_sub'); $result = - $node_publisher->safe_psql('postgres', "SELECT * FROM tab1 ORDER BY a"); + $node_subscriber->safe_psql('postgres', "SELECT * FROM tab1 ORDER BY a"); is( $result, qq(1 2), "check replication of a table in the EXCEPT clause of one publication but included by another" From bb6125ca3ac756a44be9ef574e89aa5cff482afb Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Sat, 25 Jul 2026 10:30:30 +0900 Subject: [PATCH 217/481] Avoid reporting permission-denied publisher sequences as missing Previously, if a sequence synchronization batch contained both a sequence that had been dropped on the publisher and another for which the replication role lacked SELECT privilege, the latter was reported twice: once as a permission failure and again as missing on the publisher. This happened because the permission-denied sequence was not marked as found on the publisher. As a result, when another sequence in the batch was genuinely missing, the later missing-sequence check incorrectly classified the permission-denied sequence as missing as well. Fix this by marking the permission-denied sequence as found before reporting the permission failure, so it is not later reported as missing. Reported-by: Noah Misch Author: Vignesh C Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CALDaNm3LsUjW7PahuCsbYAxajSF+S328tw5E9rF0erdh7dKOXw@mail.gmail.com Backpatch-through: 19 --- .../replication/logical/sequencesync.c | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/backend/replication/logical/sequencesync.c b/src/backend/replication/logical/sequencesync.c index 06946afe683..69a1a4c0473 100644 --- a/src/backend/replication/logical/sequencesync.c +++ b/src/backend/replication/logical/sequencesync.c @@ -308,8 +308,24 @@ get_and_validate_seq_info(TupleTableSlot *slot, Relation *sequence_rel, */ datum = slot_getattr(slot, ++col, &isnull); if (isnull) - return remote_has_select_priv ? COPYSEQ_SKIPPED : - COPYSEQ_PUBLISHER_INSUFFICIENT_PERM; + { + /* + * The sequence was dropped concurrently after it was identified in + * the catalog snapshot. Treat it as skipped (and, since it no longer + * exists on the publisher, ultimately missing). + */ + if (remote_has_select_priv) + return COPYSEQ_SKIPPED; + + /* + * The publisher lacks the SELECT privilege required by + * pg_get_sequence_data(). Since has_sequence_privilege() returned + * false, not NULL, do not classify this sequence as missing on the + * publisher. + */ + seqinfo_local->found_on_pub = true; + return COPYSEQ_PUBLISHER_INSUFFICIENT_PERM; + } seqinfo_local->last_value = DatumGetInt64(datum); From 77aeca80249c9e640c811e80633a2e334a9320de Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Sat, 25 Jul 2026 19:09:19 +0900 Subject: [PATCH 218/481] psql: Allow pg_read_all_stats to see database size in \l+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pg_database_size() allows access to users who have either CONNECT privilege on the target database or privileges of the pg_read_all_stats role. However, previously, psql's \l+ checked only for CONNECT, so users with privileges of pg_read_all_stats still saw "No Access" for databases they could not connect to. Fix this by making \l+ also check pg_has_role('pg_read_all_stats', 'USAGE'), matching pg_database_size()'s permission rules. For back branches, emit the pg_read_all_stats check only when connected to PostgreSQL 10 or later, since earlier releases do not have that predefined role. Backpatch to all supported versions. Author: Christoph Berg Reviewed-by: Álvaro Herrera Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/amCo6qRmnfPVk4-V@msg.df7cb.de Backpatch-through: 14 --- doc/src/sgml/ref/psql-ref.sgml | 5 +++-- src/bin/psql/describe.c | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 7c05afd4719..844cd0d5d8b 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -2817,8 +2817,9 @@ SELECT are displayed in expanded mode. If + is appended to the command name, database sizes, default tablespaces, and descriptions are also displayed. - (Size information is only available for databases that the current - user can connect to.) + Size information is available for databases on which the current user has + CONNECT privilege, or if the current user is a superuser + or has privileges of the pg_read_all_stats role. diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index af3935b0078..f258a33a808 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -1007,16 +1007,20 @@ listAllDbs(const char *pattern, bool verbose) appendPQExpBufferStr(&buf, " "); printACLColumn(&buf, "d.datacl"); if (verbose) + { appendPQExpBuffer(&buf, ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n" + " %s" " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n" " ELSE 'No Access'\n" " END as \"%s\"" ",\n t.spcname as \"%s\"" ",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"", + pset.sversion >= 100000 ? "OR pg_catalog.pg_has_role('pg_read_all_stats', 'USAGE')\n" : "", gettext_noop("Size"), gettext_noop("Tablespace"), gettext_noop("Description")); + } appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_database d\n"); if (verbose) From 2aa3c6d1fceecd94b1f605f0c62884cb686e67ed Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Sat, 25 Jul 2026 12:01:34 -0400 Subject: [PATCH 219/481] Fix another empty nbtree index SSI race. Commit f9b7fc65 fixed a race when predicate-locking completely empty btrees: without a buffer lock held, a matching key could be inserted between _bt_search and the PredicateLockRelation call, so the scan would miss concurrently inserted tuples while the writer wouldn't see the reader's predicate lock. That commit only fixed _bt_first's _bt_search path, though. Scans without useful insertion scan keys return early from _bt_first via _bt_endpoint, which still didn't recheck if the relation was empty. To fix, add handling to _bt_endpoint that is analogous to the handling added to _bt_search by commit f9b7fc65. Author: Peter Geoghegan Discussion: https://postgr.es/m/CAH2-WzkNoTn3yXY0iGkSuavJ+sL8EROf+kitW+_2v2tJVWuKmA@mail.gmail.com Backpatch-through: 14 --- src/backend/access/nbtree/nbtsearch.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index aae6acb7f57..dfcdd2d4cec 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -2195,12 +2195,21 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir) if (!BufferIsValid(so->currPos.buf)) { /* - * Empty index. Lock the whole relation, as nothing finer to lock - * exists. + * Empty index. Lock the whole relation using the approach explained + * at the same point in the _bt_first path. */ - PredicateLockRelation(rel, scan->xs_snapshot); - _bt_parallel_done(scan); - return false; + if (IsolationIsSerializable()) + { + PredicateLockRelation(rel, scan->xs_snapshot); + so->currPos.buf = _bt_get_endpoint(rel, 0, + ScanDirectionIsBackward(dir)); + } + + if (!BufferIsValid(so->currPos.buf)) + { + _bt_parallel_done(scan); + return false; + } } page = BufferGetPage(so->currPos.buf); From 603a3335f2b60b2c798da5c627b3bb288b92a7bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Sat, 25 Jul 2026 19:16:42 +0200 Subject: [PATCH 220/481] Add missing PGDLLIMPORT marker Oversight in commit fb23cc7e81db. Reported-by: Anton Voloshin Discussion: https://postgr.es/m/ad5d772e-09d9-4248-97a4-0011afab9e71@postgrespro.ru --- src/include/postmaster/syslogger.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/postmaster/syslogger.h b/src/include/postmaster/syslogger.h index 44409fc2542..0e01db63435 100644 --- a/src/include/postmaster/syslogger.h +++ b/src/include/postmaster/syslogger.h @@ -85,7 +85,7 @@ extern PGDLLIMPORT int syslogPipe[2]; extern PGDLLIMPORT HANDLE syslogPipe[2]; #endif -extern bool syslogger_setup_done; +extern PGDLLIMPORT bool syslogger_setup_done; extern int SysLogger_Start(int child_slot); From 03ec8fc25bbea225c7260a18c702b03d3d38881d Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Sun, 26 Jul 2026 12:49:54 -0400 Subject: [PATCH 221/481] Add _bt_set_startikey row compare test coverage. Add pg_regress tests that exercise the row compare logic that commit 7d9cd2df added to _bt_set_startikey. Also add tests that exercise the _bt_set_startikey SAOP array path. Author: Peter Geoghegan Discussion: https://postgr.es/m/CAH2-Wz=KjQsD2W2a=b51uH905=0mF6Le4evhWkN2FL1+uRPhUg@mail.gmail.com Backpatch-through: 19 --- src/test/regress/expected/btree_index.out | 157 ++++++++++++++++++++++ src/test/regress/sql/btree_index.sql | 85 ++++++++++++ 2 files changed, 242 insertions(+) diff --git a/src/test/regress/expected/btree_index.out b/src/test/regress/expected/btree_index.out index 21dc9b5783a..3a83e9a0534 100644 --- a/src/test/regress/expected/btree_index.out +++ b/src/test/regress/expected/btree_index.out @@ -308,6 +308,163 @@ ORDER BY proname, proargtypes, pronamespace; ---------+-------------+-------------- (0 rows) +-- +-- Test RowCompare handling within _bt_set_startikey, which decides whether +-- every tuple on a page (a page beyond the scan's first) must satisfy the +-- scan's RowCompare qual. +-- +-- The index mixes an ASC column with a DESC column (so RowCompare members +-- don't all use the same inequality strategy and are not marked required), +-- uses a low fillfactor (so scans read several pages), and disables +-- deduplication (so the "b" NULLs span more than one page). +create temp table btree_rowcompare_tab (a int, b int, c int); +insert into btree_rowcompare_tab + select a, b, b from generate_series(1, 3) a, generate_series(1, 150) b; +insert into btree_rowcompare_tab + select 2, null, null from generate_series(1, 50); +create index btree_rowcompare_idx on btree_rowcompare_tab (a, b desc, c) + with (fillfactor = 10, deduplicate_items = off); +vacuum analyze btree_rowcompare_tab; +set enable_seqscan to false; +set enable_bitmapscan to false; +-- RowCompare satisfied by every tuple on many pages (decided by its first +-- member on "a = 3" pages, and by its final member on "a = 2" pages) +explain (costs off) +select count(*) from btree_rowcompare_tab where (a, b) >= (2, 75); + QUERY PLAN +-------------------------------------------------------------------------- + Aggregate + -> Index Only Scan using btree_rowcompare_idx on btree_rowcompare_tab + Index Cond: (ROW(a, b) >= ROW(2, 75)) +(3 rows) + +select count(*) from btree_rowcompare_tab where (a, b) >= (2, 75); + count +------- + 226 +(1 row) + +-- Reaches the RowCompare's unsatisfiable NULL member argument on "a = 2" +-- pages (the "a = 2" key positions the scan within the "a = 2" group, which +-- the RowCompare qual alone would not). The combined quals are +-- contradictory, but preprocessing cannot detect that. +explain (costs off) +select count(*) from btree_rowcompare_tab where a = 2 and (a, b) >= (2, null); + QUERY PLAN +-------------------------------------------------------------------------- + Aggregate + -> Index Only Scan using btree_rowcompare_idx on btree_rowcompare_tab + Index Cond: ((ROW(a, b) >= ROW(2, NULL::integer)) AND (a = 2)) +(3 rows) + +select count(*) from btree_rowcompare_tab where a = 2 and (a, b) >= (2, null); + count +------- + 0 +(1 row) + +-- RowCompare's row omits the index's second column, so on pages whose "b" +-- values change _bt_set_startikey can't prove that every tuple satisfies the +-- RowCompare. +explain (costs off) +select count(*) from btree_rowcompare_tab where (a, c) >= (2, 100); + QUERY PLAN +-------------------------------------------------------------------------- + Aggregate + -> Index Only Scan using btree_rowcompare_idx on btree_rowcompare_tab + Index Cond: (ROW(a, c) >= ROW(2, 100)) +(3 rows) + +select count(*) from btree_rowcompare_tab where (a, c) >= (2, 100); + count +------- + 201 +(1 row) + +-- Variant that uses the remaining inequality strategies +explain (costs off) +select count(*) from btree_rowcompare_tab where (a, b) < (2, 10); + QUERY PLAN +-------------------------------------------------------------------------- + Aggregate + -> Index Only Scan using btree_rowcompare_idx on btree_rowcompare_tab + Index Cond: (ROW(a, b) < ROW(2, 10)) +(3 rows) + +select count(*) from btree_rowcompare_tab where (a, b) < (2, 10); + count +------- + 159 +(1 row) + +drop table btree_rowcompare_tab; +-- +-- Test SAOP array handling within _bt_set_startikey +-- +create temp table btree_saop_tab (a int, b int, c int); +insert into btree_saop_tab + select a, b, b from generate_series(1, 3) a, generate_series(1, 150) b; +insert into btree_saop_tab + select 2, 0, 7 from generate_series(1, 60); +create index btree_saop_idx on btree_saop_tab (a, b desc, c) + with (fillfactor = 10, deduplicate_items = off); +vacuum analyze btree_saop_tab; +-- SAOP on the leading column: pages beyond each primitive scan's first page +-- have a single "a" value that a binary search finds in the array, so the +-- scan starts past the SAOP key (forcing the nonrequired key protocol) +explain (costs off) +select count(*) from btree_saop_tab where a in (1, 3) and b >= 100; + QUERY PLAN +--------------------------------------------------------------------- + Aggregate + -> Index Only Scan using btree_saop_idx on btree_saop_tab + Index Cond: ((a = ANY ('{1,3}'::integer[])) AND (b >= 100)) +(3 rows) + +select count(*) from btree_saop_tab where a in (1, 3) and b >= 100; + count +------- + 102 +(1 row) + +-- Skip array on "b" precedes the "c" SAOP; pages whose "b" values change +-- prevent starting past the "c" SAOP key +explain (costs off) +select count(*) from btree_saop_tab where a = 2 and c in (101, 105); + QUERY PLAN +---------------------------------------------------------------------- + Aggregate + -> Index Only Scan using btree_saop_idx on btree_saop_tab + Index Cond: ((a = 2) AND (c = ANY ('{101,105}'::integer[]))) +(3 rows) + +select count(*) from btree_saop_tab where a = 2 and c in (101, 105); + count +------- + 2 +(1 row) + +-- "c" SAOP follows the "b" inequality; on pages that lie wholly within the +-- duplicate "(2, 0, 7)" run, the scan starts past all of its scan keys, +-- including the SAOP key +explain (costs off) +select count(*) from btree_saop_tab where a = 2 and b < 1 and c in (6, 7); + QUERY PLAN +------------------------------------------------------------------------------ + Aggregate + -> Index Only Scan using btree_saop_idx on btree_saop_tab + Index Cond: ((a = 2) AND (b < 1) AND (c = ANY ('{6,7}'::integer[]))) +(3 rows) + +select count(*) from btree_saop_tab where a = 2 and b < 1 and c in (6, 7); + count +------- + 60 +(1 row) + +reset enable_seqscan; +reset enable_bitmapscan; +drop table btree_saop_tab; -- -- Performs a recheck of > key following array advancement on previous (left -- sibling) page that used a high key whose attribute value corresponding to diff --git a/src/test/regress/sql/btree_index.sql b/src/test/regress/sql/btree_index.sql index 6aaaa386abc..a08bb101c20 100644 --- a/src/test/regress/sql/btree_index.sql +++ b/src/test/regress/sql/btree_index.sql @@ -216,6 +216,91 @@ SELECT proname, proargtypes, pronamespace AND pronamespace IN (1, 2, 3) AND proargtypes IN ('26 23', '5077') ORDER BY proname, proargtypes, pronamespace; +-- +-- Test RowCompare handling within _bt_set_startikey, which decides whether +-- every tuple on a page (a page beyond the scan's first) must satisfy the +-- scan's RowCompare qual. +-- +-- The index mixes an ASC column with a DESC column (so RowCompare members +-- don't all use the same inequality strategy and are not marked required), +-- uses a low fillfactor (so scans read several pages), and disables +-- deduplication (so the "b" NULLs span more than one page). +create temp table btree_rowcompare_tab (a int, b int, c int); +insert into btree_rowcompare_tab + select a, b, b from generate_series(1, 3) a, generate_series(1, 150) b; +insert into btree_rowcompare_tab + select 2, null, null from generate_series(1, 50); +create index btree_rowcompare_idx on btree_rowcompare_tab (a, b desc, c) + with (fillfactor = 10, deduplicate_items = off); +vacuum analyze btree_rowcompare_tab; + +set enable_seqscan to false; +set enable_bitmapscan to false; + +-- RowCompare satisfied by every tuple on many pages (decided by its first +-- member on "a = 3" pages, and by its final member on "a = 2" pages) +explain (costs off) +select count(*) from btree_rowcompare_tab where (a, b) >= (2, 75); +select count(*) from btree_rowcompare_tab where (a, b) >= (2, 75); + +-- Reaches the RowCompare's unsatisfiable NULL member argument on "a = 2" +-- pages (the "a = 2" key positions the scan within the "a = 2" group, which +-- the RowCompare qual alone would not). The combined quals are +-- contradictory, but preprocessing cannot detect that. +explain (costs off) +select count(*) from btree_rowcompare_tab where a = 2 and (a, b) >= (2, null); +select count(*) from btree_rowcompare_tab where a = 2 and (a, b) >= (2, null); + +-- RowCompare's row omits the index's second column, so on pages whose "b" +-- values change _bt_set_startikey can't prove that every tuple satisfies the +-- RowCompare. +explain (costs off) +select count(*) from btree_rowcompare_tab where (a, c) >= (2, 100); +select count(*) from btree_rowcompare_tab where (a, c) >= (2, 100); + +-- Variant that uses the remaining inequality strategies +explain (costs off) +select count(*) from btree_rowcompare_tab where (a, b) < (2, 10); +select count(*) from btree_rowcompare_tab where (a, b) < (2, 10); + +drop table btree_rowcompare_tab; + +-- +-- Test SAOP array handling within _bt_set_startikey +-- +create temp table btree_saop_tab (a int, b int, c int); +insert into btree_saop_tab + select a, b, b from generate_series(1, 3) a, generate_series(1, 150) b; +insert into btree_saop_tab + select 2, 0, 7 from generate_series(1, 60); +create index btree_saop_idx on btree_saop_tab (a, b desc, c) + with (fillfactor = 10, deduplicate_items = off); +vacuum analyze btree_saop_tab; + +-- SAOP on the leading column: pages beyond each primitive scan's first page +-- have a single "a" value that a binary search finds in the array, so the +-- scan starts past the SAOP key (forcing the nonrequired key protocol) +explain (costs off) +select count(*) from btree_saop_tab where a in (1, 3) and b >= 100; +select count(*) from btree_saop_tab where a in (1, 3) and b >= 100; + +-- Skip array on "b" precedes the "c" SAOP; pages whose "b" values change +-- prevent starting past the "c" SAOP key +explain (costs off) +select count(*) from btree_saop_tab where a = 2 and c in (101, 105); +select count(*) from btree_saop_tab where a = 2 and c in (101, 105); + +-- "c" SAOP follows the "b" inequality; on pages that lie wholly within the +-- duplicate "(2, 0, 7)" run, the scan starts past all of its scan keys, +-- including the SAOP key +explain (costs off) +select count(*) from btree_saop_tab where a = 2 and b < 1 and c in (6, 7); +select count(*) from btree_saop_tab where a = 2 and b < 1 and c in (6, 7); + +reset enable_seqscan; +reset enable_bitmapscan; +drop table btree_saop_tab; + -- -- Performs a recheck of > key following array advancement on previous (left -- sibling) page that used a high key whose attribute value corresponding to From aa50f4f02920101b84466668bd3b90c156dcda89 Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Mon, 27 Jul 2026 10:21:18 +0900 Subject: [PATCH 222/481] Fix deparsing of JSON_ARRAY(subquery) with a FORMAT clause Commit 8d829f5a0 introduced the JSCTOR_JSON_ARRAY_QUERY constructor type so that ruleutils.c could deparse JSON_ARRAY(subquery) using its original syntax, storing the transformed subquery in a new orig_query field. However, the input FORMAT clause of JSON_ARRAY(subquery FORMAT ...) was not preserved for deparsing. The format was recorded only in the executable expression kept in the func field, which ruleutils.c does not inspect, so it is silently dropped. This is more than cosmetic, because FORMAT JSON changes the result: without it a text value is treated as a string to be quoted, while with it the value is treated as already-formatted JSON. To fix, record the input FORMAT in a new deparse-only field of JsonConstructorExpr, alongside orig_query, and emit it in ruleutils.c. Bump catalog version. Author: Chao Li Reviewed-by: Ewan Young Reviewed-by: Richard Guo Discussion: https://postgr.es/m/4C89B193-7D54-4705-9CF9-F0D484B9E099@gmail.com Backpatch-through: 19 --- src/backend/parser/parse_expr.c | 3 +++ src/backend/utils/adt/ruleutils.c | 1 + src/include/catalog/catversion.h | 2 +- src/include/nodes/primnodes.h | 5 +++++ src/test/regress/expected/sqljson.out | 7 +++++++ src/test/regress/sql/sqljson.sql | 8 ++++++++ 6 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index e6ea34a7809..30c889f505f 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -3808,6 +3808,8 @@ transformJsonObjectConstructor(ParseState *pstate, JsonObjectConstructor *ctor) * - orig_query: the transformed Query of the user's original subquery, so * that ruleutils.c can deparse the original JSON_ARRAY(SELECT ...) syntax * for view definitions. + * + * - format: the input FORMAT clause, so that ruleutils.c can deparse it. */ static Node * transformJsonArrayQueryConstructor(ParseState *pstate, @@ -3944,6 +3946,7 @@ transformJsonArrayQueryConstructor(ParseState *pstate, false, ctor->absent_on_null, ctor->location); ((JsonConstructorExpr *) result)->orig_query = (Node *) query; + ((JsonConstructorExpr *) result)->format = ctor->format; return result; } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index c6555948df8..e0fc194b953 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -12291,6 +12291,7 @@ get_json_constructor(JsonConstructorExpr *ctor, deparse_context *context, context->prettyFlags, context->wrapColumn, context->indentLevel); + get_json_format(ctor->format, buf); get_json_constructor_options(ctor, buf); appendStringInfoChar(buf, ')'); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index d0399cc1cbe..83d462f4d4a 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202607201 +#define CATALOG_VERSION_NO 202607271 #endif diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index bb05aeebee4..775437e4426 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -1718,6 +1718,10 @@ typedef enum JsonConstructorType * orig_query holds the user's original subquery for JSON_ARRAY(query), used * only by ruleutils.c for deparsing; it is not walked because func is * authoritative for all other purposes. + * + * format likewise holds the input FORMAT clause of JSON_ARRAY(query), which + * is otherwise only represented inside func; it is used only by ruleutils.c + * for deparsing. */ typedef struct JsonConstructorExpr { @@ -1728,6 +1732,7 @@ typedef struct JsonConstructorExpr Expr *coercion; /* coercion to RETURNING type */ JsonReturning *returning; /* RETURNING clause */ Node *orig_query; /* original subquery for deparsing */ + JsonFormat *format; /* input FORMAT for JSON_ARRAY(query) */ bool absent_on_null; /* ABSENT ON NULL? */ bool unique; /* WITH UNIQUE KEYS? (JSON_OBJECT[AGG] only) */ ParseLoc location; diff --git a/src/test/regress/expected/sqljson.out b/src/test/regress/expected/sqljson.out index 091a0b98574..d72278d67ca 100644 --- a/src/test/regress/expected/sqljson.out +++ b/src/test/regress/expected/sqljson.out @@ -1233,6 +1233,13 @@ CREATE OR REPLACE VIEW public.json_array_subquery_view AS SELECT JSON_ARRAY( SELECT foo.i FROM ( VALUES (1), (2), (NULL::integer), (4)) foo(i) RETURNING text) AS "json_array" DROP VIEW json_array_subquery_view; +-- JSON_ARRAY(subquery) with an input FORMAT clause +CREATE VIEW json_array_subquery_view AS +SELECT JSON_ARRAY(SELECT '{"a": 1}'::text FORMAT JSON); +\sv json_array_subquery_view +CREATE OR REPLACE VIEW public.json_array_subquery_view AS + SELECT JSON_ARRAY( SELECT '{"a": 1}'::text AS text FORMAT JSON RETURNING json) AS "json_array" +DROP VIEW json_array_subquery_view; -- Test mutability of JSON_OBJECTAGG, JSON_ARRAYAGG, JSON_ARRAY, JSON_OBJECT create type comp1 as (a int, b date); create domain d_comp1 as comp1; diff --git a/src/test/regress/sql/sqljson.sql b/src/test/regress/sql/sqljson.sql index 2550da15c45..96217a55935 100644 --- a/src/test/regress/sql/sqljson.sql +++ b/src/test/regress/sql/sqljson.sql @@ -443,6 +443,14 @@ SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i) RETURNING DROP VIEW json_array_subquery_view; +-- JSON_ARRAY(subquery) with an input FORMAT clause +CREATE VIEW json_array_subquery_view AS +SELECT JSON_ARRAY(SELECT '{"a": 1}'::text FORMAT JSON); + +\sv json_array_subquery_view + +DROP VIEW json_array_subquery_view; + -- Test mutability of JSON_OBJECTAGG, JSON_ARRAYAGG, JSON_ARRAY, JSON_OBJECT create type comp1 as (a int, b date); create domain d_comp1 as comp1; From d2768065a979ffad11e2ee650b9fa9fd95168a8b Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Mon, 27 Jul 2026 09:04:31 +0530 Subject: [PATCH 223/481] Fix issues in logical replication sequence synchronization. 1. Stop a running sequence synchronization worker when ALTER SUBSCRIPTION ... DISABLE is executed. The worker did not reread its subscription after starting a transaction, so it kept running with a stale copy and missed the disable. It now calls maybe_reread_subscription() after StartTransactionCommand(), matching the apply worker. 2. Restore the invariant that publisher-side synchronization slots are dropped last during ALTER SUBSCRIPTION ... REFRESH PUBLICATION. The slot-drop loop now runs after the sequence-removal loop, so the non-transactional slot drops happen only after all catalog changes that could still be rolled back on error. 3. Restore psql tab completion for ALTER SUBSCRIPTION ... REFRESH PUBLICATION WITH (. 4. Make pg_stat_subscription report NULL for the fields that do not apply to a sequence synchronization worker, which does not stream from a walsender, and update the documentation accordingly. 5. Update the pg_subscription_rel.srsublsn catalog documentation to describe its semantics for sequence rows. Reported-by: Noah Misch Author: vignesh C Reviewed-by: Hayato Kuroda Reviewed-by: Amit Kapila Backpatch-through: 19, where it was introduced Discussion: https://postgr.es/m/20260710045217.f0.noahmisch@microsoft.com --- doc/src/sgml/catalogs.sgml | 6 +- doc/src/sgml/monitoring.sgml | 19 ++++--- src/backend/commands/subscriptioncmds.c | 56 +++++++++---------- .../replication/logical/sequencesync.c | 2 + src/backend/replication/logical/worker.c | 14 ++++- src/bin/psql/tab-complete.in.c | 3 + 6 files changed, 61 insertions(+), 39 deletions(-) diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 4b474c13917..6066c4784f4 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -8893,7 +8893,11 @@ SCRAM-SHA-256$<iteration count>:&l Remote LSN of the state change used for synchronization coordination when in s or r states, - otherwise null + otherwise null. For sequences, this instead holds the publisher + sequence's page LSN as of the last synchronization, which does not + track replication progress the way it does for tables; see + for how it is used to detect + out-of-sync sequences. diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 1d8094c55d4..2d0ebd6f27d 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -2318,8 +2318,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage Process ID of the leader apply worker if this process is a parallel - apply worker; NULL if this process is a leader apply worker or a table - synchronization worker + apply worker; NULL if this process is a leader apply worker, a table + synchronization worker or a sequence synchronization worker @@ -2329,7 +2329,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage OID of the relation that the worker is synchronizing; NULL for the - leader apply worker and parallel apply workers + leader apply worker, parallel apply workers and the sequence + synchronization worker @@ -2339,7 +2340,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage Last write-ahead log location received, the initial value of - this field being 0; NULL for parallel apply workers + this field being 0; NULL for parallel apply workers and the sequence + synchronization worker @@ -2349,7 +2351,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage Send time of last message received from origin WAL sender; NULL for - parallel apply workers + parallel apply workers and the sequence synchronization worker @@ -2359,7 +2361,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage Receipt time of last message received from origin WAL sender; NULL for - parallel apply workers + parallel apply workers and the sequence synchronization worker @@ -2369,7 +2371,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage Last write-ahead log location reported to origin WAL sender; NULL for - parallel apply workers + parallel apply workers and the sequence synchronization worker @@ -2379,7 +2381,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage Time of last write-ahead log location reported to origin WAL - sender; NULL for parallel apply workers + sender; NULL for parallel apply workers and the sequence synchronization + worker diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index c05f7c5de4c..5eca5a5bb4a 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -1229,34 +1229,6 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data, } } - /* - * Drop the tablesync slots associated with removed tables. This has - * to be at the end because otherwise if there is an error while doing - * the database operations we won't be able to rollback dropped slots. - */ - foreach_ptr(SubRemoveRels, sub_remove_rel, sub_remove_rels) - { - if (sub_remove_rel->state != SUBREL_STATE_READY && - sub_remove_rel->state != SUBREL_STATE_SYNCDONE) - { - char syncslotname[NAMEDATALEN] = {0}; - - /* - * For READY/SYNCDONE states we know the tablesync slot has - * already been dropped by the tablesync worker. - * - * For other states, there is no certainty, maybe the slot - * does not exist yet. Also, if we fail after removing some of - * the slots, next time, it will again try to drop already - * dropped slots and fail. For these reasons, we allow - * missing_ok = true for the drop. - */ - ReplicationSlotNameForTablesync(sub->oid, sub_remove_rel->relid, - syncslotname, sizeof(syncslotname)); - ReplicationSlotDropAtPubNode(wrconn, syncslotname, true); - } - } - /* * Next remove state for sequences we should not care about anymore * using the data we collected above @@ -1284,6 +1256,34 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data, sub->name)); } } + + /* + * Drop the tablesync slots associated with removed tables. This has + * to be at the end because otherwise if there is an error while doing + * the database operations we won't be able to rollback dropped slots. + */ + foreach_ptr(SubRemoveRels, sub_remove_rel, sub_remove_rels) + { + if (sub_remove_rel->state != SUBREL_STATE_READY && + sub_remove_rel->state != SUBREL_STATE_SYNCDONE) + { + char syncslotname[NAMEDATALEN] = {0}; + + /* + * For READY/SYNCDONE states we know the tablesync slot has + * already been dropped by the tablesync worker. + * + * For other states, there is no certainty, maybe the slot + * does not exist yet. Also, if we fail after removing some of + * the slots, next time, it will again try to drop already + * dropped slots and fail. For these reasons, we allow + * missing_ok = true for the drop. + */ + ReplicationSlotNameForTablesync(sub->oid, sub_remove_rel->relid, + syncslotname, sizeof(syncslotname)); + ReplicationSlotDropAtPubNode(wrconn, syncslotname, true); + } + } } PG_FINALLY(); { diff --git a/src/backend/replication/logical/sequencesync.c b/src/backend/replication/logical/sequencesync.c index 69a1a4c0473..40f0f1c6973 100644 --- a/src/backend/replication/logical/sequencesync.c +++ b/src/backend/replication/logical/sequencesync.c @@ -495,6 +495,7 @@ copy_sequences(WalReceiverConn *conn) TupleTableSlot *slot; StartTransactionCommand(); + maybe_reread_subscription(); for (int idx = cur_batch_base_index; idx < n_seqinfos; idx++) { @@ -724,6 +725,7 @@ LogicalRepSyncSequences(void) StringInfoData app_name; StartTransactionCommand(); + maybe_reread_subscription(); rel = table_open(SubscriptionRelRelationId, AccessShareLock); diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index 7799266c614..dba4d743cf5 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -5977,8 +5977,18 @@ SetupApplyOrSyncWorker(int worker_slot) */ /* Initialise stats to a sanish value */ - MyLogicalRepWorker->last_send_time = MyLogicalRepWorker->last_recv_time = - MyLogicalRepWorker->reply_time = GetCurrentTimestamp(); + if (am_sequencesync_worker()) + { + MyLogicalRepWorker->last_send_time = + MyLogicalRepWorker->last_recv_time = + MyLogicalRepWorker->reply_time = 0; + } + else + { + MyLogicalRepWorker->last_send_time = + MyLogicalRepWorker->last_recv_time = + MyLogicalRepWorker->reply_time = GetCurrentTimestamp(); + } /* Load the libpq-specific functions */ load_file("libpqwalreceiver", false); diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index 6207c91d482..745eb3d004c 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -2368,6 +2368,9 @@ match_previous_words(int pattern_id, /* ALTER SUBSCRIPTION REFRESH */ else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "REFRESH")) COMPLETE_WITH("PUBLICATION", "SEQUENCES"); + /* ALTER SUBSCRIPTION REFRESH PUBLICATION */ + else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "REFRESH", "PUBLICATION")) + COMPLETE_WITH("WITH ("); /* ALTER SUBSCRIPTION REFRESH PUBLICATION WITH ( */ else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, MatchAnyN, "REFRESH", "PUBLICATION", "WITH", "(")) COMPLETE_WITH("copy_data"); From 31974f64f029a29a6d7eeeb3f870030beee2066f Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 27 Jul 2026 15:29:51 +0300 Subject: [PATCH 224/481] pg_resetwal: do not allow zero next multixact offset Offset 0 is the "invalid" marker in pg_multixact/offsets since offsets went 64-bit and the allocator stopped skipping it. pg_resetwal could still produce it via -O 0 or guessed control values, breaking the first multixact created after the reset ("MultiXact n has invalid offset", and vacuum of the affected table fails from then on). Reject -O 0 like -m and -o already do, and guess 1 like initdb does. Author: Zsolt Parragi Discussion: https://www.postgresql.org/message-id/CAN4CZFNoO6MUkg526TmA=mC_RjY2gp4VKCnvK6y12v3ppOkhJA@mail.gmail.com Backpatch-through: 19 --- src/bin/pg_resetwal/pg_resetwal.c | 6 +++++- src/bin/pg_resetwal/t/001_basic.pl | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index f8d25afed9d..884a6eac547 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -303,6 +303,10 @@ main(int argc, char *argv[]) pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1); } + + /* offset 0 means "invalid" in pg_multixact/offsets */ + if (next_mxoff_val == 0) + pg_fatal("next multitransaction offset (-O) must not be 0"); next_mxoff_given = true; break; @@ -700,7 +704,7 @@ GuessControlValues(void) FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId); ControlFile.checkPointCopy.nextOid = FirstGenbkiObjectId; ControlFile.checkPointCopy.nextMulti = FirstMultiXactId; - ControlFile.checkPointCopy.nextMultiOffset = 0; + ControlFile.checkPointCopy.nextMultiOffset = 1; ControlFile.checkPointCopy.oldestXid = FirstNormalTransactionId; ControlFile.checkPointCopy.oldestXidDB = InvalidOid; ControlFile.checkPointCopy.oldestMulti = FirstMultiXactId; diff --git a/src/bin/pg_resetwal/t/001_basic.pl b/src/bin/pg_resetwal/t/001_basic.pl index d686584eb96..cff0b6423f3 100644 --- a/src/bin/pg_resetwal/t/001_basic.pl +++ b/src/bin/pg_resetwal/t/001_basic.pl @@ -145,6 +145,10 @@ [ 'pg_resetwal', '-O' => '-1', $node->data_dir ], qr/error: invalid argument for option -O/, 'fails with -O value -1'); +command_fails_like( + [ 'pg_resetwal', '-O' => '0', $node->data_dir ], + qr/must not be 0/, + 'fails with -O value 0'); # --wal-segsize command_fails_like( [ 'pg_resetwal', '--wal-segsize' => 'foo', $node->data_dir ], From 2a9541ddfd3a5b069c505e36a91f289126871a21 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 27 Jul 2026 09:37:04 -0400 Subject: [PATCH 225/481] Deparse FOR PORTION OF using the range column's current name. Commit 8e72d914c recorded the range column's name in ForPortionOfExpr and used that for deparsing FOR PORTION OF. This gives the wrong answer if the ForPortionOfExpr is saved in a rule or SQL function and then the column gets renamed. Drop the ForPortionOfExpr.range_name field; instead fetch the current column name from the catalogs when needed. Also drop ForPortionOfState.fp_rangeName, which wasn't being used anywhere. Full disclosure: an earlier draft of this patch was made with Claude Opus 4.8. Reported-by: John Naylor Author: Tom Lane Reviewed-by: Richard Guo Reviewed-by: Chao Li Discussion: https://postgr.es/m/CANWCAZYFEpJ5Oi45gi4q9Y6LYa4_oiAXxuNNWe-1ym-i0fF8Pw@mail.gmail.com Backpatch-through: 19 --- src/backend/executor/nodeModifyTable.c | 2 -- src/backend/optimizer/plan/planner.c | 4 ++- src/backend/parser/analyze.c | 1 - src/backend/utils/adt/ruleutils.c | 15 ++++++--- src/include/catalog/catversion.h | 2 +- src/include/nodes/execnodes.h | 1 - src/include/nodes/primnodes.h | 1 - src/test/regress/expected/for_portion_of.out | 33 ++++++++++++++++++++ src/test/regress/sql/for_portion_of.sql | 16 ++++++++++ 9 files changed, 64 insertions(+), 11 deletions(-) diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index b9781eb3b95..1dbf0ffff9e 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -5641,7 +5641,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) /* Create state for FOR PORTION OF operation */ fpoState = makeNode(ForPortionOfState); - fpoState->fp_rangeName = forPortionOf->range_name; fpoState->fp_rangeType = forPortionOf->rangeType; fpoState->fp_rangeAttno = forPortionOf->rangeVar->varattno; fpoState->fp_targetRange = targetRange; @@ -5928,7 +5927,6 @@ ExecInitForPortionOf(ModifyTableState *mtstate, EState *estate, leafState = makeNode(ForPortionOfState); - leafState->fp_rangeName = fpoState->fp_rangeName; leafState->fp_rangeType = fpoState->fp_rangeType; leafState->fp_targetRange = fpoState->fp_targetRange; map = ExecGetChildToRootMap(resultRelInfo); diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 3225185d16f..a0ff9159ae0 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -871,7 +871,9 @@ subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot use generated column \"%s\" in FOR PORTION OF", - forPortionOf->range_name))); + get_attname(rte->relid, + forPortionOf->rangeVar->varattno, + false)))); } /* diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 562e4facd74..581457c69c9 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -1606,7 +1606,6 @@ transformForPortionOfClause(ParseState *pstate, else result->rangeTargetList = NIL; - result->range_name = forPortionOf->range_name; result->location = forPortionOf->location; result->targetLocation = forPortionOf->target_location; diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e0fc194b953..24bf1fbbc21 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -527,6 +527,7 @@ static void get_rte_alias(RangeTblEntry *rte, int varno, bool use_as, static void get_column_alias_list(deparse_columns *colinfo, deparse_context *context); static void get_for_portion_of(ForPortionOfExpr *forPortionOf, + RangeTblEntry *rte, deparse_context *context); static void get_from_clause_coldeflist(RangeTblFunction *rtfunc, deparse_columns *colinfo, @@ -7556,7 +7557,7 @@ get_update_query_def(Query *query, deparse_context *context) generate_relation_name(rte->relid, NIL)); /* Print the FOR PORTION OF, if needed */ - get_for_portion_of(query->forPortionOf, context); + get_for_portion_of(query->forPortionOf, rte, context); /* Print the relation alias, if needed */ get_rte_alias(rte, query->resultRelation, false, context); @@ -7763,7 +7764,7 @@ get_delete_query_def(Query *query, deparse_context *context) generate_relation_name(rte->relid, NIL)); /* Print the FOR PORTION OF, if needed */ - get_for_portion_of(query->forPortionOf, context); + get_for_portion_of(query->forPortionOf, rte, context); /* Print the relation alias, if needed */ get_rte_alias(rte, query->resultRelation, false, context); @@ -13383,12 +13384,18 @@ get_rte_alias(RangeTblEntry *rte, int varno, bool use_as, * alias and SET will be on their own line with a leading space. */ static void -get_for_portion_of(ForPortionOfExpr *forPortionOf, deparse_context *context) +get_for_portion_of(ForPortionOfExpr *forPortionOf, RangeTblEntry *rte, + deparse_context *context) { if (forPortionOf) { + char *range_name; + + range_name = get_attname(rte->relid, + forPortionOf->rangeVar->varattno, + false); appendStringInfo(context->buf, " FOR PORTION OF %s", - quote_identifier(forPortionOf->range_name)); + quote_identifier(range_name)); /* * Try to write it as FROM ... TO ... if we received it that way, diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 83d462f4d4a..80c2070f358 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202607271 +#define CATALOG_VERSION_NO 202607272 #endif diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index e64fd8c7ea3..e95ac3eda35 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -476,7 +476,6 @@ typedef struct ForPortionOfState { NodeTag type; - char *fp_rangeName; /* the column named in FOR PORTION OF */ Oid fp_rangeType; /* the base type (not domain) of the FOR * PORTION OF expression */ int fp_rangeAttno; /* the attno of the range column */ diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 775437e4426..0b27c96c7a8 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -2436,7 +2436,6 @@ typedef struct ForPortionOfExpr { NodeTag type; Var *rangeVar; /* Range column */ - char *range_name; /* Range name */ Node *targetFrom; /* FOR PORTION OF FROM bound, if given */ Node *targetTo; /* FOR PORTION OF TO bound, if given */ Node *targetRange; /* FOR PORTION OF bounds as a range/multirange */ diff --git a/src/test/regress/expected/for_portion_of.out b/src/test/regress/expected/for_portion_of.out index 0e217f104ef..3c592f90e70 100644 --- a/src/test/regress/expected/for_portion_of.out +++ b/src/test/regress/expected/for_portion_of.out @@ -2255,6 +2255,39 @@ SELECT * FROM fpo_rule ORDER BY f1; (2 rows) DROP TABLE fpo_rule; +-- Deparsing FOR PORTION OF must use the range column's current name, +-- not the name it had when the rule was created. +CREATE TABLE fpo_rename (f1 bigint, f2 int4range); +CREATE TABLE fpo_rename_src (x int); +CREATE RULE fpo_rename_rule1 AS ON UPDATE TO fpo_rename_src + DO INSTEAD UPDATE fpo_rename FOR PORTION OF f2 FROM 3 TO 6 SET f1 = 2; +CREATE RULE fpo_rename_rule2 AS ON DELETE TO fpo_rename_src + DO INSTEAD DELETE FROM fpo_rename FOR PORTION OF f2 (int4range(3, 6)); +\d+ fpo_rename_src + Table "public.fpo_rename_src" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + x | integer | | | | plain | | +Rules: + fpo_rename_rule1 AS + ON UPDATE TO fpo_rename_src DO INSTEAD UPDATE fpo_rename FOR PORTION OF f2 FROM 3 TO 6 SET f1 = 2 + fpo_rename_rule2 AS + ON DELETE TO fpo_rename_src DO INSTEAD DELETE FROM fpo_rename FOR PORTION OF f2 (int4range(3, 6)) + +ALTER TABLE fpo_rename RENAME COLUMN f1 TO ff1; +ALTER TABLE fpo_rename RENAME COLUMN f2 TO ff2; +\d+ fpo_rename_src + Table "public.fpo_rename_src" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + x | integer | | | | plain | | +Rules: + fpo_rename_rule1 AS + ON UPDATE TO fpo_rename_src DO INSTEAD UPDATE fpo_rename FOR PORTION OF ff2 FROM 3 TO 6 SET ff1 = 2 + fpo_rename_rule2 AS + ON DELETE TO fpo_rename_src DO INSTEAD DELETE FROM fpo_rename FOR PORTION OF ff2 (int4range(3, 6)) + +DROP TABLE fpo_rename, fpo_rename_src; -- UPDATE/DELETE FOR PORTION OF on a GENERATED VIRTUAL range column: CREATE TABLE fpo_gen_virtual ( a int, diff --git a/src/test/regress/sql/for_portion_of.sql b/src/test/regress/sql/for_portion_of.sql index a8d29a76b22..5f7b04fdf6b 100644 --- a/src/test/regress/sql/for_portion_of.sql +++ b/src/test/regress/sql/for_portion_of.sql @@ -1495,6 +1495,22 @@ SELECT * FROM fpo_rule ORDER BY f1; DROP TABLE fpo_rule; +-- Deparsing FOR PORTION OF must use the range column's current name, +-- not the name it had when the rule was created. +CREATE TABLE fpo_rename (f1 bigint, f2 int4range); +CREATE TABLE fpo_rename_src (x int); +CREATE RULE fpo_rename_rule1 AS ON UPDATE TO fpo_rename_src + DO INSTEAD UPDATE fpo_rename FOR PORTION OF f2 FROM 3 TO 6 SET f1 = 2; +CREATE RULE fpo_rename_rule2 AS ON DELETE TO fpo_rename_src + DO INSTEAD DELETE FROM fpo_rename FOR PORTION OF f2 (int4range(3, 6)); + +\d+ fpo_rename_src +ALTER TABLE fpo_rename RENAME COLUMN f1 TO ff1; +ALTER TABLE fpo_rename RENAME COLUMN f2 TO ff2; +\d+ fpo_rename_src + +DROP TABLE fpo_rename, fpo_rename_src; + -- UPDATE/DELETE FOR PORTION OF on a GENERATED VIRTUAL range column: CREATE TABLE fpo_gen_virtual ( a int, From 99e47536bbf1a165f5dc8d504f928821ebc8df6a Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Mon, 27 Jul 2026 09:10:48 -0700 Subject: [PATCH 226/481] Fix race condition when enabling logical decoding concurrently. With wal_level = 'replica', logical decoding is enabled on demand when the first logical replication slot is created: When enabling logical decoding, EnableLogicalDecoding() flips the shared logical_decoding_enabled flag and writes an XLOG_LOGICAL_DECODING_STATUS_CHANGE record so that standbys follow the status change. The initial "already enabled?" check and the WAL record write happen under two separate acquisitions of LogicalDecodingControlLock, since the lock must be released while waiting for the ProcSignalBarrier: processes absorbing the barrier acquire the same lock in shared mode. Consequently, if two backends concurrently created the first logical slots, both could pass the initial check and both write a status-change record. The redundant record lands after the decoding start point already reserved by the other backend's slot, so decoding that slot processes the record and fails with "unexpected logical decoding status change", as xlog_decode() assumes that no such record can appear within the WAL range any slot decodes. Fix by re-checking the status after re-acquiring the lock, so that only the backend that actually performs the disabled->enabled transition writes the WAL record. Reported-by: Srinath Reddy Sadipiralla Author: Srinath Reddy Sadipiralla Reviewed-by: Masahiko Sawada Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/CAFC+b6oYzmAgp7F0ivrhfZT46-CjvCTrU9pWuMNcem-52YjOTw@mail.gmail.com Backpatch-through: 19 --- src/backend/replication/logical/logicalctl.c | 11 ++++ .../recovery/t/051_effective_wal_level.pl | 61 ++++++++++++++++++- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/backend/replication/logical/logicalctl.c b/src/backend/replication/logical/logicalctl.c index 624965ef95d..4a690a631da 100644 --- a/src/backend/replication/logical/logicalctl.c +++ b/src/backend/replication/logical/logicalctl.c @@ -384,6 +384,17 @@ EnableLogicalDecoding(void) LWLockAcquire(LogicalDecodingControlLock, LW_EXCLUSIVE); + /* + * Re-check whether logical decoding got enabled while we waited for the + * barrier above. + */ + if (LogicalDecodingCtl->logical_decoding_enabled) + { + LogicalDecodingCtl->pending_disable = false; + LWLockRelease(LogicalDecodingControlLock); + return; + } + START_CRIT_SECTION(); /* diff --git a/src/test/recovery/t/051_effective_wal_level.pl b/src/test/recovery/t/051_effective_wal_level.pl index d4bc7f0aa40..2cf2ea6546d 100644 --- a/src/test/recovery/t/051_effective_wal_level.pl +++ b/src/test/recovery/t/051_effective_wal_level.pl @@ -326,11 +326,12 @@ sub wait_for_logical_decoding_disabled $standby3->stop; -# Test the race condition at end of the recovery between the startup and logical -# decoding status change. This test requires injection points enabled. if ( $ENV{enable_injection_points} eq 'yes' && $primary->check_extension('injection_points')) { + # Test the race condition at end of the recovery between the startup and logical + # decoding status change. This test requires injection points enabled. + # Initialize standby4 and start it. my $standby4 = PostgreSQL::Test::Cluster->new('standby4'); $standby4->init_from_backup($primary, 'my_backup', has_streaming => 1); @@ -381,9 +382,63 @@ sub wait_for_logical_decoding_disabled test_wal_level($primary, "replica|replica", "effective_wal_level got decreased to 'replica' on primary"); + # Test that concurrent activations don't write redundant status-change records. + + # Start a psql session and stop it in the middle of the activation process. + my $psql_create_slot = $primary->background_psql('postgres'); + $psql_create_slot->query_until( + qr/create_slot_1/, + q(\echo create_slot_1 +select injection_points_set_local(); +select injection_points_attach('logical-decoding-activation', 'wait'); +select pg_create_logical_replication_slot('slot_1', 'test_decoding'); +)); + $primary->wait_for_event('client backend', 'logical-decoding-activation'); + note("injection_point 'logical-decoding-activation' is reached"); + + # A second backend concurrently enables logical decoding and finishes creating + # its slot, writing the status-change record. The slot reserves its decoding + # start point after its own status-change record. + $primary->safe_psql('postgres', + qq[select pg_create_logical_replication_slot('slot_2', 'test_decoding')] + ); + test_wal_level($primary, "replica|logical", + "logical decoding enabled by the first of two concurrent activations" + ); + + # Resume the first backend to complete the slot creation. It must not write + # a second redundant status-change record as logical decoding is already + # enabled. + $primary->safe_psql('postgres', + qq[select injection_points_wakeup('logical-decoding-activation')]); + + # Let the released backend finish creating its slot. + $psql_create_slot->quit; + + # Decode from slot_2, whose start point precedes where a redundant + # status-change record would have been written; this fails in xlog_decode() + # if one exists. + is( $primary->safe_psql( + 'postgres', + qq[SELECT count(*) FROM pg_logical_slot_get_changes('slot_2', NULL, NULL, 'skip-empty-xacts', '1')] + ), + 0, + 'decoding a concurrently-created slot succeeds'); + + # Restore the disabled state for the tests that follow. + $primary->safe_psql( + 'postgres', + qq[ +select pg_drop_replication_slot('slot_1'); +select pg_drop_replication_slot('slot_2'); +]); + wait_for_logical_decoding_disabled($primary); + + # Test a race when logical decoding activation is concurrently interrupted. + # Start a psql session to test the case where the activation process is # interrupted. - my $psql_create_slot = $primary->background_psql('postgres'); + $psql_create_slot = $primary->background_psql('postgres'); # Start the logical decoding activation process upon creating the logical # slot, but it will wait due to the injection point. From 9f6fb1191915f1baeb32ab11392af436cf869ce4 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 28 Jul 2026 08:35:09 +0900 Subject: [PATCH 227/481] Fix propagation of indimmediate flag in index_create_copy() index_create_copy is used to create copy definitions of existing indexes. Currently, it passes 0 as constr_flags to index_create(), which results in the copied index to always be created as immediate (indimmediate set to true). For deferrable unique constraints, it means that the transient index used during the phase 2 of REINDEX CONCURRENTLY forces immediate constraint checks on concurrent inserts, which can cause unexpected constraint violations based on the definition of the parent table, inconsistently set in the copied index. To fix this without violating the contract of constr_flags (which should only be used when creating constraints) and without relaxing the strict assertion in index_create(), this introduces a new index creation flag: INDEX_CREATE_DEFERRABLE. If set, a copied index's indimmediate is set to false, meaning that unique constraints are not enforced immediately on insertion, but at transaction commit time. An isolation test for REINDEX CONCURRENTLY is added, based on an injection point waiting after phase 1 of the operation, where an index copy has been built and is able to accept DMLs for its validation in phase 2. The test is tentatively backpatched down to v17. INJECTION_POINT() is outside a transaction context, which should be fine on HEAD since 8daeaa9b642c but I suspect may cause issues in v19 and older branches due to the wait facility depending on condition variables and a DSM setup, but let's see what the buildfarm tells. Author: Nitin Motiani Discussion: https://postgr.es/m/CAH5HC97JmjPpgiQOqW9xm8qXhNiu7zZ1Qh+FfhEESJuDv69kuQ@mail.gmail.com Backpatch-through: 14 --- src/backend/catalog/index.c | 16 +++++- src/backend/commands/indexcmds.c | 2 + src/include/catalog/index.h | 1 + src/test/modules/injection_points/Makefile | 1 + .../reindex_concurrently_deferred.out | 41 +++++++++++++++ src/test/modules/injection_points/meson.build | 1 + .../specs/reindex_concurrently_deferred.spec | 50 +++++++++++++++++++ 7 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 src/test/modules/injection_points/expected/reindex_concurrently_deferred.out create mode 100644 src/test/modules/injection_points/specs/reindex_concurrently_deferred.spec diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 336757ea699..86f22570b45 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -717,6 +717,9 @@ UpdateIndexRelation(Oid indexoid, * create a partitioned index (table must be partitioned) * INDEX_CREATE_SUPPRESS_PROGRESS: * don't report progress during the index build. + * INDEX_CREATE_DEFERRABLE: + * index supports a deferrable constraint, mark it as + * non-immediate (indimmediate = false). * * constr_flags: flags passed to index_constraint_create * (only if INDEX_CREATE_ADD_CONSTRAINT is set) @@ -1051,7 +1054,8 @@ index_create(Relation heapRelation, indexInfo, collationIds, opclassIds, coloptions, isprimary, is_exclusion, - (constr_flags & INDEX_CONSTR_CREATE_DEFERRABLE) == 0, + (constr_flags & INDEX_CONSTR_CREATE_DEFERRABLE) == 0 && + (flags & INDEX_CREATE_DEFERRABLE) == 0, !concurrent && !invalid, !concurrent); @@ -1324,6 +1328,7 @@ index_create_copy(Relation heapRelation, uint16 flags, List *indexColNames = NIL; List *indexExprs = NIL; List *indexPreds = NIL; + Form_pg_index indexForm; indexRelation = index_open(oldIndexId, RowExclusiveLock); @@ -1343,6 +1348,13 @@ index_create_copy(Relation heapRelation, uint16 flags, indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(oldIndexId)); if (!HeapTupleIsValid(indexTuple)) elog(ERROR, "cache lookup failed for index %u", oldIndexId); + + indexForm = (Form_pg_index) GETSTRUCT(indexTuple); + + /* Old index is deferrable, do the same for the new index */ + if (!indexForm->indimmediate) + flags |= INDEX_CREATE_DEFERRABLE; + indclassDatum = SysCacheGetAttrNotNull(INDEXRELID, indexTuple, Anum_pg_index_indclass); indclass = (oidvector *) DatumGetPointer(indclassDatum); @@ -1477,7 +1489,7 @@ index_create_copy(Relation heapRelation, uint16 flags, stattargets, reloptionsDatum, flags, - 0, + 0, /* constr_flags */ true, /* allow table to be a system catalog? */ false, /* is_internal? */ NULL); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 9ab74c8df0a..2a73a55d1fc 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -4158,6 +4158,8 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein CommitTransactionCommand(); } + INJECTION_POINT("reindex-conc-index-built", NULL); + StartTransactionCommand(); /* diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index 9aee8226347..b952ad071d3 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -72,6 +72,7 @@ extern void index_check_primary_key(Relation heapRel, #define INDEX_CREATE_PARTITIONED (1 << 5) #define INDEX_CREATE_INVALID (1 << 6) #define INDEX_CREATE_SUPPRESS_PROGRESS (1 << 7) +#define INDEX_CREATE_DEFERRABLE (1 << 8) extern Oid index_create(Relation heapRelation, const char *indexRelationName, diff --git a/src/test/modules/injection_points/Makefile b/src/test/modules/injection_points/Makefile index fac80f3a4a7..25a3ddd890d 100644 --- a/src/test/modules/injection_points/Makefile +++ b/src/test/modules/injection_points/Makefile @@ -14,6 +14,7 @@ REGRESS_OPTS = --dlpath=$(top_builddir)/src/test/regress ISOLATION = basic \ inplace \ + reindex_concurrently_deferred \ repack \ repack_temporal \ repack_temporal_multirange \ diff --git a/src/test/modules/injection_points/expected/reindex_concurrently_deferred.out b/src/test/modules/injection_points/expected/reindex_concurrently_deferred.out new file mode 100644 index 00000000000..39924fa24fe --- /dev/null +++ b/src/test/modules/injection_points/expected/reindex_concurrently_deferred.out @@ -0,0 +1,41 @@ +Parsed test spec with 2 sessions + +starting permutation: reindex check_catalog begin2 write2 write_dup resolve_dup commit2 wakeup noop1 +injection_points_attach +----------------------- + +(1 row) + +step reindex: REINDEX TABLE CONCURRENTLY reind_deferred; +step check_catalog: + SELECT c.relname, i.indisunique, i.indimmediate, i.indisready, i.indisvalid + FROM pg_class c + JOIN pg_index i ON i.indexrelid = c.oid + WHERE c.relname = 'uq_val_ccnew'; + +relname |indisunique|indimmediate|indisready|indisvalid +------------+-----------+------------+----------+---------- +uq_val_ccnew|t |f |t |f +(1 row) + +step begin2: BEGIN; +step write2: INSERT INTO reind_deferred VALUES (3, 9); +step write_dup: INSERT INTO reind_deferred VALUES (4, 9); +step resolve_dup: UPDATE reind_deferred SET val = 10 WHERE id = 4; +step commit2: COMMIT; +step wakeup: + SELECT injection_points_detach('reindex-conc-index-built'); + SELECT injection_points_wakeup('reindex-conc-index-built'); + +injection_points_detach +----------------------- + +(1 row) + +injection_points_wakeup +----------------------- + +(1 row) + +step reindex: <... completed> +step noop1: diff --git a/src/test/modules/injection_points/meson.build b/src/test/modules/injection_points/meson.build index 163b6374ebc..aaf0536ba7e 100644 --- a/src/test/modules/injection_points/meson.build +++ b/src/test/modules/injection_points/meson.build @@ -45,6 +45,7 @@ tests += { 'specs': [ 'basic', 'inplace', + 'reindex_concurrently_deferred', 'repack', 'repack_temporal', 'repack_temporal_multirange', diff --git a/src/test/modules/injection_points/specs/reindex_concurrently_deferred.spec b/src/test/modules/injection_points/specs/reindex_concurrently_deferred.spec new file mode 100644 index 00000000000..4b95e1da2a7 --- /dev/null +++ b/src/test/modules/injection_points/specs/reindex_concurrently_deferred.spec @@ -0,0 +1,50 @@ +# REINDEX CONCURRENTLY with DEFERRED constraints +# +# Verify that concurrent writes that temporarily violate a deferred unique +# constraint do not fail while REINDEX CONCURRENTLY is running. +# +# The injection point "reindex-conc-index-built" fires after the phase 2 +# of REINDEX CONCURRENTLY, when the new index has indisready = true (inserts +# are checked against it) but indisvalid = false. + +setup +{ + CREATE EXTENSION injection_points; + CREATE TABLE reind_deferred (id int, val int, + CONSTRAINT uq_val UNIQUE(val) DEFERRABLE INITIALLY DEFERRED); + INSERT INTO reind_deferred VALUES (1, 1), (2, 2); +} + +teardown +{ + DROP TABLE reind_deferred; + DROP EXTENSION injection_points; +} + +session s1 +setup +{ + SELECT injection_points_set_local(); + SELECT injection_points_attach('reindex-conc-index-built', 'wait'); +} +step reindex { REINDEX TABLE CONCURRENTLY reind_deferred; } +step noop1 { } + +session s2 +step check_catalog { + SELECT c.relname, i.indisunique, i.indimmediate, i.indisready, i.indisvalid + FROM pg_class c + JOIN pg_index i ON i.indexrelid = c.oid + WHERE c.relname = 'uq_val_ccnew'; +} +step begin2 { BEGIN; } +step write2 { INSERT INTO reind_deferred VALUES (3, 9); } +step write_dup { INSERT INTO reind_deferred VALUES (4, 9); } +step resolve_dup { UPDATE reind_deferred SET val = 10 WHERE id = 4; } +step commit2 { COMMIT; } +step wakeup { + SELECT injection_points_detach('reindex-conc-index-built'); + SELECT injection_points_wakeup('reindex-conc-index-built'); +} + +permutation reindex check_catalog begin2 write2 write_dup resolve_dup commit2 wakeup noop1 From 123ea94f76b8efc9f45286e2ba55ee02bff5056c Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 28 Jul 2026 10:50:23 +0900 Subject: [PATCH 228/481] Fix portability issue in authentication test 003_peer The mapped user name is built upon the OS user name of the environment where the test is run. Depending on the characters used in the OS user name, CREATE ROLE may not get parsed (the author has mentioned hyphens as one case), causing a failure of the test. Let's use double-quotes around the mapped user name, which should be a solution good enough for the environments where this test tends to run. The buildfarm issued no complaint over the years. Oversight in 3c4e26a62c31, so backpatch down to v19. Perhaps 3c4e26a62c31 and this commit should be backpatched further down, but let's leave that for another day, if it proves necessary. Author: Yugo Nagata Discussion: https://postgr.es/m/20260727133857.fbd23d43d422f10f376a8bee@sraoss.co.jp Backpatch-through: 19 --- src/test/authentication/t/003_peer.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/authentication/t/003_peer.pl b/src/test/authentication/t/003_peer.pl index 5c774babd32..686e409ce6a 100644 --- a/src/test/authentication/t/003_peer.pl +++ b/src/test/authentication/t/003_peer.pl @@ -213,7 +213,7 @@ sub test_role # Create target role for \1 tests. my $mapped_name = "test${regex_test_string}map${regex_test_string}user"; -$node->safe_psql('postgres', "CREATE ROLE $mapped_name LOGIN"); +$node->safe_psql('postgres', "CREATE ROLE \"$mapped_name\" LOGIN"); # Success as the regular expression matches and \1 is replaced in the given # subexpression. From fd92f74b91d079430ef4544713a90b7b6aa8faee Mon Sep 17 00:00:00 2001 From: Dean Rasheed Date: Tue, 28 Jul 2026 09:44:23 +0100 Subject: [PATCH 229/481] Avoid RETURNING side effects for FOR PORTION OF leftovers. UPDATE/DELETE ... FOR PORTION OF inserts leftover rows for the untouched parts of the original row. These hidden inserts should not affect the command tag or ROW_COUNT, so they call ExecInsert() with canSetTag set to false. However, ExecInsert() still processed the RETURNING list whenever the target ResultRelInfo had ri_projectReturning set. That caused RETURNING expressions to be evaluated for leftover rows even though their results were discarded. As a result, expressions with side effects and information-leaking functions could be executed on the leftover rows, in addition to the visibly updated or deleted row. Fix by having ExecInsert() skip RETURNING processing when it is handling an internal FOR PORTION OF leftover insert. Use both the presence of a FOR PORTION OF clause and mtstate->operation == CMD_INSERT for this check, so that the auxiliary INSERT of a cross-partition UPDATE with a FOR PORTION OF clause still processes RETURNING normally. Back-patch to v19, where support for FOR PORTION OF was added. Author: Chao Li Reviewed-by: Dean Rasheed Reviewed-by: Paul A Jungwirth Discussion: https://postgr.es/m/07C125E5-F6ED-460C-A394-E6503DAE18FB@gmail.com Backpatch-through: 19 --- src/backend/executor/nodeModifyTable.c | 14 ++++++-- src/test/regress/expected/for_portion_of.out | 36 +++++++++++++++----- src/test/regress/sql/for_portion_of.sql | 16 +++++++-- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 1dbf0ffff9e..9a1c0992bfe 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1335,8 +1335,18 @@ ExecInsert(ModifyTableContext *context, if (resultRelInfo->ri_WithCheckOptions != NIL) ExecWithCheckOptions(WCO_VIEW_CHECK, resultRelInfo, slot, estate); - /* Process RETURNING if present */ - if (resultRelInfo->ri_projectReturning) + /* + * Process RETURNING if present. + * + * If this is an UPDATE/DELETE ... FOR PORTION OF, we do not return the + * leftover rows inserted by ExecForPortionOfLeftovers(). Note that we + * must check mtstate->operation here, because we *do* want to process the + * newly inserted row of a cross-partition UPDATE with a FOR PORTION OF + * clause (ExecCrossPartitionUpdate() leaves mtstate->operation set to + * CMD_UPDATE, whereas ExecForPortionOfLeftovers() sets it to CMD_INSERT). + */ + if (resultRelInfo->ri_projectReturning && + !(node->forPortionOf && mtstate->operation == CMD_INSERT)) { TupleTableSlot *oldSlot = NULL; diff --git a/src/test/regress/expected/for_portion_of.out b/src/test/regress/expected/for_portion_of.out index 3c592f90e70..a6cb1ba8380 100644 --- a/src/test/regress/expected/for_portion_of.out +++ b/src/test/regress/expected/for_portion_of.out @@ -920,14 +920,23 @@ SELECT * FROM for_portion_of_test ORDER BY id, valid_at; \set QUIET true -- UPDATE ... RETURNING returns only the updated values -- (not the inserted side values, which are added by a separate "statement"): +CREATE FUNCTION fpo_returning_row(text) +RETURNS text LANGUAGE plpgsql AS +$$ +BEGIN + RAISE NOTICE 'RETURNING %', $1; + RETURN $1; +END; +$$; UPDATE for_portion_of_test FOR PORTION OF valid_at FROM '2018-02-01' TO '2018-02-15' SET name = 'three^3' WHERE id = '[3,4)' - RETURNING *; - id | valid_at | name --------+-------------------------+--------- - [3,4) | [2018-02-01,2018-02-15) | three^3 + RETURNING *, fpo_returning_row(for_portion_of_test::text); +NOTICE: RETURNING ("[3,4)","[2018-02-01,2018-02-15)",three^3) + id | valid_at | name | fpo_returning_row +-------+-------------------------+---------+--------------------------------------------- + [3,4) | [2018-02-01,2018-02-15) | three^3 | ("[3,4)","[2018-02-01,2018-02-15)",three^3) (1 row) -- UPDATE ... RETURNING supports NEW and OLD valid_at @@ -975,10 +984,11 @@ DELETE FROM for_portion_of_test WHERE id = '[99,100)'; DELETE FROM for_portion_of_test FOR PORTION OF valid_at FROM '2018-02-02' TO '2018-02-03' WHERE id = '[3,4)' - RETURNING *; - id | valid_at | name --------+-------------------------+--------- - [3,4) | [2018-02-01,2018-02-10) | three^3 + RETURNING *, fpo_returning_row(for_portion_of_test::text); +NOTICE: RETURNING ("[3,4)","[2018-02-01,2018-02-10)",three^3) + id | valid_at | name | fpo_returning_row +-------+-------------------------+---------+--------------------------------------------- + [3,4) | [2018-02-01,2018-02-10) | three^3 | ("[3,4)","[2018-02-01,2018-02-10)",three^3) (1 row) -- DELETE FOR PORTION OF in a PL/pgSQL function @@ -2137,7 +2147,14 @@ UPDATE temporal_partitioned FOR PORTION OF valid_at FROM '2000-03-01' TO '2000-0 UPDATE temporal_partitioned FOR PORTION OF valid_at FROM '2000-06-01' TO '2000-07-01' SET name = 'one^2', id = '[4,5)' - WHERE id = '[1,2)'; + WHERE id = '[1,2)' + RETURNING id, valid_at, name, fpo_returning_row(temporal_partitioned::text); +NOTICE: RETURNING ("[4,5)","[2000-06-01,2000-07-01)",one^2,30) + id | valid_at | name | fpo_returning_row +-------+-------------------------+-------+---------------------------------------------- + [4,5) | [2000-06-01,2000-07-01) | one^2 | ("[4,5)","[2000-06-01,2000-07-01)",one^2,30) +(1 row) + -- Move from partition 3 to partition 1 UPDATE temporal_partitioned FOR PORTION OF valid_at FROM '2000-06-01' TO '2000-07-01' SET name = 'three^2', @@ -2199,6 +2216,7 @@ SELECT * FROM temporal_partitioned_5 ORDER BY id, valid_at; five | [2000-07-01,2010-01-01) | [5,6) | 3471 (4 rows) +DROP FUNCTION fpo_returning_row; DROP TABLE temporal_partitioned; -- UPDATE/DELETE FOR PORTION OF with RULEs CREATE TABLE fpo_rule (f1 bigint, f2 int4range); diff --git a/src/test/regress/sql/for_portion_of.sql b/src/test/regress/sql/for_portion_of.sql index 5f7b04fdf6b..955cf666d66 100644 --- a/src/test/regress/sql/for_portion_of.sql +++ b/src/test/regress/sql/for_portion_of.sql @@ -590,11 +590,19 @@ SELECT * FROM for_portion_of_test ORDER BY id, valid_at; -- UPDATE ... RETURNING returns only the updated values -- (not the inserted side values, which are added by a separate "statement"): +CREATE FUNCTION fpo_returning_row(text) +RETURNS text LANGUAGE plpgsql AS +$$ +BEGIN + RAISE NOTICE 'RETURNING %', $1; + RETURN $1; +END; +$$; UPDATE for_portion_of_test FOR PORTION OF valid_at FROM '2018-02-01' TO '2018-02-15' SET name = 'three^3' WHERE id = '[3,4)' - RETURNING *; + RETURNING *, fpo_returning_row(for_portion_of_test::text); -- UPDATE ... RETURNING supports NEW and OLD valid_at UPDATE for_portion_of_test @@ -629,7 +637,7 @@ DELETE FROM for_portion_of_test WHERE id = '[99,100)'; DELETE FROM for_portion_of_test FOR PORTION OF valid_at FROM '2018-02-02' TO '2018-02-03' WHERE id = '[3,4)' - RETURNING *; + RETURNING *, fpo_returning_row(for_portion_of_test::text); -- DELETE FOR PORTION OF in a PL/pgSQL function INSERT INTO for_portion_of_test (id, valid_at, name) VALUES @@ -1439,7 +1447,8 @@ UPDATE temporal_partitioned FOR PORTION OF valid_at FROM '2000-03-01' TO '2000-0 UPDATE temporal_partitioned FOR PORTION OF valid_at FROM '2000-06-01' TO '2000-07-01' SET name = 'one^2', id = '[4,5)' - WHERE id = '[1,2)'; + WHERE id = '[1,2)' + RETURNING id, valid_at, name, fpo_returning_row(temporal_partitioned::text); -- Move from partition 3 to partition 1 UPDATE temporal_partitioned FOR PORTION OF valid_at FROM '2000-06-01' TO '2000-07-01' @@ -1460,6 +1469,7 @@ SELECT * FROM temporal_partitioned_1 ORDER BY id, valid_at; SELECT * FROM temporal_partitioned_3 ORDER BY id, valid_at; SELECT * FROM temporal_partitioned_5 ORDER BY id, valid_at; +DROP FUNCTION fpo_returning_row; DROP TABLE temporal_partitioned; -- UPDATE/DELETE FOR PORTION OF with RULEs From 70dad584e8371eb8a470d882829ba428a22701d4 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Tue, 28 Jul 2026 10:50:13 +0200 Subject: [PATCH 230/481] Restore vacuum_delay_point() in GIN posting-tree leaf vacuum Commit fd83c83d094 turned the recursive posting-tree cleanup in ginVacuumPostingTreeLeaves() into an iterative sweep that follows the tree's leaf pages via their rightlinks. The recursive version called vacuum_delay_point() while processing the tree, but that call was removed and never re-added to the new loop. As that commit only set out to fix a deadlock, the removal appears to have been unintentional. Consequently the leaf-page sweep of a single posting tree runs with no vacuum_delay_point(), and therefore no CHECK_FOR_INTERRUPTS(). A posting tree stores all the TIDs for one indexed key, so for a frequently occurring key it can span a large number of leaf pages. While such a tree is being vacuumed the operation ignores vacuum_cost_delay and does not respond to query cancellation or statement_timeout; an autovacuum worker likewise cannot be interrupted mid-sweep when another backend requests a conflicting lock. Restore the call, placed after the current page has been unlocked and released so that no buffer content lock is held across a potential delay (cf. 21c27af65fb). The sibling loops in ginbulkdelete() and ginvacuumcleanup() already call vacuum_delay_point() once per page. Author: Paul Kim Co-authored-by: Alexander Korotkov Reviewed-by: Michael Paquier Reviewed-by: Andrey Borodin Reviewed-by: solai v Discussion: https://postgr.es/m/178447127453.110.12276981925360691905%40mail.gmail.com Backpatch-through: 14 --- src/backend/access/gin/ginvacuum.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index 840543eb664..040f21a92e3 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -429,6 +429,13 @@ ginVacuumPostingTreeLeaves(GinVacuumState *gvs, BlockNumber blkno) if (blkno == InvalidBlockNumber) break; + /* + * A safe point to delay/accept interrupts: the previous page has been + * unlocked and released, so we hold no buffer content lock (nor any + * other LWLock) here and CHECK_FOR_INTERRUPTS() can do its job. + */ + vacuum_delay_point(false); + buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, blkno, RBM_NORMAL, gvs->strategy); LockBuffer(buffer, GIN_EXCLUSIVE); From 28c995948cfd6b8ff3b2576aedd6f3d38107e9bc Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Tue, 28 Jul 2026 10:39:40 -0700 Subject: [PATCH 231/481] Fix pg_get_publication_tables() failure with concurrent DROP TABLE. pg_get_publication_tables() collects the OIDs of the published tables on its first call, without locking them, and then reopens each table later, once per result row, to compute its column list and fetch its row filter. The reopen used table_open(), which errors out with "could not open relation with OID" if the table has been dropped in the meantime. This could happen for any published table without an explicit column list, which is every table in FOR ALL TABLES and FOR TABLES IN SCHEMA publications, but also FOR TABLE entries without a column list. The failure is common in environments where many tables are created and dropped while publication tables are being queried, e.g. by table synchronization on a subscriber. Fix by opening every table with try_table_open(), which returns NULL if the relation no longer exists, and skipping the table in that case. Concurrently dropped tables are thus simply absent from the result set, which is the expected point-in-time behavior. As a side effect, tables with an explicit column list, which were previously returned without being opened, are now also locked with AccessShareLock, so the function can block behind concurrent DDL on such tables where it previously did not. Backpatch to v16, where we added the table_open() call in pg_get_publication_tables(). Author: Bharath Rupireddy Reviewed-by: Bertrand Drouvot Reviewed-by: shveta malik Reviewed-by: Ajin Cherian Reviewed-by: Masahiko Sawada Reviewed-by: Chao Li Discussion: https://www.postgresql.org/message-id/CALj2ACVYYooWH-5tJ6cPKkU%2BmutVxwb_z4S%2BqAi-zdrFqxXE2Q%40mail.gmail.com Backpatch-through: 16 --- src/backend/catalog/pg_publication.c | 52 +++++++++++++++---- .../expected/pub-concurrent-drop.out | 16 ++++++ src/test/isolation/isolation_schedule | 1 + .../isolation/specs/pub-concurrent-drop.spec | 36 +++++++++++++ src/tools/pgindent/typedefs.list | 1 + 5 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 src/test/isolation/expected/pub-concurrent-drop.out create mode 100644 src/test/isolation/specs/pub-concurrent-drop.spec diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index 5c457d9aca8..e6ebc1e2627 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -1414,14 +1414,27 @@ pg_get_publication_tables(FunctionCallInfo fcinfo, ArrayType *pubnames, bool pub_missing_ok) { #define NUM_PUBLICATION_TABLES_ELEM 4 + + /* + * State carried across SRF calls. We track the index ourselves instead of + * using funcctx->call_cntr, so that concurrently dropped tables can be + * skipped without emitting a row. + */ + typedef struct + { + List *table_infos; /* list of published_rel */ + int curr_idx; /* current index into table_infos */ + } publication_tables_state; + FuncCallContext *funcctx; - List *table_infos = NIL; + publication_tables_state *ptstate = NULL; /* stuff done only on the first call of the function */ if (SRF_IS_FIRSTCALL()) { TupleDesc tupdesc; MemoryContext oldcontext; + List *table_infos = NIL; Datum *elems; int nelems, i; @@ -1544,26 +1557,47 @@ pg_get_publication_tables(FunctionCallInfo fcinfo, ArrayType *pubnames, TupleDescFinalize(tupdesc); funcctx->tuple_desc = BlessTupleDesc(tupdesc); - funcctx->user_fctx = table_infos; + + /* Store the state to be used across SRF calls. */ + ptstate = palloc_object(publication_tables_state); + ptstate->table_infos = table_infos; + ptstate->curr_idx = 0; + funcctx->user_fctx = ptstate; MemoryContextSwitchTo(oldcontext); } /* stuff done on every call of the function */ funcctx = SRF_PERCALL_SETUP(); - table_infos = (List *) funcctx->user_fctx; + ptstate = (publication_tables_state *) funcctx->user_fctx; - if (funcctx->call_cntr < list_length(table_infos)) + while (ptstate->curr_idx < list_length(ptstate->table_infos)) { HeapTuple pubtuple = NULL; HeapTuple rettuple; Publication *pub; - published_rel *table_info = (published_rel *) list_nth(table_infos, funcctx->call_cntr); + published_rel *table_info = (published_rel *) list_nth(ptstate->table_infos, + ptstate->curr_idx); Oid relid = table_info->relid; - Oid schemaid = get_rel_namespace(relid); + Relation rel; + Oid schemaid; Datum values[NUM_PUBLICATION_TABLES_ELEM] = {0}; bool nulls[NUM_PUBLICATION_TABLES_ELEM] = {0}; + /* Advance the index for the next call. */ + ptstate->curr_idx++; + + /* + * The table OIDs were collected earlier, so a table may have been + * dropped before we get here. try_table_open() returns NULL if it is + * already gone, in which case we skip it; such tables are simply + * absent from the result set, which is the expected point-in-time + * behavior. + */ + rel = try_table_open(relid, AccessShareLock); + if (rel == NULL) + continue; + /* * Form tuple with appropriate data. */ @@ -1577,6 +1611,7 @@ pg_get_publication_tables(FunctionCallInfo fcinfo, ArrayType *pubnames, * We don't consider row filters or column lists for FOR ALL TABLES or * FOR TABLES IN SCHEMA publications. */ + schemaid = RelationGetNamespace(rel); if (!pub->alltables && !SearchSysCacheExists2(PUBLICATIONNAMESPACEMAP, ObjectIdGetDatum(schemaid), @@ -1606,7 +1641,6 @@ pg_get_publication_tables(FunctionCallInfo fcinfo, ArrayType *pubnames, /* Show all columns when the column list is not specified. */ if (nulls[2]) { - Relation rel = table_open(relid, AccessShareLock); int nattnums = 0; int16 *attnums; TupleDesc desc = RelationGetDescr(rel); @@ -1643,10 +1677,10 @@ pg_get_publication_tables(FunctionCallInfo fcinfo, ArrayType *pubnames, values[2] = PointerGetDatum(buildint2vector(attnums, nattnums)); nulls[2] = false; } - - table_close(rel, AccessShareLock); } + table_close(rel, AccessShareLock); + rettuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(rettuple)); diff --git a/src/test/isolation/expected/pub-concurrent-drop.out b/src/test/isolation/expected/pub-concurrent-drop.out new file mode 100644 index 00000000000..8360af0ec9c --- /dev/null +++ b/src/test/isolation/expected/pub-concurrent-drop.out @@ -0,0 +1,16 @@ +Parsed test spec with 2 sessions + +starting permutation: lock list_pub_tables drop_and_commit +step lock: BEGIN; LOCK pubdrop.dropme IN ACCESS EXCLUSIVE MODE; +step list_pub_tables: + SELECT relid::regclass AS tablename + FROM pg_get_publication_tables('pub_schema') + ORDER BY tablename; + +step drop_and_commit: DROP TABLE pubdrop.dropme; COMMIT; +step list_pub_tables: <... completed> +tablename +-------------- +pubdrop.keepme +(1 row) + diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index b8ebe92553c..26abed9f9f0 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -128,3 +128,4 @@ test: matview-write-skew test: lock-nowait test: for-portion-of test: ddl-dependency-locking +test: pub-concurrent-drop diff --git a/src/test/isolation/specs/pub-concurrent-drop.spec b/src/test/isolation/specs/pub-concurrent-drop.spec new file mode 100644 index 00000000000..4f7d701d60c --- /dev/null +++ b/src/test/isolation/specs/pub-concurrent-drop.spec @@ -0,0 +1,36 @@ +# Tests for concurrently dropping a relation while a publication's tables are +# being listed. + +setup +{ + CREATE SCHEMA pubdrop; + CREATE PUBLICATION pub_schema FOR TABLES IN SCHEMA pubdrop; + CREATE TABLE pubdrop.dropme (id int); + CREATE TABLE pubdrop.keepme (id int); +} + +teardown +{ + DROP SCHEMA pubdrop CASCADE; + DROP PUBLICATION pub_schema; +} + +session s1 +step lock { BEGIN; LOCK pubdrop.dropme IN ACCESS EXCLUSIVE MODE; } +step drop_and_commit { DROP TABLE pubdrop.dropme; COMMIT; } + +session s2 +step list_pub_tables +{ + SELECT relid::regclass AS tablename + FROM pg_get_publication_tables('pub_schema') + ORDER BY tablename; +} + +# Hold an ACCESS EXCLUSIVE lock on the table in one session, so that the query +# listing a publication's tables in another session blocks when it tries to +# open the locked table. Then drop the table in the same lock-holding session +# and commit, releasing the lock, so the query in another session resumes and +# skips the now-dropped table instead of erroring with "could not open relation +# with OID". +permutation lock list_pub_tables drop_and_commit diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 3442c4b9ec9..5fcdc7a131c 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -4202,6 +4202,7 @@ pthread_mutex_t pthread_once_t pthread_t ptrdiff_t +publication_tables_state published_rel pull_var_clause_context pull_varattnos_context From 2289e65e15ee53cbba2d96543553c467c9ccbc4e Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Tue, 28 Jul 2026 12:33:31 -0700 Subject: [PATCH 232/481] Fix logical decoding of empty prepared transactions. A two-phase transaction that is assigned an XID but produces no change to be decoded -- for example, one that only acquires row locks via SELECT ... FOR SHARE -- has no base snapshot in the reorder buffer. ReorderBufferReplay() already skips such a transaction at PREPARE time and never invokes the begin_prepare/change/prepare callbacks for it, but ReorderBufferFinishPrepared() still called the commit_prepared (or rollback_prepared) callback. As a result a spurious COMMIT/ROLLBACK PREPARED was sent to the output plugin with no preceding PREPARE. For the built-in subscriber this breaks replication (the apply worker fails to find the prepared transaction), and test_decoding could even crash. Fix this by detecting an empty transaction (base_snapshot == NULL) in ReorderBufferFinishPrepared() and cleaning it up without invoking the commit/rollback prepared callbacks, mirroring the existing empty transaction handling in ReorderBufferReplay(). On v18 and newer versions, commit 072ee847ad4 changed ReorderBufferPrepare() to send the prepare whenever it had not already been sent, which also fires for empty transactions and emits a spurious PREPARE. On those branches ReorderBufferPrepare() is therefore additionally guarded with base_snapshot != NULL. This guard and the Assert(!rbtxn_sent_prepare()) added in ReorderBufferFinishPrepared(), are not necessary on v17 and older versions: there ReorderBufferPrepare() only sends a prepare for concurrently-aborted transactions (which never applies to an empty transaction) and the RBTXN_SENT_PREPARE flag does not exist. Back-patch to v14, where decoding of two-phase transactions was introduced. Bug: #19556 Reported-by: Alexander Kozhemyakin Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/19556-daa6d7ea65054d48@postgresql.org Backpatch-through: 14 --- contrib/test_decoding/expected/twophase.out | 25 +++++++++++ contrib/test_decoding/sql/twophase.sql | 12 ++++++ .../replication/logical/reorderbuffer.c | 34 +++++++++++++-- src/test/subscription/t/021_twophase.pl | 41 +++++++++++++++++++ 4 files changed, 108 insertions(+), 4 deletions(-) diff --git a/contrib/test_decoding/expected/twophase.out b/contrib/test_decoding/expected/twophase.out index 08a7c56b5df..ea3c51f8215 100644 --- a/contrib/test_decoding/expected/twophase.out +++ b/contrib/test_decoding/expected/twophase.out @@ -227,6 +227,31 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc COMMIT PREPARED 'test_toast_table_access' (1 row) +-- Test that an empty prepared transaction should not be decoded, whether it +-- is committed or rolled back. +BEGIN; +SELECT * FROM test_prepared1 WHERE id = 1 FOR SHARE; + id | data +----+------ + 1 | +(1 row) + +PREPARE TRANSACTION 'test_empty_transaction'; +COMMIT PREPARED 'test_empty_transaction'; +BEGIN; +SELECT * FROM test_prepared1 WHERE id = 1 FOR SHARE; + id | data +----+------ + 1 | +(1 row) + +PREPARE TRANSACTION 'test_empty_transaction'; +ROLLBACK PREPARED 'test_empty_transaction'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +------ +(0 rows) + -- Test 8: -- cleanup and make sure results are also empty DROP TABLE test_prepared1; diff --git a/contrib/test_decoding/sql/twophase.sql b/contrib/test_decoding/sql/twophase.sql index 4b9ef0c0c44..834e5282c30 100644 --- a/contrib/test_decoding/sql/twophase.sql +++ b/contrib/test_decoding/sql/twophase.sql @@ -125,6 +125,18 @@ COMMIT PREPARED 'test_toast_table_access'; -- consume commit prepared SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); +-- Test that an empty prepared transaction should not be decoded, whether it +-- is committed or rolled back. +BEGIN; +SELECT * FROM test_prepared1 WHERE id = 1 FOR SHARE; +PREPARE TRANSACTION 'test_empty_transaction'; +COMMIT PREPARED 'test_empty_transaction'; +BEGIN; +SELECT * FROM test_prepared1 WHERE id = 1 FOR SHARE; +PREPARE TRANSACTION 'test_empty_transaction'; +ROLLBACK PREPARED 'test_empty_transaction'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + -- Test 8: -- cleanup and make sure results are also empty DROP TABLE test_prepared1; diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 059ed860314..08be0dacc4a 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -2979,11 +2979,18 @@ ReorderBufferPrepare(ReorderBuffer *rb, TransactionId xid, txn->prepare_time, txn->origin_id, txn->origin_lsn); /* - * Send a prepare if not already done so. This might occur if we have - * detected a concurrent abort while replaying the non-streaming - * transaction. + * Send a prepare if not already done so. The "not already sent" case can + * occur if we have detected a concurrent abort while replaying the + * non-streaming transaction; we still send the prepare so that later when + * rollback prepared is decoded and sent, the downstream should be able to + * rollback such a xact. See comments atop DecodePrepare. + * + * Skip this for a transaction that made no changes to the database (i.e. + * has no base snapshot), as we haven't sent any changes for it. Such a + * transaction is cleaned up without invoking the commit/rollback prepared + * callbacks in ReorderBufferFinishPrepared(). */ - if (!rbtxn_sent_prepare(txn)) + if (!rbtxn_sent_prepare(txn) && txn->base_snapshot != NULL) { rb->prepare(rb, txn, txn->final_lsn); txn->txn_flags |= RBTXN_SENT_PREPARE; @@ -3050,6 +3057,25 @@ ReorderBufferFinishPrepared(ReorderBuffer *rb, TransactionId xid, txn->prepare_time, txn->origin_id, txn->origin_lsn); } + /* + * If this transaction has no snapshot, it didn't make any changes to the + * database, so there's nothing to decode. Note that + * ReorderBufferCommitChild will have transferred any snapshots from + * subtransactions if there were any. + */ + if (txn->base_snapshot == NULL) + { + Assert(txn->ninvalidations == 0); + Assert(!rbtxn_sent_prepare(txn)); + + /* + * Removing this txn before a commit might result in the computation + * of an incorrect restart_lsn. See SnapBuildProcessRunningXacts. + */ + ReorderBufferCleanupTXN(rb, txn); + return; + } + txn->final_lsn = commit_lsn; txn->end_lsn = end_lsn; txn->commit_time = commit_time; diff --git a/src/test/subscription/t/021_twophase.pl b/src/test/subscription/t/021_twophase.pl index 4404d7b5449..f755e748e9c 100644 --- a/src/test/subscription/t/021_twophase.pl +++ b/src/test/subscription/t/021_twophase.pl @@ -309,6 +309,47 @@ "SELECT count(*) FROM pg_prepared_xacts;"); is($result, qq(0), 'transaction is aborted on subscriber'); +############################### +# Test that an empty prepared transaction is not replicated. +# +# A transaction that is assigned an XID but makes no change decoded by logical +# replication (here, via a row lock) must not be sent to the subscriber. +# Otherwise the subscriber would receive a PREPARE with no preceding BEGIN +# PREPARE and error out, breaking replication. +############################### + +# An empty prepared transaction that is committed. +$node_publisher->safe_psql( + 'postgres', " + BEGIN; + SELECT a FROM tab_full WHERE a = 1 FOR SHARE; + PREPARE TRANSACTION 'test_empty_prepared'; + COMMIT PREPARED 'test_empty_prepared';"); + +# An empty prepared transaction that is rolled back. +$node_publisher->safe_psql( + 'postgres', " + BEGIN; + SELECT a FROM tab_full WHERE a = 1 FOR SHARE; + PREPARE TRANSACTION 'test_empty_prepared'; + ROLLBACK PREPARED 'test_empty_prepared';"); + +# A subsequent normal change must still replicate. Reaching catchup confirms +# the apply worker was not stalled by the empty prepared transactions above. +$node_publisher->safe_psql('postgres', "INSERT INTO tab_full VALUES (31);"); +$node_publisher->wait_for_catchup($appname); + +# The empty transactions must not have been prepared on the subscriber. +$result = $node_subscriber->safe_psql('postgres', + "SELECT count(*) FROM pg_prepared_xacts;"); +is($result, qq(0), 'empty prepared transaction is not replicated'); + +# The subsequent change is visible, so replication is healthy. +$result = $node_subscriber->safe_psql('postgres', + "SELECT count(*) FROM tab_full WHERE a = 31;"); +is($result, qq(1), + 'replication continues after an empty prepared transaction'); + ############################### # copy_data=false and two_phase ############################### From 9eb77f9fc80db071b434aea58681ed2adb9038d3 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Tue, 28 Jul 2026 21:52:24 +0200 Subject: [PATCH 233/481] Recheck checksum state before file_copy during CREATE DATABASE The file_copy strategy check in createdb() runs during option validation, before the transaction has an XID and before the pg_database row exists, so the datachecksumsworker launcher can start in that window and see neither the new database nor the transaction creating it. It then raw-copies a template that was not processed yet, and those files stay unchecksummed, failing verification from then on. Recheck the state in CreateDatabaseUsingFileCopy(): the XID is assigned by then, so a launcher starting after this point waits for the transaction and finds the new database, and the copy errors out instead. Add an injection point before the catalog insert to test the window. Backpatch to v19 where online checksums were introduced. Author: Zsolt Parragi Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CAN4CZFPEBsz8JeY4ixQ1V4ZL_xOY6pJaZS8ZLGH7R+wF--pEtg@mail.gmail.com Backpatch-through: 19 --- src/backend/commands/dbcommands.c | 28 ++++++++ .../modules/test_checksums/t/005_injection.pl | 68 +++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index f0819d15ab7..fa2ce033391 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -65,6 +65,7 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/injection_point.h" #include "utils/lsyscache.h" #include "utils/pg_locale.h" #include "utils/relmapper.h" @@ -558,6 +559,23 @@ CreateDatabaseUsingFileCopy(Oid src_dboid, Oid dst_dboid, Oid src_tsid, Relation rel; HeapTuple tuple; + /* + * The strategy check in createdb() runs before our transaction has an XID + * and before the pg_database row exists, so the datachecksumsworker + * launcher can start in that window and miss both the new database and + * our transaction, leaving the raw-copied files without checksums. + */ + if (DataChecksumsInProgressOn()) + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("create database strategy \"%s\" not allowed when data checksums are being enabled", + "file_copy")); + + /* + * The XID is assigned by now, so a datachecksumsworker launcher starting + * after this point will wait for us and find the new database. + */ + /* * Force a checkpoint before starting the copy. This will force all dirty * buffers, including those of unlogged tables, out to disk, to ensure @@ -1045,6 +1063,14 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) dbstrategy = CREATEDB_WAL_LOG; else if (pg_strcasecmp(strategy, "file_copy") == 0) { + /* + * If data checksums are being enabled we must not use file_copy + * since it might copy source database which hasn't yet had data + * checksums enabled, and the destination database will be skipped + * as it's expected to have data checksums enabled. Once we have + * an XID assigned this needs to be rechecked, but if can error + * out already we can save a lot of work. + */ if (DataChecksumsInProgressOn()) ereport(ERROR, errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -1510,6 +1536,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) tuple = heap_form_tuple(RelationGetDescr(pg_database_rel), new_record, new_record_nulls); + INJECTION_POINT("createdb-before-catalog-insert", NULL); + CatalogTupleInsert(pg_database_rel, tuple); /* diff --git a/src/test/modules/test_checksums/t/005_injection.pl b/src/test/modules/test_checksums/t/005_injection.pl index 7240b93bdd1..34cd47e6c81 100644 --- a/src/test/modules/test_checksums/t/005_injection.pl +++ b/src/test/modules/test_checksums/t/005_injection.pl @@ -76,5 +76,73 @@ enable_data_checksums($node, wait => 'on'); } +# --------------------------------------------------------------------------- +# Test concurrent CREATE DATABASE which use the file_copy strategy +# + +disable_data_checksums($node, wait => 1); +my $node_loglocation = -s $node->logfile; + +$node->safe_psql('postgres', + "CREATE TABLE t AS SELECT generate_series(1,10000) AS a;"); + +$node->safe_psql('postgres', + "SELECT injection_points_attach('createdb-before-catalog-insert','wait');" +); +$node->safe_psql('postgres', + "SELECT injection_points_attach('datachecksumsworker-fake-temptable-wait','wait');" +); + +# Hold CREATE DATABASE after the strategy check, before its xact is visible. +my $bg = $node->background_psql('postgres'); +$bg->query_until( + qr/starting_create/, q( +\echo starting_create +CREATE DATABASE fcdb TEMPLATE template0 STRATEGY file_copy; +)); +$node->wait_for_event('client backend', 'createdb-before-catalog-insert'); + +# Enable checksums, worker holds before processing template0. +enable_data_checksums($node); +$node->wait_for_event('datachecksums worker', + 'datachecksumsworker-fake-temptable-wait'); + +# Release CREATE DATABASE, must fail on the recheck instead of raw-copying. +$node->safe_psql('postgres', + "SELECT injection_points_wakeup('createdb-before-catalog-insert');"); +$node->safe_psql('postgres', + "SELECT injection_points_detach('createdb-before-catalog-insert');"); + +# Wait for the CREATE DATABASE xact to finish before releasing the worker. +$node->poll_query_until('postgres', + "SELECT count(*) = 0 FROM pg_catalog.pg_stat_activity " + . "WHERE query LIKE 'CREATE DATABASE%' AND state != 'idle';"); + +$node->safe_psql('postgres', + "SELECT injection_points_wakeup('datachecksumsworker-fake-temptable-wait');" +); +$node->safe_psql('postgres', + "SELECT injection_points_detach('datachecksumsworker-fake-temptable-wait');" +); + +wait_for_checksum_state($node, 'on'); + +my $result = $node->safe_psql('postgres', + "SELECT count(*) FROM pg_catalog.pg_database WHERE datname = 'fcdb';"); +is($result, '0', 'file_copy database creation was refused'); + +my $log = + PostgreSQL::Test::Utils::slurp_file($node->logfile, $node_loglocation); +like( + $log, + qr/create database strategy "file_copy" not allowed/m, + 'file_copy error message in log'); + +# --------------------------------------------------------------------------- +# Test teardown +# + +$bg->{run}->finish; +$bg->quit; $node->stop; done_testing(); From e469e4784ea9f632b91e5d988cd336cbf54af58a Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Tue, 28 Jul 2026 21:52:27 +0200 Subject: [PATCH 234/481] Handle invalid and dropped databases during checksum enable Enable errors out early with a hint when an invalid database exists, since the worker cannot connect to it and its files stay on disk. A worker that started but failed gets the same dropped-database heuristic as one that failed to start, so a concurrent drop during processing no longer aborts the whole run. The existence check locks the database first, otherwise a DROP DATABASE ... WITH (FORCE) which killed the worker is still only halfway done and the database looks like it is there to stay. Backpatch to v19 where online checksums were introduced. Author: Zsolt Parragi Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CAN4CZFOGdqxtZ5-6gb4apqmvoH=Z+TNH8RKJ3mVtoR1HirKQWg@mail.gmail.com Backpatch-through: 19 --- src/backend/postmaster/datachecksum_state.c | 71 ++++++++++ .../modules/test_checksums/t/001_basic.pl | 121 ++++++++++++++++++ 2 files changed, 192 insertions(+) diff --git a/src/backend/postmaster/datachecksum_state.c b/src/backend/postmaster/datachecksum_state.c index 7f29551202f..a83236c3683 100644 --- a/src/backend/postmaster/datachecksum_state.c +++ b/src/backend/postmaster/datachecksum_state.c @@ -385,6 +385,7 @@ static void StartDataChecksumsWorkerLauncher(DataChecksumsWorkerOperation op, int cost_limit); static void DataChecksumsShmemRequest(void *arg); static bool DatabaseExists(Oid dboid); +static void ErrorOnInvalidDatabases(void); static List *BuildDatabaseList(void); static List *BuildRelationList(bool temp_relations, bool include_shared); static void FreeDatabaseList(List *dblist); @@ -583,6 +584,15 @@ enable_data_checksums(PG_FUNCTION_ARGS) errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cost limit must be greater than zero")); + /* + * An invalid database cannot be connected to, so the worker would fail to + * process it, and unlike a dropped database its files stay around. Error + * out early with a hint rather than failing halfway through processing. A + * database which turns invalid after this check is handled by the + * launcher treating it as concurrently dropped. + */ + ErrorOnInvalidDatabases(); + StartDataChecksumsWorkerLauncher(ENABLE_DATACHECKSUMS, cost_delay, cost_limit); PG_RETURN_VOID(); @@ -984,6 +994,17 @@ ProcessDatabase(DataChecksumsWorkerDatabase *db) DataChecksumState->worker_pid = InvalidPid; LWLockRelease(DataChecksumsWorkerLock); + /* + * A worker which started but failed before reporting a result has most + * likely FATALed in InitPostgres. If the database was dropped, or was + * invalidated by a DROP DATABASE which is bound to remove its files, + * after we built the database list then that is the expected outcome and + * not an error, so apply the same heuristic as when the worker failed to + * start. + */ + if (result == DATACHECKSUMSWORKER_FAILED && !DatabaseExists(db->dboid)) + result = DATACHECKSUMSWORKER_DROPDB; + if (result == DATACHECKSUMSWORKER_ABORTED) ereport(LOG, errmsg("data checksums processing was aborted in database \"%s\"", @@ -1410,6 +1431,15 @@ DatabaseExists(Oid dboid) StartTransactionCommand(); + /* + * DROP DATABASE holds an exclusive lock on the database from before it + * terminates the connections to it until it commits, so take a lock which + * conflicts with it to wait out a drop which is in flight. Without this + * we can see a database whose worker was just killed by DROP DATABASE ... + * WITH (FORCE) as still existing, and report a spurious failure. + */ + LockSharedObject(DatabaseRelationId, dboid, 0, AccessShareLock); + rel = table_open(DatabaseRelationId, AccessShareLock); ScanKeyInit(&skey, Anum_pg_database_oid, @@ -1436,6 +1466,47 @@ DatabaseExists(Oid dboid) return found; } +/* + * ErrorOnInvalidDatabases + * Error out if the cluster contains an invalid database + * + * A database left invalid by an interrupted DROP DATABASE cannot be connected + * to, so data checksums can never be enabled in it, while its files remain on + * disk where checksum verification will find them. Report it to the caller + * so the user can drop it before retrying. Called from a normal backend, so + * unlike DatabaseExists we are already in a transaction. + * + * A cluster can contain more than one invalid database, but only the first one + * found is reported; collecting them all is not worth the complexity here. A + * user with several of them gets the error again for the next one after + * dropping the reported database, which the hint accounts for. + */ +static void +ErrorOnInvalidDatabases(void) +{ + Relation rel; + TableScanDesc scan; + HeapTuple tup; + + rel = table_open(DatabaseRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, 0, NULL); + + while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) + { + Form_pg_database pgdb = (Form_pg_database) GETSTRUCT(tup); + + if (database_is_invalid_form(pgdb)) + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot enable data checksums in a cluster with invalid database \"%s\"", + NameStr(pgdb->datname)), + errhint("Use DROP DATABASE to drop invalid databases.")); + } + + table_endscan(scan); + table_close(rel, AccessShareLock); +} + /* * BuildDatabaseList * Compile a list of all currently available databases in the cluster diff --git a/src/test/modules/test_checksums/t/001_basic.pl b/src/test/modules/test_checksums/t/001_basic.pl index a78118320d5..72e0d0df46f 100644 --- a/src/test/modules/test_checksums/t/001_basic.pl +++ b/src/test/modules/test_checksums/t/001_basic.pl @@ -59,5 +59,126 @@ $result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1"); is($result, '10000', 'ensure checksummed pages can be read back'); +# Enabling checksums in a cluster which contains an invalid database left +# behind by an interrupted DROP DATABASE must be refused. +disable_data_checksums($node, wait => 1); + +$node->safe_psql('postgres', "CREATE DATABASE baddb;"); +$node->safe_psql('baddb', + "CREATE TABLE bad_t AS SELECT generate_series(1,100) AS a;"); + +# Mark the database invalid, as an interrupted DROP DATABASE would. +$node->safe_psql('postgres', + "UPDATE pg_database SET datconnlimit = -2 WHERE datname = 'baddb';"); + +# The request must fail up front with an actionable error, rather than fail +# halfway through processing. +my ($ret, $stdout, $stderr) = + $node->psql('postgres', "SELECT pg_enable_data_checksums();"); +isnt($ret, 0, 'pg_enable_data_checksums fails with an invalid database'); +like( + $stderr, + qr/invalid database "baddb"/, + 'error message names the invalid database'); +like( + $stderr, + qr/DROP DATABASE/, + 'error message hints at dropping the database'); +test_checksum_state($node, 'off'); + +# Dropping the invalid database clears the way. +$node->safe_psql('postgres', "DROP DATABASE baddb;"); +enable_data_checksums($node, wait => 'on'); + +# A database dropped while processing is in progress is not an error, the +# remaining databases are still processed. +disable_data_checksums($node, wait => 1); + +$node->safe_psql('postgres', "CREATE DATABASE dropme;"); +$node->safe_psql('dropme', + "CREATE TABLE dropme_t AS SELECT generate_series(1,10000) AS a;"); + +# Hold the worker in the "postgres" database by keeping a temporary table +# around, the worker waits for pre-existing temp tables to disappear before +# it reports the database as processed. "dropme" was created last, so it is +# processed after "postgres" and is still untouched while we wait. +my $bg = $node->background_psql('postgres'); +$bg->query_safe('CREATE TEMP TABLE holdme (a int);'); + +enable_data_checksums($node); + +$node->poll_query_until( + 'postgres', qq[ + SELECT count(*) > 0 FROM pg_stat_activity + WHERE backend_type = 'datachecksums worker' AND datname = 'postgres' + AND query LIKE 'Waiting for % temp tables to be removed'] +) or die "timed out waiting for worker to wait for temporary tables"; + +# Verify the assumption that processing has not reached "dropme" yet, without +# it the test would silently stop covering the concurrent drop. +my $log = slurp_file($node->logfile); +unlike( + $log, + qr/initiating data checksum processing in database "dropme"/, + 'processing has not reached the database to drop'); + +# Not processed yet and nobody is connected to it, so this must succeed. +$node->safe_psql('postgres', "DROP DATABASE dropme;"); + +# Let the worker in "postgres" finish, the launcher then moves on to the +# database which no longer exists. +$bg->query_safe('DROP TABLE holdme;'); +$bg->quit; + +wait_for_checksum_state($node, 'on'); +$node->poll_query_until('postgres', + "SELECT count(*) = 0 " + . "FROM pg_catalog.pg_stat_activity " + . "WHERE backend_type = 'datachecksums launcher';"); + +# Same thing with DROP DATABASE ... WITH (FORCE), which terminates the +# checksums worker connected to the database being dropped. +disable_data_checksums($node, wait => 1); + +$node->safe_psql('postgres', "CREATE DATABASE dropmeforce;"); +$node->safe_psql('dropmeforce', + "CREATE TABLE dropme_t AS SELECT generate_series(1,10000) AS a;"); + +# Hold the worker inside "dropmeforce" by keeping a temporary table around +# there. +$bg = $node->background_psql('dropmeforce'); +$bg->query_safe('CREATE TEMP TABLE holdme (a int);'); + +enable_data_checksums($node); + +$node->poll_query_until( + 'postgres', qq[ + SELECT count(*) > 0 FROM pg_stat_activity + WHERE backend_type = 'datachecksums worker' AND datname = 'dropmeforce' + AND query LIKE 'Waiting for % temp tables to be removed'] +) or die "timed out waiting for worker to wait for temporary tables"; + +# Terminates both the session holding the temp table and the checksums +# worker connected to the database. +$node->safe_psql('postgres', "DROP DATABASE dropmeforce WITH (FORCE);"); +$bg->{run}->finish; +$bg->quit; + +wait_for_checksum_state($node, 'on'); +$node->poll_query_until('postgres', + "SELECT count(*) = 0 " + . "FROM pg_catalog.pg_stat_activity " + . "WHERE backend_type = 'datachecksums launcher';"); + +$result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1"); +is($result, '10000', 'ensure checksummed pages can be read back'); + $node->stop; + +# The resulting cluster must also pass offline verification, proving no +# unchecksummed files were left behind. +command_ok( + [ 'pg_checksums', '--check', '-D', $node->data_dir ], + 'offline checksum verification passes after enable'); + done_testing(); From 9740c68ff7aa5d5a2d40c3ff0172467b38a17df8 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 28 Jul 2026 16:08:46 -0400 Subject: [PATCH 235/481] Fix planner's nullability/strictness logic for ScalarArrayOpExpr. find_nonnullable_rels and find_nonnullable_vars mistakenly treated a ScalarArrayOpExpr that could return FALSE as strict, but that's okay only at top level of a qual expression; further down, we've got to insist on a guaranteed-NULL result. The result was that we could draw mistaken conclusions about whether outer joins can be simplified, if the decision hinged on a non-top-level ScalarArrayOpExpr with a potentially-empty array argument. I believe this error dates to commit 72a070a36, which taught find_nonnullable_rels to descend into non-top-level parts of qual expressions. is_strict_saop (added earlier by 72153c058) already had enough intelligence to do the case correctly, but it wasn't passed the proper flag, ie "top_level" needs to be passed for "falseOK". e006a24ad copied that mistake into find_nonnullable_vars. Later, over-eager refactoring in commit 2f153ddfd broke contain_nonstrict_functions' handling of ScalarArrayOpExpr by treating it as though it were no different from an OpExpr. It is, because we must also prove the array is non-empty before concluding that the expression is strict. This could result in misclassifying an expression as strict when it is not, leading to assorted planning mistakes such as inlining a SQL function that shouldn't be inlined. We can almost fix this by just re-adding the previous handling of ScalarArrayOpExpr in that function, but doing only that would lead to also calling check_functions_in_node() and thus redundantly checking the operator's strictness. Avoid that by turning the if-series into an else-if chain, as it arguably should have been all along. The reason these errors have escaped detection for decades is that they are exposed only in arcane corner cases. ScalarArrayOpExpr with an empty array isn't typical usage, and even when that's possible several other conditions apply before the planner can reach a mistaken conclusion. While it's possible to build test cases demonstrating these mistakes, I (tgl) judged them too indirect and special-purpose to justify consuming regression test cycles forevermore. Author: Ayush Tiwari Reviewed-by: Tom Lane Discussion: https://postgr.es/m/CAJTYsWV3vqRJmST-gv1NsXEef-zOnjVJpYS910aBaiuMij4nFg@mail.gmail.com Discussion: https://postgr.es/m/CAJTYsWWcLGmz0f8_QPP_Liq-fc7-geiFSCdqoq3XGeRHPPsWeA@mail.gmail.com Backpatch-through: 14 --- src/backend/optimizer/util/clauses.c | 74 +++++++++++++++------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index aa8886ec210..7d7f2f9664b 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -1040,7 +1040,7 @@ contain_nonstrict_functions_walker(Node *node, void *context) /* an aggregate could return non-null with null input */ return true; } - if (IsA(node, GroupingFunc)) + else if (IsA(node, GroupingFunc)) { /* * A GroupingFunc doesn't evaluate its arguments, and therefore must @@ -1048,12 +1048,12 @@ contain_nonstrict_functions_walker(Node *node, void *context) */ return true; } - if (IsA(node, WindowFunc)) + else if (IsA(node, WindowFunc)) { /* a window function could return non-null with null input */ return true; } - if (IsA(node, SubscriptingRef)) + else if (IsA(node, SubscriptingRef)) { SubscriptingRef *sbsref = (SubscriptingRef *) node; const SubscriptRoutines *sbsroutines; @@ -1067,17 +1067,25 @@ contain_nonstrict_functions_walker(Node *node, void *context) return true; /* else fall through to check args */ } - if (IsA(node, DistinctExpr)) + else if (IsA(node, DistinctExpr)) { /* IS DISTINCT FROM is inherently non-strict */ return true; } - if (IsA(node, NullIfExpr)) + else if (IsA(node, NullIfExpr)) { /* NULLIF is inherently non-strict */ return true; } - if (IsA(node, BoolExpr)) + else if (IsA(node, ScalarArrayOpExpr)) + { + ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; + + if (!is_strict_saop(expr, false)) + return true; + /* else fall through to check args */ + } + else if (IsA(node, BoolExpr)) { BoolExpr *expr = (BoolExpr *) node; @@ -1091,28 +1099,26 @@ contain_nonstrict_functions_walker(Node *node, void *context) break; } } - if (IsA(node, SubLink)) + else if (IsA(node, SubLink)) { /* In some cases a sublink might be strict, but in general not */ return true; } - if (IsA(node, SubPlan)) + else if (IsA(node, SubPlan)) return true; - if (IsA(node, AlternativeSubPlan)) + else if (IsA(node, AlternativeSubPlan)) return true; - if (IsA(node, FieldStore)) + else if (IsA(node, FieldStore)) return true; - if (IsA(node, CoerceViaIO)) + else if (IsA(node, CoerceViaIO)) { /* * CoerceViaIO is strict regardless of whether the I/O functions are, - * so just go look at its argument; asking check_functions_in_node is - * useless expense and could deliver the wrong answer. + * so we should skip check_functions_in_node() and just fall through + * to check the arguments. */ - return contain_nonstrict_functions_walker((Node *) ((CoerceViaIO *) node)->arg, - context); } - if (IsA(node, ArrayCoerceExpr)) + else if (IsA(node, ArrayCoerceExpr)) { /* * ArrayCoerceExpr is strict at the array level, regardless of what @@ -1122,31 +1128,33 @@ contain_nonstrict_functions_walker(Node *node, void *context) return contain_nonstrict_functions_walker((Node *) ((ArrayCoerceExpr *) node)->arg, context); } - if (IsA(node, CaseExpr)) + else if (IsA(node, CaseExpr)) return true; - if (IsA(node, ArrayExpr)) + else if (IsA(node, ArrayExpr)) return true; - if (IsA(node, RowExpr)) + else if (IsA(node, RowExpr)) return true; - if (IsA(node, RowCompareExpr)) + else if (IsA(node, RowCompareExpr)) return true; - if (IsA(node, CoalesceExpr)) + else if (IsA(node, CoalesceExpr)) return true; - if (IsA(node, MinMaxExpr)) + else if (IsA(node, MinMaxExpr)) return true; - if (IsA(node, XmlExpr)) + else if (IsA(node, XmlExpr)) return true; - if (IsA(node, NullTest)) - return true; - if (IsA(node, BooleanTest)) + else if (IsA(node, NullTest)) return true; - if (IsA(node, JsonConstructorExpr)) + else if (IsA(node, BooleanTest)) return true; - - /* Check other function-containing nodes */ - if (check_functions_in_node(node, contain_nonstrict_functions_checker, - context)) + else if (IsA(node, JsonConstructorExpr)) return true; + else + { + /* Check other function-containing nodes */ + if (check_functions_in_node(node, contain_nonstrict_functions_checker, + context)) + return true; + } return expression_tree_walker(node, contain_nonstrict_functions_walker, context); @@ -1546,7 +1554,7 @@ find_nonnullable_rels_walker(Node *node, bool top_level) { ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; - if (is_strict_saop(expr, true)) + if (is_strict_saop(expr, top_level)) result = find_nonnullable_rels_walker((Node *) expr->args, false); } else if (IsA(node, BoolExpr)) @@ -1799,7 +1807,7 @@ find_nonnullable_vars_walker(Node *node, bool top_level) { ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; - if (is_strict_saop(expr, true)) + if (is_strict_saop(expr, top_level)) result = find_nonnullable_vars_walker((Node *) expr->args, false); } else if (IsA(node, BoolExpr)) From e46c2a65710f021e25bc0fcf404dd00c86aec1d7 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Wed, 29 Jul 2026 09:39:59 +0530 Subject: [PATCH 236/481] Avoid accumulating relation locks during sequence synchronization. While collecting the sequences to synchronize, the sequence sync worker opened each INIT sequence with RowExclusiveLock and held it until the transaction committed. With many such sequences, this could exhaust the shared lock table and fail with "out of shared memory". The worker only reads each sequence's identity (namespace and name) here and needs it to stay stable while read, for which AccessShareLock is enough, as it conflicts with the AccessExclusiveLock taken by DROP, RENAME, and SET SCHEMA. Take that lock instead and release it as soon as the identity is read. The later synchronization re-opens each sequence, so it does not rely on the lock being retained. Reported-by: Noah Misch Author: vignesh C Reviewed-by: Hayato Kuroda Reviewed-by: Amit Kapila Backpatch-through: 19, where it was introduced Discussion: https://postgr.es/m/20260710045217.f0.noahmisch@microsoft.com --- src/backend/replication/logical/sequencesync.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/backend/replication/logical/sequencesync.c b/src/backend/replication/logical/sequencesync.c index 40f0f1c6973..bd74a17d28b 100644 --- a/src/backend/replication/logical/sequencesync.c +++ b/src/backend/replication/logical/sequencesync.c @@ -752,7 +752,16 @@ LogicalRepSyncSequences(void) subrel = (Form_pg_subscription_rel) GETSTRUCT(tup); - sequence_rel = try_table_open(subrel->srrelid, RowExclusiveLock); + /* + * Lock the sequence so its identity (namespace and name) cannot + * change under us via a concurrent DROP, RENAME or SET SCHEMA. The + * lock is released immediately rathen than at the transaction end. + * The later synchronization does not depend on this captured identity + * remaining valid, as it re-opens the sequence and tolerates + * concurrent changes. Releasing early also avoids holding one lock + * per sequence, which could exhaust the lock table. + */ + sequence_rel = try_table_open(subrel->srrelid, AccessShareLock); /* Skip if sequence was dropped concurrently */ if (!sequence_rel) @@ -761,7 +770,7 @@ LogicalRepSyncSequences(void) /* Skip if the relation is not a sequence */ if (sequence_rel->rd_rel->relkind != RELKIND_SEQUENCE) { - table_close(sequence_rel, NoLock); + table_close(sequence_rel, AccessShareLock); continue; } @@ -779,7 +788,7 @@ LogicalRepSyncSequences(void) MemoryContextSwitchTo(oldctx); - table_close(sequence_rel, NoLock); + table_close(sequence_rel, AccessShareLock); } /* Cleanup */ From 16c3435794befad6499449cbd73696f6d3ca8e24 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 29 Jul 2026 17:39:40 +0900 Subject: [PATCH 237/481] Protect PGPROC lookup when terminating background workers TerminateBackgroundWorkersForDatabase() uses BackendPidGetProc() and, until now, accessed fields of the returned PGPROC after releasing ProcArrayLock, including its database OID. If the PGPROC slot is recycled during this window, the database OID being checked may belong to a different backend, causing an unrelated background worker to be terminated. Triggering this bug requires a very narrow race: the background worker identified by BackendPidGetProc() must exit, its PGPROC slot must be released and reused, and only then must TerminateBackgroundWorkersForDatabase() examine the database OID. TerminateBackgroundWorkersForDatabase() holds BackgroundWorkerLock, preventing parallel workers and dynamically registered workers (such as those created by worker_spi) from reusing the slot. As far as I know, the only plausible scenario is a static background worker that exits and is restarted quickly enough to reuse the same PGPROC slot within the race window. In practice, this race is extremely unlikely, still reachable in theory. Oversight in f1e251be80a0. Author: Chao Li Reviewed-by: Aya Iwata Reviewed-by: Haibo Yan Discussion: https://postgr.es/m/78E81763-EA1D-4788-9741-4092BCB997A5@gmail.com Backpatch-through: 19 --- src/backend/postmaster/bgworker.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 2e4acad4f00..4627f99dafb 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -1444,16 +1444,20 @@ TerminateBackgroundWorkersForDatabase(Oid databaseId) if (slot->in_use && (slot->worker.bgw_flags & BGWORKER_INTERRUPTIBLE)) { - PGPROC *proc = BackendPidGetProc(slot->pid); + PGPROC *proc; + pid_t pid = slot->pid; + LWLockAcquire(ProcArrayLock, LW_SHARED); + proc = BackendPidGetProcWithLock(pid); if (proc && proc->databaseId == databaseId) { slot->terminate = true; signal_postmaster = true; elog(DEBUG1, "termination requested for worker (PID %d) on database %u", - (int) slot->pid, databaseId); + (int) pid, databaseId); } + LWLockRelease(ProcArrayLock); } } From bef46aed394917be95f6572f64af90e24b1c0652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Wed, 29 Jul 2026 17:15:45 +0200 Subject: [PATCH 238/481] Fix cascading standby reconnect failure after archive fallback A cascading standby could fail to reconnect to its upstream standby with "requested starting point ... is ahead of the WAL flush position" after falling back to archive recovery. This happened because archive recovery processes whole segment files, so after replaying a segment the cascade's next read position lands at the start of the following segment, which is ahead of the upstream's flush position reported by GetStandbyFlushRecPtr() (still inside the just-replayed segment). Fix by having the walreceiver check the upstream's current WAL flush position via IDENTIFY_SYSTEM before issuing START_REPLICATION. IDENTIFY_SYSTEM already returns this position (as xlogpos), but walrcv_identify_system() previously discarded it; now we have a use for it. If the requested start point exceeds the upstream's flush position on the same timeline, the walreceiver waits for wal_retrieve_retry_interval and retries. The wait is limited to gaps of at most one WAL segment, which is the expected case from the segment-granularity of archive recovery. Larger gaps indicate the upstream is genuinely behind, so START_REPLICATION is allowed to proceed (and fail) normally, letting the startup process fall back to other WAL sources. The first wait is logged at LOG level; subsequent waits are demoted to DEBUG1 to avoid log noise. The walreceiver honors wal_receiver_timeout during the wait, so it will exit if the upstream doesn't catch up in time. To preserve ABI compatibility on back branches, the flush position from IDENTIFY_SYSTEM is communicated via a new global variable (WalRcvIdentifySystemLsn) rather than changing the signature of walrcv_identify_system(). The bug was introduced in Postgres 9.3 by commit abfd192b1b5b, which added a flush-position check in StartReplication() that rejects requests ahead of the upstream server's WAL flush position. Author: Marco Nenciarini Reviewed-by: Xuneng Zhou Backpatch-through: 14 Discussion: https://postgr.es/m/CA+nrD2cTuTkkX5WXVZengTYYZbAO6zV8K+Tri-R0fbLFuoyMBA@mail.gmail.com --- .../libpqwalreceiver/libpqwalreceiver.c | 21 ++- src/backend/replication/logical/worker.c | 2 +- src/backend/replication/walreceiver.c | 72 ++++++++- .../utils/activity/wait_event_names.txt | 1 + src/include/replication/walreceiver.h | 9 +- src/test/recovery/meson.build | 1 + src/test/recovery/t/055_cascade_reconnect.pl | 148 ++++++++++++++++++ 7 files changed, 247 insertions(+), 7 deletions(-) create mode 100644 src/test/recovery/t/055_cascade_reconnect.pl diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index b56f069a73b..331617f1c5b 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -63,7 +63,8 @@ static char *libpqrcv_get_conninfo(WalReceiverConn *conn); static void libpqrcv_get_senderinfo(WalReceiverConn *conn, char **sender_host, int *sender_port); static char *libpqrcv_identify_system(WalReceiverConn *conn, - TimeLineID *primary_tli); + TimeLineID *primary_tli, + XLogRecPtr *server_lsn); static char *libpqrcv_get_dbname_from_conninfo(const char *connInfo); static char *libpqrcv_get_option_from_conninfo(const char *connInfo, const char *keyword); @@ -421,7 +422,8 @@ libpqrcv_get_senderinfo(WalReceiverConn *conn, char **sender_host, * timeline ID of the primary. */ static char * -libpqrcv_identify_system(WalReceiverConn *conn, TimeLineID *primary_tli) +libpqrcv_identify_system(WalReceiverConn *conn, TimeLineID *primary_tli, + XLogRecPtr *server_lsn) { PGresult *res; char *primary_sysid; @@ -452,6 +454,21 @@ libpqrcv_identify_system(WalReceiverConn *conn, TimeLineID *primary_tli) PQntuples(res), PQnfields(res), 1, 3))); primary_sysid = pstrdup(PQgetvalue(res, 0, 0)); *primary_tli = pg_strtoint32(PQgetvalue(res, 0, 1)); + + /* Column 2 is the server's current WAL flush position */ + if (server_lsn) + { + uint32 hi, + lo; + + if (sscanf(PQgetvalue(res, 0, 2), "%X/%X", &hi, &lo) != 2) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("could not parse WAL location \"%s\"", + PQgetvalue(res, 0, 2)))); + *server_lsn = ((uint64) hi) << 32 | lo; + } + PQclear(res); return primary_sysid; diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index dba4d743cf5..3c4a0b907a4 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -5732,7 +5732,7 @@ run_apply_worker(void) * We don't really use the output identify_system for anything but it does * some initializations on the upstream so let's still call it. */ - (void) walrcv_identify_system(LogRepWorkerWalRcvConn, &startpointTLI); + (void) walrcv_identify_system(LogRepWorkerWalRcvConn, &startpointTLI, NULL); set_apply_error_context_origin(originname); diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 05e2f690fa7..7167c02d73d 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -54,6 +54,7 @@ #include "access/htup_details.h" #include "access/timeline.h" #include "access/transam.h" +#include "access/xlog.h" #include "access/xlog_internal.h" #include "access/xlogarchive.h" #include "access/xlogrecovery.h" @@ -161,6 +162,8 @@ WalReceiverMain(const void *startup_data, size_t startup_data_len) TimeLineID startpointTLI; TimeLineID primaryTLI; bool first_stream; + bool upstream_catchup_logged = false; + TimestampTz upstream_catchup_deadline = 0; WalRcvData *walrcv; TimestampTz now; char *err; @@ -318,13 +321,15 @@ WalReceiverMain(const void *startup_data, size_t startup_data_len) { char *primary_sysid; char standby_sysid[32]; + XLogRecPtr primaryFlushPtr; WalRcvStreamOptions options; /* * Check that we're connected to a valid server using the * IDENTIFY_SYSTEM replication command. */ - primary_sysid = walrcv_identify_system(wrconn, &primaryTLI); + primary_sysid = walrcv_identify_system(wrconn, &primaryTLI, + &primaryFlushPtr); snprintf(standby_sysid, sizeof(standby_sysid), UINT64_FORMAT, GetSystemIdentifier()); @@ -348,6 +353,71 @@ WalReceiverMain(const void *startup_data, size_t startup_data_len) errmsg("highest timeline %u of the primary is behind recovery timeline %u", primaryTLI, startpointTLI))); + /* + * If our requested startpoint is ahead of the upstream server's + * current WAL flush position, we cannot start streaming yet. (We say + * "upstream" here and not "primary" because this condition can only + * happen on a cascading standby.) This can happen when such a + * cascading standby has advanced past the upstream via archive + * recovery but the intermediate standby has not caught up with that + * yet. In this case, wait for the upstream to catch up before + * attempting START_REPLICATION, because that would fail with + * "requested starting point is ahead of the WAL flush position". + * + * We only perform this check when we're on the same timeline as the + * primary; when timelines differ, let START_REPLICATION handle the + * timeline negotiation. + * + * We also only wait if the gap is within one WAL segment. This is + * the expected case because archive recovery processes whole segment + * files: the cascade's next read position lands at the start of the + * following segment while the upstream's flush position is still + * inside the just-replayed one, producing at most a sub-segment gap. + * A larger gap means the upstream is genuinely behind, so we let + * START_REPLICATION fail normally and allow the startup process to + * fall back to other WAL sources. + * + * Honor wal_receiver_timeout so the walreceiver doesn't wait + * indefinitely: if the upstream hasn't caught up within the timeout, + * exit and let the startup process retry normally. + */ + if (startpointTLI == primaryTLI && + startpoint > primaryFlushPtr && + startpoint - primaryFlushPtr <= wal_segment_size) + { + /* Set deadline on first iteration */ + if (!upstream_catchup_logged && wal_receiver_timeout > 0) + upstream_catchup_deadline = + TimestampTzPlusMilliseconds(GetCurrentTimestamp(), + wal_receiver_timeout); + + ereport(upstream_catchup_logged ? DEBUG1 : LOG, + errmsg("walreceiver requested start point %X/%08X on timeline %u is ahead of the upstream server's flush position %X/%08X, waiting", + LSN_FORMAT_ARGS(startpoint), startpointTLI, + LSN_FORMAT_ARGS(primaryFlushPtr))); + upstream_catchup_logged = true; + + (void) WaitLatch(MyLatch, + WL_EXIT_ON_PM_DEATH | WL_TIMEOUT | WL_LATCH_SET, + wal_retrieve_retry_interval, + WAIT_EVENT_WAL_RECEIVER_UPSTREAM_CATCHUP); + ResetLatch(MyLatch); + + if (upstream_catchup_deadline > 0 && + GetCurrentTimestamp() >= upstream_catchup_deadline) + ereport(ERROR, + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("terminating walreceiver due to timeout while waiting for upstream to catch up"))); + + CHECK_FOR_INTERRUPTS(); + continue; + } + else + { + upstream_catchup_logged = false; + upstream_catchup_deadline = 0; + } + /* * Get any missing history files. We do this always, even when we're * not interested in that timeline, so that if we're promoted to diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt index 1016502d042..256b3a3c02e 100644 --- a/src/backend/utils/activity/wait_event_names.txt +++ b/src/backend/utils/activity/wait_event_names.txt @@ -163,6 +163,7 @@ WAIT_FOR_WAL_FLUSH "Waiting for WAL flush to reach a target LSN on a primary or WAIT_FOR_WAL_REPLAY "Waiting for WAL replay to reach a target LSN on a standby." WAIT_FOR_WAL_WRITE "Waiting for WAL write to reach a target LSN on a standby." WAL_RECEIVER_EXIT "Waiting for the WAL receiver to exit." +WAL_RECEIVER_UPSTREAM_CATCHUP "Waiting for upstream server WAL flush position to catch up to requested start point." WAL_RECEIVER_WAIT_START "Waiting for startup process to send initial data for streaming replication." WAL_SUMMARY_READY "Waiting for a new WAL summary to be generated." XACT_GROUP_UPDATE "Waiting for the group leader to update transaction status at transaction end." diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h index 47c07574d4d..80a78720a93 100644 --- a/src/include/replication/walreceiver.h +++ b/src/include/replication/walreceiver.h @@ -280,9 +280,12 @@ typedef void (*walrcv_get_senderinfo_fn) (WalReceiverConn *conn, * Run IDENTIFY_SYSTEM on the cluster connected to and validate the * identity of the cluster. Returns the system ID of the cluster * connected to. 'primary_tli' is the timeline ID of the sender. + * If 'server_lsn' is not NULL, it is set to the current WAL flush + * position of the sender. */ typedef char *(*walrcv_identify_system_fn) (WalReceiverConn *conn, - TimeLineID *primary_tli); + TimeLineID *primary_tli, + XLogRecPtr *server_lsn); /* * walrcv_get_dbname_from_conninfo_fn @@ -441,8 +444,8 @@ extern PGDLLIMPORT WalReceiverFunctionsType *WalReceiverFunctions; WalReceiverFunctions->walrcv_get_conninfo(conn) #define walrcv_get_senderinfo(conn, sender_host, sender_port) \ WalReceiverFunctions->walrcv_get_senderinfo(conn, sender_host, sender_port) -#define walrcv_identify_system(conn, primary_tli) \ - WalReceiverFunctions->walrcv_identify_system(conn, primary_tli) +#define walrcv_identify_system(conn, primary_tli, server_lsn) \ + WalReceiverFunctions->walrcv_identify_system(conn, primary_tli, server_lsn) #define walrcv_get_dbname_from_conninfo(conninfo) \ WalReceiverFunctions->walrcv_get_dbname_from_conninfo(conninfo) #define walrcv_server_version(conn) \ diff --git a/src/test/recovery/meson.build b/src/test/recovery/meson.build index ad0d85f4189..39ec8c4946d 100644 --- a/src/test/recovery/meson.build +++ b/src/test/recovery/meson.build @@ -63,6 +63,7 @@ tests += { 't/052_checkpoint_segment_missing.pl', 't/053_standby_login_event_trigger.pl', 't/054_unlogged_sequence_promotion.pl', + 't/055_cascade_reconnect.pl', ], }, } diff --git a/src/test/recovery/t/055_cascade_reconnect.pl b/src/test/recovery/t/055_cascade_reconnect.pl new file mode 100644 index 00000000000..051a3292533 --- /dev/null +++ b/src/test/recovery/t/055_cascade_reconnect.pl @@ -0,0 +1,148 @@ +# Copyright (c) 2026, PostgreSQL Global Development Group + +# Test that a cascading standby can reconnect to its upstream standby after +# advancing past the upstream's WAL flush position via archive recovery. +# +# Setup: praline -> samurai -> stubble +# stubble has both streaming (from samurai) and restore_command +# (from praline's archive). +# +# When samurai's walreceiver is stopped and stubble falls back to +# archive recovery, stubble may advance its recovery position past +# samurai's replay position. Previously, stubble's walreceiver +# would fail with "requested starting point is ahead of the WAL flush +# position" when reconnecting to samurai. + +use strict; +use warnings FATAL => 'all'; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +# Initialize praline with archiving +my $praline = PostgreSQL::Test::Cluster->new('praline'); +$praline->init(allows_streaming => 1, has_archiving => 1); +$praline->append_conf( + 'postgresql.conf', qq( +wal_keep_size = 128MB +checkpoint_timeout = 1h +)); +$praline->start; + +# Take backup and create samurai (streaming from praline, no archive) +my $backup_name = 'my_backup'; +$praline->backup($backup_name); + +my $samurai = PostgreSQL::Test::Cluster->new('samurai'); +$samurai->init_from_backup($praline, $backup_name, has_streaming => 1); +$samurai->start; + +# Wait for samurai to start streaming +$praline->wait_for_catchup($samurai); + +# Take backup from samurai and create stubble +# stubble streams from samurai AND restores from praline's archive +$samurai->backup($backup_name); + +my $stubble = PostgreSQL::Test::Cluster->new('stubble'); +$stubble->init_from_backup($samurai, $backup_name, has_streaming => 1); +$stubble->enable_restoring($praline); +$stubble->start; + +# Generate initial data and wait for full cascade replication +$praline->safe_psql('postgres', + "CREATE TABLE test_tab AS SELECT generate_series(1, 1000) AS id"); +$praline->wait_for_replay_catchup($samurai); +$samurai->wait_for_replay_catchup($stubble, $praline); + +my $result = $stubble->safe_psql('postgres', "SELECT count(*) FROM test_tab"); +is($result, '1000', 'initial data replicated to stubble'); + +# Disconnect samurai from praline by clearing primary_conninfo. +# This stops samurai's walreceiver, so samurai can no longer receive +# new WAL. Its GetStandbyFlushRecPtr() will return only replayPtr. +$samurai->append_conf('postgresql.conf', "primary_conninfo = ''"); +$samurai->reload; + +# Wait for samurai's walreceiver to stop +$samurai->poll_query_until('postgres', + "SELECT NOT EXISTS (SELECT 1 FROM pg_stat_wal_receiver)") + or die "Timed out waiting for samurai walreceiver to stop"; + +# Stop stubble cleanly. We'll restart it after generating new WAL +# so it enters the recovery state machine fresh and tries archive first. +$stubble->stop; + +# Force a checkpoint now so that no background checkpoint can generate +# extra WAL during the INSERT below and push it across a segment boundary. +# Combined with checkpoint_timeout = 1h this ensures the new WAL fits +# within a single segment, keeping the gap within wal_segment_size. +$praline->safe_psql('postgres', "CHECKPOINT"); + +# Generate more WAL on praline +$praline->safe_psql('postgres', + "INSERT INTO test_tab SELECT generate_series(1001, 2000)"); + +# Force WAL switch and wait for archiving to complete, so that +# stubble can find the new WAL in the archive when it starts. +my $walfile = $praline->safe_psql('postgres', + "SELECT pg_walfile_name(pg_current_wal_lsn())"); +$praline->safe_psql('postgres', "SELECT pg_switch_wal()"); +$praline->poll_query_until('postgres', + "SELECT '$walfile' <= last_archived_wal FROM pg_stat_archiver") + or die "Timed out waiting for WAL archiving"; + +# Rotate stubble's log so we can check just the new log output +$stubble->rotate_logfile; +my $stubble_log_offset = -s $stubble->logfile; + +# Start stubble. It will: +# 1. Read new WAL from praline's archive (XLOG_FROM_ARCHIVE) +# 2. Advance RecPtr past samurai's replay position +# 3. Try streaming from samurai (XLOG_FROM_STREAM) +# 4. detect that upstream is behind via +# IDENTIFY_SYSTEM and wait instead of failing +$stubble->start; + +# Wait for stubble to replay the new data from archive +$stubble->poll_query_until('postgres', + "SELECT count(*) >= 2000 FROM test_tab") + or die "Timed out waiting for stubble to replay archived WAL"; + +$result = $stubble->safe_psql('postgres', "SELECT count(*) FROM test_tab"); +is($result, '2000', 'stubble replayed new data from archive'); + +# Wait for walreceiver to hit the upstream-catchup wait event, proving we +# exercised the START_REPLICATION-ahead-of-upstream path. +$stubble->wait_for_event('walreceiver', 'WalReceiverUpstreamCatchup'); + +# Verify no errors occurred in stubble. +my $stubble_loglines = + PostgreSQL::Test::Utils::slurp_file($stubble->logfile, $stubble_log_offset); +ok( $stubble_loglines !~ m/ERROR/, 'no errors in stubble log'); + +# Now restore samurai's streaming from praline so it can catch up +$samurai->enable_streaming($praline); +$samurai->reload; + +# Wait for samurai to catch up with praline +$praline->wait_for_replay_catchup($samurai); + +# stubble's walreceiver should eventually connect to samurai and +# resume streaming (once samurai has caught up past stubble's position) +$samurai->poll_query_until('postgres', + "SELECT EXISTS (SELECT 1 FROM pg_stat_replication)") + or die "Timed out waiting for stubble to reconnect to samurai"; + +# Verify end-to-end cascade streaming works with new data +$praline->safe_psql('postgres', + "INSERT INTO test_tab SELECT generate_series(2001, 3000)"); +$praline->wait_for_replay_catchup($samurai); +$samurai->wait_for_replay_catchup($stubble, $praline); + +$result = $stubble->safe_psql('postgres', "SELECT count(*) FROM test_tab"); +is($result, '3000', + 'cascade streaming resumes normally after upstream catches up'); + +done_testing(); From 4ee0ccfd55f973160a2ab013bc96488715221270 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Wed, 29 Jul 2026 09:52:10 -0700 Subject: [PATCH 239/481] Fix stale comment in parallel_vacuum_main(). The comment claimed that a parallel vacuum worker has only the PROC_IN_VACUUM flag because parallel vacuum is not supported for autovacuum, but commit 1ff3180ca01 allowed autovacuum to use parallel vacuum workers. The assertion itself still holds: the leader, whether a backend running VACUUM or an autovacuum worker, sets PROC_IN_VACUUM before taking its snapshot, and a parallel worker inherits the flag when importing the leader's snapshot. The leader's other flags don't reach the worker, since the snapshot import copies only the PROC_XMIN_FLAGS bits and PROC_IS_AUTOVACUUM is never set on parallel workers, which run as regular background workers. Reword the comment to explain that. Oversight in commit 1ff3180ca01. Author: Bharath Rupireddy Reviewed-by: Masahiko Sawada Reviewed-by: Chao Li Discussion: https://postgr.es/m/CALj2ACVwQ4WABqq8Lnf+VZEJ45jcTFhyFLFr_ctfS4=QLL-r5w@mail.gmail.com Backpatch-through: 19 --- src/backend/commands/vacuumparallel.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index 41cefcfde54..dd355a3d246 100644 --- a/src/backend/commands/vacuumparallel.c +++ b/src/backend/commands/vacuumparallel.c @@ -1209,8 +1209,16 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) ErrorContextCallback errcallback; /* - * A parallel vacuum worker must have only PROC_IN_VACUUM flag since we - * don't support parallel vacuum for autovacuum as of now. + * A parallel vacuum worker carries only the PROC_IN_VACUUM flag. The + * leader, whether it's a backend running a VACUUM command or an + * autovacuum worker, sets PROC_IN_VACUUM when it starts vacuuming the + * table, and the worker inherits the flag by importing the leader's + * snapshot (see ProcArrayInstallRestoredXmin). The leader's other flags + * don't reach the worker: the snapshot import copies only the + * PROC_XMIN_FLAGS bits, so PROC_VACUUM_FOR_WRAPAROUND isn't carried + * over, and PROC_IS_AUTOVACUUM is never set on the worker in the first + * place since parallel workers run as regular background workers, not + * autovacuum workers. */ Assert(MyProc->statusFlags == PROC_IN_VACUUM); From bc90a53455836a61c4282073866325d3c14954d5 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 29 Jul 2026 14:20:35 -0400 Subject: [PATCH 240/481] doc: remove added space within synopsis replaceable tags Restructuring the tags makes the output consistent and doesn't require added spaces. Reported-by: Peter Smith Author: Peter Smith Discussion: https://postgr.es/m/CAHut+Pu8JahGm76CMdpzH350pHJedA4R2b8JmOim3+m3yxft3Q@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/ref/initdb.sgml | 6 +++--- doc/src/sgml/ref/pg_checksums.sgml | 4 ++-- doc/src/sgml/ref/pg_controldata.sgml | 4 ++-- doc/src/sgml/ref/pg_createsubscriber.sgml | 10 +++++++--- doc/src/sgml/ref/pg_resetwal.sgml | 24 +++++++++++++---------- doc/src/sgml/ref/pg_rewind.sgml | 10 ++++++---- 6 files changed, 34 insertions(+), 24 deletions(-) diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml index bd0dbff8caa..5e3f8dd0076 100644 --- a/doc/src/sgml/ref/initdb.sgml +++ b/doc/src/sgml/ref/initdb.sgml @@ -23,13 +23,13 @@ PostgreSQL documentation initdb option - + - datadir - + datadir + diff --git a/doc/src/sgml/ref/pg_checksums.sgml b/doc/src/sgml/ref/pg_checksums.sgml index 8a18f447d15..ae66fad3f0f 100644 --- a/doc/src/sgml/ref/pg_checksums.sgml +++ b/doc/src/sgml/ref/pg_checksums.sgml @@ -23,13 +23,13 @@ PostgreSQL documentation pg_checksums option - + datadir - + diff --git a/doc/src/sgml/ref/pg_controldata.sgml b/doc/src/sgml/ref/pg_controldata.sgml index 22dc6161008..580a6a3641f 100644 --- a/doc/src/sgml/ref/pg_controldata.sgml +++ b/doc/src/sgml/ref/pg_controldata.sgml @@ -23,13 +23,13 @@ PostgreSQL documentation pg_controldata option - + datadir - + diff --git a/doc/src/sgml/ref/pg_createsubscriber.sgml b/doc/src/sgml/ref/pg_createsubscriber.sgml index 3b3038d1891..193f60628bc 100644 --- a/doc/src/sgml/ref/pg_createsubscriber.sgml +++ b/doc/src/sgml/ref/pg_createsubscriber.sgml @@ -23,23 +23,27 @@ PostgreSQL documentation pg_createsubscriber option - + dbname + + - + datadir + + connstr - + diff --git a/doc/src/sgml/ref/pg_resetwal.sgml b/doc/src/sgml/ref/pg_resetwal.sgml index 41f2b1d480c..664c525f481 100644 --- a/doc/src/sgml/ref/pg_resetwal.sgml +++ b/doc/src/sgml/ref/pg_resetwal.sgml @@ -22,22 +22,26 @@ PostgreSQL documentation pg_resetwal - - - - - - - - + + + + + + + + + + + + option - + datadir - + diff --git a/doc/src/sgml/ref/pg_rewind.sgml b/doc/src/sgml/ref/pg_rewind.sgml index f704dc108e6..b95e3868e9d 100644 --- a/doc/src/sgml/ref/pg_rewind.sgml +++ b/doc/src/sgml/ref/pg_rewind.sgml @@ -23,17 +23,19 @@ PostgreSQL documentation pg_rewind option - + - datadir - + datadir + + + - + From 55c81430af1c70d5ed250f320f82e31d9a3e63e0 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Wed, 29 Jul 2026 21:51:46 +0200 Subject: [PATCH 241/481] doc: Add a note that refint will be removed in v20 refint has been removed from the spi contrib module in v20. Add a note to the documentation of the still-supported back branches so that users are aware the module is going away. Author: Ayush Tiwari Reported-by: Daniel Gustafsson Discussion: https://postgr.es/m/CAJTYsWUHq8Ohc6-N-xamOPYz-q3qUYMtwQX-1=Zi=5N1Q_GSEQ@mail.gmail.com Backpatch-through: 14 --- doc/src/sgml/contrib-spi.sgml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/contrib-spi.sgml b/doc/src/sgml/contrib-spi.sgml index 7e4e580bc74..9f397aeaddf 100644 --- a/doc/src/sgml/contrib-spi.sgml +++ b/doc/src/sgml/contrib-spi.sgml @@ -31,7 +31,8 @@ check_primary_key() and check_foreign_key() are used to check foreign key constraints. (This functionality is long since superseded by the built-in foreign - key mechanism, of course, but the module is still useful as an example.) + key mechanism, of course, but the module is still useful as an example. + This module will be removed in PostgreSQL 20.) From 33cffe591deebb873bc7b97a5f5d10eda9d219ae Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Thu, 30 Jul 2026 11:49:33 +0530 Subject: [PATCH 242/481] Skip SUBSCRIPTION TABLE TOC entries with --no-subscriptions. pg_dump in --binary-upgrade mode emits "SUBSCRIPTION TABLE" TOC entries to preserve pg_subscription_rel state across pg_upgrade. When such a dump was restored with --no-subscriptions, _tocEntryRequired() skipped the "SUBSCRIPTION" entry but not the associated "SUBSCRIPTION TABLE" entries, so the restore would try to apply subscription-relation state for a subscription that was never created. Skip "SUBSCRIPTION TABLE" entries as well when no_subscriptions is set. This can happen when pg_subscription_rel has entries, the dump is taken with --binary-upgrade, and it is restored with --no-subscriptions. Reported-by: Hayato Kuroda Author: Hayato Kuroda Reviewed-by: Shlok Kyal Reviewed-by: Amit Kapila Backpatch-through: 17, where it was introduced Discussion: https://postgr.es/m/OS9PR01MB121493DA4C1A7748B11A646D8F5C02@OS9PR01MB12149.jpnprd01.prod.outlook.com --- src/bin/pg_dump/pg_backup_archiver.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 46f4c518347..63313e5297e 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -3095,7 +3095,9 @@ _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH) } /* If it's a subscription, maybe ignore it */ - if (ropt->no_subscriptions && strcmp(te->desc, "SUBSCRIPTION") == 0) + if (ropt->no_subscriptions && + (strcmp(te->desc, "SUBSCRIPTION") == 0 || + strcmp(te->desc, "SUBSCRIPTION TABLE") == 0)) return 0; /* Ignore it if section is not to be dumped/restored */ From b1aeda3ec939c2867e5c3eb4ee7e1bae4768503e Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Thu, 30 Jul 2026 09:26:07 +0200 Subject: [PATCH 243/481] pgindent fix for 4ee0ccfd --- src/backend/commands/vacuumparallel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index dd355a3d246..767d162e578 100644 --- a/src/backend/commands/vacuumparallel.c +++ b/src/backend/commands/vacuumparallel.c @@ -1215,9 +1215,9 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) * table, and the worker inherits the flag by importing the leader's * snapshot (see ProcArrayInstallRestoredXmin). The leader's other flags * don't reach the worker: the snapshot import copies only the - * PROC_XMIN_FLAGS bits, so PROC_VACUUM_FOR_WRAPAROUND isn't carried - * over, and PROC_IS_AUTOVACUUM is never set on the worker in the first - * place since parallel workers run as regular background workers, not + * PROC_XMIN_FLAGS bits, so PROC_VACUUM_FOR_WRAPAROUND isn't carried over, + * and PROC_IS_AUTOVACUUM is never set on the worker in the first place + * since parallel workers run as regular background workers, not * autovacuum workers. */ Assert(MyProc->statusFlags == PROC_IN_VACUUM); From 6d38b535d6f5789ef604ea4147825cf07bd127e3 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Thu, 30 Jul 2026 09:30:53 +0200 Subject: [PATCH 244/481] Add previous commit to .git-blame-ignore-revs --- .git-blame-ignore-revs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 4d8f98d953b..8d94034e79b 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -14,6 +14,9 @@ # # $ git log --pretty=format:"%H # %cd%n# %s" $PGINDENTGITHASH -1 --date=iso +b1aeda3ec939c2867e5c3eb4ee7e1bae4768503e # 2026-07-30 09:26:07 +0200 +# pgindent fix for 4ee0ccfd + 99e44c3181c779ae0f3539ba7f408661983fbf8e # 2026-06-29 15:27:44 -0400 # Run pgperltidy From b835cdba9aa96cc338ba8d9dc979a29b48fca88f Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Thu, 30 Jul 2026 12:41:40 +0200 Subject: [PATCH 245/481] Make sure to detach injection points for re-attaching The new test for enabling data checksums with concurrent CREATE DATABASE calls use the same injection points as a previous test but accidentally missed detaching the injection point first. Fix by detaching the injection point in the PG_TEST_EXTRA SKIP block to make it can be reused. Pointed out by buildfarm member porpoise which failed with: die: error running SQL: 'psql::1: ERROR: injection point "datachecksumsworker-fake-temptable-wait" already defined' Backpatch to v19 where online checksums were introduced. Author: Daniel Gustafsson Reported-by: Buildfarm member porpoise Reviewed-by: Jonathan Gonzalez V. Discussion: https://postgr.es/m/28CF6FD9-E1C4-4C04-8270-E3305AC46171@yesql.se Backpatch-through: 19 --- src/test/modules/test_checksums/t/005_injection.pl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/modules/test_checksums/t/005_injection.pl b/src/test/modules/test_checksums/t/005_injection.pl index 34cd47e6c81..2387e4399ba 100644 --- a/src/test/modules/test_checksums/t/005_injection.pl +++ b/src/test/modules/test_checksums/t/005_injection.pl @@ -74,6 +74,9 @@ "SELECT injection_points_attach('datachecksumsworker-fake-temptable-wait', 'notice');" ); enable_data_checksums($node, wait => 'on'); + $node->safe_psql('postgres', + "SELECT injection_points_detach('datachecksumsworker-fake-temptable-wait');" + ); } # --------------------------------------------------------------------------- From 5707d7517fa893f6d36b0e4a1173ee71699ada48 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Thu, 30 Jul 2026 14:06:20 +0200 Subject: [PATCH 246/481] Initialize bs_reltuples in parallel GIN builds Index builds update pg_class.reltuples for the table. In parallel GIN builds, workers track the number of processed rows, and report it to the leader, who then updates the pg_class with a total. However, gin_parallel_build_main failed to initialize the bs_reltuples field, leaving it set to whatever happens to be on the stack (which may be bogus values like Infinity or NaN, or just impossibly high values). If such values get reported to the leader and stored in pg_class, that can have serious consequences. The pg_class.reltuples field is used to decide when a table is due for autovacuum or autoanalyze, and if it happens to be set to a bogus value, that may never happen. The field is also used by the optimizer when calculating costs. Fixed by initializing bs_reltuples together with the rest of the build state. The bs_numtuples was initialized later, but it seems cleaner to just initialize all the fields at once. After a bogus value gets persisted in pg_class, affected systems are unlikely to self-heal. That would require an ANALYZE, but preventing that is one of the consequences. We have considered forcing autoanalyze in these cases, but there's not a good way to reliably identify bogus values (except for a small minority like Infitiny/NaN). A manual ANALYZE on (possibly) affected tables is the only solution. Backpatch to 18, where parallel GIN builds were introduced. Reported-by: Jan Nidzwetzki Discussion: https://postgr.es/m/518BA772-8026-412A-AA8F-A7FE4C6B3717@planetscale.com Backpatch-through: 18 --- src/backend/access/gin/gininsert.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index cb9ed3b563c..16abb76c001 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -1875,9 +1875,6 @@ _gin_process_worker_data(GinBuildState *state, Tuplesortstate *worker_sort, tuplesort_performsort(state->bs_worker_sort); - /* reset the number of GIN tuples produced by this worker */ - state->bs_numtuples = 0; - if (progress) pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, PROGRESS_GIN_PHASE_MERGE_1); @@ -2158,6 +2155,11 @@ _gin_parallel_build_main(dsm_segment *seg, shm_toc *toc) /* initialize the GIN build state */ initGinState(&buildstate.ginstate, indexRel); buildstate.indtuples = 0; + + /* Initialize counters used to report tuple counts to the leader */ + buildstate.bs_numtuples = 0; + buildstate.bs_reltuples = 0; + memset(&buildstate.buildStats, 0, sizeof(GinStatsData)); memset(&buildstate.tid, 0, sizeof(ItemPointerData)); From 068447dcd9d7def7b58531078d167c280d9d1861 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Thu, 30 Jul 2026 15:30:19 +0200 Subject: [PATCH 247/481] Reject non-finite reltuples when restoring stats When restoring relation stats, pg_restore_relation_stats() rejected calls with (reltuples < -1.0). But that is insufficient - Infinity and NaN values both pass that check, and get stored in pg_class verbatim. This can have various undesirable consequences. Fixed by rejecting non-finite reltuple values, in the same non-fatal way as for the existing checks (emit WARNING and skip the update). Adds a regression test to stats_import for these non-finite values, and to check the -1.0 special value is still accepted. Backpatch to 18, where pg_restore_relation_stats() was introduced. Patch by Jan Nidzwetzki, minor commit message tweaks by me. Author: Jan Nidzwetzki Discussion: https://postgr.es/m/518BA772-8026-412A-AA8F-A7FE4C6B3717@planetscale.com Backpatch-through: 18 --- src/backend/statistics/relation_stats.c | 11 ++- src/test/regress/expected/stats_import.out | 79 ++++++++++++++++++++++ src/test/regress/sql/stats_import.sql | 43 ++++++++++++ 3 files changed, 132 insertions(+), 1 deletion(-) diff --git a/src/backend/statistics/relation_stats.c b/src/backend/statistics/relation_stats.c index fbaab92284f..9de5d64c384 100644 --- a/src/backend/statistics/relation_stats.c +++ b/src/backend/statistics/relation_stats.c @@ -17,6 +17,8 @@ #include "postgres.h" +#include + #include "access/heapam.h" #include "catalog/indexing.h" #include "catalog/namespace.h" @@ -123,7 +125,14 @@ relation_statistics_update_internal(Oid reloid, FunctionCallInfo fcinfo) if (!PG_ARGISNULL(RELTUPLES_ARG)) { reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG); - if (reltuples < -1.0) + if (isnan(reltuples) || isinf(reltuples)) + { + ereport(WARNING, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("argument \"%s\" must be a finite value", "reltuples"))); + result = false; + } + else if (reltuples < -1.0) { ereport(WARNING, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out index dabf9ba1cd8..fa086195e65 100644 --- a/src/test/regress/expected/stats_import.out +++ b/src/test/regress/expected/stats_import.out @@ -440,6 +440,85 @@ WHERE oid = 'stats_import.test'::regclass; 16 | 500 | 4 | 2 (1 row) +-- error: reltuples must be finite (rejected with WARNING, returns false) +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', 'Infinity'::real); +WARNING: argument "reltuples" must be a finite value + pg_restore_relation_stats +--------------------------- + f +(1 row) + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', '-Infinity'::real); +WARNING: argument "reltuples" must be a finite value + pg_restore_relation_stats +--------------------------- + f +(1 row) + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', 'NaN'::real); +WARNING: argument "reltuples" must be a finite value + pg_restore_relation_stats +--------------------------- + f +(1 row) + +-- error: reltuples must not be less than -1.0 (rejected with WARNING, returns false) +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', '-5'::real); +WARNING: argument "reltuples" must not be less than -1.0 + pg_restore_relation_stats +--------------------------- + f +(1 row) + +-- reltuples is unchanged (still 500) after the rejected values above +SELECT relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + relpages | reltuples | relallvisible | relallfrozen +----------+-----------+---------------+-------------- + 16 | 500 | 4 | 2 +(1 row) + +-- ok: -1 (the "unknown" sentinel) is still accepted +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', '-1'::real); + pg_restore_relation_stats +--------------------------- + t +(1 row) + +SELECT relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + relpages | reltuples | relallvisible | relallfrozen +----------+-----------+---------------+-------------- + 16 | -1 | 4 | 2 +(1 row) + +-- restore reltuples to 500 for the following tests +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', '500'::real); + pg_restore_relation_stats +--------------------------- + t +(1 row) + -- ok: set just relallvisible, rest stay same SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql index 58140315efb..812a8335e6b 100644 --- a/src/test/regress/sql/stats_import.sql +++ b/src/test/regress/sql/stats_import.sql @@ -365,6 +365,49 @@ SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class WHERE oid = 'stats_import.test'::regclass; +-- error: reltuples must be finite (rejected with WARNING, returns false) +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', 'Infinity'::real); + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', '-Infinity'::real); + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', 'NaN'::real); + +-- error: reltuples must not be less than -1.0 (rejected with WARNING, returns false) +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', '-5'::real); + +-- reltuples is unchanged (still 500) after the rejected values above +SELECT relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + +-- ok: -1 (the "unknown" sentinel) is still accepted +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', '-1'::real); + +SELECT relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + +-- restore reltuples to 500 for the following tests +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', '500'::real); + -- ok: set just relallvisible, rest stay same SELECT pg_restore_relation_stats( 'schemaname', 'stats_import', From 6a80179f6b09a6c71a48e864cc4e85f3ea2f4e3c Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 30 Jul 2026 12:47:08 -0700 Subject: [PATCH 248/481] Fix races between deactivation of logical decoding and slot creation. On standbys, logical decoding can be deactivated while a logical slot is being created: either by replaying an XLOG_LOGICAL_DECODING_STATUS_CHANGE record, or by the end-of-recovery transition upon promotion, which deactivates logical decoding if no valid logical slot exists. Both could interleave with a check of the logical decoding status performed before creating a new slot because the slot invalidation executed as part of the deactivation cannot find a slot being created. For regular slot creation on standbys, EnsureLogicalDecodingEnabled() assumed that logical decoding must still be enabled during recovery since the caller had already checked it, tripping an assertion failure if a concurrent deactivation interleaved. For slot synchronization, the local slot could be created and persisted based on the remote slot information fetched before the deactivation was replayed, leaving a valid slot whose restart_lsn precedes the deactivation. Fix both paths by re-checking the logical decoding status after the new slot has been created: regular slot creation raises an error, and slot synchronization skips persisting the slot. If the deactivation happens after the re-check instead, it is guaranteed to invalidate the newly created slot. Reviewed-by: Srinath Reddy Sadipiralla Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/CAD21AoDEB99VtNbQdDrNd=1gQupJNGMfW_5kdnxq03Q82EK3ag@mail.gmail.com Backpatch-through: 19 --- src/backend/replication/logical/logicalctl.c | 62 +++++-- src/backend/replication/logical/slotsync.c | 36 ++++ src/backend/replication/slot.c | 2 + src/backend/replication/slotfuncs.c | 11 +- src/backend/replication/walsender.c | 4 +- .../recovery/t/051_effective_wal_level.pl | 161 ++++++++++++++++++ 6 files changed, 261 insertions(+), 15 deletions(-) diff --git a/src/backend/replication/logical/logicalctl.c b/src/backend/replication/logical/logicalctl.c index 4a690a631da..e5340880fa7 100644 --- a/src/backend/replication/logical/logicalctl.c +++ b/src/backend/replication/logical/logicalctl.c @@ -274,11 +274,10 @@ abort_logical_decoding_activation(int code, Datum arg) /* * Enable logical decoding if disabled. * - * If this function is called during recovery, it simply returns without - * action since the logical decoding status change is not allowed during - * this time. The logical decoding status depends on the status on the primary. - * The caller should use CheckLogicalDecodingRequirements() before calling this - * function to make sure that the logical decoding status can be modified. + * If this function is called during recovery, it just checks that logical + * decoding is still enabled, since the logical decoding status cannot be + * changed during this time. The logical decoding status depends on the + * status on the primary. * * Note that there is no interlock between logical decoding activation * and slot creation. To ensure enabling logical decoding, the caller @@ -298,11 +297,30 @@ EnsureLogicalDecodingEnabled(void) if (RecoveryInProgress()) { /* - * CheckLogicalDecodingRequirements() must have already errored out if - * logical decoding is not enabled since we cannot enable the logical - * decoding status during recovery. + * The caller has already checked that logical decoding is enabled via + * CheckLogicalDecodingRequirements(), but the status could have been + * disabled concurrently before we created our slot: either by + * replaying an XLOG_LOGICAL_DECODING_STATUS_CHANGE record, or by + * UpdateLogicalDecodingStatusEndOfRecovery() upon promotion. We + * cannot enable logical decoding during recovery, so raise an error. + * + * Our slot has already been created, so its in_use flag is set and + * the slot scans performed by a deactivation can see it. It + * guarantees that this check doesn't miss a concurrent deactivation: + * UpdateLogicalDecodingStatusEndOfRecovery() won't disable logical + * decoding since CheckLogicalSlotExists() finds our valid slot, and + * replaying a status change record after this check invalidates our + * slot, so this slot creation fails afterwards anyway (by a recovery + * conflict or the requirement re-check in + * CreateInitDecodingContext()). Hence, this check only needs to catch + * deactivations that completed before our slot's in_use flag was set. */ - Assert(IsLogicalDecodingEnabled()); + if (!IsLogicalDecodingEnabled()) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("logical decoding on standby requires \"effective_wal_level\" >= \"logical\" on the primary"), + errdetail("Logical decoding was concurrently disabled during the logical replication slot creation."))); + return; } @@ -429,6 +447,11 @@ EnableLogicalDecoding(void) * * Note that this function does not verify whether logical slots exist. The * checkpointer will verify if logical decoding should actually be disabled. + * + * This may be called during recovery, for example when a standby invalidates + * its last valid logical slot. That is safe because the queued request is only + * acted upon outside recovery. See the RecoveryInProgress() check in + * DisableLogicalDecodingIfNecessary(). */ void RequestDisableLogicalDecoding(void) @@ -471,6 +494,14 @@ DisableLogicalDecodingIfNecessary(void) */ Assert(!MyReplicationSlot); + /* + * During recovery the logical decoding status follows the primary via WAL + * replay, so we must not disable it here. A pending_disable request + * queued during recovery, for example by a local slot invalidation, is + * intentionally left for the end-of-recovery transition or the + * post-promotion checkpointer to act on. See + * UpdateLogicalDecodingStatusEndOfRecovery(). + */ if (RecoveryInProgress()) return; @@ -602,10 +633,15 @@ UpdateLogicalDecodingStatusEndOfRecovery(void) * already occur due to the checkpointer's asynchronous deactivation * process. * - * For 'disable' case, backend cannot create logical replication slots - * during recovery (see checks in CheckLogicalDecodingRequirements()), - * which prevents a race condition between disabling logical decoding and - * concurrent slot creation. + * For 'disable' case, a backend concurrently creating a logical slot on a + * standby could have passed its CheckLogicalDecodingRequirements() check + * when creating its slot only after our slot check above. Such a backend + * rechecks the status after creating the slot in + * EnsureLogicalDecodingEnabled() and raises an error if logical decoding + * has been disabled meanwhile, so it cannot end up with a logical slot + * while logical decoding remains disabled. (If recovery has already ended + * by the time of the recheck, the backend instead enables logical + * decoding by itself, which is fine after promotion.) */ if (new_status != LogicalDecodingCtl->logical_decoding_enabled) { diff --git a/src/backend/replication/logical/slotsync.c b/src/backend/replication/logical/slotsync.c index 05637344363..c184cdf1c17 100644 --- a/src/backend/replication/logical/slotsync.c +++ b/src/backend/replication/logical/slotsync.c @@ -67,6 +67,7 @@ #include "pgstat.h" #include "postmaster/interrupt.h" #include "replication/logical.h" +#include "replication/logicalctl.h" #include "replication/slotsync.h" #include "replication/snapbuild.h" #include "storage/ipc.h" @@ -708,6 +709,41 @@ update_and_persist_local_synced_slot(RemoteSlot *remote_slot, Oid remote_dbid, return false; } + /* + * Do not persist the slot if logical decoding got disabled concurrently. + * This can happen if the last logical slot on the primary was dropped and + * the corresponding XLOG_LOGICAL_DECODING_STATUS_CHANGE record was + * replayed after we fetched the remote slot information: WAL records + * following the slot's restart_lsn might lack the information required by + * logical decoding, and the slot invalidation performed when replaying + * the record could not find our slot as it was not created yet. + * + * It is important to perform this check after creating the slot and + * before persisting it. This way, even if the status change record is + * replayed after this check, the replay will invalidate our slot. + * + * If the check fails, we keep the temporary slot and let the caller + * retry; the next cycle fetches the remote slot information again and + * will drop this slot as the remote slot no longer exists. + * + * XXX: this check cannot detect the case where logical decoding is + * already re-enabled by a slot creation on the primary at this point. + * Detecting that would require comparing the slot's restart_lsn with the + * LSN at which logical decoding was last enabled. + */ + if (!IsLogicalDecodingEnabled()) + { + ereport(LOG, + errmsg("could not synchronize replication slot \"%s\"", + remote_slot->name), + errdetail("Logical decoding was concurrently disabled.")); + + if (slot_persistence_pending) + *slot_persistence_pending = true; + + return false; + } + ReplicationSlotPersist(); ereport(LOG, diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index d7fb9f5a67f..d7a5be2fb8a 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -420,6 +420,8 @@ ReplicationSlotCreate(const char *name, bool db_specific, errmsg("cannot enable failover for a temporary replication slot")); } + INJECTION_POINT("replication-slot-create-begin", NULL); + /* * If some other backend ran this code concurrently with us, we'd likely * both allocate the same slot, and that would be bad. We'd also be at diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index 16fbd383735..fdeb6a23d7b 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -153,7 +153,16 @@ create_logical_replication_slot(char *name, char *plugin, * decoding context. */ EnsureLogicalDecodingEnabled(); - Assert(IsLogicalDecodingEnabled()); + + /* + * Outside of recovery, holding a valid logical slot prevents logical + * decoding from being disabled. During recovery, however, replaying a + * status change record can disable it at any time regardless of slot + * existence, so we cannot assert that it is still enabled here. That is + * harmless: such a replay invalidates slots, so this slot creation fails + * afterwards. + */ + Assert(RecoveryInProgress() || IsLogicalDecodingEnabled()); /* * Create logical decoding context to find start point or, if we don't diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index c931d9b4fa8..bf856244788 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -1356,7 +1356,9 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) * logical decoding context. */ EnsureLogicalDecodingEnabled(); - Assert(IsLogicalDecodingEnabled()); + + /* See the comment in create_logical_replication_slot() */ + Assert(RecoveryInProgress() || IsLogicalDecodingEnabled()); ctx = CreateInitDecodingContext(cmd->plugin, NIL, need_full_snapshot, false, diff --git a/src/test/recovery/t/051_effective_wal_level.pl b/src/test/recovery/t/051_effective_wal_level.pl index 2cf2ea6546d..5990d76888d 100644 --- a/src/test/recovery/t/051_effective_wal_level.pl +++ b/src/test/recovery/t/051_effective_wal_level.pl @@ -467,6 +467,8 @@ sub wait_for_logical_decoding_disabled wait_for_logical_decoding_disabled($primary); pass("the activation process aborted"); + $psql_create_slot->quit; + # Test concurrent activation processes run and one is interrupted. $psql_create_slot = $primary->background_psql('postgres'); @@ -507,6 +509,165 @@ sub wait_for_logical_decoding_disabled test_wal_level($primary, "replica|logical", "effective_wal_level remains 'logical' even after the concurrent activation is interrupted" ); + + $psql_create_slot->quit; + + # Test races between the deactivation of logical decoding and slot + # creation during recovery. Logical decoding can be deactivated while a + # logical slot is being created on a standby, either by replaying an + # XLOG_LOGICAL_DECODING_STATUS_CHANGE record or by the end-of-recovery + # transition upon promotion. Slot creation paths must detect the + # deactivation after creating their slot and fail cleanly, instead + # of leaving a slot that cannot be decoded. + + # Restore the disabled state, and disable autovacuum so that the primary + # assigns no XIDs, keeping the slot synchronization test below + # deterministic. + $primary->safe_psql('postgres', + qq[select pg_drop_replication_slot('test_slot2')]); + wait_for_logical_decoding_disabled($primary); + $primary->safe_psql( + 'postgres', qq[ +alter system set autovacuum = off; +select pg_reload_conf(); +]); + + # Initialize standby5 node, setting up the requirements for slot + # synchronization. + $primary->safe_psql('postgres', + qq[select pg_create_physical_replication_slot('phys_slot')]); + my $standby5 = PostgreSQL::Test::Cluster->new('standby5'); + $standby5->init_from_backup($primary, 'my_backup', has_streaming => 1); + my $connstr = $primary->connstr; + $standby5->append_conf( + 'postgresql.conf', qq[ +primary_slot_name = 'phys_slot' +primary_conninfo = '$connstr dbname=postgres' +hot_standby_feedback = on +]); + $standby5->start; + + # Test that slot synchronization doesn't persist a slot whose remote + # slot information was fetched before a deactivation was replayed. + # Otherwise, the slot would survive with a restart_lsn preceding the + # deactivation, as the slot invalidation performed by the replay cannot + # find the slot that is not created yet. + + # Enable logical decoding by creating a failover-enabled slot, and wait + # for the standby to replay the activation. + $primary->safe_psql('postgres', + qq[select pg_create_logical_replication_slot('sync_slot', 'test_decoding', false, false, true)] + ); + $primary->wait_for_replay_catchup($standby5); + test_wal_level($standby5, "replica|logical", + "logical decoding got activated on standby5"); + + # Start slot synchronization, stopping it after fetching the remote slot + # information but before creating the local slot. + my $psql_sync_slot = $standby5->background_psql('postgres'); + $psql_sync_slot->query_until( + qr/sync_slots/, + q(\echo sync_slots +select injection_points_set_local(); +select injection_points_attach('replication-slot-create-begin', 'wait'); +select pg_sync_replication_slots(); +)); + $standby5->wait_for_event('client backend', + 'replication-slot-create-begin'); + note("injection_point 'replication-slot-create-begin' is reached"); + + # Drop the last logical slot on the primary and wait for the standby to + # replay the deactivation. + $primary->safe_psql('postgres', + qq[select pg_drop_replication_slot('sync_slot')]); + wait_for_logical_decoding_disabled($primary); + $primary->wait_for_replay_catchup($standby5); + test_wal_level($standby5, "replica|replica", + "logical decoding got deactivated on standby5"); + + # Resume the slot synchronization; it must skip persisting the slot. + $log_offset = -s $standby5->logfile; + $standby5->safe_psql('postgres', + qq[select injection_points_wakeup('replication-slot-create-begin')]); + $standby5->wait_for_log( + qr/could not synchronize replication slot "sync_slot"/, $log_offset); + $psql_sync_slot->quit; + is( $standby5->safe_psql( + 'postgres', qq[select count(*) from pg_replication_slots]), + '0', + "no synced slot is left behind on standby5"); + + # Test that logical slot creation on a standby fails cleanly if logical + # decoding is concurrently deactivated by the end-of-recovery transition + # upon promotion, which cannot find the slot that is not created yet. + + # Enable logical decoding again. + $primary->safe_psql('postgres', + qq[select pg_create_logical_replication_slot('test_slot3', 'test_decoding')] + ); + $primary->wait_for_replay_catchup($standby5); + test_wal_level($standby5, "replica|logical", + "logical decoding got activated again on standby5"); + + # Hold the startup process right after the end-of-recovery status + # change, before recovery actually ends. + $standby5->safe_psql('postgres', + qq[select injection_points_attach('startup-logical-decoding-status-change-end-of-recovery', 'wait')] + ); + + # Start creating a logical slot, stopping it before creating the slot. + $psql_create_slot = + $standby5->background_psql('postgres', on_error_stop => 0); + $psql_create_slot->query_until( + qr/create_standby5_slot/, + q(\echo create_standby5_slot +select injection_points_set_local(); +select injection_points_attach('replication-slot-create-begin', 'wait'); +select pg_create_logical_replication_slot('standby5_slot', 'test_decoding'); +)); + $standby5->wait_for_event('client backend', + 'replication-slot-create-begin'); + note("injection_point 'replication-slot-create-begin' is reached"); + + # Promote the standby without waiting; the startup process deactivates + # logical decoding as no logical slot, and stops at the injection point, + # still in recovery. + $standby5->safe_psql('postgres', qq[select pg_promote(false)]); + $standby5->wait_for_event('startup', + 'startup-logical-decoding-status-change-end-of-recovery'); + + # Resume the slot creation; it must fail cleanly. + $log_offset = -s $standby5->logfile; + $standby5->safe_psql('postgres', + qq[select injection_points_wakeup('replication-slot-create-begin')]); + $standby5->wait_for_log( + qr/ERROR: .* logical decoding on standby requires "effective_wal_level" >= "logical" on the primary/, + $log_offset); + $psql_create_slot->quit; + is( $standby5->safe_psql( + 'postgres', qq[select count(*) from pg_replication_slots]), + '0', + "no slot is left behind on standby5"); + + # Let the promotion complete. + $standby5->safe_psql('postgres', + qq[select injection_points_wakeup('startup-logical-decoding-status-change-end-of-recovery')] + ); + $standby5->safe_psql('postgres', + qq[select injection_points_detach('startup-logical-decoding-status-change-end-of-recovery')] + ); + $standby5->poll_query_until('postgres', + qq[select not pg_is_in_recovery()]) + or die "timed out waiting for promotion"; + + # Retrying the slot creation on the promoted standby5 must succeed and + # activate logical decoding. + $standby5->safe_psql('postgres', + qq[select pg_create_logical_replication_slot('standby5_slot', 'test_decoding')] + ); + test_wal_level($standby5, "replica|logical", + "logical decoding got activated on the promoted standby5 after retry" + ); } $primary->stop; From 5c808b8c5c395a7d7afea7efaaa3328b4bc4e004 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 30 Jul 2026 16:17:13 -0700 Subject: [PATCH 249/481] Fix background psql session cleanup in 051_effective_wal_level.pl. Commit 6aba42c660c added quit() calls for two background psql sessions whose slot creation is canceled by pg_cancel_backend(). Both sessions ran with the default ON_ERROR_STOP=1 and ended their script with \q, so psql exited as soon as the cancellation error arrived. quit() then wrote another \q to the already-closed pipe, making the test die with "ack Broken pipe". Run both sessions with on_error_stop => 0 and drop the trailing \q, so that psql stays at the prompt after reporting the error and quit() can shut it down cleanly. Discussion: https://postgr.es/m/CAD21AoCZY1fKYgfkvHGWGiXpatUKd23FSLnDCL4m9bWFjdXNZw@mail.gmail.com Backpatch-through: 19 --- src/test/recovery/t/051_effective_wal_level.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/recovery/t/051_effective_wal_level.pl b/src/test/recovery/t/051_effective_wal_level.pl index 5990d76888d..401a67ad1a6 100644 --- a/src/test/recovery/t/051_effective_wal_level.pl +++ b/src/test/recovery/t/051_effective_wal_level.pl @@ -438,7 +438,8 @@ sub wait_for_logical_decoding_disabled # Start a psql session to test the case where the activation process is # interrupted. - $psql_create_slot = $primary->background_psql('postgres'); + $psql_create_slot = + $primary->background_psql('postgres', on_error_stop => 0); # Start the logical decoding activation process upon creating the logical # slot, but it will wait due to the injection point. @@ -448,7 +449,6 @@ sub wait_for_logical_decoding_disabled select injection_points_set_local(); select injection_points_attach('logical-decoding-activation', 'wait'); select pg_create_logical_replication_slot('slot_canceled', 'pgoutput'); -\q )); $primary->wait_for_event('client backend', 'logical-decoding-activation'); @@ -470,7 +470,8 @@ sub wait_for_logical_decoding_disabled $psql_create_slot->quit; # Test concurrent activation processes run and one is interrupted. - $psql_create_slot = $primary->background_psql('postgres'); + $psql_create_slot = + $primary->background_psql('postgres', on_error_stop => 0); # Start a psql session and stops in the middle of the activation # process. @@ -480,7 +481,6 @@ sub wait_for_logical_decoding_disabled select injection_points_set_local(); select injection_points_attach('logical-decoding-activation', 'wait'); select pg_create_logical_replication_slot('slot_canceled2', 'pgoutput'); -\q )); $primary->wait_for_event('client backend', 'logical-decoding-activation'); note("injection_point 'logical-decoding-activation' is reached"); From 4a791db9bdbd48280e752578b93909995f93fe49 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Fri, 31 Jul 2026 13:16:29 +1200 Subject: [PATCH 250/481] Fix incorrect Result node flattening logic This fixes some incorrect flattening of nested Result nodes during create_plan that was introduced by f2bae51df. That commit failed to maintain the logic that checks for subplans and gating quals from the nested Result node before flattening, and that could result in the nested gating qual and subplan being lost, which could produce incorrect results. Bug: #19579 Reported-by: Viktor Leis Author: Ayush Tiwari Reviewed-by: David Rowley Discussion: https://postgr.es/m/19579-e6296b6c9fc0591c@postgresql.org Backpatch-through: 19 --- src/backend/optimizer/plan/createplan.c | 21 +++++++++++---------- src/test/regress/expected/join.out | 11 +++++++++++ src/test/regress/sql/join.sql | 8 ++++++++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index de6a183da79..d8a266c386d 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -1027,21 +1027,22 @@ create_gating_plan(PlannerInfo *root, Path *path, Plan *plan, (Node *) gating_quals, plan); /* - * We might have had a trivial Result plan already. Stacking one Result - * atop another is silly, so if that applies, just discard the input plan. - * (We're assuming its targetlist is uninteresting; it should be either - * the same as the result of build_path_tlist, or a simplified version. - * However, we preserve the set of relids that it purports to scan and - * attribute that to our replacement Result instead, and likewise for the - * result_type.) + * See if we can reduce down stacked Result nodes to a single node. This + * is only possible when the nested Result has no subplan and no gating + * qual. If we do remove the nested Result, we maintain the relids and + * result_type for EXPLAIN. */ if (IsA(plan, Result)) { Result *rplan = (Result *) plan; - gplan->plan.lefttree = NULL; - gplan->relids = rplan->relids; - gplan->result_type = rplan->result_type; + if (rplan->plan.lefttree == NULL && + rplan->resconstantqual == NULL) + { + gplan->plan.lefttree = NULL; + gplan->relids = rplan->relids; + gplan->result_type = rplan->result_type; + } } /* diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index 19e2cca548b..05f359d3aa7 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -6707,6 +6707,17 @@ select p.* from One-Time Filter: false (3 rows) +-- Ensure multiple gating quals are evaluated correctly +select * from ( + select c0 from + (select null::int as c0 from ((select 1) union all (select 2))) t1 + full join (select 1) t2 on true + where c0 is not null +) t3 where now() is not null; + c0 +---- +(0 rows) + -- bug 5255: this is not optimizable by join removal begin; CREATE TEMP TABLE a (id int PRIMARY KEY); diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index 85aed7bf704..450bd5bbf2c 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -2487,6 +2487,14 @@ select p.* from (parent p left join child c on (p.k = c.k)) join parent x on p.k = x.k where p.k = 1 and p.k = 2; +-- Ensure multiple gating quals are evaluated correctly +select * from ( + select c0 from + (select null::int as c0 from ((select 1) union all (select 2))) t1 + full join (select 1) t2 on true + where c0 is not null +) t3 where now() is not null; + -- bug 5255: this is not optimizable by join removal begin; From f9282a65058b30f0e10fc5dff0171bbd6eb9a254 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Fri, 31 Jul 2026 15:37:12 +1200 Subject: [PATCH 251/481] Fix issue with RANGE's DEFAULT partition pruning Partition pruning for RANGE-partitioned tables could mistakenly prune the DEFAULT partition in some cases when it was not valid to do so, which could lead to rows missing from query results. The only known cases where this could happen is when combining pruning steps from an IS NOT NULL clause with other steps that matched to the DEFAULT partition. This could occur due to RANGE partitioned tables having two distinct internal representations for marking if the DEFAULT partition should be scanned. The IS NOT NULL steps would mark the "scan_default" boolean, but other steps created for different purposes could mark a bound_offset Bitmapset, which would ultimately translate into also scanning the default partition. This could all fail after multiple steps were combined with a combine intersect operator, as that will intersect the bound_offset bits and only set scan_default if all pruning steps have that flag set. When both input steps to the intersect operator had different representations of whether to scan the DEFAULT partition, the resulting intersect step result would contain neither representation. Here, we fix this by having the IS NOT NULL pruning result mark the bound_offsets so that it uses both representations to mark that the DEFAULT partition must be scanned. Reported-by: Jacob Brazeal Diagnosed-by: Jacob Brazeal Author: David Rowley Discussion: https://postgr.es/m/CA+COZaDXrfTaBjLE=Z79MTaH6Xun1V4PeKxLvCNv8mXS8wn0rw@mail.gmail.com Backpatch-through: 14 --- src/backend/partitioning/partprune.c | 10 +--- src/test/regress/expected/partition_prune.out | 46 +++++++++++++++++++ src/test/regress/sql/partition_prune.sql | 20 ++++++++ 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c index e7c318bbcac..afe57ac297d 100644 --- a/src/backend/partitioning/partprune.c +++ b/src/backend/partitioning/partprune.c @@ -3031,15 +3031,9 @@ get_matching_range_bounds(PartitionPruneContext *context, */ if (nvalues == 0) { - /* ignore key space not covered by any partitions */ - if (partindices[minoff] < 0) - minoff++; - if (partindices[maxoff] < 0) - maxoff--; - result->scan_default = partition_bound_has_default(boundinfo); - Assert(partindices[minoff] >= 0 && - partindices[maxoff] >= 0); + Assert(partindices[minoff] >= -1 && + partindices[maxoff] >= -1); result->bound_offsets = bms_add_range(NULL, minoff, maxoff); return result; diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out index 849049f9c51..0d21a2d027c 100644 --- a/src/test/regress/expected/partition_prune.out +++ b/src/test/regress/expected/partition_prune.out @@ -691,6 +691,52 @@ explain (costs off) select * from rlp where (a = 1 and a = 3) or (a > 1 and a = Filter: (((a = 1) AND (a = 3)) OR ((a > 1) AND (a = 15))) (11 rows) +-- Test cases for range partitioned tables with IN clauses. +create table rangepart (a int) partition by range (a); +create table rangepart1 partition of rangepart for values from (0) to (10); +create table rangepart2 partition of rangepart for values from (10) to (20); +create table rangepart_def partition of rangepart default; +-- Ensure we scan all apart from the default partition +explain (costs off) select * from rangepart where a in(5,15); + QUERY PLAN +------------------------------------------------- + Append + -> Seq Scan on rangepart1 rangepart_1 + Filter: (a = ANY ('{5,15}'::integer[])) + -> Seq Scan on rangepart2 rangepart_2 + Filter: (a = ANY ('{5,15}'::integer[])) +(5 rows) + +-- Ensure we scan only the default +explain (costs off) select * from rangepart where a in(20,21); + QUERY PLAN +-------------------------------------------- + Seq Scan on rangepart_def rangepart + Filter: (a = ANY ('{20,21}'::integer[])) +(2 rows) + +-- Ensure we scan only the default +explain (costs off) select * from rangepart where a in(-1,20); + QUERY PLAN +-------------------------------------------- + Seq Scan on rangepart_def rangepart + Filter: (a = ANY ('{-1,20}'::integer[])) +(2 rows) + +-- Ensure we scan all partitions +explain (costs off) select * from rangepart where a is not null and a in(-1,5,15,20); + QUERY PLAN +----------------------------------------------------------------------------- + Append + -> Seq Scan on rangepart1 rangepart_1 + Filter: ((a IS NOT NULL) AND (a = ANY ('{-1,5,15,20}'::integer[]))) + -> Seq Scan on rangepart2 rangepart_2 + Filter: ((a IS NOT NULL) AND (a = ANY ('{-1,5,15,20}'::integer[]))) + -> Seq Scan on rangepart_def rangepart_3 + Filter: ((a IS NOT NULL) AND (a = ANY ('{-1,5,15,20}'::integer[]))) +(7 rows) + +drop table rangepart; -- multi-column keys create table mc3p (a int, b int, c int) partition by range (a, abs(b), c); create table mc3p_default partition of mc3p default; diff --git a/src/test/regress/sql/partition_prune.sql b/src/test/regress/sql/partition_prune.sql index 359a9208056..dac673ef80a 100644 --- a/src/test/regress/sql/partition_prune.sql +++ b/src/test/regress/sql/partition_prune.sql @@ -118,6 +118,26 @@ explain (costs off) select * from rlp where a > 1 and a >=15; /* rlp3 onwards, i explain (costs off) select * from rlp where a = 1 and a = 3; /* empty */ explain (costs off) select * from rlp where (a = 1 and a = 3) or (a > 1 and a = 15); +-- Test cases for range partitioned tables with IN clauses. +create table rangepart (a int) partition by range (a); +create table rangepart1 partition of rangepart for values from (0) to (10); +create table rangepart2 partition of rangepart for values from (10) to (20); +create table rangepart_def partition of rangepart default; + +-- Ensure we scan all apart from the default partition +explain (costs off) select * from rangepart where a in(5,15); + +-- Ensure we scan only the default +explain (costs off) select * from rangepart where a in(20,21); + +-- Ensure we scan only the default +explain (costs off) select * from rangepart where a in(-1,20); + +-- Ensure we scan all partitions +explain (costs off) select * from rangepart where a is not null and a in(-1,5,15,20); + +drop table rangepart; + -- multi-column keys create table mc3p (a int, b int, c int) partition by range (a, abs(b), c); create table mc3p_default partition of mc3p default; From c7d8049682d623109a40de0c84d68e114c013c26 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Fri, 31 Jul 2026 09:51:08 +0530 Subject: [PATCH 252/481] Improve wording of sequence origin warning in logical replication. check_publications_origin_sequences() warns when a subscription with origin = NONE synchronizes sequence values that may have originated from another subscription. The existing warning is phrased in terms of copy_data and copying data, which is appropriate for table synchronization but misleading for sequence synchronization. Reword the warning, detail, and hint to describe sequence synchronization and the associated origin = NONE semantics more accurately. Also fix a typo ("rathen" -> "rather") in a comment in sequencesync.c. Reported-by: Noah Misch Reported-by: Peter Smith Author: vignesh C Reviewed-by: Amit Kapila Backpatch-through: 19, where it was introduced Discussion: https://postgr.es/m/20260710045217.f0.noahmisch@microsoft.com --- src/backend/commands/subscriptioncmds.c | 8 ++++---- src/backend/replication/logical/sequencesync.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 5eca5a5bb4a..e330fb13e42 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -3126,12 +3126,12 @@ check_publications_origin_sequences(WalReceiverConn *wrconn, List *publications, ereport(WARNING, errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("subscription \"%s\" requested copy_data with origin = NONE but might copy data that had a different origin", + errmsg("subscription \"%s\" requested origin = NONE but might synchronize sequence values that had a different origin", subname), - errdetail_plural("The subscription subscribes to a publication (%s) that contains sequences that are written to by other subscriptions.", - "The subscription subscribes to publications (%s) that contain sequences that are written to by other subscriptions.", + errdetail_plural("The subscription subscribes to a publication (%s) that contains sequences that are synchronized from other subscriptions.", + "The subscription subscribes to publications (%s) that contain sequences that are synchronized from other subscriptions.", list_length(publist), pubnames.data), - errhint("Verify that initial data copied from the publisher sequences did not come from other origins.")); + errhint("Verify that the initial values copied from the publisher sequences did not come from other origins.")); } ExecDropSingleTupleTableSlot(slot); diff --git a/src/backend/replication/logical/sequencesync.c b/src/backend/replication/logical/sequencesync.c index bd74a17d28b..9f0d2762dad 100644 --- a/src/backend/replication/logical/sequencesync.c +++ b/src/backend/replication/logical/sequencesync.c @@ -755,7 +755,7 @@ LogicalRepSyncSequences(void) /* * Lock the sequence so its identity (namespace and name) cannot * change under us via a concurrent DROP, RENAME or SET SCHEMA. The - * lock is released immediately rathen than at the transaction end. + * lock is released immediately rather than at the transaction end. * The later synchronization does not depend on this captured identity * remaining valid, as it re-opens the sequence and tolerates * concurrent changes. Releasing early also avoids holding one lock From a71a348ed1e081d3bd32f0b1f9c177f44f9a822a Mon Sep 17 00:00:00 2001 From: David Rowley Date: Fri, 31 Jul 2026 23:24:23 +1200 Subject: [PATCH 253/481] Fix Hash Join performance issue when hashing NULL values adf97c156 allowed expression evaluation to perform hashing, and subsequently 9ca67658d fixed a memory stomping bug in that commit that caused unrelated-to-hashing expression op steps to stomp on the intermediate hash value. The intermediate hash value needs to be maintained when hashing multiple hash keys. 9ca67658d didn't quite get things right when in "strict" mode when it aborted hashing early after encountering a NULL hash key. What was meant to happen was that the expression returns NULL directly to indicate to the caller the value hashed to NULL. The problem was that any EEOP_HASHDATUM_FIRST_STRICT or EEOP_HASHDATUM_NEXT32_STRICT op step that didn't belong to the final key to be hashed would have its op->resnull and op->resvalue pointing to the location to store the intermediate hash value. That's correct for non-NULLs since we bit-rotate the intermediate value and continue hashing, but with the strict case, when we get a NULL key, we immediately jump to the "jumpdone" step. The problem is the jumpdone step expects the ExprState resnull and resvalue fields to be set (as they would be if we didn't abort hashing early due to the NULL), but when we aborted early, the ExprState fields never got set. This would result in inserting records into the hash table that would never match to any join partner, which is a waste of CPU and memory. Here we fix this by having EEOP_HASHDATUM_FIRST_STRICT and EEOP_HASHDATUM_NEXT32_STRICT populate the ExprState resnull and resvalue fields directly when the value to hash is NULL. Although Hash Agg and Hashed Subplans do use hashing from ExprStates, those were unaffected by this bug, as neither of those uses the STRICT op steps. Thanks to Tomas Vondra for finding the offending commit. Reported-by: Dan Stefura Author: David Rowley Discussion: https://postgr.es/m/YQBPR0101MB89738FB972FBD02A3640C6D3D6C92@YQBPR0101MB8973.CANPRD01.PROD.OUTLOOK.COM Backpatch-through: 18 --- src/backend/executor/execExprInterp.c | 8 ++++---- src/backend/jit/llvm/llvmjit_expr.c | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index d45812c23aa..9bc23cb16fa 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -1843,8 +1843,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) * ignoring NULL input values. We've nothing more to do after * finding a NULL. */ - *op->resnull = true; - *op->resvalue = (Datum) 0; + state->resnull = true; + state->resvalue = (Datum) 0; EEO_JUMP(op->d.hashdatum.jumpdone); } @@ -1891,8 +1891,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) * ignoring NULL input values. We've nothing more to do after * finding a NULL. */ - *op->resnull = true; - *op->resvalue = (Datum) 0; + state->resnull = true; + state->resvalue = (Datum) 0; EEO_JUMP(op->d.hashdatum.jumpdone); } else diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c index 0e160b8502c..29617437477 100644 --- a/src/backend/jit/llvm/llvmjit_expr.c +++ b/src/backend/jit/llvm/llvmjit_expr.c @@ -2111,11 +2111,12 @@ llvm_compile_expr(ExprState *state) LLVMPositionBuilderAtEnd(b, b_ifnullblock); /* - * In strict node, NULL inputs result in NULL. Save - * the NULL result and goto jumpdone. + * In strict mode, NULL inputs result in NULL. Save + * the NULL to the ExprState's resnull/resvalue fields + * directly, then goto jumpdone. */ - LLVMBuildStore(b, l_sbool_const(1), v_resnullp); - LLVMBuildStore(b, l_datum_const(0), v_resvaluep); + LLVMBuildStore(b, l_sbool_const(1), v_tmpisnullp); + LLVMBuildStore(b, l_datum_const(0), v_tmpvaluep); LLVMBuildBr(b, opblocks[op->d.hashdatum.jumpdone]); } else From b3331578b58650be6811e842d79937c4a51b74ef Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Fri, 31 Jul 2026 10:34:40 -0500 Subject: [PATCH 254/481] Fix autovacuum's database sorting. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When db_comparator() was updated to use pg_cmp_s32(), the arguments were listed in the wrong order. This caused autovacuum to sort the databases by their scores in ascending order instead of descending order. To fix, swap the arguments to pg_cmp_s32(). Oversight in commit 3b42bdb471. Reported-by: Хамидуллин Рустам Author: Хамидуллин Рустам Discussion: https://postgr.es/m/5c5a7984-b149-b505-7ad9-2a7766c65b55%40postgrespro.ru Backpatch-through: 17 --- src/backend/postmaster/autovacuum.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index e9aaf24c1be..0c975d0eda6 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -1119,8 +1119,8 @@ rebuild_database_list(Oid newdb) static int db_comparator(const void *a, const void *b) { - return pg_cmp_s32(((const avl_dbase *) a)->adl_score, - ((const avl_dbase *) b)->adl_score); + return pg_cmp_s32(((const avl_dbase *) b)->adl_score, + ((const avl_dbase *) a)->adl_score); } /* From dfb96277d7ba01d3bcb70a64b7835182ae419022 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Fri, 31 Jul 2026 11:55:54 -0400 Subject: [PATCH 255/481] Prevent walsummarizer from getting stuck at a timeline switch. As previously coded, walsummarizer only wants to read WAL from a file where the TimeLineID in the filename exactly matches the TimeLineID being summarized. But in some cases, when a timeline switch occurs, the WAL file from the old timeline is not archived, because it's never completely filled, so the only way to obtain the contents of that last partial segment is to read from the first segment on the new timeline. Teach WAL summarizer to do that, and add a test case to make sure that it works. Reported-by: Nick Ivanov Reviewed-by: Andrey Borodin Tested-by: Amit Kapila Reviewed-by: Srinath Reddy Sadipiralla Reviewed-by: Zhijie Hou Reviewed-by: Thom Brown Discussion: http://postgr.es/m/CA+Tgmobr27GpKDZx3_ezW2+C5_g18i+jSK3sGF_cR-_ESv5N5A@mail.gmail.com Backpatch-through: 17 --- src/backend/postmaster/walsummarizer.c | 173 ++++++++++++++++++++-- src/bin/pg_walsummary/meson.build | 1 + src/bin/pg_walsummary/t/003_tli_switch.pl | 146 ++++++++++++++++++ 3 files changed, 306 insertions(+), 14 deletions(-) create mode 100644 src/bin/pg_walsummary/t/003_tli_switch.pl diff --git a/src/backend/postmaster/walsummarizer.c b/src/backend/postmaster/walsummarizer.c index 8b429cb51d7..ff246b07a21 100644 --- a/src/backend/postmaster/walsummarizer.c +++ b/src/backend/postmaster/walsummarizer.c @@ -105,6 +105,8 @@ typedef struct bool historic; XLogRecPtr read_upto; bool end_of_wal; + int num_descendant_tlis; + TimeLineID *descendant_tlis; } SummarizerReadLocalXLogPrivate; /* Pointer to shared memory state. */ @@ -156,10 +158,14 @@ int wal_summary_keep_time = 10 * HOURS_PER_DAY * MINS_PER_HOUR; static void WalSummarizerShutdown(int code, Datum arg); static XLogRecPtr GetLatestLSN(TimeLineID *tli); +static XLogRecPtr WalSummarizerSwitchPoint(TimeLineID current_tli, List *tles, + int *num_descendant_tlis, + TimeLineID **descendant_tlis); static void ProcessWalSummarizerInterrupts(void); static XLogRecPtr SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn, bool exact, XLogRecPtr switch_lsn, - XLogRecPtr maximum_lsn); + XLogRecPtr maximum_lsn, + int num_descendant_tlis, TimeLineID *descendant_tlis); static void SummarizeDbaseRecord(XLogReaderState *xlogreader, BlockRefTable *brtab); static void SummarizeSmgrRecord(XLogReaderState *xlogreader, @@ -168,6 +174,9 @@ static void SummarizeXactRecord(XLogReaderState *xlogreader, BlockRefTable *brtab); static bool SummarizeXlogRecord(XLogReaderState *xlogreader, bool *new_fast_forward); +static void summarizer_wal_segment_open(XLogReaderState *state, + XLogSegNo nextSegNo, + TimeLineID *tli_p); static int summarizer_read_local_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen, @@ -222,16 +231,19 @@ WalSummarizerMain(const void *startup_data, size_t startup_data_len) * true if 'current_lsn' is known to be the start of a WAL record or WAL * segment, and false if it might be in the middle of a record someplace. * - * 'switch_lsn' and 'switch_tli', if set, are the LSN at which we need to - * switch to a new timeline and the timeline to which we need to switch. - * If not set, we either haven't figured out the answers yet or we're - * already on the latest timeline. + * 'switch_lsn', is the LSN at which we need to switch to a new timeline. + * If not set, we either haven't figured out the answer yet or we're + * already on the latest timeline. 'descendant_tlis' stores an array of + * future timeline IDs to which we know we'll need to switch, and + * 'num_descendant_tlis' is the length of that array. The first element of + * the array is the first timeline to which we will need to switch. */ XLogRecPtr current_lsn; TimeLineID current_tli; bool exact; XLogRecPtr switch_lsn = InvalidXLogRecPtr; - TimeLineID switch_tli = 0; + int num_descendant_tlis = 0; + TimeLineID *descendant_tlis = NULL; Assert(startup_data_len == 0); @@ -380,11 +392,33 @@ WalSummarizerMain(const void *startup_data, size_t startup_data_len) if (current_tli != latest_tli && !XLogRecPtrIsValid(switch_lsn)) { List *tles = readTimeLineHistory(latest_tli); + int new_num_descendant_tlis; + TimeLineID *new_descendant_tlis; - switch_lsn = tliSwitchPoint(current_tli, tles, &switch_tli); + /* + * Make sure that the array of descendant TLIs get stored into + * TopMemoryContext. + */ + MemoryContextSwitchTo(TopMemoryContext); + switch_lsn = WalSummarizerSwitchPoint(current_tli, tles, + &new_num_descendant_tlis, + &new_descendant_tlis); + MemoryContextSwitchTo(context); + + /* + * Free any old array of descendant TLIs and install the new + * values. + */ + if (descendant_tlis != NULL) + pfree(descendant_tlis); + num_descendant_tlis = new_num_descendant_tlis; + descendant_tlis = new_descendant_tlis; + + /* Debug message. */ ereport(DEBUG1, errmsg_internal("switch point from TLI %u to TLI %u is at %X/%08X", - current_tli, switch_tli, LSN_FORMAT_ARGS(switch_lsn))); + current_tli, descendant_tlis[0], + LSN_FORMAT_ARGS(switch_lsn))); } /* @@ -395,12 +429,15 @@ WalSummarizerMain(const void *startup_data, size_t startup_data_len) if (XLogRecPtrIsValid(switch_lsn) && current_lsn >= switch_lsn) { /* Restart summarization from switch point. */ - current_tli = switch_tli; + Assert(num_descendant_tlis > 0); + current_tli = descendant_tlis[0]; current_lsn = switch_lsn; - /* Next timeline and switch point, if any, not yet known. */ + /* Switch point, if any, and future TLIs, not yet known. */ switch_lsn = InvalidXLogRecPtr; - switch_tli = 0; + num_descendant_tlis = 0; + pfree(descendant_tlis); + descendant_tlis = NULL; /* Update (really, rewind, if needed) state in shared memory. */ LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE); @@ -417,7 +454,8 @@ WalSummarizerMain(const void *startup_data, size_t startup_data_len) maximum_lsn = XLogRecPtrIsValid(switch_lsn) ? switch_lsn : latest_lsn; end_of_summary_lsn = SummarizeWAL(current_tli, current_lsn, exact, - switch_lsn, maximum_lsn); + switch_lsn, maximum_lsn, + num_descendant_tlis, descendant_tlis); Assert(XLogRecPtrIsValid(end_of_summary_lsn)); Assert(end_of_summary_lsn >= current_lsn); @@ -853,6 +891,62 @@ GetLatestLSN(TimeLineID *tli) } } +/* + * Compute the LSN at which we switched from current_tli to some later timeline. + * 'tles' must be the timeline history of the latest timeline. + * + * As a side effect, we set *num_descendant_tlis to the number of later TLIs that + * appear in the timeline history, and *descendant_tlis to an array of those TLIs, + * starting with immediate successor of current_tli. + */ +static XLogRecPtr +WalSummarizerSwitchPoint(TimeLineID current_tli, List *tles, + int *num_descendant_tlis, TimeLineID **descendant_tlis) +{ + XLogRecPtr switch_lsn = InvalidXLogRecPtr; + int count = 0; + + /* + * Find the switch point and, at the same time, count the number of TLIs + * in this history that are descendants of that TLI. + */ + foreach_ptr(TimeLineHistoryEntry, tle, tles) + { + if (tle->tli == current_tli) + { + switch_lsn = tle->end; + break; + } + ++count; + } + + /* Sanity checks. */ + if (!XLogRecPtrIsValid(switch_lsn)) + ereport(ERROR, + (errmsg("requested timeline %u is not in this server's history", + current_tli))); + if (count == 0) + elog(ERROR, "cannot compute switch point for current TLI %u", current_tli); + + /* + * Generate an array of TLIs that are part of this history and descendants + * of current_tli. The TLE list starts with the newest timeline and works + * backward toward older timelines; we want the opposite ordering. + */ + *num_descendant_tlis = count; + *descendant_tlis = palloc_array(TimeLineID, count); + for (int i = 0; i < count; ++i) + { + TimeLineHistoryEntry *tle; + + tle = (TimeLineHistoryEntry *) list_nth(tles, count - i - 1); + (*descendant_tlis)[i] = tle->tli; + } + + /* Return value is the switchpoint. */ + return switch_lsn; +} + /* * Interrupt handler for main loop of WAL summarizer process. */ @@ -906,7 +1000,8 @@ ProcessWalSummarizerInterrupts(void) */ static XLogRecPtr SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn, bool exact, - XLogRecPtr switch_lsn, XLogRecPtr maximum_lsn) + XLogRecPtr switch_lsn, XLogRecPtr maximum_lsn, + int num_descendant_tlis, TimeLineID *descendant_tlis) { SummarizerReadLocalXLogPrivate *private_data; XLogReaderState *xlogreader; @@ -924,11 +1019,13 @@ SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn, bool exact, private_data->tli = tli; private_data->historic = XLogRecPtrIsValid(switch_lsn); private_data->read_upto = maximum_lsn; + private_data->num_descendant_tlis = num_descendant_tlis; + private_data->descendant_tlis = descendant_tlis; /* Create xlogreader. */ xlogreader = XLogReaderAllocate(wal_segment_size, NULL, XL_ROUTINE(.page_read = &summarizer_read_local_xlog_page, - .segment_open = &wal_segment_open, + .segment_open = &summarizer_wal_segment_open, .segment_close = &wal_segment_close), private_data); if (xlogreader == NULL) @@ -1492,6 +1589,54 @@ SummarizeXlogRecord(XLogReaderState *xlogreader, bool *new_fast_forward) return true; } +/* + * Similar to wal_segment_open, but checks for a file on any descendant timelines + * known to us if no file is found on the requested timeline. + */ +static void +summarizer_wal_segment_open(XLogReaderState *state, XLogSegNo nextSegNo, + TimeLineID *tli_p) +{ + SummarizerReadLocalXLogPrivate *private_data = state->private_data; + int count = 0; + TimeLineID tli = *tli_p; + char path[MAXPGPATH]; + + for (;;) + { + XLogFilePath(path, tli, nextSegNo, state->segcxt.ws_segsize); + state->seg.ws_file = BasicOpenFile(path, O_RDONLY | PG_BINARY); + if (state->seg.ws_file >= 0) + { + *tli_p = tli; + return; + } + + /* + * If the error is anything other than file-not-found, complain at + * once. + */ + if (errno != ENOENT) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not open file \"%s\": %m", + path))); + + /* Try other timelines, if any remain. */ + if (count >= private_data->num_descendant_tlis) + break; + tli = private_data->descendant_tlis[count]; + ++count; + } + + /* Complain about the originally requested filename. */ + XLogFilePath(path, *tli_p, nextSegNo, state->segcxt.ws_segsize); + ereport(ERROR, + (errcode_for_file_access(), + errmsg("requested WAL segment %s has already been removed", + path))); +} + /* * Similar to read_local_xlog_page, but limited to read from one particular * timeline. If the end of WAL is reached, it will wait for more if reading diff --git a/src/bin/pg_walsummary/meson.build b/src/bin/pg_walsummary/meson.build index d012275402b..839b644ef23 100644 --- a/src/bin/pg_walsummary/meson.build +++ b/src/bin/pg_walsummary/meson.build @@ -25,6 +25,7 @@ tests += { 'tests': [ 't/001_basic.pl', 't/002_blocks.pl', + 't/003_tli_switch.pl', ], } } diff --git a/src/bin/pg_walsummary/t/003_tli_switch.pl b/src/bin/pg_walsummary/t/003_tli_switch.pl new file mode 100644 index 00000000000..810d27d908e --- /dev/null +++ b/src/bin/pg_walsummary/t/003_tli_switch.pl @@ -0,0 +1,146 @@ +# Copyright (c) 2021-2026, PostgreSQL Global Development Group +# +# In the original version of the WAL summarizer code, we were only willing +# to read WAL for a given TLI from a file with that exact TLI encoded into +# the filename. This could result in WAL summarization running on an archiving +# standby getting stuck. +# +# The reason for the problem is that when a new primary is promoted, the +# partial file that ends the old timeline is renamed, giving it a ".partial" +# suffix, meaning that it will be ignored by both recovery and by the WAL +# summarizer. The bytes that appear at the start of that segment will be copied +# into the first segment on the new timeline, and recovery was able to read +# them from there and work as expected. However, the WAL summarizer was +# unwilling to do the same thing, so it got stuck. This test aims to validate +# that this bug has been fixed. + +use strict; +use warnings FATAL => 'all'; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +# Set up node1 as primary. +my $node1 = PostgreSQL::Test::Cluster->new('node1'); +$node1->init(allows_streaming => 1); +$node1->append_conf('postgresql.conf', <start; + +# Set up node2 as a standby for node1. Use archive_mode=always, to make sure it +# archives both before and after promotion. +$node1->backup('backup1'); +my $node2 = PostgreSQL::Test::Cluster->new('node2'); +$node2->init_from_backup($node1, 'backup1', has_streaming => 1); +$node2->enable_archiving(); +$node2->append_conf('postgresql.conf', <start; + +# Wait for node2 to catch up. +$node1->wait_for_replay_catchup($node2); + +# Set up node3 as a standby for node2. We want it to fetch WAL only from the +# archive, so we clear primary_conninfo. We don't want long delays during the +# test, so we reduce wal_retrieve_retry_interval. We also don't want it to try +# to archive anything to node2's archive, but at the same time, we don't want +# it to remove WAL before we enable WAL summarization. To accomplish that, we +# set archive_command to the empty string. +$node2->backup('backup2'); +my $node3 = PostgreSQL::Test::Cluster->new('node3'); +$node3->init_from_backup($node2, 'backup2', has_restoring => 1); +$node3->append_conf('postgresql.conf', <start; + +# Create a new, partially-filled WAL segment on node1. +$node1->safe_psql('postgres', <wait_for_replay_catchup($node2); + +# Record the WAL insert LSN on node1, so we can later verify that summarization +# on node3 advances past this point. +my $node1_final_lsn = $node1->safe_psql('postgres', + 'SELECT pg_current_wal_insert_lsn()'); + +# Promote node2. This creates a timeline switch that node3 must follow. +$node2->promote; +$node2->poll_query_until('postgres', "SELECT pg_is_in_recovery() = 'f';"); + +# Cause the partial segment to get archived on the *new* timeline. +# +# In more detail: the WAL segment that contains the current insert LSN exists +# on timeline 1, but since all we did is CREATE TABLE dummy (), it wasn't full. +# We're now running on timeline 2, and pg_switch_wal() fills up the rest of the +# segment. So the full segment should get archived on timeline 2, but not on +# timeline 1. We do a CHECKPOINT here to make sure that the summarizer tries +# to progress. +$node2->safe_psql('postgres', <poll_query_until('postgres', + "SELECT replay_end_tli = 2 FROM pg_stat_get_recovery()") + or die "TLI 2 not reached on node3"; +$node3->append_conf('postgresql.conf', <reload; + +# Wait for WAL summarization on node3 to advance past the pre-promotion LSN. +# If the bug is present, the summarizer gets stuck trying to open the old +# timeline's segment file. +my $result = $node3->poll_query_until('postgres', <safe_psql('postgres', <safe_psql('postgres', <= '$node1_final_lsn' ORDER BY start_lsn +EOM +my @summary_lines = split(/\n/, $summaries); +ok(@summary_lines > 0, "at least one summary from LSN $node1_final_lsn or later"); + +# We expect the new summaries to be empty, because we have not actually touched +# any block data (and we disabled autovacuum from the start). +for my $line (@summary_lines) +{ + my ($tli, $start_lsn, $end_lsn) = split(/\|/, $line); + my $filename = sprintf "%s/pg_wal/summaries/%08s%08s%08s%08s%08s.summary", + $node3->data_dir, $tli, + split(m@/@, $start_lsn), + split(m@/@, $end_lsn); + my ($stdout, $stderr) = run_command([ 'pg_walsummary', $filename ]); + is($stdout, '', "pg_walsummary TLI $tli $start_lsn-$end_lsn: no blocks"); + is($stderr, '', "pg_walsummary TLI $tli $start_lsn-$end_lsn: no error"); +} + +done_testing(); From 19ff9a1ae04087ff324dc2180c757d56258ab89a Mon Sep 17 00:00:00 2001 From: Jacob Champion Date: Fri, 31 Jul 2026 11:13:41 -0700 Subject: [PATCH 256/481] libpq-oauth: Avoid overflow for very large intervals The slow_down interval parsing code checks explicitly for overflow, but since it does that after the signed overflow has already occurred, we end up inviting undefined behavior from the compiler anyway. Use checked arithmetic instead. set_timer() takes a long int in order to interface nicely with libcurl, so use an int32 as the interval counter and clamp to LONG_MAX during conversion to milliseconds. Backpatch to 18, where libpq-oauth was introduced. Reported-by: Andres Freund Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/qtclihmrkq67ach3xjxyi4qcksstin5qxwsnkqefkmotxwh4g6%40ae2bj6jvcmry Backpatch-through: 18 --- src/interfaces/libpq-oauth/oauth-curl.c | 35 ++++++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/interfaces/libpq-oauth/oauth-curl.c b/src/interfaces/libpq-oauth/oauth-curl.c index d4dcc4cd7a5..bb29f67933e 100644 --- a/src/interfaces/libpq-oauth/oauth-curl.c +++ b/src/interfaces/libpq-oauth/oauth-curl.c @@ -28,6 +28,7 @@ #error libpq-oauth is not supported on this platform #endif +#include "common/int.h" #include "common/jsonapi.h" #include "mb/pg_wchar.h" #include "oauth-curl.h" @@ -136,7 +137,7 @@ struct device_authz /* Fields below are parsed from the corresponding string above. */ int expires_in; - int interval; + int32 interval; }; static void @@ -1020,7 +1021,7 @@ parse_json_number(const char *s) * expensive network polling loop.) Tests may remove the lower bound with * PGOAUTHDEBUG, for improved performance. */ -static int +static int32 parse_interval(struct async_ctx *actx, const char *interval_str) { double parsed; @@ -1031,8 +1032,8 @@ parse_interval(struct async_ctx *actx, const char *interval_str) if (parsed < 1) return (actx->debug_flags & OAUTHDEBUG_UNSAFE_DOS_ENDPOINT) ? 0 : 1; - else if (parsed >= INT_MAX) - return INT_MAX; + else if (parsed >= INT32_MAX) + return INT32_MAX; return parsed; } @@ -2620,10 +2621,7 @@ handle_token_response(struct async_ctx *actx, char **token) */ if (strcmp(err->error, "slow_down") == 0) { - int prev_interval = actx->authz.interval; - - actx->authz.interval += 5; - if (actx->authz.interval < prev_interval) + if (pg_add_s32_overflow(actx->authz.interval, 5, &actx->authz.interval)) { actx_error(actx, "slow_down interval overflow"); goto token_cleanup; @@ -2964,8 +2962,25 @@ pg_fe_run_oauth_flow_impl(PGconn *conn, PGoauthBearerRequestV2 *request, * Wait for the required interval before issuing the next * request. */ - if (!set_timer(actx, actx->authz.interval * 1000)) - goto error_return; + { + /* + * Avoid overflow of long int. (By the time we reach + * LONG_MAX milliseconds -- 24 days on 32-bit platforms -- + * continuing to honor slow_down requests seems pretty + * pointless anyway.) + */ + int64 interval_ms; + + if (pg_mul_s64_overflow(actx->authz.interval, 1000, + &interval_ms) + || (interval_ms > LONG_MAX)) + { + interval_ms = LONG_MAX; + } + + if (!set_timer(actx, (long) interval_ms)) + goto error_return; + } /* * No Curl requests are running, so we can simplify by having From 0c57a40694d88cdda588b5f8a6e5568861d1759d Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Fri, 31 Jul 2026 14:00:37 -0500 Subject: [PATCH 257/481] Add list of major features to the v19 release notes. Reviewed-by: Michael Banck Discussion: https://postgr.es/m/akWIxtcathhoUuCQ%40nathan Backpatch-through: 19 only --- doc/src/sgml/release-19.sgml | 78 +++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/release-19.sgml b/doc/src/sgml/release-19.sgml index 21f1be994d0..cb5a220f7c3 100644 --- a/doc/src/sgml/release-19.sgml +++ b/doc/src/sgml/release-19.sgml @@ -19,7 +19,83 @@ - fill in later + + Support for + property graph queries + (SQL/PGQ). + + + + + + A new REPACK command + that reclaims disk space and reorganizes table contents, combining the + functionality of the existing VACUUM FULL and + CLUSTER commands. Its CONCURRENTLY + option allows repacking without blocking reads and writes to the table. + + + + + + Logical replication now + replicates sequence values + and can be enabled without a server restart when + is set to replica. + + + + + + Autovacuum can now use + parallel worker processes + to vacuum a table's indexes, and a + new scoring system prioritizes + the tables that most need vacuuming or analyzing. + + + + + + Data checksums can now be + enabled or disabled while the database server is running. + + + + + + A new WAIT FOR + command that waits until a standby has replayed changes up to a chosen + point, thereby supporting read-your-writes query patterns + on standbys. + + + + + + Support for temporal updates and deletes via the new + FOR PORTION OF + clause. + + + + + + A new + pg_plan_advice + extension for stabilizing and controlling the query planner's decisions, + and a companion + pg_stash_advice + extension that applies this advice automatically based on the query. + + + + + + Better performance in many areas, including automatic scaling of the + number of I/O worker processes, quicker foreign-key checks, and further + planning and execution optimizations. + From d6792cc58e9c0aead136f381052151e1c246b534 Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Fri, 31 Jul 2026 17:45:45 -0400 Subject: [PATCH 258/481] Allow IO time to be counted without a matching IO operation in pg_stat_io Since 999dec9ec6a816680, pg_stat_io can show read time with zero reads for an IO Context: a foreign IO is counted as a read only in the initiating backend, while other waiters record only the wait time. That violates pgstat_bktype_io_stats_valid(). Relax the check to allow time without a matching operation count, since we want to count read wait time even in backends that did not initiate the read. This also enables future accounting of waits on IO resources (e.g., AIO handles) in backends that didn't start the IO. Author: Andrey Rachitskiy Reported-by: Justin Pryzby Reviewed-by: Melanie Plageman Reviewed-by: Andrey Borodin Discussion: https://postgr.es/m/ak5lccE4qiQpOBHn@pryzbyj2023 Backpatch-through: 19 --- doc/src/sgml/monitoring.sgml | 4 +++- src/backend/storage/buffer/bufmgr.c | 8 ++++---- src/backend/utils/activity/pgstat_io.c | 22 +++++++--------------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 2d0ebd6f27d..d60b6710bfd 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -3050,7 +3050,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage object is not wal, or if is enabled and object is wal, - otherwise zero) + otherwise zero). This may include time spent waiting for a + read started by another backend. In that case + reads may still be zero. diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 3908529872a..169829eb020 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -1829,8 +1829,9 @@ WaitReadBuffers(ReadBuffersOperation *operation) needed_wait = true; /* - * The IO operation itself was already counted earlier, in - * AsyncReadBuffers(), this just accounts for the wait time. + * This just accounts for the wait time. The IO operation + * itself was already counted earlier in AsyncReadBuffers() -- + * either by us or by another backend if this is a foreign IO. */ pgstat_count_io_op_time(io_object, io_context, IOOP_READ, io_start, 0, 0); @@ -2018,8 +2019,7 @@ AsyncReadBuffers(ReadBuffersOperation *operation, int *nblocks_progress) * A secondary benefit is that this would allow us to measure the time in * pgaio_io_acquire() without causing undue timer overhead in the common, * non-blocking, case. However, currently the pgstats infrastructure - * doesn't really allow that, as it a) asserts that an operation can't - * have time without operations b) doesn't have an API to report + * doesn't really allow that because it doesn't have an API to report * "accumulated" time. */ ioh = pgaio_io_acquire_nb(CurrentResourceOwner, &operation->io_return); diff --git a/src/backend/utils/activity/pgstat_io.c b/src/backend/utils/activity/pgstat_io.c index 4f7a39aaa0e..8ec1aad5078 100644 --- a/src/backend/utils/activity/pgstat_io.c +++ b/src/backend/utils/activity/pgstat_io.c @@ -25,9 +25,10 @@ static bool have_iostats = false; /* * Check that stats have not been counted for any combination of IOObject, - * IOContext, and IOOp which are not tracked for the passed-in BackendType. If - * stats are tracked for this combination and IO times are non-zero, counts - * should be non-zero. + * IOContext, and IOOp which are not tracked for the passed-in BackendType. + * Non-zero time with a zero operation count is allowed as there are cases + * where this may be appropriate -- like when a backend is waiting on IO + * initiated by another backend. * * The passed-in PgStat_BktypeIO must contain stats from the BackendType * specified by the second parameter. Caller is responsible for locking the @@ -43,19 +44,10 @@ pgstat_bktype_io_stats_valid(PgStat_BktypeIO *backend_io, { for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++) { - /* we do track it */ - if (pgstat_tracks_io_op(bktype, io_object, io_context, io_op)) - { - /* ensure that if IO times are non-zero, counts are > 0 */ - if (backend_io->times[io_object][io_context][io_op] != 0 && - backend_io->counts[io_object][io_context][io_op] <= 0) - return false; - - continue; - } - /* we don't track it, and it is not 0 */ - if (backend_io->counts[io_object][io_context][io_op] != 0) + if (!pgstat_tracks_io_op(bktype, io_object, io_context, io_op) && + (backend_io->counts[io_object][io_context][io_op] != 0 || + backend_io->times[io_object][io_context][io_op] != 0)) return false; } } From 602f19c84ca1db471b6264d4965e2becfc00cbbc Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Sat, 1 Aug 2026 21:35:19 +0200 Subject: [PATCH 259/481] doc: Fix glossary entry for data checksums workers The glossary entry for data checksums workers incorrectly stated that they were auxiliary processes, but they are implemented as background workers. Fix, and while there, simplify the entry by combining the worker and launcher into a single glossary term. Backpatch down to v19 where online checksums were introduced. Author: Daniel Gustafsson Reported-by: Fujii Masao Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CAHGQGwEv-C9ia+rBYyePzO8F=5FVvS412ZqcOupazuOb5RafNg@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/glossary.sgml | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/doc/src/sgml/glossary.sgml b/doc/src/sgml/glossary.sgml index b881ae71198..b9a3cb83bc2 100644 --- a/doc/src/sgml/glossary.sgml +++ b/doc/src/sgml/glossary.sgml @@ -199,8 +199,6 @@ (but not the autovacuum workers), the background writer, the checkpointer, - the data checksums worker, - the data checksums worker launcher, the logger, the startup process, the WAL archiver, @@ -236,8 +234,9 @@ which runs system- or user-supplied code. Serves as infrastructure for several features in PostgreSQL, such as - logical replication - and parallel queries. + logical replication, + parallel queries and + data checksums processing. In addition, Extensions can add custom background worker processes. @@ -576,24 +575,17 @@ - - Data Checksums Worker + + Data Checksums (process) - A background worker - which enables data checksums in a specific database. - - - - - - Data Checksums Worker Launcher - - - A background worker - which starts data - checksum worker processes for enabling data checksums in each - database, or disables data checksums cluster-wide. + A set of + background worker + processes which can enable or disable data checksums in a running cluster. + The process which coordinates the work is known as the + data checksums launcher and the process which + operates on the individual databases is known as the + data checksums worker. From 4afa9788b51625d19eee08a1420b48b04c0699fa Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Sat, 1 Aug 2026 21:35:51 +0200 Subject: [PATCH 260/481] Add a comment to distinguish backend types The data checksums entries were seemingly auxiliary processes from reading the code, but they are in fact background workers. Add a comment to clarify. Backpatch down to v19 where online checksums were introduced. Author: Daniel Gustafsson Reported-by: Fujii Masao Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CAHGQGwFsBjQs2fv7b72hxzGV_fJMh6LAg4E83pNfDOu1jVgWCA@mail.gmail.com Backpatch-through: 19 --- src/include/miscadmin.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 7170a4bff98..0fc59af02b9 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -370,6 +370,10 @@ typedef enum BackendType B_WAL_SUMMARIZER, B_WAL_WRITER, + /* + * Data checksums processes are dynamic background workers, but they use + * dedicated backend types for pgstat I/O accounting. + */ B_DATACHECKSUMSWORKER_LAUNCHER, B_DATACHECKSUMSWORKER_WORKER, From 3c16aa29305e5ae1244132008f337780525c04e7 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 2 Aug 2026 11:26:30 -0400 Subject: [PATCH 261/481] Update time zone data files to tzdata release 2026c. Alberta (America/Edmonton) moved to permanent UTC-06 on 2026-06-18, which will affect their clocks beginning on 2026-11-01. For lack of any clarity on the point, assume their TZ abbreviation will be CST from that time forward. Morocco (Africa/Casablanca) will move to permanent UTC+00, without daylight saving time transitions, on 2026-09-20. Backpatch-through: 14 --- src/timezone/data/tzdata.zi | 138 +++--------------------------------- 1 file changed, 8 insertions(+), 130 deletions(-) diff --git a/src/timezone/data/tzdata.zi b/src/timezone/data/tzdata.zi index 53082964703..079a47fda43 100644 --- a/src/timezone/data/tzdata.zi +++ b/src/timezone/data/tzdata.zi @@ -1,4 +1,4 @@ -# version 2026b +# version 2026c # redo posix_only # This zic input file is in the public domain. R d 1916 o - Jun 14 23s 1 S @@ -135,132 +135,6 @@ R M 2025 o - F 23 3 -1 - R M 2025 o - Ap 6 2 0 - R M 2026 o - F 15 3 -1 - R M 2026 o - Mar 22 2 0 - -R M 2027 o - F 7 3 -1 - -R M 2027 o - Mar 14 2 0 - -R M 2028 o - Ja 23 3 -1 - -R M 2028 o - Mar 5 2 0 - -R M 2029 o - Ja 14 3 -1 - -R M 2029 o - F 18 2 0 - -R M 2029 o - D 30 3 -1 - -R M 2030 o - F 10 2 0 - -R M 2030 o - D 22 3 -1 - -R M 2031 o - Ja 26 2 0 - -R M 2031 o - D 14 3 -1 - -R M 2032 o - Ja 18 2 0 - -R M 2032 o - N 28 3 -1 - -R M 2033 o - Ja 9 2 0 - -R M 2033 o - N 20 3 -1 - -R M 2033 o - D 25 2 0 - -R M 2034 o - N 5 3 -1 - -R M 2034 o - D 17 2 0 - -R M 2035 o - O 28 3 -1 - -R M 2035 o - D 9 2 0 - -R M 2036 o - O 19 3 -1 - -R M 2036 o - N 23 2 0 - -R M 2037 o - O 4 3 -1 - -R M 2037 o - N 15 2 0 - -R M 2038 o - S 26 3 -1 - -R M 2038 o - O 31 2 0 - -R M 2039 o - S 18 3 -1 - -R M 2039 o - O 23 2 0 - -R M 2040 o - S 2 3 -1 - -R M 2040 o - O 14 2 0 - -R M 2041 o - Au 25 3 -1 - -R M 2041 o - S 29 2 0 - -R M 2042 o - Au 10 3 -1 - -R M 2042 o - S 21 2 0 - -R M 2043 o - Au 2 3 -1 - -R M 2043 o - S 13 2 0 - -R M 2044 o - Jul 24 3 -1 - -R M 2044 o - Au 28 2 0 - -R M 2045 o - Jul 9 3 -1 - -R M 2045 o - Au 20 2 0 - -R M 2046 o - Jul 1 3 -1 - -R M 2046 o - Au 5 2 0 - -R M 2047 o - Jun 23 3 -1 - -R M 2047 o - Jul 28 2 0 - -R M 2048 o - Jun 7 3 -1 - -R M 2048 o - Jul 19 2 0 - -R M 2049 o - May 30 3 -1 - -R M 2049 o - Jul 4 2 0 - -R M 2050 o - May 15 3 -1 - -R M 2050 o - Jun 26 2 0 - -R M 2051 o - May 7 3 -1 - -R M 2051 o - Jun 18 2 0 - -R M 2052 o - Ap 28 3 -1 - -R M 2052 o - Jun 2 2 0 - -R M 2053 o - Ap 13 3 -1 - -R M 2053 o - May 25 2 0 - -R M 2054 o - Ap 5 3 -1 - -R M 2054 o - May 10 2 0 - -R M 2055 o - Mar 28 3 -1 - -R M 2055 o - May 2 2 0 - -R M 2056 o - Mar 12 3 -1 - -R M 2056 o - Ap 23 2 0 - -R M 2057 o - Mar 4 3 -1 - -R M 2057 o - Ap 8 2 0 - -R M 2058 o - F 17 3 -1 - -R M 2058 o - Mar 31 2 0 - -R M 2059 o - F 9 3 -1 - -R M 2059 o - Mar 23 2 0 - -R M 2060 o - F 1 3 -1 - -R M 2060 o - Mar 7 2 0 - -R M 2061 o - Ja 16 3 -1 - -R M 2061 o - F 27 2 0 - -R M 2062 o - Ja 8 3 -1 - -R M 2062 o - F 12 2 0 - -R M 2062 o - D 31 3 -1 - -R M 2063 o - F 4 2 0 - -R M 2063 o - D 16 3 -1 - -R M 2064 o - Ja 27 2 0 - -R M 2064 o - D 7 3 -1 - -R M 2065 o - Ja 11 2 0 - -R M 2065 o - N 22 3 -1 - -R M 2066 o - Ja 3 2 0 - -R M 2066 o - N 14 3 -1 - -R M 2066 o - D 26 2 0 - -R M 2067 o - N 6 3 -1 - -R M 2067 o - D 11 2 0 - -R M 2068 o - O 21 3 -1 - -R M 2068 o - D 2 2 0 - -R M 2069 o - O 13 3 -1 - -R M 2069 o - N 17 2 0 - -R M 2070 o - O 5 3 -1 - -R M 2070 o - N 9 2 0 - -R M 2071 o - S 20 3 -1 - -R M 2071 o - N 1 2 0 - -R M 2072 o - S 11 3 -1 - -R M 2072 o - O 16 2 0 - -R M 2073 o - Au 27 3 -1 - -R M 2073 o - O 8 2 0 - -R M 2074 o - Au 19 3 -1 - -R M 2074 o - S 30 2 0 - -R M 2075 o - Au 11 3 -1 - -R M 2075 o - S 15 2 0 - -R M 2076 o - Jul 26 3 -1 - -R M 2076 o - S 6 2 0 - -R M 2077 o - Jul 18 3 -1 - -R M 2077 o - Au 22 2 0 - -R M 2078 o - Jul 10 3 -1 - -R M 2078 o - Au 14 2 0 - -R M 2079 o - Jun 25 3 -1 - -R M 2079 o - Au 6 2 0 - -R M 2080 o - Jun 16 3 -1 - -R M 2080 o - Jul 21 2 0 - -R M 2081 o - Jun 1 3 -1 - -R M 2081 o - Jul 13 2 0 - -R M 2082 o - May 24 3 -1 - -R M 2082 o - Jun 28 2 0 - -R M 2083 o - May 16 3 -1 - -R M 2083 o - Jun 20 2 0 - -R M 2084 o - Ap 30 3 -1 - -R M 2084 o - Jun 11 2 0 - -R M 2085 o - Ap 22 3 -1 - -R M 2085 o - May 27 2 0 - -R M 2086 o - Ap 14 3 -1 - -R M 2086 o - May 19 2 0 - -R M 2087 o - Mar 30 3 -1 - -R M 2087 o - May 11 2 0 - R NA 1994 o - Mar 21 0 -1 WAT R NA 1994 2017 - S Su>=1 2 0 CAT R NA 1995 2017 - Ap Su>=1 2 -1 WAT @@ -2106,7 +1980,8 @@ Z Africa/Casablanca -0:30:20 - LMT 1913 O 26 0 M %z 1984 Mar 16 1 - %z 1986 0 M %z 2018 O 28 3 -1 M %z +1 M %z 2026 S 20 2 +0 - %z Z Africa/Ceuta -0:21:16 - LMT 1901 Ja 1 0u 0 - WET 1918 May 6 23 0 1 WEST 1918 O 7 23 @@ -2119,7 +1994,8 @@ Z Africa/Ceuta -0:21:16 - LMT 1901 Ja 1 0u Z Africa/El_Aaiun -0:52:48 - LMT 1934 -1 - %z 1976 Ap 14 0 M %z 2018 O 28 3 -1 M %z +1 M %z 2026 S 20 2 +0 - %z Z Africa/Johannesburg 1:52 - LMT 1892 F 8 1:30 - SAST 1903 Mar 2 SA SAST @@ -2483,7 +2359,9 @@ Z America/Detroit -5:32:11 - LMT 1905 -5 u E%sT Z America/Edmonton -7:33:52 - LMT 1906 S -7 Ed M%sT 1987 --7 C M%sT +-7 C M%sT 2026 Jun 18 +-7 1 MDT 2026 N 1 2 +-6 - CST Z America/Eirunepe -4:39:28 - LMT 1914 -5 B %z 1988 S 12 -5 - %z 1993 S 28 From 3fe4062cc6216e4edee1ac981020173b3dc01a81 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 2 Aug 2026 13:22:39 -0400 Subject: [PATCH 262/481] Fix memory-safety bugs in the ispell/hunspell dictionary loader. Allocate CompoundAffix with room for its terminator, initialize the old-format flag buffer before NIAddAffix(), and reject incomplete or missing Hunspell AF aliases. None of these errors would be likely to trigger on real dictionary files, accounting for the lack of previous reports; but they're certainly bugs. Bug: #19595 Reported-by: Michael Malis Author: Andrey Rachitskiy Reviewed-by: Tom Lane Discussion: https://postgr.es/m/19595-7dc18b4e212c4757@postgresql.org Backpatch-through: 14 --- src/backend/tsearch/spell.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c index 15dccb47bf5..8ada640f988 100644 --- a/src/backend/tsearch/spell.c +++ b/src/backend/tsearch/spell.c @@ -1182,12 +1182,18 @@ getAffixFlagSet(IspellDict *Conf, char *s) errmsg("invalid affix alias \"%s\"", s))); if (curaffix > 0 && curaffix < Conf->nAffixData) + { + if (Conf->AffixData[curaffix] == NULL) + ereport(ERROR, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("invalid affix alias \"%s\"", s))); /* * Do not subtract 1 from curaffix because empty string was added * in NIImportOOAffixes */ return Conf->AffixData[curaffix]; + } else if (curaffix > Conf->nAffixData) ereport(ERROR, (errcode(ERRCODE_CONFIG_FILE_ERROR), @@ -1422,6 +1428,13 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename) tsearch_readline_end(&trst); if (ptype) pfree(ptype); + + /* Reject incomplete AF alias table. */ + if (Conf->useFlagAliases && curaffix != naffix) + ereport(ERROR, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("number of aliases is less than specified number %d", + naffix - 1))); } /* @@ -1449,6 +1462,8 @@ NIImportAffixes(IspellDict *Conf, const char *filename) bool oldformat = false; char *recoded = NULL; + flag[0] = '\0'; /* no flag seen yet */ + if (!tsearch_readline_begin(&trst, filename)) ereport(ERROR, (errcode(ERRCODE_CONFIG_FILE_ERROR), @@ -1998,7 +2013,8 @@ NISortAffixes(IspellDict *Conf) /* Store compound affixes in the Conf->CompoundAffix array */ if (Conf->naffixes > 1) qsort(Conf->Affix, Conf->naffixes, sizeof(AFFIX), cmpaffix); - Conf->CompoundAffix = ptr = palloc_array(CMPDAffix, Conf->naffixes); + /* +1 for terminator */ + Conf->CompoundAffix = ptr = palloc_array(CMPDAffix, Conf->naffixes + 1); ptr->affix = NULL; for (i = 0; i < Conf->naffixes; i++) From df8407d7dc7dc77165f56e5bdfed13ac72048696 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 2 Aug 2026 16:49:18 -0400 Subject: [PATCH 263/481] Tighten up TS dictionary cache entry creation. In the not-too-likely scenario where we successfully created a hash table entry for a TS dictionary, but then failed to make a small memory context for it, we left the hash entry in existence but with a garbage value for dictCtx. This confused the code the next time through, leading to a crash. Rearrange things so that we leave the hash entry in a well-defined state with dictCtx == NULL, and then the next try knows it still needs to make a memory context. Reported-by: Alexander Lakhin Author: Tom Lane Discussion: https://postgr.es/m/0f3ddeb5-0dbd-479c-9d0e-ae254758e624@gmail.com Backpatch-through: 14 --- src/backend/utils/cache/ts_cache.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c index 9e29f1386b0..1cec9a1f9a6 100644 --- a/src/backend/utils/cache/ts_cache.c +++ b/src/backend/utils/cache/ts_cache.c @@ -280,37 +280,50 @@ lookup_ts_dictionary_cache(Oid dictId) elog(ERROR, "text search template %u has no lexize method", template->tmpllexize); + /* + * OK, create or clear out the hashtable entry + */ if (entry == NULL) { bool found; - /* Now make the cache entry */ entry = (TSDictionaryCacheEntry *) hash_search(TSDictionaryCacheHash, &dictId, HASH_ENTER, &found); Assert(!found); /* it wasn't there a moment ago */ - /* Create private memory context the first time through */ + memset(entry, 0, sizeof(TSDictionaryCacheEntry)); + entry->dictId = dictId; + saveCtx = NULL; + } + else + { + saveCtx = entry->dictCtx; /* could be NULL if we failed before */ + memset(entry, 0, sizeof(TSDictionaryCacheEntry)); + entry->dictId = dictId; + entry->dictCtx = saveCtx; + } + + /* + * Create or clear the entry's private memory context + */ + if (saveCtx == NULL) + { saveCtx = AllocSetContextCreate(CacheMemoryContext, "TS dictionary", ALLOCSET_SMALL_SIZES); + entry->dictCtx = saveCtx; MemoryContextCopyAndSetIdentifier(saveCtx, NameStr(dict->dictname)); } else { - /* Clear the existing entry's private context */ - saveCtx = entry->dictCtx; /* Don't let context's ident pointer dangle while we reset it */ MemoryContextSetIdentifier(saveCtx, NULL); MemoryContextReset(saveCtx); MemoryContextCopyAndSetIdentifier(saveCtx, NameStr(dict->dictname)); } - MemSet(entry, 0, sizeof(TSDictionaryCacheEntry)); - entry->dictId = dictId; - entry->dictCtx = saveCtx; - entry->lexizeOid = template->tmpllexize; if (OidIsValid(template->tmplinit)) From 3fb599b26411a1322dec89759349ce4920e1055a Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Mon, 3 Aug 2026 15:51:59 +0900 Subject: [PATCH 264/481] Fix nullability check for a sub-select's upper-level Vars When checking whether a sub-select's output columns can produce NULL, so as to decide whether a NOT IN can be converted to an anti-join, query_outputs_are_not_nullable() falls back on find_nonnullable_vars() for targetlist entries that are plain Vars: if the sub-select's own quals prove the Var non-null, the output is non-nullable. But that test compared only varno and varattno, without checking varlevelsup. An outer reference in the targetlist could thus be matched against a Var of the sub-select's own range table that happens to share the same varno and varattno, wrongly proving the output non-nullable and allowing an invalid conversion to an anti-join, which yields wrong answers when the outer reference is NULL. To fix, restrict the fallback to Vars of the current query level. Author: Rui Zhao Reviewed-by: Tender Wang Reviewed-by: Richard Guo Discussion: https://postgr.es/m/CAHWVJhGuaFFRpmq4j+mcMcm_HC5QOT7LZsC9bf9b7BCBmvbfMA@mail.gmail.com Backpatch-through: 19 --- src/backend/optimizer/util/clauses.c | 3 ++- src/test/regress/expected/subselect.out | 24 ++++++++++++++++++++++++ src/test/regress/sql/subselect.sql | 15 +++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 7d7f2f9664b..337fc27262e 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -2163,7 +2163,8 @@ query_outputs_are_not_nullable(Query *query) if (expr_is_nonnullable(&subroot, expr, NOTNULL_SOURCE_CATALOG)) continue; - if (IsA(expr, Var)) + /* Note we can only prove things about this query's own Vars */ + if (IsA(expr, Var) && ((Var *) expr)->varlevelsup == 0) { Var *var = (Var *) expr; diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index 20140f171af..427b3765ae3 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -3998,4 +3998,28 @@ WHERE id NOT IN (SELECT id FROM notnull_notvalid_tab); ----+----- (0 rows) +-- No ANTI JOIN: the sub-select's output is an upper-level Var, so the +-- sub-select's own quals tell us nothing about its nullability +INSERT INTO null_tab VALUES (1, NULL); +INSERT INTO not_null_tab VALUES (2, 2); +EXPLAIN (COSTS OFF) +SELECT * FROM null_tab t1 +WHERE COALESCE(t1.id, -1) NOT IN + (SELECT t1.val FROM not_null_tab t2 WHERE t2.val IS NOT NULL); + QUERY PLAN +---------------------------------------------------------------------------- + Seq Scan on null_tab t1 + Filter: (NOT (ANY (COALESCE(id, '-1'::integer) = (SubPlan any_1).col1))) + SubPlan any_1 + -> Seq Scan on not_null_tab t2 +(4 rows) + +-- NOT IN with NULL on inner side should return no rows +SELECT * FROM null_tab t1 +WHERE COALESCE(t1.id, -1) NOT IN + (SELECT t1.val FROM not_null_tab t2 WHERE t2.val IS NOT NULL); + id | val +----+----- +(0 rows) + ROLLBACK; diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql index 3defbc29177..73fb346bbea 100644 --- a/src/test/regress/sql/subselect.sql +++ b/src/test/regress/sql/subselect.sql @@ -1751,4 +1751,19 @@ WHERE id NOT IN (SELECT id FROM notnull_notvalid_tab); SELECT * FROM not_null_tab WHERE id NOT IN (SELECT id FROM notnull_notvalid_tab); +-- No ANTI JOIN: the sub-select's output is an upper-level Var, so the +-- sub-select's own quals tell us nothing about its nullability +INSERT INTO null_tab VALUES (1, NULL); +INSERT INTO not_null_tab VALUES (2, 2); + +EXPLAIN (COSTS OFF) +SELECT * FROM null_tab t1 +WHERE COALESCE(t1.id, -1) NOT IN + (SELECT t1.val FROM not_null_tab t2 WHERE t2.val IS NOT NULL); + +-- NOT IN with NULL on inner side should return no rows +SELECT * FROM null_tab t1 +WHERE COALESCE(t1.id, -1) NOT IN + (SELECT t1.val FROM not_null_tab t2 WHERE t2.val IS NOT NULL); + ROLLBACK; From d2ac26eb9b1e8ad19fd526efb0ffff4fae5ed56f Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 3 Aug 2026 10:14:30 +0200 Subject: [PATCH 265/481] Fix missing space before WHERE in GRAPH_TABLE deparse get_graph_pattern_def() emitted the pattern-level WHERE keyword as "WHERE " with no leading space, so reverse-parsing produced output like "(o IS orders)WHERE (...)". The element-level WHERE deparse in get_path_pattern_expr_def() already prepends a separating space; the pattern-level branch was inconsistent with it. Emit " WHERE " to match. The output still re-parses to the same tree, so this is cosmetic. For test coverage, add a whole-pattern WHERE clause to the existing customers_us view, which is already reverse-parsed with pg_get_viewdef(). Author: Dhruv Chauhan Reviewed-by: Ashutosh Bapat Discussion: https://www.postgresql.org/message-id/flat/CANWwWcpHb0h7tg6otRnL-FV83jwQpAiyw1bhvv8T78kpwZ-0ow%40mail.gmail.com --- src/backend/utils/adt/ruleutils.c | 2 +- src/test/regress/expected/graph_table.out | 21 +++++++++++---------- src/test/regress/sql/graph_table.sql | 5 +++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 24bf1fbbc21..b5a9c8be56e 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -8135,7 +8135,7 @@ get_graph_pattern_def(GraphPattern *graph_pattern, deparse_context *context) if (graph_pattern->whereClause) { - appendStringInfoString(buf, "WHERE "); + appendStringInfoString(buf, " WHERE "); get_rule_expr(graph_pattern->whereClause, context, false); } } diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out index 46566b2e32f..b7a6182457d 100644 --- a/src/test/regress/expected/graph_table.out +++ b/src/test/regress/expected/graph_table.out @@ -965,13 +965,14 @@ SELECT * FROM GRAPH_TABLE (g4 MATCH (s WHERE s.id = 3)-[e]-(d) COLUMNS (s.val, e -- GRAPH_TABLE in views -- The query in the view definition is intentionally complex to test one view with many --- features like label disjunction, lateral references, WHERE clauses in graph --- patterns. +-- features like label disjunction, lateral references, WHERE clauses on graph +-- pattern elements as well as on the whole graph pattern. CREATE VIEW customers_us AS SELECT g.* FROM x1, GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.address = 'US' AND c.customer_id = x1.a) -[IS customer_orders | customer_wishlists ]-> (l IS orders | wishlists)-[ IS list_items]->(p IS products) + WHERE p.price > 0 COLUMNS (c.name AS customer_name, p.name AS product_name, p.price, x1.a AS a)) g ORDER BY customer_name, product_name; -- Dropping properties or labels used by a view is not allowed @@ -993,14 +994,14 @@ DETAIL: view customers_us depends on property price of property graph myshop HINT: Use DROP ... CASCADE to drop the dependent objects too. -- ruleutils reverse parsing SELECT pg_get_viewdef('customers_us'::regclass); - pg_get_viewdef ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - SELECT g.customer_name, + - g.product_name, + - g.price, + - g.a + - FROM x1, + - GRAPH_TABLE (myshop MATCH (c IS customers WHERE (((c.address)::text = 'US'::text) AND (c.customer_id = x1.a)))-[IS customer_orders|customer_wishlists]->(l IS orders|wishlists)-[IS list_items]->(p IS products) COLUMNS (c.name AS customer_name, p.name AS product_name, p.price AS price, x1.a AS a)) g+ + pg_get_viewdef +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + SELECT g.customer_name, + + g.product_name, + + g.price, + + g.a + + FROM x1, + + GRAPH_TABLE (myshop MATCH (c IS customers WHERE (((c.address)::text = 'US'::text) AND (c.customer_id = x1.a)))-[IS customer_orders|customer_wishlists]->(l IS orders|wishlists)-[IS list_items]->(p IS products) WHERE (p.price > (0)::numeric) COLUMNS (c.name AS customer_name, p.name AS product_name, p.price AS price, x1.a AS a)) g+ ORDER BY g.customer_name, g.product_name; (1 row) diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql index 3fb0e50ddb2..85298f93964 100644 --- a/src/test/regress/sql/graph_table.sql +++ b/src/test/regress/sql/graph_table.sql @@ -539,13 +539,14 @@ SELECT * FROM GRAPH_TABLE (g4 MATCH (s WHERE s.id = 3)-[e]-(d) COLUMNS (s.val, e -- GRAPH_TABLE in views -- The query in the view definition is intentionally complex to test one view with many --- features like label disjunction, lateral references, WHERE clauses in graph --- patterns. +-- features like label disjunction, lateral references, WHERE clauses on graph +-- pattern elements as well as on the whole graph pattern. CREATE VIEW customers_us AS SELECT g.* FROM x1, GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.address = 'US' AND c.customer_id = x1.a) -[IS customer_orders | customer_wishlists ]-> (l IS orders | wishlists)-[ IS list_items]->(p IS products) + WHERE p.price > 0 COLUMNS (c.name AS customer_name, p.name AS product_name, p.price, x1.a AS a)) g ORDER BY customer_name, product_name; -- Dropping properties or labels used by a view is not allowed From 1d24c588975a3982720cd7874496d1dffb83d292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Mon, 3 Aug 2026 13:52:41 +0200 Subject: [PATCH 266/481] Remove unused arg and dead code in set_attnotnull() The is_valid parameter was never referenced in the function body, and the 'thisatt' local variable is set but never used. Remove both. Oversight in a379061a22a8. Author: Sami Imseih Backpatch-through: 18 Discussion: https://postgr.es/m/CAA5RZ0tHnvSrfUy4jWJchjvkL_aJe0hCnZpMsFRdLrSxCne5qQ@mail.gmail.com --- src/backend/commands/tablecmds.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index ed212f5af5c..c323eb36a10 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -547,7 +547,7 @@ static void add_column_collation_dependency(Oid relid, int32 attnum, Oid collid) static ObjectAddress ATExecDropNotNull(Relation rel, const char *colName, bool recurse, LOCKMODE lockmode); static void set_attnotnull(List **wqueue, Relation rel, AttrNumber attnum, - bool is_valid, bool queue_validation); + bool queue_validation); static ObjectAddress ATExecSetNotNull(List **wqueue, Relation rel, char *conName, char *colName, bool recurse, bool recursing, @@ -1411,7 +1411,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, nncols = AddRelationNotNullConstraints(rel, stmt->nnconstraints, old_notnulls, connames); foreach_int(attrnum, nncols) - set_attnotnull(NULL, rel, attrnum, true, false); + set_attnotnull(NULL, rel, attrnum, false); ObjectAddressSet(address, RelationRelationId, relationId); @@ -7936,10 +7936,9 @@ ATExecDropNotNull(Relation rel, const char *colName, bool recurse, */ static void set_attnotnull(List **wqueue, Relation rel, AttrNumber attnum, - bool is_valid, bool queue_validation) + bool queue_validation) { Form_pg_attribute attr; - CompactAttribute *thisatt; Assert(!queue_validation || wqueue); @@ -7965,9 +7964,6 @@ set_attnotnull(List **wqueue, Relation rel, AttrNumber attnum, elog(ERROR, "cache lookup failed for attribute %d of relation %u", attnum, RelationGetRelid(rel)); - thisatt = TupleDescCompactAttr(RelationGetDescr(rel), attnum - 1); - thisatt->attnullability = ATTNULLABLE_VALID; - attr = (Form_pg_attribute) GETSTRUCT(tuple); attr->attnotnull = true; @@ -8149,7 +8145,7 @@ ATExecSetNotNull(List **wqueue, Relation rel, char *conName, char *colName, ObjectAddressSet(address, ConstraintRelationId, ccon->conoid); /* Mark pg_attribute.attnotnull for the column and queue validation */ - set_attnotnull(wqueue, rel, attnum, true, true); + set_attnotnull(wqueue, rel, attnum, true); InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), attnum); @@ -10070,7 +10066,6 @@ ATAddCheckNNConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, */ if (constr->contype == CONSTR_NOTNULL) set_attnotnull(wqueue, rel, ccon->attnum, - !constr->skip_validation, !constr->skip_validation); ObjectAddressSet(address, ConstraintRelationId, ccon->conoid); @@ -13771,7 +13766,7 @@ QueueNNConstraintValidation(List **wqueue, Relation conrel, Relation rel, } /* Set attnotnull appropriately without queueing another validation */ - set_attnotnull(NULL, rel, attnum, true, false); + set_attnotnull(NULL, rel, attnum, false); tab = ATGetQueueEntry(wqueue, rel); tab->verify_new_notnull = true; From 072b962d99c6317e5cd5a5ac11b21fae2cab6f8a Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 3 Aug 2026 12:25:01 -0400 Subject: [PATCH 267/481] Undo inadvertent loosening of archive filename checking. Commit c8a350a439826267186c187dbfbf1f839f7521aa attempted to consolidate code for identify possibly-compressed tar archives by suffix into a new function parse_tar_compress_algorithm(). Unfortunately, the refactoring wasn't perfect, and slightly changed the behavior at both existing call sites. In CreateBackupStreamer(), the previous code required the filename to consist of more than just a suffix, so the aforementioned commit had the effect of allowing pg_basebackup to accept a file from the server whose entire name was something like .tar.gz -- which should never happen, but let's reject it as previous releases did. In precheck_tar_backup_file(), the previous code required the suffix to be immediately adjacent to the prefix already checked, so the commit in question allowed pg_verifybackup to accept not only filenames like base.tar.gz but also filenames like baseFOOBARBAZ.tar.gz. While such filenames are perhaps unlikely, rejecting them is correct, so let's go back to that behavior. Discussion: http://postgr.es/m/CA+TgmoYJY8FkoeYKGF_YF1S6uOK7fd0Bd3zrw0XY_oZXbmVFpQ@mail.gmail.com Reported-by: Sarath Kumar Reviewed-by: Andrew Dunstan Backpatch-through: 19 --- src/bin/pg_basebackup/pg_basebackup.c | 4 ++-- src/bin/pg_verifybackup/pg_verifybackup.c | 8 +++++-- src/bin/pg_waldump/pg_waldump.c | 5 ++-- src/common/compression.c | 28 +++++++++++++++++------ src/include/common/compression.h | 2 +- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index 80dc3bbc8da..00408f1de49 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -1082,8 +1082,8 @@ CreateBackupStreamer(char *archive_name, char *spclocation, inject_manifest = (format == 't' && strcmp(basedir, "-") == 0 && manifest); /* Check whether it is a tar archive and its compression type */ - is_tar = parse_tar_compress_algorithm(archive_name, - &compressed_tar_algorithm); + is_tar = (parse_tar_compress_algorithm(archive_name, + &compressed_tar_algorithm) > 0); /* Is this any kind of compressed tar? */ is_compressed_tar = (is_tar && diff --git a/src/bin/pg_verifybackup/pg_verifybackup.c b/src/bin/pg_verifybackup/pg_verifybackup.c index bd4fe635c6f..a972dae3070 100644 --- a/src/bin/pg_verifybackup/pg_verifybackup.c +++ b/src/bin/pg_verifybackup/pg_verifybackup.c @@ -967,8 +967,12 @@ precheck_tar_backup_file(verifier_context *context, char *relpath, tblspc_oid = (Oid) num; } - /* Now, check the compression type of the tar */ - if (!parse_tar_compress_algorithm(suffix, &compress_algorithm)) + /* + * If parse_tar_compress_algorithm returns exactly 0, there are no + * characters between the prefix we already checked and the detected + * suffix. Any other case is unexpected. + */ + if (parse_tar_compress_algorithm(suffix, &compress_algorithm) != 0) { report_backup_error(context, "file \"%s\" is not expected in a tar format backup", diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c index c777e6763e5..d6b2a7adcbf 100644 --- a/src/bin/pg_waldump/pg_waldump.c +++ b/src/bin/pg_waldump/pg_waldump.c @@ -1242,7 +1242,7 @@ main(int argc, char **argv) if (waldir != NULL) { /* Check whether the path looks like a tar archive by its extension */ - if (parse_tar_compress_algorithm(waldir, &compression)) + if (parse_tar_compress_algorithm(waldir, &compression) >= 0) { split_path(waldir, &private.archive_dir, &private.archive_name); } @@ -1286,7 +1286,8 @@ main(int argc, char **argv) pg_fatal("could not open directory \"%s\": %m", waldir); } - if (fname != NULL && parse_tar_compress_algorithm(fname, &compression)) + if (fname != NULL && + parse_tar_compress_algorithm(fname, &compression) >= 0) { private.archive_dir = waldir; private.archive_name = fname; diff --git a/src/common/compression.c b/src/common/compression.c index ae2089d9406..e78913ad9dc 100644 --- a/src/common/compression.c +++ b/src/common/compression.c @@ -42,33 +42,47 @@ static bool expect_boolean_value(char *keyword, char *value, pg_compress_specification *result); /* - * Look up a compression algorithm by archive file extension. Returns true and - * sets *algorithm if the extension is recognized. Otherwise returns false. + * Look up a compression algorithm by archive file extension. Sets *algorithm + * and returns the length of the non-extension portion of the filename, or -1 + * if the filename does not end with a recognized tar extension. */ -bool +int parse_tar_compress_algorithm(const char *fname, pg_compress_algorithm *algorithm) { - size_t fname_len = strlen(fname); + int fname_len = strlen(fname); if (fname_len >= 4 && strcmp(fname + fname_len - 4, ".tar") == 0) + { *algorithm = PG_COMPRESSION_NONE; + return fname_len - 4; + } else if (fname_len >= 4 && strcmp(fname + fname_len - 4, ".tgz") == 0) + { *algorithm = PG_COMPRESSION_GZIP; + return fname_len - 4; + } else if (fname_len >= 7 && strcmp(fname + fname_len - 7, ".tar.gz") == 0) + { *algorithm = PG_COMPRESSION_GZIP; + return fname_len - 7; + } else if (fname_len >= 8 && strcmp(fname + fname_len - 8, ".tar.lz4") == 0) + { *algorithm = PG_COMPRESSION_LZ4; + return fname_len - 8; + } else if (fname_len >= 8 && strcmp(fname + fname_len - 8, ".tar.zst") == 0) + { *algorithm = PG_COMPRESSION_ZSTD; - else - return false; + return fname_len - 8; + } - return true; + return -1; } /* diff --git a/src/include/common/compression.h b/src/include/common/compression.h index f99c747cdd3..adbe668a105 100644 --- a/src/include/common/compression.h +++ b/src/include/common/compression.h @@ -41,7 +41,7 @@ typedef struct pg_compress_specification extern void parse_compress_options(const char *option, char **algorithm, char **detail); -extern bool parse_tar_compress_algorithm(const char *fname, +extern int parse_tar_compress_algorithm(const char *fname, pg_compress_algorithm *algorithm); extern bool parse_compress_algorithm(char *name, pg_compress_algorithm *algorithm); extern const char *get_compress_algorithm_name(pg_compress_algorithm algorithm); From 72b0fee51df2e5d9ab3313407f1a5313fd768882 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 3 Aug 2026 11:34:58 -0700 Subject: [PATCH 268/481] Do not log subscription conninfo. Logging connection information, even at DEBUG1, creates unnecessary risks. Remove the entire log message because it had no other useful content. Addresses finding 14 in report from linked discussion. Reported-by: Noah Misch Discussion: https://postgr.es/m/20260710195902.4f.noahmisch@microsoft.com Backpatch-through: 14 --- src/backend/replication/logical/worker.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index 3c4a0b907a4..24ce03be067 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -5995,10 +5995,6 @@ SetupApplyOrSyncWorker(int worker_slot) InitializeLogRepWorker(); - /* Connect to the origin and start the replication. */ - elog(DEBUG1, "connecting to publisher using connection string \"%s\"", - MySubscription->conninfo); - /* * Setup callback for syscache so that we know when something changes in * the subscription relation state. From 343d98c3601abf3060ff82b7b2a8bc7903105bf3 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Mon, 3 Aug 2026 20:44:57 +0200 Subject: [PATCH 269/481] Don't skip invalid databases when enabling data checksums When enabling checksums cannot process a database, the launcher uses DatabaseExists to tell a concurrent drop (benign) from a real failure. Since 1df361e3d82 that check also treats a present, but-invalid, data- base as non-existent. An interrupted DROP DATABASE flush the invalid marker before the row and files are removed, so a crash or ERROR can leave an invalid row whose files remain on disk. Report a database as existing whenever its catalog row is found to ensure that checksums cannot be enabled if there are invalid databases. The AccessShareLock in DatabaseExists already waits out an in-flight drop, so an invalid-but-present row can only be an interrupted drop leftover whose files still need checksums; enabling then aborts until it is dropped. Backpatch to v19 where online checksums were introduced. Author: Ayush Tiwari Reviewed-by: Zsolt Parragi Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CAN4CZFOGdqxtZ5-6gb4apqmvoH=Z+TNH8RKJ3mVtoR1HirKQWg@mail.gmail.com Backpatch-through: 19 --- src/backend/commands/dbcommands.c | 2 + src/backend/postmaster/datachecksum_state.c | 29 +++------ .../modules/test_checksums/t/005_injection.pl | 63 +++++++++++++++++++ 3 files changed, 75 insertions(+), 19 deletions(-) diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index fa2ce033391..600fc742a68 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -1883,6 +1883,8 @@ dropdb(const char *dbname, bool missing_ok, bool force) systable_inplace_update_finish(inplace_state, tup); XLogFlush(XactLastRecEnd); + INJECTION_POINT("dropdb-after-invalid-marker", NULL); + /* * Also delete the tuple - transactionally. If this transaction commits, * the row will be gone, but if we fail, dropdb() can be invoked again. diff --git a/src/backend/postmaster/datachecksum_state.c b/src/backend/postmaster/datachecksum_state.c index a83236c3683..122640b0a9a 100644 --- a/src/backend/postmaster/datachecksum_state.c +++ b/src/backend/postmaster/datachecksum_state.c @@ -588,8 +588,10 @@ enable_data_checksums(PG_FUNCTION_ARGS) * An invalid database cannot be connected to, so the worker would fail to * process it, and unlike a dropped database its files stay around. Error * out early with a hint rather than failing halfway through processing. A - * database which turns invalid after this check is handled by the - * launcher treating it as concurrently dropped. + * database which turns invalid after this check, for example from an + * interrupted DROP DATABASE, instead makes its worker fail; the launcher + * then aborts and leaves checksums disabled, since the invalid database's + * files would otherwise be left without valid checksums. */ ErrorOnInvalidDatabases(); @@ -996,11 +998,9 @@ ProcessDatabase(DataChecksumsWorkerDatabase *db) /* * A worker which started but failed before reporting a result has most - * likely FATALed in InitPostgres. If the database was dropped, or was - * invalidated by a DROP DATABASE which is bound to remove its files, - * after we built the database list then that is the expected outcome and - * not an error, so apply the same heuristic as when the worker failed to - * start. + * likely FATALed in InitPostgres. If the database was dropped after we + * built the database list then that is the expected outcome and not an + * error, so apply the same heuristic as when the worker failed to start. */ if (result == DATACHECKSUMSWORKER_FAILED && !DatabaseExists(db->dboid)) result = DATACHECKSUMSWORKER_DROPDB; @@ -1415,9 +1415,9 @@ DataChecksumsShmemRequest(void *arg) * DatabaseExists * * Scans the system catalog to check if a database with the given Oid exists - * and returns true if it is found and valid, else false. Note, we cannot use - * database_is_invalid_oid here as it will ERROR out, and we want to gracefully - * handle errors. + * and returns true if it is found, even if it is marked invalid. An invalid + * database still has files that need checksums, so only a missing catalog row + * proves that a concurrent DROP DATABASE completed. */ static bool DatabaseExists(Oid dboid) @@ -1427,7 +1427,6 @@ DatabaseExists(Oid dboid) SysScanDesc scan; bool found; HeapTuple tuple; - Form_pg_database pg_database_tuple; StartTransactionCommand(); @@ -1450,14 +1449,6 @@ DatabaseExists(Oid dboid) tuple = systable_getnext(scan); found = HeapTupleIsValid(tuple); - /* If the Oid exists, ensure that it's not partially dropped */ - if (found) - { - pg_database_tuple = (Form_pg_database) GETSTRUCT(tuple); - if (database_is_invalid_form(pg_database_tuple)) - found = false; - } - systable_endscan(scan); table_close(rel, AccessShareLock); diff --git a/src/test/modules/test_checksums/t/005_injection.pl b/src/test/modules/test_checksums/t/005_injection.pl index 2387e4399ba..60bb716d922 100644 --- a/src/test/modules/test_checksums/t/005_injection.pl +++ b/src/test/modules/test_checksums/t/005_injection.pl @@ -79,6 +79,69 @@ ); } +# --------------------------------------------------------------------------- +# Test an interrupted DROP DATABASE while checksum enabling is in progress +# + +disable_data_checksums($node, wait => 1); + +$node->safe_psql('postgres', 'CREATE DATABASE invalid_dropdb;'); +$node->safe_psql('invalid_dropdb', + "CREATE TABLE bad_t AS SELECT generate_series(1,1000) AS a;"); + +# Hold the worker in "postgres", so invalid_dropdb is still waiting in the +# launcher's database list when DROP DATABASE is interrupted. +my $hold = $node->background_psql('postgres'); +$hold->query_safe('CREATE TEMP TABLE holdme (a int);'); + +my $dropdb_log_offset = -s $node->logfile; +enable_data_checksums($node); +$node->poll_query_until( + 'postgres', qq[ + SELECT count(*) > 0 FROM pg_stat_activity + WHERE backend_type = 'datachecksums worker' AND datname = 'postgres' + AND query LIKE 'Waiting for % temp tables to be removed'] +) or die "timed out waiting for worker to wait for temporary tables"; + +my $dropdb_log = + PostgreSQL::Test::Utils::slurp_file($node->logfile, $dropdb_log_offset); +unlike( + $dropdb_log, + qr/initiating data checksum processing in database "invalid_dropdb"/, + 'invalid database has not been processed yet'); + +# Leave the database durably marked invalid, but abort DROP DATABASE before +# its catalog row and files are removed. +$node->safe_psql('postgres', + "SELECT injection_points_attach('dropdb-after-invalid-marker','error');"); +my ($drop_ret, $drop_stdout, $drop_stderr) = + $node->psql('postgres', 'DROP DATABASE invalid_dropdb;'); +isnt($drop_ret, 0, 'DROP DATABASE was interrupted after invalidation'); +like( + $drop_stderr, + qr/dropdb-after-invalid-marker/, + 'DROP DATABASE reached the invalid-marker injection point'); +$node->safe_psql('postgres', + "SELECT injection_points_detach('dropdb-after-invalid-marker');"); + +my $invalid_state = $node->safe_psql('postgres', + "SELECT datconnlimit FROM pg_database WHERE datname = 'invalid_dropdb';"); +is($invalid_state, '-2', 'interrupted DROP left an invalid database row'); + +# Let checksum processing continue. The invalid database must be treated as +# a processing failure, not as a successfully dropped database. +$hold->query_safe('DROP TABLE holdme;'); +$hold->quit; +$node->poll_query_until('postgres', + "SELECT count(*) = 0 " + . "FROM pg_catalog.pg_stat_activity " + . "WHERE backend_type = 'datachecksums launcher';") + or die "timed out waiting for datachecksums launcher to exit"; +test_checksum_state($node, 'off'); + +# Remove the invalid database and continue with the remaining tests. +$node->safe_psql('postgres', 'DROP DATABASE invalid_dropdb;'); + # --------------------------------------------------------------------------- # Test concurrent CREATE DATABASE which use the file_copy strategy # From 9eccdae22aca63360c48f5005d062a1684f017af Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 3 Aug 2026 12:21:05 -0700 Subject: [PATCH 270/481] Fix lock release for role membership grants in DROP OWNED BY. Commit 6566133c5f5 added a case for AuthMemRelationId in AcquireDeletionLock(), but not ReleaseDeletionLock(). The fall-through case would go to UnlockDatabaseObject(), which would raise a WARNING; and the lock would be retained until the end of the transaction. Add the missing branch. Discussion: https://postgr.es/m/2487ddcd737d4fc8e408e87aa9ad4365eed3bbb3.camel@j-davis.com Backpatch-through: 16 --- src/backend/catalog/dependency.c | 3 ++ .../isolation/expected/drop-owned-grant.out | 8 +++++ src/test/isolation/isolation_schedule | 1 + .../isolation/specs/drop-owned-grant.spec | 30 +++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 src/test/isolation/expected/drop-owned-grant.out create mode 100644 src/test/isolation/specs/drop-owned-grant.spec diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index c54774b3275..52cd2caf9d4 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -1600,6 +1600,9 @@ ReleaseDeletionLock(const ObjectAddress *object) { if (object->classId == RelationRelationId) UnlockRelationOid(object->objectId, AccessExclusiveLock); + else if (object->classId == AuthMemRelationId) + UnlockSharedObject(object->classId, object->objectId, 0, + AccessExclusiveLock); else /* assume we should lock the whole object not a sub-object */ UnlockDatabaseObject(object->classId, object->objectId, 0, diff --git a/src/test/isolation/expected/drop-owned-grant.out b/src/test/isolation/expected/drop-owned-grant.out new file mode 100644 index 00000000000..ea6cca277b6 --- /dev/null +++ b/src/test/isolation/expected/drop-owned-grant.out @@ -0,0 +1,8 @@ +Parsed test spec with 2 sessions + +starting permutation: s1b s1d s2d s1c +step s1b: BEGIN; +step s1d: DROP OWNED BY regress_dropowned_grantor; +step s2d: DROP OWNED BY regress_dropowned_grantor; +step s1c: COMMIT; +step s2d: <... completed> diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 26abed9f9f0..df8ce44ede6 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -129,3 +129,4 @@ test: lock-nowait test: for-portion-of test: ddl-dependency-locking test: pub-concurrent-drop +test: drop-owned-grant diff --git a/src/test/isolation/specs/drop-owned-grant.spec b/src/test/isolation/specs/drop-owned-grant.spec new file mode 100644 index 00000000000..636cc213a6b --- /dev/null +++ b/src/test/isolation/specs/drop-owned-grant.spec @@ -0,0 +1,30 @@ +# Test locking of role membership grants during concurrent DROP OWNED BY. + +setup +{ + CREATE ROLE regress_dropowned_role; + CREATE ROLE regress_dropowned_member; + CREATE ROLE regress_dropowned_grantor; + GRANT regress_dropowned_role TO regress_dropowned_grantor + WITH ADMIN OPTION; + SET ROLE regress_dropowned_grantor; + GRANT regress_dropowned_role TO regress_dropowned_member; + RESET ROLE; +} + +teardown +{ + DROP ROLE regress_dropowned_member; + DROP ROLE regress_dropowned_grantor; + DROP ROLE regress_dropowned_role; +} + +session s1 +step s1b { BEGIN; } +step s1d { DROP OWNED BY regress_dropowned_grantor; } +step s1c { COMMIT; } + +session s2 +step s2d { DROP OWNED BY regress_dropowned_grantor; } + +permutation s1b s1d s2d s1c From 608704adee75fd4316a10f4aa9a93aa8c6dc7eeb Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 3 Aug 2026 13:21:46 -0700 Subject: [PATCH 271/481] Improve DROP SERVER handling of dependent subscriptions. We do not allow a DROP SERVER ... CASCADE to implicitly drop a subscription, because it's in a shared catalog and dropping a subscription has side effects. Instead we throw an error and the user must drop the subscription explicitly. Document this behavior and add a HINT to the error message. Generalize AcquireDeletionLock()/ReleaseDeletionLock() to use shared object locks for all shared catalogs, which includes AuthMemRelationId and now SubscriptionRelationId. Move error message after AcquireDeletionLock() to avoid an unnecessary error if there's a concurrent DROP SUBSCRIPTION. Addresses finding 10 & 15 in report from linked discussion. Reported-by: Noah Misch Discussion: https://postgr.es/m/20260710195902.4f.noahmisch@microsoft.com Backpatch-through: 19 --- doc/src/sgml/ref/drop_server.sgml | 4 +++ src/backend/catalog/dependency.c | 31 +++++++++++++--------- src/test/regress/expected/subscription.out | 4 +++ src/test/regress/sql/subscription.sql | 2 ++ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/doc/src/sgml/ref/drop_server.sgml b/doc/src/sgml/ref/drop_server.sgml index f83a661b3eb..5fa0b763f36 100644 --- a/doc/src/sgml/ref/drop_server.sgml +++ b/doc/src/sgml/ref/drop_server.sgml @@ -66,6 +66,10 @@ DROP SERVER [ IF EXISTS ] name [, . user mappings), and in turn all objects that depend on those objects (see ). + However, a subscription that uses the server is never dropped + automatically; it must be dropped with + DROP SUBSCRIPTION + before the server can be dropped. diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 52cd2caf9d4..c8dd78341eb 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -900,17 +900,6 @@ findDependentObjects(const ObjectAddress *object, object->objectSubId == 0) continue; - /* - * Check that the dependent object is not in a shared catalog, which - * is not supported by doDeletion(). - */ - if (IsSharedRelation(otherObject.classId)) - ereport(ERROR, - (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), - errmsg("cannot drop %s because %s depends on it", - getObjectDescription(object, false), - getObjectDescription(&otherObject, false)))); - /* * Must lock the dependent object before recursing to it. */ @@ -931,6 +920,22 @@ findDependentObjects(const ObjectAddress *object, continue; } + /* + * Check that the dependent object is not in a shared catalog, which + * is not supported by doDeletion(). + */ + if (IsSharedRelation(otherObject.classId)) + { + char *otherObjDesc = getObjectDescription(&otherObject, + false); + + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot drop %s because %s depends on it", + getObjectDescription(object, false), otherObjDesc), + errhint("Drop %s first.", otherObjDesc))); + } + /* * We do need to delete it, so identify objflags to be passed down, * which depend on the dependency type. @@ -1579,7 +1584,7 @@ AcquireDeletionLock(const ObjectAddress *object, int flags) else LockRelationOid(object->objectId, AccessExclusiveLock); } - else if (object->classId == AuthMemRelationId) + else if (IsSharedRelation(object->classId)) LockSharedObject(object->classId, object->objectId, 0, AccessExclusiveLock); else @@ -1600,7 +1605,7 @@ ReleaseDeletionLock(const ObjectAddress *object) { if (object->classId == RelationRelationId) UnlockRelationOid(object->objectId, AccessExclusiveLock); - else if (object->classId == AuthMemRelationId) + else if (IsSharedRelation(object->classId)) UnlockSharedObject(object->classId, object->objectId, 0, AccessExclusiveLock); else diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index 6d89cec1503..229402826eb 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -205,6 +205,10 @@ ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection; WARNING: changing the foreign-data wrapper connection function can cause the options for dependent objects to become invalid DROP USER MAPPING FOR regress_subscription_user2 SERVER test_server; REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user2; +-- fail, subscription depends on the server and cannot be dropped by CASCADE +DROP SERVER test_server CASCADE; +ERROR: cannot drop server test_server because subscription regress_testsub6 depends on it +HINT: Drop subscription regress_testsub6 first. REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user3; SET SESSION AUTHORIZATION regress_subscription_user3; -- ok, lacks USAGE on test_server, but replacing connection anyway diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql index cfee0b41224..03e047b8ce0 100644 --- a/src/test/regress/sql/subscription.sql +++ b/src/test/regress/sql/subscription.sql @@ -150,6 +150,8 @@ ALTER SUBSCRIPTION regress_testsub6 OWNER TO regress_subscription_user2; ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection; DROP USER MAPPING FOR regress_subscription_user2 SERVER test_server; REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user2; +-- fail, subscription depends on the server and cannot be dropped by CASCADE +DROP SERVER test_server CASCADE; REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user3; SET SESSION AUTHORIZATION regress_subscription_user3; From 8c1723f550a7adf6373c8c507e819fc3249d793a Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 3 Aug 2026 13:41:17 -0700 Subject: [PATCH 272/481] postgres_fdw: reject use_scram_passthrough for subscriptions. The subscription is initiated from a logical replication worker, so SCRAM pass-through won't work. Partially addresses finding 3 in report from linked discussion. Reported-by: Noah Misch Discussion: https://postgr.es/m/20260710195902.4f.noahmisch@microsoft.com Backpatch-through: 19 --- contrib/postgres_fdw/connection.c | 12 ++++++++++++ contrib/postgres_fdw/t/010_subscription.pl | 16 +++++++++++++++- doc/src/sgml/postgres-fdw.sgml | 7 +++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c index aab21695979..094eac2f343 100644 --- a/contrib/postgres_fdw/connection.c +++ b/contrib/postgres_fdw/connection.c @@ -2479,6 +2479,18 @@ postgres_fdw_connection(PG_FUNCTION_ARGS) char *appname; char *sep = ""; + /* + * SCRAM pass-through cannot work for subscriptions because the connection + * happens in a worker process. + */ + if (UseScramPassthrough(server, user)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("SCRAM pass-through authentication is not supported for subscription connections"), + errdetail("The foreign server or user mapping for user \"%s\" has \"use_scram_passthrough\" enabled.", + GetUserNameFromId(userid, false)), + errhint("Store a password in the user mapping instead."))); + construct_connection_params(server, user, &keywords, &values, &appname); initStringInfo(&str); diff --git a/contrib/postgres_fdw/t/010_subscription.pl b/contrib/postgres_fdw/t/010_subscription.pl index c34b3d15b8d..449fa35ce31 100644 --- a/contrib/postgres_fdw/t/010_subscription.pl +++ b/contrib/postgres_fdw/t/010_subscription.pl @@ -41,7 +41,21 @@ ); $node_subscriber->safe_psql('postgres', - "CREATE USER MAPPING FOR PUBLIC SERVER tap_server"); + "CREATE USER MAPPING FOR PUBLIC SERVER tap_server OPTIONS (use_scram_passthrough 'true')" +); + +my ($ret, $stdout, $stderr) = $node_subscriber->psql('postgres', + "CREATE SUBSCRIPTION tap_sub SERVER tap_server PUBLICATION tap_pub WITH (password_required=false)" +); +isnt($ret, 0, 'CREATE SUBSCRIPTION fails with use_scram_passthrough'); +like( + $stderr, + qr/ERROR.*SCRAM pass-through authentication is not supported for subscription connections/, + 'CREATE SUBSCRIPTION gives correct connection error'); + +$node_subscriber->safe_psql('postgres', + "ALTER USER MAPPING FOR PUBLIC SERVER tap_server OPTIONS (DROP use_scram_passthrough)" +); $node_subscriber->safe_psql('postgres', "CREATE SUBSCRIPTION tap_sub SERVER tap_server PUBLICATION tap_pub WITH (password_required=false)" diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml index b9e1b04463e..8b0669f672d 100644 --- a/doc/src/sgml/postgres-fdw.sgml +++ b/doc/src/sgml/postgres-fdw.sgml @@ -861,6 +861,13 @@ OPTIONS (ADD password_required 'false'); This is a technical requirement of the SCRAM protocol. + + + + The foreign server must not be used for subscription connections + (see ). + + From 98bcb0ab8aa3c783adc27e677ab861a4a8baa411 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Tue, 4 Aug 2026 08:52:00 +0530 Subject: [PATCH 273/481] Validate publisher for retain_dead_tuples in the apply worker. Enabling retain_dead_tuples requires the publisher to run PostgreSQL 19 or later and to not be in recovery. Previously this was checked only at DDL time. That forced ALTER SUBSCRIPTION ... ENABLE to connect to the publisher, so pg_upgrade (which re-enables subscriptions during restore) failed if the publisher was unreachable. It was also not authoritative, since the publisher's version or recovery status can change afterwards, for example after a failover. Perform the check authoritatively in the apply worker when it connects, and stop doing it when enabling a subscription. ENABLE is the only command issued during restore that triggered it, so this also fixes the pg_upgrade failure. The DDL-time check is kept as a convenience for the other paths, none of which are issued during restore. Reported-by: Noah Misch Analyzed-by: Jeff Davis Author: Amit Kapila Reviewed-by: Jeff Davis Reviewed-by: Hayato Kuroda Backpatch-through: 19, where it was introduced Discussion: https://postgr.es/m/20260710195902.4f.noahmisch@microsoft.com --- src/backend/commands/subscriptioncmds.c | 22 +++++++++------------- src/backend/replication/logical/worker.c | 15 +++++++++++++++ src/include/commands/subscriptioncmds.h | 4 ++++ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index e330fb13e42..9671541caf9 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -135,7 +135,6 @@ static void check_publications_origin_sequences(WalReceiverConn *wrconn, Oid *subrel_local_oids, int subrel_count, char *subname); -static void check_pub_dead_tuple_retention(WalReceiverConn *wrconn); 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); @@ -918,7 +917,7 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, NULL, 0, stmt->subname); if (opts.retaindeadtuples) - check_pub_dead_tuple_retention(wrconn); + CheckPubDeadTupleRetention(wrconn); /* * Set sync state based on if we were asked to do data copy or @@ -1931,14 +1930,6 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, ApplyLauncherWakeupAtCommit(); update_tuple = true; - - /* - * The subscription might be initially created with - * connect=false and retain_dead_tuples=true, meaning the - * remote server's status may not be checked. Ensure this - * check is conducted now. - */ - check_pub_rdt = sub->retaindeadtuples && opts.enabled; break; } @@ -2275,7 +2266,7 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, PG_TRY(); { if (retain_dead_tuples) - check_pub_dead_tuple_retention(wrconn); + CheckPubDeadTupleRetention(wrconn); check_publications_origin_tables(wrconn, sub->publications, false, retain_dead_tuples, origin, NULL, 0, @@ -3147,10 +3138,15 @@ check_publications_origin_sequences(WalReceiverConn *wrconn, List *publications, * than the PG19, or if the publisher is in recovery (i.e., it is a standby * server). * + * This is used both at DDL time (as a convenience, when a connection to the + * publisher is already being made) and by the apply worker when it connects, + * which is the authoritative check because the publisher's version and + * recovery status can change after the DDL command. + * * See comments atop worker.c for a detailed explanation. */ -static void -check_pub_dead_tuple_retention(WalReceiverConn *wrconn) +void +CheckPubDeadTupleRetention(WalReceiverConn *wrconn) { WalRcvExecResult *res; Oid RecoveryRow[1] = {BOOLOID}; diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index 24ce03be067..2dd421412d6 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -5734,6 +5734,21 @@ run_apply_worker(void) */ (void) walrcv_identify_system(LogRepWorkerWalRcvConn, &startpointTLI, NULL); + /* + * If retain_dead_tuples is enabled, verify that the publisher is + * suitable, that is, it runs a version that supports the feature and is + * not in recovery. This is the authoritative check. Although the same + * validation is performed opportunistically at DDL time, the publisher's + * version or recovery status may have changed since then, for example + * after a failover. + */ + if (MySubscription->retaindeadtuples) + { + StartTransactionCommand(); + CheckPubDeadTupleRetention(LogRepWorkerWalRcvConn); + CommitTransactionCommand(); + } + set_apply_error_context_origin(originname); set_stream_options(&options, slotname, &origin_startpos); diff --git a/src/include/commands/subscriptioncmds.h b/src/include/commands/subscriptioncmds.h index 63504232a14..c735db60020 100644 --- a/src/include/commands/subscriptioncmds.h +++ b/src/include/commands/subscriptioncmds.h @@ -18,6 +18,8 @@ #include "catalog/objectaddress.h" #include "parser/parse_node.h" +struct WalReceiverConn; /* avoid pulling in walreceiver.h here */ + extern ObjectAddress CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, bool isTopLevel); extern ObjectAddress AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, bool isTopLevel); @@ -36,4 +38,6 @@ extern void CheckSubDeadTupleRetention(bool check_guc, bool sub_disabled, bool retention_active, bool max_retention_set); +extern void CheckPubDeadTupleRetention(struct WalReceiverConn *wrconn); + #endif /* SUBSCRIPTIONCMDS_H */ From 5cb0f004f179435dcb53b94e9b5827d540886b42 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Tue, 4 Aug 2026 16:09:29 +1200 Subject: [PATCH 274/481] Fix missing MCXT_ALLOC_NO_OOM handling in MemoryContextAllocAligned Fix missing NULL check in MemoryContextAllocAligned(). The underlying call to MemoryContextAllocExtended() could return NULL when flags contains MCXT_ALLOC_NO_OOM and the underlying malloc fails. There are no current callers using MemoryContextAllocAligned() that pass the MCXT_ALLOC_NO_OOM in core, so no live bug fix in core here. However, an extension might use this pattern, so we'd better fix. Fix this so we correctly pass the NULL to the caller rather than trying to write to a NULL memory address. This also fixes the same bug in AlignedAllocRealloc(), which is also unused in core. Backpatch to v16, where these functions first appeared. Author: Chao Li Discussion: https://postgr.es/m/07DAC4C3-120D-4F3C-8FEE-BA236F7E9C1D@gmail.com Backpatch-through: 16 --- src/backend/utils/mmgr/mcxt.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index 930fc457328..594c7a93bba 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -1541,6 +1541,13 @@ MemoryContextAllocAligned(MemoryContext context, unaligned = MemoryContextAllocExtended(context, alloc_size, flags & ~MCXT_ALLOC_ZERO); + if (unlikely(unaligned == NULL)) + { + /* NULL can be returned only when using MCXT_ALLOC_NO_OOM */ + Assert(flags & MCXT_ALLOC_NO_OOM); + return NULL; + } + /* compute the aligned pointer */ aligned = (void *) TYPEALIGN(alignto, (char *) unaligned + sizeof(MemoryChunk)); From 7746f7492d5b521f66af1e99cd42024cae8dde82 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Tue, 4 Aug 2026 17:59:58 +1200 Subject: [PATCH 275/481] Fix missing money overflow checks for INT64_MIN / -1 Similar to what 1f7cb5c30 did for the INT types, protect against overflow when dividing the lowest possible money value by -1. This cannot be represented on a two's complement machine. Without this check, the result depends on the machine, and in the worst case, could result in a crash. With the fix installed, this will now result in: ERROR: money out of range Bug: #19585 Author: Andrey Rachitskiy Reported-by: Michael Malis Reviewed-by: Tristan Partin Reviewed-by: Rafia Sabih Discussion: https://postgr.es/m/19586-bb603bf5ad9934dd%40postgresql.org Discussion: https://postgr.es/m/CAB8bMisnXJVXte6s3kUOpuuAY9%3D9kehG6MMX-%2BTQoFsSGan22Q%40mail.gmail.com Backpatch-through: 14 --- src/backend/utils/adt/cash.c | 16 ++++++++++++++++ src/test/regress/expected/money.out | 8 ++++++++ src/test/regress/sql/money.sql | 4 ++++ 3 files changed, 28 insertions(+) diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c index 4bf60085c61..310b3bb3fca 100644 --- a/src/backend/utils/adt/cash.c +++ b/src/backend/utils/adt/cash.c @@ -161,6 +161,22 @@ cash_div_int64(Cash c, int64 i) (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); + /* + * INT64_MIN / -1 is problematic, since the result can't be represented on + * a two's-complement machine. Some machines produce INT64_MIN, some + * produce zero, some throw an exception. We can dodge the problem by + * recognizing that division by -1 is the same as negation. + */ + if (i == -1) + { + if (unlikely(c == PG_INT64_MIN)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("money out of range"))); + return -c; + } + + /* No overflow is possible */ return c / i; } diff --git a/src/test/regress/expected/money.out b/src/test/regress/expected/money.out index cc2ff4d96e8..e7fdb9b7d0d 100644 --- a/src/test/regress/expected/money.out +++ b/src/test/regress/expected/money.out @@ -539,6 +539,14 @@ SELECT '-1'::money / 1.175494e-38::float4; ERROR: money out of range SELECT '92233720368547758.07'::money * 2::int4; ERROR: money out of range +SELECT '-92233720368547758.08'::money * -1::int8; +ERROR: money out of range +SELECT '-92233720368547758.08'::money / -1::int8; +ERROR: money out of range +SELECT '-92233720368547758.08'::money / -1::int4; +ERROR: money out of range +SELECT '-92233720368547758.08'::money / -1::int2; +ERROR: money out of range SELECT '1'::money / 0::int2; ERROR: division by zero SELECT '42'::money * 'inf'::float8; diff --git a/src/test/regress/sql/money.sql b/src/test/regress/sql/money.sql index b888ec21c30..d769a211090 100644 --- a/src/test/regress/sql/money.sql +++ b/src/test/regress/sql/money.sql @@ -142,6 +142,10 @@ SELECT '-92233720368547758.08'::money - '0.01'::money; SELECT '92233720368547758.07'::money * 2::float8; SELECT '-1'::money / 1.175494e-38::float4; SELECT '92233720368547758.07'::money * 2::int4; +SELECT '-92233720368547758.08'::money * -1::int8; +SELECT '-92233720368547758.08'::money / -1::int8; +SELECT '-92233720368547758.08'::money / -1::int4; +SELECT '-92233720368547758.08'::money / -1::int2; SELECT '1'::money / 0::int2; SELECT '42'::money * 'inf'::float8; SELECT '42'::money * '-inf'::float8; From ce6e434ceeb05d1aaf64a3f48c5927f46ea3c2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Tue, 4 Aug 2026 09:06:46 +0200 Subject: [PATCH 276/481] Fix ALTER COLUMN ... DROP EXPRESSION with subpartitions Per commit 8bf6ec3ba3a4, a column can be GENERATED only if it is such in the whole inheritance tree. For this reason, ATPrepDropExpression refuses to be called with ONLY on a partitioned table. To detect this, the current implementation checks whether recurse is set to false and the rel has direct children. Recursion is implemented with ATSimpleRecursion, which calls ATPrepCmd with recurse = false for every node in the tree. Inner nodes (for example a partition which itself has subpartitions) then fail the check, accidentally preventing the command from working on inheritance trees of depth > 2. This commit fixes it by also checking that we're at the top level of the recursive calls using the recursing parameter, which is always true when called through ATSimpleRecursion, always false when invoked on the root rel. Also, remove a comment claiming that DROP EXPRESSION could be implemented with some effort. It cannot, as the commit message for 8bf6ec3ba3a4 explains. Author: Alberto Piai Backpatch-through: 14 Discussion: https://postgr.es/m/DHMT78XOD8BK.341V3H87KZ7NO@gmail.com --- src/backend/commands/tablecmds.c | 15 ++---- .../regress/expected/generated_stored.out | 51 +++++++++++++++++++ src/test/regress/sql/generated_stored.sql | 15 ++++++ 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index c323eb36a10..a2003c75331 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8844,17 +8844,12 @@ static void ATPrepDropExpression(Relation rel, AlterTableCmd *cmd, bool recurse, bool recursing, LOCKMODE lockmode) { /* - * Reject ONLY if there are child tables. We could implement this, but it - * is a bit complicated. GENERATED clauses must be attached to the column - * definition and cannot be added later like DEFAULT, so if a child table - * has a generation expression that the parent does not have, the child - * column will necessarily be an attislocal column. So to implement ONLY - * here, we'd need extra code to update attislocal of the direct child - * tables, somewhat similar to how DROP COLUMN does it, so that the - * resulting state can be properly dumped and restored. + * Reject ONLY if there are child tables -- but only, of course, at the + * top of the tree, otherwise it'd be impossible to run this command with + * trees deeper than two levels. Caller already got lock. */ - if (!recurse && - find_inheritance_children(RelationGetRelid(rel), lockmode)) + if (!recurse && !recursing && + find_inheritance_children(RelationGetRelid(rel), NoLock)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("ALTER TABLE / DROP EXPRESSION must be applied to child tables too"))); diff --git a/src/test/regress/expected/generated_stored.out b/src/test/regress/expected/generated_stored.out index 6a8b5113e73..fd6caf1cf2d 100644 --- a/src/test/regress/expected/generated_stored.out +++ b/src/test/regress/expected/generated_stored.out @@ -1434,6 +1434,57 @@ Inherits: ALTER TABLE gtest30_1 ALTER COLUMN b DROP EXPRESSION; -- error ERROR: cannot drop generation expression from inherited column +BEGIN; +CREATE TABLE gtest30_1_1 () INHERITS (gtest30_1); +ALTER TABLE gtest30 ALTER COLUMN b DROP EXPRESSION; +\d gtest30_1_1 + Table "generated_stored_tests.gtest30_1_1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | +Inherits: + gtest30_1 + +ROLLBACK; +-- test drop expression with subpartitions +CREATE TABLE gtest_root (a int, b int, c int GENERATED ALWAYS AS (a + b) STORED) PARTITION BY LIST (a); +CREATE TABLE gtest_node PARTITION OF gtest_root FOR VALUES IN (1) PARTITION BY LIST (b); +CREATE TABLE gtest_leaf PARTITION OF gtest_node FOR VALUES IN (1); +ALTER TABLE gtest_node ALTER COLUMN c DROP EXPRESSION; -- fails +ERROR: cannot drop generation expression from inherited column +ALTER TABLE ONLY gtest_root ALTER COLUMN c DROP EXPRESSION; -- fails +ERROR: ALTER TABLE / DROP EXPRESSION must be applied to child tables too +ALTER TABLE gtest_root ALTER COLUMN c DROP EXPRESSION; +\d gtest_(root|node|leaf) + Table "generated_stored_tests.gtest_leaf" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | + c | integer | | | +Partition of: gtest_node FOR VALUES IN (1) + +Partitioned table "generated_stored_tests.gtest_node" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | + c | integer | | | +Partition of: gtest_root FOR VALUES IN (1) +Partition key: LIST (b) +Number of partitions: 1 (Use \d+ to list them.) + +Partitioned table "generated_stored_tests.gtest_root" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | + c | integer | | | +Partition key: LIST (a) +Number of partitions: 1 (Use \d+ to list them.) + +DROP TABLE gtest_root; -- composite type dependencies CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') STORED, c text); CREATE TABLE gtest31_2 (x int, y gtest31_1); diff --git a/src/test/regress/sql/generated_stored.sql b/src/test/regress/sql/generated_stored.sql index b349a16ddf3..9eecd13dd9e 100644 --- a/src/test/regress/sql/generated_stored.sql +++ b/src/test/regress/sql/generated_stored.sql @@ -676,6 +676,21 @@ ALTER TABLE ONLY gtest30 ALTER COLUMN b DROP EXPRESSION; -- error \d gtest30 \d gtest30_1 ALTER TABLE gtest30_1 ALTER COLUMN b DROP EXPRESSION; -- error +BEGIN; +CREATE TABLE gtest30_1_1 () INHERITS (gtest30_1); +ALTER TABLE gtest30 ALTER COLUMN b DROP EXPRESSION; +\d gtest30_1_1 +ROLLBACK; + +-- test drop expression with subpartitions +CREATE TABLE gtest_root (a int, b int, c int GENERATED ALWAYS AS (a + b) STORED) PARTITION BY LIST (a); +CREATE TABLE gtest_node PARTITION OF gtest_root FOR VALUES IN (1) PARTITION BY LIST (b); +CREATE TABLE gtest_leaf PARTITION OF gtest_node FOR VALUES IN (1); +ALTER TABLE gtest_node ALTER COLUMN c DROP EXPRESSION; -- fails +ALTER TABLE ONLY gtest_root ALTER COLUMN c DROP EXPRESSION; -- fails +ALTER TABLE gtest_root ALTER COLUMN c DROP EXPRESSION; +\d gtest_(root|node|leaf) +DROP TABLE gtest_root; -- composite type dependencies CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') STORED, c text); From 8380013cd288ca35d225f862c809ec64b563d4fd Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Tue, 4 Aug 2026 17:03:27 +0900 Subject: [PATCH 277/481] Fix error handling in getCopyDataMessage() and pqFunctionCall3() Commit f6f0542266f0 changed getNotify(), getParameterStatus(), and related libpq message-processing paths to abandon the connection on out-of-memory errors. However, getCopyDataMessage() and pqFunctionCall3() did not handle this new fatal-error state. Both can process asynchronous NotificationResponse and ParameterStatus messages while waiting for other responses. If one of those messages triggered a fatal error, these loops continued processing instead of reporting it immediately. Fix this by checking for a saved fatal error after processing an asynchronous message. If the connection has been abandoned, return the appropriate error immediately instead of continuing to parse input. Backpatch to v18, where commit f6f0542266f0 introduced this issue. Author: Anthonin Bonnefoy Reviewed-by: Ewan Young Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CAO6_XqpGfm+XHE1OzS=_+jroeDOxhhGa11P3cbm9q2gT05yorA@mail.gmail.com Backpatch-through: 18 --- src/interfaces/libpq/fe-protocol3.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c index 9d6a285fb28..f807670409c 100644 --- a/src/interfaces/libpq/fe-protocol3.c +++ b/src/interfaces/libpq/fe-protocol3.c @@ -1931,6 +1931,13 @@ getCopyDataMessage(PGconn *conn) return -1; } + /* + * An error may have been triggered while processing the message, + * report it if it's the case + */ + if (conn->error_result && conn->status == CONNECTION_BAD) + return -2; + /* Drop the processed message and loop around for another */ pqParseDone(conn, conn->inCursor); } @@ -2425,6 +2432,13 @@ pqFunctionCall3(PGconn *conn, Oid fnid, return pqPrepareAsyncResult(conn); } + /* + * An error may have been triggered while processing the message, bail + * out + */ + if (conn->error_result && conn->status == CONNECTION_BAD) + return pqPrepareAsyncResult(conn); + /* Completed parsing this message, keep going */ pqParseDone(conn, conn->inStart + 5 + msgLength); needInput = false; From 4054ec5b4f39272f5009516db19fb7c253989ebd Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 4 Aug 2026 09:55:03 +0200 Subject: [PATCH 278/481] Prohibit GRANT ... ON TABLE on a property graph We allowed GRANT ... ON TABLE on sequences for backward compatibility. We don't need to consider backward compatibility in case of property graphs since we will be prohibiting its usage on property graph from the very release which introduced property graphs. Change regression tests that used GRANT ... ON [TABLE] on property graphs to use GRANT ... ON PROPERTY GRAPH instead. While here, add the missing RELKIND_PROPGRAPH cases in pg_class_aclmask_ext() and in the object-type switch in ExecGrant_Relation() so that the default ACL and the objtype passed to restrict_and_check_grant() are correct. Author: Ashutosh Bapat Reviewed-by: Noah Misch Reviewed-by: Tom Lane Discussion: https://www.postgresql.org/message-id/20260630023308.c7.noahmisch@microsoft.com --- src/backend/catalog/aclchk.c | 20 ++++++++++++++++++- .../expected/create_property_graph.out | 3 +++ src/test/regress/expected/graph_table_rls.out | 6 +++--- src/test/regress/expected/privileges.out | 4 ++-- .../regress/sql/create_property_graph.sql | 1 + src/test/regress/sql/graph_table_rls.sql | 6 +++--- src/test/regress/sql/privileges.sql | 4 ++-- 7 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index a6e8073d02e..89f146f9f0f 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -1784,7 +1784,7 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname, } /* - * This processes both sequences and non-sequences. + * This processes all pg_class entries including sequences and property graphs. */ static void ExecGrant_Relation(InternalGrant *istmt) @@ -1891,6 +1891,18 @@ ExecGrant_Relation(InternalGrant *istmt) this_privileges &= (AclMode) ACL_ALL_RIGHTS_SEQUENCE; } } + else if (pg_class_tuple->relkind == RELKIND_PROPGRAPH) + { + /* + * Do not allow GRANT ... TABLE on property graph. We allowed + * it on sequences for backward compatibility but there is no + * reason to continue that further. + */ + ereport(ERROR, + errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a property graph", NameStr(pg_class_tuple->relname)), + errhint("Use GRANT ... ON PROPERTY GRAPH instead.")); + } else { if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_RELATION)) @@ -1996,6 +2008,9 @@ ExecGrant_Relation(InternalGrant *istmt) case RELKIND_SEQUENCE: objtype = OBJECT_SEQUENCE; break; + case RELKIND_PROPGRAPH: + objtype = OBJECT_PROPGRAPH; + break; default: objtype = OBJECT_TABLE; break; @@ -3375,6 +3390,9 @@ pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, case RELKIND_SEQUENCE: acl = acldefault(OBJECT_SEQUENCE, ownerId); break; + case RELKIND_PROPGRAPH: + acl = acldefault(OBJECT_PROPGRAPH, ownerId); + break; default: acl = acldefault(OBJECT_TABLE, ownerId); break; diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out index 7387751eac2..9a3cc6c13b2 100644 --- a/src/test/regress/expected/create_property_graph.out +++ b/src/test/regress/expected/create_property_graph.out @@ -236,6 +236,9 @@ SET ROLE regress_graph_user1; GRANT SELECT ON PROPERTY GRAPH g1 TO regress_graph_user2; GRANT UPDATE ON PROPERTY GRAPH g1 TO regress_graph_user2; -- fail ERROR: invalid privilege type UPDATE for property graph +GRANT UPDATE ON TABLE g1 TO regress_graph_user2; -- fail +ERROR: "g1" is a property graph +HINT: Use GRANT ... ON PROPERTY GRAPH instead. RESET ROLE; -- collation CREATE TABLE tc1 (a int, b text); diff --git a/src/test/regress/expected/graph_table_rls.out b/src/test/regress/expected/graph_table_rls.out index 0e719c7ebd7..230ae4cdb01 100644 --- a/src/test/regress/expected/graph_table_rls.out +++ b/src/test/regress/expected/graph_table_rls.out @@ -74,7 +74,7 @@ CREATE PROPERTY GRAPH cabinet EDGE TABLES (accessed KEY (aid) SOURCE KEY (uid) REFERENCES users (uid) DESTINATION KEY (did) REFERENCES document (did)); -GRANT SELECT ON cabinet TO public; +GRANT SELECT ON PROPERTY GRAPH cabinet TO public; -- -- Basic RLS tests -- @@ -261,7 +261,7 @@ CREATE PROPERTY GRAPH cabinet EDGE TABLES (accessed KEY (aid) SOURCE KEY (uid) REFERENCES users (uid) DESTINATION KEY (did) REFERENCES document (did)); -GRANT SELECT ON cabinet TO public; +GRANT SELECT ON PROPERTY GRAPH cabinet TO public; SET row_security TO ON; -- viewpoint from regress_graph_rls_bob SET SESSION AUTHORIZATION regress_graph_rls_bob; @@ -456,7 +456,7 @@ CREATE PROPERTY GRAPH cabinet EDGE TABLES (accessed KEY (aid) SOURCE KEY (uid) REFERENCES users (uid) DESTINATION KEY (did) REFERENCES document (did)); -GRANT SELECT ON cabinet TO public; +GRANT SELECT ON PROPERTY GRAPH cabinet TO public; SET row_security TO ON; -- viewpoint from regress_graph_rls_bob SET SESSION AUTHORIZATION regress_graph_rls_bob; diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index f6cc1a1029c..fd18549e84e 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -3206,7 +3206,7 @@ select * from graph_table (ptg1 match (is atest5) COLUMNS (1 as value)) limit 0; ------- (0 rows) -grant select on ptg1 to regress_priv_user2; +grant select on property graph ptg1 to regress_priv_user2; set session role regress_priv_user2; select * from graph_table (ptg1 match (is atest1) COLUMNS (1 as value)) limit 0; -- ok value @@ -3232,7 +3232,7 @@ select * from graph_table (ptg1 match (v is lttc) COLUMNS (v.lttck)) limit 0; -- ------- (0 rows) -grant select on ptg1 to regress_priv_user4; +grant select on property graph ptg1 to regress_priv_user4; set session role regress_priv_user4; select * from graph_table (ptg1 match (a is atest5) COLUMNS (a.four)) limit 0; -- ok four diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql index 3494390b923..1ee223809f3 100644 --- a/src/test/regress/sql/create_property_graph.sql +++ b/src/test/regress/sql/create_property_graph.sql @@ -184,6 +184,7 @@ ALTER PROPERTY GRAPH g1 OWNER TO regress_graph_user1; SET ROLE regress_graph_user1; GRANT SELECT ON PROPERTY GRAPH g1 TO regress_graph_user2; GRANT UPDATE ON PROPERTY GRAPH g1 TO regress_graph_user2; -- fail +GRANT UPDATE ON TABLE g1 TO regress_graph_user2; -- fail RESET ROLE; -- collation diff --git a/src/test/regress/sql/graph_table_rls.sql b/src/test/regress/sql/graph_table_rls.sql index 5837eac402e..5c79ade68d4 100644 --- a/src/test/regress/sql/graph_table_rls.sql +++ b/src/test/regress/sql/graph_table_rls.sql @@ -87,7 +87,7 @@ CREATE PROPERTY GRAPH cabinet EDGE TABLES (accessed KEY (aid) SOURCE KEY (uid) REFERENCES users (uid) DESTINATION KEY (did) REFERENCES document (did)); -GRANT SELECT ON cabinet TO public; +GRANT SELECT ON PROPERTY GRAPH cabinet TO public; -- -- Basic RLS tests @@ -198,7 +198,7 @@ CREATE PROPERTY GRAPH cabinet EDGE TABLES (accessed KEY (aid) SOURCE KEY (uid) REFERENCES users (uid) DESTINATION KEY (did) REFERENCES document (did)); -GRANT SELECT ON cabinet TO public; +GRANT SELECT ON PROPERTY GRAPH cabinet TO public; SET row_security TO ON; @@ -267,7 +267,7 @@ CREATE PROPERTY GRAPH cabinet EDGE TABLES (accessed KEY (aid) SOURCE KEY (uid) REFERENCES users (uid) DESTINATION KEY (did) REFERENCES document (did)); -GRANT SELECT ON cabinet TO public; +GRANT SELECT ON PROPERTY GRAPH cabinet TO public; SET row_security TO ON; -- viewpoint from regress_graph_rls_bob diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index 6cd9bb840ff..6e0686da131 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -1890,7 +1890,7 @@ create property graph ptg1 label ltv properties (col1 as ltvk)); -- select privileges on property graph as well as table select * from graph_table (ptg1 match (is atest5) COLUMNS (1 as value)) limit 0; -- ok -grant select on ptg1 to regress_priv_user2; +grant select on property graph ptg1 to regress_priv_user2; set session role regress_priv_user2; select * from graph_table (ptg1 match (is atest1) COLUMNS (1 as value)) limit 0; -- ok -- select privileges on property graph but not table @@ -1904,7 +1904,7 @@ select * from graph_table (ptg1 match (is atest5) COLUMNS (1 as value)) limit 0; -- column privileges set session role regress_priv_user1; select * from graph_table (ptg1 match (v is lttc) COLUMNS (v.lttck)) limit 0; -- ok -grant select on ptg1 to regress_priv_user4; +grant select on property graph ptg1 to regress_priv_user4; set session role regress_priv_user4; select * from graph_table (ptg1 match (a is atest5) COLUMNS (a.four)) limit 0; -- ok select * from graph_table (ptg1 match (v is lttc) COLUMNS (v.lttck)) limit 0; -- fail From 77964322d608f33b34f455ac2d3bd772f222160f Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 4 Aug 2026 10:31:55 +0200 Subject: [PATCH 279/481] doc: Add PROPERTY GRAPH to the access privilege tables The SELECT privilege can be granted on a property graph, and its privileges can be examined with psql's \dp command, but property graphs were missing from both summary tables in the "Privileges" section: the applicable object types for SELECT in the privilege abbreviations table, and the per-object-type row in the summary of access privileges table. Add the missing entries so the tables match the actual behavior described for the SELECT privilege and in GRANT. While at it, also add a test for \dp on a property graph. Author: Shinya Kato Reviewed-by: Ashutosh Bapat Discussion: https://www.postgresql.org/message-id/flat/CAOzEurScgwLDXQmNFnDZANGAMMiva9GnLH_kO8qGtGVHUvVk2A%40mail.gmail.com --- doc/src/sgml/ddl.sgml | 7 +++++++ src/test/regress/expected/privileges.out | 8 ++++++++ src/test/regress/sql/privileges.sql | 1 + 3 files changed, 16 insertions(+) diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index 82176945bc2..160f4eebb35 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -2615,6 +2615,7 @@ REVOKE ALL ON accounts FROM PUBLIC; r (read) LARGE OBJECT, + PROPERTY GRAPH, SEQUENCE, TABLE (and table-like objects), table column @@ -2783,6 +2784,12 @@ REVOKE ALL ON accounts FROM PUBLIC; none \dconfig+ + + PROPERTY GRAPH + r + none + \dp + SCHEMA UC diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index fd18549e84e..5e3c9510490 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -3208,6 +3208,14 @@ select * from graph_table (ptg1 match (is atest5) COLUMNS (1 as value)) limit 0; grant select on property graph ptg1 to regress_priv_user2; set session role regress_priv_user2; +\dp ptg1 + Access privileges + Schema | Name | Type | Access privileges | Column privileges | Policies +--------+------+----------------+-----------------------------------------+-------------------+---------- + public | ptg1 | property graph | regress_priv_user1=r/regress_priv_user1+| | + | | | regress_priv_user2=r/regress_priv_user1 | | +(1 row) + select * from graph_table (ptg1 match (is atest1) COLUMNS (1 as value)) limit 0; -- ok value ------- diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index 6e0686da131..d3e87fa617f 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -1892,6 +1892,7 @@ create property graph ptg1 select * from graph_table (ptg1 match (is atest5) COLUMNS (1 as value)) limit 0; -- ok grant select on property graph ptg1 to regress_priv_user2; set session role regress_priv_user2; +\dp ptg1 select * from graph_table (ptg1 match (is atest1) COLUMNS (1 as value)) limit 0; -- ok -- select privileges on property graph but not table select * from graph_table (ptg1 match (is atest5) COLUMNS (1 as value)) limit 0; -- fails From 1f24c823720dfbd6632383c8e8ba92a4b3bc0785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Tue, 4 Aug 2026 11:44:11 +0200 Subject: [PATCH 280/481] pg_surgery: Fix infinite loop on large TID arrays heap_force_common() tracked the current position in the caller-supplied tid[] using OffsetNumber, which is only 16 bits wide, so when the array held more than 65535 entries, the updated index wrapped around and the outer loop never reached the exit condition. A SQL call with a sufficiently large TID array would then run until interrupted. Fix by tracking the tid[] position using int instead of OffsetNumber. A regress case based on the report is included. Author: Andrey Rachitskiy Reviewed-by: Andrey Borodin Reported-by: Yuelin Wang <1217816127@qq.com> Backpatch-through: 14 Bug: #19607 Discussion: https://postgr.es/m/19607-2f256a66481c514b@postgresql.org --- contrib/pg_surgery/expected/heap_surgery.out | 17 +++++++++++++++++ contrib/pg_surgery/heap_surgery.c | 6 +++--- contrib/pg_surgery/sql/heap_surgery.sql | 8 ++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/contrib/pg_surgery/expected/heap_surgery.out b/contrib/pg_surgery/expected/heap_surgery.out index df7d13b0908..42586137d88 100644 --- a/contrib/pg_surgery/expected/heap_surgery.out +++ b/contrib/pg_surgery/expected/heap_surgery.out @@ -134,6 +134,23 @@ select heap_force_kill('htab2'::regclass, ARRAY['(0, 3)']::tid[]); (1 row) +-- a tid[] larger than 65535 entries must still finish +create temp table htab3(a int); +insert into htab3 values (1); +select heap_force_kill( + 'htab3'::regclass, + array(select '(0,1)'::tid from generate_series(1, 65536))); + heap_force_kill +----------------- + +(1 row) + +select count(*) from htab3; + count +------- + 0 +(1 row) + -- materialized view. -- note that we don't commit the transaction, so autovacuum can't interfere. begin; diff --git a/contrib/pg_surgery/heap_surgery.c b/contrib/pg_surgery/heap_surgery.c index a10876cb800..50a39d98ff3 100644 --- a/contrib/pg_surgery/heap_surgery.c +++ b/contrib/pg_surgery/heap_surgery.c @@ -44,7 +44,7 @@ static Datum heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt); static void sanity_check_tid_array(ArrayType *ta, int *ntids); static BlockNumber find_tids_one_page(ItemPointer tids, int ntids, - OffsetNumber *next_start_ptr); + int *next_start_ptr); /*------------------------------------------------------------------------- * heap_force_kill() @@ -91,7 +91,7 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt) int ntids, nblocks; Relation rel; - OffsetNumber curr_start_ptr, + int curr_start_ptr, next_start_ptr; bool include_this_tid[MaxHeapTuplesPerPage]; @@ -413,7 +413,7 @@ sanity_check_tid_array(ArrayType *ta, int *ntids) * ------------------------------------------------------------------------ */ static BlockNumber -find_tids_one_page(ItemPointer tids, int ntids, OffsetNumber *next_start_ptr) +find_tids_one_page(ItemPointer tids, int ntids, int *next_start_ptr) { int i; BlockNumber prev_blkno, diff --git a/contrib/pg_surgery/sql/heap_surgery.sql b/contrib/pg_surgery/sql/heap_surgery.sql index 6526b27535d..c4e933da13a 100644 --- a/contrib/pg_surgery/sql/heap_surgery.sql +++ b/contrib/pg_surgery/sql/heap_surgery.sql @@ -65,6 +65,14 @@ select heap_force_kill('htab2'::regclass, ARRAY[NULL]::tid[]); -- but we should be able to kill the one tuple we have select heap_force_kill('htab2'::regclass, ARRAY['(0, 3)']::tid[]); +-- a tid[] larger than 65535 entries must still finish +create temp table htab3(a int); +insert into htab3 values (1); +select heap_force_kill( + 'htab3'::regclass, + array(select '(0,1)'::tid from generate_series(1, 65536))); +select count(*) from htab3; + -- materialized view. -- note that we don't commit the transaction, so autovacuum can't interfere. begin; From 01805b7d16b9a06d5223071215db0337bc8e6d92 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Tue, 4 Aug 2026 12:16:55 +0200 Subject: [PATCH 281/481] Do not reuse rd_smgr in fork loop when enabling data checksums ProcessSingleRelationByOid called RelationGetSmgr(rel), discarded the result, and then read rel->rd_smgr directly when looping over forks. Only RelationGetSmgr is authorized to read that field since a relcache invalidation resets rd_smgr to NULL. Backpatch to v19 where online checksums were introduced. Author: Mihail Nikalayeu Reviewed-by: ChangAo Chen Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CADzfLwXGvb4Y-mqy8T+O0f_tkXR1sTDBGzP5Z=V_qcGnZ46rWg@mail.gmail.com Backpatch-through: 19 --- src/backend/postmaster/datachecksum_state.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backend/postmaster/datachecksum_state.c b/src/backend/postmaster/datachecksum_state.c index 122640b0a9a..368df23e967 100644 --- a/src/backend/postmaster/datachecksum_state.c +++ b/src/backend/postmaster/datachecksum_state.c @@ -841,11 +841,10 @@ ProcessSingleRelationByOid(Oid relationId, BufferAccessStrategy strategy) pgstat_report_activity(STATE_IDLE, NULL); return true; } - RelationGetSmgr(rel); for (ForkNumber fnum = 0; fnum <= MAX_FORKNUM; fnum++) { - if (smgrexists(rel->rd_smgr, fnum)) + if (smgrexists(RelationGetSmgr(rel), fnum)) { if (!ProcessSingleRelationFork(rel, fnum, strategy)) { From 16aba1f9b3addecc6f8463ac2ab783551627d148 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 4 Aug 2026 14:36:47 +0200 Subject: [PATCH 282/481] doc: Make synopsis placeholders consistent Existing text (e.g., create_foreign_table.sgml) uses server_name, not servername. --- doc/src/sgml/ref/alter_subscription.sgml | 6 +++--- doc/src/sgml/ref/create_subscription.sgml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml index 33c78aef748..04388ebf82d 100644 --- a/doc/src/sgml/ref/alter_subscription.sgml +++ b/doc/src/sgml/ref/alter_subscription.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -ALTER SUBSCRIPTION name SERVER servername +ALTER SUBSCRIPTION name SERVER server_name ALTER SUBSCRIPTION name CONNECTION 'conninfo' ALTER SUBSCRIPTION name SET PUBLICATION publication_name [, ...] [ WITH ( publication_option [= value] [, ... ] ) ] ALTER SUBSCRIPTION name ADD PUBLICATION publication_name [, ...] [ WITH ( publication_option [= value] [, ... ] ) ] @@ -111,12 +111,12 @@ ALTER SUBSCRIPTION name RENAME TO < - SERVER servername + SERVER server_name This clause replaces the foreign server or connection string originally set by with the foreign server - servername. + server_name. diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml index 07d5b1bd77c..da89c9dd037 100644 --- a/doc/src/sgml/ref/create_subscription.sgml +++ b/doc/src/sgml/ref/create_subscription.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION subscription_name - { SERVER servername | CONNECTION 'conninfo' } + { SERVER server_name | CONNECTION 'conninfo' } PUBLICATION publication_name [, ...] [ WITH ( subscription_parameter [= value] [, ... ] ) ] @@ -78,7 +78,7 @@ CREATE SUBSCRIPTION subscription_name - SERVER servername + SERVER server_name A foreign server to use for the connection. The server's foreign data @@ -86,7 +86,7 @@ CREATE SUBSCRIPTION subscription_nameUSAGE privileges on - servername. + server_name. From 8126fe4739b52f930a1bf2b9f205536e3b26f81b Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 4 Aug 2026 15:10:22 +0200 Subject: [PATCH 283/481] psql: Message style fixes --- src/bin/psql/help.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 5e0d8f3aae1..e9ecd050a08 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -480,9 +480,9 @@ helpVariables(unsigned short int pager) " field separator for CSV output format (default \"%c\")\n", DEFAULT_CSV_FIELD_SEP); HELP0(" display_false\n" - " set the string to be printed in place of a boolean 'false'\n"); + " set the string to be printed in place of a Boolean \"false\"\n"); HELP0(" display_true\n" - " set the string to be printed in place of a boolean 'true'\n"); + " set the string to be printed in place of a Boolean \"true\"\n"); HELP0(" expanded (or x)\n" " expanded output [on, off, auto]\n"); HELPN(" fieldsep\n" From 2f768dda531c94c071972a68d77163fba35684a6 Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Tue, 4 Aug 2026 18:04:28 -0400 Subject: [PATCH 284/481] Silence Coverity warning about unused visibilitymap_clear() result Commit c0d9864f5ce made all but one caller of visibilitymap_clear() check its return value, causing Coverity to flag the remaining unchecked call in heap_page_fix_vm_corruption(). This VM clear is not WAL-logged, so the caller doesn't need the return value of visibilitymap_clear(). Add an explicit void cast and comment to document that the return value is intentionally ignored. Backpatch to 19 when the number of callers discarding the return value dropped low enough to trigger Coverity's warning. Discussion: https://postgr.es/m/1065814.1784514869%40sss.pgh.pa.us Reported-by: Tom Lane Backpatch-through: 19 --- src/backend/access/heap/pruneheap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index 704187a7268..e1be6c37084 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -948,9 +948,10 @@ heap_page_fix_vm_corruption(PruneState *prstate, OffsetNumber offnum, if (do_clear_vm) { LockBuffer(prstate->vmbuffer, BUFFER_LOCK_EXCLUSIVE); - visibilitymap_clear(prstate->relation, prstate->block, - prstate->vmbuffer, - VISIBILITYMAP_VALID_BITS); + /* This VM clear is not WAL-logged, so its return value is not needed. */ + (void) visibilitymap_clear(prstate->relation, prstate->block, + prstate->vmbuffer, + VISIBILITYMAP_VALID_BITS); LockBuffer(prstate->vmbuffer, BUFFER_LOCK_UNLOCK); prstate->old_vmbits = 0; } From 1aaca5ab8ffb7f9387dce2a2de128eff006ac1c4 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 5 Aug 2026 11:29:15 +0900 Subject: [PATCH 285/481] doc: Clarify wal_sender_shutdown_timeout values Clarify how special wal_sender_shutdown_timeout values affect shutdown waiting. A value of -1 disables the shutdown timeout and lets the WAL sender wait for the receiver to catch up, while 0 causes immediate termination without waiting for catch-up. Positive values bound how long shutdown waits, so document that they should be high enough for WAL data to be replicated under normal circumstances. Update the main documentation, the GUC long description, and postgresql.conf.sample consistently. While here, fix nearby paragraph indentation and spacing. Backpatch to v19, where wal_sender_shutdown_timeout was introduced. Author: Chao Li Reviewed-by: Ian Barwick Reviewed-by: Daniel Gustafsson Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/AF4FE756-A220-4DA7-87B7-A126F3F307FD@gmail.com Backpatch-through: 19 --- doc/src/sgml/config.sgml | 32 ++++++++++++------- src/backend/utils/misc/guc_parameters.dat | 2 +- src/backend/utils/misc/postgresql.conf.sample | 4 ++- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 124f62e6e8f..0a2afe88ea0 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -4988,23 +4988,31 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows Specifies the maximum time the server waits during shutdown for all WAL data to be replicated to the receiver. If this value is specified without units, it is taken as milliseconds. A value of - -1 (the default) disables the timeout mechanism. + -1 (the default) disables the timeout mechanism, + allowing the WAL sender to wait as long as necessary for the receiver + to catch up. A value of 0 causes the WAL sender to + terminate without waiting for the receiver to catch up. + - When replication is in use, the sending server normally waits until - all WAL data has been transferred to the receiver before completing - shutdown. This helps keep sender and receiver in sync after shutdown, - which is especially important for physical replication switchovers, - but it can delay shutdown. + When replication is in use, the sending server normally waits until + all WAL data has been transferred to the receiver before completing + shutdown. This helps keep sender and receiver in sync after shutdown, + which is especially important for physical replication switchovers, + but it can delay shutdown. + - If this parameter is set, the server stops waiting and completes - shutdown when the timeout expires. This can shorten shutdown time, - for example, when replication is slow on high-latency networks or - when a logical replication apply worker is blocked waiting for locks. - However, in this case the sender and receiver may be out of sync after - shutdown. + If this parameter is set to zero or a positive value, the server stops + waiting and completes shutdown when the timeout expires. This can + shorten shutdown time, for example, when replication is slow on + high-latency networks or when a logical replication apply worker is + blocked waiting for locks. However, in this case the sender and + receiver may be out of sync after shutdown. Care should be taken to + select a value high enough to allow all WAL data to be replicated to + the receiver under normal circumstances. + This parameter can be set in primary_conninfo and in the CONNECTION clause of diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat index 3c1e6b31bf8..2cd115deaee 100644 --- a/src/backend/utils/misc/guc_parameters.dat +++ b/src/backend/utils/misc/guc_parameters.dat @@ -3558,7 +3558,7 @@ { name => 'wal_sender_shutdown_timeout', type => 'int', context => 'PGC_USERSET', group => 'REPLICATION_SENDING', short_desc => 'Sets the maximum time the server waits during shutdown for all WAL data to be replicated to the receiver.', - long_desc => '-1 disables the timeout', + long_desc => '-1 disables the timeout and waits for the receiver to catch up; 0 does not wait for the receiver to catch up.', flags => 'GUC_UNIT_MS', variable => 'wal_sender_shutdown_timeout', boot_val => '-1', diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 86f2e16eba0..23dd27957be 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -362,7 +362,9 @@ #max_slot_wal_keep_size = -1 # in megabytes; -1 disables #idle_replication_slot_timeout = 0 # in seconds; 0 disables #wal_sender_timeout = 60s # in milliseconds; 0 disables -#wal_sender_shutdown_timeout = -1 # in milliseconds; -1 disables +#wal_sender_shutdown_timeout = -1 # in milliseconds + # -1 disables the timeout and waits for catch-up + # 0 does not wait for catch-up #track_commit_timestamp = off # collect timestamp of transaction commit # (change requires restart) From 3d4216d85f42d9f011001367d5f962ca8d1d72e2 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 5 Aug 2026 11:34:29 +0900 Subject: [PATCH 286/481] Clarify wraparound warning percentage messages Commit e646450e609 added DETAIL messages for XID and MultiXactId wraparound warnings that described the reported percentage as the percentage of IDs available for use. However, the percentage is actually calculated from the remaining distance to the wraparound limit, not the stop limit where new IDs are refused. As a result, the wording could be misinterpreted as meaning that the reported percentage of IDs can still be allocated. Update the wording to clarify that the reported percentage represents the remaining transaction ID space or MultiXactId space before wraparound. Also update the related XID warning hints to use "transaction ID" terminology consistently. Backpatch to v19, where the DETAIL messages were added. Author: Fujii Masao Reviewed-by: Bharath Rupireddy Reviewed-by: Kyotaro Horiguchi Reviewed-by: Nathan Bossart Reviewed-by: Yugo Nagata Discussion: https://postgr.es/m/CAHGQGwHWZTsR6bjdfpa+pOkBPjoXXm2LuJ+5nh+CvdyqEASHcQ@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/maintenance.sgml | 4 ++-- src/backend/access/transam/multixact.c | 8 ++++---- src/backend/access/transam/varsup.c | 14 +++++++------- src/test/modules/xid_wraparound/t/002_limits.pl | 3 ++- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 0eec6e2e888..75749ea145c 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,8 +674,8 @@ SELECT datname, age(datfrozenxid) FROM pg_database; WARNING: database "mydb" must be vacuumed within 99985967 transactions -DETAIL: Approximately 4.66% of transaction IDs are available for use. -HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. +DETAIL: Approximately 4.66% of transaction ID space remains before wraparound. +HINT: To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database. (A manual VACUUM should fix the problem, as suggested by the diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8c694658132..424516dc106 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1070,7 +1070,7 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), - errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + errdetail("Approximately %.2f%% of MultiXactId space remains before wraparound.", (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions."))); @@ -1081,7 +1081,7 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), - errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + errdetail("Approximately %.2f%% of MultiXactId space remains before wraparound.", (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions."))); @@ -2208,7 +2208,7 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), - errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + errdetail("Approximately %.2f%% of MultiXactId space remains before wraparound.", (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions."))); @@ -2219,7 +2219,7 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), - errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + errdetail("Approximately %.2f%% of MultiXactId space remains before wraparound.", (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions."))); diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index dc5e32d86f3..cb68d8fa974 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -166,7 +166,7 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), - errdetail("Approximately %.2f%% of transaction IDs are available for use.", + errdetail("Approximately %.2f%% of transaction ID space remains before wraparound.", (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); @@ -175,9 +175,9 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), - errdetail("Approximately %.2f%% of transaction IDs are available for use.", + errdetail("Approximately %.2f%% of transaction ID space remains before wraparound.", (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), - errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" + errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -485,18 +485,18 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), - errdetail("Approximately %.2f%% of transaction IDs are available for use.", + errdetail("Approximately %.2f%% of transaction ID space remains before wraparound.", (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), - errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" + errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else ereport(WARNING, (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), - errdetail("Approximately %.2f%% of transaction IDs are available for use.", + errdetail("Approximately %.2f%% of transaction ID space remains before wraparound.", (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), - errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" + errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } } diff --git a/src/test/modules/xid_wraparound/t/002_limits.pl b/src/test/modules/xid_wraparound/t/002_limits.pl index 86632a8d510..29d071a677b 100644 --- a/src/test/modules/xid_wraparound/t/002_limits.pl +++ b/src/test/modules/xid_wraparound/t/002_limits.pl @@ -70,7 +70,8 @@ # the warning: # # WARNING: database "postgres" must be vacuumed within 3000024 transactions -# HINT: To avoid a database shutdown, execute a database-wide VACUUM in that database. +# DETAIL: Approximately 0.14% of transaction ID space remains before wraparound. +# HINT: To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database. # You might also need to commit or roll back old prepared transactions, or drop stale replication slots. my $stderr; my $warn_limit = 0; From 4642ddc2a58623af6934bec1708d901a3a8e9cd4 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 5 Aug 2026 11:36:43 +0900 Subject: [PATCH 287/481] doc: Update XID wraparound error example Commit edee0c621de, and the equivalent v17 commit f2353dd71724, changed the runtime XID wraparound messages to use "transaction IDs" terminology, but one corresponding error example in maintenance.sgml still used the older XID wording. Update that documentation example in line with the current runtime message. Backpatch to v17, where the runtime messages were changed. Author: Fujii Masao Reviewed-by: Yugo Nagata Discussion: https://postgr.es/m/CAHGQGwHTN-Xc5iDtbzNSjfxuab5Y9qAArw8cB4PrrDJpZ+1fgA@mail.gmail.com Backpatch-through: 17 --- doc/src/sgml/maintenance.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 75749ea145c..e351e5e9ca1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -686,7 +686,7 @@ HINT: To avoid transaction ID assignment failures, execute a database-wide VACU there are fewer than three million transactions left until wraparound: -ERROR: database is not accepting commands that assign new XIDs to avoid wraparound data loss in database "mydb" +ERROR: database is not accepting commands that assign new transaction IDs to avoid wraparound data loss in database "mydb" HINT: Execute a database-wide VACUUM in that database. From c5e11de2f378b8e52893bfcd3f6ffd583fffc160 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 5 Aug 2026 08:35:10 +0200 Subject: [PATCH 288/481] More tab-completion for DROP PROPERTY GRAPH This adds completion for CASCADE and RESTRICT, similar to what completion of other DROP commands provides. Author: Peter Smith Reviewed-by: Chao Li Discussion: https://www.postgresql.org/message-id/flat/CAHut+PuHsLupVWZ9SUeKm=jKR34wYP6qAZPoOHFhU3uDbx34wQ@mail.gmail.com --- src/bin/psql/tab-complete.in.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index 745eb3d004c..807d1d3b527 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -4496,6 +4496,8 @@ match_previous_words(int pattern_id, COMPLETE_WITH("GRAPH"); else if (Matches("DROP", "PROPERTY", "GRAPH")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_propgraphs); + else if (Matches("DROP", "PROPERTY", "GRAPH", MatchAny)) + COMPLETE_WITH("CASCADE", "RESTRICT"); /* DROP RULE */ else if (Matches("DROP", "RULE", MatchAny)) From 0e2fb2c8c307aaee5ab47aa92055b53ca146706b Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 5 Aug 2026 16:55:26 +0900 Subject: [PATCH 289/481] Initialize read stream before fetching metapage in hash bulk-deletion hashbulkdelete() fetched the relcache's cached hash metapage before calling read_stream_begin_relation(). During the read stream initialization, relation lookups may process pending relcache invalidation messages, which could cause the cached metapage to be invalidated before the read stream uses it, leading to the failure of a VACUUM bulk-deletion for a hash index. This commit reworks the order of hashbulkdelete() so as its read stream is initialized before fetching the cached metapage, so as pending invalidation messages do not interfere with the relation scan. Issue introduced by bfa3c4f106b1. Author: Mikhail Nikalayeu Reviewed-by: Bertrand Drouvot Reviewed-by: Nazir Bilal Yavuz Reviewed-by: Xuneng Zhou Discussion: https://postgr.es/m/CADzfLwVEJ2_7ioX3ZSB1P7qXW40ghUy_ZCzeFvhDLoa_3Muztg@mail.gmail.com Backpatch-through: 19 --- src/backend/access/hash/hash.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index 8d8cd30dc38..b2e34d2d45e 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -515,6 +515,21 @@ hashbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, tuples_removed = 0; num_index_tuples = 0; + /* + * Set up the streaming read before fetching the cached metapage as read + * stream initialization may process relcache invalidation messages, + * invalidating the cached metapage. It is safe to use batchmode as + * hash_bulkdelete_read_stream_cb takes no locks. + */ + stream = read_stream_begin_relation(READ_STREAM_MAINTENANCE | + READ_STREAM_USE_BATCHING, + info->strategy, + rel, + MAIN_FORKNUM, + hash_bulkdelete_read_stream_cb, + &stream_private, + 0); + /* * We need a copy of the metapage so that we can use its hashm_spares[] * values to compute bucket page addresses, but a cached copy should be @@ -536,19 +551,6 @@ hashbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, stream_private.next_bucket = cur_bucket; stream_private.max_bucket = cur_maxbucket; - /* - * It is safe to use batchmode as hash_bulkdelete_read_stream_cb takes no - * locks. - */ - stream = read_stream_begin_relation(READ_STREAM_MAINTENANCE | - READ_STREAM_USE_BATCHING, - info->strategy, - rel, - MAIN_FORKNUM, - hash_bulkdelete_read_stream_cb, - &stream_private, - 0); - bucket_loop: while (cur_bucket <= cur_maxbucket) { From 8ce749f8f65c8991d6d2f5010116530e0d7fb2ad Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 5 Aug 2026 10:44:10 +0200 Subject: [PATCH 290/481] Disallow aggregates, window functions, and SRFs in GRAPH_TABLE COLUMNS The COLUMNS list of a GRAPH_TABLE query is parsed as an ordinary select target list, which permits aggregate functions, window functions, and set-returning functions. GRAPH_TABLE has no machinery to evaluate them, though: the rewriter copies the COLUMNS target list verbatim into a freshly built subquery whose hasAggs/hasWindowFuncs/hasTargetSRFs flags are never set, so the planner builds no Agg/WindowAgg node (and no SRF expansion) and the Aggref/WindowFunc/SRF reaches the executor. This triggers an assertion failure ("ecxt_aggvalues != NULL"), or "Aggref found in non-Agg plan node" on a non-assert build, for otherwise parser-accepted SQL such as SELECT max(c) FROM GRAPH_TABLE (g MATCH (x IS v) COLUMNS (count(*) AS c)); Reject these constructs in transformRangeGraphTable() the same way subqueries are already handled: save and clear pstate->p_hasAggs, p_hasWindowFuncs, and p_hasTargetSRFs around the transformation of the COLUMNS list, and raise a "not supported" error if any of them got set. This is deliberately a blanket prohibition for now. Once quantified element patterns such as (a)->{1,5} are supported, aggregates over property references of higher degree (e.g. count(a) or sum(a.val)) can be allowed; at that point the check will need to inspect the aggregate arguments rather than reject all aggregates outright. Author: Ewan Young Reviewed-by: Ashutosh Bapat Discussion: https://www.postgresql.org/message-id/flat/CAON2xHOYAmYLkB2jGi6g77d6Fqv8YgOrfV-riQVf0K_7AdxD3w@mail.gmail.com --- src/backend/parser/parse_clause.c | 30 +++++++++++++++++++++++ src/test/regress/expected/graph_table.out | 7 ++++++ src/test/regress/sql/graph_table.sql | 4 +++ 3 files changed, 41 insertions(+) diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 485e33b9e5a..68b525ffdcc 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -946,6 +946,9 @@ transformRangeGraphTable(ParseState *pstate, RangeGraphTable *rgt) ListCell *lc; int resno = 0; bool saved_hasSublinks; + bool saved_hasAggs; + bool saved_hasWindowFuncs; + bool saved_hasTargetSRFs; rel = parserOpenPropGraph(pstate, rgt->graph_name, AccessShareLock); @@ -967,6 +970,13 @@ transformRangeGraphTable(ParseState *pstate, RangeGraphTable *rgt) saved_hasSublinks = pstate->p_hasSubLinks; pstate->p_hasSubLinks = false; + saved_hasAggs = pstate->p_hasAggs; + pstate->p_hasAggs = false; + saved_hasWindowFuncs = pstate->p_hasWindowFuncs; + pstate->p_hasWindowFuncs = false; + saved_hasTargetSRFs = pstate->p_hasTargetSRFs; + pstate->p_hasTargetSRFs = false; + gp = transformGraphPattern(pstate, rgt->graph_pattern); /* @@ -1031,6 +1041,26 @@ transformRangeGraphTable(ParseState *pstate, RangeGraphTable *rgt) errmsg("subqueries within GRAPH_TABLE reference are not supported"))); pstate->p_hasSubLinks = saved_hasSublinks; + /* + * GRAPH_TABLE cannot yet evaluate aggregate, window, or set-returning + * functions in its COLUMNS list, so prohibit them for now. + */ + if (pstate->p_hasAggs) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("aggregate functions in GRAPH_TABLE COLUMNS are not supported")); + if (pstate->p_hasWindowFuncs) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("window functions in GRAPH_TABLE COLUMNS are not supported")); + if (pstate->p_hasTargetSRFs) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("set-returning functions in GRAPH_TABLE COLUMNS are not supported")); + pstate->p_hasAggs = saved_hasAggs; + pstate->p_hasWindowFuncs = saved_hasWindowFuncs; + pstate->p_hasTargetSRFs = saved_hasTargetSRFs; + return addRangeTableEntryForGraphTable(pstate, graphid, castNode(GraphPattern, gp), columns, colnames, rgt->alias, false, true); } diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out index b7a6182457d..cde3114ebf4 100644 --- a/src/test/regress/expected/graph_table.out +++ b/src/test/regress/expected/graph_table.out @@ -471,6 +471,13 @@ SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.* IS NOT NULL)-[ ERROR: "*" not allowed here LINE 1: ...M GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.* IS NOT... ^ +-- aggregate, window, and set-returning functions are not supported in COLUMNS +SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers) COLUMNS (count(*) AS num)); +ERROR: aggregate functions in GRAPH_TABLE COLUMNS are not supported +SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers) COLUMNS (row_number() OVER () AS rn)); +ERROR: window functions in GRAPH_TABLE COLUMNS are not supported +SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers) COLUMNS (generate_series(1, 2) AS gs)); +ERROR: set-returning functions in GRAPH_TABLE COLUMNS are not supported -- consecutive element patterns with same kind SELECT * FROM GRAPH_TABLE (g1 MATCH ()() COLUMNS (1 as one)); ERROR: adjacent vertex patterns are not supported diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql index 85298f93964..7a4189833d8 100644 --- a/src/test/regress/sql/graph_table.sql +++ b/src/test/regress/sql/graph_table.sql @@ -306,6 +306,10 @@ SELECT * FROM GRAPH_TABLE (g1 MATCH (src IS el1 | vl1)-[conn]->(dest) COLUMNS (c SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.address = 'US')-[IS customer_orders]->(o IS orders) COLUMNS (c.*)); -- star anywhere else is not allowed as a property reference SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.* IS NOT NULL)-[IS customer_orders]->(o IS orders) COLUMNS (c.name)); +-- aggregate, window, and set-returning functions are not supported in COLUMNS +SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers) COLUMNS (count(*) AS num)); +SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers) COLUMNS (row_number() OVER () AS rn)); +SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers) COLUMNS (generate_series(1, 2) AS gs)); -- consecutive element patterns with same kind SELECT * FROM GRAPH_TABLE (g1 MATCH ()() COLUMNS (1 as one)); SELECT * FROM GRAPH_TABLE (g1 MATCH -> COLUMNS (1 AS one)); From 55ea764269b6fe8b3fcc221a970c09e12ef7a96b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Wed, 5 Aug 2026 11:40:39 +0200 Subject: [PATCH 291/481] Fix calculating length of match to localized month/weekday names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit seq_search_localized() returns the length of the matching prefix in *len, but because it internally case-folds the inputs, it gets confused on the length. The caller expects to get the length of the prefix in the original string, but what it actually returns is the length of the prefix after case-folding, which can be different if the case-folded characters have different byte-length than the original, or with ICU, if the case-folding changes the number of characters (e.g. "ß", the German double s). To fix, once we have determined that we have a match, work harder to find the match's length in the original string. This adds some overhead, but the strings are expected to be short. The function does "case-folding" by converting a string to upper-case, then to lower-case, which is a little ugly given that we have dedicated functions for case-folding nowadays. But switching to that doesn't seem appropriate to backpatch in a security fix, and that's not available in older stable versions, anyway. Author: Heikki Linnakangas Reported-by: Xint Code Reviewed-by: Jeff Davis --- src/backend/utils/adt/formatting.c | 146 ++++++++++++++++-- .../regress/expected/collate.linux.utf8.out | 18 +++ src/test/regress/sql/collate.linux.utf8.sql | 3 + 3 files changed, 150 insertions(+), 17 deletions(-) diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index d52d71b0a8c..641b7aa679e 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -103,6 +103,7 @@ #define DCH_MAX_ITEM_SIZ 12 /* max localized day name */ #define NUM_MAX_ITEM_SIZ 8 /* roman number (RN has 15 chars) */ +#define MAX_L10N_DATA 80 /* max localized day or month name */ /* * Format parser structs @@ -2328,6 +2329,41 @@ seq_search_ascii(const char *name, const char *const *array, size_t *len) return -1; } +/* + * Compare 'name' with 'element' in a case-insensitive way, by first + * converting 'name' to upper case, then lower case. ('element' is already + * case-folded that way.) + * + * A helper function for seq_search_localized(). + */ +static bool +casefold_str_cmp(const char *name, size_t name_len, + const char *element, size_t element_len, + pg_locale_t mylocale) +{ + /* + * 'name' is expected to fit in MAX_L10N_DATA, even with the case + * conversions. + */ + char upper_substr[MAX_L10N_DATA]; + size_t upper_substr_len; + char lower_substr[MAX_L10N_DATA]; + size_t lower_substr_len; + + upper_substr_len = pg_strupper(upper_substr, sizeof(upper_substr), + name, name_len, + mylocale); + if (upper_substr_len > sizeof(upper_substr) - 1) + return false; /* shouldn't happen */ + lower_substr_len = pg_strlower(lower_substr, sizeof(lower_substr), + upper_substr, upper_substr_len, + mylocale); + if (lower_substr_len > sizeof(lower_substr) - 1) + return false; /* shouldn't happen */ + + return strcmp(lower_substr, element) == 0; +} + /* * Sequentially search an array of possibly non-English words for * a case-insensitive match to the initial character(s) of "name". @@ -2342,8 +2378,11 @@ seq_search_ascii(const char *name, const char *const *array, size_t *len) static int seq_search_localized(const char *name, char **array, size_t *len, Oid collid) { + size_t name_len = strlen(name); + const char *name_end = name + name_len; char *upper_name; char *lower_name; + pg_locale_t mylocale; *len = 0; @@ -2366,36 +2405,109 @@ seq_search_localized(const char *name, char **array, size_t *len, Oid collid) } } + mylocale = pg_newlocale_from_collation(collid); + /* * Fold to upper case, then to lower case, so that we can match reliably * even in languages in which case conversions are not injective. */ - upper_name = str_toupper(name, strlen(name), collid); + upper_name = str_toupper(name, name_len, collid); lower_name = str_tolower(upper_name, strlen(upper_name), collid); pfree(upper_name); for (char **a = array; *a != NULL; a++) { - char *upper_element; - char *lower_element; - size_t element_len; + char upper_element[MAX_L10N_DATA]; + size_t upper_element_len; + char lower_element[MAX_L10N_DATA]; + size_t lower_element_len; /* Likewise upper/lower-case array element */ - upper_element = str_toupper(*a, strlen(*a), collid); - lower_element = str_tolower(upper_element, strlen(upper_element), - collid); - pfree(upper_element); - element_len = strlen(lower_element); - - /* Match? */ - if (strncmp(lower_name, lower_element, element_len) == 0) + upper_element_len = pg_strupper(upper_element, sizeof(upper_element), + *a, strlen(*a), + mylocale); + if (upper_element_len > sizeof(upper_element) - 1) + continue; /* shouldn't happen */ + lower_element_len = pg_strlower(lower_element, sizeof(lower_element), + upper_element, upper_element_len, + mylocale); + if (lower_element_len > sizeof(lower_element) - 1) + continue; /* shouldn't happen */ + + /* Is 'lower_element' a prefix of 'lower_name' ? */ + if (strncmp(lower_name, lower_element, lower_element_len) == 0) { - *len = element_len; - pfree(lower_element); - pfree(lower_name); - return a - array; + /* + * We have a match, but we still need to figure out how long the + * match is. The case conversions could have changed the lengths + * of either string, or both. + */ + const char *ep; + const char *element_end; + size_t element_nchars; + size_t substr_len; + size_t substr_nchars; + + /* + * First, check the easy case that the string matches as whole. + */ + if (strlen(lower_name) == lower_element_len) + { + *len = name_len; + pfree(lower_name); + return a - array; + } + + /* + * Another good guess is that the case conversions did not change + * the number of characters. + */ + + /* count characters in the element */ + ep = lower_element; + element_end = lower_element + lower_element_len; + for (element_nchars = 0; ep < element_end; element_nchars++) + ep += pg_mblen_range(ep, element_end); + + /* + * count the byte length of a substring of 'name' having the same + * character count as the element + */ + substr_len = 0; + for (substr_nchars = 0; + substr_nchars < element_nchars && substr_len < name_len; + substr_nchars++) + { + substr_len += pg_mblen_range(name + substr_len, name_end); + } + + if (casefold_str_cmp(name, substr_len, lower_element, lower_element_len, mylocale)) + { + *len = substr_len; + pfree(lower_name); + return a - array; + } + + /* + * As last resort, try the case conversion and comparison for + * every substring from the beginning of the original string until + * we find a match. + */ + substr_len = 0; + while (substr_len < name_len) + { + substr_len += pg_mblen_range(name + substr_len, name_end); + + if (casefold_str_cmp(name, substr_len, + lower_element, lower_element_len, + mylocale)) + { + *len = substr_len; + pfree(lower_name); + return a - array; + } + } } - pfree(lower_element); } pfree(lower_name); diff --git a/src/test/regress/expected/collate.linux.utf8.out b/src/test/regress/expected/collate.linux.utf8.out index c6e84c27b69..e0a39e4c300 100644 --- a/src/test/regress/expected/collate.linux.utf8.out +++ b/src/test/regress/expected/collate.linux.utf8.out @@ -479,6 +479,24 @@ SELECT to_date('01 Şub 2010', 'DD TMMON YYYY'); SELECT to_date('1234567890ab 2010', 'TMMONTH YYYY'); -- fail ERROR: invalid value "1234567890ab" for "MONTH" DETAIL: The given value did not match any of the allowed values for this field. +SELECT to_date('01 Aralık 2010', 'DD TMMONTH YYYY'); + to_date +------------ + 12-01-2010 +(1 row) + +SELECT to_date('01 aralık 2010', 'DD TMMONTH YYYY'); + to_date +------------ + 12-01-2010 +(1 row) + +SELECT to_date('2010 01 araLık', 'YYYY DD TMMONTH'); + to_date +------------ + 12-01-2010 +(1 row) + -- backwards parsing CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc'; CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C"; diff --git a/src/test/regress/sql/collate.linux.utf8.sql b/src/test/regress/sql/collate.linux.utf8.sql index 132d13af0a8..6d726ee9c99 100644 --- a/src/test/regress/sql/collate.linux.utf8.sql +++ b/src/test/regress/sql/collate.linux.utf8.sql @@ -188,6 +188,9 @@ SELECT to_date('01 ŞUB 2010', 'DD TMMON YYYY'); SELECT to_date('01 Şub 2010', 'DD TMMON YYYY'); SELECT to_date('1234567890ab 2010', 'TMMONTH YYYY'); -- fail +SELECT to_date('01 Aralık 2010', 'DD TMMONTH YYYY'); +SELECT to_date('01 aralık 2010', 'DD TMMONTH YYYY'); +SELECT to_date('2010 01 araLık', 'YYYY DD TMMONTH'); -- backwards parsing From 8f7617ff7af60f4d9b2be0ba2d89b2fedbc027cc Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 5 Aug 2026 11:36:37 -0700 Subject: [PATCH 292/481] Remove Subscription conninfo field; generate in caller. After server-based subscriptions, conninfo became more than just a catalog field. It has its own error paths, and it's important that callers that don't need conninfo don't encounter errors related to it. Reviewed-by: Amit Kapila Reviewed-by: Hayato Kuroda (Fujitsu) Discussion: https://postgr.es/m/20260710195902.4f.noahmisch%40microsoft.com Backpatch-through: 19 --- src/backend/catalog/pg_subscription.c | 105 ++++++++++-------- src/backend/commands/subscriptioncmds.c | 43 +++++-- .../replication/logical/sequencesync.c | 2 +- src/backend/replication/logical/tablesync.c | 2 +- src/backend/replication/logical/worker.c | 24 +++- src/include/catalog/pg_subscription.h | 6 +- src/include/replication/worker_internal.h | 1 + 7 files changed, 118 insertions(+), 65 deletions(-) diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c index d1a110f1ff3..d1d5478b8fa 100644 --- a/src/backend/catalog/pg_subscription.c +++ b/src/backend/catalog/pg_subscription.c @@ -79,14 +79,10 @@ GetPublicationsStr(List *publications, StringInfo dest, bool quote_literal) /* * Fetch the subscription from the syscache. * - * If conninfo_needed is true, conninfo will be constructed, possibly - * encountering errors in ForeignServerConnectionString(). Callers not - * expecting such errors should pass false, in which case conninfo will be - * NULL. + * Callers that need conninfo must call SubscriptionConninfo(). */ Subscription * -GetSubscription(Oid subid, bool missing_ok, bool conninfo_needed, - bool conninfo_aclcheck) +GetSubscription(Oid subid, bool missing_ok) { HeapTuple tup; Subscription *sub; @@ -96,8 +92,6 @@ GetSubscription(Oid subid, bool missing_ok, bool conninfo_needed, MemoryContext cxt; MemoryContext oldcxt; - Assert(conninfo_needed || !conninfo_aclcheck); - tup = SearchSysCache1(SUBSCRIPTIONOID, ObjectIdGetDatum(subid)); if (!HeapTupleIsValid(tup)) @@ -139,42 +133,6 @@ GetSubscription(Oid subid, bool missing_ok, bool conninfo_needed, sub->maxretention = subform->submaxretention; sub->retentionactive = subform->subretentionactive; - if (conninfo_needed) - { - if (OidIsValid(subform->subserver)) - { - AclResult aclresult; - ForeignServer *server; - - server = GetForeignServer(subform->subserver); - - if (conninfo_aclcheck) - { - /* recheck ACL if requested */ - aclresult = object_aclcheck(ForeignServerRelationId, - subform->subserver, - subform->subowner, ACL_USAGE); - - if (aclresult != ACLCHECK_OK) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("subscription owner \"%s\" does not have permission on foreign server \"%s\"", - GetUserNameFromId(subform->subowner, false), - server->servername))); - } - - sub->conninfo = ForeignServerConnectionString(subform->subowner, - server); - } - else - { - datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID, - tup, - Anum_pg_subscription_subconninfo); - sub->conninfo = TextDatumGetCString(datum); - } - } - /* Get slotname */ datum = SysCacheGetAttr(SUBSCRIPTIONOID, tup, @@ -219,6 +177,65 @@ GetSubscription(Oid subid, bool missing_ok, bool conninfo_needed, return sub; } +/* + * Generate the connection string for a subscription. + * + * This is deliberately separate from GetSubscription() because resolving + * conninfo for a server-based subscription has its own error paths (foreign + * server USAGE, user mapping, ForeignServerConnectionString()). Keeping it + * separate lets a caller load the subscription and decide whether a + * connection is actually needed, and check things such as whether the + * subscription is enabled, before risking those errors. Callers that never + * connect thus never hit them, which matters during restore. + */ +char * +SubscriptionConninfo(Subscription *sub, bool aclcheck) +{ + HeapTuple tup; + Form_pg_subscription subform; + Datum datum; + char *conninfo; + + tup = SearchSysCache1(SUBSCRIPTIONOID, ObjectIdGetDatum(sub->oid)); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for subscription %u", sub->oid); + + subform = (Form_pg_subscription) GETSTRUCT(tup); + + if (OidIsValid(subform->subserver)) + { + ForeignServer *server; + AclResult aclresult; + + server = GetForeignServer(subform->subserver); + + if (aclcheck) + { + aclresult = object_aclcheck(ForeignServerRelationId, + subform->subserver, + sub->owner, ACL_USAGE); + if (aclresult != ACLCHECK_OK) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("subscription owner \"%s\" does not have permission on foreign server \"%s\"", + GetUserNameFromId(sub->owner, false), + server->servername))); + } + + conninfo = ForeignServerConnectionString(sub->owner, server); + } + else + { + datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID, tup, + Anum_pg_subscription_subconninfo); + conninfo = TextDatumGetCString(datum); + } + + ReleaseSysCache(tup); + + return conninfo; +} + /* * Return number of subscriptions defined in given database. * Used by dropdb() to check if database can indeed be dropped. diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 9671541caf9..f553fe3294e 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -1028,7 +1028,7 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, static void AlterSubscription_refresh(Subscription *sub, bool copy_data, - List *validate_publications) + List *validate_publications, char *conninfo) { char *err; List *pubrels = NIL; @@ -1052,12 +1052,19 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data, WalReceiverConn *wrconn; bool must_use_password; + /* + * Should not happen: CREATE/ALTER/DROP SUBSCRIPTION did not call + * SubscriptionConninfo() in a path where it's required. + */ + if (!conninfo) + elog(ERROR, "no connection string provided for subscription"); + /* Load the library providing us libpq calls. */ load_file("libpqwalreceiver", false); /* Try to connect to the publisher. */ must_use_password = sub->passwordrequired && !sub->ownersuperuser; - wrconn = walrcv_connect(sub->conninfo, true, true, must_use_password, + wrconn = walrcv_connect(conninfo, true, true, must_use_password, sub->name, &err); if (!wrconn) ereport(ERROR, @@ -1298,19 +1305,26 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data, * Marks all sequences with INIT state. */ static void -AlterSubscription_refresh_seq(Subscription *sub) +AlterSubscription_refresh_seq(Subscription *sub, char *conninfo) { char *err = NULL; WalReceiverConn *wrconn; bool must_use_password; List *subrel_states; + /* + * Should not happen: CREATE/ALTER/DROP SUBSCRIPTION did not call + * SubscriptionConninfo() in a path where it's required. + */ + if (!conninfo) + elog(ERROR, "no connection string provided for subscription"); + /* Load the library providing us libpq calls. */ load_file("libpqwalreceiver", false); /* Try to connect to the publisher. */ must_use_password = sub->passwordrequired && !sub->ownersuperuser; - wrconn = walrcv_connect(sub->conninfo, true, true, must_use_password, + wrconn = walrcv_connect(conninfo, true, true, must_use_password, sub->name, &err); if (!wrconn) ereport(ERROR, @@ -1502,6 +1516,7 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, int max_retention; bool retention_active; char *new_conninfo = NULL; + char *orig_conninfo = NULL; char *origin; Subscription *sub; Form_pg_subscription form; @@ -1603,6 +1618,8 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, orig_conninfo_needed = false; } + sub = GetSubscription(subid, false); + /* * Skip ACL checks on the subscription's foreign server, if any. If * changing the server (or replacing it with a raw connection), then the @@ -1610,7 +1627,8 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, * there's no need to do an additional ACL check here; that will be done * by the subscription worker. */ - sub = GetSubscription(subid, false, orig_conninfo_needed, false); + if (orig_conninfo_needed) + orig_conninfo = SubscriptionConninfo(sub, false); retain_dead_tuples = sub->retaindeadtuples; origin = sub->origin; @@ -2065,7 +2083,8 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, sub->publications = stmt->publication; AlterSubscription_refresh(sub, opts.copy_data, - stmt->publication); + stmt->publication, + orig_conninfo); } break; @@ -2120,7 +2139,8 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, sub->publications = publist; AlterSubscription_refresh(sub, opts.copy_data, - validate_publications); + validate_publications, + orig_conninfo); } break; @@ -2159,7 +2179,8 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, PreventInTransactionBlock(isTopLevel, "ALTER SUBSCRIPTION ... REFRESH PUBLICATION"); - AlterSubscription_refresh(sub, opts.copy_data, NULL); + AlterSubscription_refresh(sub, opts.copy_data, NULL, + orig_conninfo); break; } @@ -2172,7 +2193,7 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, errmsg("%s is not allowed for disabled subscriptions", "ALTER SUBSCRIPTION ... REFRESH SEQUENCES")); - AlterSubscription_refresh_seq(sub); + AlterSubscription_refresh_seq(sub, orig_conninfo); break; } @@ -2244,7 +2265,7 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, char *err; WalReceiverConn *wrconn; - Assert(new_conninfo || orig_conninfo_needed); + Assert(new_conninfo || orig_conninfo); /* Load the library providing us libpq calls. */ load_file("libpqwalreceiver", false); @@ -2254,7 +2275,7 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, * available. */ must_use_password = sub->passwordrequired && !sub->ownersuperuser; - wrconn = walrcv_connect(new_conninfo ? new_conninfo : sub->conninfo, + wrconn = walrcv_connect(new_conninfo ? new_conninfo : orig_conninfo, true, true, must_use_password, sub->name, &err); if (!wrconn) diff --git a/src/backend/replication/logical/sequencesync.c b/src/backend/replication/logical/sequencesync.c index 9f0d2762dad..35286c3f727 100644 --- a/src/backend/replication/logical/sequencesync.c +++ b/src/backend/replication/logical/sequencesync.c @@ -815,7 +815,7 @@ LogicalRepSyncSequences(void) * Establish the connection to the publisher for sequence synchronization. */ LogRepWorkerWalRcvConn = - walrcv_connect(MySubscription->conninfo, true, true, + walrcv_connect(MySubscriptionConninfo, true, true, must_use_password, app_name.data, &err); if (LogRepWorkerWalRcvConn == NULL) diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c index a04b84ebc1d..e5101997cd3 100644 --- a/src/backend/replication/logical/tablesync.c +++ b/src/backend/replication/logical/tablesync.c @@ -1305,7 +1305,7 @@ LogicalRepSyncTableStart(XLogRecPtr *origin_startpos) * so that synchronous replication can distinguish them. */ LogRepWorkerWalRcvConn = - walrcv_connect(MySubscription->conninfo, true, true, + walrcv_connect(MySubscriptionConninfo, true, true, must_use_password, slotname, &err); if (LogRepWorkerWalRcvConn == NULL) diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index 2dd421412d6..56949f49788 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -482,6 +482,7 @@ static MemoryContext LogicalStreamingContext = NULL; WalReceiverConn *LogRepWorkerWalRcvConn = NULL; Subscription *MySubscription = NULL; +char *MySubscriptionConninfo = NULL; static bool MySubscriptionValid = false; static List *on_commit_wakeup_workers_subids = NIL; @@ -5061,6 +5062,8 @@ void maybe_reread_subscription(void) { Subscription *newsub; + char *old_conninfo; + char *new_conninfo; bool started_tx = false; /* When cache state is valid there is nothing to do here. */ @@ -5074,7 +5077,7 @@ maybe_reread_subscription(void) started_tx = true; } - newsub = GetSubscription(MyLogicalRepWorker->subid, true, true, true); + newsub = GetSubscription(MyLogicalRepWorker->subid, true); if (newsub) { @@ -5097,6 +5100,9 @@ maybe_reread_subscription(void) proc_exit(0); } + /* allocated in transaction context */ + new_conninfo = SubscriptionConninfo(newsub, true); + /* Exit if the subscription was disabled. */ if (!newsub->enabled) { @@ -5120,7 +5126,7 @@ maybe_reread_subscription(void) * 'parallel' to any other value or the server decides not to stream the * in-progress transaction. */ - if (strcmp(newsub->conninfo, MySubscription->conninfo) != 0 || + if (strcmp(new_conninfo, MySubscriptionConninfo) != 0 || strcmp(newsub->name, MySubscription->name) != 0 || strcmp(newsub->slotname, MySubscription->slotname) != 0 || newsub->binary != MySubscription->binary || @@ -5171,6 +5177,11 @@ maybe_reread_subscription(void) MemoryContextDelete(MySubscription->cxt); MySubscription = newsub; + /* copy to ApplyContext and update MySubscriptionConninfo */ + old_conninfo = MySubscriptionConninfo; + MySubscriptionConninfo = MemoryContextStrdup(ApplyContext, new_conninfo); + pfree(old_conninfo); + /* Change synchronous commit according to the user's wishes */ SetConfigOption("synchronous_commit", MySubscription->synccommit, PGC_BACKEND, PGC_S_OVERRIDE); @@ -5718,7 +5729,7 @@ run_apply_worker(void) must_use_password = MySubscription->passwordrequired && !MySubscription->ownersuperuser; - LogRepWorkerWalRcvConn = walrcv_connect(MySubscription->conninfo, true, + LogRepWorkerWalRcvConn = walrcv_connect(MySubscriptionConninfo, true, true, must_use_password, MySubscription->name, &err); @@ -5838,7 +5849,7 @@ InitializeLogRepWorker(void) LockSharedObject(SubscriptionRelationId, MyLogicalRepWorker->subid, 0, AccessShareLock); - MySubscription = GetSubscription(MyLogicalRepWorker->subid, true, true, true); + MySubscription = GetSubscription(MyLogicalRepWorker->subid, true); if (MySubscription) { @@ -5857,6 +5868,11 @@ InitializeLogRepWorker(void) proc_exit(0); } + /* build conninfo in transaction context and copy to ApplyContext */ + MySubscriptionConninfo = + MemoryContextStrdup(ApplyContext, + SubscriptionConninfo(MySubscription, true)); + MySubscriptionValid = true; if (!MySubscription->enabled) diff --git a/src/include/catalog/pg_subscription.h b/src/include/catalog/pg_subscription.h index 48944201889..cbb46113c2d 100644 --- a/src/include/catalog/pg_subscription.h +++ b/src/include/catalog/pg_subscription.h @@ -164,7 +164,6 @@ typedef struct Subscription * and the retention duration has not * exceeded max_retention_duration, when * defined */ - char *conninfo; /* Connection string to the publisher */ char *slotname; /* Name of the replication slot */ char *synccommit; /* Synchronous commit setting for worker */ char *walrcvtimeout; /* wal_receiver_timeout setting for worker */ @@ -212,9 +211,8 @@ typedef struct Subscription #endif /* EXPOSE_TO_CLIENT_CODE */ -extern Subscription *GetSubscription(Oid subid, bool missing_ok, - bool conninfo_needed, - bool conninfo_aclcheck); +extern Subscription *GetSubscription(Oid subid, bool missing_ok); +extern char *SubscriptionConninfo(Subscription *sub, bool aclcheck); extern void DisableSubscription(Oid subid); extern int CountDBSubscriptions(Oid dbid); diff --git a/src/include/replication/worker_internal.h b/src/include/replication/worker_internal.h index 745b7d9e969..88cb7c1e252 100644 --- a/src/include/replication/worker_internal.h +++ b/src/include/replication/worker_internal.h @@ -247,6 +247,7 @@ extern PGDLLIMPORT struct WalReceiverConn *LogRepWorkerWalRcvConn; /* Worker and subscription objects. */ extern PGDLLIMPORT Subscription *MySubscription; +extern PGDLLIMPORT char *MySubscriptionConninfo; extern PGDLLIMPORT LogicalRepWorker *MyLogicalRepWorker; extern PGDLLIMPORT bool in_remote_transaction; From f567e066d6e3d09b1db740d0a891b9464c64caa2 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 5 Aug 2026 11:57:36 -0700 Subject: [PATCH 293/481] Build subscription conninfo after checking that it's enabled. If a subscription is disabled, don't try to build conninfo because that may generate a confusing error and try to disable an already-disabled subscription. Partially addresses finding 5 in report from linked discussion. Reported-by: Noah Misch Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/20260710195902.4f.noahmisch%40microsoft.com Backpatch-through: 19 --- src/backend/replication/logical/worker.c | 28 +++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index 56949f49788..fb54eb7d207 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -5100,9 +5100,6 @@ maybe_reread_subscription(void) proc_exit(0); } - /* allocated in transaction context */ - new_conninfo = SubscriptionConninfo(newsub, true); - /* Exit if the subscription was disabled. */ if (!newsub->enabled) { @@ -5113,6 +5110,13 @@ maybe_reread_subscription(void) apply_worker_exit(); } + /* + * May raise error, so build conninfo after checking that the subscription + * is enabled. Allocated in transaction context; must be copied to + * ApplyContext when we set MySubscriptionConninfo. + */ + new_conninfo = SubscriptionConninfo(newsub, true); + /* !slotname should never happen when enabled is true. */ Assert(newsub->slotname); @@ -5868,13 +5872,6 @@ InitializeLogRepWorker(void) proc_exit(0); } - /* build conninfo in transaction context and copy to ApplyContext */ - MySubscriptionConninfo = - MemoryContextStrdup(ApplyContext, - SubscriptionConninfo(MySubscription, true)); - - MySubscriptionValid = true; - if (!MySubscription->enabled) { ereport(LOG, @@ -5884,6 +5881,17 @@ InitializeLogRepWorker(void) apply_worker_exit(); } + /* + * May raise error for server-based subscriptions, so build conninfo after + * checking that the subscription is enabled. Build in transaction context + * and copy to ApplyContext. + */ + MySubscriptionConninfo = + MemoryContextStrdup(ApplyContext, + SubscriptionConninfo(MySubscription, true)); + + MySubscriptionValid = true; + /* * Restart the worker if retain_dead_tuples was enabled during startup. * From ae420d66e72051b7ceab49d14f990094f1c8c6b4 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 5 Aug 2026 13:11:04 -0700 Subject: [PATCH 294/481] Be precise about when ALTER SUBSCRIPTION needs conninfo. Decide early whether the original conninfo is needed so that errors happen consistently. Addresses finding 12 in report from linked discussion. Co-authored-by: Shlok Kyal Reported-by: Noah Misch Reviewed-by: Hayato Kuroda (Fujitsu) Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/20260710195902.4f.noahmisch%40microsoft.com Backpatch-through: 19 --- src/backend/commands/subscriptioncmds.c | 79 ++++++++++++++-------- src/test/regress/expected/subscription.out | 8 +++ src/test/regress/sql/subscription.sql | 9 +++ 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index f553fe3294e..a8b2b849e81 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -1507,7 +1507,7 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, Datum values[Natts_pg_subscription]; HeapTuple tup; Oid subid; - bool orig_conninfo_needed = true; + bool orig_conninfo_needed = false; bool update_tuple = false; bool update_failover = false; bool update_two_phase = false; @@ -1588,37 +1588,60 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, if (supported_opts > 0) parse_subscription_options(pstate, stmt->options, supported_opts, &opts); + sub = GetSubscription(subid, false); + /* - * Ensure that ALTER SUBSCRIPTION commands that could be used to fix a - * broken connection or prepare to drop a broken subscription don't - * attempt to construct the conninfo. Otherwise, we might encounter the - * error the user is trying to fix. - * - * Specifically, ALTER SUBSCRIPTION DISABLE, ALTER SUBSCRIPTION SERVER, - * ALTER SUBSCRIPTION CONNECTION, or ALTER SUBSCRIPTION SET - * (slot_name=NONE). - * - * NB: if the user specifies multiple SET options, then we may still need - * to construct conninfo even if slot_name is set to NONE. + * Determine in advance whether we need the original conninfo or not, so + * that errors are generated consistently in cases where we do need it; + * and not generated at all if we don't. */ - if (stmt->kind == ALTER_SUBSCRIPTION_ENABLED) - { - if (opts.specified_opts == SUBOPT_ENABLED && !opts.enabled) - orig_conninfo_needed = false; - } - else if (stmt->kind == ALTER_SUBSCRIPTION_SERVER || - stmt->kind == ALTER_SUBSCRIPTION_CONNECTION) - { - orig_conninfo_needed = false; - } - else if (stmt->kind == ALTER_SUBSCRIPTION_OPTIONS) + + /* conninfo needed when refreshing */ + switch (stmt->kind) { - /* ... SET (slot_name = NONE) with no other options */ - if (opts.specified_opts == SUBOPT_SLOT_NAME && !opts.slot_name) - orig_conninfo_needed = false; - } + case ALTER_SUBSCRIPTION_REFRESH_PUBLICATION: + case ALTER_SUBSCRIPTION_REFRESH_SEQUENCES: + orig_conninfo_needed = true; + break; - sub = GetSubscription(subid, false); + case ALTER_SUBSCRIPTION_SET_PUBLICATION: + case ALTER_SUBSCRIPTION_ADD_PUBLICATION: + case ALTER_SUBSCRIPTION_DROP_PUBLICATION: + /* opts.refresh defaults to true when the option is supported */ + orig_conninfo_needed = opts.refresh; + break; + + case ALTER_SUBSCRIPTION_OPTIONS: + { + if (sub->slotname) + { + if (IsSet(opts.specified_opts, SUBOPT_FAILOVER)) + orig_conninfo_needed = true; + if (IsSet(opts.specified_opts, SUBOPT_TWOPHASE_COMMIT) && + !opts.twophase) + orig_conninfo_needed = true; + } + + if (IsSet(opts.specified_opts, SUBOPT_RETAIN_DEAD_TUPLES) && + opts.retaindeadtuples) + orig_conninfo_needed = true; + + if (IsSet(opts.specified_opts, SUBOPT_ORIGIN)) + { + bool rdt; + + rdt = IsSet(opts.specified_opts, SUBOPT_RETAIN_DEAD_TUPLES) ? + opts.retaindeadtuples : sub->retaindeadtuples; + + if (rdt && pg_strcasecmp(opts.origin, LOGICALREP_ORIGIN_ANY) == 0) + orig_conninfo_needed = true; + } + } + break; + + default: + break; + } /* * Skip ACL checks on the subscription's foreign server, if any. If diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index 229402826eb..8809834c0d9 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -229,6 +229,14 @@ CREATE SUBSCRIPTION regress_testsub6 SERVER test_server WARNING: subscription was created, but is not connected HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. DROP USER MAPPING FOR regress_subscription_user3 SERVER test_server; +-- ok, catalog-only forms don't construct conninfo +ALTER SUBSCRIPTION regress_testsub6 ENABLE; +ALTER SUBSCRIPTION regress_testsub6 DISABLE; +ALTER SUBSCRIPTION regress_testsub6 SET (synchronous_commit = local); +ALTER SUBSCRIPTION regress_testsub6 SET (synchronous_commit = off); +ALTER SUBSCRIPTION regress_testsub6 SET (disable_on_error = true); +ALTER SUBSCRIPTION regress_testsub6 SET (disable_on_error = false); +ALTER SUBSCRIPTION regress_testsub6 SET PUBLICATION testpub WITH (refresh = false); -- ok, test_server lacks user mapping, but replacing connection anyway BEGIN; ALTER SUBSCRIPTION regress_testsub6 CONNECTION 'dbname=regress_doesnotexist password=secret'; diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql index 03e047b8ce0..bc8c133f24c 100644 --- a/src/test/regress/sql/subscription.sql +++ b/src/test/regress/sql/subscription.sql @@ -176,6 +176,15 @@ CREATE SUBSCRIPTION regress_testsub6 SERVER test_server DROP USER MAPPING FOR regress_subscription_user3 SERVER test_server; +-- ok, catalog-only forms don't construct conninfo +ALTER SUBSCRIPTION regress_testsub6 ENABLE; +ALTER SUBSCRIPTION regress_testsub6 DISABLE; +ALTER SUBSCRIPTION regress_testsub6 SET (synchronous_commit = local); +ALTER SUBSCRIPTION regress_testsub6 SET (synchronous_commit = off); +ALTER SUBSCRIPTION regress_testsub6 SET (disable_on_error = true); +ALTER SUBSCRIPTION regress_testsub6 SET (disable_on_error = false); +ALTER SUBSCRIPTION regress_testsub6 SET PUBLICATION testpub WITH (refresh = false); + -- ok, test_server lacks user mapping, but replacing connection anyway BEGIN; ALTER SUBSCRIPTION regress_testsub6 CONNECTION 'dbname=regress_doesnotexist password=secret'; From 5ba18183c4ca34beeedf7023d1f260ba1f5e9f87 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 5 Aug 2026 13:18:34 -0700 Subject: [PATCH 295/481] Always check foreign-server USAGE when resolving subscription conninfo. Previously, this was skipped in some cases to avoid raising errors when conninfo wasn't even needed. That was wrong in cases where conninfo was needed. Now that we only build conninfo when needed, always perform the USAGE check. Addresses finding 7 in report from linked discussion. Co-authored-by: Shlok Kyal Reported-by: Noah Misch Reviewed-by: Shlok Kyal Reviewed-by: Hayato Kuroda (Fujitsu) Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/20260710195902.4f.noahmisch%40microsoft.com Backpatch-through: 19 --- src/backend/catalog/pg_subscription.c | 23 ++++++++++------------ src/backend/commands/subscriptioncmds.c | 9 +-------- src/backend/replication/logical/worker.c | 4 ++-- src/include/catalog/pg_subscription.h | 2 +- src/test/regress/expected/subscription.out | 3 +++ src/test/regress/sql/subscription.sql | 3 +++ 6 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c index d1d5478b8fa..3072a39c456 100644 --- a/src/backend/catalog/pg_subscription.c +++ b/src/backend/catalog/pg_subscription.c @@ -189,7 +189,7 @@ GetSubscription(Oid subid, bool missing_ok) * connect thus never hit them, which matters during restore. */ char * -SubscriptionConninfo(Subscription *sub, bool aclcheck) +SubscriptionConninfo(Subscription *sub) { HeapTuple tup; Form_pg_subscription subform; @@ -209,18 +209,15 @@ SubscriptionConninfo(Subscription *sub, bool aclcheck) server = GetForeignServer(subform->subserver); - if (aclcheck) - { - aclresult = object_aclcheck(ForeignServerRelationId, - subform->subserver, - sub->owner, ACL_USAGE); - if (aclresult != ACLCHECK_OK) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("subscription owner \"%s\" does not have permission on foreign server \"%s\"", - GetUserNameFromId(sub->owner, false), - server->servername))); - } + aclresult = object_aclcheck(ForeignServerRelationId, + subform->subserver, + sub->owner, ACL_USAGE); + if (aclresult != ACLCHECK_OK) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("subscription owner \"%s\" does not have permission on foreign server \"%s\"", + GetUserNameFromId(sub->owner, false), + server->servername))); conninfo = ForeignServerConnectionString(sub->owner, server); } diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index a8b2b849e81..c546a1d2896 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -1643,15 +1643,8 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, break; } - /* - * Skip ACL checks on the subscription's foreign server, if any. If - * changing the server (or replacing it with a raw connection), then the - * old one will be removed anyway. If changing something unrelated, - * there's no need to do an additional ACL check here; that will be done - * by the subscription worker. - */ if (orig_conninfo_needed) - orig_conninfo = SubscriptionConninfo(sub, false); + orig_conninfo = SubscriptionConninfo(sub); retain_dead_tuples = sub->retaindeadtuples; origin = sub->origin; diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index fb54eb7d207..b3cdbce8d10 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -5115,7 +5115,7 @@ maybe_reread_subscription(void) * is enabled. Allocated in transaction context; must be copied to * ApplyContext when we set MySubscriptionConninfo. */ - new_conninfo = SubscriptionConninfo(newsub, true); + new_conninfo = SubscriptionConninfo(newsub); /* !slotname should never happen when enabled is true. */ Assert(newsub->slotname); @@ -5888,7 +5888,7 @@ InitializeLogRepWorker(void) */ MySubscriptionConninfo = MemoryContextStrdup(ApplyContext, - SubscriptionConninfo(MySubscription, true)); + SubscriptionConninfo(MySubscription)); MySubscriptionValid = true; diff --git a/src/include/catalog/pg_subscription.h b/src/include/catalog/pg_subscription.h index cbb46113c2d..54fec5a8940 100644 --- a/src/include/catalog/pg_subscription.h +++ b/src/include/catalog/pg_subscription.h @@ -212,7 +212,7 @@ typedef struct Subscription #endif /* EXPOSE_TO_CLIENT_CODE */ extern Subscription *GetSubscription(Oid subid, bool missing_ok); -extern char *SubscriptionConninfo(Subscription *sub, bool aclcheck); +extern char *SubscriptionConninfo(Subscription *sub); extern void DisableSubscription(Oid subid); extern int CountDBSubscriptions(Oid dbid); diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index 8809834c0d9..576b15c856b 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -215,6 +215,9 @@ SET SESSION AUTHORIZATION regress_subscription_user3; BEGIN; ALTER SUBSCRIPTION regress_testsub6 CONNECTION 'dbname=regress_doesnotexist password=secret'; ABORT; +-- fail, connecting forms recheck USAGE on the foreign server +ALTER SUBSCRIPTION regress_testsub6 REFRESH PUBLICATION; +ERROR: subscription owner "regress_subscription_user3" does not have permission on foreign server "test_server" -- fails, cannot drop slot DROP SUBSCRIPTION regress_testsub6; ERROR: could not connect to publisher when attempting to drop replication slot "dummy": subscription owner "regress_subscription_user3" does not have permission on foreign server "test_server" diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql index bc8c133f24c..a466dc39cde 100644 --- a/src/test/regress/sql/subscription.sql +++ b/src/test/regress/sql/subscription.sql @@ -161,6 +161,9 @@ BEGIN; ALTER SUBSCRIPTION regress_testsub6 CONNECTION 'dbname=regress_doesnotexist password=secret'; ABORT; +-- fail, connecting forms recheck USAGE on the foreign server +ALTER SUBSCRIPTION regress_testsub6 REFRESH PUBLICATION; + -- fails, cannot drop slot DROP SUBSCRIPTION regress_testsub6; From caadb9e97f571e19f359a42ad186df877ea834c7 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 5 Aug 2026 13:18:44 -0700 Subject: [PATCH 296/481] For subscription DDL, demote user mapping checks to WARNING. The checks are useful to report to the user, but there's no reason to raise an error. If needed while constructing conninfo, fdwconnection will raise an error then. Partially addresses finding 1, and addresses finding 13 in report from the linked discussion. Reported-by: Noah Misch Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/20260710195902.4f.noahmisch%40microsoft.com Discussion: https://postgr.es/m/e103ae8daf74485e0c0ebde297fae735d38f54d1.camel@j-davis.com Backpatch-through: 19 --- src/backend/commands/subscriptioncmds.c | 8 ++++---- src/backend/foreign/foreign.c | 14 +++++++++++++- src/include/foreign/foreign.h | 1 + src/test/regress/expected/subscription.out | 8 +++----- src/test/regress/sql/subscription.sql | 5 +---- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index c546a1d2896..43dca50c385 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -780,8 +780,8 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername); - /* make sure a user mapping exists */ - GetUserMapping(owner, server->serverid); + /* check user mapping */ + GetUserMappingExtended(owner, server->serverid, WARNING); serverid = server->serverid; conninfo = ForeignServerConnectionString(owner, server); @@ -2004,8 +2004,8 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, GetUserNameFromId(form->subowner, false), new_server->servername)); - /* make sure a user mapping exists */ - GetUserMapping(form->subowner, new_server->serverid); + /* check user mapping */ + GetUserMappingExtended(form->subowner, new_server->serverid, WARNING); new_conninfo = ForeignServerConnectionString(form->subowner, new_server); diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c index 821d45c1e11..73343f017b3 100644 --- a/src/backend/foreign/foreign.c +++ b/src/backend/foreign/foreign.c @@ -230,6 +230,16 @@ ForeignServerConnectionString(Oid userid, ForeignServer *server) */ UserMapping * GetUserMapping(Oid userid, Oid serverid) +{ + return GetUserMappingExtended(userid, serverid, ERROR); +} + +/* + * Like GetUserMapping(), but allows caller to specify an elevel. If elevel is + * less than ERROR, returns NULL if the user mapping doesn't exist. + */ +UserMapping * +GetUserMappingExtended(Oid userid, Oid serverid, int elevel) { Datum datum; HeapTuple tp; @@ -252,10 +262,12 @@ GetUserMapping(Oid userid, Oid serverid) { ForeignServer *server = GetForeignServer(serverid); - ereport(ERROR, + ereport(elevel, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("user mapping not found for user \"%s\", server \"%s\"", MappingUserName(userid), server->servername))); + + return NULL; } um = palloc_object(UserMapping); diff --git a/src/include/foreign/foreign.h b/src/include/foreign/foreign.h index 92a55214fee..9b4532895a4 100644 --- a/src/include/foreign/foreign.h +++ b/src/include/foreign/foreign.h @@ -73,6 +73,7 @@ extern ForeignServer *GetForeignServerByName(const char *srvname, extern char *ForeignServerConnectionString(Oid userid, ForeignServer *server); extern UserMapping *GetUserMapping(Oid userid, Oid serverid); +extern UserMapping *GetUserMappingExtended(Oid userid, Oid serverid, int elevel); extern ForeignDataWrapper *GetForeignDataWrapper(Oid fdwid); extern ForeignDataWrapper *GetForeignDataWrapperExtended(Oid fdwid, uint16 flags); diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index 576b15c856b..a98102391b4 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -177,14 +177,12 @@ ERROR: permission denied for foreign server test_server RESET SESSION AUTHORIZATION; GRANT USAGE ON FOREIGN SERVER test_server TO regress_subscription_user3; SET SESSION AUTHORIZATION regress_subscription_user3; --- fail, need user mapping -CREATE SUBSCRIPTION regress_testsub6 SERVER test_server PUBLICATION testpub WITH (slot_name = NONE, connect = false); -ERROR: user mapping not found for user "regress_subscription_user3", server "test_server" -CREATE USER MAPPING FOR regress_subscription_user3 SERVER test_server OPTIONS(user 'foo', password 'secret'); --- fail, need CONNECTION clause +-- warn, need user mapping, then fail, FDW doesn't support connections CREATE SUBSCRIPTION regress_testsub6 SERVER test_server PUBLICATION testpub WITH (slot_name = NONE, connect = false); +WARNING: user mapping not found for user "regress_subscription_user3", server "test_server" ERROR: foreign data wrapper "test_fdw" does not support subscription connections DETAIL: Foreign data wrapper must be defined with CONNECTION specified. +CREATE USER MAPPING FOR regress_subscription_user3 SERVER test_server OPTIONS(user 'foo', password 'secret'); RESET SESSION AUTHORIZATION; ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection; SET SESSION AUTHORIZATION regress_subscription_user3; diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql index a466dc39cde..c5a011fc4ef 100644 --- a/src/test/regress/sql/subscription.sql +++ b/src/test/regress/sql/subscription.sql @@ -124,14 +124,11 @@ RESET SESSION AUTHORIZATION; GRANT USAGE ON FOREIGN SERVER test_server TO regress_subscription_user3; SET SESSION AUTHORIZATION regress_subscription_user3; --- fail, need user mapping +-- warn, need user mapping, then fail, FDW doesn't support connections CREATE SUBSCRIPTION regress_testsub6 SERVER test_server PUBLICATION testpub WITH (slot_name = NONE, connect = false); CREATE USER MAPPING FOR regress_subscription_user3 SERVER test_server OPTIONS(user 'foo', password 'secret'); --- fail, need CONNECTION clause -CREATE SUBSCRIPTION regress_testsub6 SERVER test_server PUBLICATION testpub WITH (slot_name = NONE, connect = false); - RESET SESSION AUTHORIZATION; ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection; SET SESSION AUTHORIZATION regress_subscription_user3; From 1718a16433a3f6572e0ff9c64ef394ae8fec3765 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 5 Aug 2026 13:19:02 -0700 Subject: [PATCH 297/481] CREATE SUBSCRIPTION: do not construct conninfo unnecessarily. Still check that the creating user has USAGE privileges on the server, and that the FDW supports subscription connections. Addresses finding 1 in the report from the linked discussion. Reported-by: Noah Misch Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/20260710195902.4f.noahmisch%40microsoft.com Discussion: https://postgr.es/m/e103ae8daf74485e0c0ebde297fae735d38f54d1.camel@j-davis.com Backpatch-through: 19 --- src/backend/commands/subscriptioncmds.c | 37 ++++++++++++++++------ src/backend/foreign/foreign.c | 4 +-- src/test/regress/expected/subscription.out | 4 +-- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 43dca50c385..70d94016e2f 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -653,8 +653,8 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, Datum values[Natts_pg_subscription]; Oid owner = GetUserId(); HeapTuple tup; - Oid serverid; - char *conninfo; + Oid serverid = InvalidOid; + char *conninfo = NULL; char originname[NAMEDATALEN]; List *publications; uint32 supported_opts; @@ -773,30 +773,47 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, ForeignServer *server; Assert(!stmt->conninfo); - conninfo = NULL; server = GetForeignServerByName(stmt->servername, false); - aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, owner, ACL_USAGE); + serverid = server->serverid; + + /* check USAGE privileges on server */ + aclresult = object_aclcheck(ForeignServerRelationId, serverid, owner, ACL_USAGE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername); /* check user mapping */ GetUserMappingExtended(owner, server->serverid, WARNING); - serverid = server->serverid; - conninfo = ForeignServerConnectionString(owner, server); + /* + * Check conninfo if connecting; otherwise only check that the + * server's FDW supports connections. + */ + if (opts.connect) + { + conninfo = ForeignServerConnectionString(owner, server); + walrcv_check_conninfo(conninfo, opts.passwordrequired && !superuser()); + } + else + { + ForeignDataWrapper *fdw = GetForeignDataWrapper(server->fdwid); + + if (!OidIsValid(fdw->fdwconnection)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("foreign-data wrapper \"%s\" does not support subscription connections", + fdw->fdwname), + errdetail("Foreign-data wrapper must be defined with CONNECTION specified."))); + } } else { Assert(stmt->conninfo); - serverid = InvalidOid; conninfo = stmt->conninfo; + walrcv_check_conninfo(conninfo, opts.passwordrequired && !superuser()); } - /* Check the connection info string. */ - walrcv_check_conninfo(conninfo, opts.passwordrequired && !superuser()); - publications = stmt->publication; /* Everything ok, form a new tuple. */ diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c index 73343f017b3..7ad8e8ee56b 100644 --- a/src/backend/foreign/foreign.c +++ b/src/backend/foreign/foreign.c @@ -209,9 +209,9 @@ ForeignServerConnectionString(Oid userid, ForeignServer *server) if (!OidIsValid(fdw->fdwconnection)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("foreign data wrapper \"%s\" does not support subscription connections", + errmsg("foreign-data wrapper \"%s\" does not support subscription connections", fdw->fdwname), - errdetail("Foreign data wrapper must be defined with CONNECTION specified."))); + errdetail("Foreign-data wrapper must be defined with CONNECTION specified."))); connection_datum = OidFunctionCall3(fdw->fdwconnection, ObjectIdGetDatum(userid), diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index a98102391b4..b023e6fa563 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -180,8 +180,8 @@ SET SESSION AUTHORIZATION regress_subscription_user3; -- warn, need user mapping, then fail, FDW doesn't support connections CREATE SUBSCRIPTION regress_testsub6 SERVER test_server PUBLICATION testpub WITH (slot_name = NONE, connect = false); WARNING: user mapping not found for user "regress_subscription_user3", server "test_server" -ERROR: foreign data wrapper "test_fdw" does not support subscription connections -DETAIL: Foreign data wrapper must be defined with CONNECTION specified. +ERROR: foreign-data wrapper "test_fdw" does not support subscription connections +DETAIL: Foreign-data wrapper must be defined with CONNECTION specified. CREATE USER MAPPING FOR regress_subscription_user3 SERVER test_server OPTIONS(user 'foo', password 'secret'); RESET SESSION AUTHORIZATION; ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection; From 45b479a836ec5434933b5d57fdc2c215b7e11b61 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 5 Aug 2026 13:19:10 -0700 Subject: [PATCH 298/481] Revert "Validate subscription conninfo on owner change" This reverts commit 1c9c35890421e96a91129b51f2c6446a6d95af95. Raising errors during OWNER TO can cause problems during restore. An upcoming commit will avoid other errors that can happen in this path. Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/e103ae8daf74485e0c0ebde297fae735d38f54d1.camel@j-davis.com Backpatch-through: 19 --- doc/src/sgml/ref/alter_subscription.sgml | 7 ------- src/backend/commands/subscriptioncmds.c | 14 ++------------ src/test/regress/expected/subscription.out | 17 ----------------- src/test/regress/regress.c | 9 --------- src/test/regress/sql/subscription.sql | 15 --------------- 5 files changed, 2 insertions(+), 60 deletions(-) diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml index 04388ebf82d..8632657e45a 100644 --- a/doc/src/sgml/ref/alter_subscription.sgml +++ b/doc/src/sgml/ref/alter_subscription.sgml @@ -53,13 +53,6 @@ ALTER SUBSCRIPTION name RENAME TO < to alter the owner, you must be able to SET ROLE to the new owning role. If the subscription has password_required=false, only superusers can modify it. - If the subscription uses a foreign server, the new owner must have - USAGE privilege on the foreign server, a user mapping - for the new owner or for PUBLIC must exist, and the - connection string generated for the new owner must be valid. If the new - owner is not a superuser and the subscription has - password_required=true, the generated connection string - must include a password. diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 70d94016e2f..50a5e279252 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -2791,12 +2791,11 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) /* * If the subscription uses a server, check that the new owner has USAGE - * privileges on the server, that a user mapping exists, and that the - * resulting connection string is valid for the new owner. + * privileges on the server and that a user mapping exists. Note: does not + * re-check the resulting connection string. */ if (OidIsValid(form->subserver)) { - char *conninfo; ForeignServer *server = GetForeignServer(form->subserver); aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, newOwnerId, ACL_USAGE); @@ -2809,15 +2808,6 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) /* make sure a user mapping exists */ GetUserMapping(newOwnerId, server->serverid); - - conninfo = ForeignServerConnectionString(newOwnerId, server); - - /* Load the library providing us libpq calls. */ - load_file("libpqwalreceiver", false); - /* Check the connection info string. */ - walrcv_check_conninfo(conninfo, - form->subpasswordrequired && - !superuser_arg(newOwnerId)); } form->subowner = newOwnerId; diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index b023e6fa563..c034b25f3d5 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -9,10 +9,6 @@ CREATE FUNCTION test_fdw_connection(oid, oid, internal) RETURNS text AS :'regresslib', 'test_fdw_connection' LANGUAGE C; -CREATE FUNCTION test_fdw_connection_no_password(oid, oid, internal) - RETURNS text - AS :'regresslib', 'test_fdw_connection_no_password' - LANGUAGE C; CREATE ROLE regress_subscription_user LOGIN SUPERUSER; CREATE ROLE regress_subscription_user2; CREATE ROLE regress_subscription_user3 IN ROLE pg_create_subscription; @@ -191,18 +187,6 @@ CREATE SUBSCRIPTION regress_testsub6 SERVER test_server WARNING: subscription was created, but is not connected HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications. RESET SESSION AUTHORIZATION; -GRANT USAGE ON FOREIGN SERVER test_server TO regress_subscription_user2; -CREATE USER MAPPING FOR regress_subscription_user2 SERVER test_server OPTIONS(user 'foo'); -ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection_no_password; -WARNING: changing the foreign-data wrapper connection function can cause the options for dependent objects to become invalid --- fail, new owner's generated conninfo must satisfy password_required -ALTER SUBSCRIPTION regress_testsub6 OWNER TO regress_subscription_user2; -ERROR: password is required -DETAIL: Non-superusers must provide a password in the connection string. -ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection; -WARNING: changing the foreign-data wrapper connection function can cause the options for dependent objects to become invalid -DROP USER MAPPING FOR regress_subscription_user2 SERVER test_server; -REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user2; -- fail, subscription depends on the server and cannot be dropped by CASCADE DROP SERVER test_server CASCADE; ERROR: cannot drop server test_server because subscription regress_testsub6 depends on it @@ -260,7 +244,6 @@ HINT: Use DROP ... CASCADE to drop the dependent objects too. ALTER FOREIGN DATA WRAPPER test_fdw NO CONNECTION; WARNING: removing the foreign-data wrapper connection function will cause dependent subscriptions to fail DROP FUNCTION test_fdw_connection(oid, oid, internal); -DROP FUNCTION test_fdw_connection_no_password(oid, oid, internal); DROP FOREIGN DATA WRAPPER test_fdw; -- fail - invalid connection string during ALTER ALTER SUBSCRIPTION regress_testsub CONNECTION 'foobar'; diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 3cc3756a81a..90bb2a7e881 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -742,15 +742,6 @@ test_fdw_connection(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(cstring_to_text("dbname=regress_doesnotexist user=doesnotexist password=secret")); } -PG_FUNCTION_INFO_V1(test_fdw_connection_no_password); -Datum -test_fdw_connection_no_password(PG_FUNCTION_ARGS) -{ - /* Ensure the test fails if no valid user mapping exists. */ - GetUserMapping(PG_GETARG_OID(0), PG_GETARG_OID(1)); - PG_RETURN_TEXT_P(cstring_to_text("dbname=regress_doesnotexist user=doesnotexist")); -} - PG_FUNCTION_INFO_V1(is_catalog_text_unique_index_oid); Datum is_catalog_text_unique_index_oid(PG_FUNCTION_ARGS) diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql index c5a011fc4ef..cbdaaa9294d 100644 --- a/src/test/regress/sql/subscription.sql +++ b/src/test/regress/sql/subscription.sql @@ -12,10 +12,6 @@ CREATE FUNCTION test_fdw_connection(oid, oid, internal) RETURNS text AS :'regresslib', 'test_fdw_connection' LANGUAGE C; -CREATE FUNCTION test_fdw_connection_no_password(oid, oid, internal) - RETURNS text - AS :'regresslib', 'test_fdw_connection_no_password' - LANGUAGE C; CREATE ROLE regress_subscription_user LOGIN SUPERUSER; CREATE ROLE regress_subscription_user2; @@ -137,16 +133,6 @@ CREATE SUBSCRIPTION regress_testsub6 SERVER test_server PUBLICATION testpub WITH (slot_name = 'dummy', connect = false); RESET SESSION AUTHORIZATION; -GRANT USAGE ON FOREIGN SERVER test_server TO regress_subscription_user2; -CREATE USER MAPPING FOR regress_subscription_user2 SERVER test_server OPTIONS(user 'foo'); -ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection_no_password; - --- fail, new owner's generated conninfo must satisfy password_required -ALTER SUBSCRIPTION regress_testsub6 OWNER TO regress_subscription_user2; - -ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection; -DROP USER MAPPING FOR regress_subscription_user2 SERVER test_server; -REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user2; -- fail, subscription depends on the server and cannot be dropped by CASCADE DROP SERVER test_server CASCADE; @@ -208,7 +194,6 @@ DROP FUNCTION test_fdw_connection(oid, oid, internal); ALTER FOREIGN DATA WRAPPER test_fdw NO CONNECTION; DROP FUNCTION test_fdw_connection(oid, oid, internal); -DROP FUNCTION test_fdw_connection_no_password(oid, oid, internal); DROP FOREIGN DATA WRAPPER test_fdw; From a1e39c501d7a89a01c2738fecf7b66927e4e8bb7 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 5 Aug 2026 13:19:21 -0700 Subject: [PATCH 299/481] When changing owner of a subscription, do not throw an error. Errors will be caught when the connection is actually used. Restore uses multiple DDL commands to restore a subscription, so checks of the intermediate state risk restore errors. In the future we could address this with a more careful restoration order, but the DDL-time errors are merely for convenience. Addresses finding 2 in the report from the linked discussion. Reported-by: Noah Misch Reviewed-by: Shlok Kyal Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/20260710195902.4f.noahmisch%40microsoft.com Discussion: https://postgr.es/m/e103ae8daf74485e0c0ebde297fae735d38f54d1.camel@j-davis.com Backpatch-through: 19 --- src/backend/commands/subscriptioncmds.c | 24 +++++++--------------- src/test/regress/expected/subscription.out | 5 +++++ src/test/regress/sql/subscription.sql | 4 ++++ 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 50a5e279252..fd28c978c6e 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -2790,25 +2790,15 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) get_database_name(MyDatabaseId)); /* - * If the subscription uses a server, check that the new owner has USAGE - * privileges on the server and that a user mapping exists. Note: does not - * re-check the resulting connection string. + * The privileges will be checked before the connection is actually used, + * so it does not need to be done here. Avoid unnecessary risk of errors + * here, which could interfere with restore. + * + * However, it is convenient to check if a user mapping exists, and raise + * a WARNING if not. */ if (OidIsValid(form->subserver)) - { - ForeignServer *server = GetForeignServer(form->subserver); - - aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, newOwnerId, ACL_USAGE); - if (aclresult != ACLCHECK_OK) - ereport(ERROR, - errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("new subscription owner \"%s\" does not have permission on foreign server \"%s\"", - GetUserNameFromId(newOwnerId, false), - server->servername)); - - /* make sure a user mapping exists */ - GetUserMapping(newOwnerId, server->serverid); - } + GetUserMappingExtended(newOwnerId, form->subserver, WARNING); form->subowner = newOwnerId; CatalogTupleUpdate(rel, &tup->t_self, tup); diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index c034b25f3d5..7163b756787 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -191,6 +191,11 @@ RESET SESSION AUTHORIZATION; DROP SERVER test_server CASCADE; ERROR: cannot drop server test_server because subscription regress_testsub6 depends on it HINT: Drop subscription regress_testsub6 first. +-- ok, USAGE privilege on server not checked for OWNER TO, but warn +-- about user mapping +ALTER SUBSCRIPTION regress_testsub6 OWNER TO regress_subscription_user2; +WARNING: user mapping not found for user "regress_subscription_user2", server "test_server" +ALTER SUBSCRIPTION regress_testsub6 OWNER TO regress_subscription_user3; REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user3; SET SESSION AUTHORIZATION regress_subscription_user3; -- ok, lacks USAGE on test_server, but replacing connection anyway diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql index cbdaaa9294d..1a6fd89854a 100644 --- a/src/test/regress/sql/subscription.sql +++ b/src/test/regress/sql/subscription.sql @@ -136,6 +136,10 @@ RESET SESSION AUTHORIZATION; -- fail, subscription depends on the server and cannot be dropped by CASCADE DROP SERVER test_server CASCADE; +-- ok, USAGE privilege on server not checked for OWNER TO, but warn +-- about user mapping +ALTER SUBSCRIPTION regress_testsub6 OWNER TO regress_subscription_user2; +ALTER SUBSCRIPTION regress_testsub6 OWNER TO regress_subscription_user3; REVOKE USAGE ON FOREIGN SERVER test_server FROM regress_subscription_user3; SET SESSION AUTHORIZATION regress_subscription_user3; From 4edd59de527780f536fbbf97d5e117524ded2723 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Thu, 6 Aug 2026 17:43:26 +1200 Subject: [PATCH 300/481] Fix unlikely incremental tuple deform bug with missing attrs The code added in c456e3911 added populate_isnull_array() to bulk populate the slot's tts_isnull array 8 elements at a time. When tuples don't have an exact multiple-of-eight number of attributes, this will lead to populating the tts_isnull elements for attributes that don't exist in the tuple. This is ok as the array is large enough. However, if we perform tuple deforming in two passes, and on the first pass deform *some* of the attributes with slot_getmissingattrs() then later when we deform the remaining missing attributes, the subsequent call to populate_isnull_array() would overwrite the tts_isnull values previously set by slot_getmissingattrs(), and since that function only continues where it left off, it wouldn't reapply the previously set values and those would be left as NULLs, as populate_isnull_array() would have set them. Here, we fix by passing the tuple's natts to slot_getmissingattrs() rather than the attnum we're deforming from. This means we apply all the missing attribute values each deform pass, so slightly more work, but deforming several missing values in different deform passes is likely exceedingly rare. Doing that seems much better than adding overhead in the happy path to check for this and skip the subsequent call to populate_isnull_array(). Author: David Rowley Reported-by: Peter Geoghegan Discussion: https://postgr.es/m/CAH2-WznHo4b+6AmAj0GZ0jXqDSK69MfHe8fAQwuY_01y7cVNdw@mail.gmail.com Backpatch-through: 19 --- src/backend/executor/execTuples.c | 12 +++++++++++- src/test/regress/expected/fast_default.out | 15 +++++++++++++++ src/test/regress/sql/fast_default.sql | 10 ++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 97ae019d10a..3ad983c7fa5 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -1254,7 +1254,17 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp, * to implement a tail-call optimization */ *offp = off; - slot_getmissingattrs(slot, attnum, reqnatts); + + Assert(HeapTupleHeaderGetNatts(tup) <= attnum); + + /* + * Fetch all missing attributes. We pass natts rather than attnum as + * if we're deforming attributes after having already deformed some + * missing attributes, then the call to populate_isnull_array() may + * have overwritten the previous tts_isnull values from what was + * stored in the previous call to slot_getmissingattrs(). + */ + slot_getmissingattrs(slot, HeapTupleHeaderGetNatts(tup), reqnatts); return; } done: diff --git a/src/test/regress/expected/fast_default.out b/src/test/regress/expected/fast_default.out index 49485f5ec6a..20356467655 100644 --- a/src/test/regress/expected/fast_default.out +++ b/src/test/regress/expected/fast_default.out @@ -944,6 +944,21 @@ SELECT * FROM t ORDER BY id; (3 rows) DROP TABLE t; +-- Ensure defaults are correctly applied during tuple deformation for whole +-- row vars when the defaults are deformed incrementally. +CREATE TABLE t_missing_wholerow (a int NOT NULL, b int); +INSERT INTO t_missing_wholerow (a, b) VALUES (1, null); -- with NULL bitmap +INSERT INTO t_missing_wholerow (a, b) VALUES (2, 3); -- without NULL bitmap +ALTER TABLE t_missing_wholerow ADD COLUMN c int NOT NULL DEFAULT 15; +ALTER TABLE t_missing_wholerow ADD COLUMN d bigint NOT NULL DEFAULT 25; +SELECT a, b, c, t FROM t_missing_wholerow t; + a | b | c | t +---+---+----+------------- + 1 | | 15 | (1,,15,25) + 2 | 3 | 15 | (2,3,15,25) +(2 rows) + +DROP TABLE t_missing_wholerow; -- cleanup DROP FOREIGN TABLE ft1; DROP SERVER s0; diff --git a/src/test/regress/sql/fast_default.sql b/src/test/regress/sql/fast_default.sql index ccd138c4efc..36f81a184f0 100644 --- a/src/test/regress/sql/fast_default.sql +++ b/src/test/regress/sql/fast_default.sql @@ -618,6 +618,16 @@ REPACK t; SELECT * FROM t ORDER BY id; DROP TABLE t; +-- Ensure defaults are correctly applied during tuple deformation for whole +-- row vars when the defaults are deformed incrementally. +CREATE TABLE t_missing_wholerow (a int NOT NULL, b int); +INSERT INTO t_missing_wholerow (a, b) VALUES (1, null); -- with NULL bitmap +INSERT INTO t_missing_wholerow (a, b) VALUES (2, 3); -- without NULL bitmap +ALTER TABLE t_missing_wholerow ADD COLUMN c int NOT NULL DEFAULT 15; +ALTER TABLE t_missing_wholerow ADD COLUMN d bigint NOT NULL DEFAULT 25; +SELECT a, b, c, t FROM t_missing_wholerow t; +DROP TABLE t_missing_wholerow; + -- cleanup DROP FOREIGN TABLE ft1; DROP SERVER s0; From f4e44f184cef6a80b4d11bbaeaf2b13e59c1dd8e Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Thu, 6 Aug 2026 11:33:05 +0530 Subject: [PATCH 301/481] Fix race condition in subscription TAP test 023_twophase_stream. Buildfarm member olingo intermittently failed this test, timing out while waiting for the subscriber log to report an ERROR because max_prepared_transactions is zero there. The test captured the log offset only after issuing the publisher's BEGIN/INSERT/PREPARE TRANSACTION/COMMIT PREPARED sequence. Since streaming is enabled, the subscriber can receive and apply the transaction, and log the expected ERROR, before that publisher SQL command even returns, i.e. before the test captures the offset. The subsequent wait_for_log() calls then searched only from a point after the message had already been written, and timed out waiting for it. Fix by moving the offset capture to before the publisher's transaction is issued, ensuring it always precedes the point where the ERROR can appear in the subscriber log. Reported-by: Alexander Lakhin Author: Zhijie Hou Reviewed-by: Amit Kapila Backpatch-through: 16, where test was introduced Discussion: https://postgr.es/m/c43753d8-5265-4f77-83ff-9b1167276ec5@gmail.com --- src/test/subscription/t/023_twophase_stream.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/subscription/t/023_twophase_stream.pl b/src/test/subscription/t/023_twophase_stream.pl index e9e0f753f7c..fbb2dffbd95 100644 --- a/src/test/subscription/t/023_twophase_stream.pl +++ b/src/test/subscription/t/023_twophase_stream.pl @@ -439,6 +439,8 @@ sub test_streaming )); $node_subscriber->restart; +$offset = -s $node_subscriber->logfile; + $node_publisher->safe_psql( 'postgres', q{ BEGIN; @@ -447,8 +449,6 @@ sub test_streaming COMMIT PREPARED 'xact'; }); -$offset = -s $node_subscriber->logfile; - # Confirm the ERROR is reported because max_prepared_transactions is zero $node_subscriber->wait_for_log( qr/ERROR: ( [A-Z0-9]+:)? prepared transactions are disabled/, $offset); From 22d0eebfef780b21c4e5a16966eff59fb7a9b9d6 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 6 Aug 2026 10:23:44 +0200 Subject: [PATCH 302/481] Report duplicate property and label names with a proper error Adding a property with the same name multiple times to a label on an element, either within a single PROPERTIES clause or across statements via ALTER PROPERTY GRAPH ... ADD PROPERTIES, previously failed with a unique-index violation on pg_propgraph_label_property. The same class of bug existed for labels: listing the same label multiple times on one element in CREATE PROPERTY GRAPH, or adding a label to an element that already has it via ALTER PROPERTY GRAPH ... ADD LABEL, failed with a unique-index violation on pg_propgraph_element_label. Detect the duplicates up front and raise a friendlier error in both cases. For properties, the cross-statement duplicate is caught by a syscache probe before insertion. The in-clause duplicate could have been caught by the same probe if we issued a CommandCounterIncrement() between property inserts, but that forces a catalog invalidation per property purely to detect a condition we can check for free on the in-memory target list. The list-based check is only needed when the properties are listed explicitly; when they are derived from the table's attributes, names are already unique. For labels, a single syscache probe on pg_propgraph_element_label suffices for both the in-clause and cross-statement cases because insert_element_record() already issues CommandCounterIncrement() between successive label inserts. Author: Ashutosh Bapat Reported-by: Noah Misch Discussion: https://www.postgresql.org/message-id/flat/20260630173053.51.noahmisch%40microsoft.com --- src/backend/commands/propgraphcmds.c | 37 +++++++++++++++++-- .../expected/create_property_graph.out | 14 +++++++ .../regress/sql/create_property_graph.sql | 12 ++++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/backend/commands/propgraphcmds.c b/src/backend/commands/propgraphcmds.c index c87c519b032..9c9f4f2b299 100644 --- a/src/backend/commands/propgraphcmds.c +++ b/src/backend/commands/propgraphcmds.c @@ -784,6 +784,13 @@ insert_label_record(Oid graphid, Oid peoid, const char *label) /* * Insert into pg_propgraph_element_label */ + if (SearchSysCacheExists2(PROPGRAPHELEMENTLABELELEMENTLABEL, + ObjectIdGetDatum(peoid), + ObjectIdGetDatum(labeloid))) + ereport(ERROR, + errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("label \"%s\" already exists", label)); + else { Relation rel; Datum values[Natts_pg_propgraph_element_label] = {0}; @@ -901,12 +908,30 @@ insert_property_records(Oid graphid, Oid ellabeloid, Oid pgerelid, const PropGra resolveTargetListUnknowns(pstate, tp); assign_expr_collations(pstate, (Node *) tp); - foreach(lc, tp) + /* + * When properties are derived from the table's attributes, names are + * already unique. Reject duplicate property names within an explicit + * PROPERTIES clause. Do this after transformTargetList() so that any + * names derived by transformTargetList() are considered. + */ + if (!properties->all) { - TargetEntry *te = lfirst_node(TargetEntry, lc); + List *seen = NIL; - insert_property_record(graphid, ellabeloid, pgerelid, te->resname, te->expr); + foreach_node(TargetEntry, te, tp) + { + String *name = makeString(te->resname); + + if (list_member(seen, name)) + ereport(ERROR, + errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("property \"%s\" specified more than once", te->resname)); + seen = lappend(seen, name); + } } + + foreach_node(TargetEntry, te, tp) + insert_property_record(graphid, ellabeloid, pgerelid, te->resname, te->expr); } /* @@ -1003,6 +1028,12 @@ insert_property_record(Oid graphid, Oid ellabeloid, Oid pgerelid, const char *pr /* * Insert into pg_propgraph_label_property */ + if (SearchSysCacheExists2(PROPGRAPHLABELPROP, ObjectIdGetDatum(ellabeloid), + ObjectIdGetDatum(propoid))) + ereport(ERROR, + errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("property \"%s\" already exists", propname)); + else { Relation rel; Datum values[Natts_pg_propgraph_label_property] = {0}; diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out index 9a3cc6c13b2..646e5fed5e2 100644 --- a/src/test/regress/expected/create_property_graph.out +++ b/src/test/regress/expected/create_property_graph.out @@ -207,6 +207,20 @@ CREATE PROPERTY GRAPH gx ); DROP PROPERTY GRAPH gx; DROP TABLE t1x, t2x; +CREATE PROPERTY GRAPH gx + VERTEX TABLES ( + t1 KEY (a) LABEL l1 PROPERTIES (a AS p, a AS p) -- duplicate property on label + ); +ERROR: property "p" specified more than once +ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 ADD PROPERTIES (k * 2 AS i_j); -- duplicate property on label +ERROR: property "i_j" already exists +CREATE PROPERTY GRAPH gx + VERTEX TABLES ( + t1 KEY (a) LABEL l1 LABEL l1 -- duplicate label on element + ); +ERROR: label "l1" already exists +ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t3 ADD LABEL t3l1 NO PROPERTIES; -- duplicate label on element +ERROR: label "t3l1" already exists CREATE PROPERTY GRAPH gx VERTEX TABLES ( t1 KEY (a) LABEL l1 PROPERTIES (a, a AS aa), diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql index 1ee223809f3..b1a8d12a040 100644 --- a/src/test/regress/sql/create_property_graph.sql +++ b/src/test/regress/sql/create_property_graph.sql @@ -161,6 +161,18 @@ CREATE PROPERTY GRAPH gx DROP PROPERTY GRAPH gx; DROP TABLE t1x, t2x; +CREATE PROPERTY GRAPH gx + VERTEX TABLES ( + t1 KEY (a) LABEL l1 PROPERTIES (a AS p, a AS p) -- duplicate property on label + ); +ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 ADD PROPERTIES (k * 2 AS i_j); -- duplicate property on label + +CREATE PROPERTY GRAPH gx + VERTEX TABLES ( + t1 KEY (a) LABEL l1 LABEL l1 -- duplicate label on element + ); +ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t3 ADD LABEL t3l1 NO PROPERTIES; -- duplicate label on element + CREATE PROPERTY GRAPH gx VERTEX TABLES ( t1 KEY (a) LABEL l1 PROPERTIES (a, a AS aa), From fd90c3221850d9ee1d05f4ce3f5420a54b3e471c Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Thu, 6 Aug 2026 17:16:23 -0400 Subject: [PATCH 303/481] Restore vacuum failsafe abandonment of buffer access strategy VACUUM's wraparound failsafe mode exists to reclaim transaction IDs as quickly as possible. 4830f1024325 made the failsafe stop using the BAS_VACUUM buffer access strategy so that the rest of the vacuum could make use of all of shared buffers rather than being confined to the small strategy ring. However, when 9256822608f3 made vacuum's first heap pass use the read stream, this was accidentally disabled. The read stream keeps its own references to the buffer access strategy, so clearing vacrel->bstrategy in lazy_check_wraparound_failsafe() no longer had any effect on the reads issued by the first pass. Fix this by adding clearing the BufferAccessStrategy reference actually being used by the ongoing scan -- those in the ReadBuffersOperations structs themselves. Two things we accept rather than fix, as neither is worth the added complexity given how rarely failsafe mode is reached: - A small amount of read time for IOs that were already in progress when the strategy was cleared may be attributed to IOCONTEXT_NORMAL instead of IOCONTEXT_VACUUM. WaitReadBuffers() derives the IOContext from the (now cleared) strategy, so the wait time of these in-flight IOs is misattributed. This is bounded by the stream's look-ahead window and happens at most once per vacuum, when the strategy is first cleared. - The stream's buffer pin limit stays lower than it would have been had no strategy been used at all. max_pinned_buffers is capped by the strategy's pin limit when the stream is created and is not recomputed when the strategy is cleared. Raising it would mean building a new, larger ring, which would require first waiting for all in-progress IOs to complete. That didn't seem worth it. Reported-by: Jingtang Zhang Discussion: https://postgr.es/m/CAPsk3_APRYVLhAJ5TMwdmpSx8W_%3DPHMm%3DPmKAvnC3gBrfNommQ%40mail.gmail.com Backpatch-to: 18 --- src/backend/access/heap/vacuumlazy.c | 25 ++++++++++++++++++++++--- src/backend/storage/aio/read_stream.c | 21 +++++++++++++++++++++ src/include/storage/read_stream.h | 1 + 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 39395aed0d5..d346344934c 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -1385,6 +1385,15 @@ lazy_scan_heap(LVRelState *vacrel) PROGRESS_VACUUM_PHASE_SCAN_HEAP); } + /* + * If the wraparound failsafe has engaged -- either via the check + * above or during index vacuuming invoked from this loop -- stop + * using the buffer access strategy so that the rest of the vacuum may + * use all of shared buffers. + */ + if (unlikely(VacuumFailsafeActive)) + read_stream_clear_strategy(stream); + buf = read_stream_next_buffer(stream, &per_buffer_data); /* The relation is exhausted. */ @@ -2905,9 +2914,19 @@ lazy_check_wraparound_failsafe(LVRelState *vacrel) VacuumFailsafeActive = true; /* - * Abandon use of a buffer access strategy to allow use of all of - * shared buffers. We assume the caller who allocated the memory for - * the BufferAccessStrategy will free it. + * We abandon use of the strategy in failsafe mode to allow use of all + * of shared buffers. vacrel->bstrategy is not the source of truth for + * an ongoing heap scan, but clear it just for tidiness. Any ongoing + * phase I heap scan has its own references to the strategy and clears + * them separately (see lazy_scan_heap()). And none of the other + * vacuum phases will read from vacrel->bstrategy once failsafe mode + * is engaged. The phase I read stream clears the strategy references + * held by the ReadBuffersOperations outside of this function because + * lazy_check_wraparound_failsafe() may be called from any phase of + * vacuum, including when the phase I stream is inactive. + * + * We assume the caller who allocated the memory for the + * BufferAccessStrategy will free it. */ vacrel->bstrategy = NULL; diff --git a/src/backend/storage/aio/read_stream.c b/src/backend/storage/aio/read_stream.c index a318539e56c..e7dbbe03326 100644 --- a/src/backend/storage/aio/read_stream.c +++ b/src/backend/storage/aio/read_stream.c @@ -1407,6 +1407,27 @@ read_stream_resume(ReadStream *stream) stream->combine_distance = stream->resume_combine_distance; } +/* + * Stop using a buffer access strategy for reads from this stream. + * + * This clears the strategy for all of the stream's ReadBuffersOperations, + * including those with in-progress IOs. The completion of an IO whose + * strategy was cleared while it was in flight may have a small amount of its + * read time attributed to IOCONTEXT_NORMAL instead of the strategy's + * IOContext, because WaitReadBuffers() derives the IOContext from the (now + * cleared) strategy. This is bounded by the stream's look-ahead window and + * happens at most once, when the strategy is first cleared, so it is not worth + * the complexity of preserving the original IOContext for those IOs. + * + * Note that the caller is responsible for freeing the strategy's memory. + */ +void +read_stream_clear_strategy(ReadStream *stream) +{ + for (int i = 0; i < stream->max_ios; ++i) + stream->ios[i].op.strategy = NULL; +} + /* * Reset a read stream by releasing any queued up buffers, allowing the stream * to be used again for different blocks. This can be used to clear an diff --git a/src/include/storage/read_stream.h b/src/include/storage/read_stream.h index 48995c6d534..e2dcf1be50a 100644 --- a/src/include/storage/read_stream.h +++ b/src/include/storage/read_stream.h @@ -102,6 +102,7 @@ extern ReadStream *read_stream_begin_smgr_relation(int flags, size_t per_buffer_data_size); extern BlockNumber read_stream_pause(ReadStream *stream); extern void read_stream_resume(ReadStream *stream); +extern void read_stream_clear_strategy(ReadStream *stream); extern void read_stream_reset(ReadStream *stream); extern void read_stream_end(ReadStream *stream); extern void read_stream_enable_stats(ReadStream *stream, struct IOStats *stats); From cacba321c2ef9dfd1c1b6924b6c7291a1182d2d6 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 7 Aug 2026 12:28:44 +0900 Subject: [PATCH 304/481] Make 030_pg_recvlogical robust against PID reuse The reconnection test assumed that a restarted walsender would always have a different PID from the previous one. On some platforms, however, PIDs can be reused quickly, causing the test to time out even though pg_recvlogical has successfully reconnected. This issue was reported by buildfarm member fairywren: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=fairywren&dt=2026-07-30%2009%3A58%3A12 Fix this by waiting for the server log message indicating that the logical replication slot has been acquired again, rather than relying on a PID change. Backpatch to v19, where the affected reconnection test was introduced by commit d89b1d817513. Author: Hayato Kuroda Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/OS9PR01MB121497CF10DFF54F745E37204F5C92@OS9PR01MB12149.jpnprd01.prod.outlook.com Backpatch-through: 19 --- src/bin/pg_basebackup/t/030_pg_recvlogical.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl index 945a242bdad..35c77358f11 100644 --- a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl +++ b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl @@ -198,6 +198,8 @@ # Wait for pg_recvlogical to receive and write the first INSERT my $first_ins = wait_for_file($outfile, qr/INSERT/); +my $log_offset = -s $node->logfile; + # Terminate the walsender to force pg_recvlogical to reconnect my $backend_pid = $node->safe_psql('postgres', "SELECT active_pid FROM pg_replication_slots WHERE slot_name = 'reconnect_test'" @@ -205,9 +207,8 @@ $node->safe_psql('postgres', "SELECT pg_terminate_backend($backend_pid)"); # Wait for pg_recvlogical to reconnect -$node->poll_query_until('postgres', - "SELECT active_pid IS NOT NULL AND active_pid != $backend_pid FROM pg_replication_slots WHERE slot_name = 'reconnect_test'" -) or die "Timed out while waiting for pg_recvlogical to reconnect"; +$node->wait_for_log(qr/acquired logical replication slot \"reconnect_test\"/, + $log_offset); # Insert the second record for this test $node->safe_psql('postgres', 'INSERT INTO test_table VALUES (2)'); From 89fc6a7c12f2ee6d75e6ebab06844edd4737c348 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 7 Aug 2026 14:23:33 +0900 Subject: [PATCH 305/481] Fix local pgstat entry leak on OOM during entry creation When pgstat_init_entry() fails due to an OOM in the DSA allocation, pgstat_get_entry_ref() cleaned up the shared hashtable but forgot to remove the local reference that pgstat_get_entry_ref_cached() had already inserted into pgStatEntryRefHash. Missing this cleanup would leave a backend with a stale local cache entry whose entry_ref points to a NULL shared_stats. If pgstat_gc_entry_refs() runs with this reference still around, it would crash due to a pointer dereference. The local reference is now removed before removing the shared entry, the order being sensitive to pending interrupts. Oversight in 8191e0c16a03. Author: Niall Newman Discussion: https://postgr.es/m/2FDAA194-9CF3-4FD7-A450-F1A4BEB125F6@turacolabs.com Backpatch-through: 15 --- src/backend/utils/activity/pgstat_shmem.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/activity/pgstat_shmem.c b/src/backend/utils/activity/pgstat_shmem.c index 5ea3f1973f9..58b99002f3f 100644 --- a/src/backend/utils/activity/pgstat_shmem.c +++ b/src/backend/utils/activity/pgstat_shmem.c @@ -539,9 +539,12 @@ pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, uint64 objid, bool create, if (shheader == NULL) { /* - * Failed the allocation of a new entry, so clean up the - * shared hashtable before giving up. + * Failed the allocation of a new entry, so clean up both the + * local reference and the shared hashtable before giving up. + * Clean the local state first, since releasing the dshash + * lock can process a pending interrupt. */ + pgstat_release_entry_ref(key, entry_ref, false); dshash_delete_entry(pgStatLocal.shared_hash, shhashent); ereport(ERROR, From c17b91ed9f84e43efc9a3d41ade5d1d1b827f8d4 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Fri, 7 Aug 2026 16:12:47 +0900 Subject: [PATCH 306/481] Remove stale comment on ri_FastPathCheck() The note claiming ri_FastPathCheck() is only used by the ALTER TABLE validation path is no longer accurate. Rather than reword it, remove it; the block comment above RI_FKey_check()'s call to the function already documents when each path is taken, and a duplicated cross-reference here would only drift out of date again. Reported-by: Noah Misch Reviewed-by: Ayush Tiwari Discussion: https://postgr.es/m/20260705210533.ee.noahmisch@microsoft.com Backpatch-through: 19 --- src/backend/utils/adt/ri_triggers.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index bf54f9b4592..2f6c8197b2d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -2795,9 +2795,6 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, * * If no matching PK row exists, report the violation via ri_ReportViolation(), * otherwise, the function returns normally. - * - * Note: This is only used by the ALTER TABLE validation path. Other paths use - * ri_FastPathBatchAdd(). */ static void ri_FastPathCheck(RI_ConstraintInfo *riinfo, From 8c0aa08c159494a86fe5c3206e8a9f5de850112e Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Fri, 7 Aug 2026 16:30:15 +0900 Subject: [PATCH 307/481] Restrict RI fast-path FK check to btree referenced indexes The RI fast-path check probes the referenced index directly and, for single-column keys, uses SK_SEARCHARRAY. Both assume the index is a btree. A comment claimed "PK indexes are always btree", but a foreign key's referenced index need not be a primary key: transformFkeyCheckAttrs() accepts any unique (or, for temporal keys, exclusion) index, so an out-of-tree access method advertising amcanunique could supply a non-btree index reachable by the fast path. Add pk_index_is_btree to RI_ConstraintInfo, set from the referenced index's access method when the constraint is loaded, and make ri_fastpath_is_applicable() return false for non-btree indexes so such constraints fall back to the SPI path. Reported-by: Noah Misch Reviewed-by: Ayush Tiwari Discussion: https://postgr.es/m/20260705210533.ee.noahmisch@microsoft.com Backpatch-through: 19 --- src/backend/utils/adt/ri_triggers.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 2f6c8197b2d..74774f6b2bd 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -32,6 +32,7 @@ #include "access/tableam.h" #include "access/xact.h" #include "catalog/index.h" +#include "catalog/pg_am_d.h" #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" #include "catalog/pg_namespace.h" @@ -142,6 +143,7 @@ typedef struct RI_ConstraintInfo Oid conindid; bool pk_is_partitioned; + bool pk_index_is_btree; /* is conindid a btree index? */ FastPathMeta *fpmeta; } RI_ConstraintInfo; @@ -2503,6 +2505,8 @@ ri_LoadConstraintInfo(Oid constraintOid) riinfo->conindid = conForm->conindid; riinfo->pk_is_partitioned = (get_rel_relkind(riinfo->pk_relid) == RELKIND_PARTITIONED_TABLE); + riinfo->pk_index_is_btree = + (get_rel_relam(riinfo->conindid) == BTREE_AM_OID); ReleaseSysCache(tup); @@ -3150,7 +3154,8 @@ ri_FastPathFlushArray(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, * Build scan key with SK_SEARCHARRAY. The index AM code will internally * sort and deduplicate, then walk leaf pages in order. * - * PK indexes are always btree, which supports SK_SEARCHARRAY. + * ri_fastpath_is_applicable() restricts the fast path to btree indexes, + * which support SK_SEARCHARRAY. * * This path handles single-column FKs only, so index_attnos[0] == 1. */ @@ -3359,6 +3364,17 @@ ri_fastpath_is_applicable(const RI_ConstraintInfo *riinfo) if (riinfo->hasperiod) return false; + /* + * The fast path probes the referenced index directly and, for + * single-column keys, uses SK_SEARCHARRAY. A foreign key's referenced + * index need not be a primary key; transformFkeyCheckAttrs() accepts any + * unique index, so an out-of-tree amcanunique access method could reach + * here. Restrict the fast path to btree, which is what the direct probe + * and SK_SEARCHARRAY assume; other access methods fall back to SPI. + */ + if (!riinfo->pk_index_is_btree) + return false; + return true; } From f68f47fe7d66a475d934823624013bcb7fae6f01 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Fri, 7 Aug 2026 16:34:00 +0900 Subject: [PATCH 308/481] Begin RI fast-path index scan under the switched user id ri_FastPathCheck() called index_beginscan() before switching to the referenced relation's owner for the permission check and probe. For btree this has no consequence, but starting the scan before the user id switch sets a poor example for code dealing with out-of-tree access methods, whose beginscan could observe the wrong user id. Move index_beginscan() after the SetUserIdAndSecContext() call. Reported-by: Noah Misch Reviewed-by: Ayush Tiwari Discussion: https://postgr.es/m/20260705210533.ee.noahmisch@microsoft.com Backpatch-through: 19 --- src/backend/utils/adt/ri_triggers.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 74774f6b2bd..19af06ee794 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -2828,10 +2828,6 @@ ri_FastPathCheck(RI_ConstraintInfo *riinfo, idx_rel = index_open(riinfo->conindid, AccessShareLock); slot = table_slot_create(pk_rel, NULL); - scandesc = index_beginscan(pk_rel, idx_rel, - snapshot, NULL, - riinfo->nkeys, 0, - SO_NONE); GetUserIdAndSecContext(&saved_userid, &saved_sec_context); SetUserIdAndSecContext(RelationGetForm(pk_rel)->relowner, @@ -2840,6 +2836,17 @@ ri_FastPathCheck(RI_ConstraintInfo *riinfo, SECURITY_NOFORCE_RLS); ri_CheckPermissions(pk_rel); + /* + * Begin the scan under the switched user id, so that any access method + * code invoked by index_beginscan() runs as the PK relation's owner. For + * btree this has no functional consequence, but it keeps the ordering + * correct for out-of-tree access methods. + */ + scandesc = index_beginscan(pk_rel, idx_rel, + snapshot, NULL, + riinfo->nkeys, 0, + SO_NONE); + if (riinfo->fpmeta == NULL) { /* Reload to ensure it's valid. */ @@ -2965,9 +2972,6 @@ ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel, */ oldcxt = MemoryContextSwitchTo(fpentry->flush_cxt); - scandesc = index_beginscan(pk_rel, idx_rel, snapshot, NULL, - riinfo->nkeys, 0, SO_NONE); - GetUserIdAndSecContext(&saved_userid, &saved_sec_context); SetUserIdAndSecContext(RelationGetForm(pk_rel)->relowner, saved_sec_context | @@ -2983,6 +2987,15 @@ ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel, */ ri_CheckPermissions(pk_rel); + /* + * Begin the scan under the switched user id, so that any access method + * code invoked by index_beginscan() runs as the PK relation's owner. For + * btree this has no functional consequence, but it keeps the ordering + * correct for out-of-tree access methods. + */ + scandesc = index_beginscan(pk_rel, idx_rel, snapshot, NULL, + riinfo->nkeys, 0, SO_NONE); + if (riinfo->fpmeta == NULL) { /* Reload to ensure it's valid. */ From acdfaee1b947776ec381a4756f01979d31316774 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Fri, 7 Aug 2026 17:25:42 +0900 Subject: [PATCH 309/481] Fire fast-path FK batches inside the deferred trigger loop AfterTriggerFireDeferred() drained its queued events in a loop, then called FireAfterTriggerBatchCallbacks() once after the loop to flush the RI fast-path FK-check batches the fired triggers accumulated. A batch callback runs user-supplied cast or equality functions, whose DML can queue further deferred trigger events. Because the flush ran after the loop had exited, such an event was left in afterTriggers.events with nothing to fire it, since AfterTriggerFireDeferred() is the last drainer at commit. The deferred check was skipped and a row violating the constraint committed. Move the flush inside the loop, after afterTriggerInvokeEvents(), and drop the "all fired" break, so afterTriggerMarkEvents() re-checks after each flush and fires events a flush queued at the correct time. The other FireAfterTriggerBatchCallbacks() callers leave any queued event for the eventual commit-time AfterTriggerFireDeferred(), so only the commit-time firing, which has no later drainer, lost events. Reported-by: Noah Misch Reviewed-by: Ayush Tiwari Discussion: https://postgr.es/m/20260705210533.ee.noahmisch@microsoft.com Backpatch-through: 19 --- src/backend/commands/trigger.c | 20 +++++++++--- src/test/regress/expected/foreign_key.out | 39 +++++++++++++++++++++++ src/test/regress/sql/foreign_key.sql | 38 ++++++++++++++++++++++ 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index b87b4b40d07..c1991505ace 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -5355,12 +5355,22 @@ AfterTriggerFireDeferred(void) { CommandId firing_id = afterTriggers.firing_counter++; - if (afterTriggerInvokeEvents(events, firing_id, NULL, true)) - break; /* all fired */ - } + (void) afterTriggerInvokeEvents(events, firing_id, NULL, true); - /* Flush any fast-path batches accumulated by the triggers just fired. */ - FireAfterTriggerBatchCallbacks(afterTriggers.batch_callbacks); + /* + * Flush any fast-path FK-check batches accumulated by the triggers + * just fired. A batch callback runs user-supplied cast or equality + * functions, whose DML can queue further deferred trigger events. + * Flush inside the loop so afterTriggerMarkEvents() sees any such + * events on the next iteration and fires them; flushing after the + * loop would leave them unfired, silently skipping e.g. a deferred FK + * check and letting a violating row commit. (The former "all fired" + * break is therefore gone: the loop now terminates only when + * afterTriggerMarkEvents() finds nothing left, including events queued + * by the flush.) + */ + FireAfterTriggerBatchCallbacks(afterTriggers.batch_callbacks); + } afterTriggers.firing_depth--; diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out index c334cce752c..120d3319451 100644 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@ -3604,6 +3604,45 @@ ERROR: insert or update on table "fp_fk_defer" violates foreign key constraint DETAIL: Key (a)=(3) is not present in table "fp_pk_defer". COMMIT; DROP TABLE fp_pk_defer, fp_fk_defer; +-- A deferred FK check queued while firing deferred triggers at commit must +-- not be lost. The RI fast-path flush runs during the deferred firing loop +-- and can run user cast/equality code whose DML queues a further deferred +-- check; that check must still fire. fk_defer_main's deferred fast-path check +-- runs a cast whose function inserts a violating row into fk_defer_t2, +-- queueing fk_defer_t2's own deferred check, which must still be reported. +CREATE TABLE fk_defer_t2_pk (id int PRIMARY KEY); +CREATE TABLE fk_defer_t2 (a int REFERENCES fk_defer_t2_pk(id) + DEFERRABLE INITIALLY DEFERRED); +CREATE TYPE fk_defer_vch AS (v int); +CREATE FUNCTION fk_defer_cast(fk_defer_vch) RETURNS int + LANGUAGE plpgsql AS $$ +BEGIN + INSERT INTO fk_defer_t2 VALUES (999); -- 999 absent, queues deferred check + RETURN $1.v; +END$$; +CREATE CAST (fk_defer_vch AS int) WITH FUNCTION fk_defer_cast(fk_defer_vch) + AS IMPLICIT; +CREATE TABLE fk_defer_main_pk (id int PRIMARY KEY); +INSERT INTO fk_defer_main_pk VALUES (1); +CREATE TABLE fk_defer_main (a fk_defer_vch REFERENCES fk_defer_main_pk(id) + DEFERRABLE INITIALLY DEFERRED); +-- At COMMIT the queued fk_defer_t2 check must fire and report the violation, +-- rather than being dropped (which would let the dangling row commit). +BEGIN; +INSERT INTO fk_defer_main VALUES (row(1)::fk_defer_vch); +COMMIT; -- expected: ERROR on fk_defer_t2_a_fkey +ERROR: insert or update on table "fk_defer_t2" violates foreign key constraint "fk_defer_t2_a_fkey" +DETAIL: Key (a)=(999) is not present in table "fk_defer_t2_pk". +-- The queued check must fire at transaction end, not early: making the +-- referenced row present in the same transaction lets the commit succeed. +INSERT INTO fk_defer_t2_pk VALUES (999); +BEGIN; +INSERT INTO fk_defer_main VALUES (row(1)::fk_defer_vch); +COMMIT; -- expected: success +DROP TABLE fk_defer_main, fk_defer_main_pk, fk_defer_t2, fk_defer_t2_pk; +DROP CAST (fk_defer_vch AS int); +DROP FUNCTION fk_defer_cast(fk_defer_vch); +DROP TYPE fk_defer_vch; -- Subtransaction abort: cached state must be invalidated on ROLLBACK TO CREATE TABLE fp_pk_subxact (a int PRIMARY KEY); CREATE TABLE fp_fk_subxact (a int REFERENCES fp_pk_subxact); diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql index 17eadc4bb5a..b9b88064ea5 100644 --- a/src/test/regress/sql/foreign_key.sql +++ b/src/test/regress/sql/foreign_key.sql @@ -2580,6 +2580,44 @@ INSERT INTO fp_fk_defer VALUES (3); -- should fail, also tests that cache was c COMMIT; DROP TABLE fp_pk_defer, fp_fk_defer; +-- A deferred FK check queued while firing deferred triggers at commit must +-- not be lost. The RI fast-path flush runs during the deferred firing loop +-- and can run user cast/equality code whose DML queues a further deferred +-- check; that check must still fire. fk_defer_main's deferred fast-path check +-- runs a cast whose function inserts a violating row into fk_defer_t2, +-- queueing fk_defer_t2's own deferred check, which must still be reported. +CREATE TABLE fk_defer_t2_pk (id int PRIMARY KEY); +CREATE TABLE fk_defer_t2 (a int REFERENCES fk_defer_t2_pk(id) + DEFERRABLE INITIALLY DEFERRED); +CREATE TYPE fk_defer_vch AS (v int); +CREATE FUNCTION fk_defer_cast(fk_defer_vch) RETURNS int + LANGUAGE plpgsql AS $$ +BEGIN + INSERT INTO fk_defer_t2 VALUES (999); -- 999 absent, queues deferred check + RETURN $1.v; +END$$; +CREATE CAST (fk_defer_vch AS int) WITH FUNCTION fk_defer_cast(fk_defer_vch) + AS IMPLICIT; +CREATE TABLE fk_defer_main_pk (id int PRIMARY KEY); +INSERT INTO fk_defer_main_pk VALUES (1); +CREATE TABLE fk_defer_main (a fk_defer_vch REFERENCES fk_defer_main_pk(id) + DEFERRABLE INITIALLY DEFERRED); +-- At COMMIT the queued fk_defer_t2 check must fire and report the violation, +-- rather than being dropped (which would let the dangling row commit). +BEGIN; +INSERT INTO fk_defer_main VALUES (row(1)::fk_defer_vch); +COMMIT; -- expected: ERROR on fk_defer_t2_a_fkey +-- The queued check must fire at transaction end, not early: making the +-- referenced row present in the same transaction lets the commit succeed. +INSERT INTO fk_defer_t2_pk VALUES (999); +BEGIN; +INSERT INTO fk_defer_main VALUES (row(1)::fk_defer_vch); +COMMIT; -- expected: success +DROP TABLE fk_defer_main, fk_defer_main_pk, fk_defer_t2, fk_defer_t2_pk; +DROP CAST (fk_defer_vch AS int); +DROP FUNCTION fk_defer_cast(fk_defer_vch); +DROP TYPE fk_defer_vch; + -- Subtransaction abort: cached state must be invalidated on ROLLBACK TO CREATE TABLE fp_pk_subxact (a int PRIMARY KEY); CREATE TABLE fp_fk_subxact (a int REFERENCES fp_pk_subxact); From 7d74b26447229cccc2005d8b48b36bcd8bd17f33 Mon Sep 17 00:00:00 2001 From: Etsuro Fujita Date: Fri, 7 Aug 2026 17:30:01 +0900 Subject: [PATCH 310/481] Drain pending asynchronous requests during ExecReScanAppend. The logic for asynchronous Append assumes that pending requests made for subplans of an Append are drained during ExecReScanAppend. To ensure that, commit 9e283fc85 modified postgresReScanForeignScan to drain such a request if any, but failed to take into account that if such a request was made for a subplan that is re-scanned with parameter changes or pruned in the next round by runtime pruning, the postgres_fdw callback function is called after ExecReScanAppend or never called, respectively. This would cause such a request to remain even after ExecReScanAppend, leading to incorrect results, an infinite loop, or an assertion failure. To fix, modify ExecReScanAppend to, for each of the pending requests, give the FDW a chance to drain that request using the existing ForeignAsyncConfigureWait/ForeignAsyncNotify callback functions. This makes the change made to postgresReScanForeignScan useless, so remove it as well. Back-patch to v14 where asynchronous Append was added. Reported-by: Alexander Korotkov Co-authored-by: Alexander Korotkov Co-authored-by: Gleb Kashkin Co-authored-by: Etsuro Fujita Reviewed-by: Alexander Pyhalov Reviewed-by: Gleb Kashkin Discussion: https://postgr.es/m/CAPpHfduMOTnV5Zj2KGJ7zanL_10QvccZHtPUaDfJvBhsh9axnQ%40mail.gmail.com Backpatch-through: 14 --- .../postgres_fdw/expected/postgres_fdw.out | 70 ++++++++++++- contrib/postgres_fdw/postgres_fdw.c | 15 +-- contrib/postgres_fdw/sql/postgres_fdw.sql | 14 ++- src/backend/executor/nodeAppend.c | 97 +++++++++++++++---- 4 files changed, 163 insertions(+), 33 deletions(-) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index d19121b05da..5a77671d35f 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -11836,6 +11836,72 @@ SELECT * FROM result_tbl ORDER BY a; (3 rows) DELETE FROM result_tbl; +-- Test ExecAppendAsyncReset code path that drains outstanding async requests +-- (case where subplans are re-scanned with parameter changes) +EXPLAIN (VERBOSE, COSTS OFF) +SELECT o.x FROM (VALUES (2505), (3505)) o(x), LATERAL (SELECT a FROM async_pt WHERE a = o.x OR a = 1505 LIMIT 1) s ORDER BY o.x; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Sort + Output: "*VALUES*".column1 + Sort Key: "*VALUES*".column1 + -> Nested Loop + Output: "*VALUES*".column1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1 + -> Limit + Output: NULL::integer + -> Append + -> Async Foreign Scan on public.async_p1 async_pt_1 + Output: NULL::integer + Remote SQL: SELECT NULL FROM public.base_tbl1 WHERE (((a = $1::integer) OR (a = 1505))) + -> Async Foreign Scan on public.async_p2 async_pt_2 + Output: NULL::integer + Remote SQL: SELECT NULL FROM public.base_tbl2 WHERE (((a = $1::integer) OR (a = 1505))) + -> Async Foreign Scan on public.async_p3 async_pt_3 + Output: NULL::integer + Remote SQL: SELECT NULL FROM public.base_tbl3 WHERE (((a = $1::integer) OR (a = 1505))) +(19 rows) + +SELECT o.x FROM (VALUES (2505), (3505)) o(x), LATERAL (SELECT a FROM async_pt WHERE a = o.x OR a = 1505 LIMIT 1) s ORDER BY o.x; + x +------ + 2505 + 3505 +(2 rows) + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT o.x FROM (VALUES (2505), (3505)) o(x), LATERAL (SELECT a FROM async_pt WHERE a = o.x OR (a = 1505 AND o.x = 2505) LIMIT 1) s ORDER BY o.x; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: "*VALUES*".column1 + Sort Key: "*VALUES*".column1 + -> Nested Loop + Output: "*VALUES*".column1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1 + -> Limit + Output: NULL::integer + -> Append + -> Async Foreign Scan on public.async_p1 async_pt_1 + Output: NULL::integer + Remote SQL: SELECT NULL FROM public.base_tbl1 WHERE (((a = $1::integer) OR ((a = 1505) AND ($1::integer = 2505)))) + -> Async Foreign Scan on public.async_p2 async_pt_2 + Output: NULL::integer + Remote SQL: SELECT NULL FROM public.base_tbl2 WHERE (((a = $1::integer) OR ((a = 1505) AND ($1::integer = 2505)))) + -> Async Foreign Scan on public.async_p3 async_pt_3 + Output: NULL::integer + Remote SQL: SELECT NULL FROM public.base_tbl3 WHERE (((a = $1::integer) OR ((a = 1505) AND ($1::integer = 2505)))) +(19 rows) + +SELECT o.x FROM (VALUES (2505), (3505)) o(x), LATERAL (SELECT a FROM async_pt WHERE a = o.x OR (a = 1505 AND o.x = 2505) LIMIT 1) s ORDER BY o.x; + x +------ + 2505 + 3505 +(2 rows) + -- Test COPY TO when foreign table is partition COPY async_pt TO stdout; --error ERROR: cannot copy from foreign table "async_p1" @@ -12621,8 +12687,8 @@ DROP TABLE base_tbl1; DROP TABLE base_tbl2; DROP TABLE result_tbl; DROP TABLE join_tbl; --- Test that an asynchronous fetch is processed before restarting the scan in --- ReScanForeignScan +-- Test ExecAppendAsyncReset code path that drains outstanding async requests +-- (case where subplans are re-scanned without parameter changes) CREATE TABLE base_tbl (a int, b int); INSERT INTO base_tbl VALUES (1, 11), (2, 22), (3, 33); CREATE FOREIGN TABLE foreign_tbl (b int) diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 8b660a6c02c..b9739610131 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -1751,16 +1751,11 @@ postgresReScanForeignScan(ForeignScanState *node) return; /* - * If the node is async-capable, and an asynchronous fetch for it has - * begun, the asynchronous fetch might not have yet completed. Check if - * the node is async-capable, and an asynchronous fetch for it is still in - * progress; if so, complete the asynchronous fetch before restarting the - * scan. - */ - if (fsstate->async_capable && - fsstate->conn_state->pendingAreq && - fsstate->conn_state->pendingAreq->requestee == (PlanState *) node) - fetch_more_data(node); + * If the node is async-capable, any asynchronous fetch made for it should + * have been processed before we get here (see ExecAppendAsyncReset()). + */ + Assert(!fsstate->async_capable || !fsstate->conn_state->pendingAreq || + fsstate->conn_state->pendingAreq->requestee != (PlanState *) node); /* * If any internal parameters affecting this node have changed, we'd diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index e7019952173..54d09040d0d 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -4090,6 +4090,16 @@ INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; SELECT * FROM result_tbl ORDER BY a; DELETE FROM result_tbl; +-- Test ExecAppendAsyncReset code path that drains outstanding async requests +-- (case where subplans are re-scanned with parameter changes) +EXPLAIN (VERBOSE, COSTS OFF) +SELECT o.x FROM (VALUES (2505), (3505)) o(x), LATERAL (SELECT a FROM async_pt WHERE a = o.x OR a = 1505 LIMIT 1) s ORDER BY o.x; +SELECT o.x FROM (VALUES (2505), (3505)) o(x), LATERAL (SELECT a FROM async_pt WHERE a = o.x OR a = 1505 LIMIT 1) s ORDER BY o.x; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT o.x FROM (VALUES (2505), (3505)) o(x), LATERAL (SELECT a FROM async_pt WHERE a = o.x OR (a = 1505 AND o.x = 2505) LIMIT 1) s ORDER BY o.x; +SELECT o.x FROM (VALUES (2505), (3505)) o(x), LATERAL (SELECT a FROM async_pt WHERE a = o.x OR (a = 1505 AND o.x = 2505) LIMIT 1) s ORDER BY o.x; + -- Test COPY TO when foreign table is partition COPY async_pt TO stdout; --error @@ -4329,8 +4339,8 @@ DROP TABLE base_tbl2; DROP TABLE result_tbl; DROP TABLE join_tbl; --- Test that an asynchronous fetch is processed before restarting the scan in --- ReScanForeignScan +-- Test ExecAppendAsyncReset code path that drains outstanding async requests +-- (case where subplans are re-scanned without parameter changes) CREATE TABLE base_tbl (a int, b int); INSERT INTO base_tbl VALUES (1, 11), (2, 22), (3, 33); CREATE FOREIGN TABLE foreign_tbl (b int) diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index 987358e27fa..51654b31ad1 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -95,6 +95,7 @@ static void ExecAppendAsyncBegin(AppendState *node); static bool ExecAppendAsyncGetNext(AppendState *node, TupleTableSlot **result); static bool ExecAppendAsyncRequest(AppendState *node, TupleTableSlot **result); static void ExecAppendAsyncEventWait(AppendState *node); +static void ExecAppendAsyncReset(AppendState *node); static void classify_matching_subplans(AppendState *node); /* ---------------------------------------------------------------- @@ -426,6 +427,10 @@ ExecReScanAppend(AppendState *node) int nasyncplans = node->as_nasyncplans; int i; + /* If there are any async subplans, reset async requests made for them. */ + if (nasyncplans > 0) + ExecAppendAsyncReset(node); + /* * If any PARAM_EXEC Params used in pruning expressions have changed, then * we'd better unset the valid subplans so that they are reselected for @@ -461,25 +466,6 @@ ExecReScanAppend(AppendState *node) ExecReScan(subnode); } - /* Reset async state */ - if (nasyncplans > 0) - { - i = -1; - while ((i = bms_next_member(node->as_asyncplans, i)) >= 0) - { - AsyncRequest *areq = node->as_asyncrequests[i]; - - areq->callback_pending = false; - areq->request_complete = false; - areq->result = NULL; - } - - node->as_nasyncresults = 0; - node->as_nasyncremain = 0; - bms_free(node->as_needrequest); - node->as_needrequest = NULL; - } - /* Let choose_next_subplan_* function handle setting the first subplan */ node->as_whichplan = INVALID_SUBPLAN_INDEX; node->as_syncdone = false; @@ -1135,6 +1121,79 @@ ExecAppendAsyncEventWait(AppendState *node) } } +/* ---------------------------------------------------------------- + * ExecAppendAsyncReset + * + * Reset asynchronous requests made for async-capable subplans. + * ---------------------------------------------------------------- + */ +static void +ExecAppendAsyncReset(AppendState *node) +{ + int i; + + /* We should never be called when there are no async subplans. */ + Assert(node->as_nasyncplans > 0); + + /* + * Drain pending async requests if any. We force the as_syncdone flag to + * be true so that ExecAppendAsyncEventWait() waits until at least one + * event occurs. + */ + node->as_syncdone = true; + for (;;) + { + bool found = false; + + /* + * When called from ExecAppendAsyncEventWait(), postgres_fdw (and + * possibly other FDWs) will skip configuration of events for pending + * requests in some cases if as_needrequest isn't empty. To avoid + * that, discard results we already have. Note that we need to do + * this on every iteration, as the call to that function may produce + * new results. + */ + node->as_nasyncresults = 0; + bms_free(node->as_needrequest); + node->as_needrequest = NULL; + + i = -1; + while ((i = bms_next_member(node->as_asyncplans, i)) >= 0) + { + AsyncRequest *areq = node->as_asyncrequests[i]; + + if (areq->callback_pending) + { + found = true; + break; + } + } + if (!found) + break; + + CHECK_FOR_INTERRUPTS(); + + /* Wait or poll for async events. */ + ExecAppendAsyncEventWait(node); + } + + /* Reset async requests. */ + i = -1; + while ((i = bms_next_member(node->as_asyncplans, i)) >= 0) + { + AsyncRequest *areq = node->as_asyncrequests[i]; + + Assert(!areq->callback_pending); + areq->request_complete = false; + areq->result = NULL; + } + + /* Reset state variables. */ + Assert(node->as_nasyncresults == 0); + Assert(node->as_needrequest == NULL); + node->as_nasyncremain = 0; +} + /* ---------------------------------------------------------------- * ExecAsyncAppendResponse * From 52d87b42d9bef6a2ca66572fc39e5c1b0f61f5dd Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Fri, 7 Aug 2026 17:34:08 +0900 Subject: [PATCH 311/481] Fix indentation issue introduced by commit 291a4bd2ca Noticed before the commit reached koel. --- src/backend/commands/trigger.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index c1991505ace..e980f847ec3 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -5366,8 +5366,8 @@ AfterTriggerFireDeferred(void) * loop would leave them unfired, silently skipping e.g. a deferred FK * check and letting a violating row commit. (The former "all fired" * break is therefore gone: the loop now terminates only when - * afterTriggerMarkEvents() finds nothing left, including events queued - * by the flush.) + * afterTriggerMarkEvents() finds nothing left, including events + * queued by the flush.) */ FireAfterTriggerBatchCallbacks(afterTriggers.batch_callbacks); } From d1458441e03ba23e6c79e144de938592f19f8273 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Fri, 7 Aug 2026 17:43:47 +0900 Subject: [PATCH 312/481] Add previous commit to .git-blame-ignore-revs --- .git-blame-ignore-revs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 8d94034e79b..ef919ccb7bd 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -14,6 +14,9 @@ # # $ git log --pretty=format:"%H # %cd%n# %s" $PGINDENTGITHASH -1 --date=iso +52d87b42d9bef6a2ca66572fc39e5c1b0f61f5dd # 2026-08-07 17:38:13 +0900 +# Fix indentation issue introduced by commit 291a4bd2ca + b1aeda3ec939c2867e5c3eb4ee7e1bae4768503e # 2026-07-30 09:26:07 +0200 # pgindent fix for 4ee0ccfd From a05ece57b16088e564bf95f92646350bafa2cfa1 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Fri, 7 Aug 2026 17:39:24 +0900 Subject: [PATCH 313/481] Handle nullable referenced key in RI fast-path check The RI fast-path FK check asserted that the referenced key is never NULL, in ri_FastPathFlushArray() and in recheck_matched_pk_tuple(). That holds for a primary key, but a foreign key may reference any unique column, and a UNIQUE column is nullable. The assertion is reachable under READ COMMITTED. ri_LockPKTuple() locks the matched PK tuple with TUPLE_LOCK_FLAG_FIND_LAST_VERSION, so when a concurrent transaction commits a key-changing UPDATE while the check waits, the lock follows the update chain to the latest version. If that version now has NULL in the referenced column, the fast path reaches the assert; in a non-assert build it would compare against the NULL and treat it as a match. A NULL referenced key cannot equal any (non-null) FK value, so treat it as no match and let the ordinary foreign-key violation be raised. This matches the SPI path, whose requalifying "pkatt = $n" evaluates to NULL for such a row, so the row is not returned and the check reports a violation. Reported-by: Noah Misch Reviewed-by: Ayush Tiwari Discussion: https://postgr.es/m/20260705210533.ee.noahmisch@microsoft.com Backpatch-through: 19 --- src/backend/utils/adt/ri_triggers.c | 25 +++++++++--- .../expected/fk-fastpath-null-key.out | 17 ++++++++ src/test/isolation/isolation_schedule | 1 + .../isolation/specs/fk-fastpath-null-key.spec | 40 +++++++++++++++++++ 4 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 src/test/isolation/expected/fk-fastpath-null-key.out create mode 100644 src/test/isolation/specs/fk-fastpath-null-key.spec diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 19af06ee794..e5ee1541077 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -3199,9 +3199,19 @@ ri_FastPathFlushArray(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, if (!ri_LockPKTuple(pk_rel, pk_slot, snapshot, &concurrently_updated)) continue; - /* Extract the PK value from the matched and locked tuple */ + /* + * Extract the PK value from the matched and locked tuple. + * + * A foreign key may reference a nullable unique column, not just a + * NOT NULL primary key. If ri_LockPKTuple() chased an update chain + * to a version whose referenced key is now NULL, that version cannot + * equal any buffered (non-null) FK value, so skip it. This mirrors + * the SPI path, where the requalifying "pkatt = $n" yields NULL and + * the row is not returned. + */ found_val = slot_getattr(pk_slot, riinfo->pk_attnums[0], &found_null); - Assert(!found_null); + if (found_null) + continue; if (concurrently_updated) { @@ -3453,9 +3463,14 @@ recheck_matched_pk_tuple(Relation idxrel, ScanKeyData *skeys, int nkeys, { ScanKeyData *skey = &skeys[i]; - /* A PK column can never be set to NULL. */ - Assert(!isnull[i]); - if (!DatumGetBool(FunctionCall2Coll(&skey->sk_func, + /* + * A foreign key may reference a nullable unique column, so the + * version we chased the update chain to may have a NULL in a key + * column. A NULL never equals the value we searched for, so treat it + * as no match, as the SPI path's requalification would. + */ + if (isnull[i] || + !DatumGetBool(FunctionCall2Coll(&skey->sk_func, skey->sk_collation, values[i], skey->sk_argument))) diff --git a/src/test/isolation/expected/fk-fastpath-null-key.out b/src/test/isolation/expected/fk-fastpath-null-key.out new file mode 100644 index 00000000000..3efe1e781b2 --- /dev/null +++ b/src/test/isolation/expected/fk-fastpath-null-key.out @@ -0,0 +1,17 @@ +Parsed test spec with 2 sessions + +starting permutation: s1b s1upd_null s2ins s1c +step s1b: BEGIN; +step s1upd_null: UPDATE pktable SET u = NULL WHERE u = 5; +step s2ins: INSERT INTO fktable VALUES (5); +step s1c: COMMIT; +step s2ins: <... completed> +ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_a_fkey" + +starting permutation: s1b s1upd_null s2ins_arr s1c +step s1b: BEGIN; +step s1upd_null: UPDATE pktable SET u = NULL WHERE u = 5; +step s2ins_arr: INSERT INTO fktable VALUES (5), (6); +step s1c: COMMIT; +step s2ins_arr: <... completed> +ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_a_fkey" diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index df8ce44ede6..a27480a86a2 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -38,6 +38,7 @@ test: fk-snapshot test: fk-snapshot-2 test: fk-snapshot-3 test: fk-concurrent-pk-upd +test: fk-fastpath-null-key test: subxid-overflow test: eval-plan-qual test: eval-plan-qual-trigger diff --git a/src/test/isolation/specs/fk-fastpath-null-key.spec b/src/test/isolation/specs/fk-fastpath-null-key.spec new file mode 100644 index 00000000000..51e11b101dc --- /dev/null +++ b/src/test/isolation/specs/fk-fastpath-null-key.spec @@ -0,0 +1,40 @@ +# A foreign key may reference a nullable UNIQUE column, not only a NOT NULL +# primary key. Test that the RI fast-path check copes when a concurrent +# transaction sets the referenced key to NULL. +# +# s2's INSERT probes the PK index, finds the (u=5) row, and blocks on s1's +# in-progress key-changing UPDATE. After s1 commits, the tuple lock follows +# the update chain (table_tuple_lock with TUPLE_LOCK_FLAG_FIND_LAST_VERSION) +# to the now-NULL version. The check must treat that as "referenced row not +# found" and raise an ordinary foreign-key violation -- not assume that a +# referenced key can never be NULL. +# +# Two permutations exercise the two fast-path flush routines: a single-row +# INSERT goes through ri_FastPathFlushLoop()/recheck_matched_pk_tuple(), while +# a multi-row single-column INSERT goes through ri_FastPathFlushArray(). + +setup +{ + CREATE TABLE pktable (u int UNIQUE, c int); + CREATE TABLE fktable (a int REFERENCES pktable (u)); + INSERT INTO pktable VALUES (5, 1), (6, 2); +} + +teardown +{ + DROP TABLE fktable, pktable; +} + +session s1 +step s1b { BEGIN; } +step s1upd_null { UPDATE pktable SET u = NULL WHERE u = 5; } +step s1c { COMMIT; } + +session s2 +# single-row batch -> per-row loop flush path +step s2ins { INSERT INTO fktable VALUES (5); } +# multi-row single-column batch -> SK_SEARCHARRAY flush path +step s2ins_arr { INSERT INTO fktable VALUES (5), (6); } + +permutation s1b s1upd_null s2ins s1c +permutation s1b s1upd_null s2ins_arr s1c From 55d01a10f2b79c9ed76cbf668f35863f4be7112a Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Fri, 7 Aug 2026 09:59:55 -0400 Subject: [PATCH 314/481] Only clear VACUUM's read stream strategy once in failsafe mode 112c2683807b4d690 restored failsafe vacuum's abandonment of a buffer access strategy by clearing the ReadBuffersOperations' strategy references. But it did so in lazy_scan_heap()'s main loop, meaning it looped through all the ReadBuffersOperations once per block after failsafe was engaged. Track it with a local flag and clear the strategy only once. Reported-by: Melanie Plageman Discussion: https://postgr.es/m/CAAKRu_Zse14nSNeCgtnE1LUAH8Of7OmYR%2BCc3O_DAzxt3m6T-g%40mail.gmail.com Backpatch-through: 18 --- src/backend/access/heap/vacuumlazy.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index d346344934c..9bce43e563c 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -1285,6 +1285,7 @@ lazy_scan_heap(LVRelState *vacrel) BlockNumber orig_eager_scan_success_limit = vacrel->eager_scan_remaining_successes; /* for logging */ Buffer vmbuffer = InvalidBuffer; + bool strategy_cleared = false; const int initprog_index[] = { PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_TOTAL_HEAP_BLKS, @@ -1389,10 +1390,14 @@ lazy_scan_heap(LVRelState *vacrel) * If the wraparound failsafe has engaged -- either via the check * above or during index vacuuming invoked from this loop -- stop * using the buffer access strategy so that the rest of the vacuum may - * use all of shared buffers. + * use all of shared buffers. Failsafe mode stays engaged once + * triggered, so we only need to do this once. */ - if (unlikely(VacuumFailsafeActive)) + if (unlikely(VacuumFailsafeActive) && !strategy_cleared) + { read_stream_clear_strategy(stream); + strategy_cleared = true; + } buf = read_stream_next_buffer(stream, &per_buffer_data); From 7673dfe771e9de85b079ea2ec5cc6f22c83adab1 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Sat, 8 Aug 2026 00:09:05 +0900 Subject: [PATCH 315/481] Fix hot standby accepting connections too early after a crash reset Commit b53b88109f9 made the postmaster maintain reachedConsistency in addition to the startup process. Since the startup process is forked from the postmaster, it begins life holding whatever value the postmaster last set. On a crash reset the postmaster re-forks the startup process while its own copy still says true: it clears that copy only on receipt of PMSIGNAL_RECOVERY_STARTED, which the replacement process cannot send before it exists. The replacement therefore starts out believing the database is already consistent. CheckRecoveryConsistency() then skips the minRecoveryPoint comparison altogether, so hot standby is announced at redo start while replay may be arbitrarily far behind minRecoveryPoint. Read-only connections are accepted and answer from heap pages that were flushed ahead of the replay position, returning wrong results with no error raised. The same branch also runs XLogCheckInvalidPages() and CheckTablespaceDirectory(), which are skipped as well, and log_invalid_page() treats page references that are normal before consistency as a PANIC. Fix by clearing reachedConsistency in InitWalRecovery(), so that a startup process never depends on the value it inherited. The postmaster's own copy is deliberately left alone: forked backends read it to choose the "not yet accepting connections" errdetail, and it converges once the new startup process sends PMSIGNAL_RECOVERY_STARTED and, on reaching minRecoveryPoint, PMSIGNAL_RECOVERY_CONSISTENT. Successive crash resets alternate. A startup process that skips the branch never sends PMSIGNAL_RECOVERY_CONSISTENT, so the postmaster's copy stays false and the next reset forks a process holding the correct value; that pass reaches consistency properly, which sets the postmaster's copy back to true and re-arms the problem for the reset after it. Roughly every other crash reset is therefore affected, not just the first one. EXEC_BACKEND builds are unaffected, as reachedConsistency is not carried in BackendParameters. Backpatch to v18, where commit b53b88109f9 introduced this issue. Reported-by: Eric Ridge Author: Nikhil Sontakke Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CA+UBoq2n2Zg9rKgMfUtUohzGssisF9cDeyjKqPrnRNFprEyX1Q@mail.gmail.com Backpatch-through: 18 --- src/backend/access/transam/xlogrecovery.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c index c0ae4d3f63f..51253906d5e 100644 --- a/src/backend/access/transam/xlogrecovery.c +++ b/src/backend/access/transam/xlogrecovery.c @@ -469,6 +469,15 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr, dbstate_at_startup = ControlFile->state; + /* + * A startup process always starts with an inconsistent database. Set the + * flag accordingly, even if it was inherited from a postmaster that had + * already marked the database as consistent. This keeps the invariant + * local to the startup process without requiring every fork path to clear + * the flag. + */ + reachedConsistency = false; + /* * Initialize on the assumption we want to recover to the latest timeline * that's active according to pg_control. From b330f4978df65116c4339aeea0796ca2b9717214 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 10 Aug 2026 12:10:27 +0200 Subject: [PATCH 316/481] Translation updates Source-Git-URL: https://git.postgresql.org/git/pgtranslation/messages.git Source-Git-Hash: 1cfa61615af29902242c24687492c8e49d94c1d0 --- src/backend/po/de.po | 6095 ++++++++++++-------------- src/backend/po/ru.po | 2907 ++++++------ src/bin/initdb/po/ru.po | 22 +- src/bin/initdb/po/sv.po | 383 +- src/bin/pg_amcheck/po/ru.po | 22 +- src/bin/pg_archivecleanup/po/ru.po | 22 +- src/bin/pg_basebackup/po/ru.po | 493 ++- src/bin/pg_checksums/po/ru.po | 22 +- src/bin/pg_combinebackup/po/ru.po | 42 +- src/bin/pg_config/po/ru.po | 22 +- src/bin/pg_controldata/po/de.po | 111 +- src/bin/pg_controldata/po/ka.po | 112 +- src/bin/pg_controldata/po/ru.po | 22 +- src/bin/pg_ctl/po/ru.po | 26 +- src/bin/pg_dump/po/de.po | 247 +- src/bin/pg_dump/po/ka.po | 173 +- src/bin/pg_dump/po/ru.po | 103 +- src/bin/pg_resetwal/po/de.po | 223 +- src/bin/pg_resetwal/po/ru.po | 20 +- src/bin/pg_rewind/po/de.po | 28 +- src/bin/pg_rewind/po/ru.po | 356 +- src/bin/pg_rewind/po/sv.po | 570 +-- src/bin/pg_test_fsync/po/ru.po | 22 +- src/bin/pg_test_timing/po/de.po | 4 +- src/bin/pg_upgrade/po/de.po | 10 +- src/bin/pg_upgrade/po/ka.po | 14 +- src/bin/pg_upgrade/po/ru.po | 22 +- src/bin/pg_verifybackup/po/ru.po | 29 +- src/bin/pg_waldump/po/sv.po | 501 ++- src/bin/pg_walsummary/po/ru.po | 22 +- src/bin/psql/po/de.po | 950 ++-- src/bin/psql/po/ru.po | 754 ++-- src/bin/scripts/po/ru.po | 32 +- src/interfaces/ecpg/preproc/po/ru.po | 12 +- src/interfaces/libpq/po/de.po | 257 +- src/interfaces/libpq/po/ka.po | 264 +- src/interfaces/libpq/po/ru.po | 415 +- src/pl/plpython/po/ru.po | 56 +- 38 files changed, 7722 insertions(+), 7663 deletions(-) diff --git a/src/backend/po/de.po b/src/backend/po/de.po index 119a4d2b9a3..e92a7deceef 100644 --- a/src/backend/po/de.po +++ b/src/backend/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-07-09 08:41+0000\n" -"PO-Revision-Date: 2026-07-09 12:08+0200\n" +"POT-Creation-Date: 2026-08-06 09:11+0000\n" +"PO-Revision-Date: 2026-08-06 21:55+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -22,52 +22,52 @@ msgstr "" msgid "out of binary heap slots" msgstr "alle Slots für Binary-Heaps belegt" -#: ../common/compression.c:162 ../common/compression.c:171 -#: ../common/compression.c:180 +#: ../common/compression.c:176 ../common/compression.c:185 +#: ../common/compression.c:194 #, c-format msgid "this build does not support compression with %s" msgstr "diese Installation unterstützt keine Komprimierung mit %s" -#: ../common/compression.c:235 +#: ../common/compression.c:249 msgid "found empty string where a compression option was expected" msgstr "leere Zeichenkette gefunden wo eine Komprimierungsoption erwartet wurde" -#: ../common/compression.c:274 +#: ../common/compression.c:288 #, c-format msgid "unrecognized compression option: \"%s\"" msgstr "unbekannte Komprimierungsoption: »%s«" -#: ../common/compression.c:313 +#: ../common/compression.c:327 #, c-format msgid "compression option \"%s\" requires a value" msgstr "Komprimierungsoption »%s« benötigt einen Wert" -#: ../common/compression.c:322 +#: ../common/compression.c:336 #, c-format msgid "value for compression option \"%s\" must be an integer" msgstr "Wert für Komprimierungsoption »%s« muss eine ganze Zahl sein" -#: ../common/compression.c:361 +#: ../common/compression.c:375 #, c-format msgid "value for compression option \"%s\" must be a Boolean value" msgstr "Wert für Komprimierungsoption »%s« muss ein Boole’scher Wert sein" -#: ../common/compression.c:409 +#: ../common/compression.c:423 #, c-format msgid "compression algorithm \"%s\" does not accept a compression level" msgstr "Komprimierungsalgorithmus »%s« akzeptiert kein Komprimierungsniveau" -#: ../common/compression.c:416 +#: ../common/compression.c:430 #, c-format msgid "compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)" msgstr "Komprimierungsalgorithmus »%s« erwartet ein Komprimierungsniveau zwischen %d und %d (Standard bei %d)" -#: ../common/compression.c:427 +#: ../common/compression.c:441 #, c-format msgid "compression algorithm \"%s\" does not accept a worker count" msgstr "Komprimierungsalgorithmus »%s« akzeptiert keine Worker-Anzahl" -#: ../common/compression.c:438 +#: ../common/compression.c:452 #, c-format msgid "compression algorithm \"%s\" does not support long-distance mode" msgstr "Komprimierungsalgorithmus »%s« unterstützt keinen Long-Distance-Modus" @@ -94,9 +94,9 @@ msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" #: access/transam/xlogrecovery.c:1399 backup/basebackup.c:2145 #: backup/walsummary.c:283 commands/extension.c:4035 libpq/hba.c:765 #: replication/logical/origin.c:786 replication/logical/origin.c:814 -#: replication/logical/reorderbuffer.c:5392 -#: replication/logical/snapbuild.c:1955 replication/slot.c:2747 -#: replication/slot.c:2788 replication/walsender.c:678 +#: replication/logical/reorderbuffer.c:5418 +#: replication/logical/snapbuild.c:1955 replication/slot.c:2749 +#: replication/slot.c:2790 replication/walsender.c:678 #: storage/file/buffile.c:471 storage/file/copydir.c:202 #: utils/adt/genfile.c:197 utils/adt/misc.c:1001 utils/cache/relmapper.c:830 #, c-format @@ -106,8 +106,8 @@ msgstr "konnte Datei »%s« nicht lesen: %m" #: ../common/controldata_utils.c:117 ../common/controldata_utils.c:120 #: access/transam/xlog.c:3538 access/transam/xlog.c:4436 #: replication/logical/origin.c:791 replication/logical/origin.c:829 -#: replication/logical/snapbuild.c:1960 replication/slot.c:2751 -#: replication/slot.c:2792 replication/walsender.c:683 +#: replication/logical/snapbuild.c:1960 replication/slot.c:2753 +#: replication/slot.c:2794 replication/walsender.c:683 #: utils/cache/relmapper.c:834 #, c-format msgid "could not read file \"%s\": read %d of %zu" @@ -124,9 +124,9 @@ msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" #: access/transam/xlog.c:4401 access/transam/xlog.c:5690 #: commands/copyfrom.c:1953 commands/copyto.c:758 libpq/be-fsstubs.c:475 #: libpq/be-fsstubs.c:545 replication/logical/origin.c:724 -#: replication/logical/origin.c:862 replication/logical/reorderbuffer.c:5444 +#: replication/logical/origin.c:862 replication/logical/reorderbuffer.c:5470 #: replication/logical/snapbuild.c:1700 replication/logical/snapbuild.c:1826 -#: replication/slot.c:2633 replication/slot.c:2799 replication/walsender.c:693 +#: replication/slot.c:2635 replication/slot.c:2801 replication/walsender.c:693 #: storage/file/copydir.c:225 storage/file/copydir.c:230 #: storage/file/copydir.c:285 storage/file/copydir.c:290 storage/file/fd.c:829 #: storage/file/fd.c:3803 storage/file/fd.c:3909 utils/cache/relmapper.c:842 @@ -164,13 +164,13 @@ msgstr "" #: access/transam/xlog.c:4421 access/transam/xlogrecovery.c:4276 #: access/transam/xlogrecovery.c:4377 access/transam/xlogutils.c:849 #: backup/basebackup.c:553 backup/basebackup.c:1600 backup/walsummary.c:220 -#: libpq/hba.c:622 postmaster/syslogger.c:1531 replication/logical/origin.c:776 -#: replication/logical/reorderbuffer.c:4049 -#: replication/logical/reorderbuffer.c:4603 -#: replication/logical/reorderbuffer.c:5372 +#: libpq/hba.c:622 postmaster/syslogger.c:1531 postmaster/walsummarizer.c:1622 +#: replication/logical/origin.c:776 replication/logical/reorderbuffer.c:4075 +#: replication/logical/reorderbuffer.c:4629 +#: replication/logical/reorderbuffer.c:5398 #: replication/logical/snapbuild.c:1655 replication/logical/snapbuild.c:1767 -#: replication/slot.c:2719 replication/walsender.c:651 -#: replication/walsender.c:3329 storage/file/copydir.c:168 +#: replication/slot.c:2721 replication/walsender.c:651 +#: replication/walsender.c:3331 storage/file/copydir.c:168 #: storage/file/copydir.c:256 storage/file/fd.c:804 storage/file/fd.c:3560 #: storage/file/fd.c:3790 storage/file/fd.c:3880 storage/smgr/md.c:697 #: utils/cache/relmapper.c:819 utils/cache/relmapper.c:936 @@ -200,9 +200,9 @@ msgstr "konnte Datei »%s« nicht schreiben: %m" #: access/transam/twophase.c:1799 access/transam/xlog.c:3369 #: access/transam/xlog.c:3567 access/transam/xlog.c:4394 #: access/transam/xlog.c:9344 access/transam/xlog.c:9388 -#: backup/basebackup_server.c:207 commands/dbcommands.c:518 -#: replication/logical/snapbuild.c:1693 replication/slot.c:2617 -#: replication/slot.c:2729 storage/file/fd.c:821 storage/file/fd.c:3901 +#: backup/basebackup_server.c:207 commands/dbcommands.c:519 +#: replication/logical/snapbuild.c:1693 replication/slot.c:2619 +#: replication/slot.c:2731 storage/file/fd.c:821 storage/file/fd.c:3901 #: storage/smgr/md.c:1480 storage/smgr/md.c:1540 storage/sync/sync.c:447 #: utils/misc/guc.c:4428 #, c-format @@ -221,8 +221,8 @@ msgstr "konnte Datei »%s« nicht fsyncen: %m" #: libpq/auth.c:1435 libpq/auth.c:2006 libpq/be-secure-gssapi.c:539 #: libpq/be-secure-gssapi.c:719 postmaster/bgworker.c:381 #: postmaster/bgworker.c:1045 postmaster/postmaster.c:3615 -#: postmaster/walsummarizer.c:935 -#: replication/libpqwalreceiver/libpqwalreceiver.c:367 +#: postmaster/walsummarizer.c:1034 +#: replication/libpqwalreceiver/libpqwalreceiver.c:368 #: replication/logical/logical.c:201 replication/walsender.c:860 #: storage/buffer/localbuf.c:778 storage/file/fd.c:913 storage/file/fd.c:1431 #: storage/file/fd.c:1592 storage/file/fd.c:2576 storage/ipc/procarray.c:1456 @@ -368,8 +368,8 @@ msgstr "konnte Verzeichnis »%s« nicht lesen: %m" #: ../common/file_utils.c:520 access/transam/xlogarchive.c:390 #: postmaster/pgarch.c:839 postmaster/syslogger.c:1579 -#: replication/logical/snapbuild.c:1712 replication/slot.c:1106 -#: replication/slot.c:2500 replication/slot.c:2649 storage/file/fd.c:839 +#: replication/logical/snapbuild.c:1712 replication/slot.c:1108 +#: replication/slot.c:2502 replication/slot.c:2651 storage/file/fd.c:839 #: utils/time/snapmgr.c:1275 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" @@ -728,9 +728,9 @@ msgstr "konnte Statuscode des Subprozesses nicht ermitteln: Fehlercode %lu" #: access/transam/twophase.c:1738 access/transam/xlogarchive.c:120 #: access/transam/xlogarchive.c:400 backup/walsummary.c:254 #: postmaster/postmaster.c:1084 postmaster/syslogger.c:1508 -#: replication/logical/origin.c:632 replication/logical/reorderbuffer.c:4871 +#: replication/logical/origin.c:632 replication/logical/reorderbuffer.c:4897 #: replication/logical/snapbuild.c:1593 replication/logical/snapbuild.c:2049 -#: replication/slot.c:2703 storage/file/fd.c:879 storage/file/fd.c:3428 +#: replication/slot.c:2705 storage/file/fd.c:879 storage/file/fd.c:3428 #: storage/file/fd.c:3490 storage/file/reinit.c:261 storage/ipc/dsm.c:353 #: storage/smgr/md.c:412 storage/smgr/md.c:471 storage/sync/sync.c:244 #: utils/time/snapmgr.c:1611 @@ -851,36 +851,28 @@ msgid "checkpointer" msgstr "Checkpointer" #: ../include/postmaster/proctypelist.h:41 -#, fuzzy -#| msgid "autovacuum launcher" msgid "datachecksums launcher" -msgstr "Autovacuum-Launcher" +msgstr "Datenprüfsummen-Launcher" #: ../include/postmaster/proctypelist.h:42 -#, fuzzy -#| msgid "autovacuum worker" msgid "datachecksums worker" -msgstr "Autovacuum-Worker" +msgstr "Datenprüfsummen-Worker" #: ../include/postmaster/proctypelist.h:43 msgid "dead-end client backend" msgstr "dead-end Client-Backend" #: ../include/postmaster/proctypelist.h:44 -#, fuzzy -#| msgid "unrecognized status code" msgid "unrecognized" -msgstr "nicht erkannter Statuscode" +msgstr "unbekannt" #: ../include/postmaster/proctypelist.h:45 postmaster/postmaster.c:2536 msgid "io worker" msgstr "I/O-Arbeitsprozess" #: ../include/postmaster/proctypelist.h:46 -#, fuzzy -#| msgid "logger" msgid "syslogger" -msgstr "Logger" +msgstr "Syslogger" #: ../include/postmaster/proctypelist.h:47 msgid "slotsync worker" @@ -1024,7 +1016,7 @@ msgstr "Anzahl eingefügter, geänderter oder gelöschter Tupel vor einem Analyz #. translator: GUC parameter "autovacuum_analyze_score_weight" short description #: ../include/utils/guc_tables.inc.c:222 utils/guc_tables.inc.c:222 msgid "Scaling factor of analyze score for autovacuum prioritization." -msgstr "" +msgstr "Skalierungsfaktor des Analyze-Scores für die Autovacuum-Priorisierung." #. translator: GUC parameter "autovacuum_analyze_threshold" short description #: ../include/utils/guc_tables.inc.c:237 utils/guc_tables.inc.c:237 @@ -1039,14 +1031,12 @@ msgstr "Alter, nach dem eine Tabelle automatisch gevacuumt wird, um Transaktions #. translator: GUC parameter "autovacuum_freeze_score_weight" short description #: ../include/utils/guc_tables.inc.c:267 utils/guc_tables.inc.c:267 msgid "Scaling factor of freeze score for autovacuum prioritization." -msgstr "" +msgstr "Skalierungsfaktor des Freeze-Scores für die Autovacuum-Priorisierung." #. translator: GUC parameter "autovacuum_max_parallel_workers" short description #: ../include/utils/guc_tables.inc.c:282 utils/guc_tables.inc.c:282 -#, fuzzy -#| msgid "Sets the maximum number of parallel workers that can be active at one time." msgid "Maximum number of parallel workers that can be used by a single autovacuum worker." -msgstr "Setzt die maximale Anzahl paralleler Arbeitsprozesse, die gleichzeitig aktiv sein können." +msgstr "Maximale Anzahl paralleler Arbeitsprozesse, die von einem einzelnen Autovacuum-Worker verwendet werden können." #. translator: GUC parameter "autovacuum_max_workers" short description #: ../include/utils/guc_tables.inc.c:297 utils/guc_tables.inc.c:297 @@ -1061,7 +1051,7 @@ msgstr "Multixact-Alter, nach dem eine Tabelle automatisch gevacuumt wird, um Tr #. translator: GUC parameter "autovacuum_multixact_freeze_score_weight" short description #: ../include/utils/guc_tables.inc.c:327 utils/guc_tables.inc.c:327 msgid "Scaling factor of multixact freeze score for autovacuum prioritization." -msgstr "" +msgstr "Skalierungsfaktor des Multixact-Freeze-Scores für die Autovacuum-Priorisierung." #. translator: GUC parameter "autovacuum_naptime" short description #: ../include/utils/guc_tables.inc.c:342 utils/guc_tables.inc.c:342 @@ -1096,7 +1086,7 @@ msgstr "Anzahl eingefügter Tupel vor einem Vacuum, relativ zu reltuples." #. translator: GUC parameter "autovacuum_vacuum_insert_score_weight" short description #: ../include/utils/guc_tables.inc.c:408 utils/guc_tables.inc.c:408 msgid "Scaling factor of vacuum insert score for autovacuum prioritization." -msgstr "" +msgstr "Skalierungsfaktor des Vacuum-Insert-Scores für die Autovacuum-Priorisierung." #. translator: GUC parameter "autovacuum_vacuum_insert_threshold" short description #: ../include/utils/guc_tables.inc.c:423 utils/guc_tables.inc.c:423 @@ -1126,7 +1116,7 @@ msgstr "Anzahl geänderter oder gelöschter Tupel vor einem Vacuum, relativ zu r #. translator: GUC parameter "autovacuum_vacuum_score_weight" short description #: ../include/utils/guc_tables.inc.c:472 utils/guc_tables.inc.c:472 msgid "Scaling factor of vacuum score for autovacuum prioritization." -msgstr "" +msgstr "Skalierungsfaktor des Vacuum-Scores für die Autovacuum-Priorisierung." #. translator: GUC parameter "autovacuum_vacuum_threshold" short description #: ../include/utils/guc_tables.inc.c:487 utils/guc_tables.inc.c:487 @@ -1433,10 +1423,8 @@ msgstr "0 bedeutet, das normale Caching-Verhalten zu verwenden." #. translator: GUC parameter "debug_exec_backend" short description #: ../include/utils/guc_tables.inc.c:1192 utils/guc_tables.inc.c:1192 -#, fuzzy -#| msgid "Shows whether the running server has assertion checks enabled." msgid "Shows whether the running server is built with EXEC_BACKEND enabled." -msgstr "Zeigt, ob der laufende Server Assertion-Prüfungen aktiviert hat." +msgstr "Zeigt, ob der laufende Server mit EXEC_BACKEND gebaut wurde." #. translator: GUC parameter "debug_io_direct" short description #: ../include/utils/guc_tables.inc.c:1206 utils/guc_tables.inc.c:1206 @@ -1485,10 +1473,8 @@ msgstr "Schreibt den Ausführungsplan jeder Anfrage in den Log." #. translator: GUC parameter "debug_print_raw_parse" short description #: ../include/utils/guc_tables.inc.c:1297 utils/guc_tables.inc.c:1297 -#, fuzzy -#| msgid "Logs each query's parse tree." msgid "Logs each query's raw parse tree." -msgstr "Scheibt den Parsebaum jeder Anfrage in den Log." +msgstr "Schreibt den rohen Parsebaum jeder Anfrage in den Log." #. translator: GUC parameter "debug_print_rewritten" short description #: ../include/utils/guc_tables.inc.c:1310 utils/guc_tables.inc.c:1310 @@ -1608,7 +1594,7 @@ msgstr "0 schaltet simultane Anfragen aus." #. translator: GUC parameter "effective_wal_level" short description #: ../include/utils/guc_tables.inc.c:1555 utils/guc_tables.inc.c:1555 msgid "Shows effective WAL level." -msgstr "" +msgstr "Zeigt den effektiven WAL-Level." #. translator: GUC parameter "enable_async_append" short description #: ../include/utils/guc_tables.inc.c:1571 utils/guc_tables.inc.c:1571 @@ -1627,10 +1613,8 @@ msgstr "Ermöglicht Umordnen von DISTINCT-Schlüsseln." #. translator: GUC parameter "enable_eager_aggregate" short description #: ../include/utils/guc_tables.inc.c:1613 utils/guc_tables.inc.c:1613 -#, fuzzy -#| msgid "Enables partitionwise aggregation and grouping." msgid "Enables eager aggregation." -msgstr "Ermöglicht partitionsweise Aggregierung und Gruppierung." +msgstr "Ermöglicht Eager-Aggregierung." #. translator: GUC parameter "enable_gathermerge" short description #: ../include/utils/guc_tables.inc.c:1627 utils/guc_tables.inc.c:1627 @@ -1914,10 +1898,8 @@ msgstr "Setzt die »hba«-Konfigurationsdatei des Servers." #. translator: GUC parameter "hosts_file" short description #: ../include/utils/guc_tables.inc.c:2282 utils/guc_tables.inc.c:2282 -#, fuzzy -#| msgid "Sets the server's \"hba\" configuration file." msgid "Sets the server's \"hosts\" configuration file." -msgstr "Setzt die »hba«-Konfigurationsdatei des Servers." +msgstr "Setzt die »hosts«-Konfigurationsdatei des Servers." #. translator: GUC parameter "hot_standby" short description #: ../include/utils/guc_tables.inc.c:2296 utils/guc_tables.inc.c:2296 @@ -2048,10 +2030,8 @@ msgstr "Maximale Anzahl IOs, die ein Prozess gleichzeitig ausführen kann." #. translator: GUC parameter "io_max_workers" short description #: ../include/utils/guc_tables.inc.c:2592 utils/guc_tables.inc.c:2592 -#, fuzzy -#| msgid "Number of IO worker processes, for io_method=worker." msgid "Maximum number of I/O worker processes, for io_method=worker." -msgstr "Anzahl IO-Worker-Prozesse, für io_method=worker." +msgstr "Maximale Anzahl I/O-Worker-Prozesse, für io_method=worker." #. translator: GUC parameter "io_method" short description #: ../include/utils/guc_tables.inc.c:2607 utils/guc_tables.inc.c:2607 @@ -2060,24 +2040,18 @@ msgstr "Wählt die Methode zum Ausführen von asynchronem I/O." #. translator: GUC parameter "io_min_workers" short description #: ../include/utils/guc_tables.inc.c:2622 utils/guc_tables.inc.c:2622 -#, fuzzy -#| msgid "Number of IO worker processes, for io_method=worker." msgid "Minimum number of I/O worker processes, for io_method=worker." -msgstr "Anzahl IO-Worker-Prozesse, für io_method=worker." +msgstr "Minimale Anzahl I/O-Worker-Prozesse, für io_method=worker." #. translator: GUC parameter "io_worker_idle_timeout" short description #: ../include/utils/guc_tables.inc.c:2637 utils/guc_tables.inc.c:2637 -#, fuzzy -#| msgid "Number of IO worker processes, for io_method=worker." msgid "Maximum time before idle I/O worker processes time out, for io_method=worker." -msgstr "Anzahl IO-Worker-Prozesse, für io_method=worker." +msgstr "Maximale Zeit, bevor inaktive I/O-Worker-Prozesse das Zeitlimit überschreiten, für io_method=worker." #. translator: GUC parameter "io_worker_launch_interval" short description #: ../include/utils/guc_tables.inc.c:2653 utils/guc_tables.inc.c:2653 -#, fuzzy -#| msgid "Number of IO worker processes, for io_method=worker." msgid "Minimum time before launching a new I/O worker process, for io_method=worker." -msgstr "Anzahl IO-Worker-Prozesse, für io_method=worker." +msgstr "Minimale Zeit, bevor ein neuer I/O-Worker-Prozess gestartet wird, für io_method=worker." #. translator: GUC parameter "is_superuser" short description #: ../include/utils/guc_tables.inc.c:2669 utils/guc_tables.inc.c:2669 @@ -2233,31 +2207,23 @@ msgstr "Setzt die maximal erlaubte Dauer, um auf eine Sperre zu warten." #. translator: GUC parameter "log_autoanalyze_min_duration" short description #: ../include/utils/guc_tables.inc.c:3009 utils/guc_tables.inc.c:3009 -#, fuzzy -#| msgid "Sets the minimum execution time above which autovacuum actions will be logged." msgid "Sets the minimum execution time above which analyze actions by autovacuum will be logged." -msgstr "Setzt die minimale Ausführungszeit, über der Autovacuum-Aktionen geloggt werden." +msgstr "Setzt die minimale Ausführungszeit, über der Analyze-Aktionen von Autovacuum geloggt werden." #. translator: GUC parameter "log_autoanalyze_min_duration" long description #: ../include/utils/guc_tables.inc.c:3011 utils/guc_tables.inc.c:3011 -#, fuzzy -#| msgid "-1 disables logging autovacuum actions. 0 means log all autovacuum actions." msgid "-1 disables logging analyze actions by autovacuum. 0 means log all analyze actions by autovacuum." -msgstr "-1 schaltet das Loggen der Autovacuum-Aktionen aus. 0 bedeutet, alle Autovacuum-Aktionen zu loggen." +msgstr "-1 schaltet das Loggen der Analyze-Aktionen von Autovacuum aus. 0 bedeutet, alle Analyze-Aktionen von Autovacuum zu loggen." #. translator: GUC parameter "log_autovacuum_min_duration" short description #: ../include/utils/guc_tables.inc.c:3027 utils/guc_tables.inc.c:3027 -#, fuzzy -#| msgid "Sets the minimum execution time above which autovacuum actions will be logged." msgid "Sets the minimum execution time above which vacuum actions by autovacuum will be logged." -msgstr "Setzt die minimale Ausführungszeit, über der Autovacuum-Aktionen geloggt werden." +msgstr "Setzt die minimale Ausführungszeit, über der Vacuum-Aktionen von Autovacuum geloggt werden." #. translator: GUC parameter "log_autovacuum_min_duration" long description #: ../include/utils/guc_tables.inc.c:3029 utils/guc_tables.inc.c:3029 -#, fuzzy -#| msgid "-1 disables logging autovacuum actions. 0 means log all autovacuum actions." msgid "-1 disables logging vacuum actions by autovacuum. 0 means log all vacuum actions by autovacuum." -msgstr "-1 schaltet das Loggen der Autovacuum-Aktionen aus. 0 bedeutet, alle Autovacuum-Aktionen zu loggen." +msgstr "-1 schaltet das Loggen der Vacuum-Aktionen von Autovacuum aus. 0 bedeutet, alle Vacuum-Aktionen von Autovacuum zu loggen." #. translator: GUC parameter "log_btree_build_stats" short description #: ../include/utils/guc_tables.inc.c:3046 utils/guc_tables.inc.c:3046 @@ -2646,10 +2612,8 @@ msgstr "Setzt die maximale Anzahl von gleichzeitig vorbereiteten Transaktionen." #. translator: GUC parameter "max_repack_replication_slots" short description #: ../include/utils/guc_tables.inc.c:3926 utils/guc_tables.inc.c:3926 -#, fuzzy -#| msgid "Sets the maximum number of active replication origins." msgid "Sets the maximum number of replication slots for use by REPACK." -msgstr "Setzt die maximale Anzahl aktiver Replication-Origins." +msgstr "Setzt die maximale Anzahl Replikations-Slots zur Verwendung durch REPACK." #. translator: GUC parameter "max_replication_slots" short description #: ../include/utils/guc_tables.inc.c:3941 utils/guc_tables.inc.c:3941 @@ -2693,10 +2657,8 @@ msgstr "Setzt die maximale Verzögerung bevor Anfragen storniert werden, wenn ei #. translator: GUC parameter "max_sync_workers_per_subscription" short description #: ../include/utils/guc_tables.inc.c:4028 utils/guc_tables.inc.c:4028 -#, fuzzy -#| msgid "Maximum number of parallel apply workers per subscription." msgid "Maximum number of workers per subscription for synchronizing tables and sequences." -msgstr "Maximale Anzahl Parallel-Apply-Worker pro Subskription." +msgstr "Maximale Anzahl Worker pro Subskription zum Synchronisieren von Tabellen und Sequenzen." #. translator: GUC parameter "max_wal_senders" short description #: ../include/utils/guc_tables.inc.c:4043 utils/guc_tables.inc.c:4043 @@ -2726,7 +2688,7 @@ msgstr "Menge des beim Start reservierten dynamischen Shared Memory." #. translator: GUC parameter "min_eager_agg_group_size" short description #: ../include/utils/guc_tables.inc.c:4119 utils/guc_tables.inc.c:4119 msgid "Sets the minimum average group size required to consider applying eager aggregation." -msgstr "" +msgstr "Setzt die minimale durchschnittliche Gruppengröße, die erforderlich ist, um Eager-Aggregierung in Betracht zu ziehen." #. translator: GUC parameter "min_parallel_index_scan_size" short description #: ../include/utils/guc_tables.inc.c:4135 utils/guc_tables.inc.c:4135 @@ -2811,12 +2773,12 @@ msgstr "Wählt den Algorithmus zum Verschlüsseln von Passwörtern." #. translator: GUC parameter "password_expiration_warning_threshold" short description #: ../include/utils/guc_tables.inc.c:4346 utils/guc_tables.inc.c:4346 msgid "Threshold for password expiration warnings." -msgstr "" +msgstr "Schwellenwert für Warnungen über Passwortablauf." #. translator: GUC parameter "password_expiration_warning_threshold" long description #: ../include/utils/guc_tables.inc.c:4348 utils/guc_tables.inc.c:4348 msgid "0 means not to emit these warnings." -msgstr "" +msgstr "0 bedeutet, diese Warnungen nicht auszugeben." #. translator: GUC parameter "plan_cache_mode" short description #: ../include/utils/guc_tables.inc.c:4364 utils/guc_tables.inc.c:4364 @@ -3181,7 +3143,7 @@ msgstr "SSL-Renegotiation wird nicht mehr unterstützt; kann nur auf 0 gesetzt w #. translator: GUC parameter "ssl_sni" short description #: ../include/utils/guc_tables.inc.c:5308 utils/guc_tables.inc.c:5308 msgid "Sets whether to interpret SNI extensions in SSL connections." -msgstr "" +msgstr "Bestimmt, ob SNI-Erweiterungen in SSL-Verbindungen interpretiert werden." #. translator: GUC parameter "ssl_tls13_ciphers" short description #: ../include/utils/guc_tables.inc.c:5323 utils/guc_tables.inc.c:5323 @@ -3195,10 +3157,8 @@ msgstr "Eine leere Zeichenkette bedeutet, die voreingestellten Verschlüsselungs #. translator: GUC parameter "standard_conforming_strings" short description #: ../include/utils/guc_tables.inc.c:5339 utils/guc_tables.inc.c:5339 -#, fuzzy -#| msgid "SSL renegotiation is no longer supported; this can only be 0." msgid "Nonstandard strings are no longer supported; this can only be true." -msgstr "SSL-Renegotiation wird nicht mehr unterstützt; kann nur auf 0 gesetzt werden." +msgstr "Nicht standardkonforme Zeichenketten werden nicht mehr unterstützt; kann nur auf »true« gesetzt werden." #. translator: GUC parameter "statement_timeout" short description #: ../include/utils/guc_tables.inc.c:5354 utils/guc_tables.inc.c:5354 @@ -3333,12 +3293,12 @@ msgstr "Wählt eine Datei mit Zeitzonenabkürzungen." #. translator: GUC parameter "timing_clock_source" short description #: ../include/utils/guc_tables.inc.c:5728 utils/guc_tables.inc.c:5728 msgid "Controls the clock source used for collecting timing measurements." -msgstr "" +msgstr "Kontrolliert die Taktquelle, die für das Sammeln von Zeitmessungen verwendet wird." #. translator: GUC parameter "timing_clock_source" long description #: ../include/utils/guc_tables.inc.c:5730 utils/guc_tables.inc.c:5730 msgid "This enables the use of specialized clock sources, specifically the RDTSC clock source on x86-64 systems (if available), to support timing measurements with lower overhead during EXPLAIN and other instrumentation." -msgstr "" +msgstr "Dies ermöglicht die Verwendung spezialisierter Taktquellen, insbesondere der RDTSC-Taktquelle auf x86-64-Systemen (falls verfügbar), um Zeitmessungen mit geringerem Overhead bei EXPLAIN und anderer Instrumentierung zu unterstützen." #. translator: GUC parameter "trace_connection_negotiation" short description #: ../include/utils/guc_tables.inc.c:5747 utils/guc_tables.inc.c:5747 @@ -3677,17 +3637,13 @@ msgstr "Zeigt die Größe eines Write-Ahead-Log-Segments." #. translator: GUC parameter "wal_sender_shutdown_timeout" short description #: ../include/utils/guc_tables.inc.c:6625 utils/guc_tables.inc.c:6625 -#, fuzzy -#| msgid "Sets the maximum time to wait for WAL replication." msgid "Sets the maximum time the server waits during shutdown for all WAL data to be replicated to the receiver." -msgstr "Setzt die maximale Zeit, um auf WAL-Replikation zu warten." +msgstr "Setzt die maximale Zeit, die der Server beim Herunterfahren wartet, bis alle WAL-Daten zum Receiver repliziert sind." #. translator: GUC parameter "wal_sender_shutdown_timeout" long description #: ../include/utils/guc_tables.inc.c:6627 utils/guc_tables.inc.c:6627 -#, fuzzy -#| msgid "0 disables the timeout." -msgid "-1 disables the timeout" -msgstr "0 schaltet Zeitüberschreitungen aus." +msgid "-1 disables the timeout and waits for the receiver to catch up; 0 does not wait for the receiver to catch up." +msgstr "-1 schaltet das Zeitlimit aus und wartet, bis der Receiver aufgeholt hat; 0 wartet nicht, bis der Receiver aufgeholt hat." #. translator: GUC parameter "wal_sender_timeout" short description #: ../include/utils/guc_tables.inc.c:6643 utils/guc_tables.inc.c:6643 @@ -3842,9 +3798,9 @@ msgstr "Aufforderung für BRIN-Range-Summarization für Index »%s« Seite %u wu #: access/transam/xlogfuncs.c:272 access/transam/xlogfuncs.c:311 #: access/transam/xlogfuncs.c:332 access/transam/xlogfuncs.c:353 #: access/transam/xlogfuncs.c:419 access/transam/xlogfuncs.c:478 -#: commands/wait.c:192 statistics/attribute_stats.c:180 -#: statistics/attribute_stats.c:619 statistics/extended_stats_funcs.c:370 -#: statistics/extended_stats_funcs.c:1778 statistics/relation_stats.c:97 +#: commands/wait.c:192 statistics/attribute_stats.c:153 +#: statistics/attribute_stats.c:636 statistics/extended_stats_funcs.c:370 +#: statistics/extended_stats_funcs.c:1778 statistics/relation_stats.c:86 #, c-format msgid "recovery is in progress" msgstr "Wiederherstellung läuft" @@ -4095,16 +4051,14 @@ msgid "Specify storage parameters for its leaf partitions instead." msgstr "Geben Sie Storage-Parameter stattdessen für ihre Blattpartitionen an." #: access/common/toast_compression.c:31 -#, fuzzy, c-format -#| msgid "compression method lz4 not supported" +#, c-format msgid "compression method %s not supported" -msgstr "Komprimierungsmethode lz4 nicht unterstützt" +msgstr "Komprimierungsmethode %s nicht unterstützt" #: access/common/toast_compression.c:32 -#, fuzzy, c-format -#| msgid "This functionality requires the server to be built with lz4 support." +#, c-format msgid "This functionality requires the server to be built with %s support." -msgstr "Diese Funktionalität verlangt, dass der Server mit lz4-Unterstützung gebaut wird." +msgstr "Diese Funktionalität verlangt, dass der Server mit %s-Unterstützung gebaut wird." #: access/gin/ginbulk.c:44 #, c-format @@ -4235,10 +4189,10 @@ msgstr "konnte die für das Zeichenketten-Hashing zu verwendende Sortierfolge ni #: access/hash/hashfunc.c:281 access/hash/hashfunc.c:336 catalog/heap.c:703 #: catalog/heap.c:709 commands/createas.c:203 commands/createas.c:515 -#: commands/indexcmds.c:2110 commands/tablecmds.c:20644 commands/view.c:79 -#: regex/regc_pg_locale.c:48 utils/adt/formatting.c:1638 -#: utils/adt/formatting.c:1702 utils/adt/formatting.c:1766 -#: utils/adt/formatting.c:1830 utils/adt/like.c:151 utils/adt/like.c:182 +#: commands/indexcmds.c:2110 commands/tablecmds.c:20634 commands/view.c:79 +#: regex/regc_pg_locale.c:48 utils/adt/formatting.c:1639 +#: utils/adt/formatting.c:1703 utils/adt/formatting.c:1767 +#: utils/adt/formatting.c:1831 utils/adt/like.c:151 utils/adt/like.c:182 #: utils/adt/like_support.c:1107 utils/adt/varchar.c:741 #: utils/adt/varchar.c:1004 utils/adt/varchar.c:1060 utils/adt/varlena.c:1337 #, c-format @@ -4291,45 +4245,44 @@ msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlt Support-Funktion msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlen typübergreifende Operatoren" -#: access/heap/heapam.c:1221 access/index/indexam.c:274 -#, fuzzy, c-format -#| msgid "cannot use replication slot \"%s\" for logical decoding" +#: access/heap/heapam.c:1222 access/index/indexam.c:274 +#, c-format msgid "cannot query non-catalog table \"%s\" during logical decoding" -msgstr "physischer Replikations-Slot »%s« kann nicht für logisches Dekodieren verwendet werden" +msgstr "Nicht-Katalogtabelle »%s« kann während des logischen Dekodierens nicht abgefragt werden" -#: access/heap/heapam.c:2214 +#: access/heap/heapam.c:2240 #, c-format msgid "cannot insert tuples in a parallel worker" msgstr "in einem parallelen Arbeitsprozess können keine Tupel eingefügt werden" -#: access/heap/heapam.c:2752 +#: access/heap/heapam.c:2795 #, c-format msgid "cannot delete tuples during a parallel operation" msgstr "während einer parallelen Operation können keine Tupel gelöscht werden" -#: access/heap/heapam.c:2799 +#: access/heap/heapam.c:2842 #, c-format msgid "attempted to delete invisible tuple" msgstr "Versuch ein unsichtbares Tupel zu löschen" -#: access/heap/heapam.c:3264 access/index/genam.c:832 +#: access/heap/heapam.c:3334 access/index/genam.c:832 #, c-format msgid "cannot update tuples during a parallel operation" msgstr "während einer parallelen Operation können keine Tupel aktualisiert werden" -#: access/heap/heapam.c:3441 +#: access/heap/heapam.c:3511 #, c-format msgid "attempted to update invisible tuple" msgstr "Versuch ein unsichtbares Tupel zu aktualisieren" -#: access/heap/heapam.c:4957 access/heap/heapam.c:4995 -#: access/heap/heapam.c:5262 access/heap/heapam_handler.c:379 +#: access/heap/heapam.c:5147 access/heap/heapam.c:5185 +#: access/heap/heapam.c:5474 access/heap/heapam_handler.c:379 #, c-format msgid "could not obtain lock on row in relation \"%s\"" msgstr "konnte Sperre für Zeile in Relation »%s« nicht setzen" -#: access/heap/heapam.c:6392 commands/trigger.c:3402 -#: executor/nodeModifyTable.c:2875 executor/nodeModifyTable.c:2965 +#: access/heap/heapam.c:6631 commands/trigger.c:3402 +#: executor/nodeModifyTable.c:2885 executor/nodeModifyTable.c:2975 #, c-format msgid "tuple to be updated was already modified by an operation triggered by the current command" msgstr "das zu aktualisierende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" @@ -4344,32 +4297,30 @@ msgstr "das zu sperrende Tupel wurde schon durch ein gleichzeitiges Update in ei msgid "row is too big: size %zu, maximum size %zu" msgstr "Zeile ist zu groß: Größe ist %zu, Maximalgröße ist %zu" -#: access/heap/pruneheap.c:866 +#: access/heap/pruneheap.c:886 #, c-format msgid "dead line pointer found on page marked all-visible" -msgstr "" +msgstr "toter Line-Pointer auf als all-visible markierter Seite gefunden" -#: access/heap/pruneheap.c:867 access/heap/pruneheap.c:891 -#, fuzzy, c-format -#| msgid "relation \"%s\" cannot have rules" +#: access/heap/pruneheap.c:887 access/heap/pruneheap.c:911 +#, c-format msgid "relation \"%s\", page %u, tuple %u" -msgstr "Relation »%s« kann keine Regeln haben" +msgstr "Relation »%s«, Seite %u, Tupel %u" -#: access/heap/pruneheap.c:890 +#: access/heap/pruneheap.c:910 #, c-format msgid "tuple not visible to all transactions found on page marked all-visible" -msgstr "" +msgstr "für nicht alle Transaktionen sichtbares Tupel auf als all-visible markierter Seite gefunden" -#: access/heap/pruneheap.c:911 +#: access/heap/pruneheap.c:931 #, c-format msgid "page is not marked all-visible but visibility map bit is set" -msgstr "" +msgstr "Seite ist nicht als all-visible markiert, aber Visibility-Map-Bit ist gesetzt" -#: access/heap/pruneheap.c:912 -#, fuzzy, c-format -#| msgid "relation \"%s\" already exists" +#: access/heap/pruneheap.c:932 +#, c-format msgid "relation \"%s\", page %u" -msgstr "Relation »%s« existiert bereits" +msgstr "Relation »%s«, Seite %u" #: access/heap/rewriteheap.c:888 #, c-format @@ -4381,10 +4332,10 @@ msgstr "konnte nicht in Datei »%s« schreiben, %d von %d geschrieben: %m" #: access/transam/xlog.c:3294 access/transam/xlog.c:3502 #: access/transam/xlog.c:4373 access/transam/xlog.c:9940 #: access/transam/xlogfuncs.c:712 backup/basebackup_server.c:149 -#: backup/basebackup_server.c:242 commands/dbcommands.c:498 +#: backup/basebackup_server.c:242 commands/dbcommands.c:499 #: postmaster/launch_backend.c:332 postmaster/postmaster.c:4142 -#: postmaster/walsummarizer.c:1218 replication/logical/origin.c:644 -#: replication/slot.c:2561 storage/file/copydir.c:174 +#: postmaster/walsummarizer.c:1317 replication/logical/origin.c:644 +#: replication/slot.c:2563 storage/file/copydir.c:174 #: storage/file/copydir.c:262 storage/smgr/md.c:263 utils/time/snapmgr.c:1254 #, c-format msgid "could not create file \"%s\": %m" @@ -4398,11 +4349,11 @@ msgstr "konnte Datei »%s« nicht auf %u kürzen: %m" #: access/heap/rewriteheap.c:1125 access/transam/timeline.c:385 #: access/transam/timeline.c:425 access/transam/timeline.c:499 #: access/transam/xlog.c:3347 access/transam/xlog.c:3558 -#: access/transam/xlog.c:4385 commands/dbcommands.c:510 +#: access/transam/xlog.c:4385 commands/dbcommands.c:511 #: postmaster/launch_backend.c:343 postmaster/launch_backend.c:355 #: replication/logical/origin.c:656 replication/logical/origin.c:698 #: replication/logical/origin.c:717 replication/logical/snapbuild.c:1669 -#: replication/slot.c:2597 storage/file/buffile.c:546 +#: replication/slot.c:2599 storage/file/buffile.c:546 #: storage/file/copydir.c:214 utils/init/miscinit.c:1611 #: utils/init/miscinit.c:1622 utils/init/miscinit.c:1630 utils/misc/guc.c:4389 #: utils/misc/guc.c:4420 utils/misc/guc.c:5579 utils/misc/guc.c:5597 @@ -4515,14 +4466,12 @@ msgstr "%u Seiten der Tabelle (%.2f%% der Gesamtzahl) haben % tote Item- #: access/heap/vacuumlazy.c:1142 #, c-format msgid "parallel workers: index vacuum: %d planned, %d launched in total\n" -msgstr "" +msgstr "parallele Worker: Index-Vacuum: %d geplant, %d insgesamt gestartet\n" #: access/heap/vacuumlazy.c:1148 -#, fuzzy, c-format -#| msgid "launched %d parallel vacuum worker for index cleanup (planned: %d)" -#| msgid_plural "launched %d parallel vacuum workers for index cleanup (planned: %d)" +#, c-format msgid "parallel workers: index cleanup: %d planned, %d launched\n" -msgstr "%d parallelen Vacuum-Worker für Index-Cleanup gestartet (geplant: %d)" +msgstr "parallele Worker: Index-Cleanup: %d geplant, %d gestartet\n" #: access/heap/vacuumlazy.c:1160 #, c-format @@ -4550,17 +4499,16 @@ msgid "buffer usage: % hits, % reads, % dirtied\n" msgstr "Puffer-Verwendung: % Treffer, % Verfehlen, % geändert\n" #: access/heap/vacuumlazy.c:1201 commands/analyze.c:846 -#, fuzzy, c-format -#| msgid "WAL usage: % records, % full page images, % bytes, % buffers full\n" +#, c-format msgid "WAL usage: % records, % full page images, % bytes, % full page image bytes, % buffers full\n" -msgstr "WAL-Benutzung: % Einträge, % Full Page Images, % Bytes, % Puffer voll\n" +msgstr "WAL-Benutzung: % Einträge, % Full Page Images, % Bytes, % Full-Page-Image-Bytes, % Puffer voll\n" #: access/heap/vacuumlazy.c:1217 #, c-format msgid "memory usage: dead item storage %.2f MB accumulated across %d reset (limit %.2f MB each)\n" msgid_plural "memory usage: dead item storage %.2f MB accumulated across %d resets (limit %.2f MB each)\n" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Speicherverbrauch: Dead-Item-Speicher %.2f MB angesammelt über %d Zurücksetzung (Limit jeweils %.2f MB)\n" +msgstr[1] "Speicherverbrauch: Dead-Item-Speicher %.2f MB angesammelt über %d Zurücksetzungen (Limit jeweils %.2f MB)\n" #: access/heap/vacuumlazy.c:1223 commands/analyze.c:852 #, c-format @@ -4646,12 +4594,12 @@ msgstr "beim Vacuum von Block %u von Relation »%s.%s«" msgid "while vacuuming relation \"%s.%s\"" msgstr "beim Vacuum von Relation »%s.%s«" -#: access/heap/vacuumlazy.c:3831 commands/vacuumparallel.c:1351 +#: access/heap/vacuumlazy.c:3831 commands/vacuumparallel.c:1359 #, c-format msgid "while vacuuming index \"%s\" of relation \"%s.%s\"" msgstr "beim Vacuum von Index »%s« von Relation »%s.%s«" -#: access/heap/vacuumlazy.c:3836 commands/vacuumparallel.c:1357 +#: access/heap/vacuumlazy.c:3836 commands/vacuumparallel.c:1365 #, c-format msgid "while cleaning up index \"%s\" of relation \"%s.%s\"" msgstr "beim Säubern von Index »%s« von Relation »%s.%s«" @@ -4683,7 +4631,7 @@ msgstr "auf Index »%s« kann nicht zugegriffen werden, während er reindiziert #: access/index/indexam.c:204 catalog/objectaddress.c:1455 #: commands/indexcmds.c:3039 commands/tablecmds.c:288 commands/tablecmds.c:312 -#: commands/tablecmds.c:20323 commands/tablecmds.c:22267 +#: commands/tablecmds.c:20313 commands/tablecmds.c:22257 #, c-format msgid "\"%s\" is not an index" msgstr "»%s« ist kein Index" @@ -4755,7 +4703,7 @@ msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlt Support-Funktion #: access/sequence/sequence.c:75 catalog/aclchk.c:1842 #: catalog/objectaddress.c:1469 commands/tablecmds.c:270 -#: commands/tablecmds.c:20291 utils/adt/acl.c:2153 utils/adt/acl.c:2183 +#: commands/tablecmds.c:20281 utils/adt/acl.c:2153 utils/adt/acl.c:2183 #: utils/adt/acl.c:2216 utils/adt/acl.c:2252 utils/adt/acl.c:2283 #: utils/adt/acl.c:2314 #, c-format @@ -4818,10 +4766,9 @@ msgid "sample percentage must be between 0 and 100" msgstr "Stichprobenprozentsatz muss zwischen 0 und 100 sein" #: access/transam/clog.c:1060 -#, fuzzy, c-format -#| msgid "could not access status of transaction %u" +#, c-format msgid "Could not access commit status of transaction %u." -msgstr "konnte auf den Status von Transaktion %u nicht zugreifen" +msgstr "Konnte nicht auf den Commit-Status von Transaktion %u zugreifen." #: access/transam/commit_ts.c:296 #, c-format @@ -4844,10 +4791,9 @@ msgid "Make sure the configuration parameter \"%s\" is set." msgstr "Stellen Sie sicher, dass der Konfigurationsparameter »%s« gesetzt ist." #: access/transam/commit_ts.c:972 -#, fuzzy, c-format -#| msgid "could not access status of transaction %u" +#, c-format msgid "Could not access commit timestamp of transaction %u." -msgstr "konnte auf den Status von Transaktion %u nicht zugreifen" +msgstr "Konnte nicht auf den Commit-Timestamp von Transaktion %u zugreifen." #: access/transam/multixact.c:1040 #, c-format @@ -4856,16 +4802,13 @@ msgstr "Datenbank nimmt keine Befehle an, die neue MultiXactIds zuweisen, um Dat #: access/transam/multixact.c:1042 access/transam/multixact.c:1049 #: access/transam/multixact.c:1075 access/transam/multixact.c:1086 -#, fuzzy, c-format -#| msgid "" -#| "Execute a database-wide VACUUM in that database.\n" -#| "You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +#, c-format msgid "" "Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions." msgstr "" "Führen Sie ein datenbankweites VACUUM in dieser Datenbank aus.\n" -"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen." #: access/transam/multixact.c:1047 #, c-format @@ -4882,8 +4825,8 @@ msgstr[1] "Datenbank »%s« muss gevacuumt werden, bevor %u weitere MultiXactIds #: access/transam/multixact.c:1073 access/transam/multixact.c:1084 #: access/transam/multixact.c:2211 access/transam/multixact.c:2222 #, c-format -msgid "Approximately %.2f%% of MultiXactIds are available for use." -msgstr "" +msgid "Approximately %.2f%% of MultiXactId space remains before wraparound." +msgstr "Ungefähr %.2f%% des MultiXactId-Bereichs verbleiben vor dem Wraparound." #: access/transam/multixact.c:1079 access/transam/multixact.c:2217 #, c-format @@ -4893,10 +4836,9 @@ msgstr[0] "Datenbank mit OID %u muss gevacuumt werden, bevor %u weitere MultiXac msgstr[1] "Datenbank mit OID %u muss gevacuumt werden, bevor %u weitere MultiXactIds aufgebraucht sind" #: access/transam/multixact.c:1116 -#, fuzzy, c-format -#| msgid "MultiXact member wraparound protections are now enabled" +#, c-format msgid "MultiXact members would wrap around" -msgstr "MultiXact-Member-Wraparound-Schutz ist jetzt aktiviert" +msgstr "MultiXact-Member würden einen Wraparound verursachen" #: access/transam/multixact.c:1245 #, c-format @@ -4909,10 +4851,9 @@ msgid "MultiXactId %u has not been created yet -- apparent wraparound" msgstr "MultiXactId %u wurde noch nicht erzeugt -- anscheinender Überlauf" #: access/transam/multixact.c:1276 -#, fuzzy, c-format -#| msgid "MultiXact %u has invalid next offset" +#, c-format msgid "MultiXact %u has invalid offset" -msgstr "MultiXact %u hat ungültiges nächstes Offset" +msgstr "MultiXact %u hat ungültiges Offset" #: access/transam/multixact.c:1321 #, c-format @@ -4922,36 +4863,31 @@ msgstr "MultiXact %u hat ungültiges nächstes Offset" #: access/transam/multixact.c:1325 #, c-format msgid "MultiXact %u with offset (%) has zero members" -msgstr "" +msgstr "MultiXact %u mit Offset (%) hat null Member" #: access/transam/multixact.c:1330 #, c-format msgid "MultiXact %u has offset (%) greater than its next offset (%)" -msgstr "" +msgstr "MultiXact %u hat Offset (%) größer als sein nächster Offset (%)" #: access/transam/multixact.c:1335 -#, fuzzy, c-format -#| msgid "indicator struct \"%s\" has too many members" +#, c-format msgid "MultiXact %u has too many members (%)" -msgstr "Indikator-Struct »%s« hat zu viele Mitglieder" +msgstr "MultiXact %u hat zu viele Member (%)" #: access/transam/multixact.c:2213 access/transam/multixact.c:2224 -#, fuzzy, c-format -#| msgid "" -#| "To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" -#| "You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +#, c-format msgid "" "To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions." msgstr "" "Um Scheitern von MultiXactId-Zuweisungen zu vermeiden, führen Sie ein komplettes VACUUM über diese Datenbank aus.\n" -"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen." #: access/transam/multixact.c:2478 -#, fuzzy, c-format -#| msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +#, c-format msgid "MultiXact member truncation is disabled because oldest checkpointed MultiXact %u does not exist on disk" -msgstr "MultiXact-Member-Wraparound-Schutz ist deaktiviert, weil die älteste gecheckpointete MultiXact %u nicht auf der Festplatte existiert" +msgstr "MultiXact-Member-Truncation ist deaktiviert, weil die älteste gecheckpointete MultiXact %u nicht auf der Festplatte existiert" #: access/transam/multixact.c:2726 #, c-format @@ -4964,20 +4900,19 @@ msgid "cannot truncate up to MultiXact %u because it has invalid offset, skippin msgstr "kann nicht bis MultiXact %u trunkieren, weil es ein ungültiges Offset hat, Trunkierung wird ausgelassen" #: access/transam/multixact.c:2842 -#, fuzzy, c-format -#| msgid "could not access status of transaction %u" +#, c-format msgid "Could not access offset of multixact %u." -msgstr "konnte auf den Status von Transaktion %u nicht zugreifen" +msgstr "Konnte nicht auf das Offset von MultiXact %u zugreifen." #: access/transam/multixact.c:2851 #, c-format msgid "Could not access member of multixact %u at offset %." -msgstr "" +msgstr "Konnte auf Member von MultiXact %u bei Offset % nicht zugreifen." #: access/transam/multixact.c:2854 #, c-format msgid "Could not access multixact member at offset %." -msgstr "" +msgstr "Konnte auf MultiXact-Member bei Offset % nicht zugreifen." #: access/transam/parallel.c:761 access/transam/parallel.c:880 #, c-format @@ -5081,28 +5016,24 @@ msgid "file \"%s\" doesn't exist, reading as zeroes" msgstr "Datei »%s« existiert nicht, wird als Nullen eingelesen" #: access/transam/slru.c:1117 -#, fuzzy, c-format -#| msgid "Could not seek in file \"%s\" to offset %d: %m." +#, c-format msgid "could not seek in file \"%s\" to offset %d: %m" -msgstr "Konnte Positionszeiger in Datei »%s« nicht auf %d setzen: %m." +msgstr "konnte Positionszeiger in Datei »%s« nicht auf %d setzen: %m" #: access/transam/slru.c:1125 -#, fuzzy, c-format -#| msgid "Could not read from file \"%s\" at offset %d: %m." +#, c-format msgid "could not read from file \"%s\" at offset %d: %m" -msgstr "Konnte nicht aus Datei »%s« bei Position %d lesen: %m." +msgstr "konnte nicht aus Datei »%s« bei Position %d lesen: %m" #: access/transam/slru.c:1130 -#, fuzzy, c-format -#| msgid "Could not read from file \"%s\" at offset %d: read too few bytes." +#, c-format msgid "could not read from file \"%s\" at offset %d: read too few bytes" -msgstr "Konnte nicht aus Datei »%s« bei Position %d lesen: zu wenige Bytes gelesen." +msgstr "konnte nicht aus Datei »%s« bei Position %d lesen: zu wenige Bytes gelesen" #: access/transam/slru.c:1138 -#, fuzzy, c-format -#| msgid "Could not write to file \"%s\" at offset %d: %m." +#, c-format msgid "Could not write to file \"%s\" at offset %d: %m" -msgstr "Konnte nicht in Datei »%s« bei Position %d schreiben: %m." +msgstr "Konnte nicht in Datei »%s« bei Position %d schreiben: %m" #: access/transam/slru.c:1143 #, c-format @@ -5115,10 +5046,9 @@ msgid "could not truncate directory \"%s\": apparent wraparound" msgstr "konnte Verzeichnis »%s« nicht leeren: anscheinender Überlauf" #: access/transam/subtrans.c:447 -#, fuzzy, c-format -#| msgid "could not access status of transaction %u" +#, c-format msgid "Could not access subtransaction status of transaction %u." -msgstr "konnte auf den Status von Transaktion %u nicht zugreifen" +msgstr "Konnte nicht auf den Subtransaktionsstatus von Transaktion %u zugreifen." #: access/transam/timeline.c:164 access/transam/timeline.c:169 #, c-format @@ -5155,7 +5085,7 @@ msgstr "ungültige Daten in History-Datei »%s«" msgid "Timeline IDs must be less than child timeline's ID." msgstr "Zeitleisten-IDs müssen kleiner als die Zeitleisten-ID des Kindes sein." -#: access/transam/timeline.c:590 +#: access/transam/timeline.c:590 postmaster/walsummarizer.c:926 #, c-format msgid "requested timeline %u is not in this server's history" msgstr "angeforderte Zeitleiste %u ist nicht in der History dieses Servers" @@ -5258,29 +5188,26 @@ msgid "calculated CRC checksum does not match value stored in file \"%s\"" msgstr "berechnete CRC-Prüfsumme stimmt nicht mit dem Wert in Datei »%s« überein" #: access/transam/twophase.c:1433 access/transam/xlogrecovery.c:510 -#: postmaster/walsummarizer.c:936 replication/logical/logical.c:202 +#: postmaster/walsummarizer.c:1035 replication/logical/logical.c:202 #: replication/walsender.c:861 #, c-format msgid "Failed while allocating a WAL reading processor." msgstr "Fehlgeschlagen beim Anlegen eines WAL-Leseprozessors." #: access/transam/twophase.c:1443 -#, fuzzy, c-format -#| msgid "could not read two-phase state from WAL at %X/%X: %s" +#, c-format msgid "could not read two-phase state from WAL at %X/%08X: %s" -msgstr "konnte Zweiphasen-Status nicht aus dem WAL bei %X/%X lesen: %s" +msgstr "konnte Zweiphasen-Status nicht aus dem WAL bei %X/%08X lesen: %s" #: access/transam/twophase.c:1448 -#, fuzzy, c-format -#| msgid "could not read two-phase state from WAL at %X/%X" +#, c-format msgid "could not read two-phase state from WAL at %X/%08X" -msgstr "konnte Zweiphasen-Status nicht aus dem WAL bei %X/%X lesen" +msgstr "konnte Zweiphasen-Status nicht aus dem WAL bei %X/%08X lesen" #: access/transam/twophase.c:1456 -#, fuzzy, c-format -#| msgid "expected two-phase state data is not present in WAL at %X/%X" +#, c-format msgid "expected two-phase state data is not present in WAL at %X/%08X" -msgstr "erwartete Zweiphasen-Status-Daten sind nicht im WAL bei %X/%X vorhanden" +msgstr "erwartete Zweiphasen-Status-Daten sind nicht im WAL bei %X/%08X vorhanden" #: access/transam/twophase.c:1766 #, c-format @@ -5295,46 +5222,39 @@ msgstr[0] "%u Zweiphasen-Statusdatei wurde für eine lange laufende vorbereitete msgstr[1] "%u Zweiphasen-Statusdateien wurden für lange laufende vorbereitete Transaktionen geschrieben" #: access/transam/twophase.c:2120 -#, fuzzy, c-format -#| msgid "recovering prepared transaction %u from shared memory" +#, c-format msgid "recovering prepared transaction %u of epoch %u from shared memory" -msgstr "Wiederherstellung der vorbereiteten Transaktion %u aus dem Shared Memory" +msgstr "Wiederherstellung der vorbereiteten Transaktion %u der Epoche %u aus dem Shared Memory" #: access/transam/twophase.c:2216 -#, fuzzy, c-format -#| msgid "removing stale two-phase state file for transaction %u" +#, c-format msgid "removing stale two-phase state file for transaction %u of epoch %u" -msgstr "entferne abgelaufene Zweiphasen-Statusdatei für Transaktion %u" +msgstr "entferne abgelaufene Zweiphasen-Statusdatei für Transaktion %u der Epoche %u" #: access/transam/twophase.c:2224 -#, fuzzy, c-format -#| msgid "removing stale two-phase state from memory for transaction %u" +#, c-format msgid "removing stale two-phase state from memory for transaction %u of epoch %u" -msgstr "entferne abgelaufenen Zweiphasen-Status aus dem Speicher für Transaktion %u" +msgstr "entferne abgelaufenen Zweiphasen-Status aus dem Speicher für Transaktion %u der Epoche %u" #: access/transam/twophase.c:2238 -#, fuzzy, c-format -#| msgid "removing future two-phase state file for transaction %u" +#, c-format msgid "removing future two-phase state file for transaction %u of epoch %u" -msgstr "entferne zukünftige Zweiphasen-Statusdatei für Transaktion %u" +msgstr "entferne zukünftige Zweiphasen-Statusdatei für Transaktion %u der Epoche %u" #: access/transam/twophase.c:2246 -#, fuzzy, c-format -#| msgid "removing future two-phase state from memory for transaction %u" +#, c-format msgid "removing future two-phase state from memory for transaction %u of epoch %u" -msgstr "entferne zukünftigen Zweiphasen-Status aus dem Speicher für Transaktion %u" +msgstr "entferne zukünftigen Zweiphasen-Status aus dem Speicher für Transaktion %u der Epoche %u" #: access/transam/twophase.c:2272 -#, fuzzy, c-format -#| msgid "corrupted two-phase state file for transaction %u" +#, c-format msgid "corrupted two-phase state file for transaction %u of epoch %u" -msgstr "verfälschte Zweiphasen-Statusdatei für Transaktion %u" +msgstr "verfälschte Zweiphasen-Statusdatei für Transaktion %u der Epoche %u" #: access/transam/twophase.c:2278 -#, fuzzy, c-format -#| msgid "corrupted two-phase state in memory for transaction %u" +#, c-format msgid "corrupted two-phase state in memory for transaction %u of epoch %u" -msgstr "verfälschter Zweiphasen-Status im Speicher für Transaktion %u" +msgstr "verfälschter Zweiphasen-Status im Speicher für Transaktion %u der Epoche %u" #: access/transam/twophase.c:2566 #, c-format @@ -5342,10 +5262,9 @@ msgid "could not recover two-phase state file for transaction %u" msgstr "konnte Zweiphasen-Statusdatei für Transaktion %u nicht wiederherstellen" #: access/transam/twophase.c:2568 -#, fuzzy, c-format -#| msgid "Two-phase state file has been found in WAL record %X/%X, but this transaction has already been restored from disk." +#, c-format msgid "Two-phase state file has been found in WAL record %X/%08X, but this transaction has already been restored from disk." -msgstr "Zweiphasen-Statusdatei wurde in WAL-Eintrag %X/%X gefunden, aber diese Transaktion wurde schon von der Festplatte wiederhergestellt." +msgstr "Zweiphasen-Statusdatei wurde in WAL-Eintrag %X/%08X gefunden, aber diese Transaktion wurde schon von der Festplatte wiederhergestellt." #: access/transam/twophase.c:2576 storage/file/fd.c:515 utils/fmgr/dfmgr.c:214 #, c-format @@ -5379,10 +5298,11 @@ msgstr "Datenbank »%s« muss innerhalb von %u Transaktionen gevacuumt werden" #: access/transam/varsup.c:169 access/transam/varsup.c:178 #: access/transam/varsup.c:488 access/transam/varsup.c:497 #, c-format -msgid "Approximately %.2f%% of transaction IDs are available for use." -msgstr "" +msgid "Approximately %.2f%% of transaction ID space remains before wraparound." +msgstr "Ungefähr %.2f%% des Transaktions-ID-Bereichs verbleiben vor dem Wraparound." -#: access/transam/varsup.c:171 +#: access/transam/varsup.c:171 access/transam/varsup.c:180 +#: access/transam/varsup.c:490 access/transam/varsup.c:499 #, c-format msgid "" "To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" @@ -5396,16 +5316,6 @@ msgstr "" msgid "database with OID %u must be vacuumed within %u transactions" msgstr "Datenbank mit OID %u muss innerhalb von %u Transaktionen gevacuumt werden" -#: access/transam/varsup.c:180 access/transam/varsup.c:490 -#: access/transam/varsup.c:499 -#, c-format -msgid "" -"To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." -msgstr "" -"Um ein Fehler bei der Zuweisung von XIDs zu vermeiden, führen Sie ein komplettes VACUUM über diese Datenbank aus.\n" -"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." - #: access/transam/xact.c:654 #, c-format msgid "cannot assign transaction IDs during a parallel operation" @@ -5455,10 +5365,9 @@ msgstr "%s kann nicht in einer Subtransaktion laufen" #. translator: %s represents an SQL statement name #: access/transam/xact.c:3730 -#, fuzzy, c-format -#| msgid "%s cannot be executed from a function" +#, c-format msgid "%s cannot be executed from a function or procedure" -msgstr "%s kann nicht aus einer Funktion ausgeführt werden" +msgstr "%s kann nicht aus einer Funktion oder Prozedur ausgeführt werden" #. translator: %s represents an SQL statement name #: access/transam/xact.c:3802 access/transam/xact.c:4124 @@ -5522,16 +5431,14 @@ msgid "cannot have more than 2^32-1 subtransactions in a transaction" msgstr "kann nicht mehr als 2^32-1 Subtransaktionen in einer Transaktion haben" #: access/transam/xlog.c:1582 -#, fuzzy, c-format -#| msgid "request to flush past end of generated WAL; request %X/%X, current position %X/%X" +#, c-format msgid "request to flush past end of generated WAL; request %X/%08X, current position %X/%08X" -msgstr "Flush hinter das Ende des erzeugten WAL angefordert; Anforderung %X/%X, aktuelle Position %X/%X" +msgstr "Flush hinter das Ende des erzeugten WAL angefordert; Anforderung %X/%08X, aktuelle Position %X/%08X" #: access/transam/xlog.c:1809 -#, fuzzy, c-format -#| msgid "cannot read past end of generated WAL: requested %X/%X, current position %X/%X" +#, c-format msgid "cannot read past end of generated WAL: requested %X/%08X, current position %X/%08X" -msgstr "kann nicht hinter das Ende des erzeugten WAL lesen: Anforderung %X/%X, aktuelle Position %X/%X" +msgstr "kann nicht hinter das Ende des erzeugten WAL lesen: Anforderung %X/%08X, aktuelle Position %X/%08X" #: access/transam/xlog.c:2239 access/transam/xlog.c:4603 #, c-format @@ -5544,7 +5451,7 @@ msgid "could not write to log file \"%s\" at offset %u, length %zu: %m" msgstr "konnte nicht in Logdatei »%s« bei Position %u, Länge %zu schreiben: %m" #: access/transam/xlog.c:3795 access/transam/xlogutils.c:844 -#: replication/walsender.c:3323 +#: postmaster/walsummarizer.c:1636 replication/walsender.c:3325 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "das angeforderte WAL-Segment %s wurde schon entfernt" @@ -5566,7 +5473,7 @@ msgid "creating missing WAL directory \"%s\"" msgstr "erzeuge fehlendes WAL-Verzeichnis »%s«" #: access/transam/xlog.c:4181 access/transam/xlog.c:4201 -#: commands/dbcommands.c:3300 +#: commands/dbcommands.c:3330 #, c-format msgid "could not create missing directory \"%s\": %m" msgstr "konnte fehlendes Verzeichnis »%s« nicht erzeugen: %m" @@ -5651,7 +5558,7 @@ msgstr "»%s« muss mindestens zweimal so groß wie »%s« sein" #: access/transam/xlog.c:5092 catalog/namespace.c:4768 #: commands/tablespace.c:1224 commands/user.c:2544 commands/variable.c:72 -#: replication/slot.c:2976 tcop/postgres.c:3708 utils/error/elog.c:2389 +#: replication/slot.c:2978 tcop/postgres.c:3708 utils/error/elog.c:2389 #: utils/error/elog.c:2693 #, c-format msgid "List syntax is invalid." @@ -5771,12 +5678,12 @@ msgstr "Wiederherstellung aus Archiv abgeschlossen" #: access/transam/xlog.c:6616 #, c-format msgid "enabling data checksums was interrupted" -msgstr "" +msgstr "Einschalten der Datenprüfsummen wurde unterbrochen" #: access/transam/xlog.c:6617 #, c-format msgid "Data checksum processing must be manually restarted for checksums to be enabled." -msgstr "" +msgstr "Die Datenprüfsummen-Verarbeitung muss manuell neu gestartet werden, damit die Prüfsummen eingeschaltet werden." #: access/transam/xlog.c:7117 #, c-format @@ -5785,29 +5692,25 @@ msgstr "fahre herunter" #. translator: the placeholder shows checkpoint options #: access/transam/xlog.c:7178 -#, fuzzy, c-format -#| msgid "restartpoint starting:%s%s%s%s%s%s%s%s" +#, c-format msgid "restartpoint starting:%s" -msgstr "Restart-Punkt beginnt:%s%s%s%s%s%s%s%s" +msgstr "Restart-Punkt beginnt:%s" #. translator: the placeholder shows checkpoint options #: access/transam/xlog.c:7183 -#, fuzzy, c-format -#| msgid "checkpoint starting:%s%s%s%s%s%s%s%s" +#, c-format msgid "checkpoint starting:%s" -msgstr "Checkpoint beginnt:%s%s%s%s%s%s%s%s" +msgstr "Checkpoint beginnt:%s" #: access/transam/xlog.c:7241 -#, fuzzy, c-format -#| msgid "restartpoint complete: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X" +#, c-format msgid "restartpoint complete:%s: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB; lsn=%X/%08X, redo lsn=%X/%08X" -msgstr "Restart-Punkt komplett: %d Puffer geschrieben (%.1f%%), %d SLRU-Puffer geschrieben; %d WAL-Datei(en) hinzugefügt, %d entfernt, %d wiederverwendet; Schreiben=%ld,%03d s, Sync=%ld,%03d s, gesamt=%ld,%03d s; sync. Dateien=%d, längste=%ld,%03d s, Durchschnitt=%ld.%03d s; Entfernung=%d kB, Schätzung=%d kB; LSN=%X/%X, Redo-LSN=%X/%X" +msgstr "Restart-Punkt komplett:%s: %d Puffer geschrieben (%.1f%%), %d SLRU-Puffer geschrieben; %d WAL-Datei(en) hinzugefügt, %d entfernt, %d wiederverwendet; Schreiben=%ld,%03d s, Sync=%ld,%03d s, gesamt=%ld,%03d s; sync. Dateien=%d, längste=%ld,%03d s, Durchschnitt=%ld.%03d s; Entfernung=%d kB, Schätzung=%d kB; LSN=%X/%08X, Redo-LSN=%X/%08X" #: access/transam/xlog.c:7266 -#, fuzzy, c-format -#| msgid "checkpoint complete: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X" +#, c-format msgid "checkpoint complete:%s: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB; lsn=%X/%08X, redo lsn=%X/%08X" -msgstr "Checkpoint komplett: %d Puffer geschrieben (%.1f%%), %d SLRU-Puffer geschrieben; %d WAL-Datei(en) hinzugefügt, %d entfernt, %d wiederverwendet; Schreiben=%ld,%03d s, Sync=%ld,%03d s, gesamt=%ld,%03d s; sync. Dateien=%d, längste=%ld,%03d s, Durchschnitt=%ld.%03d s; Entfernung=%d kB, Schätzung=%d kB; LSN=%X/%X, Redo-LSN=%X/%X" +msgstr "Checkpoint komplett:%s: %d Puffer geschrieben (%.1f%%), %d SLRU-Puffer geschrieben; %d WAL-Datei(en) hinzugefügt, %d entfernt, %d wiederverwendet; Schreiben=%ld,%03d s, Sync=%ld,%03d s, gesamt=%ld,%03d s; sync. Dateien=%d, längste=%ld,%03d s, Durchschnitt=%ld.%03d s; Entfernung=%d kB, Schätzung=%d kB; LSN=%X/%08X, Redo-LSN=%X/%08X" #: access/transam/xlog.c:7778 #, c-format @@ -5815,10 +5718,9 @@ msgid "concurrent write-ahead log activity while database system is shutting dow msgstr "gleichzeitige Write-Ahead-Log-Aktivität während das Datenbanksystem herunterfährt" #: access/transam/xlog.c:8374 -#, fuzzy, c-format -#| msgid "recovery restart point at %X/%X" +#, c-format msgid "recovery restart point at %X/%08X" -msgstr "Recovery-Restart-Punkt bei %X/%X" +msgstr "Recovery-Restart-Punkt bei %X/%08X" #: access/transam/xlog.c:8376 #, c-format @@ -5826,10 +5728,9 @@ msgid "Last completed transaction was at log time %s." msgstr "Die letzte vollständige Transaktion war bei Logzeit %s." #: access/transam/xlog.c:8640 -#, fuzzy, c-format -#| msgid "restore point \"%s\" created at %X/%X" +#, c-format msgid "restore point \"%s\" created at %X/%08X" -msgstr "Restore-Punkt »%s« erzeugt bei %X/%X" +msgstr "Restore-Punkt »%s« erzeugt bei %X/%08X" #: access/transam/xlog.c:8889 #, c-format @@ -5867,7 +5768,7 @@ msgid "WAL level not sufficient for making an online backup" msgstr "WAL-Level nicht ausreichend, um Online-Sicherung durchzuführen" #: access/transam/xlog.c:9475 access/transam/xlog.c:9805 -#: access/transam/xlogfuncs.c:279 commands/subscriptioncmds.c:3163 +#: access/transam/xlogfuncs.c:279 commands/subscriptioncmds.c:3258 #, c-format msgid "\"wal_level\" must be set to \"replica\" or \"logical\" at server start." msgstr "»wal_level« muss beim Serverstart auf »replica« oder »logical« gesetzt werden." @@ -6245,10 +6146,9 @@ msgid "could not decompress image at %X/%08X, block %d" msgstr "konnte Abbild bei %X/%08X nicht dekomprimieren, Block %d" #: access/transam/xlogrecovery.c:562 -#, fuzzy, c-format -#| msgid "starting backup recovery with redo LSN %X/%X, checkpoint LSN %X/%X, on timeline ID %u" +#, c-format msgid "starting backup recovery with redo LSN %X/%08X, checkpoint LSN %X/%08X, on timeline ID %u" -msgstr "starte Wiederherstellung aus Backup mit Redo-LSN %X/%X, Checkpoint-LSN %X/%X, auf Zeitleisten-ID %u" +msgstr "starte Wiederherstellung aus Backup mit Redo-LSN %X/%08X, Checkpoint-LSN %X/%08X, auf Zeitleisten-ID %u" #: access/transam/xlogrecovery.c:594 access/transam/xlogrecovery.c:752 #, c-format @@ -6267,10 +6167,9 @@ msgstr "" "Vorsicht: Wenn ein Backup wiederhergestellt wird und »%s/backup_label« gelöscht wird, dann wird das den Cluster verfälschen." #: access/transam/xlogrecovery.c:605 -#, fuzzy, c-format -#| msgid "could not locate required checkpoint record at %X/%X" +#, c-format msgid "could not locate required checkpoint record at %X/%08X" -msgstr "konnte den nötigen Checkpoint-Datensatz bei %X/%X nicht finden" +msgstr "konnte den nötigen Checkpoint-Datensatz bei %X/%08X nicht finden" #: access/transam/xlogrecovery.c:635 commands/tablespace.c:672 #, c-format @@ -6293,16 +6192,14 @@ msgid "Could not rename file \"%s\" to \"%s\": %m." msgstr "Konnte Datei »%s« nicht in »%s« umbenennen: %m." #: access/transam/xlogrecovery.c:715 -#, fuzzy, c-format -#| msgid "restarting backup recovery with redo LSN %X/%X" +#, c-format msgid "restarting backup recovery with redo LSN %X/%08X" -msgstr "starte Wiederherstellung aus Backup neu mit Redo-LSN %X/%X" +msgstr "starte Wiederherstellung aus Backup neu mit Redo-LSN %X/%08X" #: access/transam/xlogrecovery.c:740 -#, fuzzy, c-format -#| msgid "could not locate a valid checkpoint record at %X/%X" +#, c-format msgid "could not locate a valid checkpoint record at %X/%08X" -msgstr "konnte keinen gültigen Checkpoint-Datensatz bei %X/%X finden" +msgstr "konnte keinen gültigen Checkpoint-Datensatz bei %X/%08X finden" #: access/transam/xlogrecovery.c:761 #, c-format @@ -6325,10 +6222,9 @@ msgid "starting point-in-time recovery to \"%s\"" msgstr "starte Point-in-Time-Recovery bis »%s«" #: access/transam/xlogrecovery.c:776 -#, fuzzy, c-format -#| msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +#, c-format msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%08X\"" -msgstr "starte Point-in-Time-Recovery bis WAL-Position (LSN) »%X/%X«" +msgstr "starte Point-in-Time-Recovery bis WAL-Position (LSN) »%X/%08X«" #: access/transam/xlogrecovery.c:780 #, c-format @@ -6347,16 +6243,14 @@ msgstr "angeforderte Zeitleiste %u ist kein Kind der History dieses Servers" #. translator: %s is a backup_label file or a pg_control file #: access/transam/xlogrecovery.c:807 -#, fuzzy, c-format -#| msgid "Latest checkpoint in file \"%s\" is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +#, c-format msgid "Latest checkpoint in file \"%s\" is at %X/%08X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%08X." -msgstr "Neuester Checkpoint in Datei »%s« ist bei %X/%X auf Zeitleiste %u, aber in der History der angeforderten Zeitleiste zweigte der Server von dieser Zeitleiste bei %X/%X ab." +msgstr "Neuester Checkpoint in Datei »%s« ist bei %X/%08X auf Zeitleiste %u, aber in der History der angeforderten Zeitleiste zweigte der Server von dieser Zeitleiste bei %X/%08X ab." #: access/transam/xlogrecovery.c:822 -#, fuzzy, c-format -#| msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" +#, c-format msgid "requested timeline %u does not contain minimum recovery point %X/%08X on timeline %u" -msgstr "angeforderte Zeitleiste %u enthält nicht den minimalen Wiederherstellungspunkt %X/%X auf Zeitleiste %u" +msgstr "angeforderte Zeitleiste %u enthält nicht den minimalen Wiederherstellungspunkt %X/%08X auf Zeitleiste %u" #: access/transam/xlogrecovery.c:850 #, c-format @@ -6446,22 +6340,19 @@ msgid "Use pg_combinebackup to reconstruct a valid data directory." msgstr "Verwenden Sie pg_combinebackup, um ein gültiges Datenverzeichnis zu rekonstruieren." #: access/transam/xlogrecovery.c:1677 -#, fuzzy, c-format -#| msgid "unexpected record type found at redo point %X/%X" +#, c-format msgid "unexpected record type found at redo point %X/%08X" -msgstr "unerwarteter Datensatztyp bei Redo-Position %X/%X gefunden" +msgstr "unerwarteter Datensatztyp bei Redo-Position %X/%08X gefunden" #: access/transam/xlogrecovery.c:1700 -#, fuzzy, c-format -#| msgid "redo starts at %X/%X" +#, c-format msgid "redo starts at %X/%08X" -msgstr "Redo beginnt bei %X/%X" +msgstr "Redo beginnt bei %X/%08X" #: access/transam/xlogrecovery.c:1713 -#, fuzzy, c-format -#| msgid "redo in progress, elapsed time: %ld.%02d s, current LSN: %X/%X" +#, c-format msgid "redo in progress, elapsed time: %ld.%02d s, current LSN: %X/%08X" -msgstr "Redo im Gang, abgelaufene Zeit: %ld.%02d s, aktuelle LSN: %X/%X" +msgstr "Redo im Gang, abgelaufene Zeit: %ld.%02d s, aktuelle LSN: %X/%08X" #: access/transam/xlogrecovery.c:1816 #, c-format @@ -6469,10 +6360,9 @@ msgid "requested recovery stop point is before consistent recovery point" msgstr "angeforderter Recovery-Endpunkt ist vor konsistentem Recovery-Punkt" #: access/transam/xlogrecovery.c:1849 -#, fuzzy, c-format -#| msgid "redo done at %X/%X system usage: %s" +#, c-format msgid "redo done at %X/%08X system usage: %s" -msgstr "Redo fertig bei %X/%X Systembenutzung: %s" +msgstr "Redo fertig bei %X/%08X Systembenutzung: %s" #: access/transam/xlogrecovery.c:1855 #, c-format @@ -6490,10 +6380,9 @@ msgid "recovery ended before configured recovery target was reached" msgstr "Wiederherstellung endete bevor das konfigurierte Wiederherstellungsziel erreicht wurde" #: access/transam/xlogrecovery.c:2070 -#, fuzzy, c-format -#| msgid "successfully skipped missing contrecord at %X/%X, overwritten at %s" +#, c-format msgid "successfully skipped missing contrecord at %X/%08X, overwritten at %s" -msgstr "fehlender Contrecord bei %X/%X erfolgreich übersprungen, überschrieben am %s" +msgstr "fehlender Contrecord bei %X/%08X erfolgreich übersprungen, überschrieben am %s" #: access/transam/xlogrecovery.c:2137 #, c-format @@ -6511,23 +6400,20 @@ msgid "Remove those directories, or set \"allow_in_place_tablespaces\" to ON tra msgstr "Entfernen Sie diese Verzeichnisse oder setzen Sie »allow_in_place_tablespaces« vorrübergehend auf ON, damit die Wiederherstellung abschließen kann." #: access/transam/xlogrecovery.c:2193 -#, fuzzy, c-format -#| msgid "completed backup recovery with redo LSN %X/%X and end LSN %X/%X" +#, c-format msgid "completed backup recovery with redo LSN %X/%08X and end LSN %X/%08X" -msgstr "Wiederherstellung aus Backup abgeschlossen mit Redo-LSN %X/%X und End-LSN %X/%X" +msgstr "Wiederherstellung aus Backup abgeschlossen mit Redo-LSN %X/%08X und End-LSN %X/%08X" #: access/transam/xlogrecovery.c:2224 -#, fuzzy, c-format -#| msgid "consistent recovery state reached at %X/%X" +#, c-format msgid "consistent recovery state reached at %X/%08X" -msgstr "konsistenter Wiederherstellungszustand erreicht bei %X/%X" +msgstr "konsistenter Wiederherstellungszustand erreicht bei %X/%08X" #. translator: %s is a WAL record description #: access/transam/xlogrecovery.c:2262 -#, fuzzy, c-format -#| msgid "WAL redo at %X/%X for %s" +#, c-format msgid "WAL redo at %X/%08X for %s" -msgstr "WAL-Redo bei %X/%X für %s" +msgstr "WAL-Redo bei %X/%08X für %s" #: access/transam/xlogrecovery.c:2360 #, c-format @@ -6540,10 +6426,9 @@ msgid "unexpected timeline ID %u (after %u) in checkpoint record" msgstr "unerwartete Zeitleisten-ID %u (nach %u) im Checkpoint-Datensatz" #: access/transam/xlogrecovery.c:2385 -#, fuzzy, c-format -#| msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" +#, c-format msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%08X on timeline %u" -msgstr "unerwartete Zeitleisten-ID %u in Checkpoint-Datensatz, bevor der minimale Wiederherstellungspunkt %X/%X auf Zeitleiste %u erreicht wurde" +msgstr "unerwartete Zeitleisten-ID %u in Checkpoint-Datensatz, bevor der minimale Wiederherstellungspunkt %X/%08X auf Zeitleiste %u erreicht wurde" #: access/transam/xlogrecovery.c:2569 access/transam/xlogrecovery.c:2845 #, c-format @@ -6551,10 +6436,9 @@ msgid "recovery stopping after reaching consistency" msgstr "Wiederherstellung beendet nachdem Konsistenz erreicht wurde" #: access/transam/xlogrecovery.c:2590 -#, fuzzy, c-format -#| msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +#, c-format msgid "recovery stopping before WAL location (LSN) \"%X/%08X\"" -msgstr "Wiederherstellung beendet vor WAL-Position (LSN) »%X/%X«" +msgstr "Wiederherstellung beendet vor WAL-Position (LSN) »%X/%08X«" #: access/transam/xlogrecovery.c:2680 #, c-format @@ -6572,10 +6456,9 @@ msgid "recovery stopping at restore point \"%s\", time %s" msgstr "Wiederherstellung beendet bei Restore-Punkt »%s«, Zeit %s" #: access/transam/xlogrecovery.c:2758 -#, fuzzy, c-format -#| msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +#, c-format msgid "recovery stopping after WAL location (LSN) \"%X/%08X\"" -msgstr "Wiederherstellung beendet nach WAL-Position (LSN) »%X/%X«" +msgstr "Wiederherstellung beendet nach WAL-Position (LSN) »%X/%08X«" #: access/transam/xlogrecovery.c:2825 #, c-format @@ -6608,22 +6491,19 @@ msgid "Execute pg_wal_replay_resume() to continue." msgstr "Führen Sie pg_wal_replay_resume() aus um fortzusetzen." #: access/transam/xlogrecovery.c:3184 -#, fuzzy, c-format -#| msgid "unexpected timeline ID %u in WAL segment %s, LSN %X/%X, offset %u" +#, c-format msgid "unexpected timeline ID %u in WAL segment %s, LSN %X/%08X, offset %u" -msgstr "unerwartete Zeitleisten-ID %u in WAL-Segment %s, LSN %X/%X, Offset %u" +msgstr "unerwartete Zeitleisten-ID %u in WAL-Segment %s, LSN %X/%08X, Offset %u" #: access/transam/xlogrecovery.c:3404 -#, fuzzy, c-format -#| msgid "could not read from WAL segment %s, LSN %X/%X, offset %u: %m" +#, c-format msgid "could not read from WAL segment %s, LSN %X/%08X, offset %u: %m" -msgstr "konnte nicht aus WAL-Segment %s, LSN %X/%X, Position %u lesen: %m" +msgstr "konnte nicht aus WAL-Segment %s, LSN %X/%08X, Position %u lesen: %m" #: access/transam/xlogrecovery.c:3411 -#, fuzzy, c-format -#| msgid "could not read from WAL segment %s, LSN %X/%X, offset %u: read %d of %zu" +#, c-format msgid "could not read from WAL segment %s, LSN %X/%08X, offset %u: read %d of %zu" -msgstr "konnte nicht aus WAL-Segment %s, LSN %X/%X, Position %u lesen: %d von %zu gelesen" +msgstr "konnte nicht aus WAL-Segment %s, LSN %X/%08X, Position %u lesen: %d von %zu gelesen" #: access/transam/xlogrecovery.c:4073 #, c-format @@ -6656,10 +6536,9 @@ msgid "new timeline %u is not a child of database system timeline %u" msgstr "neue Zeitleiste %u ist kein Kind der Datenbanksystemzeitleiste %u" #: access/transam/xlogrecovery.c:4171 -#, fuzzy, c-format -#| msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" +#, c-format msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%08X" -msgstr "neue Zeitleiste %u zweigte von der aktuellen Datenbanksystemzeitleiste %u vor dem aktuellen Wiederherstellungspunkt %X/%X ab" +msgstr "neue Zeitleiste %u zweigte von der aktuellen Datenbanksystemzeitleiste %u vor dem aktuellen Wiederherstellungspunkt %X/%08X ab" #: access/transam/xlogrecovery.c:4190 #, c-format @@ -6718,13 +6597,13 @@ msgid "You can restart the server after making the necessary configuration chang msgstr "Sie können den Server neu starten, nachdem die nötigen Konfigurationsänderungen getätigt worden sind." #: access/transam/xlogrecovery.c:4762 access/transam/xlogrecovery.c:4764 -#: catalog/dependency.c:1219 catalog/dependency.c:1226 -#: catalog/dependency.c:1237 commands/tablecmds.c:1588 -#: commands/tablecmds.c:17401 commands/tablespace.c:468 commands/user.c:1309 +#: catalog/dependency.c:1224 catalog/dependency.c:1231 +#: catalog/dependency.c:1242 commands/tablecmds.c:1588 +#: commands/tablecmds.c:17391 commands/tablespace.c:468 commands/user.c:1309 #: commands/view.c:441 commands/wait.c:108 executor/execExprInterp.c:5285 #: executor/execExprInterp.c:5293 libpq/auth-oauth.c:700 libpq/auth.c:316 -#: replication/logical/applyparallelworker.c:1060 replication/slot.c:1849 -#: replication/slot.c:2991 replication/slot.c:2993 replication/syncrep.c:1088 +#: replication/logical/applyparallelworker.c:1060 replication/slot.c:1851 +#: replication/slot.c:2993 replication/slot.c:2995 replication/syncrep.c:1088 #: storage/aio/method_io_uring.c:399 storage/lmgr/deadlock.c:1137 #: storage/lmgr/proc.c:1566 utils/init/postinit.c:1557 #: utils/init/postinit.c:1558 utils/misc/guc.c:3063 utils/misc/guc.c:3104 @@ -6755,22 +6634,19 @@ msgid "Timestamp out of range: \"%s\"." msgstr "Timestamp ist außerhalb des gültigen Bereichs: »%s«." #: access/transam/xlogrecovery.c:5009 access/transam/xlogrecovery.c:5074 -#, fuzzy, c-format -#| msgid "\"%s\" is not a number" +#, c-format msgid "\"%s\" is not a valid number." -msgstr "»%s« ist keine Zahl" +msgstr "»%s« ist keine gültige Zahl." #: access/transam/xlogrecovery.c:5016 -#, fuzzy, c-format -#| msgid "\"%s\" must be 0 or between %d kB and %d kB." +#, c-format msgid "\"%s\" must be between %u and %u." -msgstr "»%s« muss 0 sein oder zwischen %d kB und %d kB liegen." +msgstr "»%s« muss zwischen %u und %u liegen." #: access/transam/xlogrecovery.c:5081 -#, fuzzy, c-format -#| msgid "transaction ID (-x) must be greater than or equal to %u" +#, c-format msgid "\"%s\" without epoch must be greater than or equal to %u." -msgstr "Transaktions-ID (-x) muss größer oder gleich %u sein" +msgstr "»%s« ohne Epoche muss größer oder gleich %u sein." #: access/transam/xlogutils.c:1059 #, c-format @@ -6783,10 +6659,9 @@ msgid "could not read from WAL segment %s, offset %d: read %d of %d" msgstr "konnte nicht aus WAL-Segment %s, Position %d lesen: %d von %d gelesen" #: access/transam/xlogwait.c:476 -#, fuzzy, c-format -#| msgid "while waiting on promotion" +#, c-format msgid "while waiting for LSN" -msgstr "beim Warten auf Beförderung" +msgstr "beim Warten auf LSN" #: archive/shell_archive.c:99 #, c-format @@ -6886,10 +6761,9 @@ msgid "incremental backups cannot be taken unless WAL summarization is enabled" msgstr "inkrementelle Backups können nicht durchgeführt werden, wenn WAL-Zusammenfassung nicht eingeschaltet ist" #: backup/basebackup.c:811 -#, fuzzy, c-format -#| msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +#, c-format msgid "% is outside the valid range for parameter \"%s\" (%d .. %d)" -msgstr "%d ist außerhalb des gültigen Bereichs für Parameter »%s« (%d ... %d)" +msgstr "% ist außerhalb des gültigen Bereichs für Parameter »%s« (%d ... %d)" #: backup/basebackup.c:856 #, c-format @@ -7004,22 +6878,19 @@ msgid "timeline %u found in manifest, but not in this server's history" msgstr "Zeitleiste %u wurde im Manifest gefunden, aber nicht in der History dieses Servers" #: backup/basebackup_incremental.c:411 -#, fuzzy, c-format -#| msgid "manifest requires WAL from initial timeline %u starting at %X/%X, but that timeline begins at %X/%X" +#, c-format msgid "manifest requires WAL from initial timeline %u starting at %X/%08X, but that timeline begins at %X/%08X" -msgstr "Manifest benötigt WAL aus der initialen Zeitleiste %u beginnend bei %X/%X, aber diese Zeitleiste beginnt bei %X/%X" +msgstr "Manifest benötigt WAL aus der initialen Zeitleiste %u beginnend bei %X/%08X, aber diese Zeitleiste beginnt bei %X/%08X" #: backup/basebackup_incremental.c:421 -#, fuzzy, c-format -#| msgid "manifest requires WAL from continuation timeline %u starting at %X/%X, but that timeline begins at %X/%X" +#, c-format msgid "manifest requires WAL from continuation timeline %u starting at %X/%08X, but that timeline begins at %X/%08X" -msgstr "Manifest benötigt WAL aus der Fortsetzungszeitleiste %u beginnend bei %X/%X, aber diese Zeitleiste beginnt bei %X/%X" +msgstr "Manifest benötigt WAL aus der Fortsetzungszeitleiste %u beginnend bei %X/%08X, aber diese Zeitleiste beginnt bei %X/%08X" #: backup/basebackup_incremental.c:432 -#, fuzzy, c-format -#| msgid "manifest requires WAL from final timeline %u ending at %X/%X, but this backup starts at %X/%X" +#, c-format msgid "manifest requires WAL from final timeline %u ending at %X/%08X, but this backup starts at %X/%08X" -msgstr "Manifest benötigt WAL aus der finalen Zeitleiste %u endend bei %X/%X, aber dieses Backup startet bei %X/%X" +msgstr "Manifest benötigt WAL aus der finalen Zeitleiste %u endend bei %X/%08X, aber dieses Backup startet bei %X/%08X" #: backup/basebackup_incremental.c:436 #, c-format @@ -7027,28 +6898,24 @@ msgid "This can happen for incremental backups on a standby if there was little msgstr "Das kann für inkrementelle Backups auf einem Standby passieren, wenn es wenig Aktivität seit dem letzten Backup gab." #: backup/basebackup_incremental.c:443 -#, fuzzy, c-format -#| msgid "manifest requires WAL from non-final timeline %u ending at %X/%X, but this server switched timelines at %X/%X" +#, c-format msgid "manifest requires WAL from non-final timeline %u ending at %X/%08X, but this server switched timelines at %X/%08X" -msgstr "Manifest benötigt WAL aus der nicht-finalen Zeitleiste %u endend bei %X/%X, aber dieser Server hat die Zeitleiste bei %X/%X gewechselt" +msgstr "Manifest benötigt WAL aus der nicht-finalen Zeitleiste %u endend bei %X/%08X, aber dieser Server hat die Zeitleiste bei %X/%08X gewechselt" #: backup/basebackup_incremental.c:524 -#, fuzzy, c-format -#| msgid "WAL summaries are required on timeline %u from %X/%X to %X/%X, but no summaries for that timeline and LSN range exist" +#, c-format msgid "WAL summaries are required on timeline %u from %X/%08X to %X/%08X, but no summaries for that timeline and LSN range exist" -msgstr "WAL-Zusammenfassungen auf Zeitleiste %u von %X/%X bis %X/%X werden benötigt, aber für diese Zeitleiste und diesen LSN-Bereich existieren keine Zusammenfassungen." +msgstr "WAL-Zusammenfassungen auf Zeitleiste %u von %X/%08X bis %X/%08X werden benötigt, aber für diese Zeitleiste und diesen LSN-Bereich existieren keine Zusammenfassungen." #: backup/basebackup_incremental.c:531 -#, fuzzy, c-format -#| msgid "WAL summaries are required on timeline %u from %X/%X to %X/%X, but the summaries for that timeline and LSN range are incomplete" +#, c-format msgid "WAL summaries are required on timeline %u from %X/%08X to %X/%08X, but the summaries for that timeline and LSN range are incomplete" -msgstr "WAL-Zusammenfassungen auf Zeitleiste %u von %X/%X bis %X/%X werden benötigt, aber die Zusammenfassungen für diese Zeitleiste und diesen LSN-Bereich sind unvollständig." +msgstr "WAL-Zusammenfassungen auf Zeitleiste %u von %X/%08X bis %X/%08X werden benötigt, aber die Zusammenfassungen für diese Zeitleiste und diesen LSN-Bereich sind unvollständig." #: backup/basebackup_incremental.c:535 -#, fuzzy, c-format -#| msgid "The first unsummarized LSN in this range is %X/%X." +#, c-format msgid "The first unsummarized LSN in this range is %X/%08X." -msgstr "Die erste nicht zusammengefasste LSN in diesem Bereich ist %X/%X." +msgstr "Die erste nicht zusammengefasste LSN in diesem Bereich ist %X/%08X." #: backup/basebackup_incremental.c:946 #, c-format @@ -7080,9 +6947,9 @@ msgstr "Nur Rollen mit den Privilegien der Rolle »%s« können ein auf dem Serv msgid "relative path not allowed for backup stored on server" msgstr "relativer Pfad nicht erlaubt für auf dem Server abgelegtes Backup" -#: backup/basebackup_server.c:102 commands/dbcommands.c:481 +#: backup/basebackup_server.c:102 commands/dbcommands.c:482 #: commands/tablespace.c:159 commands/tablespace.c:175 -#: commands/tablespace.c:601 commands/tablespace.c:646 replication/slot.c:2488 +#: commands/tablespace.c:601 commands/tablespace.c:646 replication/slot.c:2490 #: storage/file/copydir.c:59 #, c-format msgid "could not create directory \"%s\": %m" @@ -7107,10 +6974,9 @@ msgid "Check free disk space." msgstr "Prüfen Sie den freien Festplattenplatz." #: backup/basebackup_server.c:179 backup/basebackup_server.c:272 -#, fuzzy, c-format -#| msgid "could not write file \"%s\": wrote only %d of %d bytes at offset %u" +#, c-format msgid "could not write file \"%s\": wrote only %d of %zu bytes at offset %lld" -msgstr "konnte Datei »%s« nicht schreiben: es wurden nur %d von %d Bytes bei Offset %u geschrieben" +msgstr "konnte Datei »%s« nicht schreiben: es wurden nur %d von %zu Bytes bei Offset %lld geschrieben" #: backup/basebackup_target.c:146 #, c-format @@ -7322,21 +7188,21 @@ msgstr "Klausel IN SCHEMA kann nicht verwendet werden, wenn %s verwendet wird" #: catalog/heap.c:2963 catalog/objectaddress.c:1629 #: catalog/pg_publication.c:689 commands/analyze.c:1061 commands/copy.c:1123 #: commands/propgraphcmds.c:539 commands/sequence.c:1660 -#: commands/tablecmds.c:7859 commands/tablecmds.c:8037 -#: commands/tablecmds.c:8238 commands/tablecmds.c:8367 -#: commands/tablecmds.c:8521 commands/tablecmds.c:8615 -#: commands/tablecmds.c:8718 commands/tablecmds.c:8878 -#: commands/tablecmds.c:8908 commands/tablecmds.c:9063 -#: commands/tablecmds.c:9166 commands/tablecmds.c:9300 -#: commands/tablecmds.c:9413 commands/tablecmds.c:14889 -#: commands/tablecmds.c:15092 commands/tablecmds.c:15253 -#: commands/tablecmds.c:16649 commands/tablecmds.c:19408 commands/trigger.c:949 -#: parser/analyze.c:1354 parser/analyze.c:2981 parser/parse_relation.c:777 +#: commands/tablecmds.c:7859 commands/tablecmds.c:8033 +#: commands/tablecmds.c:8234 commands/tablecmds.c:8363 +#: commands/tablecmds.c:8517 commands/tablecmds.c:8611 +#: commands/tablecmds.c:8714 commands/tablecmds.c:8869 +#: commands/tablecmds.c:8899 commands/tablecmds.c:9054 +#: commands/tablecmds.c:9157 commands/tablecmds.c:9291 +#: commands/tablecmds.c:9404 commands/tablecmds.c:14879 +#: commands/tablecmds.c:15082 commands/tablecmds.c:15243 +#: commands/tablecmds.c:16639 commands/tablecmds.c:19398 commands/trigger.c:949 +#: parser/analyze.c:1354 parser/analyze.c:2978 parser/parse_relation.c:777 #: parser/parse_target.c:1075 parser/parse_type.c:144 #: parser/parse_utilcmd.c:3956 parser/parse_utilcmd.c:3996 -#: parser/parse_utilcmd.c:4038 statistics/attribute_stats.c:201 -#: statistics/attribute_stats.c:638 utils/adt/acl.c:2969 -#: utils/adt/ruleutils.c:3218 +#: parser/parse_utilcmd.c:4038 statistics/attribute_stats.c:174 +#: statistics/attribute_stats.c:655 utils/adt/acl.c:2969 +#: utils/adt/ruleutils.c:3219 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" msgstr "Spalte »%s« von Relation »%s« existiert nicht" @@ -7346,14 +7212,14 @@ msgstr "Spalte »%s« von Relation »%s« existiert nicht" msgid "\"%s\" is an index" msgstr "»%s« ist ein Index" -#: catalog/aclchk.c:1834 commands/tablecmds.c:16807 commands/tablecmds.c:20332 +#: catalog/aclchk.c:1834 commands/tablecmds.c:16797 commands/tablecmds.c:20322 #, c-format msgid "\"%s\" is a composite type" msgstr "»%s« ist ein zusammengesetzter Typ" #: catalog/aclchk.c:1849 catalog/objectaddress.c:1462 commands/tablecmds.c:318 -#: commands/tablecmds.c:20316 parser/parse_clause.c:927 -#: utils/adt/ruleutils.c:1641 +#: commands/tablecmds.c:20306 parser/parse_clause.c:927 +#: utils/adt/ruleutils.c:1642 #, c-format msgid "\"%s\" is not a property graph" msgstr "»%s« ist kein Property-Graph" @@ -7363,431 +7229,441 @@ msgstr "»%s« ist kein Property-Graph" msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" msgstr "Sequenz »%s« unterstützt nur die Privilegien USAGE, SELECT und UPDATE" -#: catalog/aclchk.c:1906 +#: catalog/aclchk.c:1903 +#, c-format +msgid "\"%s\" is a property graph" +msgstr "»%s« ist ein Property-Graph" + +#: catalog/aclchk.c:1904 +#, c-format +msgid "Use GRANT ... ON PROPERTY GRAPH instead." +msgstr "Verwenden Sie stattdessen GRANT ... ON PROPERTY GRAPH." + +#: catalog/aclchk.c:1918 #, c-format msgid "invalid privilege type %s for table" msgstr "ungültiger Privilegtyp %s für Tabelle" -#: catalog/aclchk.c:2074 +#: catalog/aclchk.c:2089 #, c-format msgid "invalid privilege type %s for column" msgstr "ungültiger Privilegtyp %s für Spalte" -#: catalog/aclchk.c:2087 +#: catalog/aclchk.c:2102 #, c-format msgid "sequence \"%s\" only supports SELECT column privileges" msgstr "Sequenz »%s« unterstützt nur den Spaltenprivilegientyp SELECT" -#: catalog/aclchk.c:2278 +#: catalog/aclchk.c:2293 #, c-format msgid "language \"%s\" is not trusted" msgstr "Sprache »%s« ist nicht »trusted«" -#: catalog/aclchk.c:2280 +#: catalog/aclchk.c:2295 #, c-format msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." msgstr "GRANT und REVOKE sind für nicht vertrauenswürdige Sprachen nicht erlaubt, weil nur Superuser nicht vertrauenswürdige Sprachen verwenden können." -#: catalog/aclchk.c:2431 +#: catalog/aclchk.c:2446 #, c-format msgid "cannot set privileges of array types" msgstr "für Array-Typen können keine Privilegien gesetzt werden" -#: catalog/aclchk.c:2432 +#: catalog/aclchk.c:2447 #, c-format msgid "Set the privileges of the element type instead." msgstr "Setzen Sie stattdessen die Privilegien des Elementtyps." -#: catalog/aclchk.c:2436 +#: catalog/aclchk.c:2451 #, c-format msgid "cannot set privileges of multirange types" msgstr "für Multirange-Typen können keine Privilegien gesetzt werden" -#: catalog/aclchk.c:2437 +#: catalog/aclchk.c:2452 #, c-format msgid "Set the privileges of the range type instead." msgstr "Setzen Sie stattdessen die Privilegien des Range-Typs." -#: catalog/aclchk.c:2620 +#: catalog/aclchk.c:2635 #, c-format msgid "unrecognized privilege type \"%s\"" msgstr "unbekannter Privilegtyp »%s«" -#: catalog/aclchk.c:2687 +#: catalog/aclchk.c:2702 #, c-format msgid "permission denied for aggregate %s" msgstr "keine Berechtigung für Aggregatfunktion %s" -#: catalog/aclchk.c:2690 +#: catalog/aclchk.c:2705 #, c-format msgid "permission denied for collation %s" msgstr "keine Berechtigung für Sortierfolge %s" -#: catalog/aclchk.c:2693 +#: catalog/aclchk.c:2708 #, c-format msgid "permission denied for column %s" msgstr "keine Berechtigung für Spalte %s" -#: catalog/aclchk.c:2696 +#: catalog/aclchk.c:2711 #, c-format msgid "permission denied for conversion %s" msgstr "keine Berechtigung für Konversion %s" -#: catalog/aclchk.c:2699 +#: catalog/aclchk.c:2714 #, c-format msgid "permission denied for database %s" msgstr "keine Berechtigung für Datenbank %s" -#: catalog/aclchk.c:2702 +#: catalog/aclchk.c:2717 #, c-format msgid "permission denied for domain %s" msgstr "keine Berechtigung für Domäne %s" -#: catalog/aclchk.c:2705 +#: catalog/aclchk.c:2720 #, c-format msgid "permission denied for event trigger %s" msgstr "keine Berechtigung für Ereignistrigger %s" -#: catalog/aclchk.c:2708 +#: catalog/aclchk.c:2723 #, c-format msgid "permission denied for extension %s" msgstr "keine Berechtigung für Erweiterung %s" -#: catalog/aclchk.c:2711 +#: catalog/aclchk.c:2726 #, c-format msgid "permission denied for foreign-data wrapper %s" msgstr "keine Berechtigung für Fremddaten-Wrapper %s" -#: catalog/aclchk.c:2714 +#: catalog/aclchk.c:2729 #, c-format msgid "permission denied for foreign server %s" msgstr "keine Berechtigung für Fremdserver %s" -#: catalog/aclchk.c:2717 +#: catalog/aclchk.c:2732 #, c-format msgid "permission denied for foreign table %s" msgstr "keine Berechtigung für Fremdtabelle %s" -#: catalog/aclchk.c:2720 +#: catalog/aclchk.c:2735 #, c-format msgid "permission denied for function %s" msgstr "keine Berechtigung für Funktion %s" -#: catalog/aclchk.c:2723 +#: catalog/aclchk.c:2738 #, c-format msgid "permission denied for index %s" msgstr "keine Berechtigung für Index %s" -#: catalog/aclchk.c:2726 +#: catalog/aclchk.c:2741 #, c-format msgid "permission denied for language %s" msgstr "keine Berechtigung für Sprache %s" -#: catalog/aclchk.c:2729 +#: catalog/aclchk.c:2744 #, c-format msgid "permission denied for large object %s" msgstr "keine Berechtigung für Large Object %s" -#: catalog/aclchk.c:2732 +#: catalog/aclchk.c:2747 #, c-format msgid "permission denied for materialized view %s" msgstr "keine Berechtigung für materialisierte Sicht %s" -#: catalog/aclchk.c:2735 +#: catalog/aclchk.c:2750 #, c-format msgid "permission denied for operator class %s" msgstr "keine Berechtigung für Operatorklasse %s" -#: catalog/aclchk.c:2738 +#: catalog/aclchk.c:2753 #, c-format msgid "permission denied for operator %s" msgstr "keine Berechtigung für Operator %s" -#: catalog/aclchk.c:2741 +#: catalog/aclchk.c:2756 #, c-format msgid "permission denied for operator family %s" msgstr "keine Berechtigung für Operatorfamilie %s" -#: catalog/aclchk.c:2744 +#: catalog/aclchk.c:2759 #, c-format msgid "permission denied for parameter %s" msgstr "keine Berechtigung für Parameter %s" -#: catalog/aclchk.c:2747 +#: catalog/aclchk.c:2762 #, c-format msgid "permission denied for policy %s" msgstr "keine Berechtigung für Policy %s" -#: catalog/aclchk.c:2750 +#: catalog/aclchk.c:2765 #, c-format msgid "permission denied for procedure %s" msgstr "keine Berechtigung für Prozedur %s" -#: catalog/aclchk.c:2753 +#: catalog/aclchk.c:2768 #, c-format msgid "permission denied for property graph %s" msgstr "keine Berechtigung für Property-Graph %s" -#: catalog/aclchk.c:2756 +#: catalog/aclchk.c:2771 #, c-format msgid "permission denied for publication %s" msgstr "keine Berechtigung für Publikation %s" -#: catalog/aclchk.c:2759 +#: catalog/aclchk.c:2774 #, c-format msgid "permission denied for routine %s" msgstr "keine Berechtigung für Routine %s" -#: catalog/aclchk.c:2762 +#: catalog/aclchk.c:2777 #, c-format msgid "permission denied for schema %s" msgstr "keine Berechtigung für Schema %s" -#: catalog/aclchk.c:2765 commands/sequence.c:655 commands/sequence.c:881 +#: catalog/aclchk.c:2780 commands/sequence.c:655 commands/sequence.c:881 #: commands/sequence.c:923 commands/sequence.c:964 commands/sequence.c:1758 #, c-format msgid "permission denied for sequence %s" msgstr "keine Berechtigung für Sequenz %s" -#: catalog/aclchk.c:2768 +#: catalog/aclchk.c:2783 #, c-format msgid "permission denied for statistics object %s" msgstr "keine Berechtigung für Statistikobjekt %s" -#: catalog/aclchk.c:2771 +#: catalog/aclchk.c:2786 #, c-format msgid "permission denied for subscription %s" msgstr "keine Berechtigung für Subskription %s" -#: catalog/aclchk.c:2774 +#: catalog/aclchk.c:2789 #, c-format msgid "permission denied for table %s" msgstr "keine Berechtigung für Tabelle %s" -#: catalog/aclchk.c:2777 +#: catalog/aclchk.c:2792 #, c-format msgid "permission denied for tablespace %s" msgstr "keine Berechtigung für Tablespace %s" -#: catalog/aclchk.c:2780 +#: catalog/aclchk.c:2795 #, c-format msgid "permission denied for text search configuration %s" msgstr "keine Berechtigung für Textsuchekonfiguration %s" -#: catalog/aclchk.c:2783 +#: catalog/aclchk.c:2798 #, c-format msgid "permission denied for text search dictionary %s" msgstr "keine Berechtigung für Textsuchewörterbuch %s" -#: catalog/aclchk.c:2786 +#: catalog/aclchk.c:2801 #, c-format msgid "permission denied for type %s" msgstr "keine Berechtigung für Typ %s" -#: catalog/aclchk.c:2789 +#: catalog/aclchk.c:2804 #, c-format msgid "permission denied for view %s" msgstr "keine Berechtigung für Sicht %s" -#: catalog/aclchk.c:2825 +#: catalog/aclchk.c:2840 #, c-format msgid "must be owner of aggregate %s" msgstr "Berechtigung nur für Eigentümer der Aggregatfunktion %s" -#: catalog/aclchk.c:2828 +#: catalog/aclchk.c:2843 #, c-format msgid "must be owner of collation %s" msgstr "Berechtigung nur für Eigentümer der Sortierfolge %s" -#: catalog/aclchk.c:2831 +#: catalog/aclchk.c:2846 #, c-format msgid "must be owner of conversion %s" msgstr "Berechtigung nur für Eigentümer der Konversion %s" -#: catalog/aclchk.c:2834 +#: catalog/aclchk.c:2849 #, c-format msgid "must be owner of database %s" msgstr "Berechtigung nur für Eigentümer der Datenbank %s" -#: catalog/aclchk.c:2837 +#: catalog/aclchk.c:2852 #, c-format msgid "must be owner of domain %s" msgstr "Berechtigung nur für Eigentümer der Domäne %s" -#: catalog/aclchk.c:2840 +#: catalog/aclchk.c:2855 #, c-format msgid "must be owner of event trigger %s" msgstr "Berechtigung nur für Eigentümer des Ereignistriggers %s" -#: catalog/aclchk.c:2843 +#: catalog/aclchk.c:2858 #, c-format msgid "must be owner of extension %s" msgstr "Berechtigung nur für Eigentümer der Erweiterung %s" -#: catalog/aclchk.c:2846 +#: catalog/aclchk.c:2861 #, c-format msgid "must be owner of foreign-data wrapper %s" msgstr "Berechtigung nur für Eigentümer des Fremddaten-Wrappers %s" -#: catalog/aclchk.c:2849 +#: catalog/aclchk.c:2864 #, c-format msgid "must be owner of foreign server %s" msgstr "Berechtigung nur für Eigentümer des Fremdservers %s" -#: catalog/aclchk.c:2852 +#: catalog/aclchk.c:2867 #, c-format msgid "must be owner of foreign table %s" msgstr "Berechtigung nur für Eigentümer der Fremdtabelle %s" -#: catalog/aclchk.c:2855 +#: catalog/aclchk.c:2870 #, c-format msgid "must be owner of function %s" msgstr "Berechtigung nur für Eigentümer der Funktion %s" -#: catalog/aclchk.c:2858 +#: catalog/aclchk.c:2873 #, c-format msgid "must be owner of index %s" msgstr "Berechtigung nur für Eigentümer des Index %s" -#: catalog/aclchk.c:2861 +#: catalog/aclchk.c:2876 #, c-format msgid "must be owner of language %s" msgstr "Berechtigung nur für Eigentümer der Sprache %s" -#: catalog/aclchk.c:2864 +#: catalog/aclchk.c:2879 #, c-format msgid "must be owner of large object %s" msgstr "Berechtigung nur für Eigentümer des Large Object %s" -#: catalog/aclchk.c:2867 +#: catalog/aclchk.c:2882 #, c-format msgid "must be owner of materialized view %s" msgstr "Berechtigung nur für Eigentümer der materialisierten Sicht %s" -#: catalog/aclchk.c:2870 +#: catalog/aclchk.c:2885 #, c-format msgid "must be owner of operator class %s" msgstr "Berechtigung nur für Eigentümer der Operatorklasse %s" -#: catalog/aclchk.c:2873 +#: catalog/aclchk.c:2888 #, c-format msgid "must be owner of operator %s" msgstr "Berechtigung nur für Eigentümer des Operators %s" -#: catalog/aclchk.c:2876 +#: catalog/aclchk.c:2891 #, c-format msgid "must be owner of operator family %s" msgstr "Berechtigung nur für Eigentümer der Operatorfamilie %s" -#: catalog/aclchk.c:2879 +#: catalog/aclchk.c:2894 #, c-format msgid "must be owner of procedure %s" msgstr "Berechtigung nur für Eigentümer der Prozedur %s" -#: catalog/aclchk.c:2882 +#: catalog/aclchk.c:2897 #, c-format msgid "must be owner of property graph %s" msgstr "Berechtigung nur für Eigentümer des Property-Graphs %s" -#: catalog/aclchk.c:2885 +#: catalog/aclchk.c:2900 #, c-format msgid "must be owner of publication %s" msgstr "Berechtigung nur für Eigentümer der Publikation %s" -#: catalog/aclchk.c:2888 +#: catalog/aclchk.c:2903 #, c-format msgid "must be owner of routine %s" msgstr "Berechtigung nur für Eigentümer der Routine %s" -#: catalog/aclchk.c:2891 +#: catalog/aclchk.c:2906 #, c-format msgid "must be owner of sequence %s" msgstr "Berechtigung nur für Eigentümer der Sequenz %s" -#: catalog/aclchk.c:2894 +#: catalog/aclchk.c:2909 #, c-format msgid "must be owner of subscription %s" msgstr "Berechtigung nur für Eigentümer der Subskription %s" -#: catalog/aclchk.c:2897 +#: catalog/aclchk.c:2912 #, c-format msgid "must be owner of table %s" msgstr "Berechtigung nur für Eigentümer der Tabelle %s" -#: catalog/aclchk.c:2900 +#: catalog/aclchk.c:2915 #, c-format msgid "must be owner of type %s" msgstr "Berechtigung nur für Eigentümer des Typs %s" -#: catalog/aclchk.c:2903 +#: catalog/aclchk.c:2918 #, c-format msgid "must be owner of view %s" msgstr "Berechtigung nur für Eigentümer der Sicht %s" -#: catalog/aclchk.c:2906 +#: catalog/aclchk.c:2921 #, c-format msgid "must be owner of schema %s" msgstr "Berechtigung nur für Eigentümer des Schemas %s" -#: catalog/aclchk.c:2909 +#: catalog/aclchk.c:2924 #, c-format msgid "must be owner of statistics object %s" msgstr "Berechtigung nur für Eigentümer des Statistikobjekts %s" -#: catalog/aclchk.c:2912 +#: catalog/aclchk.c:2927 #, c-format msgid "must be owner of tablespace %s" msgstr "Berechtigung nur für Eigentümer des Tablespace %s" -#: catalog/aclchk.c:2915 +#: catalog/aclchk.c:2930 #, c-format msgid "must be owner of text search configuration %s" msgstr "Berechtigung nur für Eigentümer der Textsuchekonfiguration %s" -#: catalog/aclchk.c:2918 +#: catalog/aclchk.c:2933 #, c-format msgid "must be owner of text search dictionary %s" msgstr "Berechtigung nur für Eigentümer des Textsuchewörterbuches %s" -#: catalog/aclchk.c:2932 +#: catalog/aclchk.c:2947 #, c-format msgid "must be owner of relation %s" msgstr "Berechtigung nur für Eigentümer der Relation %s" -#: catalog/aclchk.c:2978 +#: catalog/aclchk.c:2993 #, c-format msgid "permission denied for column \"%s\" of relation \"%s\"" msgstr "keine Berechtigung für Spalte »%s« von Relation »%s«" -#: catalog/aclchk.c:3214 catalog/aclchk.c:3233 +#: catalog/aclchk.c:3229 catalog/aclchk.c:3248 #, c-format msgid "attribute %d of relation with OID %u does not exist" msgstr "Attribut %d der Relation mit OID %u existiert nicht" -#: catalog/aclchk.c:3271 catalog/aclchk.c:3334 catalog/aclchk.c:3991 +#: catalog/aclchk.c:3286 catalog/aclchk.c:3349 catalog/aclchk.c:4009 #, c-format msgid "relation with OID %u does not exist" msgstr "Relation mit OID %u existiert nicht" -#: catalog/aclchk.c:3519 +#: catalog/aclchk.c:3537 #, c-format msgid "parameter ACL with OID %u does not exist" msgstr "Parameter-ACL mit OID %u existiert nicht" -#: catalog/aclchk.c:3598 catalog/objectaddress.c:1149 +#: catalog/aclchk.c:3616 catalog/objectaddress.c:1149 #: catalog/pg_largeobject.c:127 libpq/be-fsstubs.c:323 #: storage/large_object/inv_api.c:247 #, c-format msgid "large object %u does not exist" msgstr "Large Object %u existiert nicht" -#: catalog/aclchk.c:3710 commands/collationcmds.c:854 +#: catalog/aclchk.c:3728 commands/collationcmds.c:854 #: commands/publicationcmds.c:2030 #, c-format msgid "schema with OID %u does not exist" msgstr "Schema mit OID %u existiert nicht" -#: catalog/aclchk.c:3784 catalog/aclchk.c:3811 catalog/aclchk.c:3840 +#: catalog/aclchk.c:3802 catalog/aclchk.c:3829 catalog/aclchk.c:3858 #: utils/cache/typcache.c:485 utils/cache/typcache.c:540 #, c-format msgid "type with OID %u does not exist" @@ -7842,33 +7718,37 @@ msgstr "»%s« ist kein Index für Spalte »%s«" msgid "cannot drop %s because it is required by the database system" msgstr "kann %s nicht löschen, wird vom Datenbanksystem benötigt" -#: catalog/dependency.c:845 catalog/dependency.c:1082 +#: catalog/dependency.c:845 catalog/dependency.c:1087 #, c-format msgid "cannot drop %s because %s requires it" msgstr "kann %s nicht löschen, wird von %s benötigt" -#: catalog/dependency.c:847 catalog/dependency.c:1084 +#: catalog/dependency.c:847 catalog/dependency.c:1089 #, c-format msgid "You can drop %s instead." msgstr "Sie können stattdessen %s löschen." -#: catalog/dependency.c:910 -#, fuzzy, c-format -#| msgid "cannot drop %s because %s requires it" +#: catalog/dependency.c:934 +#, c-format msgid "cannot drop %s because %s depends on it" -msgstr "kann %s nicht löschen, wird von %s benötigt" +msgstr "kann %s nicht löschen, weil %s davon abhängt" + +#: catalog/dependency.c:936 +#, c-format +msgid "Drop %s first." +msgstr "Löschen Sie zuerst %s." -#: catalog/dependency.c:1163 catalog/dependency.c:1172 +#: catalog/dependency.c:1168 catalog/dependency.c:1177 #, c-format msgid "%s depends on %s" msgstr "%s hängt von %s ab" -#: catalog/dependency.c:1187 catalog/dependency.c:1196 +#: catalog/dependency.c:1192 catalog/dependency.c:1201 #, c-format msgid "drop cascades to %s" msgstr "Löschvorgang löscht ebenfalls %s" -#: catalog/dependency.c:1204 catalog/pg_shdepend.c:868 +#: catalog/dependency.c:1209 catalog/pg_shdepend.c:868 #, c-format msgid "" "\n" @@ -7883,41 +7763,42 @@ msgstr[1] "" "\n" "und %d weitere Objekte (Liste im Serverlog)" -#: catalog/dependency.c:1216 +#: catalog/dependency.c:1221 #, c-format msgid "cannot drop %s because other objects depend on it" msgstr "kann %s nicht löschen, weil andere Objekte davon abhängen" -#: catalog/dependency.c:1220 catalog/dependency.c:1227 +#: catalog/dependency.c:1225 catalog/dependency.c:1232 #, c-format msgid "Use DROP ... CASCADE to drop the dependent objects too." msgstr "Verwenden Sie DROP ... CASCADE, um die abhängigen Objekte ebenfalls zu löschen." -#: catalog/dependency.c:1224 +#: catalog/dependency.c:1229 #, c-format msgid "cannot drop desired object(s) because other objects depend on them" msgstr "kann gewünschte Objekte nicht löschen, weil andere Objekte davon abhängen" -#: catalog/dependency.c:1232 +#: catalog/dependency.c:1237 #, c-format msgid "drop cascades to %d other object" msgid_plural "drop cascades to %d other objects" msgstr[0] "Löschvorgang löscht ebenfalls %d weiteres Objekt" msgstr[1] "Löschvorgang löscht ebenfalls %d weitere Objekte" -#: catalog/dependency.c:1953 catalog/dependency.c:1964 +#: catalog/dependency.c:1961 catalog/dependency.c:1972 #, c-format msgid "constant of the type %s cannot be used here" msgstr "Konstante vom Typ %s kann hier nicht verwendet werden" -#: catalog/dependency.c:2339 +#: catalog/dependency.c:2347 #, c-format msgid "transition table \"%s\" cannot be referenced in a persistent object" msgstr "auf Übergangstabelle »%s« kann in einem persistenten Objekt nicht verwiesen werden" -#: catalog/dependency.c:2524 parser/parse_relation.c:3630 -#: parser/parse_relation.c:3640 statistics/attribute_stats.c:213 -#: statistics/stat_utils.c:457 statistics/stat_utils.c:465 +#: catalog/dependency.c:2532 parser/parse_relation.c:3630 +#: parser/parse_relation.c:3640 statistics/attribute_stats.c:186 +#: statistics/attribute_stats.c:757 statistics/stat_utils.c:457 +#: statistics/stat_utils.c:465 #, c-format msgid "column %d of relation \"%s\" does not exist" msgstr "Spalte %d von Relation »%s« existiert nicht" @@ -7990,9 +7871,9 @@ msgstr "für Partitionierungsschlüsselspalte %s mit sortierbarem Typ %s wurde k msgid "no collation was derived for column \"%s\" with collatable type %s" msgstr "für Spalte »%s« mit sortierbarem Typ %s wurde keine Sortierfolge abgeleitet" -#: catalog/heap.c:1197 catalog/index.c:906 commands/createas.c:408 -#: commands/tablecmds.c:4371 commands/tablecmds.c:23161 -#: commands/tablecmds.c:23759 commands/tablecmds.c:24189 +#: catalog/heap.c:1197 catalog/index.c:909 commands/createas.c:408 +#: commands/tablecmds.c:4371 commands/tablecmds.c:23151 +#: commands/tablecmds.c:23749 commands/tablecmds.c:24179 #, c-format msgid "relation \"%s\" already exists" msgstr "Relation »%s« existiert bereits" @@ -8041,7 +7922,7 @@ msgid "cannot add not-null constraint on system column \"%s\"" msgstr "zur Systemspalte »%s« kann kein Not-Null-Constraint hinzugefügt werden" #: catalog/heap.c:2674 catalog/heap.c:2800 catalog/heap.c:3053 -#: catalog/index.c:920 catalog/pg_constraint.c:1027 commands/tablecmds.c:9924 +#: catalog/index.c:923 catalog/pg_constraint.c:1027 commands/tablecmds.c:9915 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" msgstr "Constraint »%s« existiert bereits für Relation »%s«" @@ -8073,8 +7954,8 @@ msgstr "Constraint »%s« wird mit geerbter Definition zusammengeführt" #: catalog/heap.c:2869 catalog/pg_constraint.c:803 catalog/pg_constraint.c:1156 #: commands/tablecmds.c:3254 commands/tablecmds.c:3574 -#: commands/tablecmds.c:7394 commands/tablecmds.c:8075 -#: commands/tablecmds.c:18240 commands/tablecmds.c:18422 +#: commands/tablecmds.c:7394 commands/tablecmds.c:8071 +#: commands/tablecmds.c:18230 commands/tablecmds.c:18412 #, c-format msgid "too many inheritance parents" msgstr "zu viele Elterntabellen" @@ -8144,7 +8025,7 @@ msgstr "Generierungsausdruck ist nicht »immutable«" msgid "column \"%s\" is of type %s but default expression is of type %s" msgstr "Spalte »%s« hat Typ %s, aber der Vorgabeausdruck hat Typ %s" -#: catalog/heap.c:3405 commands/prepare.c:336 parser/analyze.c:3347 +#: catalog/heap.c:3405 commands/prepare.c:336 parser/analyze.c:3344 #: parser/parse_target.c:600 parser/parse_target.c:890 #: parser/parse_target.c:900 rewrite/rewriteHandler.c:1342 #, c-format @@ -8201,74 +8082,74 @@ msgstr "Primärschlüssel können keine Ausdrücke sein" msgid "primary key column \"%s\" is not marked NOT NULL" msgstr "Primärschlüsselspalte »%s« ist nicht als NOT NULL markiert" -#: catalog/index.c:805 catalog/index.c:1939 +#: catalog/index.c:808 catalog/index.c:1951 #, c-format msgid "user-defined indexes on system catalog tables are not supported" msgstr "benutzerdefinierte Indexe für Systemkatalogtabellen werden nicht unterstützt" -#: catalog/index.c:845 +#: catalog/index.c:848 #, c-format msgid "nondeterministic collations are not supported for operator class \"%s\"" msgstr "nichtdeterministische Sortierfolgen werden von Operatorklasse »%s« nicht unterstützt" -#: catalog/index.c:860 +#: catalog/index.c:863 #, c-format msgid "concurrent index creation on system catalog tables is not supported" msgstr "nebenläufige Indexerzeugung für Systemkatalogtabellen wird nicht unterstützt" -#: catalog/index.c:869 catalog/index.c:1340 +#: catalog/index.c:872 catalog/index.c:1345 #, c-format msgid "concurrent index creation for exclusion constraints is not supported" msgstr "nebenläufige Indexerzeugung für Exclusion-Constraints wird nicht unterstützt" -#: catalog/index.c:878 +#: catalog/index.c:881 #, c-format msgid "shared indexes cannot be created after initdb" msgstr "Cluster-globale Indexe können nicht nach initdb erzeugt werden" -#: catalog/index.c:898 commands/createas.c:423 commands/sequence.c:152 +#: catalog/index.c:901 commands/createas.c:423 commands/sequence.c:152 #: parser/parse_utilcmd.c:208 #, c-format msgid "relation \"%s\" already exists, skipping" msgstr "Relation »%s« existiert bereits, wird übersprungen" -#: catalog/index.c:948 +#: catalog/index.c:951 #, c-format msgid "pg_class index OID value not set when in binary upgrade mode" msgstr "Index-OID-Wert für pg_class ist im Binary-Upgrade-Modus nicht gesetzt" -#: catalog/index.c:958 utils/cache/relcache.c:3799 +#: catalog/index.c:961 utils/cache/relcache.c:3801 #, c-format msgid "index relfilenumber value not set when in binary upgrade mode" msgstr "Index-Relfile-Nummer-Wert ist im Binary-Upgrade-Modus nicht gesetzt" -#: catalog/index.c:2240 +#: catalog/index.c:2252 #, c-format msgid "DROP INDEX CONCURRENTLY must be first action in transaction" msgstr "DROP INDEX CONCURRENTLY muss die erste Aktion in einer Transaktion sein" -#: catalog/index.c:3750 +#: catalog/index.c:3774 #, c-format msgid "cannot reindex temporary tables of other sessions" msgstr "kann temporäre Tabellen anderer Sitzungen nicht reindizieren" -#: catalog/index.c:3761 commands/indexcmds.c:3819 +#: catalog/index.c:3785 commands/indexcmds.c:3819 #, c-format msgid "cannot reindex invalid index on TOAST table" msgstr "ungültiger Index einer TOAST-Tabelle kann nicht reindiziert werden" -#: catalog/index.c:3777 commands/indexcmds.c:3697 commands/indexcmds.c:3843 +#: catalog/index.c:3801 commands/indexcmds.c:3697 commands/indexcmds.c:3843 #: commands/tablecmds.c:3778 #, c-format msgid "cannot move system relation \"%s\"" msgstr "Systemrelation »%s« kann nicht verschoben werden" -#: catalog/index.c:3914 +#: catalog/index.c:3938 #, c-format msgid "index \"%s\" was reindexed" msgstr "Index »%s« wurde neu indiziert" -#: catalog/index.c:4080 +#: catalog/index.c:4104 #, c-format msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" msgstr "ungültiger Index »%s.%s« einer TOAST-Tabelle kann nicht reindizert werden, wird übersprungen" @@ -8347,7 +8228,7 @@ msgid "text search template \"%s\" does not exist" msgstr "Textsuchevorlage »%s« existiert nicht" #: catalog/namespace.c:3269 commands/tsearchcmds.c:1168 -#: utils/adt/regproc.c:1357 utils/cache/ts_cache.c:638 +#: utils/adt/regproc.c:1357 utils/cache/ts_cache.c:651 #, c-format msgid "text search configuration \"%s\" does not exist" msgstr "Textsuchekonfiguration »%s« existiert nicht" @@ -8357,7 +8238,7 @@ msgstr "Textsuchekonfiguration »%s« existiert nicht" msgid "cross-database references are not implemented: %s" msgstr "Verweise auf andere Datenbanken sind nicht implementiert: %s" -#: catalog/namespace.c:3407 gram.y:20525 gram.y:20565 parser/parse_expr.c:890 +#: catalog/namespace.c:3407 gram.y:20519 gram.y:20559 parser/parse_expr.c:890 #: parser/parse_target.c:1274 #, c-format msgid "improper qualified name (too many dotted names): %s" @@ -8411,25 +8292,25 @@ msgstr "während einer parallelen Operation können keine temporären Tabellen e #: catalog/objectaddress.c:1477 commands/policy.c:93 commands/policy.c:373 #: commands/tablecmds.c:264 commands/tablecmds.c:306 commands/tablecmds.c:2460 -#: commands/tablecmds.c:15027 parser/parse_utilcmd.c:3541 +#: commands/tablecmds.c:15017 parser/parse_utilcmd.c:3541 #, c-format msgid "\"%s\" is not a table" msgstr "»%s« ist keine Tabelle" #: catalog/objectaddress.c:1484 commands/tablecmds.c:276 -#: commands/tablecmds.c:20296 commands/view.c:112 +#: commands/tablecmds.c:20286 commands/view.c:112 #, c-format msgid "\"%s\" is not a view" msgstr "»%s« ist keine Sicht" #: catalog/objectaddress.c:1491 commands/matview.c:200 commands/tablecmds.c:282 -#: commands/tablecmds.c:20301 +#: commands/tablecmds.c:20291 #, c-format msgid "\"%s\" is not a materialized view" msgstr "»%s« ist keine materialisierte Sicht" #: catalog/objectaddress.c:1498 commands/tablecmds.c:300 -#: commands/tablecmds.c:20306 +#: commands/tablecmds.c:20296 #, c-format msgid "\"%s\" is not a foreign table" msgstr "»%s« ist keine Fremdtabelle" @@ -8479,7 +8360,7 @@ msgstr "Benutzerabbildung für Benutzer »%s« auf Server »%s« existiert nicht #: catalog/objectaddress.c:1940 commands/foreigncmds.c:441 #: commands/foreigncmds.c:1099 commands/foreigncmds.c:1462 -#: foreign/foreign.c:745 +#: foreign/foreign.c:757 #, c-format msgid "server \"%s\" does not exist" msgstr "Server »%s« existiert nicht" @@ -8843,16 +8724,14 @@ msgid "edge %s of %s" msgstr "Kante %s von %s" #: catalog/objectaddress.c:4137 catalog/objectaddress.c:4164 -#, fuzzy, c-format -#| msgid "rule %s on %s" +#, c-format msgid "label %s of %s" -msgstr "Regel %s für %s" +msgstr "Label %s von %s" #: catalog/objectaddress.c:4195 catalog/objectaddress.c:4222 -#, fuzzy, c-format -#| msgid "improper use of \"*\"" +#, c-format msgid "property %s of %s" -msgstr "unzulässige Verwendung von »*«" +msgstr "Property %s von %s" #: catalog/objectaddress.c:4235 #, c-format @@ -8972,7 +8851,7 @@ msgstr "Anfangswert darf nicht ausgelassen werden, wenn Übergangsfunktion strik msgid "return type of inverse transition function %s is not %s" msgstr "Rückgabetyp der inversen Übergangsfunktion %s ist nicht %s" -#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:3180 +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:3176 #, c-format msgid "strictness of aggregate's forward and inverse transition functions must match" msgstr "Striktheit der vorwärtigen und inversen Übergangsfunktionen einer Aggregatfunktion müssen übereinstimmen" @@ -9153,23 +9032,23 @@ msgstr "Sortierfolge »%s« existiert bereits" msgid "collation \"%s\" for encoding \"%s\" already exists" msgstr "Sortierfolge »%s« für Kodierung »%s« existiert bereits" -#: catalog/pg_constraint.c:764 commands/tablecmds.c:8060 +#: catalog/pg_constraint.c:764 commands/tablecmds.c:8056 #, c-format msgid "cannot change NO INHERIT status of NOT NULL constraint \"%s\" on relation \"%s\"" msgstr "NO INHERIT-Status von NOT-NULL-Constraint »%s« von Relation »%s« kann nicht geändert werden" -#: catalog/pg_constraint.c:766 commands/tablecmds.c:9686 +#: catalog/pg_constraint.c:766 commands/tablecmds.c:9677 #, c-format msgid "You might need to make the existing constraint inheritable using %s." msgstr "Sie müssen möglicherweise den bestehenden Constraint mit %s vererbbar machen." -#: catalog/pg_constraint.c:776 commands/tablecmds.c:8409 +#: catalog/pg_constraint.c:776 commands/tablecmds.c:8405 #, c-format msgid "incompatible NOT VALID constraint \"%s\" on relation \"%s\"" msgstr "inkompatibler NOT-VALID-Constraint »%s« für Relation »%s«" -#: catalog/pg_constraint.c:778 commands/tablecmds.c:8411 -#: commands/tablecmds.c:9698 +#: catalog/pg_constraint.c:778 commands/tablecmds.c:8407 +#: commands/tablecmds.c:9689 #, c-format msgid "You might need to validate it using %s." msgstr "Sie müssen ihn möglicherweise mit %s validieren." @@ -9245,16 +9124,14 @@ msgid "cannot remove dependency on %s because it is a system object" msgstr "kann Abhängigkeit von %s nicht entfernen, weil es ein Systemobjekt ist" #: catalog/pg_depend.c:812 -#, fuzzy, c-format -#| msgid "role %u was concurrently dropped" +#, c-format msgid "referenced %s was concurrently dropped" -msgstr "Rolle %u wurde gleichzeitig gelöscht" +msgstr "referenziertes %s wurde gleichzeitig gelöscht" #: catalog/pg_depend.c:844 -#, fuzzy, c-format -#| msgid "role %u was concurrently dropped" +#, c-format msgid "referenced relation was concurrently dropped" -msgstr "Rolle %u wurde gleichzeitig gelöscht" +msgstr "referenzierte Relation wurde gleichzeitig gelöscht" #: catalog/pg_enum.c:170 catalog/pg_enum.c:327 catalog/pg_enum.c:637 #, c-format @@ -9267,10 +9144,9 @@ msgid "Labels must be %d bytes or less." msgstr "Labels müssen %d oder weniger Bytes haben." #: catalog/pg_enum.c:187 -#, fuzzy, c-format -#| msgid "argument name \"%s\" used more than once" +#, c-format msgid "enum label \"%s\" used more than once" -msgstr "Argumentname »%s« mehrmals angegeben" +msgstr "Enum-Label »%s« mehrmals verwendet" #: catalog/pg_enum.c:356 #, c-format @@ -9308,7 +9184,7 @@ msgid "The partition is being detached concurrently or has an unfinished detach. msgstr "Die Partition wird nebenläufig abgetrennt oder hat eine unfertige Abtrennoperation." #: catalog/pg_inherits.c:596 commands/tablecmds.c:4996 -#: commands/tablecmds.c:18543 +#: commands/tablecmds.c:18533 #, c-format msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation." msgstr "Verwendet Sie ALTER TABLE ... DETACH PARTITION ... FINALIZE, um die unerledigte Abtrennoperation abzuschließen." @@ -9486,16 +9362,14 @@ msgid "cannot change data type of existing parameter default value" msgstr "kann Datentyp eines bestehenden Parametervorgabewerts nicht ändern" #: catalog/pg_proc.c:681 -#, fuzzy, c-format -#| msgid "view \"%s\" will be a temporary view" +#, c-format msgid "function \"%s\" will be effectively temporary" -msgstr "Sicht »%s« wird eine temporäre Sicht" +msgstr "Funktion »%s« wird effektiv temporär sein" #: catalog/pg_proc.c:683 commands/view.c:493 -#, fuzzy, c-format -#| msgid "%s depends on %s" +#, c-format msgid "It depends on temporary %s." -msgstr "%s hängt von %s ab" +msgstr "Sie hängt von temporärem %s ab." #: catalog/pg_proc.c:796 #, c-format @@ -9518,10 +9392,9 @@ msgid "SQL function \"%s\"" msgstr "SQL-Funktion »%s«" #: catalog/pg_publication.c:65 -#, fuzzy, c-format -#| msgid "cannot add relation \"%s\" to publication" +#, c-format msgid "cannot specify relation \"%s\" in the publication EXCEPT clause" -msgstr "Relation »%s« kann nicht zu Publikation hinzugefügt werden" +msgstr "Relation »%s« kann nicht in der EXCEPT-Klausel der Publikation angegeben werden" #: catalog/pg_publication.c:70 #, c-format @@ -9529,10 +9402,9 @@ msgid "cannot add relation \"%s\" to publication" msgstr "Relation »%s« kann nicht zu Publikation hinzugefügt werden" #: catalog/pg_publication.c:78 -#, fuzzy, c-format -#| msgid "This operation is not supported for partitioned tables." +#, c-format msgid "This operation is not supported for individual partitions." -msgstr "Diese Operation wird für partitionierte Tabellen nicht unterstützt." +msgstr "Diese Operation wird für einzelne Partitionen nicht unterstützt." #: catalog/pg_publication.c:93 #, c-format @@ -9662,32 +9534,30 @@ msgstr "kann Objekte, die %s gehören, nicht löschen, weil sie vom Datenbanksys msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" msgstr "kann den Eigentümer von den Objekten, die %s gehören, nicht ändern, weil die Objekte vom Datenbanksystem benötigt werden" -#: catalog/pg_subscription.c:70 commands/tablecmds.c:21005 +#: catalog/pg_subscription.c:70 commands/tablecmds.c:20995 #: replication/logical/relation.c:252 #, c-format msgid "\"%s\"" msgstr "»%s«" -#: catalog/pg_subscription.c:72 commands/tablecmds.c:21007 +#: catalog/pg_subscription.c:72 commands/tablecmds.c:20997 #: replication/logical/relation.c:254 -#, fuzzy, c-format -#| msgid "\"%s\"" +#, c-format msgid ", \"%s\"" -msgstr "»%s«" +msgstr ", »%s«" -#: catalog/pg_subscription.c:155 commands/subscriptioncmds.c:1935 -#: commands/subscriptioncmds.c:2291 -#, fuzzy, c-format -#| msgid "user mapping for \"%s\" does not exist for server \"%s\"" +#: catalog/pg_subscription.c:218 commands/subscriptioncmds.c:2020 +#: commands/subscriptioncmds.c:2379 +#, c-format msgid "subscription owner \"%s\" does not have permission on foreign server \"%s\"" -msgstr "Benutzerabbildung für »%s« existiert nicht für Server »%s«" +msgstr "Subskriptionseigentümer »%s« hat keine Berechtigung für Fremdserver »%s«" -#: catalog/pg_subscription.c:541 +#: catalog/pg_subscription.c:564 #, c-format msgid "could not drop relation mapping for subscription \"%s\"" msgstr "konnte Relation-Mapping für Subskription »%s« nicht löschen" -#: catalog/pg_subscription.c:543 +#: catalog/pg_subscription.c:566 #, c-format msgid "Table synchronization for relation \"%s\" is in progress and is in state \"%c\"." msgstr "Tabellensynchronisierung für Relation »%s« ist im Gang und hat Status »%c«." @@ -9695,7 +9565,7 @@ msgstr "Tabellensynchronisierung für Relation »%s« ist im Gang und hat Status #. translator: first %s is a SQL ALTER command and second %s is a #. SQL DROP command #. -#: catalog/pg_subscription.c:550 +#: catalog/pg_subscription.c:573 #, c-format msgid "Use %s to enable subscription if not already enabled or use %s to drop the subscription." msgstr "Verwenden Sie %s um die Subskription zu aktivieren, falls noch nicht aktiviert, oder %s um die Subskription zu löschen." @@ -9902,15 +9772,15 @@ msgid "must be superuser to rename %s" msgstr "nur Superuser können %s umbenennen" #: commands/alter.c:250 commands/subscriptioncmds.c:719 -#: commands/subscriptioncmds.c:1585 commands/subscriptioncmds.c:1660 -#: commands/subscriptioncmds.c:2682 +#: commands/subscriptioncmds.c:1678 commands/subscriptioncmds.c:1753 +#: commands/subscriptioncmds.c:2773 #, c-format msgid "password_required=false is superuser-only" msgstr "password_required=false ist nur für Superuser" #: commands/alter.c:251 commands/subscriptioncmds.c:720 -#: commands/subscriptioncmds.c:1586 commands/subscriptioncmds.c:1661 -#: commands/subscriptioncmds.c:2683 +#: commands/subscriptioncmds.c:1679 commands/subscriptioncmds.c:1754 +#: commands/subscriptioncmds.c:2774 #, c-format msgid "Subscriptions with the password_required option set to false may only be created or modified by the superuser." msgstr "Subskriptionen mit der Option password_required auf falsch gesetzt können nur vom Superuser erzeugt oder geändert werden." @@ -9948,16 +9818,15 @@ msgstr "keine Handler-Funktion angegeben" #: commands/amcmds.c:264 commands/event_trigger.c:206 #: commands/foreigncmds.c:500 commands/foreigncmds.c:548 commands/proclang.c:79 -#: commands/trigger.c:707 parser/parse_clause.c:1077 +#: commands/trigger.c:707 parser/parse_clause.c:1107 #, c-format msgid "function %s must return type %s" msgstr "Funktion %s muss Rückgabetyp %s haben" #: commands/analyze.c:245 -#, fuzzy, c-format -#| msgid "skipping \"%s\" --- cannot analyze this foreign table" +#, c-format msgid "skipping \"%s\" -- cannot analyze this foreign table." -msgstr "überspringe »%s« --- kann diese Fremdtabelle nicht analysieren" +msgstr "überspringe »%s« -- kann diese Fremdtabelle nicht analysieren." #: commands/analyze.c:263 #, c-format @@ -10007,7 +9876,7 @@ msgstr "überspringe Analysieren des Vererbungsbaums »%s.%s« --- dieser Vererb #: commands/async.c:631 #, c-format msgid "Could not access async queue at page %, offset %d." -msgstr "" +msgstr "Konnte auf Async-Queue bei Seite %, Offset %d nicht zugreifen." #: commands/async.c:915 #, c-format @@ -10055,14 +9924,14 @@ msgid "collation attribute \"%s\" not recognized" msgstr "Attribut »%s« für Sortierfolge unbekannt" #: commands/collationcmds.c:128 commands/collationcmds.c:134 -#: commands/define.c:374 commands/tablecmds.c:8502 +#: commands/define.c:374 commands/tablecmds.c:8498 #: replication/pgoutput/pgoutput.c:323 replication/pgoutput/pgoutput.c:346 #: replication/pgoutput/pgoutput.c:364 replication/pgoutput/pgoutput.c:374 #: replication/pgoutput/pgoutput.c:384 replication/pgoutput/pgoutput.c:394 #: replication/pgoutput/pgoutput.c:406 replication/walsender.c:1195 #: replication/walsender.c:1217 replication/walsender.c:1227 -#: replication/walsender.c:1236 replication/walsender.c:1487 -#: replication/walsender.c:1496 +#: replication/walsender.c:1236 replication/walsender.c:1489 +#: replication/walsender.c:1498 #, c-format msgid "conflicting or redundant options" msgstr "widersprüchliche oder überflüssige Optionen" @@ -10093,7 +9962,7 @@ msgstr "unbekannter Sortierfolgen-Provider: %s" msgid "parameter \"%s\" must be specified" msgstr "Parameter »%s« muss angegeben werden" -#: commands/collationcmds.c:298 commands/dbcommands.c:1189 +#: commands/collationcmds.c:298 commands/dbcommands.c:1215 #, c-format msgid "using standard form \"%s\" for ICU locale \"%s\"" msgstr "verwende Standardform »%s« für ICU-Locale »%s«" @@ -10103,7 +9972,7 @@ msgstr "verwende Standardform »%s« für ICU-Locale »%s«" msgid "nondeterministic collations not supported with this provider" msgstr "nichtdeterministische Sortierfolgen werden von diesem Provider nicht unterstützt" -#: commands/collationcmds.c:322 commands/dbcommands.c:1142 +#: commands/collationcmds.c:322 commands/dbcommands.c:1168 #, c-format msgid "ICU rules cannot be specified unless locale provider is ICU" msgstr "ICU-Regeln können nur angegeben werden, wenn der Locale-Provider ICU ist" @@ -10130,26 +9999,26 @@ msgstr "Version der Standardsortierfolge kann nicht aufgefrischt werden" #. translator: %s is an SQL command #. translator: %s is an SQL ALTER command -#: commands/collationcmds.c:448 commands/subscriptioncmds.c:2064 -#: commands/tablecmds.c:8254 commands/tablecmds.c:8264 -#: commands/tablecmds.c:8266 commands/tablecmds.c:16810 -#: commands/tablecmds.c:20334 commands/tablecmds.c:20355 +#: commands/collationcmds.c:448 commands/subscriptioncmds.c:2150 +#: commands/tablecmds.c:8250 commands/tablecmds.c:8260 +#: commands/tablecmds.c:8262 commands/tablecmds.c:16800 +#: commands/tablecmds.c:20324 commands/tablecmds.c:20345 #: commands/typecmds.c:3827 commands/typecmds.c:3912 commands/typecmds.c:4266 #, c-format msgid "Use %s instead." msgstr "Verwenden Sie stattdessen %s." -#: commands/collationcmds.c:481 commands/dbcommands.c:2628 +#: commands/collationcmds.c:481 commands/dbcommands.c:2658 #, c-format msgid "changing version from %s to %s" msgstr "Version wird von %s in %s geändert" -#: commands/collationcmds.c:496 commands/dbcommands.c:2641 +#: commands/collationcmds.c:496 commands/dbcommands.c:2671 #, c-format msgid "version has not changed" msgstr "Version hat sich nicht geändert" -#: commands/collationcmds.c:529 commands/dbcommands.c:2811 +#: commands/collationcmds.c:529 commands/dbcommands.c:2841 #: utils/adt/dbsize.c:180 utils/adt/ddlutils.c:677 #, c-format msgid "database with OID %u does not exist" @@ -10170,10 +10039,10 @@ msgstr "nur Superuser können Systemsortierfolgen importieren" msgid "no usable system locales were found" msgstr "keine brauchbaren System-Locales gefunden" -#: commands/comment.c:62 commands/dbcommands.c:1720 commands/dbcommands.c:1944 -#: commands/dbcommands.c:2056 commands/dbcommands.c:2254 -#: commands/dbcommands.c:2495 commands/dbcommands.c:2588 -#: commands/dbcommands.c:2712 commands/dbcommands.c:3223 +#: commands/comment.c:62 commands/dbcommands.c:1748 commands/dbcommands.c:1974 +#: commands/dbcommands.c:2086 commands/dbcommands.c:2284 +#: commands/dbcommands.c:2525 commands/dbcommands.c:2618 +#: commands/dbcommands.c:2742 commands/dbcommands.c:3253 #: utils/adt/regproc.c:1813 utils/init/postinit.c:1067 #: utils/init/postinit.c:1131 utils/init/postinit.c:1204 #, c-format @@ -10261,24 +10130,22 @@ msgid "Only roles with privileges of the \"%s\" role may COPY to a file." msgstr "Nur Rollen mit den Privilegien der Rolle »%s« können mit COPY in eine Datei schreiben." #: commands/copy.c:187 -#, fuzzy, c-format -#| msgid "generated columns are not supported in COPY FROM WHERE conditions" +#, c-format msgid "system columns are not supported in COPY FROM WHERE conditions" -msgstr "generierte Spalten werden in COPY-FROM-WHERE-Bedingungen nicht unterstützt" +msgstr "Systemspalten werden in COPY-FROM-WHERE-Bedingungen nicht unterstützt" #: commands/copy.c:188 -#, fuzzy, c-format -#| msgid "Column \"%s\" is a generated column." +#, c-format msgid "Column \"%s\" is a system column." -msgstr "Spalte »%s« ist eine generierte Spalte." +msgstr "Spalte »%s« ist eine Systemspalte." #: commands/copy.c:202 #, c-format msgid "generated columns are not supported in COPY FROM WHERE conditions" msgstr "generierte Spalten werden in COPY-FROM-WHERE-Bedingungen nicht unterstützt" -#: commands/copy.c:203 commands/tablecmds.c:14910 commands/tablecmds.c:20481 -#: commands/tablecmds.c:20563 commands/trigger.c:661 +#: commands/copy.c:203 commands/tablecmds.c:14900 commands/tablecmds.c:20471 +#: commands/tablecmds.c:20553 commands/trigger.c:661 #: rewrite/rewriteHandler.c:1001 rewrite/rewriteHandler.c:1036 #, c-format msgid "Column \"%s\" is a generated column." @@ -10302,22 +10169,19 @@ msgstr "»%s« kann nicht mit HEADER in COPY TO verwendet werden" #. translator: first %s is the name of a COPY option, e.g. ON_ERROR, #. second %s is the special value "match" for that option #: commands/copy.c:452 -#, fuzzy, c-format -#| msgid "remainder for hash partition must be an integer value greater than or equal to zero" +#, c-format msgid "%s requires a Boolean value, an integer value greater than or equal to zero, or the string \"%s\"" -msgstr "Rest für Hashpartition muss eine ganze Zahl größer als oder gleich null sein" +msgstr "%s benötigt einen Boole’schen Wert, eine ganze Zahl größer als oder gleich null oder die Zeichenkette »%s«" #: commands/copy.c:464 -#, fuzzy, c-format -#| msgid "type modifier cannot be specified for shell type \"%s\"" +#, c-format msgid "a negative integer value cannot be specified for %s" -msgstr "Typmodifikator kann für Hüllentyp »%s« nicht angegeben werden" +msgstr "ein negativer ganzzahliger Wert kann für %s nicht angegeben werden" #: commands/copy.c:470 -#, fuzzy, c-format -#| msgid "cannot exit pipeline mode while in COPY" +#, c-format msgid "cannot use multi-line header in COPY TO" -msgstr "kann Pipeline-Modus nicht beenden während COPY aktiv ist" +msgstr "mehrzeiliger Header kann in COPY TO nicht verwendet werden" #. translator: first %s is the name of a COPY option, e.g. ON_ERROR, #. second %s is a COPY with direction, e.g. COPY TO @@ -10361,7 +10225,7 @@ msgstr "Argument von Option »%s« muss eine Liste aus Spaltennamen sein" msgid "argument to option \"%s\" must be a valid encoding name" msgstr "Argument von Option »%s« muss ein gültiger Kodierungsname sein" -#: commands/copy.c:780 commands/dbcommands.c:889 commands/dbcommands.c:2443 +#: commands/copy.c:780 commands/dbcommands.c:907 commands/dbcommands.c:2473 #: commands/wait.c:144 #, c-format msgid "option \"%s\" not recognized" @@ -10375,10 +10239,9 @@ msgstr "%s kann nicht im BINARY-Modus angegeben werden" #: commands/copy.c:796 commands/copy.c:805 commands/copy.c:814 #: commands/copy.c:888 -#, fuzzy, c-format -#| msgid "cannot specify %s in BINARY mode" +#, c-format msgid "cannot specify %s in JSON mode" -msgstr "%s kann nicht im BINARY-Modus angegeben werden" +msgstr "%s kann nicht im JSON-Modus angegeben werden" #: commands/copy.c:836 #, c-format @@ -10440,16 +10303,14 @@ msgid "CSV quote character must not appear in the %s specification" msgstr "CSV-Quote-Zeichen darf nicht in der %s-Darstellung erscheinen" #: commands/copy.c:996 -#, fuzzy, c-format -#| msgid "unit \"%s\" not supported for type %s" +#, c-format msgid "COPY %s is not supported for %s" -msgstr "Einheit »%s« nicht unterstützt für Typ %s" +msgstr "COPY %s wird für %s nicht unterstützt" #: commands/copy.c:1001 -#, fuzzy, c-format -#| msgid "COPY %s cannot be used with %s" +#, c-format msgid "COPY %s can only be used with JSON mode" -msgstr "COPY %s kann nicht mit %s verwendet werden" +msgstr "COPY %s kann nur mit JSON-Modus verwendet werden" #: commands/copy.c:1036 #, c-format @@ -10582,13 +10443,11 @@ msgstr[0] "% Zeile wurde übersprungen wegen Datentypinkompatibilität" msgstr[1] "% Zeilen wurden übersprungen wegen Datentypinkompatibilität" #: commands/copyfrom.c:1479 -#, fuzzy, c-format -#| msgid "% row was skipped due to data type incompatibility" -#| msgid_plural "% rows were skipped due to data type incompatibility" +#, c-format msgid "in % row, columns were set to null due to data type incompatibility" msgid_plural "in % rows, columns were set to null due to data type incompatibility" -msgstr[0] "% Zeile wurde übersprungen wegen Datentypinkompatibilität" -msgstr[1] "% Zeilen wurden übersprungen wegen Datentypinkompatibilität" +msgstr[0] "in % Zeile wurden Spalten wegen Datentypinkompatibilität auf NULL gesetzt" +msgstr[1] "in % Zeilen wurden Spalten wegen Datentypinkompatibilität auf NULL gesetzt" #. translator: first %s is the name of a COPY option, e.g. FORCE_NOT_NULL #. translator: %s is the name of a COPY option, e.g. FORCE_NOT_NULL @@ -10708,7 +10567,7 @@ msgstr "Domäne %s erlaubt keine NULL-Werte" #: commands/copyfromparse.c:1089 #, c-format msgid "ON_ERROR SET_NULL cannot be applied because column \"%s\" (domain %s) does not accept null values." -msgstr "" +msgstr "ON_ERROR SET_NULL kann nicht angewendet werden, weil Spalte »%s« (Domäne %s) keine NULL-Werte annimmt." #: commands/copyfromparse.c:1123 #, c-format @@ -10716,10 +10575,9 @@ msgid "skipping row due to data type incompatibility at line % for colum msgstr "Zeile wird übersprungen wegen Datentypinkompatibilität auf Zeile % für Spalte »%s«: »%s«" #: commands/copyfromparse.c:1129 -#, fuzzy, c-format -#| msgid "skipping row due to data type incompatibility at line % for column \"%s\": \"%s\"" +#, c-format msgid "setting to null due to data type incompatibility at line % for column \"%s\": \"%s\"" -msgstr "Zeile wird übersprungen wegen Datentypinkompatibilität auf Zeile % für Spalte »%s«: »%s«" +msgstr "wird auf NULL gesetzt wegen Datentypinkompatibilität auf Zeile % für Spalte »%s«: »%s«" #: commands/copyfromparse.c:1139 #, c-format @@ -10858,10 +10716,9 @@ msgid "cannot copy from sequence \"%s\"" msgstr "kann nicht aus Sequenz »%s« kopieren" #: commands/copyto.c:859 -#, fuzzy, c-format -#| msgid "partition \"%s\" already pending detach in partitioned table \"%s.%s\"" -msgid "Partition \"%s\" is a foreign table in partitioned table \"%s\"" -msgstr "Partition »%s« hat schon eine unerledigte Abtrennoperation in der partitionierten Tabelle »%s.%s«" +#, c-format +msgid "Partition \"%s\" is a foreign table in partitioned table \"%s\"." +msgstr "Partition »%s« ist eine Fremdtabelle in partitionierter Tabelle »%s«." #: commands/copyto.c:872 #, c-format @@ -10933,400 +10790,399 @@ msgstr "zu viele Spaltennamen wurden angegeben" msgid "policies not yet implemented for this command" msgstr "Policys sind für diesen Befehl noch nicht implementiert" -#: commands/dbcommands.c:751 commands/dbcommands.c:1932 -#, fuzzy, c-format -#| msgid "database name contains a newline or carriage return: \"%s\"\n" +#: commands/dbcommands.c:571 commands/dbcommands.c:1077 +#, c-format +msgid "create database strategy \"%s\" not allowed when data checksums are being enabled" +msgstr "Datenbankerzeugungsstrategie »%s« nicht erlaubt, während Datenprüfsummen eingeschaltet werden" + +#: commands/dbcommands.c:769 commands/dbcommands.c:1962 +#, c-format msgid "database name \"%s\" contains a newline or carriage return character" -msgstr "Datenbankname enthält Newline oder Carriage Return: »%s«\n" +msgstr "Datenbankname »%s« enthält Newline- oder Carriage-Return-Zeichen" -#: commands/dbcommands.c:852 +#: commands/dbcommands.c:870 #, c-format msgid "LOCATION is not supported anymore" msgstr "LOCATION wird nicht mehr unterstützt" -#: commands/dbcommands.c:853 +#: commands/dbcommands.c:871 #, c-format msgid "Consider using tablespaces instead." msgstr "Verwenden Sie stattdessen Tablespaces." -#: commands/dbcommands.c:878 +#: commands/dbcommands.c:896 #, c-format msgid "OIDs less than %u are reserved for system objects" msgstr "OIDs kleiner als %u sind für Systemobjekte reserviert" -#: commands/dbcommands.c:909 utils/adt/ascii.c:146 +#: commands/dbcommands.c:927 utils/adt/ascii.c:146 #, c-format msgid "%d is not a valid encoding code" msgstr "%d ist kein gültiger Kodierungscode" -#: commands/dbcommands.c:920 utils/adt/ascii.c:128 +#: commands/dbcommands.c:938 utils/adt/ascii.c:128 #, c-format msgid "%s is not a valid encoding name" msgstr "%s ist kein gültiger Kodierungsname" -#: commands/dbcommands.c:954 +#: commands/dbcommands.c:972 #, c-format msgid "unrecognized locale provider: %s" msgstr "unbekannter Locale-Provider: %s" -#: commands/dbcommands.c:967 commands/dbcommands.c:2476 commands/user.c:306 +#: commands/dbcommands.c:985 commands/dbcommands.c:2506 commands/user.c:306 #: commands/user.c:746 #, c-format msgid "invalid connection limit: %d" msgstr "ungültige Verbindungshöchstgrenze: %d" -#: commands/dbcommands.c:988 +#: commands/dbcommands.c:1006 #, c-format msgid "permission denied to create database" msgstr "keine Berechtigung, um Datenbank zu erzeugen" -#: commands/dbcommands.c:1012 +#: commands/dbcommands.c:1030 #, c-format msgid "template database \"%s\" does not exist" msgstr "Template-Datenbank »%s« existiert nicht" -#: commands/dbcommands.c:1022 +#: commands/dbcommands.c:1040 #, c-format msgid "cannot use invalid database \"%s\" as template" msgstr "ungültige Datenbank »%s« kann nicht als Template verwendet werden" -#: commands/dbcommands.c:1023 commands/dbcommands.c:2506 -#: utils/init/postinit.c:1146 +#: commands/dbcommands.c:1041 commands/dbcommands.c:2536 +#: postmaster/datachecksum_state.c:1493 utils/init/postinit.c:1146 #, c-format msgid "Use DROP DATABASE to drop invalid databases." msgstr "Verwenden Sie DROP DATABASE, um ungültige Datenbanken zu löschen." -#: commands/dbcommands.c:1034 +#: commands/dbcommands.c:1052 #, c-format msgid "permission denied to copy database \"%s\"" msgstr "keine Berechtigung, um Datenbank »%s« zu kopieren" -#: commands/dbcommands.c:1051 -#, c-format -msgid "create database strategy \"%s\" not allowed when data checksums are being enabled" -msgstr "" - -#: commands/dbcommands.c:1058 +#: commands/dbcommands.c:1084 #, c-format msgid "invalid create database strategy \"%s\"" msgstr "ungültige Datenbankerzeugungsstrategie »%s«" -#: commands/dbcommands.c:1059 +#: commands/dbcommands.c:1085 #, c-format msgid "Valid strategies are \"wal_log\" and \"file_copy\"." msgstr "Gültige Strategien sind »wal_log« und »file_copy«." -#: commands/dbcommands.c:1080 +#: commands/dbcommands.c:1106 #, c-format msgid "invalid server encoding %d" msgstr "ungültige Serverkodierung %d" -#: commands/dbcommands.c:1088 commands/dbcommands.c:1093 -#: commands/dbcommands.c:1098 +#: commands/dbcommands.c:1114 commands/dbcommands.c:1119 +#: commands/dbcommands.c:1124 #, c-format msgid "invalid LC_COLLATE locale name: \"%s\"" msgstr "ungültiger LC_COLLATE-Locale-Name: »%s«" -#: commands/dbcommands.c:1089 commands/dbcommands.c:1107 +#: commands/dbcommands.c:1115 commands/dbcommands.c:1133 #, c-format msgid "If the locale name is specific to the builtin provider, use BUILTIN_LOCALE." msgstr "Wenn der Locale-Name nur für den Provider »builtin« gültig ist, verwenden Sie BUILTIN_LOCALE." -#: commands/dbcommands.c:1094 commands/dbcommands.c:1112 +#: commands/dbcommands.c:1120 commands/dbcommands.c:1138 #, c-format msgid "If the locale name is specific to the ICU provider, use ICU_LOCALE." msgstr "Wenn der Locale-Name nur für den ICU-Provider gültig ist, verwenden Sie ICU_LOCALE." -#: commands/dbcommands.c:1106 commands/dbcommands.c:1111 -#: commands/dbcommands.c:1116 +#: commands/dbcommands.c:1132 commands/dbcommands.c:1137 +#: commands/dbcommands.c:1142 #, c-format msgid "invalid LC_CTYPE locale name: \"%s\"" msgstr "ungültiger LC_CTYPE-Locale-Name: »%s«" -#: commands/dbcommands.c:1129 +#: commands/dbcommands.c:1155 #, c-format msgid "BUILTIN_LOCALE cannot be specified unless locale provider is builtin" msgstr "BUILTIN_LOCALE kann nur angegeben werden, wenn der Locale-Provider »builtin« ist" -#: commands/dbcommands.c:1137 +#: commands/dbcommands.c:1163 #, c-format msgid "ICU locale cannot be specified unless locale provider is ICU" msgstr "ICU-Locale kann nur angegeben werden, wenn der Locale-Provider ICU ist" -#: commands/dbcommands.c:1155 +#: commands/dbcommands.c:1181 #, c-format msgid "LOCALE or BUILTIN_LOCALE must be specified" msgstr "LOCALE oder BUILTIN_LOCALE muss angegeben werden" -#: commands/dbcommands.c:1164 +#: commands/dbcommands.c:1190 #, c-format msgid "encoding \"%s\" is not supported with ICU provider" msgstr "Kodierung »%s« wird vom ICU-Provider nicht unterstützt" -#: commands/dbcommands.c:1174 +#: commands/dbcommands.c:1200 #, c-format msgid "LOCALE or ICU_LOCALE must be specified" msgstr "LOCALE oder ICU_LOCALE muss angegeben werden" -#: commands/dbcommands.c:1218 +#: commands/dbcommands.c:1244 #, c-format msgid "new encoding (%s) is incompatible with the encoding of the template database (%s)" msgstr "neue Kodierung (%s) ist inkompatibel mit der Kodierung der Template-Datenbank (%s)" -#: commands/dbcommands.c:1221 +#: commands/dbcommands.c:1247 #, c-format msgid "Use the same encoding as in the template database, or use template0 as template." msgstr "Verwenden Sie die gleiche Kodierung wie die Template-Datenbank oder verwenden Sie template0 als Template." -#: commands/dbcommands.c:1226 +#: commands/dbcommands.c:1252 #, c-format msgid "new collation (%s) is incompatible with the collation of the template database (%s)" msgstr "neue Sortierreihenfolge (%s) ist inkompatibel mit der Sortierreihenfolge der Template-Datenbank (%s)" -#: commands/dbcommands.c:1228 +#: commands/dbcommands.c:1254 #, c-format msgid "Use the same collation as in the template database, or use template0 as template." msgstr "Verwenden Sie die gleiche Sortierreihenfolge wie die Template-Datenbank oder verwenden Sie template0 als Template." -#: commands/dbcommands.c:1233 +#: commands/dbcommands.c:1259 #, c-format msgid "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)" msgstr "neues LC_CTYPE (%s) ist inkompatibel mit dem LC_CTYPE der Template-Datenbank (%s)" -#: commands/dbcommands.c:1235 +#: commands/dbcommands.c:1261 #, c-format msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." msgstr "Verwenden Sie das gleiche LC_CTYPE wie die Template-Datenbank oder verwenden Sie template0 als Template." -#: commands/dbcommands.c:1240 +#: commands/dbcommands.c:1266 #, c-format msgid "new locale provider (%s) does not match locale provider of the template database (%s)" msgstr "neuer Locale-Provider (%s) stimmt nicht mit dem Locale-Provider der Template-Datenbank (%s) überein" -#: commands/dbcommands.c:1242 +#: commands/dbcommands.c:1268 #, c-format msgid "Use the same locale provider as in the template database, or use template0 as template." msgstr "Verwenden Sie den gleichen Locale-Provider wie die Template-Datenbank oder verwenden Sie template0 als Template." -#: commands/dbcommands.c:1254 +#: commands/dbcommands.c:1280 #, c-format msgid "new ICU locale (%s) is incompatible with the ICU locale of the template database (%s)" msgstr "neue ICU-Locale (%s) ist inkompatibel mit der ICU-Locale der Template-Datenbank (%s)" -#: commands/dbcommands.c:1256 +#: commands/dbcommands.c:1282 #, c-format msgid "Use the same ICU locale as in the template database, or use template0 as template." msgstr "Verwenden Sie die gleiche ICU-Locale wie die Template-Datenbank oder verwenden Sie template0 als Template." -#: commands/dbcommands.c:1267 +#: commands/dbcommands.c:1293 #, c-format msgid "new ICU collation rules (%s) are incompatible with the ICU collation rules of the template database (%s)" msgstr "die neuen ICU-Sortierfolgenregeln (%s) sind inkompatibel mit den ICU-Sortierfolgenregeln der Template-Datenbank (%s)" -#: commands/dbcommands.c:1269 +#: commands/dbcommands.c:1295 #, c-format msgid "Use the same ICU collation rules as in the template database, or use template0 as template." msgstr "Verwenden Sie die gleichen ICU-Sortierfolgenregeln wie in der Template-Datenbank oder verwenden Sie template0 als Template." -#: commands/dbcommands.c:1298 +#: commands/dbcommands.c:1324 #, c-format msgid "template database \"%s\" has a collation version, but no actual collation version could be determined" msgstr "Template-Datenbank »%s« hat eine Sortierfolgenversion, aber keine tatsächliche Sortierfolgenversion konnte ermittelt werden" -#: commands/dbcommands.c:1303 +#: commands/dbcommands.c:1329 #, c-format msgid "template database \"%s\" has a collation version mismatch" msgstr "Version von Sortierfolge für Template-Datenbank »%s« stimmt nicht überein" -#: commands/dbcommands.c:1305 +#: commands/dbcommands.c:1331 #, c-format msgid "The template database was created using collation version %s, but the operating system provides version %s." msgstr "Die Template-Datenbank wurde mit Sortierfolgenversion %s erzeugt, aber das Betriebssystem hat Version %s." -#: commands/dbcommands.c:1308 +#: commands/dbcommands.c:1334 #, c-format msgid "Rebuild all objects in the template database that use the default collation and run ALTER DATABASE %s REFRESH COLLATION VERSION, or build PostgreSQL with the right library version." msgstr "Bauen Sie alle Objekte in der Template-Datenbank, die die Standardsortierfolge verwenden, neu und führen Sie ALTER DATABASE %s REFRESH COLLATION VERSION aus, oder bauen Sie PostgreSQL mit der richtigen Bibliotheksversion." -#: commands/dbcommands.c:1353 commands/dbcommands.c:2102 +#: commands/dbcommands.c:1379 commands/dbcommands.c:2132 #, c-format msgid "pg_global cannot be used as default tablespace" msgstr "pg_global kann nicht als Standard-Tablespace verwendet werden" -#: commands/dbcommands.c:1379 +#: commands/dbcommands.c:1405 #, c-format msgid "cannot assign new default tablespace \"%s\"" msgstr "kann neuen Standard-Tablespace »%s« nicht setzen" -#: commands/dbcommands.c:1381 +#: commands/dbcommands.c:1407 #, c-format msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." msgstr "Es gibt einen Konflikt, weil Datenbank »%s« schon einige Tabellen in diesem Tablespace hat." -#: commands/dbcommands.c:1411 commands/dbcommands.c:1973 +#: commands/dbcommands.c:1437 commands/dbcommands.c:2003 #, c-format msgid "database \"%s\" already exists" msgstr "Datenbank »%s« existiert bereits" -#: commands/dbcommands.c:1425 +#: commands/dbcommands.c:1451 #, c-format msgid "source database \"%s\" is being accessed by other users" msgstr "auf Quelldatenbank »%s« wird gerade von anderen Benutzern zugegriffen" -#: commands/dbcommands.c:1447 +#: commands/dbcommands.c:1473 #, c-format msgid "database OID %u is already in use by database \"%s\"" msgstr "Datenbank-OID %u wird bereits von Datenbank »%s« verwendet" -#: commands/dbcommands.c:1453 +#: commands/dbcommands.c:1479 #, c-format msgid "data directory with the specified OID %u already exists" msgstr "Datenverzeichnis mit der angegebenen OID %u existiert bereits" -#: commands/dbcommands.c:1626 commands/dbcommands.c:1641 +#: commands/dbcommands.c:1654 commands/dbcommands.c:1669 #: utils/adt/pg_locale.c:1713 #, c-format msgid "encoding \"%s\" does not match locale \"%s\"" msgstr "Kodierung »%s« stimmt nicht mit Locale »%s« überein" -#: commands/dbcommands.c:1629 +#: commands/dbcommands.c:1657 #, c-format msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." msgstr "Die gewählte LC_CTYPE-Einstellung verlangt die Kodierung »%s«." -#: commands/dbcommands.c:1644 +#: commands/dbcommands.c:1672 #, c-format msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." msgstr "Die gewählte LC_COLLATE-Einstellung verlangt die Kodierung »%s«." -#: commands/dbcommands.c:1727 +#: commands/dbcommands.c:1755 #, c-format msgid "database \"%s\" does not exist, skipping" msgstr "Datenbank »%s« existiert nicht, wird übersprungen" -#: commands/dbcommands.c:1751 +#: commands/dbcommands.c:1779 #, c-format msgid "cannot drop a template database" msgstr "Template-Datenbank kann nicht gelöscht werden" -#: commands/dbcommands.c:1757 +#: commands/dbcommands.c:1785 #, c-format msgid "cannot drop the currently open database" msgstr "kann aktuell geöffnete Datenbank nicht löschen" -#: commands/dbcommands.c:1770 +#: commands/dbcommands.c:1798 #, c-format msgid "database \"%s\" is used by an active logical replication slot" msgstr "Datenbank »%s« wird von einem aktiven logischen Replikations-Slot verwendet" -#: commands/dbcommands.c:1772 +#: commands/dbcommands.c:1800 #, c-format msgid "There is %d active slot." msgid_plural "There are %d active slots." msgstr[0] "%d Slot ist vorhanden." msgstr[1] "%d Slots sind vorhanden." -#: commands/dbcommands.c:1786 +#: commands/dbcommands.c:1814 #, c-format msgid "database \"%s\" is being used by logical replication subscription" msgstr "Datenbank »%s« wird von einer Subskription für logische Replikation verwendet" -#: commands/dbcommands.c:1788 +#: commands/dbcommands.c:1816 #, c-format msgid "There is %d subscription." msgid_plural "There are %d subscriptions." msgstr[0] "%d Subskription ist vorhanden." msgstr[1] "%d Subskriptionen sind vorhanden." -#: commands/dbcommands.c:1809 commands/dbcommands.c:1995 -#: commands/dbcommands.c:2124 +#: commands/dbcommands.c:1837 commands/dbcommands.c:2025 +#: commands/dbcommands.c:2154 #, c-format msgid "database \"%s\" is being accessed by other users" msgstr "auf Datenbank »%s« wird von anderen Benutzern zugegriffen" -#: commands/dbcommands.c:1955 +#: commands/dbcommands.c:1985 #, c-format msgid "permission denied to rename database" msgstr "keine Berechtigung, um Datenbank umzubenennen" -#: commands/dbcommands.c:1984 +#: commands/dbcommands.c:2014 #, c-format msgid "current database cannot be renamed" msgstr "aktuelle Datenbank kann nicht umbenannt werden" -#: commands/dbcommands.c:2080 +#: commands/dbcommands.c:2110 #, c-format msgid "cannot change the tablespace of the currently open database" msgstr "kann den Tablespace der aktuell geöffneten Datenbank nicht ändern" -#: commands/dbcommands.c:2186 +#: commands/dbcommands.c:2216 #, c-format msgid "some relations of database \"%s\" are already in tablespace \"%s\"" msgstr "einige Relationen von Datenbank »%s« ist bereits in Tablespace »%s«" -#: commands/dbcommands.c:2188 +#: commands/dbcommands.c:2218 #, c-format msgid "You must move them back to the database's default tablespace before using this command." msgstr "Sie müssen sie zurück in den Standard-Tablespace der Datenbank verschieben, bevor Sie diesen Befehl verwenden können." -#: commands/dbcommands.c:2317 commands/dbcommands.c:3061 -#: commands/dbcommands.c:3337 commands/dbcommands.c:3451 +#: commands/dbcommands.c:2347 commands/dbcommands.c:3091 +#: commands/dbcommands.c:3367 commands/dbcommands.c:3481 #, c-format msgid "some useless files may be left behind in old database directory \"%s\"" msgstr "einige nutzlose Dateien wurde möglicherweise im alten Datenbankverzeichnis »%s« zurückgelassen" -#: commands/dbcommands.c:2378 commands/explain_state.c:170 +#: commands/dbcommands.c:2408 commands/explain_state.c:170 #: commands/indexcmds.c:2874 commands/repack.c:281 commands/vacuum.c:236 #: commands/vacuum.c:299 postmaster/checkpointer.c:1031 #, c-format msgid "unrecognized %s option \"%s\"" msgstr "unbekannte %s-Option »%s«" -#: commands/dbcommands.c:2457 +#: commands/dbcommands.c:2487 #, c-format msgid "option \"%s\" cannot be specified with other options" msgstr "Option »%s« kann nicht mit anderen Optionen angegeben werden" -#: commands/dbcommands.c:2505 +#: commands/dbcommands.c:2535 #, c-format msgid "cannot alter invalid database \"%s\"" msgstr "ungültige Datenbank »%s« kann nicht geändert werden" -#: commands/dbcommands.c:2522 +#: commands/dbcommands.c:2552 #, c-format msgid "cannot disallow connections for current database" msgstr "Verbindungen mit der aktuellen Datenbank können nicht verboten werden" -#: commands/dbcommands.c:2752 +#: commands/dbcommands.c:2782 #, c-format msgid "permission denied to change owner of database" msgstr "keine Berechtigung, um Eigentümer der Datenbank zu ändern" -#: commands/dbcommands.c:3167 +#: commands/dbcommands.c:3197 #, c-format msgid "There are %d other session(s) and %d prepared transaction(s) using the database." msgstr "%d andere Sitzung(en) und %d vorbereitete Transaktion(en) verwenden die Datenbank." -#: commands/dbcommands.c:3170 +#: commands/dbcommands.c:3200 #, c-format msgid "There is %d other session using the database." msgid_plural "There are %d other sessions using the database." msgstr[0] "%d andere Sitzung verwendet die Datenbank." msgstr[1] "%d andere Sitzungen verwenden die Datenbank." -#: commands/dbcommands.c:3175 storage/ipc/procarray.c:3867 +#: commands/dbcommands.c:3205 storage/ipc/procarray.c:3867 #, c-format msgid "There is %d prepared transaction using the database." msgid_plural "There are %d prepared transactions using the database." msgstr[0] "%d vorbereitete Transaktion verwendet die Datenbank." msgstr[1] "%d vorbereitete Transaktionen verwenden die Datenbank." -#: commands/dbcommands.c:3293 +#: commands/dbcommands.c:3323 #, c-format msgid "missing directory \"%s\"" msgstr "Verzeichnis »%s« fehlt" -#: commands/dbcommands.c:3351 commands/tablespace.c:186 +#: commands/dbcommands.c:3381 commands/tablespace.c:186 #: commands/tablespace.c:641 #, c-format msgid "could not stat directory \"%s\": %m" @@ -11364,7 +11220,7 @@ msgid "invalid argument for %s: \"%s\"" msgstr "ungültiges Argument für %s: »%s«" #: commands/dropcmds.c:96 commands/functioncmds.c:1403 -#: utils/adt/ruleutils.c:3316 +#: utils/adt/ruleutils.c:3317 #, c-format msgid "\"%s\" is an aggregate function" msgstr "»%s« ist eine Aggregatfunktion" @@ -11374,9 +11230,9 @@ msgstr "»%s« ist eine Aggregatfunktion" msgid "Use DROP AGGREGATE to drop aggregate functions." msgstr "Verwenden Sie DROP AGGREGATE, um Aggregatfunktionen zu löschen." -#: commands/dropcmds.c:153 commands/propgraphcmds.c:1312 +#: commands/dropcmds.c:153 commands/propgraphcmds.c:1343 #: commands/sequence.c:457 commands/tablecmds.c:4089 commands/tablecmds.c:4250 -#: commands/tablecmds.c:4302 commands/tablecmds.c:19606 tcop/utility.c:1331 +#: commands/tablecmds.c:4302 commands/tablecmds.c:19596 tcop/utility.c:1331 #, c-format msgid "relation \"%s\" does not exist, skipping" msgstr "Relation »%s« existiert nicht, wird übersprungen" @@ -11616,16 +11472,14 @@ msgid "%s options %s and %s cannot be used together" msgstr "%s-Optionen %s und %s können nicht zusammen verwendet werden" #: commands/explain_state.c:427 -#, fuzzy, c-format -#| msgid "unrecognized %s option \"%s\"" +#, c-format msgid "unrecognized EXPLAIN option \"%s\"" -msgstr "unbekannte %s-Option »%s«" +msgstr "unbekannte EXPLAIN-Option »%s«" #: commands/explain_state.c:492 -#, fuzzy, c-format -#| msgid "parameter \"%s\" requires a Boolean value" +#, c-format msgid "EXPLAIN option \"%s\" requires a Boolean value" -msgstr "Parameter »%s« erfordert einen Boole’schen Wert" +msgstr "EXPLAIN-Option »%s« erfordert einen Boole’schen Wert" #: commands/extension.c:239 commands/extension.c:3517 #, c-format @@ -11887,8 +11741,8 @@ msgstr "Erweiterung »%s« verhindert Verlagerung von Erweiterung »%s«." #: commands/extension.c:3436 #, c-format -msgid "%s is not in the extension's schema \"%s\"" -msgstr "%s ist nicht im Schema der Erweiterung (»%s«)" +msgid "%s is not in the extension's schema \"%s\"." +msgstr "%s ist nicht im Schema der Erweiterung (»%s«)." #: commands/extension.c:3497 #, c-format @@ -11950,7 +11804,7 @@ msgstr "Nur Superuser können den Eigentümer eines Fremddaten-Wrappers ändern. msgid "The owner of a foreign-data wrapper must be a superuser." msgstr "Der Eigentümer eines Fremddaten-Wrappers muss ein Superuser sein." -#: commands/foreigncmds.c:302 commands/foreigncmds.c:771 foreign/foreign.c:723 +#: commands/foreigncmds.c:302 commands/foreigncmds.c:771 foreign/foreign.c:735 #, c-format msgid "foreign-data wrapper \"%s\" does not exist" msgstr "Fremddaten-Wrapper »%s« existiert nicht" @@ -11996,16 +11850,14 @@ msgid "changing the foreign-data wrapper validator can cause the options for dep msgstr "durch Ändern des Validators des Fremddaten-Wrappers können die Optionen von abhängigen Objekten ungültig werden" #: commands/foreigncmds.c:840 -#, fuzzy, c-format -#| msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" +#, c-format msgid "changing the foreign-data wrapper connection function can cause the options for dependent objects to become invalid" -msgstr "durch Ändern des Validators des Fremddaten-Wrappers können die Optionen von abhängigen Objekten ungültig werden" +msgstr "durch Ändern der Verbindungsfunktion des Fremddaten-Wrappers können die Optionen von abhängigen Objekten ungültig werden" #: commands/foreigncmds.c:844 -#, fuzzy, c-format -#| msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" +#, c-format msgid "removing the foreign-data wrapper connection function will cause dependent subscriptions to fail" -msgstr "durch Ändern des Validators des Fremddaten-Wrappers können die Optionen von abhängigen Objekten ungültig werden" +msgstr "durch Entfernen der Verbindungsfunktion des Fremddaten-Wrappers werden abhängige Subskriptionen fehlschlagen" #: commands/foreigncmds.c:982 #, c-format @@ -12032,7 +11884,7 @@ msgstr "Benutzerabbildung für »%s« existiert nicht für Server »%s«" msgid "user mapping for \"%s\" does not exist for server \"%s\", skipping" msgstr "Benutzerabbildung für »%s« existiert nicht für Server »%s«, wird übersprungen" -#: commands/foreigncmds.c:1613 foreign/foreign.c:436 +#: commands/foreigncmds.c:1613 foreign/foreign.c:448 #, c-format msgid "foreign-data wrapper \"%s\" has no handler" msgstr "Fremddaten-Wrapper »%s« hat keinen Handler" @@ -12446,7 +12298,7 @@ msgid "cannot specify default tablespace for partitioned relations" msgstr "für partitionierte Relationen kann kein Standard-Tablespace angegeben werden" #: commands/indexcmds.c:822 commands/tablecmds.c:978 commands/tablecmds.c:3785 -#: commands/tablecmds.c:23210 +#: commands/tablecmds.c:23200 #, c-format msgid "only shared relations can be placed in pg_global tablespace" msgstr "nur geteilte Relationen können in den Tablespace »pg_global« gelegt werden" @@ -12513,10 +12365,9 @@ msgstr "Partitionierungsschlüssel kann nicht mit Nicht-Ist-Gleich-Operator »%s #. translator: %s is UNIQUE, PRIMARY KEY, etc #: commands/indexcmds.c:1098 -#, fuzzy, c-format -#| msgid "unique constraint on partitioned table must include all partitioning columns" +#, c-format msgid "%s constraint on partitioned table must include all partitioning columns" -msgstr "Unique-Constraint für partitionierte Tabelle muss alle Partitionierungsspalten enthalten" +msgstr "%s-Constraint für partitionierte Tabelle muss alle Partitionierungsspalten enthalten" #. translator: first %s is UNIQUE, PRIMARY KEY, etc #: commands/indexcmds.c:1101 @@ -12600,7 +12451,7 @@ msgstr "inkludierte Spalte unterstützt die Optionen NULLS FIRST/LAST nicht" msgid "could not determine which collation to use for index expression" msgstr "konnte die für den Indexausdruck zu verwendende Sortierfolge nicht bestimmen" -#: commands/indexcmds.c:2118 commands/tablecmds.c:20651 commands/typecmds.c:814 +#: commands/indexcmds.c:2118 commands/tablecmds.c:20641 commands/typecmds.c:814 #: parser/parse_expr.c:2837 parser/parse_type.c:568 parser/parse_utilcmd.c:4389 #: utils/adt/misc.c:603 #, c-format @@ -12637,8 +12488,8 @@ msgstr "Zugriffsmethode »%s« unterstützt die Optionen ASC/DESC nicht" msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "Zugriffsmethode »%s« unterstützt die Optionen NULLS FIRST/LAST nicht" -#: commands/indexcmds.c:2303 commands/tablecmds.c:20676 -#: commands/tablecmds.c:20682 commands/typecmds.c:2381 parser/analyze.c:1505 +#: commands/indexcmds.c:2303 commands/tablecmds.c:20666 +#: commands/tablecmds.c:20672 commands/typecmds.c:2381 parser/analyze.c:1505 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" msgstr "Datentyp %s hat keine Standardoperatorklasse für Zugriffsmethode »%s«" @@ -12674,7 +12525,7 @@ msgstr "konnte keinen Überlappungsoperator für Typ %s ermitteln" msgid "could not identify a contained-by operator for type %s" msgstr "konnte keinen Contained-By-Operator für Typ %s ermitteln" -#: commands/indexcmds.c:2501 commands/tablecmds.c:10461 +#: commands/indexcmds.c:2501 commands/tablecmds.c:10451 #, c-format msgid "Could not translate compare type %d for operator family \"%s\" of access method \"%s\"." msgstr "Konnte Vergleichstyp %d für Operatorfamilie »%s« von Zugriffsmethode »%s« nicht übersetzen." @@ -12725,7 +12576,7 @@ msgstr "beim Reindizieren der partitionierten Tabelle »%s.%s«" msgid "while reindexing partitioned index \"%s.%s\"" msgstr "beim Reindizieren des partitionierten Index »%s.%s«" -#: commands/indexcmds.c:3558 commands/indexcmds.c:4455 +#: commands/indexcmds.c:3558 commands/indexcmds.c:4457 #, c-format msgid "table \"%s.%s\" was reindexed" msgstr "Tabelle »%s.%s« wurde neu indiziert" @@ -12755,12 +12606,12 @@ msgstr "diese Art Relation kann nicht nebenläufig reindiziert werden" msgid "cannot move non-shared relation to tablespace \"%s\"" msgstr "nicht geteilte Relation kann nicht nach Tablespace »%s« verschoben werden" -#: commands/indexcmds.c:4436 commands/indexcmds.c:4448 +#: commands/indexcmds.c:4438 commands/indexcmds.c:4450 #, c-format msgid "index \"%s.%s\" was reindexed" msgstr "Index »%s.%s« wurde neu indiziert" -#: commands/indexcmds.c:4438 commands/indexcmds.c:4457 +#: commands/indexcmds.c:4440 commands/indexcmds.c:4459 #, c-format msgid "%s." msgstr "%s." @@ -13114,11 +12965,11 @@ msgstr "Operator-Attribut »%s« kann nicht geändert werden" msgid "operator attribute \"%s\" cannot be changed if it has already been set" msgstr "Operator-Attribut »%s« kann nicht geändert werden, wenn es schon gesetzt wurde" -#: commands/policy.c:86 commands/policy.c:379 commands/repack.c:637 +#: commands/policy.c:86 commands/policy.c:379 commands/repack.c:595 #: commands/statscmds.c:154 commands/tablecmds.c:1873 commands/tablecmds.c:2476 #: commands/tablecmds.c:3899 commands/tablecmds.c:6901 -#: commands/tablecmds.c:10217 commands/tablecmds.c:20217 -#: commands/tablecmds.c:20252 commands/trigger.c:320 commands/trigger.c:1339 +#: commands/tablecmds.c:10207 commands/tablecmds.c:20207 +#: commands/tablecmds.c:20242 commands/trigger.c:320 commands/trigger.c:1339 #: commands/trigger.c:1449 rewrite/rewriteDefine.c:268 #: rewrite/rewriteDefine.c:763 rewrite/rewriteRemove.c:74 #, c-format @@ -13222,10 +13073,9 @@ msgid "property graphs cannot be unlogged because they do not have storage" msgstr "Property-Graphs können nicht ungeloggt sein, weil sie keinen Speicherplatz verwenden" #: commands/propgraphcmds.c:146 commands/propgraphcmds.c:189 -#, fuzzy, c-format -#| msgid "common column name \"%s\" appears more than once in left table" +#, c-format msgid "alias \"%s\" used more than once as element table" -msgstr "gemeinsamer Spaltenname »%s« erscheint mehrmals in der linken Tabelle" +msgstr "Alias »%s« mehrmals als Elementtabelle verwendet" #: commands/propgraphcmds.c:215 #, c-format @@ -13238,148 +13088,152 @@ msgid "destination vertex \"%s\" of edge \"%s\" does not exist" msgstr "Zielknoten »%s« von Kante »%s« existiert nicht" #: commands/propgraphcmds.c:260 -#, fuzzy, c-format -#| msgid "view \"%s\" will be a temporary view" +#, c-format msgid "property graph \"%s\" will be temporary" -msgstr "Sicht »%s« wird eine temporäre Sicht" +msgstr "Property-Graph »%s« wird temporär sein" #: commands/propgraphcmds.c:336 #, c-format msgid "no key specified and no suitable primary key exists for definition of element \"%s\"" -msgstr "" +msgstr "kein Schlüssel angegeben und kein passender Primärschlüssel für die Definition von Element »%s« vorhanden" #: commands/propgraphcmds.c:389 -#, fuzzy, c-format -#| msgid "mismatched number of columns and values for index statistics" +#, c-format msgid "mismatching number of columns in %s vertex definition of edge \"%s\"" -msgstr "Anzahl Spalten und Werte für Indexstatistiken stimmt nicht überein" +msgstr "Anzahl der Spalten in %s-Knotendefinition von Kante »%s« stimmt nicht überein" #: commands/propgraphcmds.c:452 #, c-format msgid "no equality operator exists for %s key comparison of edge \"%s\"" -msgstr "" +msgstr "kein Ist-Gleich-Operator für %s-Schlüsselvergleich von Kante »%s« vorhanden" #: commands/propgraphcmds.c:470 #, c-format msgid "collation mismatch in %s key of edge \"%s\": %s vs. %s" -msgstr "" +msgstr "Sortierfolge in %s-Schlüssel von Kante »%s« stimmt nicht überein: %s gegen %s" #: commands/propgraphcmds.c:487 #, c-format msgid "more than one suitable foreign key exists for %s key of edge \"%s\"" -msgstr "" +msgstr "mehr als ein passender Fremdschlüssel für %s-Schlüssel von Kante »%s« vorhanden" #: commands/propgraphcmds.c:496 #, c-format msgid "no %s key specified and no suitable foreign key exists for definition of edge \"%s\"" -msgstr "" +msgstr "kein %s-Schlüssel angegeben und kein passender Fremdschlüssel für die Definition von Kante »%s« vorhanden" #: commands/propgraphcmds.c:552 -#, fuzzy, c-format -#| msgid "foreign key referenced-columns list must not contain duplicates" +#, c-format msgid "graph key columns list must not contain duplicates" -msgstr "die Liste der Spalten, auf die ein Fremdschlüssel verweist, darf keine doppelten Einträge enthalten" +msgstr "die Liste der Graph-Schlüsselspalten darf keine doppelten Einträge enthalten" -#: commands/propgraphcmds.c:881 -#, fuzzy, c-format -#| msgid "view name is required" +#: commands/propgraphcmds.c:792 +#, c-format +msgid "label \"%s\" already exists" +msgstr "Label »%s« existiert bereits" + +#: commands/propgraphcmds.c:888 +#, c-format msgid "property name required" -msgstr "Sichtname wird benötigt" +msgstr "Property-Name wird benötigt" + +#: commands/propgraphcmds.c:928 +#, c-format +msgid "property \"%s\" specified more than once" +msgstr "Property »%s« mehrmals angegeben" -#: commands/propgraphcmds.c:987 +#: commands/propgraphcmds.c:1012 #, c-format msgid "property \"%s\" data type mismatch: %s vs. %s" -msgstr "" +msgstr "Datentyp von Property »%s« stimmt nicht überein: %s gegen %s" -#: commands/propgraphcmds.c:989 +#: commands/propgraphcmds.c:1014 #, c-format msgid "In a property graph, a property of the same name has to have the same data type in each label." -msgstr "" +msgstr "In einem Property-Graph muss eine Property gleichen Namens in jedem Label den gleichen Datentyp haben." -#: commands/propgraphcmds.c:997 +#: commands/propgraphcmds.c:1022 #, c-format msgid "property \"%s\" collation mismatch: %s vs. %s" -msgstr "" +msgstr "Sortierfolge von Property »%s« stimmt nicht überein: %s gegen %s" -#: commands/propgraphcmds.c:999 +#: commands/propgraphcmds.c:1024 #, c-format msgid "In a property graph, a property of the same name has to have the same collation in each label." -msgstr "" +msgstr "In einem Property-Graph muss eine Property gleichen Namens in jedem Label die gleiche Sortierfolge haben." -#: commands/propgraphcmds.c:1145 -#, fuzzy, c-format -#| msgid "column \"%s\" is of type %s but expression is of type %s" +#: commands/propgraphcmds.c:1035 +#, c-format +msgid "property \"%s\" already exists" +msgstr "Property »%s« existiert bereits" + +#: commands/propgraphcmds.c:1176 +#, c-format msgid "element \"%s\" property \"%s\" expression mismatch: %s vs. %s" -msgstr "Spalte »%s« hat Typ %s, aber der Ausdruck hat Typ %s" +msgstr "Ausdruck von Element »%s« Property »%s« stimmt nicht überein: %s gegen %s" -#: commands/propgraphcmds.c:1147 +#: commands/propgraphcmds.c:1178 #, c-format msgid "In a property graph element, a property of the same name has to have the same expression in each label." -msgstr "" +msgstr "In einem Property-Graph-Element muss eine Property gleichen Namens in jedem Label den gleichen Ausdruck haben." -#: commands/propgraphcmds.c:1263 -#, fuzzy, c-format -#| msgid "invalid number of parents %d for table \"%s\"" +#: commands/propgraphcmds.c:1294 +#, c-format msgid "mismatching number of properties in definition of label \"%s\"" -msgstr "ungültige Anzahl Eltern %d für Tabelle »%s«" +msgstr "Anzahl der Propertys in Definition von Label »%s« stimmt nicht überein" -#: commands/propgraphcmds.c:1271 -#, fuzzy, c-format -#| msgid "merging multiple inherited definitions of column \"%s\"" +#: commands/propgraphcmds.c:1302 +#, c-format msgid "mismatching property names in definition of label \"%s\"" -msgstr "geerbte Definitionen von Spalte »%s« werden zusammengeführt" +msgstr "Property-Namen in Definition von Label »%s« stimmen nicht überein" -#: commands/propgraphcmds.c:1336 commands/propgraphcmds.c:1386 -#, fuzzy, c-format -#| msgid "cannot create temporary relation in non-temporary schema" +#: commands/propgraphcmds.c:1367 commands/propgraphcmds.c:1417 +#, c-format msgid "cannot add temporary element table to non-temporary property graph" -msgstr "kann keine temporäre Relation in einem nicht-temporären Schema erzeugen" +msgstr "kann temporäre Elementtabelle nicht zu nicht-temporärem Property-Graph hinzufügen" -#: commands/propgraphcmds.c:1337 commands/propgraphcmds.c:1387 -#, fuzzy, c-format -#| msgid "view \"%s\" will be a temporary view" +#: commands/propgraphcmds.c:1368 commands/propgraphcmds.c:1418 +#, c-format msgid "Table \"%s\" is a temporary table." -msgstr "Sicht »%s« wird eine temporäre Sicht" +msgstr "Tabelle »%s« ist eine temporäre Tabelle." -#: commands/propgraphcmds.c:1356 commands/propgraphcmds.c:1425 +#: commands/propgraphcmds.c:1387 commands/propgraphcmds.c:1456 #, c-format msgid "alias \"%s\" already exists in property graph \"%s\"" msgstr "Alias »%s« existiert bereits in Property-Graph »%s«" -#: commands/propgraphcmds.c:1521 commands/propgraphcmds.c:1557 -#: commands/propgraphcmds.c:1607 commands/propgraphcmds.c:1645 +#: commands/propgraphcmds.c:1552 commands/propgraphcmds.c:1588 +#: commands/propgraphcmds.c:1638 commands/propgraphcmds.c:1676 #, c-format msgid "property graph \"%s\" element \"%s\" has no label \"%s\"" msgstr "Property-Graph »%s« Element »%s« hat kein Label »%s«" -#: commands/propgraphcmds.c:1568 -#, fuzzy, c-format -#| msgid "cannot delete from table \"%s\"" +#: commands/propgraphcmds.c:1599 +#, c-format msgid "cannot drop the last label from element \"%s\"" -msgstr "kann nicht aus Tabelle »%s« löschen" +msgstr "kann das letzte Label von Element »%s« nicht löschen" -#: commands/propgraphcmds.c:1570 -#, fuzzy, c-format -#| msgid "RETURNING must have at least one column" +#: commands/propgraphcmds.c:1601 +#, c-format msgid "Every element must have at least one label." -msgstr "RETURNING muss mindestens eine Spalte haben" +msgstr "Jedes Element muss mindestens ein Label haben." -#: commands/propgraphcmds.c:1667 +#: commands/propgraphcmds.c:1698 #, c-format msgid "property graph \"%s\" element \"%s\" label \"%s\" has no property \"%s\"" -msgstr "" +msgstr "Property-Graph »%s« Element »%s« Label »%s« hat keine Property »%s«" -#: commands/propgraphcmds.c:1731 commands/propgraphcmds.c:1763 +#: commands/propgraphcmds.c:1762 commands/propgraphcmds.c:1794 #, c-format msgid "property graph \"%s\" has no element with alias \"%s\"" msgstr "Property-Graph »%s« hat kein Element mit Alias »%s«" -#: commands/propgraphcmds.c:1738 +#: commands/propgraphcmds.c:1769 #, c-format msgid "element \"%s\" of property graph \"%s\" is not a vertex" msgstr "Element »%s« von Property-Graph »%s« ist kein Knoten" -#: commands/propgraphcmds.c:1770 +#: commands/propgraphcmds.c:1801 #, c-format msgid "element \"%s\" of property graph \"%s\" is not an edge" msgstr "Element »%s« von Property-Graph »%s« ist keine Kante" @@ -13462,15 +13316,14 @@ msgid "Column lists cannot be specified for partitioned tables when %s is false. msgstr "Spaltenlisten können nicht für partitionierte Tabellen angegeben werden, wenn %s falsch ist." #: commands/publicationcmds.c:867 -#, fuzzy, c-format -#| msgid "must be superuser to create FOR ALL TABLES publication" +#, c-format msgid "must be superuser to create a FOR ALL TABLES or ALL SEQUENCES publication" -msgstr "nur Superuser können eine Publikation FOR ALL TABLES erzeugen" +msgstr "nur Superuser können eine Publikation FOR ALL TABLES oder ALL SEQUENCES erzeugen" #: commands/publicationcmds.c:902 commands/publicationcmds.c:1049 #, c-format msgid "publication parameters are not applicable to sequence synchronization and will be ignored for sequences" -msgstr "" +msgstr "Publikationsparameter sind nicht auf Sequenzsynchronisation anwendbar und werden für Sequenzen ignoriert" #: commands/publicationcmds.c:966 #, c-format @@ -13478,16 +13331,14 @@ msgid "must be superuser to create FOR TABLES IN SCHEMA publication" msgstr "nur Superuser können eine Publikation FOR TABLES IN SCHEMA erzeugen" #: commands/publicationcmds.c:1007 -#, fuzzy, c-format -#| msgid "\"wal_level\" is insufficient to publish logical changes" +#, c-format msgid "logical decoding must be enabled to publish logical changes" -msgstr "»wal_level« ist nicht ausreichend, um logische Veränderungen zu publizieren" +msgstr "logisches Dekodieren muss eingeschaltet sein, um logische Veränderungen zu publizieren" #: commands/publicationcmds.c:1008 -#, fuzzy, c-format -#| msgid "Change \"wal_level\" to be \"replica\" or higher." +#, c-format msgid "Before creating subscriptions, ensure that \"wal_level\" is set to \"replica\" or higher." -msgstr "Ändern Sie »wal_level« in »replica« oder höher." +msgstr "Stellen Sie vor dem Erzeugen von Subskriptionen sicher, dass »wal_level« auf »replica« oder höher gesetzt ist." #: commands/publicationcmds.c:1115 commands/publicationcmds.c:1123 #, c-format @@ -13520,28 +13371,24 @@ msgid "must be superuser to add or set schemas" msgstr "nur Superuser können Schemas hinzufügen oder setzen" #: commands/publicationcmds.c:1526 -#, fuzzy, c-format -#| msgid "must be superuser to create FOR ALL TABLES publication" +#, c-format msgid "must be superuser to set ALL TABLES" -msgstr "nur Superuser können eine Publikation FOR ALL TABLES erzeugen" +msgstr "nur Superuser können ALL TABLES setzen" #: commands/publicationcmds.c:1531 -#, fuzzy, c-format -#| msgid "must be superuser to set schema of %s" +#, c-format msgid "must be superuser to set ALL SEQUENCES" -msgstr "nur Superuser können Schema von %s setzen" +msgstr "nur Superuser können ALL SEQUENCES setzen" #: commands/publicationcmds.c:1542 commands/publicationcmds.c:1565 -#, fuzzy, c-format -#| msgid "publication \"%s\" is defined as FOR ALL TABLES" +#, c-format msgid "publication \"%s\" is defined as FOR ALL TABLES, ALL SEQUENCES" -msgstr "Publikation »%s« ist als FOR ALL TABLES definiert" +msgstr "Publikation »%s« ist als FOR ALL TABLES, ALL SEQUENCES definiert" #: commands/publicationcmds.c:1544 -#, fuzzy, c-format -#| msgid "Schemas cannot be added to or dropped from FOR ALL TABLES publications." +#, c-format msgid "Schemas cannot be added to or dropped from FOR ALL TABLES, ALL SEQUENCES publications." -msgstr "In einer FOR-ALL-TABLES-Publikation können keine Schemas hinzugefügt oder entfernt werden." +msgstr "In einer FOR-ALL-TABLES-, ALL-SEQUENCES-Publikation können keine Schemas hinzugefügt oder entfernt werden." #: commands/publicationcmds.c:1548 commands/publicationcmds.c:1571 #, c-format @@ -13554,51 +13401,44 @@ msgid "Schemas cannot be added to or dropped from FOR ALL TABLES publications." msgstr "In einer FOR-ALL-TABLES-Publikation können keine Schemas hinzugefügt oder entfernt werden." #: commands/publicationcmds.c:1554 commands/publicationcmds.c:1577 -#, fuzzy, c-format -#| msgid "publication \"%s\" is defined as FOR ALL TABLES" +#, c-format msgid "publication \"%s\" is defined as FOR ALL SEQUENCES" -msgstr "Publikation »%s« ist als FOR ALL TABLES definiert" +msgstr "Publikation »%s« ist als FOR ALL SEQUENCES definiert" #: commands/publicationcmds.c:1556 -#, fuzzy, c-format -#| msgid "Schemas cannot be added to or dropped from FOR ALL TABLES publications." +#, c-format msgid "Schemas cannot be added to or dropped from FOR ALL SEQUENCES publications." -msgstr "In einer FOR-ALL-TABLES-Publikation können keine Schemas hinzugefügt oder entfernt werden." +msgstr "In einer FOR-ALL-SEQUENCES-Publikation können keine Schemas hinzugefügt oder entfernt werden." #: commands/publicationcmds.c:1567 -#, fuzzy, c-format -#| msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +#, c-format msgid "Tables or sequences cannot be added to or dropped from FOR ALL TABLES, ALL SEQUENCES publications." -msgstr "In einer FOR-ALL-TABLES-Publikation können keine Tabellen hinzugefügt oder entfernt werden." +msgstr "In einer FOR-ALL-TABLES-, ALL-SEQUENCES-Publikation können keine Tabellen oder Sequenzen hinzugefügt oder entfernt werden." #: commands/publicationcmds.c:1573 -#, fuzzy, c-format -#| msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +#, c-format msgid "Tables or sequences cannot be added to or dropped from FOR ALL TABLES publications." -msgstr "In einer FOR-ALL-TABLES-Publikation können keine Tabellen hinzugefügt oder entfernt werden." +msgstr "In einer FOR-ALL-TABLES-Publikation können keine Tabellen oder Sequenzen hinzugefügt oder entfernt werden." #: commands/publicationcmds.c:1579 -#, fuzzy, c-format -#| msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +#, c-format msgid "Tables or sequences cannot be added to or dropped from FOR ALL SEQUENCES publications." -msgstr "In einer FOR-ALL-TABLES-Publikation können keine Tabellen hinzugefügt oder entfernt werden." +msgstr "In einer FOR-ALL-SEQUENCES-Publikation können keine Tabellen oder Sequenzen hinzugefügt oder entfernt werden." #: commands/publicationcmds.c:1594 -#, fuzzy, c-format -#| msgid "access method \"%s\" does not support NULLS FIRST/LAST options" +#, c-format msgid "publication \"%s\" does not support ALL TABLES operations" -msgstr "Zugriffsmethode »%s« unterstützt die Optionen NULLS FIRST/LAST nicht" +msgstr "Publikation »%s« unterstützt keine ALL-TABLES-Operationen" #: commands/publicationcmds.c:1595 -#, fuzzy, c-format -#| msgid "access method \"%s\" does not support ASC/DESC options" +#, c-format msgid "publication \"%s\" does not support ALL SEQUENCES operations" -msgstr "Zugriffsmethode »%s« unterstützt die Optionen ASC/DESC nicht" +msgstr "Publikation »%s« unterstützt keine ALL-SEQUENCES-Operationen" #: commands/publicationcmds.c:1596 #, c-format msgid "This operation requires the publication to be defined as FOR ALL TABLES/SEQUENCES or to be empty." -msgstr "" +msgstr "Diese Operation erfordert, dass die Publikation als FOR ALL TABLES/SEQUENCES definiert oder leer ist." #: commands/publicationcmds.c:1671 commands/publicationcmds.c:1711 #: commands/publicationcmds.c:2245 utils/cache/lsyscache.c:3995 @@ -13642,10 +13482,9 @@ msgid "permission denied to change owner of publication \"%s\"" msgstr "keine Berechtigung, um Eigentümer der Publikation »%s« zu ändern" #: commands/publicationcmds.c:2210 -#, fuzzy, c-format -#| msgid "The owner of a FOR TABLES IN SCHEMA publication must be a superuser." +#, c-format msgid "The owner of a FOR ALL TABLES or ALL SEQUENCES or TABLES IN SCHEMA publication must be a superuser." -msgstr "Der Eigentümer einer FOR-TABLES-IN-SCHEMA-Publikation muss ein Superuser sein." +msgstr "Der Eigentümer einer FOR-ALL-TABLES- oder ALL-SEQUENCES- oder TABLES-IN-SCHEMA-Publikation muss ein Superuser sein." #: commands/publicationcmds.c:2277 #, c-format @@ -13663,169 +13502,139 @@ msgid "Valid values are \"%s\" and \"%s\"." msgstr "Gültige Werte sind »%s« und »%s«." #: commands/repack.c:274 -#, fuzzy, c-format -#| msgid "This operation is not supported for views." +#, c-format msgid "CONCURRENTLY option not supported for %s" -msgstr "Diese Operation wird für Sichten nicht unterstützt." +msgstr "Option CONCURRENTLY wird für %s nicht unterstützt" #: commands/repack.c:328 -#, fuzzy, c-format -#| msgid "cannot execute MERGE on relation \"%s\"" +#, c-format msgid "cannot execute %s on multiple tables" -msgstr "MERGE kann für Relation »%s« nicht ausgeführt werden" +msgstr "%s kann nicht für mehrere Tabellen ausgeführt werden" #: commands/repack.c:344 -#, fuzzy, c-format -#| msgid "This operation is not supported for partitioned tables." +#, c-format msgid "%s is not supported for partitioned tables" -msgstr "Diese Operation wird für partitionierte Tabellen nicht unterstützt." +msgstr "%s wird für partitionierte Tabellen nicht unterstützt" #: commands/repack.c:346 #, c-format msgid "Consider running the command on individual partitions." -msgstr "" +msgstr "Führen Sie den Befehl eventuell für einzelne Partitionen aus." #: commands/repack.c:351 -#, fuzzy, c-format -#| msgid "%s requires a numeric value" -msgid "%s requires an explicit table name" -msgstr "%s erfordert einen numerischen Wert" - -#: commands/repack.c:409 commands/repack.c:2500 #, c-format -msgid "there is no previously clustered index for table \"%s\"" -msgstr "es gibt keinen bereits geclusterten Index für Tabelle »%s«" - -#. translator: first %s is name of a SQL command, eg. REPACK -#: commands/repack.c:415 -#, fuzzy, c-format -#| msgid "cannot create index on partitioned table \"%s\" concurrently" -msgid "cannot execute %s on partitioned table \"%s\" USING INDEX with no index name" -msgstr "kann Index für partitionierte Tabelle »%s« nicht nebenläufig erzeugen" +msgid "%s requires an explicit table name" +msgstr "%s erfordert einen expliziten Tabellennamen" #. translator: first %s is name of a SQL command, eg. REPACK -#: commands/repack.c:587 -#, fuzzy, c-format -#| msgid "cannot cluster a shared catalog" +#: commands/repack.c:545 +#, c-format msgid "cannot execute %s on a shared catalog" -msgstr "globaler Katalog kann nicht geclustert werden" +msgstr "%s kann nicht für einen globalen Katalog ausgeführt werden" #. translator: first %s is name of a SQL command, eg. REPACK -#: commands/repack.c:604 commands/repack.c:2420 -#, fuzzy, c-format -#| msgid "cannot cluster temporary tables of other sessions" +#: commands/repack.c:562 commands/repack.c:2424 +#, c-format msgid "cannot execute %s on temporary tables of other sessions" -msgstr "kann temporäre Tabellen anderer Sitzungen nicht clustern" +msgstr "%s kann nicht für temporäre Tabellen anderer Sitzungen ausgeführt werden" -#: commands/repack.c:639 +#: commands/repack.c:597 #, c-format msgid "System catalogs can only be clustered by the index they're already clustered on, if any, unless \"%s\" is enabled." -msgstr "" +msgstr "Systemkataloge können nur nach dem Index geclustert werden, nach dem sie bereits geclustert sind, falls vorhanden, außer wenn »%s« eingeschaltet ist." -#: commands/repack.c:785 commands/tablecmds.c:19175 +#: commands/repack.c:745 commands/tablecmds.c:19165 #, c-format msgid "\"%s\" is not an index for table \"%s\"" msgstr "»%s« ist kein Index für Tabelle »%s«" -#: commands/repack.c:793 +#: commands/repack.c:753 #, c-format msgid "cannot cluster on index \"%s\" because access method does not support clustering" msgstr "kann nicht anhand des Index »%s« clustern, weil die Indexmethode Clustern nicht unterstützt" -#: commands/repack.c:805 +#: commands/repack.c:765 #, c-format msgid "cannot cluster on partial index \"%s\"" msgstr "kann nicht anhand des partiellen Index »%s« clustern" -#: commands/repack.c:819 +#: commands/repack.c:779 #, c-format msgid "cannot cluster on invalid index \"%s\"" msgstr "kann nicht anhand des ungültigen Index »%s« clustern" -#: commands/repack.c:907 -#, fuzzy, c-format -#| msgid "cannot execute %s in a read-only transaction" +#: commands/repack.c:867 +#, c-format msgid "cannot execute %s in this configuration" -msgstr "%s kann nicht in einer Read-Only-Transaktion ausgeführt werden" +msgstr "%s kann nicht in dieser Konfiguration ausgeführt werden" -#: commands/repack.c:909 -#, fuzzy, c-format -#| msgid "Change \"wal_level\" to be \"replica\" or higher." +#: commands/repack.c:869 +#, c-format msgid "%s requires \"wal_level\" to be set to \"replica\" or higher." -msgstr "Ändern Sie »wal_level« in »replica« oder höher." +msgstr "%s erfordert, dass »wal_level« auf »replica« oder höher gesetzt ist." -#: commands/repack.c:916 commands/repack.c:928 commands/repack.c:937 -#: commands/repack.c:951 commands/repack.c:972 commands/repack.c:981 -#, fuzzy, c-format -#| msgid "cannot execute MERGE on relation \"%s\"" +#: commands/repack.c:876 commands/repack.c:888 commands/repack.c:897 +#: commands/repack.c:911 commands/repack.c:932 commands/repack.c:941 +#, c-format msgid "cannot execute %s on relation \"%s\"" -msgstr "MERGE kann für Relation »%s« nicht ausgeführt werden" +msgstr "%s kann nicht für Relation »%s« ausgeführt werden" -#: commands/repack.c:918 -#, fuzzy, c-format -#| msgid "WHERE CURRENT OF is not supported for this table type" +#: commands/repack.c:878 +#, c-format msgid "%s is not supported for catalog relations." -msgstr "WHERE CURRENT OF wird für diesen Tabellentyp nicht unterstützt" +msgstr "%s wird für Katalogrelationen nicht unterstützt." -#: commands/repack.c:930 -#, fuzzy, c-format -#| msgid "MERGE is not supported for relations with rules." +#: commands/repack.c:890 +#, c-format msgid "%s is not supported for TOAST relations." -msgstr "MERGE wird für Relationen mit Regeln nicht unterstützt." +msgstr "%s wird für TOAST-Relationen nicht unterstützt." -#: commands/repack.c:939 -#, fuzzy, c-format -#| msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +#: commands/repack.c:899 +#, c-format msgid "%s is only allowed for permanent relations." -msgstr "ALTER SUBSCRIPTION mit Refresh ist für deaktivierte Subskriptionen nicht erlaubt" +msgstr "%s ist nur für permanente Relationen erlaubt." -#: commands/repack.c:953 -#, fuzzy, c-format -#| msgid "this build does not support compression with %s" +#: commands/repack.c:913 +#, c-format msgid "%s does not support tables with %s." -msgstr "diese Installation unterstützt keine Komprimierung mit %s" +msgstr "%s unterstützt keine Tabellen mit %s." -#: commands/repack.c:975 -#, fuzzy, c-format -#| msgid "XML does not support infinite date values." +#: commands/repack.c:935 +#, c-format msgid "%s does not support deferrable primary keys." -msgstr "XML unterstützt keine unendlichen Datumswerte." +msgstr "%s unterstützt keine aufschiebbaren Primärschlüssel." -#: commands/repack.c:977 +#: commands/repack.c:937 #, c-format msgid "Use ALTER TABLE ... REPLICA IDENTITY USING INDEX to designate another index as replica identity." -msgstr "" +msgstr "Verwenden Sie ALTER TABLE ... REPLICA IDENTITY USING INDEX, um einen anderen Index als Replik-Identität zu bestimmen." -#: commands/repack.c:983 -#, fuzzy, c-format -#| msgid "table \"%s\" has no indexes to reindex" +#: commands/repack.c:943 +#, c-format msgid "Relation \"%s\" has no identity index." -msgstr "Tabelle »%s« hat keine zu reindizierenden Indexe" +msgstr "Relation »%s« hat keinen Identitätsindex." -#: commands/repack.c:1432 -#, fuzzy, c-format -#| msgid "clustering \"%s.%s\" using index scan on \"%s\"" +#: commands/repack.c:1392 +#, c-format msgid "repacking \"%s.%s\" using index scan on \"%s\"" -msgstr "clustere »%s.%s« durch Index-Scan von »%s«" +msgstr "repacke »%s.%s« durch Index-Scan von »%s«" -#: commands/repack.c:1438 -#, fuzzy, c-format -#| msgid "clustering \"%s.%s\" using sequential scan and sort" +#: commands/repack.c:1398 +#, c-format msgid "repacking \"%s.%s\" using sequential scan and sort" -msgstr "clustere »%s.%s« durch sequenziellen Scan und Sortieren" +msgstr "repacke »%s.%s« durch sequenziellen Scan und Sortieren" -#: commands/repack.c:1443 -#, fuzzy, c-format -#| msgid "analyzing \"%s.%s\" inheritance tree" +#: commands/repack.c:1403 +#, c-format msgid "repacking \"%s.%s\" in physical order" -msgstr "analysiere Vererbungsbaum von »%s.%s«" +msgstr "repacke »%s.%s« in physischer Reihenfolge" -#: commands/repack.c:1475 +#: commands/repack.c:1435 #, c-format msgid "\"%s.%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" msgstr "»%s.%s«: %.0f entfernbare, %.0f nicht entfernbare Zeilenversionen in %u Seiten gefunden" -#: commands/repack.c:1480 +#: commands/repack.c:1440 #, c-format msgid "" "%.0f dead row versions cannot be removed yet.\n" @@ -13834,37 +13643,46 @@ msgstr "" "%.0f tote Zeilenversionen können noch nicht entfernt werden.\n" "%s." -#: commands/repack.c:2366 -#, fuzzy, c-format -#| msgid "permission denied to cluster \"%s\", skipping it" +#: commands/repack.c:2248 commands/repack.c:2504 +#, c-format +msgid "there is no previously clustered index for table \"%s\"" +msgstr "es gibt keinen bereits geclusterten Index für Tabelle »%s«" + +#. translator: first %s is name of a SQL command, eg. REPACK +#: commands/repack.c:2254 +#, c-format +msgid "cannot execute %s on partitioned table \"%s\" USING INDEX with no index name" +msgstr "%s kann nicht für partitionierte Tabelle »%s« mit USING INDEX ohne Indexnamen ausgeführt werden" + +#: commands/repack.c:2369 +#, c-format msgid "permission denied to execute %s on \"%s\", skipping it" -msgstr "keine Berechtigung für Clustern von »%s«, wird übersprungen" +msgstr "keine Berechtigung um %s für »%s« auszuführen, wird übersprungen" -#: commands/repack.c:2402 commands/vacuum.c:351 +#: commands/repack.c:2406 commands/vacuum.c:351 #, c-format msgid "ANALYZE option must be specified when a column list is provided" msgstr "Option ANALYZE muss angegeben werden, wenn eine Spaltenliste angegeben ist" -#: commands/repack.c:2510 commands/tablecmds.c:17108 commands/tablecmds.c:19165 +#: commands/repack.c:2514 commands/tablecmds.c:17098 commands/tablecmds.c:19155 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "Index »%s« für Tabelle »%s« existiert nicht" -#: commands/repack.c:2707 commands/repack.c:2745 -#, fuzzy, c-format -#| msgid "cannot alter constraint \"%s\" on relation \"%s\"" +#: commands/repack.c:2711 commands/repack.c:2749 +#, c-format msgid "could not apply concurrent %s on relation \"%s\"" -msgstr "Constraint »%s« von Relation »%s« kann nicht geändert werden" +msgstr "konnte nebenläufiges %s für Relation »%s« nicht anwenden" -#: commands/repack.c:3654 replication/logical/launcher.c:565 +#: commands/repack.c:3658 replication/logical/launcher.c:565 #, c-format msgid "out of background worker slots" msgstr "alle Slots für Background-Worker belegt" #. translator: %s is a GUC variable name -#: commands/repack.c:3655 replication/logical/launcher.c:468 -#: replication/logical/launcher.c:566 replication/slot.c:1814 -#: replication/slot.c:1834 storage/lmgr/lock.c:1051 storage/lmgr/lock.c:1089 +#: commands/repack.c:3659 replication/logical/launcher.c:468 +#: replication/logical/launcher.c:566 replication/slot.c:1816 +#: replication/slot.c:1836 storage/lmgr/lock.c:1051 storage/lmgr/lock.c:1089 #: storage/lmgr/lock.c:3009 storage/lmgr/lock.c:4386 storage/lmgr/lock.c:4451 #: storage/lmgr/lock.c:4801 storage/lmgr/predicate.c:2408 #: storage/lmgr/predicate.c:2423 storage/lmgr/predicate.c:3820 @@ -13872,32 +13690,29 @@ msgstr "alle Slots für Background-Worker belegt" msgid "You might need to increase \"%s\"." msgstr "Sie müssen möglicherweise »%s« erhöhen." -#: commands/repack.c:3707 -#, fuzzy, c-format -#| msgid "postmaster exited during a parallel transaction" +#: commands/repack.c:3711 +#, c-format msgid "postmaster exited during REPACK command" -msgstr "Postmaster beendete während einer parallelen Transaktion" +msgstr "Postmaster beendete während des REPACK-Befehls" -#: commands/repack.c:3934 commands/repack.c:3936 +#: commands/repack.c:3938 commands/repack.c:3940 msgid "REPACK decoding worker" -msgstr "" +msgstr "REPACK-Dekodierungs-Worker" -#: commands/repack_worker.c:412 postmaster/walsummarizer.c:1051 -#, fuzzy, c-format -#| msgid "could not read WAL from timeline %u at %X/%X: %s" +#: commands/repack_worker.c:412 postmaster/walsummarizer.c:1150 +#, c-format msgid "could not read WAL from timeline %u at %X/%08X: %s" -msgstr "konnte WAL aus Zeitleiste %u bei %X/%X nicht lesen: %s" +msgstr "konnte WAL aus Zeitleiste %u bei %X/%08X nicht lesen: %s" #: commands/repack_worker.c:429 -#, fuzzy, c-format -#| msgid "could not read WAL record at %X/%08X" +#, c-format msgid "could not read WAL record" -msgstr "konnte WAL-Eintrag bei %X/%08X nicht lesen" +msgstr "konnte WAL-Eintrag nicht lesen" #: commands/repack_worker.c:477 #, c-format msgid "waiting for WAL failed" -msgstr "" +msgstr "Warten auf WAL fehlgeschlagen" #: commands/schemacmds.c:109 commands/schemacmds.c:290 #, c-format @@ -14054,8 +13869,8 @@ msgstr "Sequenz muss im selben Schema wie die verknüpfte Tabelle sein" msgid "cannot change ownership of identity sequence" msgstr "kann Eigentümer einer Identitätssequenz nicht ändern" -#: commands/sequence.c:1676 commands/tablecmds.c:16797 -#: commands/tablecmds.c:19626 +#: commands/sequence.c:1676 commands/tablecmds.c:16787 +#: commands/tablecmds.c:19616 #, c-format msgid "Sequence \"%s\" is linked to table \"%s\"." msgstr "Sequenz »%s« ist mit Tabelle »%s« verknüpft." @@ -14091,38 +13906,34 @@ msgid "statistics creation on system columns is not supported" msgstr "Statistikerzeugung für Systemspalten wird nicht unterstützt" #: commands/statscmds.c:283 commands/statscmds.c:330 -#, fuzzy, c-format -#| msgid "cannot clear statistics on system column \"%s\"" +#, c-format msgid "cannot create multivariate statistics on column \"%s\"" -msgstr "Statistiken für Systemspalte »%s« können nicht geleert werden" +msgstr "kann keine multivariaten Statistiken für Spalte »%s« erzeugen" #: commands/statscmds.c:285 commands/statscmds.c:332 commands/statscmds.c:383 -#, fuzzy, c-format -#| msgid "data type %s has no default operator class for access method \"%s\"" +#, c-format msgid "The type %s has no default btree operator class." -msgstr "Datentyp %s hat keine Standardoperatorklasse für Zugriffsmethode »%s«" +msgstr "Der Typ %s hat keine Standard-Btree-Operatorklasse." #: commands/statscmds.c:382 -#, fuzzy, c-format -#| msgid "cannot use subquery in statistics expression" +#, c-format msgid "cannot create multivariate statistics on this expression" -msgstr "Unteranfragen können nicht in Statistikausdrücken verwendet werden" +msgstr "kann keine multivariaten Statistiken für diesen Ausdruck erzeugen" #: commands/statscmds.c:399 -#, fuzzy, c-format -#| msgid "cannot alter statistics on virtual generated column \"%s\"" +#, c-format msgid "cannot create extended statistics on a single non-virtual column" -msgstr "Statistiken von virtueller generierter Spalte »%s« können nicht geändert werden" +msgstr "kann keine erweiterten Statistiken für eine einzelne nicht-virtuelle Spalte erzeugen" #: commands/statscmds.c:400 #, c-format msgid "Univariate statistics are already built for each individual non-virtual table column." -msgstr "" +msgstr "Univariate Statistiken werden bereits für jede einzelne nicht-virtuelle Tabellenspalte erstellt." #: commands/statscmds.c:409 #, c-format msgid "cannot specify statistics kinds when building univariate statistics" -msgstr "" +msgstr "Statistikarten können nicht angegeben werden, wenn univariate Statistiken erstellt werden" #: commands/statscmds.c:436 #, c-format @@ -14139,12 +13950,12 @@ msgstr "doppelter Spaltenname in Statistikdefinition" msgid "duplicate expression in statistics definition" msgstr "doppelter Ausdruck in Statistikdefinition" -#: commands/statscmds.c:684 commands/tablecmds.c:9041 +#: commands/statscmds.c:684 commands/tablecmds.c:9032 #, c-format msgid "statistics target %d is too low" msgstr "Statistikziel %d ist zu niedrig" -#: commands/statscmds.c:692 commands/tablecmds.c:9049 +#: commands/statscmds.c:692 commands/tablecmds.c:9040 #, c-format msgid "lowering statistics target to %d" msgstr "setze Statistikziel auf %d herab" @@ -14155,10 +13966,9 @@ msgid "statistics object \"%s.%s\" does not exist, skipping" msgstr "Statistikobjekt »%s.%s« existiert nicht, wird übersprungen" #: commands/subscriptioncmds.c:363 -#, fuzzy, c-format -#| msgid "\"timeout\" must not be negative" +#, c-format msgid "max_retention_duration cannot be negative" -msgstr "»timeout« darf nicht negativ sein" +msgstr "max_retention_duration darf nicht negativ sein" #: commands/subscriptioncmds.c:386 replication/pgoutput/pgoutput.c:417 #, c-format @@ -14211,302 +14021,301 @@ msgstr "keine Berechtigung, um Subskription zu erzeugen" msgid "Only roles with privileges of the \"%s\" role may create subscriptions." msgstr "Nur Rollen mit den Privilegien der Rolle »%s« können Subskriptionen erzeugen." -#: commands/subscriptioncmds.c:901 commands/subscriptioncmds.c:1065 -#: commands/subscriptioncmds.c:1317 commands/subscriptioncmds.c:2229 +#: commands/subscriptioncmds.c:804 foreign/foreign.c:212 +#, c-format +msgid "foreign-data wrapper \"%s\" does not support subscription connections" +msgstr "Fremddaten-Wrapper »%s« unterstützt keine Subskriptionsverbindungen" + +#: commands/subscriptioncmds.c:806 foreign/foreign.c:214 +#, c-format +msgid "Foreign-data wrapper must be defined with CONNECTION specified." +msgstr "Der Fremddaten-Wrapper muss mit angegebenem CONNECTION definiert werden." + +#: commands/subscriptioncmds.c:918 commands/subscriptioncmds.c:1089 +#: commands/subscriptioncmds.c:1349 commands/subscriptioncmds.c:2317 #, c-format msgid "subscription \"%s\" could not connect to the publisher: %s" msgstr "Subskription »%s« konnte nicht mit dem Publikationsserver verbinden: %s" -#: commands/subscriptioncmds.c:992 +#: commands/subscriptioncmds.c:1009 #, c-format msgid "created replication slot \"%s\" on publisher" msgstr "Replikations-Slot »%s« wurde auf dem Publikationsserver erzeugt" -#: commands/subscriptioncmds.c:1004 +#: commands/subscriptioncmds.c:1021 #, c-format msgid "subscription was created, but is not connected" msgstr "Subskription wurde erzeugt, ist aber nicht verbunden" -#: commands/subscriptioncmds.c:1005 -#, fuzzy, c-format -#| msgid "To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription." +#: commands/subscriptioncmds.c:1022 +#, c-format msgid "To initiate replication, you must manually create the replication slot, enable the subscription, and alter the subscription to refresh publications." -msgstr "Um die Replikation einzuleiten, müssen Sie den Replikations-Slot manuell erzeugen, die Subskription aktivieren und die Subskription auffrischen." +msgstr "Um die Replikation einzuleiten, müssen Sie den Replikations-Slot manuell erzeugen, die Subskription aktivieren und die Subskription ändern, um die Publikationen aufzufrischen." -#: commands/subscriptioncmds.c:1414 +#: commands/subscriptioncmds.c:1363 replication/logical/sequencesync.c:471 +#, c-format +msgid "cannot synchronize sequences if the publisher is running a version earlier than PostgreSQL 19" +msgstr "Sequenzen können nicht synchronisiert werden, wenn der Publikationsserver eine Version älter als PostgreSQL 19 hat" + +#: commands/subscriptioncmds.c:1487 #, c-format msgid "cannot set option \"%s\" for enabled subscription" msgstr "für eine aktivierte Subskription kann Option »%s« nicht gesetzt werden" -#: commands/subscriptioncmds.c:1428 +#: commands/subscriptioncmds.c:1501 #, c-format msgid "cannot set option \"%s\" for a subscription that does not have a slot name" msgstr "Option »%s« kann nicht für eine Subskription ohne Slot-Name gesetzt werden" -#: commands/subscriptioncmds.c:1478 commands/subscriptioncmds.c:2345 -#: commands/subscriptioncmds.c:2758 utils/cache/lsyscache.c:4045 +#: commands/subscriptioncmds.c:1552 commands/subscriptioncmds.c:2433 +#: commands/subscriptioncmds.c:2839 utils/cache/lsyscache.c:4045 #, c-format msgid "subscription \"%s\" does not exist" msgstr "Subskription »%s« existiert nicht" -#: commands/subscriptioncmds.c:1614 +#: commands/subscriptioncmds.c:1707 #, c-format msgid "cannot set %s for enabled subscription" msgstr "für eine aktivierte Subskription kann nicht %s gesetzt werden" -#: commands/subscriptioncmds.c:1699 +#: commands/subscriptioncmds.c:1792 #, c-format msgid "\"slot_name\" and \"two_phase\" cannot be altered at the same time" msgstr "»slot_name« und »two_phase« können nicht gleichzeitig geändert werden" -#: commands/subscriptioncmds.c:1715 +#: commands/subscriptioncmds.c:1808 #, c-format msgid "cannot alter \"two_phase\" when logical replication worker is still running" msgstr "»two_phase« kann nicht geändert werden, wenn ein Replikationsarbeitsprozess noch läuft" -#: commands/subscriptioncmds.c:1716 commands/subscriptioncmds.c:1800 +#: commands/subscriptioncmds.c:1809 commands/subscriptioncmds.c:1893 #, c-format msgid "Try again after some time." msgstr "Versuchen Sie es nach einer Weile erneut." -#: commands/subscriptioncmds.c:1729 +#: commands/subscriptioncmds.c:1822 #, c-format msgid "cannot disable \"two_phase\" when prepared transactions exist" msgstr "»two_phase« kann nicht ausgeschaltet werden, wenn vorbereitete Transaktionen existieren" -#: commands/subscriptioncmds.c:1730 +#: commands/subscriptioncmds.c:1823 #, c-format msgid "Resolve these transactions and try again." msgstr "Lösen Sie diese Transaktionen auf und versuchen Sie erneut." -#: commands/subscriptioncmds.c:1799 -#, fuzzy, c-format -#| msgid "cannot alter \"two_phase\" when logical replication worker is still running" +#: commands/subscriptioncmds.c:1892 +#, c-format msgid "cannot alter retain_dead_tuples when logical replication worker is still running" -msgstr "»two_phase« kann nicht geändert werden, wenn ein Replikationsarbeitsprozess noch läuft" +msgstr "retain_dead_tuples kann nicht geändert werden, wenn ein Replikationsarbeitsprozess noch läuft" -#: commands/subscriptioncmds.c:1872 +#: commands/subscriptioncmds.c:1965 #, c-format msgid "cannot enable subscription that does not have a slot name" msgstr "eine Subskription ohne Slot-Name kann nicht aktiviert werden" -#: commands/subscriptioncmds.c:2015 commands/subscriptioncmds.c:2062 +#: commands/subscriptioncmds.c:2100 commands/subscriptioncmds.c:2148 #, c-format msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" msgstr "ALTER SUBSCRIPTION mit Refresh ist für deaktivierte Subskriptionen nicht erlaubt" -#: commands/subscriptioncmds.c:2016 +#: commands/subscriptioncmds.c:2101 #, c-format msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." msgstr "Verwenden Sie ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." -#: commands/subscriptioncmds.c:2025 commands/subscriptioncmds.c:2076 +#: commands/subscriptioncmds.c:2110 commands/subscriptioncmds.c:2162 #, c-format msgid "ALTER SUBSCRIPTION with refresh and copy_data is not allowed when two_phase is enabled" msgstr "ALTER SUBSCRIPTION mit »refresh« und »copy_data« ist nicht erlaubt, wenn »two_phase« eingeschaltet ist" -#: commands/subscriptioncmds.c:2026 +#: commands/subscriptioncmds.c:2111 #, c-format msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION with refresh = false, or with copy_data = false, or use DROP/CREATE SUBSCRIPTION." msgstr "Verwenden Sie ALTER SUBSCRIPTION ... SET PUBLICATION mit refresh = false, oder mit copy_data = false, oder verwenden Sie DROP/CREATE SUBSCRIPTION." #. translator: %s is an SQL ALTER command -#: commands/subscriptioncmds.c:2078 +#: commands/subscriptioncmds.c:2164 #, c-format msgid "Use %s with refresh = false, or with copy_data = false, or use DROP/CREATE SUBSCRIPTION." msgstr "Verwenden Sie %s mit refresh = false, oder mit copy_data = false, oder verwenden Sie DROP/CREATE SUBSCRIPTION." -#: commands/subscriptioncmds.c:2100 commands/subscriptioncmds.c:2138 -#, fuzzy, c-format -#| msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +#: commands/subscriptioncmds.c:2187 commands/subscriptioncmds.c:2226 +#, c-format msgid "%s is not allowed for disabled subscriptions" -msgstr "ALTER SUBSCRIPTION mit Refresh ist für deaktivierte Subskriptionen nicht erlaubt" +msgstr "%s ist für deaktivierte Subskriptionen nicht erlaubt" -#: commands/subscriptioncmds.c:2123 -#, fuzzy, c-format -#| msgid "ALTER SUBSCRIPTION ... REFRESH with copy_data is not allowed when two_phase is enabled" +#: commands/subscriptioncmds.c:2210 +#, c-format msgid "ALTER SUBSCRIPTION ... REFRESH PUBLICATION with copy_data is not allowed when two_phase is enabled" -msgstr "ALTER SUBSCRIPTION ... REFRESH mit »copy_data« ist nicht erlaubt, wenn »two_phase« eingeschaltet ist" +msgstr "ALTER SUBSCRIPTION ... REFRESH PUBLICATION mit »copy_data« ist nicht erlaubt, wenn »two_phase« eingeschaltet ist" -#: commands/subscriptioncmds.c:2124 -#, fuzzy, c-format -#| msgid "Use ALTER SUBSCRIPTION ... REFRESH with copy_data = false, or use DROP/CREATE SUBSCRIPTION." +#: commands/subscriptioncmds.c:2211 +#, c-format msgid "Use ALTER SUBSCRIPTION ... REFRESH PUBLICATION with copy_data = false, or use DROP/CREATE SUBSCRIPTION." -msgstr "Verwenden Sie ALTER SUBSCRIPTION ... REFRESH mit copy_data = false, oder verwenden Sie DROP/CREATE SUBSCRIPTION." +msgstr "Verwenden Sie ALTER SUBSCRIPTION ... REFRESH PUBLICATION mit copy_data = false, oder verwenden Sie DROP/CREATE SUBSCRIPTION." -#: commands/subscriptioncmds.c:2170 -#, fuzzy, c-format -#| msgid "skip WAL location (LSN %X/%X) must be greater than origin LSN %X/%X" +#: commands/subscriptioncmds.c:2258 +#, c-format msgid "skip WAL location (LSN %X/%08X) must be greater than origin LSN %X/%08X" -msgstr "zu überspringende WAL-Position (LSN %X/%X) muss größer als Origin-LSN %X/%X sein" +msgstr "zu überspringende WAL-Position (LSN %X/%08X) muss größer als Origin-LSN %X/%08X sein" -#: commands/subscriptioncmds.c:2349 +#: commands/subscriptioncmds.c:2437 #, c-format msgid "subscription \"%s\" does not exist, skipping" msgstr "Subskription »%s« existiert nicht, wird übersprungen" -#: commands/subscriptioncmds.c:2627 +#: commands/subscriptioncmds.c:2715 #, c-format msgid "dropped replication slot \"%s\" on publisher" msgstr "Replikations-Slot »%s« auf dem Publikationsserver wurde gelöscht" -#: commands/subscriptioncmds.c:2636 commands/subscriptioncmds.c:2644 +#: commands/subscriptioncmds.c:2724 commands/subscriptioncmds.c:2732 #, c-format msgid "could not drop replication slot \"%s\" on publisher: %s" msgstr "konnte Replikations-Slot »%s« auf dem Publikationsserver nicht löschen: %s" -#: commands/subscriptioncmds.c:2714 -#, fuzzy, c-format -#| msgid "user mapping for \"%s\" does not exist for server \"%s\"" -msgid "new subscription owner \"%s\" does not have permission on foreign server \"%s\"" -msgstr "Benutzerabbildung für »%s« existiert nicht für Server »%s«" - -#: commands/subscriptioncmds.c:2790 +#: commands/subscriptioncmds.c:2872 #, c-format msgid "subscription with OID %u does not exist" msgstr "Subskription mit OID %u existiert nicht" -#: commands/subscriptioncmds.c:2905 commands/subscriptioncmds.c:3289 +#: commands/subscriptioncmds.c:2995 commands/subscriptioncmds.c:3384 #, c-format msgid "could not receive list of replicated tables from the publisher: %s" msgstr "konnte Liste der replizierten Tabellen nicht vom Publikationsserver empfangen: %s" -#: commands/subscriptioncmds.c:2944 commands/subscriptioncmds.c:3064 +#: commands/subscriptioncmds.c:3034 #, c-format msgid "subscription \"%s\" requested copy_data with origin = NONE but might copy data that had a different origin" msgstr "Subskription »%s« verlangte copy_data mit origin = NONE, aber könnte Daten kopieren, die einen anderen Origin hatten" -#: commands/subscriptioncmds.c:2946 commands/subscriptioncmds.c:2955 -#, fuzzy, c-format -#| msgid "The subscription being created subscribes to a publication (%s) that contains tables that are written to by other subscriptions." -#| msgid_plural "The subscription being created subscribes to publications (%s) that contain tables that are written to by other subscriptions." +#: commands/subscriptioncmds.c:3036 commands/subscriptioncmds.c:3045 +#, c-format msgid "The subscription subscribes to a publication (%s) that contains tables that are written to by other subscriptions." msgid_plural "The subscription subscribes to publications (%s) that contain tables that are written to by other subscriptions." -msgstr[0] "Die zu erzeugende Subskription hat eine Publikation (%s) abonniert, die Tabellen enthält, in die von anderen Subskriptionen geschrieben wird." -msgstr[1] "Die zu erzeugende Subskription hat Publikationen (%s) abonniert, die Tabellen enthalten, in die von anderen Subskriptionen geschrieben wird." +msgstr[0] "Die Subskription hat eine Publikation (%s) abonniert, die Tabellen enthält, in die von anderen Subskriptionen geschrieben wird." +msgstr[1] "Die Subskription hat Publikationen (%s) abonniert, die Tabellen enthalten, in die von anderen Subskriptionen geschrieben wird." -#: commands/subscriptioncmds.c:2949 +#: commands/subscriptioncmds.c:3039 #, c-format msgid "Verify that initial data copied from the publisher tables did not come from other origins." msgstr "Überprüfen Sie, dass die von den publizierten Tabellen kopierten initialen Daten nicht von anderen Origins kamen." -#: commands/subscriptioncmds.c:2953 +#: commands/subscriptioncmds.c:3043 #, c-format msgid "subscription \"%s\" enabled retain_dead_tuples but might not reliably detect conflicts for changes from different origins" -msgstr "" +msgstr "Subskription »%s« hat retain_dead_tuples eingeschaltet, aber erkennt möglicherweise Konflikte für Änderungen von verschiedenen Origins nicht zuverlässig" -#: commands/subscriptioncmds.c:2958 +#: commands/subscriptioncmds.c:3048 #, c-format msgid "Consider using origin = NONE or disabling retain_dead_tuples." -msgstr "" +msgstr "Verwenden Sie eventuell origin = NONE oder schalten Sie retain_dead_tuples aus." -#: commands/subscriptioncmds.c:3032 -#, fuzzy, c-format -#| msgid "could not receive list of replicated tables from the publisher: %s" +#: commands/subscriptioncmds.c:3122 +#, c-format msgid "could not receive list of replicated sequences from the publisher: %s" -msgstr "konnte Liste der replizierten Tabellen nicht vom Publikationsserver empfangen: %s" +msgstr "konnte Liste der replizierten Sequenzen nicht vom Publikationsserver empfangen: %s" -#: commands/subscriptioncmds.c:3066 -#, fuzzy, c-format -#| msgid "The subscription being created subscribes to a publication (%s) that contains tables that are written to by other subscriptions." -#| msgid_plural "The subscription being created subscribes to publications (%s) that contain tables that are written to by other subscriptions." -msgid "The subscription subscribes to a publication (%s) that contains sequences that are written to by other subscriptions." -msgid_plural "The subscription subscribes to publications (%s) that contain sequences that are written to by other subscriptions." -msgstr[0] "Die zu erzeugende Subskription hat eine Publikation (%s) abonniert, die Tabellen enthält, in die von anderen Subskriptionen geschrieben wird." -msgstr[1] "Die zu erzeugende Subskription hat Publikationen (%s) abonniert, die Tabellen enthalten, in die von anderen Subskriptionen geschrieben wird." - -#: commands/subscriptioncmds.c:3069 -#, fuzzy, c-format -#| msgid "Verify that initial data copied from the publisher tables did not come from other origins." -msgid "Verify that initial data copied from the publisher sequences did not come from other origins." -msgstr "Überprüfen Sie, dass die von den publizierten Tabellen kopierten initialen Daten nicht von anderen Origins kamen." +#: commands/subscriptioncmds.c:3154 +#, c-format +msgid "subscription \"%s\" requested origin = NONE but might synchronize sequence values that had a different origin" +msgstr "Subskription »%s« verlangte origin = NONE, aber könnte Sequenzwerte synchronisieren, die einen anderen Origin hatten" + +#: commands/subscriptioncmds.c:3156 +#, c-format +msgid "The subscription subscribes to a publication (%s) that contains sequences that are synchronized from other subscriptions." +msgid_plural "The subscription subscribes to publications (%s) that contain sequences that are synchronized from other subscriptions." +msgstr[0] "Die Subskription hat eine Publikation (%s) abonniert, die Sequenzen enthält, die von anderen Subskriptionen synchronisiert werden." +msgstr[1] "Die Subskription hat Publikationen (%s) abonniert, die Sequenzen enthalten, die von anderen Subskriptionen synchronisiert werden." + +#: commands/subscriptioncmds.c:3159 +#, c-format +msgid "Verify that the initial values copied from the publisher sequences did not come from other origins." +msgstr "Überprüfen Sie, dass die von den publizierten Sequenzen kopierten initialen Werte nicht von anderen Origins kamen." -#: commands/subscriptioncmds.c:3099 +#: commands/subscriptioncmds.c:3194 #, c-format msgid "cannot enable retain_dead_tuples if the publisher is running a version earlier than PostgreSQL 19" -msgstr "" +msgstr "retain_dead_tuples kann nicht eingeschaltet werden, wenn der Publikationsserver eine Version älter als PostgreSQL 19 verwendet" -#: commands/subscriptioncmds.c:3106 -#, fuzzy, c-format -#| msgid "could not obtain recovery progress: %s" +#: commands/subscriptioncmds.c:3201 +#, c-format msgid "could not obtain recovery progress from the publisher: %s" -msgstr "konnte Recovery-Fortschritt nicht ermitteln: %s" +msgstr "konnte Recovery-Fortschritt nicht vom Publikationsserver ermitteln: %s" -#: commands/subscriptioncmds.c:3118 +#: commands/subscriptioncmds.c:3213 #, c-format msgid "cannot enable retain_dead_tuples if the publisher is in recovery" -msgstr "" +msgstr "retain_dead_tuples kann nicht eingeschaltet werden, wenn der Publikationsserver in der Wiederherstellung ist" -#: commands/subscriptioncmds.c:3162 -#, fuzzy, c-format -#| msgid "\"wal_level\" is insufficient to publish logical changes" +#: commands/subscriptioncmds.c:3257 +#, c-format msgid "\"wal_level\" is insufficient to create the replication slot required by retain_dead_tuples" -msgstr "»wal_level« ist nicht ausreichend, um logische Veränderungen zu publizieren" +msgstr "»wal_level« ist nicht ausreichend, um den von retain_dead_tuples benötigten Replikations-Slot zu erzeugen" -#: commands/subscriptioncmds.c:3168 +#: commands/subscriptioncmds.c:3263 #, c-format msgid "commit timestamp and origin data required for detecting conflicts won't be retained" -msgstr "" +msgstr "Commit-Timestamp und Origin-Daten, die zum Erkennen von Konflikten benötigt werden, werden nicht aufbewahrt" -#: commands/subscriptioncmds.c:3169 +#: commands/subscriptioncmds.c:3264 #, c-format msgid "Consider setting \"%s\" to true." -msgstr "" +msgstr "Setzen Sie »%s« eventuell auf true." -#: commands/subscriptioncmds.c:3175 +#: commands/subscriptioncmds.c:3270 #, c-format msgid "deleted rows to detect conflicts would not be removed until the subscription is enabled" -msgstr "" +msgstr "gelöschte Zeilen zum Erkennen von Konflikten würden erst entfernt, wenn die Subskription eingeschaltet ist" -#: commands/subscriptioncmds.c:3177 -#, fuzzy, c-format -#| msgid "Consider using tablespaces instead." +#: commands/subscriptioncmds.c:3272 +#, c-format msgid "Consider setting %s to false." -msgstr "Verwenden Sie stattdessen Tablespaces." +msgstr "Setzen Sie %s eventuell auf false." -#: commands/subscriptioncmds.c:3184 +#: commands/subscriptioncmds.c:3279 #, c-format msgid "max_retention_duration is ineffective when retain_dead_tuples is disabled" -msgstr "" +msgstr "max_retention_duration ist wirkungslos, wenn retain_dead_tuples ausgeschaltet ist" -#: commands/subscriptioncmds.c:3317 replication/logical/tablesync.c:851 +#: commands/subscriptioncmds.c:3412 replication/logical/tablesync.c:851 #: replication/pgoutput/pgoutput.c:1191 #, c-format msgid "cannot use different column lists for table \"%s.%s\" in different publications" msgstr "für Tabelle »%s.%s« können nicht verschiedene Spaltenlisten für verschiedene Publikationen verwendet werden" -#: commands/subscriptioncmds.c:3367 +#: commands/subscriptioncmds.c:3462 #, c-format msgid "could not connect to publisher when attempting to drop replication slot \"%s\": %s" msgstr "konnte beim Versuch den Replikations-Slot »%s« zu löschen nicht mit dem Publikationsserver verbinden: %s" #. translator: %s is an SQL ALTER command -#: commands/subscriptioncmds.c:3370 +#: commands/subscriptioncmds.c:3465 #, c-format msgid "Use %s to disable the subscription, and then use %s to disassociate it from the slot." msgstr "Verwenden Sie %s, um die Subskription zu deaktivieren, und dann %s, um sie vom Slot zu trennen." -#: commands/subscriptioncmds.c:3401 +#: commands/subscriptioncmds.c:3496 #, c-format msgid "publication name \"%s\" used more than once" msgstr "Publikationsname »%s« mehrmals angegeben" -#: commands/subscriptioncmds.c:3445 +#: commands/subscriptioncmds.c:3540 #, c-format msgid "publication \"%s\" is already in subscription \"%s\"" msgstr "Publikation »%s« ist bereits in Subskription »%s«" -#: commands/subscriptioncmds.c:3459 +#: commands/subscriptioncmds.c:3554 #, c-format msgid "publication \"%s\" is not in subscription \"%s\"" msgstr "Publikation »%s« ist nicht in Subskription »%s«" -#: commands/subscriptioncmds.c:3470 +#: commands/subscriptioncmds.c:3565 #, c-format msgid "cannot drop all the publications from a subscription" msgstr "kann nicht alle Publikationen von einer Subskription löschen" -#: commands/subscriptioncmds.c:3527 +#: commands/subscriptioncmds.c:3622 #, c-format msgid "%s requires a Boolean value or \"parallel\"" msgstr "%s erfordert einen Boole’schen Wert oder »parallel«" @@ -14567,7 +14376,7 @@ msgstr "materialisierte Sicht »%s« existiert nicht, wird übersprungen" msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." msgstr "Verwenden Sie DROP MATERIALIZED VIEW, um eine materialisierte Sicht zu löschen." -#: commands/tablecmds.c:286 commands/tablecmds.c:310 commands/tablecmds.c:22310 +#: commands/tablecmds.c:286 commands/tablecmds.c:310 commands/tablecmds.c:22300 #: parser/parse_utilcmd.c:2434 #, c-format msgid "index \"%s\" does not exist" @@ -14591,8 +14400,8 @@ msgstr "»%s« ist kein Typ" msgid "Use DROP TYPE to remove a type." msgstr "Verwenden Sie DROP TYPE, um einen Typen zu löschen." -#: commands/tablecmds.c:298 commands/tablecmds.c:16635 -#: commands/tablecmds.c:19328 +#: commands/tablecmds.c:298 commands/tablecmds.c:16625 +#: commands/tablecmds.c:19318 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "Fremdtabelle »%s« existiert nicht" @@ -14635,7 +14444,7 @@ msgstr "partitionierte Tabellen können nicht ungeloggt sein" msgid "cannot create temporary table within security-restricted operation" msgstr "kann temporäre Tabelle nicht in einer sicherheitsbeschränkten Operation erzeugen" -#: commands/tablecmds.c:930 commands/tablecmds.c:18057 +#: commands/tablecmds.c:930 commands/tablecmds.c:18047 #, c-format msgid "relation \"%s\" would be inherited from more than once" msgstr "von der Relation »%s« würde mehrmals geerbt werden" @@ -14660,7 +14469,7 @@ msgstr "kann keine Fremdpartition der partitionierten Tabelle »%s« erzeugen" msgid "Table \"%s\" contains indexes that are unique." msgstr "Tabelle »%s« enthält Unique Indexe." -#: commands/tablecmds.c:1482 commands/tablecmds.c:15444 +#: commands/tablecmds.c:1482 commands/tablecmds.c:15434 #, c-format msgid "too many array dimensions" msgstr "zu viele Array-Dimensionen" @@ -14711,7 +14520,7 @@ msgstr "kann Fremdtabelle »%s« nicht leeren" msgid "cannot truncate temporary tables of other sessions" msgstr "kann temporäre Tabellen anderer Sitzungen nicht leeren" -#: commands/tablecmds.c:2751 commands/tablecmds.c:17951 +#: commands/tablecmds.c:2751 commands/tablecmds.c:17941 #, c-format msgid "cannot inherit from partitioned table \"%s\"" msgstr "von partitionierter Tabelle »%s« kann nicht geerbt werden" @@ -14727,23 +14536,23 @@ msgstr "von Partition »%s« kann nicht geerbt werden" msgid "inherited relation \"%s\" is not a table or foreign table" msgstr "geerbte Relation »%s« ist keine Tabelle oder Fremdtabelle" -#: commands/tablecmds.c:2776 commands/tablecmds.c:23173 +#: commands/tablecmds.c:2776 commands/tablecmds.c:23163 #, c-format msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" msgstr "eine temporäre Relation kann nicht als Partition der permanenten Relation »%s« erzeugt werden" -#: commands/tablecmds.c:2785 commands/tablecmds.c:17932 +#: commands/tablecmds.c:2785 commands/tablecmds.c:17922 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "von temporärer Relation »%s« kann nicht geerbt werden" -#: commands/tablecmds.c:2794 commands/tablecmds.c:17939 +#: commands/tablecmds.c:2794 commands/tablecmds.c:17929 #, c-format msgid "cannot inherit from temporary relation of another session" msgstr "von temporärer Relation einer anderen Sitzung kann nicht geerbt werden" #: commands/tablecmds.c:2949 commands/tablecmds.c:3003 -#: commands/tablecmds.c:15127 parser/parse_utilcmd.c:1438 +#: commands/tablecmds.c:15117 parser/parse_utilcmd.c:1438 #: parser/parse_utilcmd.c:1482 parser/parse_utilcmd.c:1914 #: parser/parse_utilcmd.c:2026 #, c-format @@ -14781,13 +14590,13 @@ msgid "A child table column cannot be generated unless its parent column is." msgstr "Eine Spalte einer abgeleiteten Tabelle kann nur generiert sein, wenn die Spalte in der Elterntabelle es auch ist." #: commands/tablecmds.c:3147 commands/tablecmds.c:3441 -#: commands/tablecmds.c:18219 +#: commands/tablecmds.c:18209 #, c-format msgid "column \"%s\" inherits from generated column of different kind" msgstr "Spalte »%s« erbt von einer generierten Spalte einer anderen Art" #: commands/tablecmds.c:3149 commands/tablecmds.c:3443 -#: commands/tablecmds.c:18220 +#: commands/tablecmds.c:18210 #, c-format msgid "Parent column is %s, child column is %s." msgstr "Spalte in Elterntabelle ist %s, Spalte in abgeleiteter Tabelle ist %s." @@ -14856,7 +14665,7 @@ msgid "column \"%s\" has a collation conflict" msgstr "für Spalte »%s« besteht ein Sortierfolgenkonflikt" #: commands/tablecmds.c:3357 commands/tablecmds.c:3523 -#: commands/tablecmds.c:7385 parser/parse_expr.c:4914 +#: commands/tablecmds.c:7385 parser/parse_expr.c:4917 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "»%s« gegen »%s«" @@ -14988,7 +14797,7 @@ msgstr "kann temporäre Tabellen anderer Sitzungen nicht neu schreiben" msgid "column \"%s\" of relation \"%s\" contains null values" msgstr "Spalte »%s« von Relation »%s« enthält NULL-Werte" -#: commands/tablecmds.c:6589 commands/tablecmds.c:22847 +#: commands/tablecmds.c:6589 commands/tablecmds.c:22837 #, c-format msgid "check constraint \"%s\" of relation \"%s\" is violated by some row" msgstr "Check-Constraint »%s« von Relation »%s« wird von irgendeiner Zeile verletzt" @@ -15059,12 +14868,12 @@ msgstr "zu einer getypten Tabelle kann keine Spalte hinzugefügt werden" msgid "cannot add column to a partition" msgstr "zu einer Partition kann keine Spalte hinzugefügt werden" -#: commands/tablecmds.c:7377 commands/tablecmds.c:18175 +#: commands/tablecmds.c:7377 commands/tablecmds.c:18165 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" msgstr "abgeleitete Tabelle »%s« hat unterschiedlichen Typ für Spalte »%s«" -#: commands/tablecmds.c:7383 commands/tablecmds.c:18181 +#: commands/tablecmds.c:7383 commands/tablecmds.c:18171 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" msgstr "abgeleitete Tabelle »%s« hat unterschiedliche Sortierfolge für Spalte »%s«" @@ -15094,19 +14903,19 @@ msgstr "Spalte »%s« von Relation »%s« existiert bereits, wird übersprungen" msgid "column \"%s\" of relation \"%s\" already exists" msgstr "Spalte »%s« von Relation »%s« existiert bereits" -#: commands/tablecmds.c:7877 commands/tablecmds.c:8044 -#: commands/tablecmds.c:8245 commands/tablecmds.c:8376 -#: commands/tablecmds.c:8530 commands/tablecmds.c:8624 -#: commands/tablecmds.c:8727 commands/tablecmds.c:8917 -#: commands/tablecmds.c:9083 commands/tablecmds.c:9174 -#: commands/tablecmds.c:9308 commands/tablecmds.c:14899 -#: commands/tablecmds.c:16658 commands/tablecmds.c:19417 +#: commands/tablecmds.c:7877 commands/tablecmds.c:8040 +#: commands/tablecmds.c:8241 commands/tablecmds.c:8372 +#: commands/tablecmds.c:8526 commands/tablecmds.c:8620 +#: commands/tablecmds.c:8723 commands/tablecmds.c:8908 +#: commands/tablecmds.c:9074 commands/tablecmds.c:9165 +#: commands/tablecmds.c:9299 commands/tablecmds.c:14889 +#: commands/tablecmds.c:16648 commands/tablecmds.c:19407 #, c-format msgid "cannot alter system column \"%s\"" msgstr "Systemspalte »%s« kann nicht geändert werden" -#: commands/tablecmds.c:7883 commands/tablecmds.c:8251 -#: commands/tablecmds.c:14660 +#: commands/tablecmds.c:7883 commands/tablecmds.c:8247 +#: commands/tablecmds.c:14650 #, c-format msgid "column \"%s\" of relation \"%s\" is an identity column" msgstr "Spalte »%s« von Relation »%s« ist eine Identitätsspalte" @@ -15116,1120 +14925,1110 @@ msgstr "Spalte »%s« von Relation »%s« ist eine Identitätsspalte" msgid "column \"%s\" is marked NOT NULL in parent table" msgstr "Spalte »%s« ist in Elterntabelle als NOT NULL markiert" -#: commands/tablecmds.c:8122 commands/tablecmds.c:10116 +#: commands/tablecmds.c:8118 commands/tablecmds.c:10106 #, c-format msgid "constraint must be added to child tables too" msgstr "Constraint muss ebenso in den abgeleiteten Tabellen hinzugefügt werden" -#: commands/tablecmds.c:8123 commands/tablecmds.c:8354 -#: commands/tablecmds.c:8486 commands/tablecmds.c:8603 -#: commands/tablecmds.c:9481 commands/tablecmds.c:12310 -#: commands/tablecmds.c:12783 +#: commands/tablecmds.c:8119 commands/tablecmds.c:8350 +#: commands/tablecmds.c:8482 commands/tablecmds.c:8599 +#: commands/tablecmds.c:9472 commands/tablecmds.c:12300 +#: commands/tablecmds.c:12773 #, c-format msgid "Do not specify the ONLY keyword." msgstr "Lassen Sie das Schlüsselwort ONLY weg." -#: commands/tablecmds.c:8260 +#: commands/tablecmds.c:8256 #, c-format msgid "column \"%s\" of relation \"%s\" is a generated column" msgstr "Spalte »%s« von Relation »%s« ist eine generierte Spalte" -#: commands/tablecmds.c:8353 +#: commands/tablecmds.c:8349 #, c-format msgid "cannot add identity to a column of only the partitioned table" msgstr "Identität kann nicht einer Spalte nur in der partitionierten Tabelle hinzugefügt werden" -#: commands/tablecmds.c:8359 +#: commands/tablecmds.c:8355 #, c-format msgid "cannot add identity to a column of a partition" msgstr "zu einer Spalte einer Partition kann keine Identität hinzugefügt werden" -#: commands/tablecmds.c:8387 +#: commands/tablecmds.c:8383 #, c-format msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" msgstr "Spalte »%s« von Relation »%s« muss als NOT NULL deklariert werden, bevor Sie Identitätsspalte werden kann" -#: commands/tablecmds.c:8418 +#: commands/tablecmds.c:8414 #, c-format msgid "column \"%s\" of relation \"%s\" is already an identity column" msgstr "Spalte »%s« von Relation »%s« ist bereits eine Identitätsspalte" -#: commands/tablecmds.c:8424 +#: commands/tablecmds.c:8420 #, c-format msgid "column \"%s\" of relation \"%s\" already has a default value" msgstr "Spalte »%s« von Relation »%s« hat bereits einen Vorgabewert" -#: commands/tablecmds.c:8485 +#: commands/tablecmds.c:8481 #, c-format msgid "cannot change identity column of only the partitioned table" msgstr "Identitätsspalte kann nicht nur in der partitionierten Tabelle geändert werden" -#: commands/tablecmds.c:8491 +#: commands/tablecmds.c:8487 #, c-format msgid "cannot change identity column of a partition" msgstr "Identitätsspalte einer Partition kann nicht geändert werden" -#: commands/tablecmds.c:8536 commands/tablecmds.c:8632 +#: commands/tablecmds.c:8532 commands/tablecmds.c:8628 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column" msgstr "Spalte »%s« von Relation »%s« ist keine Identitätsspalte" -#: commands/tablecmds.c:8602 +#: commands/tablecmds.c:8598 #, c-format msgid "cannot drop identity from a column of only the partitioned table" msgstr "Identität kann nicht von einer Spalte nur in der partitionierten Tabelle gelöscht werden" -#: commands/tablecmds.c:8608 +#: commands/tablecmds.c:8604 #, c-format msgid "cannot drop identity from a column of a partition" msgstr "Identität kann nicht von einer Spalte einer Partition gelöscht werden" -#: commands/tablecmds.c:8637 +#: commands/tablecmds.c:8633 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" msgstr "Spalte »%s« von Relation »%s« ist keine Identitätsspalte, wird übersprungen" -#: commands/tablecmds.c:8734 commands/tablecmds.c:8938 +#: commands/tablecmds.c:8730 commands/tablecmds.c:8929 #, c-format msgid "column \"%s\" of relation \"%s\" is not a generated column" msgstr "Spalte »%s« von Relation »%s« ist keine generierte Spalte" -#: commands/tablecmds.c:8751 +#: commands/tablecmds.c:8747 #, c-format msgid "ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns in tables that are part of a publication" msgstr "ALTER TABLE / SET EXPRESSION wird nicht unterstützt für virtuelle generierte Spalten in Tabellen, die Teil einer Publikation sind" -#: commands/tablecmds.c:8752 commands/tablecmds.c:8930 +#: commands/tablecmds.c:8748 commands/tablecmds.c:8921 #, c-format msgid "Column \"%s\" of relation \"%s\" is a virtual generated column." msgstr "Spalte »%s« von Relation »%s« ist eine virtuelle generierte Spalte." -#: commands/tablecmds.c:8864 +#: commands/tablecmds.c:8855 #, c-format msgid "ALTER TABLE / DROP EXPRESSION must be applied to child tables too" msgstr "ALTER TABLE / DROP EXPRESSION muss auch auf abgeleitete Tabellen angewendet werden" -#: commands/tablecmds.c:8886 +#: commands/tablecmds.c:8877 #, c-format msgid "cannot drop generation expression from inherited column" msgstr "Generierungsausdruck von vererbter Spalte kann nicht gelöscht werden" -#: commands/tablecmds.c:8929 +#: commands/tablecmds.c:8920 #, c-format msgid "ALTER TABLE / DROP EXPRESSION is not supported for virtual generated columns" msgstr "ALTER TABLE / DROP EXPRESSION wird für virtuelle generierte Spalten nicht unterstützt" -#: commands/tablecmds.c:8943 +#: commands/tablecmds.c:8934 #, c-format msgid "column \"%s\" of relation \"%s\" is not a generated column, skipping" msgstr "Spalte »%s« von Relation »%s« ist keine generierte Spalte, wird übersprungen" -#: commands/tablecmds.c:9021 +#: commands/tablecmds.c:9012 #, c-format msgid "cannot refer to non-index column by number" msgstr "auf eine Nicht-Index-Spalte kann nicht per Nummer verwiesen werden" -#: commands/tablecmds.c:9073 +#: commands/tablecmds.c:9064 #, c-format msgid "column number %d of relation \"%s\" does not exist" msgstr "Spalte Nummer %d von Relation »%s« existiert nicht" -#: commands/tablecmds.c:9093 +#: commands/tablecmds.c:9084 #, c-format msgid "cannot alter statistics on virtual generated column \"%s\"" msgstr "Statistiken von virtueller generierter Spalte »%s« können nicht geändert werden" -#: commands/tablecmds.c:9102 +#: commands/tablecmds.c:9093 #, c-format msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" msgstr "Statistiken von eingeschlossener Spalte »%s« von Index »%s« können nicht geändert werden" -#: commands/tablecmds.c:9107 +#: commands/tablecmds.c:9098 #, c-format msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" msgstr "kann Statistiken von Spalte »%s« von Index »%s«, welche kein Ausdruck ist, nicht ändern" -#: commands/tablecmds.c:9109 +#: commands/tablecmds.c:9100 #, c-format msgid "Alter statistics on table column instead." msgstr "Ändern Sie stattdessen die Statistiken für die Tabellenspalte." -#: commands/tablecmds.c:9355 +#: commands/tablecmds.c:9346 #, c-format msgid "cannot drop column from typed table" msgstr "aus einer getypten Tabelle können keine Spalten gelöscht werden" -#: commands/tablecmds.c:9419 +#: commands/tablecmds.c:9410 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" msgstr "Spalte »%s« von Relation »%s« existiert nicht, wird übersprungen" -#: commands/tablecmds.c:9432 +#: commands/tablecmds.c:9423 #, c-format msgid "cannot drop system column \"%s\"" msgstr "Systemspalte »%s« kann nicht gelöscht werden" -#: commands/tablecmds.c:9442 +#: commands/tablecmds.c:9433 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "geerbte Spalte »%s« kann nicht gelöscht werden" -#: commands/tablecmds.c:9455 +#: commands/tablecmds.c:9446 #, c-format msgid "cannot drop column \"%s\" because it is part of the partition key of relation \"%s\"" msgstr "Spalte »%s« kann nicht gelöscht werden, weil sie Teil des Partitionierungsschlüssels von Relation »%s« ist" -#: commands/tablecmds.c:9480 +#: commands/tablecmds.c:9471 #, c-format msgid "cannot drop column from only the partitioned table when partitions exist" msgstr "Spalte kann nicht nur aus der partitionierten Tabelle gelöscht werden, wenn Partitionen existieren" -#: commands/tablecmds.c:9645 +#: commands/tablecmds.c:9636 #, c-format msgid "column \"%s\" of table \"%s\" is not marked NOT NULL" msgstr "Spalte »%s« von Tabelle »%s« ist nicht als NOT NULL markiert" -#: commands/tablecmds.c:9681 commands/tablecmds.c:9693 +#: commands/tablecmds.c:9672 commands/tablecmds.c:9684 #, c-format msgid "cannot create primary key on column \"%s\"" msgstr "kann keinen Primärschlüssel über Spalte »%s« erzeugen" #. translator: fourth %s is a constraint characteristic such as NOT VALID -#: commands/tablecmds.c:9683 commands/tablecmds.c:9695 +#: commands/tablecmds.c:9674 commands/tablecmds.c:9686 #, c-format msgid "The constraint \"%s\" on column \"%s\" of table \"%s\", marked %s, is incompatible with a primary key." msgstr "Der Constraint »%s« für Spalte »%s« von Tabelle »%s«, markiert als %s, ist inkompatibel mit einem Primärschlüssel." -#: commands/tablecmds.c:9820 +#: commands/tablecmds.c:9811 #, c-format msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX wird für partitionierte Tabellen nicht unterstützt" -#: commands/tablecmds.c:9845 +#: commands/tablecmds.c:9836 #, c-format msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX benennt Index »%s« um in »%s«" -#: commands/tablecmds.c:10203 +#: commands/tablecmds.c:10193 #, c-format msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" msgstr "ONLY nicht möglich für Fremdschlüssel für partitionierte Tabelle »%s« verweisend auf Relation »%s«" -#: commands/tablecmds.c:10211 commands/tablecmds.c:10838 +#: commands/tablecmds.c:10201 commands/tablecmds.c:10828 #, c-format msgid "referenced relation \"%s\" is not a table" msgstr "Relation »%s«, auf die verwiesen wird, ist keine Tabelle" -#: commands/tablecmds.c:10234 +#: commands/tablecmds.c:10224 #, c-format msgid "constraints on permanent tables may reference only permanent tables" msgstr "Constraints für permanente Tabellen dürfen nur auf permanente Tabellen verweisen" -#: commands/tablecmds.c:10241 +#: commands/tablecmds.c:10231 #, c-format msgid "constraints on unlogged tables may reference only permanent or unlogged tables" msgstr "Constraints für ungeloggte Tabellen dürfen nur auf permanente oder ungeloggte Tabellen verweisen" -#: commands/tablecmds.c:10247 +#: commands/tablecmds.c:10237 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "Constraints für temporäre Tabellen dürfen nur auf temporäre Tabellen verweisen" -#: commands/tablecmds.c:10251 +#: commands/tablecmds.c:10241 #, c-format msgid "constraints on temporary tables must involve temporary tables of this session" msgstr "Constraints für temporäre Tabellen müssen temporäre Tabellen dieser Sitzung beinhalten" -#: commands/tablecmds.c:10266 commands/tablecmds.c:10294 +#: commands/tablecmds.c:10256 commands/tablecmds.c:10284 #, c-format msgid "foreign key uses PERIOD on the referenced table but not the referencing table" msgstr "Fremdschlüssel verwendet PERIOD für die Tabelle, auf die verwiesen wird, aber nicht für die verweisende Tabelle" -#: commands/tablecmds.c:10306 +#: commands/tablecmds.c:10296 #, c-format msgid "foreign key uses PERIOD on the referencing table but not the referenced table" msgstr "Fremdschlüssel verwendet PERIOD für die verweisende Tabelle, aber nicht für die Tabelle, auf die verwiesen wird" -#: commands/tablecmds.c:10320 +#: commands/tablecmds.c:10310 #, c-format msgid "foreign key must use PERIOD when referencing a primary key using WITHOUT OVERLAPS" msgstr "Fremdschlüssel muss PERIOD verwenden, wenn auf einen Primärschlüssel verwiesen wird, der WITHOUT OVERLAPS verwendet" -#: commands/tablecmds.c:10344 commands/tablecmds.c:10350 +#: commands/tablecmds.c:10334 commands/tablecmds.c:10340 #, c-format msgid "invalid %s action for foreign key constraint containing generated column" msgstr "ungültige %s-Aktion für Fremdschlüssel-Constraint, der eine generierte Spalte enthält" -#: commands/tablecmds.c:10365 +#: commands/tablecmds.c:10355 #, c-format msgid "foreign key constraints on virtual generated columns are not supported" msgstr "Fremdschlüssel-Constraints für virtuelle generierte Spalten werden nicht unterstützt" -#: commands/tablecmds.c:10379 commands/tablecmds.c:10388 +#: commands/tablecmds.c:10369 commands/tablecmds.c:10378 #, c-format msgid "unsupported %s action for foreign key constraint using PERIOD" msgstr "nicht unterstützte %s-Aktion für Fremdschlüssel-Constraint, der PERIOD verwendet" -#: commands/tablecmds.c:10403 +#: commands/tablecmds.c:10393 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "Anzahl der Quell- und Zielspalten im Fremdschlüssel stimmt nicht überein" -#: commands/tablecmds.c:10459 +#: commands/tablecmds.c:10449 #, c-format msgid "could not identify an overlaps operator for foreign key" msgstr "konnte keinen Überlappungsoperator für den Fremdschlüssel ermitteln" -#: commands/tablecmds.c:10460 +#: commands/tablecmds.c:10450 #, c-format msgid "could not identify an equality operator for foreign key" msgstr "konnte keinen Ist-Gleich-Operator für den Fremdschlüssel ermitteln" -#: commands/tablecmds.c:10525 commands/tablecmds.c:10559 +#: commands/tablecmds.c:10515 commands/tablecmds.c:10549 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "Fremdschlüssel-Constraint »%s« kann nicht implementiert werden" -#: commands/tablecmds.c:10527 +#: commands/tablecmds.c:10517 #, c-format msgid "Key columns \"%s\" of the referencing table and \"%s\" of the referenced table are of incompatible types: %s and %s." msgstr "Schlüsselspalten »%s« der referenzierenden Tabelle und »%s« der referenzierten Tabelle haben inkompatible Typen: %s und %s." -#: commands/tablecmds.c:10560 +#: commands/tablecmds.c:10550 #, c-format msgid "Key columns \"%s\" of the referencing table and \"%s\" of the referenced table have incompatible collations: \"%s\" and \"%s\". If either collation is nondeterministic, then both collations have to be the same." msgstr "Schlüsselspalten »%s« der referenzierenden Tabelle und »%s« der referenzierten Tabelle haben inkompatible Sortierfolgen: »%s« und »%s«. Wenn eine der Sortierfolgen nichtdeterministisch ist, dann müssen beide Sortierfolgen die selbe sein." -#: commands/tablecmds.c:10766 +#: commands/tablecmds.c:10756 #, c-format msgid "column \"%s\" referenced in ON DELETE SET action must be part of foreign key" msgstr "Spalte »%s«, auf die in der ON-DELETE-SET-Aktion verwiesen wird, muss Teil des Fremdschlüssels sein" -#: commands/tablecmds.c:11150 commands/tablecmds.c:11583 +#: commands/tablecmds.c:11140 commands/tablecmds.c:11573 #: parser/parse_utilcmd.c:939 parser/parse_utilcmd.c:1084 #, c-format msgid "foreign key constraints are not supported on foreign tables" msgstr "Fremdschlüssel-Constraints auf Fremdtabellen werden nicht unterstützt" -#: commands/tablecmds.c:11566 +#: commands/tablecmds.c:11556 #, c-format msgid "cannot attach table \"%s\" as a partition because it is referenced by foreign key \"%s\"" msgstr "kann Tabelle »%s« nicht als Partition anfügen, weil auf sie von Fremdschlüssel »%s« verwiesen wird" -#: commands/tablecmds.c:11847 +#: commands/tablecmds.c:11837 #, c-format msgid "constraint \"%s\" enforceability conflicts with constraint \"%s\" on relation \"%s\"" msgstr "ENFORCED-Einstellung von Constraint »%s« kollidiert mit Constraint »%s« für Relation »%s«" -#: commands/tablecmds.c:12309 +#: commands/tablecmds.c:12299 #, c-format msgid "constraint must be altered in child tables too" msgstr "Constraint muss ebenso in den abgeleiteten Tabellen geändert werden" -#: commands/tablecmds.c:12338 commands/tablecmds.c:12890 -#: commands/tablecmds.c:13421 commands/tablecmds.c:14539 -#: commands/tablecmds.c:14768 +#: commands/tablecmds.c:12328 commands/tablecmds.c:12880 +#: commands/tablecmds.c:13411 commands/tablecmds.c:14529 +#: commands/tablecmds.c:14758 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "Constraint »%s« von Relation »%s« existiert nicht" -#: commands/tablecmds.c:12345 +#: commands/tablecmds.c:12335 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "Constraint »%s« von Relation »%s« ist kein Fremdschlüssel-Constraint" -#: commands/tablecmds.c:12351 +#: commands/tablecmds.c:12341 #, c-format msgid "cannot alter enforceability of constraint \"%s\" of relation \"%s\"" msgstr "ENFORCED-Einstellung des Constraints »%s« von Relation »%s« kann nicht geändert werden" -#: commands/tablecmds.c:12353 +#: commands/tablecmds.c:12343 #, c-format msgid "Only foreign key and check constraints can change enforceability." -msgstr "" +msgstr "Nur Fremdschlüssel- und Check-Constraints können die ENFORCED-Einstellung ändern." -#: commands/tablecmds.c:12358 +#: commands/tablecmds.c:12348 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a not-null constraint" msgstr "Constraint »%s« von Relation »%s« ist kein Not-Null-Constraint" -#: commands/tablecmds.c:12364 -#, fuzzy, c-format -#| msgid "not-null constraints on partitioned tables cannot be NO INHERIT" +#: commands/tablecmds.c:12354 +#, c-format msgid "not-null constraint \"%s\" on partitioned table \"%s\" cannot be NO INHERIT" -msgstr "Not-Null-Constraints für partitionierte Tabellen können nicht NO INHERIT sein" +msgstr "Not-Null-Constraint »%s« für partitionierte Tabelle »%s« kann nicht NO INHERIT sein" -#: commands/tablecmds.c:12372 +#: commands/tablecmds.c:12362 #, c-format msgid "cannot alter inherited constraint \"%s\" on relation \"%s\"" msgstr "geerbter Constraint »%s« von Relation »%s« kann nicht geändert werden" -#: commands/tablecmds.c:12412 +#: commands/tablecmds.c:12402 #, c-format msgid "cannot alter constraint \"%s\" on relation \"%s\"" msgstr "Constraint »%s« von Relation »%s« kann nicht geändert werden" -#: commands/tablecmds.c:12415 +#: commands/tablecmds.c:12405 #, c-format msgid "Constraint \"%s\" is derived from constraint \"%s\" of relation \"%s\"." msgstr "Constraint »%s« ist von Constraint »%s« von Relation »%s« abgeleitet." -#: commands/tablecmds.c:12417 +#: commands/tablecmds.c:12407 #, c-format msgid "You may alter the constraint it derives from instead." msgstr "Sie können stattdessen den Constraint, von dem er abgeleitet ist, ändern." -#: commands/tablecmds.c:12713 -#, fuzzy, c-format -#| msgid "cannot rename inherited constraint \"%s\"" +#: commands/tablecmds.c:12703 +#, c-format msgid "cannot mark inherited constraint \"%s\" as %s" -msgstr "kann vererbten Constraint »%s« nicht umbenennen" +msgstr "kann vererbten Constraint »%s« nicht als %s markieren" -#: commands/tablecmds.c:12716 -#, fuzzy, c-format -#| msgid "Make sure the configuration parameter \"%s\" is set." +#: commands/tablecmds.c:12706 +#, c-format msgid "The matching constraint on parent table \"%s\" is %s." -msgstr "Stellen Sie sicher, dass der Konfigurationsparameter »%s« gesetzt ist." +msgstr "Der passende Constraint für Elterntabelle »%s« ist %s." -#: commands/tablecmds.c:12782 -#, fuzzy, c-format -#| msgid "constraint must be altered in child tables too" +#: commands/tablecmds.c:12772 +#, c-format msgid "constraint must be altered on child tables too" msgstr "Constraint muss ebenso in den abgeleiteten Tabellen geändert werden" -#: commands/tablecmds.c:13430 +#: commands/tablecmds.c:13420 #, c-format msgid "cannot validate constraint \"%s\" of relation \"%s\"" msgstr "Constraint »%s« von Relation »%s« kann nicht validiert werden" -#: commands/tablecmds.c:13432 +#: commands/tablecmds.c:13422 #, c-format msgid "This operation is not supported for this type of constraint." msgstr "Diese Operation wird für diese Art von Constraint nicht unterstützt." -#: commands/tablecmds.c:13437 +#: commands/tablecmds.c:13427 #, c-format msgid "cannot validate NOT ENFORCED constraint" msgstr "auf NOT ENFORCED gesetzter Constraint kann nicht validiert werden" -#: commands/tablecmds.c:13649 commands/tablecmds.c:13749 +#: commands/tablecmds.c:13639 commands/tablecmds.c:13739 #, c-format msgid "constraint must be validated on child tables too" msgstr "Constraint muss ebenso in den abgeleiteten Tabellen validiert werden" -#: commands/tablecmds.c:13826 +#: commands/tablecmds.c:13816 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" msgstr "Spalte »%s«, die im Fremdschlüssel verwendet wird, existiert nicht" -#: commands/tablecmds.c:13832 +#: commands/tablecmds.c:13822 #, c-format msgid "system columns cannot be used in foreign keys" msgstr "Systemspalten können nicht in Fremdschlüsseln verwendet werden" -#: commands/tablecmds.c:13836 +#: commands/tablecmds.c:13826 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "Fremdschlüssel kann nicht mehr als %d Schlüssel haben" -#: commands/tablecmds.c:13904 +#: commands/tablecmds.c:13894 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "aufschiebbarer Primärschlüssel kann nicht für Tabelle »%s«, auf die verwiesen wird, verwendet werden" -#: commands/tablecmds.c:13921 +#: commands/tablecmds.c:13911 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "in Tabelle »%s«, auf die verwiesen wird, gibt es keinen Primärschlüssel" -#: commands/tablecmds.c:13994 +#: commands/tablecmds.c:13984 #, c-format msgid "foreign key referenced-columns list must not contain duplicates" msgstr "die Liste der Spalten, auf die ein Fremdschlüssel verweist, darf keine doppelten Einträge enthalten" -#: commands/tablecmds.c:14097 +#: commands/tablecmds.c:14087 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "aufschiebbarer Unique-Constraint kann nicht für Tabelle »%s«, auf die verwiesen wird, verwendet werden" -#: commands/tablecmds.c:14102 +#: commands/tablecmds.c:14092 #, c-format msgid "there is no unique constraint matching given keys for referenced table \"%s\"" msgstr "in Tabelle »%s«, auf die verwiesen wird, gibt es keinen Unique-Constraint, der auf die angegebenen Schlüssel passt" -#: commands/tablecmds.c:14543 +#: commands/tablecmds.c:14533 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" msgstr "Constraint »%s« von Relation »%s« existiert nicht, wird übersprungen" -#: commands/tablecmds.c:14588 +#: commands/tablecmds.c:14578 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "geerbter Constraint »%s« von Relation »%s« kann nicht gelöscht werden" -#: commands/tablecmds.c:14640 +#: commands/tablecmds.c:14630 #, c-format msgid "column \"%s\" is in a primary key" msgstr "Spalte »%s« ist in einem Primärschlüssel" -#: commands/tablecmds.c:14648 +#: commands/tablecmds.c:14638 #, c-format msgid "column \"%s\" is in index used as replica identity" msgstr "Spalte »%s« ist in einem Index, der als Replik-Identität verwendet wird" -#: commands/tablecmds.c:14881 +#: commands/tablecmds.c:14871 #, c-format msgid "cannot alter column type of typed table" msgstr "Spaltentyp einer getypten Tabelle kann nicht geändert werden" -#: commands/tablecmds.c:14909 +#: commands/tablecmds.c:14899 #, c-format msgid "cannot specify USING when altering type of generated column" msgstr "USING kann nicht angegeben werden, wenn der Typ einer generierten Spalte geändert wird" -#: commands/tablecmds.c:14921 +#: commands/tablecmds.c:14911 #, c-format msgid "cannot alter inherited column \"%s\"" msgstr "kann vererbte Spalte »%s« nicht ändern" -#: commands/tablecmds.c:14930 +#: commands/tablecmds.c:14920 #, c-format msgid "cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"" msgstr "Spalte »%s« kann nicht geändert werden, weil sie Teil des Partitionierungsschlüssels von Relation »%s« ist" -#: commands/tablecmds.c:14985 +#: commands/tablecmds.c:14975 #, c-format msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" msgstr "Ergebnis der USING-Klausel für Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" -#: commands/tablecmds.c:14988 +#: commands/tablecmds.c:14978 #, c-format msgid "You might need to add an explicit cast." msgstr "Sie müssen möglicherweise eine ausdrückliche Typumwandlung hinzufügen." -#: commands/tablecmds.c:14992 +#: commands/tablecmds.c:14982 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" msgstr "Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" #. translator: USING is SQL, don't translate it -#: commands/tablecmds.c:14996 +#: commands/tablecmds.c:14986 #, c-format msgid "You might need to specify \"USING %s::%s\"." msgstr "Sie müssen möglicherweise »USING %s::%s« angeben." -#: commands/tablecmds.c:15099 +#: commands/tablecmds.c:15089 #, c-format msgid "cannot alter inherited column \"%s\" of relation \"%s\"" msgstr "geerbte Spalte »%s« von Relation »%s« kann nicht geändert werden" -#: commands/tablecmds.c:15128 +#: commands/tablecmds.c:15118 #, c-format msgid "USING expression contains a whole-row table reference." msgstr "USING-Ausdruck enthält einen Verweis auf die ganze Zeile der Tabelle." -#: commands/tablecmds.c:15139 +#: commands/tablecmds.c:15129 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" msgstr "Typ der vererbten Spalte »%s« muss ebenso in den abgeleiteten Tabellen geändert werden" -#: commands/tablecmds.c:15264 +#: commands/tablecmds.c:15254 #, c-format msgid "cannot alter type of column \"%s\" twice" msgstr "Typ der Spalte »%s« kann nicht zweimal geändert werden" -#: commands/tablecmds.c:15302 +#: commands/tablecmds.c:15292 #, c-format msgid "generation expression for column \"%s\" cannot be cast automatically to type %s" msgstr "Generierungsausdruck der Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" -#: commands/tablecmds.c:15307 +#: commands/tablecmds.c:15297 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "Vorgabewert der Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" -#: commands/tablecmds.c:15611 +#: commands/tablecmds.c:15601 #, c-format msgid "cannot alter type of a column used by a function or procedure" msgstr "Typ einer Spalte, die von einer Funktion oder Prozedur verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:15612 commands/tablecmds.c:15627 -#: commands/tablecmds.c:15647 commands/tablecmds.c:15666 -#: commands/tablecmds.c:15725 +#: commands/tablecmds.c:15602 commands/tablecmds.c:15617 +#: commands/tablecmds.c:15637 commands/tablecmds.c:15656 +#: commands/tablecmds.c:15715 #, c-format -msgid "%s depends on column \"%s\"" -msgstr "%s hängt von Spalte »%s« ab" +msgid "%s depends on column \"%s\"." +msgstr "%s hängt von Spalte »%s« ab." -#: commands/tablecmds.c:15626 +#: commands/tablecmds.c:15616 #, c-format msgid "cannot alter type of a column used by a view or rule" msgstr "Typ einer Spalte, die von einer Sicht oder Regel verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:15646 +#: commands/tablecmds.c:15636 #, c-format msgid "cannot alter type of a column used in a trigger definition" msgstr "Typ einer Spalte, die in einer Trigger-Definition verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:15665 +#: commands/tablecmds.c:15655 #, c-format msgid "cannot alter type of a column used in a policy definition" msgstr "Typ einer Spalte, die in einer Policy-Definition verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:15696 +#: commands/tablecmds.c:15686 #, c-format msgid "cannot alter type of a column used by a generated column" msgstr "Typ einer Spalte, die von einer generierten Spalte verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:15697 +#: commands/tablecmds.c:15687 #, c-format msgid "Column \"%s\" is used by generated column \"%s\"." msgstr "Spalte »%s« wird von generierter Spalte »%s« verwendet." -#: commands/tablecmds.c:15724 +#: commands/tablecmds.c:15714 #, c-format msgid "cannot alter type of a column used by a publication WHERE clause" msgstr "Typ einer Spalte, die in der WHERE-Klausel einer Publikation verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:16767 commands/tablecmds.c:16779 +#: commands/tablecmds.c:16757 commands/tablecmds.c:16769 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "kann Eigentümer des Index »%s« nicht ändern" -#: commands/tablecmds.c:16769 commands/tablecmds.c:16781 +#: commands/tablecmds.c:16759 commands/tablecmds.c:16771 #, c-format msgid "Change the ownership of the index's table instead." msgstr "Ändern Sie stattdessen den Eigentümer der Tabelle des Index." -#: commands/tablecmds.c:16795 +#: commands/tablecmds.c:16785 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "kann Eigentümer der Sequenz »%s« nicht ändern" -#: commands/tablecmds.c:16820 +#: commands/tablecmds.c:16810 #, c-format msgid "cannot change owner of relation \"%s\"" msgstr "kann Eigentümer der Relation »%s« nicht ändern" -#: commands/tablecmds.c:17287 +#: commands/tablecmds.c:17277 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "mehrere SET TABLESPACE Unterbefehle sind ungültig" -#: commands/tablecmds.c:17366 +#: commands/tablecmds.c:17356 #, c-format msgid "cannot set options for relation \"%s\"" msgstr "für Relation »%s« können keine Optionen gesetzt werden" -#: commands/tablecmds.c:17400 commands/view.c:440 +#: commands/tablecmds.c:17390 commands/view.c:440 #, c-format msgid "WITH CHECK OPTION is supported only on automatically updatable views" msgstr "WITH CHECK OPTION wird nur für automatisch aktualisierbare Sichten unterstützt" -#: commands/tablecmds.c:17653 +#: commands/tablecmds.c:17643 #, c-format msgid "only tables, indexes, and materialized views exist in tablespaces" msgstr "nur Tabellen, Indexe und materialisierte Sichten existieren in Tablespaces" -#: commands/tablecmds.c:17665 +#: commands/tablecmds.c:17655 #, c-format msgid "cannot move relations in to or out of pg_global tablespace" msgstr "Relationen können nicht in den oder aus dem Tablespace »pg_global« verschoben werden" -#: commands/tablecmds.c:17757 +#: commands/tablecmds.c:17747 #, c-format msgid "aborting because lock on relation \"%s.%s\" is not available" msgstr "Abbruch weil Sperre für Relation »%s.%s« nicht verfügbar ist" -#: commands/tablecmds.c:17773 +#: commands/tablecmds.c:17763 #, c-format msgid "no matching relations in tablespace \"%s\" found" msgstr "keine passenden Relationen in Tablespace »%s« gefunden" -#: commands/tablecmds.c:17893 +#: commands/tablecmds.c:17883 #, c-format msgid "cannot change inheritance of typed table" msgstr "Vererbung einer getypten Tabelle kann nicht geändert werden" -#: commands/tablecmds.c:17898 +#: commands/tablecmds.c:17888 #, c-format msgid "cannot change inheritance of a partition" msgstr "Vererbung einer Partition kann nicht geändert werden" -#: commands/tablecmds.c:17945 +#: commands/tablecmds.c:17935 #, c-format msgid "cannot inherit to temporary relation of another session" msgstr "an temporäre Relation einer anderen Sitzung kann nicht vererbt werden" -#: commands/tablecmds.c:17958 +#: commands/tablecmds.c:17948 #, c-format msgid "cannot inherit from a partition" msgstr "von einer Partition kann nicht geerbt werden" -#: commands/tablecmds.c:17980 commands/tablecmds.c:21076 +#: commands/tablecmds.c:17970 commands/tablecmds.c:21066 #, c-format msgid "circular inheritance not allowed" msgstr "zirkuläre Vererbung ist nicht erlaubt" -#: commands/tablecmds.c:17981 commands/tablecmds.c:21077 +#: commands/tablecmds.c:17971 commands/tablecmds.c:21067 #, c-format msgid "\"%s\" is already a child of \"%s\"." msgstr "»%s« ist schon von »%s« abgeleitet." -#: commands/tablecmds.c:17994 +#: commands/tablecmds.c:17984 #, c-format msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" msgstr "Trigger »%s« verhindert, dass Tabelle »%s« ein Vererbungskind werden kann" -#: commands/tablecmds.c:17996 +#: commands/tablecmds.c:17986 #, c-format msgid "ROW triggers with transition tables are not supported in inheritance hierarchies." msgstr "ROW-Trigger mit Übergangstabellen werden in Vererbungshierarchien nicht unterstützt." -#: commands/tablecmds.c:18200 commands/tablecmds.c:18449 +#: commands/tablecmds.c:18190 commands/tablecmds.c:18439 #, c-format msgid "column \"%s\" in child table \"%s\" must be marked NOT NULL" msgstr "Spalte »%s« in abgeleiteter Tabelle »%s« muss als NOT NULL markiert sein" -#: commands/tablecmds.c:18210 +#: commands/tablecmds.c:18200 #, c-format msgid "column \"%s\" in child table must be a generated column" msgstr "Spalte »%s« in abgeleiteter Tabelle muss eine generierte Spalte sein" -#: commands/tablecmds.c:18214 +#: commands/tablecmds.c:18204 #, c-format msgid "column \"%s\" in child table must not be a generated column" msgstr "Spalte »%s« in abgeleiteter Tabelle darf keine generierte Spalte sein" -#: commands/tablecmds.c:18260 +#: commands/tablecmds.c:18250 #, c-format msgid "child table is missing column \"%s\"" msgstr "Spalte »%s« fehlt in abgeleiteter Tabelle" -#: commands/tablecmds.c:18377 +#: commands/tablecmds.c:18367 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" msgstr "abgeleitete Tabelle »%s« hat unterschiedliche Definition für Check-Constraint »%s«" -#: commands/tablecmds.c:18386 +#: commands/tablecmds.c:18376 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" msgstr "Constraint »%s« kollidiert mit nicht vererbtem Constraint für abgeleitete Tabelle »%s«" -#: commands/tablecmds.c:18397 +#: commands/tablecmds.c:18387 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" msgstr "Constraint »%s« kollidiert mit NOT-VALID-Constraint für abgeleitete Tabelle »%s«" -#: commands/tablecmds.c:18408 +#: commands/tablecmds.c:18398 #, c-format msgid "constraint \"%s\" conflicts with NOT ENFORCED constraint on child table \"%s\"" msgstr "Constraint »%s« kollidiert mit NOT-ENFORCED-Constraint für abgeleitete Tabelle »%s«" -#: commands/tablecmds.c:18457 +#: commands/tablecmds.c:18447 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "Constraint »%s« fehlt in abgeleiteter Tabelle" -#: commands/tablecmds.c:18539 +#: commands/tablecmds.c:18529 #, c-format msgid "partition \"%s\" already pending detach in partitioned table \"%s.%s\"" msgstr "Partition »%s« hat schon eine unerledigte Abtrennoperation in der partitionierten Tabelle »%s.%s«" -#: commands/tablecmds.c:18568 commands/tablecmds.c:18616 +#: commands/tablecmds.c:18558 commands/tablecmds.c:18606 #: parser/parse_utilcmd.c:3558 #, c-format msgid "relation \"%s\" is not a partition of relation \"%s\"" msgstr "Relation »%s« ist keine Partition von Relation »%s«" -#: commands/tablecmds.c:18622 +#: commands/tablecmds.c:18612 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "Relation »%s« ist keine Basisrelation von Relation »%s«" -#: commands/tablecmds.c:18893 +#: commands/tablecmds.c:18883 #, c-format msgid "typed tables cannot inherit" msgstr "getypte Tabellen können nicht erben" -#: commands/tablecmds.c:18923 +#: commands/tablecmds.c:18913 #, c-format msgid "table is missing column \"%s\"" msgstr "Spalte »%s« fehlt in Tabelle" -#: commands/tablecmds.c:18934 +#: commands/tablecmds.c:18924 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" msgstr "Tabelle hat Spalte »%s«, aber Typ benötigt »%s«" -#: commands/tablecmds.c:18943 +#: commands/tablecmds.c:18933 #, c-format msgid "table \"%s\" has different type for column \"%s\"" msgstr "Tabelle »%s« hat unterschiedlichen Typ für Spalte »%s«" -#: commands/tablecmds.c:18957 +#: commands/tablecmds.c:18947 #, c-format msgid "table has extra column \"%s\"" msgstr "Tabelle hat zusätzliche Spalte »%s«" -#: commands/tablecmds.c:19009 +#: commands/tablecmds.c:18999 #, c-format msgid "\"%s\" is not a typed table" msgstr "»%s« ist keine getypte Tabelle" -#: commands/tablecmds.c:19189 +#: commands/tablecmds.c:19179 #, c-format msgid "cannot use non-unique index \"%s\" as replica identity" msgstr "nicht eindeutiger Index »%s« kann nicht als Replik-Identität verwendet werden" -#: commands/tablecmds.c:19195 +#: commands/tablecmds.c:19185 #, c-format msgid "cannot use non-immediate index \"%s\" as replica identity" msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil er nicht IMMEDIATE ist" -#: commands/tablecmds.c:19201 +#: commands/tablecmds.c:19191 #, c-format msgid "cannot use expression index \"%s\" as replica identity" msgstr "Ausdrucksindex »%s« kann nicht als Replik-Identität verwendet werden" -#: commands/tablecmds.c:19207 +#: commands/tablecmds.c:19197 #, c-format msgid "cannot use partial index \"%s\" as replica identity" msgstr "partieller Index »%s« kann nicht als Replik-Identität verwendet werden" -#: commands/tablecmds.c:19224 +#: commands/tablecmds.c:19214 #, c-format msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil Spalte %d eine Systemspalte ist" -#: commands/tablecmds.c:19231 +#: commands/tablecmds.c:19221 #, c-format msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil Spalte »%s« NULL-Werte akzeptiert" -#: commands/tablecmds.c:19480 +#: commands/tablecmds.c:19470 #, c-format msgid "cannot change logged status of table \"%s\" because it is temporary" msgstr "kann den geloggten Status der Tabelle »%s« nicht ändern, weil sie temporär ist" -#: commands/tablecmds.c:19504 +#: commands/tablecmds.c:19494 #, c-format msgid "cannot change table \"%s\" to unlogged because it is part of a publication" msgstr "kann Tabelle »%s« nicht in ungeloggt ändern, weil sie Teil einer Publikation ist" -#: commands/tablecmds.c:19506 +#: commands/tablecmds.c:19496 #, c-format msgid "Unlogged relations cannot be replicated." msgstr "Ungeloggte Relationen können nicht repliziert werden." -#: commands/tablecmds.c:19551 +#: commands/tablecmds.c:19541 #, c-format msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" msgstr "konnte Tabelle »%s« nicht in geloggt ändern, weil sie auf die ungeloggte Tabelle »%s« verweist" -#: commands/tablecmds.c:19561 +#: commands/tablecmds.c:19551 #, c-format msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" msgstr "konnte Tabelle »%s« nicht in ungeloggt ändern, weil sie auf die geloggte Tabelle »%s« verweist" -#: commands/tablecmds.c:19625 +#: commands/tablecmds.c:19615 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "einer Tabelle zugeordnete Sequenz kann nicht in ein anderes Schema verschoben werden" -#: commands/tablecmds.c:19733 +#: commands/tablecmds.c:19723 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "Relation »%s« existiert bereits in Schema »%s«" -#: commands/tablecmds.c:20158 +#: commands/tablecmds.c:20148 #, c-format msgid "\"%s\" is not a table or materialized view" msgstr "»%s« ist keine Tabelle oder materialisierte Sicht" -#: commands/tablecmds.c:20311 +#: commands/tablecmds.c:20301 #, c-format msgid "\"%s\" is not a composite type" msgstr "»%s« ist kein zusammengesetzter Typ" -#: commands/tablecmds.c:20346 +#: commands/tablecmds.c:20336 #, c-format msgid "cannot change schema of index \"%s\"" msgstr "kann Schema des Index »%s« nicht ändern" -#: commands/tablecmds.c:20348 commands/tablecmds.c:20362 +#: commands/tablecmds.c:20338 commands/tablecmds.c:20352 #, c-format msgid "Change the schema of the table instead." msgstr "Ändern Sie stattdessen das Schema der Tabelle." -#: commands/tablecmds.c:20352 +#: commands/tablecmds.c:20342 #, c-format msgid "cannot change schema of composite type \"%s\"" msgstr "kann Schema des zusammengesetzten Typs »%s« nicht ändern" -#: commands/tablecmds.c:20360 +#: commands/tablecmds.c:20350 #, c-format msgid "cannot change schema of TOAST table \"%s\"" msgstr "kann Schema der TOAST-Tabelle »%s« nicht ändern" -#: commands/tablecmds.c:20392 +#: commands/tablecmds.c:20382 #, c-format msgid "cannot use \"list\" partition strategy with more than one column" msgstr "Partitionierungsstrategie »list« kann nicht mit mehr als einer Spalte verwendet werden" -#: commands/tablecmds.c:20458 +#: commands/tablecmds.c:20448 #, c-format msgid "column \"%s\" named in partition key does not exist" msgstr "Spalte »%s«, die im Partitionierungsschlüssel verwendet wird, existiert nicht" -#: commands/tablecmds.c:20466 +#: commands/tablecmds.c:20456 #, c-format msgid "cannot use system column \"%s\" in partition key" msgstr "Systemspalte »%s« kann nicht im Partitionierungsschlüssel verwendet werden" -#: commands/tablecmds.c:20480 commands/tablecmds.c:20562 +#: commands/tablecmds.c:20470 commands/tablecmds.c:20552 #, c-format msgid "cannot use generated column in partition key" msgstr "generierte Spalte kann nicht im Partitionierungsschlüssel verwendet werden" -#: commands/tablecmds.c:20549 +#: commands/tablecmds.c:20539 #, c-format msgid "partition key expressions cannot contain system column references" msgstr "Partitionierungsschlüsselausdruck kann nicht auf Systemspalten verweisen" -#: commands/tablecmds.c:20613 +#: commands/tablecmds.c:20603 #, c-format msgid "functions in partition key expression must be marked IMMUTABLE" msgstr "Funktionen im Partitionierungsschlüsselausdruck müssen als IMMUTABLE markiert sein" -#: commands/tablecmds.c:20622 +#: commands/tablecmds.c:20612 #, c-format msgid "cannot use constant expression as partition key" msgstr "Partitionierungsschlüssel kann kein konstanter Ausdruck sein" -#: commands/tablecmds.c:20643 +#: commands/tablecmds.c:20633 #, c-format msgid "could not determine which collation to use for partition expression" msgstr "konnte die für den Partitionierungsausdruck zu verwendende Sortierfolge nicht bestimmen" -#: commands/tablecmds.c:20678 +#: commands/tablecmds.c:20668 #, c-format msgid "You must specify a hash operator class or define a default hash operator class for the data type." msgstr "Sie müssen eine hash-Operatorklasse angeben oder eine hash-Standardoperatorklasse für den Datentyp definieren." -#: commands/tablecmds.c:20684 +#: commands/tablecmds.c:20674 #, c-format msgid "You must specify a btree operator class or define a default btree operator class for the data type." msgstr "Sie müssen eine btree-Operatorklasse angeben oder eine btree-Standardoperatorklasse für den Datentyp definieren." -#: commands/tablecmds.c:20979 +#: commands/tablecmds.c:20969 #, c-format msgid "\"%s\" is already a partition" msgstr "»%s« ist bereits eine Partition" -#: commands/tablecmds.c:20985 +#: commands/tablecmds.c:20975 #, c-format msgid "cannot attach a typed table as partition" msgstr "eine getypte Tabelle kann nicht als Partition angefügt werden" -#: commands/tablecmds.c:21013 -#, fuzzy, c-format -#| msgid "cannot attach table \"%s\" as a partition because it is referenced by foreign key \"%s\"" +#: commands/tablecmds.c:21003 +#, c-format msgid "cannot attach table \"%s\" as partition because it is referenced in publication %s EXCEPT clause" msgid_plural "cannot attach table \"%s\" as partition because it is referenced in publications %s EXCEPT clause" -msgstr[0] "kann Tabelle »%s« nicht als Partition anfügen, weil auf sie von Fremdschlüssel »%s« verwiesen wird" -msgstr[1] "kann Tabelle »%s« nicht als Partition anfügen, weil auf sie von Fremdschlüssel »%s« verwiesen wird" +msgstr[0] "kann Tabelle »%s« nicht als Partition anfügen, weil auf sie in der EXCEPT-Klausel von Publikation %s verwiesen wird" +msgstr[1] "kann Tabelle »%s« nicht als Partition anfügen, weil auf sie in der EXCEPT-Klausel von Publikationen %s verwiesen wird" -#: commands/tablecmds.c:21018 +#: commands/tablecmds.c:21008 #, c-format msgid "The publication EXCEPT clause cannot contain tables that are partitions." -msgstr "" +msgstr "Die EXCEPT-Klausel der Publikation kann keine Tabellen enthalten, die Partitionen sind." -#: commands/tablecmds.c:21019 +#: commands/tablecmds.c:21009 #, c-format msgid "Change the publication's EXCEPT clause using ALTER PUBLICATION ... SET ALL TABLES." -msgstr "" +msgstr "Ändern Sie die EXCEPT-Klausel der Publikation mit ALTER PUBLICATION ... SET ALL TABLES." -#: commands/tablecmds.c:21038 +#: commands/tablecmds.c:21028 #, c-format msgid "cannot attach inheritance child as partition" msgstr "ein Vererbungskind kann nicht als Partition angefügt werden" -#: commands/tablecmds.c:21052 +#: commands/tablecmds.c:21042 #, c-format msgid "cannot attach inheritance parent as partition" msgstr "eine Tabelle mit abgeleiteten Tabellen kann nicht als Partition angefügt werden" -#: commands/tablecmds.c:21086 +#: commands/tablecmds.c:21076 #, c-format msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" msgstr "eine temporäre Relation kann nicht als Partition an permanente Relation »%s« angefügt werden" -#: commands/tablecmds.c:21094 +#: commands/tablecmds.c:21084 #, c-format msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" msgstr "eine permanente Relation kann nicht als Partition an temporäre Relation »%s« angefügt werden" -#: commands/tablecmds.c:21101 +#: commands/tablecmds.c:21091 #, c-format msgid "cannot attach as partition of temporary relation of another session" msgstr "kann nicht als Partition an temporäre Relation einer anderen Sitzung anfügen" -#: commands/tablecmds.c:21107 +#: commands/tablecmds.c:21097 #, c-format msgid "cannot attach temporary relation of another session as partition" msgstr "temporäre Relation einer anderen Sitzung kann nicht als Partition angefügt werden" -#: commands/tablecmds.c:21127 +#: commands/tablecmds.c:21117 #, c-format msgid "table \"%s\" being attached contains an identity column \"%s\"" msgstr "anzufügende Tabelle »%s« enthält eine Identitätsspalte »%s«" -#: commands/tablecmds.c:21129 +#: commands/tablecmds.c:21119 #, c-format msgid "The new partition may not contain an identity column." msgstr "Die neue Partition darf keine Identitätsspalte enthalten." -#: commands/tablecmds.c:21137 +#: commands/tablecmds.c:21127 #, c-format msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" msgstr "Tabelle »%s« enthält Spalte »%s«, die nicht in der Elterntabelle »%s« gefunden wurde" -#: commands/tablecmds.c:21140 +#: commands/tablecmds.c:21130 #, c-format msgid "The new partition may contain only the columns present in parent." msgstr "Die neue Partition darf nur Spalten enthalten, die auch die Elterntabelle hat." -#: commands/tablecmds.c:21152 +#: commands/tablecmds.c:21142 #, c-format msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" msgstr "Trigger »%s« verhindert, dass Tabelle »%s« eine Partition werden kann" -#: commands/tablecmds.c:21154 +#: commands/tablecmds.c:21144 #, c-format msgid "ROW triggers with transition tables are not supported on partitions." msgstr "ROW-Trigger mit Übergangstabellen werden für Partitionen nicht unterstützt." -#: commands/tablecmds.c:21320 +#: commands/tablecmds.c:21310 #, c-format msgid "cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"" msgstr "kann Fremdtabelle »%s« nicht als Partition an partitionierte Tabelle »%s« anfügen" -#: commands/tablecmds.c:21323 +#: commands/tablecmds.c:21313 #, c-format msgid "Partitioned table \"%s\" contains unique indexes." msgstr "Partitionierte Tabelle »%s« enthält Unique-Indexe." -#: commands/tablecmds.c:21647 +#: commands/tablecmds.c:21637 #, c-format msgid "cannot detach partitions concurrently when a default partition exists" msgstr "nebenläufiges Abtrennen einer Partition ist nicht möglich, wenn eine Standardpartition existiert" -#: commands/tablecmds.c:21750 +#: commands/tablecmds.c:21740 #, c-format msgid "partitioned table \"%s\" was removed concurrently" msgstr "partitionierte Tabelle »%s« wurde nebenläufig entfernt" -#: commands/tablecmds.c:21756 +#: commands/tablecmds.c:21746 #, c-format msgid "partition \"%s\" was removed concurrently" msgstr "Partition »%s« wurde nebenläufig entfernt" -#: commands/tablecmds.c:22347 commands/tablecmds.c:22367 -#: commands/tablecmds.c:22388 commands/tablecmds.c:22407 -#: commands/tablecmds.c:22464 +#: commands/tablecmds.c:22337 commands/tablecmds.c:22357 +#: commands/tablecmds.c:22378 commands/tablecmds.c:22397 +#: commands/tablecmds.c:22454 #, c-format msgid "cannot attach index \"%s\" as a partition of index \"%s\"" msgstr "kann Index »%s« nicht als Partition an Index »%s« anfügen" -#: commands/tablecmds.c:22350 +#: commands/tablecmds.c:22340 #, c-format msgid "Index \"%s\" is already attached to another index." msgstr "Index »%s« ist bereits an einen anderen Index angefügt." -#: commands/tablecmds.c:22370 +#: commands/tablecmds.c:22360 #, c-format msgid "Index \"%s\" is not an index on any partition of table \"%s\"." msgstr "Index »%s« ist kein Index irgendeiner Partition von Tabelle »%s«." -#: commands/tablecmds.c:22391 +#: commands/tablecmds.c:22381 #, c-format msgid "The index definitions do not match." msgstr "Die Indexdefinitionen stimmen nicht überein." -#: commands/tablecmds.c:22410 +#: commands/tablecmds.c:22400 #, c-format msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." msgstr "Der Index »%s« gehört zu einem Constraint in Tabelle »%s«, aber kein Constraint existiert für Index »%s«." -#: commands/tablecmds.c:22467 -#, fuzzy, c-format -#| msgid "Another index is already attached for partition \"%s\"." +#: commands/tablecmds.c:22457 +#, c-format msgid "Another index \"%s\" is already attached for partition \"%s\"." -msgstr "Ein anderer Index ist bereits für Partition »%s« angefügt." +msgstr "Ein anderer Index »%s« ist bereits für Partition »%s« angefügt." -#: commands/tablecmds.c:22591 +#: commands/tablecmds.c:22581 #, c-format msgid "invalid primary key definition" msgstr "ungültige Primärschlüsseldefinition" -#: commands/tablecmds.c:22592 +#: commands/tablecmds.c:22582 #, c-format msgid "Column \"%s\" of relation \"%s\" is not marked NOT NULL." msgstr "Spalte »%s« von Relation »%s« ist nicht als NOT NULL markiert." -#: commands/tablecmds.c:22727 +#: commands/tablecmds.c:22717 #, c-format msgid "column data type %s does not support compression" msgstr "Spaltendatentyp %s unterstützt keine Komprimierung" -#: commands/tablecmds.c:22734 +#: commands/tablecmds.c:22724 #, c-format msgid "invalid compression method \"%s\"" msgstr "ungültige Komprimierungsmethode »%s«" -#: commands/tablecmds.c:22760 +#: commands/tablecmds.c:22750 #, c-format msgid "invalid storage type \"%s\"" msgstr "ungültiger Storage-Typ »%s«" -#: commands/tablecmds.c:22770 +#: commands/tablecmds.c:22760 #, c-format msgid "column data type %s can only have storage PLAIN" msgstr "Spaltendatentyp %s kann nur Storage-Typ PLAIN" -#: commands/tablecmds.c:23144 -#, fuzzy, c-format -#| msgid "cannot attach as partition of temporary relation of another session" +#: commands/tablecmds.c:23134 +#, c-format msgid "cannot create as partition of temporary relation of another session" -msgstr "kann nicht als Partition an temporäre Relation einer anderen Sitzung anfügen" +msgstr "kann nicht als Partition einer temporären Relation einer anderen Sitzung erzeugen" -#: commands/tablecmds.c:23181 -#, fuzzy, c-format -#| msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" +#: commands/tablecmds.c:23171 +#, c-format msgid "cannot create a permanent relation as partition of temporary relation \"%s\"" -msgstr "eine permanente Relation kann nicht als Partition an temporäre Relation »%s« angefügt werden" +msgstr "eine permanente Relation kann nicht als Partition einer temporären Relation »%s« erzeugt werden" -#: commands/tablecmds.c:23570 -#, fuzzy, c-format -#| msgid "cannot alter partition \"%s\" with an incomplete detach" +#: commands/tablecmds.c:23560 +#, c-format msgid "cannot merge partitions with conflicting extension dependencies" -msgstr "kann Partition »%s« mit einer unvollständigen Abtrennoperation nicht ändern" +msgstr "kann Partitionen mit widersprüchlichen Erweiterungsabhängigkeiten nicht zusammenführen" -#: commands/tablecmds.c:23571 +#: commands/tablecmds.c:23561 #, c-format msgid "Partition indexes \"%s\" and \"%s\" depend on different extensions." -msgstr "" +msgstr "Partitionsindexe »%s« und »%s« hängen von verschiedenen Erweiterungen ab." -#: commands/tablecmds.c:23707 +#: commands/tablecmds.c:23697 #, c-format msgid "partitions being merged have different owners" -msgstr "" +msgstr "die zusammenzuführenden Partitionen haben verschiedene Eigentümer" -#: commands/tablecmds.c:24073 -#, fuzzy, c-format -#| msgid "cannot inherit from a partition" +#: commands/tablecmds.c:24063 +#, c-format msgid "cannot find partition for split partition row" -msgstr "von einer Partition kann nicht geerbt werden" +msgstr "kann keine Partition für Zeile der aufzuteilenden Partition finden" #: commands/tablespace.c:195 commands/tablespace.c:652 #, c-format @@ -16252,10 +16051,9 @@ msgid "tablespace location cannot contain single quotes" msgstr "Tablespace-Pfad darf keine Apostrophe enthalten" #: commands/tablespace.c:250 commands/tablespace.c:985 -#, fuzzy, c-format -#| msgid "database name contains a newline or carriage return: \"%s\"\n" +#, c-format msgid "tablespace name \"%s\" contains a newline or carriage return character" -msgstr "Datenbankname enthält Newline oder Carriage Return: »%s«\n" +msgstr "Tablespace-Name »%s« enthält Newline- oder Carriage-Return-Zeichen" #: commands/tablespace.c:263 #, c-format @@ -16605,25 +16403,25 @@ msgstr "Vor der Ausführung von Trigger »%s« gehörte die Zeile in Partition msgid "cannot collect transition tuples from child foreign tables" msgstr "aus abgeleiteten Fremdtabellen können keine Übergangstupel gesammelt werden" -#: commands/trigger.c:3403 executor/nodeModifyTable.c:1962 -#: executor/nodeModifyTable.c:2036 executor/nodeModifyTable.c:2876 -#: executor/nodeModifyTable.c:2966 executor/nodeModifyTable.c:3791 -#: executor/nodeModifyTable.c:3988 +#: commands/trigger.c:3403 executor/nodeModifyTable.c:1972 +#: executor/nodeModifyTable.c:2046 executor/nodeModifyTable.c:2886 +#: executor/nodeModifyTable.c:2976 executor/nodeModifyTable.c:3801 +#: executor/nodeModifyTable.c:3998 #, c-format msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." msgstr "Verwenden Sie einen AFTER-Trigger anstelle eines BEFORE-Triggers, um Änderungen an andere Zeilen zu propagieren." #: commands/trigger.c:3445 executor/nodeLockRows.c:228 -#: executor/nodeModifyTable.c:413 executor/nodeModifyTable.c:1978 -#: executor/nodeModifyTable.c:2892 executor/nodeModifyTable.c:3098 -#: executor/nodeModifyTable.c:3829 utils/adt/ri_triggers.c:3314 +#: executor/nodeModifyTable.c:413 executor/nodeModifyTable.c:1988 +#: executor/nodeModifyTable.c:2902 executor/nodeModifyTable.c:3108 +#: executor/nodeModifyTable.c:3839 utils/adt/ri_triggers.c:3314 #, c-format msgid "could not serialize access due to concurrent update" msgstr "konnte Zugriff nicht serialisieren wegen gleichzeitiger Aktualisierung" #: commands/trigger.c:3453 executor/nodeLockRows.c:237 -#: executor/nodeModifyTable.c:2068 executor/nodeModifyTable.c:2983 -#: executor/nodeModifyTable.c:3114 executor/nodeModifyTable.c:3809 +#: executor/nodeModifyTable.c:2078 executor/nodeModifyTable.c:2993 +#: executor/nodeModifyTable.c:3124 executor/nodeModifyTable.c:3819 #: utils/adt/ri_triggers.c:3307 #, c-format msgid "could not serialize access due to concurrent delete" @@ -17106,10 +16904,9 @@ msgid "%s is not a base type" msgstr "%s ist kein Basistyp" #: commands/user.c:178 commands/user.c:1361 -#, fuzzy, c-format -#| msgid "database name contains a newline or carriage return: \"%s\"\n" +#, c-format msgid "role name \"%s\" contains a newline or carriage return character" -msgstr "Datenbankname enthält Newline oder Carriage Return: »%s«\n" +msgstr "Rollenname »%s« enthält Newline- oder Carriage-Return-Zeichen" #: commands/user.c:207 #, c-format @@ -17133,8 +16930,8 @@ msgstr "Nur Rollen mit dem %s-Attribut können Rollen erzeugen." msgid "Only roles with the %s attribute may create roles with the %s attribute." msgstr "Nur Rollen mit dem %s-Attribut können Rollen mit dem %s-Attribut erzeugen." -#: commands/user.c:361 commands/user.c:1399 commands/user.c:1406 gram.y:18610 -#: gram.y:18656 utils/adt/acl.c:5762 utils/adt/acl.c:5768 +#: commands/user.c:361 commands/user.c:1399 commands/user.c:1406 gram.y:18605 +#: gram.y:18651 utils/adt/acl.c:5762 utils/adt/acl.c:5768 #: utils/adt/ddlutils.c:187 #, c-format msgid "role name \"%s\" is reserved" @@ -17297,7 +17094,7 @@ msgstr "Nur Rollen mit dem %s-Attribut und der %s-Option für Rolle »%s« könn msgid "MD5 password cleared because of role rename" msgstr "MD5-Passwort wegen Rollenumbenennung gelöscht" -#: commands/user.c:1531 gram.y:1377 +#: commands/user.c:1531 gram.y:1376 #, c-format msgid "unrecognized role option \"%s\"" msgstr "unbekannte Rollenoption »%s«" @@ -17438,16 +17235,14 @@ msgid "\"%s\" must be 0 or between %d kB and %d kB." msgstr "»%s« muss 0 sein oder zwischen %d kB und %d kB liegen." #: commands/vacuum.c:225 -#, fuzzy, c-format -#| msgid "\"%s\" must be 0 or between %d kB and %d kB." +#, c-format msgid "%s option must be 0 or between %d kB and %d kB" -msgstr "»%s« muss 0 sein oder zwischen %d kB und %d kB liegen." +msgstr "Option %s muss 0 sein oder zwischen %d kB und %d kB liegen" #: commands/vacuum.c:278 -#, fuzzy, c-format -#| msgid "sample size must be between 0 and %d" +#, c-format msgid "%s option must be between 0 and %d" -msgstr "Stichprobengröße muss zwischen 0 und %d sein" +msgstr "Option %s muss zwischen 0 und %d sein" #: commands/vacuum.c:326 #, c-format @@ -17539,16 +17334,13 @@ msgid "cutoff for freezing multixacts is far in the past" msgstr "Obergrenze für das Einfrieren von Multixacts ist weit in der Vergangenheit" #: commands/vacuum.c:1179 -#, fuzzy, c-format -#| msgid "" -#| "Close open transactions soon to avoid wraparound problems.\n" -#| "You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +#, c-format msgid "" "Close open transactions soon to avoid wraparound problems.\n" "You might also need to commit or roll back old prepared transactions." msgstr "" "Schließen Sie bald alle offenen Transaktionen, um Überlaufprobleme zu vermeiden.\n" -"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen." #: commands/vacuum.c:1944 #, c-format @@ -17723,13 +17515,12 @@ msgstr "SSL wird von dieser Installation nicht unterstützt" #: commands/variable.c:1274 #, c-format msgid "SNI requires OpenSSL 1.1.1 or later" -msgstr "" +msgstr "SNI benötigt OpenSSL 1.1.1 oder neuer" #: commands/variable.c:1289 -#, fuzzy, c-format -#| msgid "postfix operators are not supported" +#, c-format msgid "non-standard string literals are not supported" -msgstr "Postfix-Operatoren werden nicht unterstützt" +msgstr "nicht-standardkonforme Zeichenkettenkonstanten werden nicht unterstützt" #: commands/view.c:77 #, c-format @@ -17787,102 +17578,94 @@ msgid "view \"%s\" will be a temporary view" msgstr "Sicht »%s« wird eine temporäre Sicht" #: commands/wait.c:56 -#, fuzzy, c-format -#| msgid "%s cannot be used as a role name here" +#, c-format msgid "%s can only be executed as a top-level statement" -msgstr "%s kann hier nicht als Rollenname verwendet werden" +msgstr "%s kann nur als Anweisung auf der obersten Ebene ausgeführt werden" #: commands/wait.c:58 -#, fuzzy, c-format -#| msgid "WITH ORDINALITY cannot be used with a column definition list" +#, c-format msgid "WAIT FOR cannot be used within a function, procedure, or DO block." -msgstr "WITH ORDINALITY kann nicht mit einer Spaltendefinitionsliste verwendet werden" +msgstr "WAIT FOR kann nicht in einer Funktion, Prozedur oder einem DO-Block verwendet werden." #: commands/wait.c:107 -#, fuzzy, c-format -#| msgid "invalid cidr value: \"%s\"" +#, c-format msgid "invalid timeout value: \"%s\"" -msgstr "ungültiger cidr-Wert: »%s«" +msgstr "ungültiger Timeout-Wert: »%s«" #: commands/wait.c:122 -#, fuzzy, c-format -#| msgid "input is out of range" +#, c-format msgid "timeout value is out of range" -msgstr "Eingabe ist außerhalb des gültigen Bereichs" +msgstr "Timeout-Wert ist außerhalb des gültigen Bereichs" #: commands/wait.c:127 -#, fuzzy, c-format -#| msgid "\"timeout\" must not be negative" +#, c-format msgid "timeout cannot be negative" -msgstr "»timeout« darf nicht negativ sein" +msgstr "Timeout darf nicht negativ sein" #: commands/wait.c:174 #, c-format msgid "WAIT FOR must be called without an active or registered snapshot" -msgstr "" +msgstr "WAIT FOR muss ohne aktiven oder registrierten Snapshot aufgerufen werden" #: commands/wait.c:175 #, c-format msgid "WAIT FOR cannot be executed within a transaction with an isolation level higher than READ COMMITTED." -msgstr "" +msgstr "WAIT FOR kann nicht in einer Transaktion mit einem höheren Isolationsgrad als READ COMMITTED ausgeführt werden." #: commands/wait.c:193 #, c-format msgid "Waiting for primary_flush can only be done on a primary server. Use standby_flush mode on a standby server." -msgstr "" +msgstr "Das Warten auf primary_flush kann nur auf einem Primärserver erfolgen. Verwenden Sie den Modus standby_flush auf einem Standby-Server." #: commands/wait.c:220 #, c-format msgid "timed out while waiting for target LSN %X/%08X to be replayed; current standby_replay LSN %X/%08X" -msgstr "" +msgstr "Zeitüberschreitung beim Warten darauf, dass Ziel-LSN %X/%08X zurückgespielt wird; aktuelle standby_replay-LSN %X/%08X" #: commands/wait.c:228 #, c-format msgid "timed out while waiting for target LSN %X/%08X to be written; current standby_write LSN %X/%08X" -msgstr "" +msgstr "Zeitüberschreitung beim Warten darauf, dass Ziel-LSN %X/%08X geschrieben wird; aktuelle standby_write-LSN %X/%08X" #: commands/wait.c:236 #, c-format msgid "timed out while waiting for target LSN %X/%08X to be flushed; current standby_flush LSN %X/%08X" -msgstr "" +msgstr "Zeitüberschreitung beim Warten darauf, dass Ziel-LSN %X/%08X geflusht wird; aktuelle standby_flush-LSN %X/%08X" #: commands/wait.c:244 #, c-format msgid "timed out while waiting for target LSN %X/%08X to be flushed; current primary_flush LSN %X/%08X" -msgstr "" +msgstr "Zeitüberschreitung beim Warten darauf, dass Ziel-LSN %X/%08X geflusht wird; aktuelle primary_flush-LSN %X/%08X" #: commands/wait.c:270 #, c-format msgid "Recovery ended before target LSN %X/%08X was replayed; last standby_replay LSN %X/%08X." -msgstr "" +msgstr "Die Wiederherstellung endete, bevor Ziel-LSN %X/%08X zurückgespielt wurde; letzte standby_replay-LSN %X/%08X." #: commands/wait.c:279 #, c-format msgid "Recovery ended before target LSN %X/%08X was written; last standby_write LSN %X/%08X." -msgstr "" +msgstr "Die Wiederherstellung endete, bevor Ziel-LSN %X/%08X geschrieben wurde; letzte standby_write-LSN %X/%08X." #: commands/wait.c:288 #, c-format msgid "Recovery ended before target LSN %X/%08X was flushed; last standby_flush LSN %X/%08X." -msgstr "" +msgstr "Die Wiederherstellung endete, bevor Ziel-LSN %X/%08X geflusht wurde; letzte standby_flush-LSN %X/%08X." #: commands/wait.c:305 -#, fuzzy, c-format -#| msgid "Recovery control functions can only be executed during recovery." +#, c-format msgid "Waiting for the standby_replay LSN can only be executed during recovery." -msgstr "Wiederherstellungskontrollfunktionen können nur während der Wiederherstellung ausgeführt werden." +msgstr "Warten auf die standby_replay-LSN kann nur während der Wiederherstellung ausgeführt werden." #: commands/wait.c:312 -#, fuzzy, c-format -#| msgid "Recovery control functions can only be executed during recovery." +#, c-format msgid "Waiting for the standby_write LSN can only be executed during recovery." -msgstr "Wiederherstellungskontrollfunktionen können nur während der Wiederherstellung ausgeführt werden." +msgstr "Warten auf die standby_write-LSN kann nur während der Wiederherstellung ausgeführt werden." #: commands/wait.c:319 -#, fuzzy, c-format -#| msgid "Recovery control functions can only be executed during recovery." +#, c-format msgid "Waiting for the standby_flush LSN can only be executed during recovery." -msgstr "Wiederherstellungskontrollfunktionen können nur während der Wiederherstellung ausgeführt werden." +msgstr "Warten auf die standby_flush-LSN kann nur während der Wiederherstellung ausgeführt werden." #: executor/execCurrent.c:79 #, c-format @@ -18141,16 +17924,14 @@ msgid "cannot change materialized view \"%s\"" msgstr "kann materialisierte Sicht »%s« nicht ändern" #: executor/execMain.c:1134 -#, fuzzy, c-format -#| msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" +#, c-format msgid "foreign tables don't support FOR PORTION OF" -msgstr "Fremddaten-Wrapper »%s« unterstützt IMPORT FOREIGN SCHEMA nicht" +msgstr "Fremdtabellen unterstützen kein FOR PORTION OF" #: executor/execMain.c:1135 -#, fuzzy, c-format -#| msgid "\"%s\" is a foreign table" +#, c-format msgid "\"%s\" is a foreign table." -msgstr "»%s« ist eine Fremdtabelle" +msgstr "»%s« ist eine Fremdtabelle." #: executor/execMain.c:1146 #, c-format @@ -18360,7 +18141,7 @@ msgstr "Relation »%s.%s« kann nicht als Ziel für logische Replikation verwend #: executor/execReplication.c:1162 #, c-format msgid "relation \"%s.%s\" type mismatch: source \"%s\", target \"%s\"" -msgstr "" +msgstr "Typ von Relation »%s.%s« stimmt nicht überein: Quelle »%s«, Ziel »%s«" #: executor/execSRF.c:317 #, c-format @@ -18511,12 +18292,11 @@ msgid "return type %s is not supported for SQL functions" msgstr "Rückgabetyp %s wird von SQL-Funktionen nicht unterstützt" #: executor/instrument.c:400 -#, fuzzy, c-format -#| msgid "LOCATION is not supported anymore" +#, c-format msgid "TSC is not supported as timing clock source" -msgstr "LOCATION wird nicht mehr unterstützt" +msgstr "TSC wird nicht als Taktquelle für die Zeitmessung unterstützt" -#: executor/nodeAgg.c:4036 executor/nodeWindowAgg.c:3164 +#: executor/nodeAgg.c:4036 executor/nodeWindowAgg.c:3160 #, c-format msgid "aggregate %u needs to have compatible input type and transition type" msgstr "Aggregatfunktion %u muss kompatiblen Eingabe- und Übergangstyp haben" @@ -18536,7 +18316,7 @@ msgstr "Custom-Scan »%s« unterstützt MarkPos nicht" msgid "could not rewind hash-join temporary file" msgstr "konnte Position in temporärer Datei für Hash-Verbund nicht auf Anfang setzen" -#: executor/nodeIndexonlyscan.c:243 +#: executor/nodeIndexonlyscan.c:225 #, c-format msgid "lossy distance functions are not supported in index-only scans" msgstr "verlustbehaftete Abstandsfunktionen werden in Index-Only-Scans nicht unterstützt" @@ -18571,67 +18351,67 @@ msgstr "Anfrage liefert einen Wert für eine generierte Spalte auf Position %d." msgid "Query has too few columns." msgstr "Anfrage hat zu wenige Spalten." -#: executor/nodeModifyTable.c:1961 executor/nodeModifyTable.c:2035 +#: executor/nodeModifyTable.c:1971 executor/nodeModifyTable.c:2045 #, c-format msgid "tuple to be deleted was already modified by an operation triggered by the current command" msgstr "das zu löschende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" -#: executor/nodeModifyTable.c:2234 +#: executor/nodeModifyTable.c:2244 #, c-format msgid "invalid ON UPDATE specification" msgstr "ungültige ON-UPDATE-Angabe" -#: executor/nodeModifyTable.c:2235 +#: executor/nodeModifyTable.c:2245 #, c-format msgid "The result tuple would appear in a different partition than the original tuple." msgstr "Das Ergebnistupel würde in einer anderen Partition erscheinen als das ursprüngliche Tupel." -#: executor/nodeModifyTable.c:2705 +#: executor/nodeModifyTable.c:2715 #, c-format msgid "cannot move tuple across partitions when a non-root ancestor of the source partition is directly referenced in a foreign key" msgstr "Tupel kann nicht zwischen Partitionen bewegt werden, wenn ein Fremdschlüssel direkt auf einen Vorgänger (außer der Wurzel) der Quellpartition verweist" -#: executor/nodeModifyTable.c:2706 +#: executor/nodeModifyTable.c:2716 #, c-format msgid "A foreign key points to ancestor \"%s\" but not the root ancestor \"%s\"." msgstr "Ein Fremdschlüssel verweist auf den Vorgänger »%s«, aber nicht auf den Wurzelvorgänger »%s«." -#: executor/nodeModifyTable.c:2709 +#: executor/nodeModifyTable.c:2719 #, c-format msgid "Consider defining the foreign key on table \"%s\"." msgstr "Definieren Sie den Fremdschlüssel eventuell für Tabelle »%s«." #. translator: %s is a SQL command name -#: executor/nodeModifyTable.c:3076 executor/nodeModifyTable.c:3797 -#: executor/nodeModifyTable.c:3994 +#: executor/nodeModifyTable.c:3086 executor/nodeModifyTable.c:3807 +#: executor/nodeModifyTable.c:4004 #, c-format msgid "%s command cannot affect row a second time" msgstr "Befehl in %s kann eine Zeile nicht ein zweites Mal ändern" -#: executor/nodeModifyTable.c:3078 +#: executor/nodeModifyTable.c:3088 #, c-format msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." msgstr "Stellen Sie sicher, dass keine im selben Befehl fürs Einfügen vorgesehene Zeilen doppelte Werte haben, die einen Constraint verletzen würden." -#: executor/nodeModifyTable.c:3790 executor/nodeModifyTable.c:3987 +#: executor/nodeModifyTable.c:3800 executor/nodeModifyTable.c:3997 #, c-format msgid "tuple to be updated or deleted was already modified by an operation triggered by the current command" msgstr "das zu aktualisierende oder zu löschende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" -#: executor/nodeModifyTable.c:3799 executor/nodeModifyTable.c:3996 +#: executor/nodeModifyTable.c:3809 executor/nodeModifyTable.c:4006 #, c-format msgid "Ensure that not more than one source row matches any one target row." msgstr "Stellen Sie sicher, dass nicht mehr als eine Quellzeile auf jede Zielzeile passt." -#: executor/nodeModifyTable.c:3873 +#: executor/nodeModifyTable.c:3883 #, c-format msgid "tuple to be merged was already moved to another partition due to concurrent update" msgstr "das zu mergende Tupel wurde schon durch ein gleichzeitiges Update in eine andere Partition verschoben" -#: executor/nodeModifyTable.c:5638 +#: executor/nodeModifyTable.c:5648 #, c-format msgid "FOR PORTION OF target was null" -msgstr "" +msgstr "Ziel von FOR PORTION OF war NULL" #: executor/nodeSamplescan.c:245 #, c-format @@ -18674,40 +18454,40 @@ msgstr "Filter für Spalte »%s« ist NULL." msgid "null is not allowed in column \"%s\"" msgstr "NULL ist in Spalte »%s« nicht erlaubt" -#: executor/nodeWindowAgg.c:403 +#: executor/nodeWindowAgg.c:402 #, c-format msgid "moving-aggregate transition function must not return null" msgstr "Moving-Aggregat-Übergangsfunktion darf nicht NULL zurückgeben" -#: executor/nodeWindowAgg.c:2224 +#: executor/nodeWindowAgg.c:2223 #, c-format msgid "frame starting offset must not be null" msgstr "Frame-Start-Offset darf nicht NULL sein" -#: executor/nodeWindowAgg.c:2238 +#: executor/nodeWindowAgg.c:2237 #, c-format msgid "frame starting offset must not be negative" msgstr "Frame-Start-Offset darf nicht negativ sein" -#: executor/nodeWindowAgg.c:2251 +#: executor/nodeWindowAgg.c:2250 #, c-format msgid "frame ending offset must not be null" msgstr "Frame-Ende-Offset darf nicht NULL sein" -#: executor/nodeWindowAgg.c:2265 +#: executor/nodeWindowAgg.c:2264 #, c-format msgid "frame ending offset must not be negative" msgstr "Frame-Ende-Offset darf nicht negativ sein" -#: executor/nodeWindowAgg.c:3080 +#: executor/nodeWindowAgg.c:3076 #, c-format msgid "aggregate function %s does not support use as a window function" msgstr "Aggregatfunktion %s unterstützt die Verwendung als Fensterfunktion nicht" -#: executor/nodeWindowAgg.c:3664 +#: executor/nodeWindowAgg.c:3660 #, c-format msgid "function %s does not allow RESPECT/IGNORE NULLS" -msgstr "" +msgstr "Funktion %s erlaubt kein RESPECT/IGNORE NULLS" #: executor/spi.c:242 executor/spi.c:342 #, c-format @@ -18755,7 +18535,7 @@ msgstr "%s kann nicht als Cursor geöffnet werden" msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE wird nicht unterstützt" -#: executor/spi.c:1720 parser/analyze.c:3428 +#: executor/spi.c:1720 parser/analyze.c:3425 #, c-format msgid "Scrollable cursors must be READ ONLY." msgstr "Scrollbare Cursor müssen READ ONLY sein." @@ -18791,466 +18571,452 @@ msgstr "SQL-Anweisung »%s«" msgid "could not send tuple to shared-memory queue" msgstr "konnte Tupel nicht an Shared-Memory-Queue senden" -#: foreign/foreign.c:212 -#, fuzzy, c-format -#| msgid "foreign-data wrapper \"%s\" does not exist, skipping" -msgid "foreign data wrapper \"%s\" does not support subscription connections" -msgstr "Fremddaten-Wrapper »%s« existiert nicht, wird übersprungen" - -#: foreign/foreign.c:214 -#, c-format -msgid "Foreign data wrapper must be defined with CONNECTION specified." -msgstr "" - -#: foreign/foreign.c:257 +#: foreign/foreign.c:267 #, c-format msgid "user mapping not found for user \"%s\", server \"%s\"" msgstr "Benutzerabbildung für Benutzer »%s«, Server »%s« nicht gefunden" -#: foreign/foreign.c:368 optimizer/plan/createplan.c:7138 +#: foreign/foreign.c:380 optimizer/plan/createplan.c:7139 #: optimizer/util/plancat.c:542 #, c-format msgid "access to non-system foreign table is restricted" msgstr "Zugriff auf Nicht-System-Fremdtabelle ist beschränkt" -#: foreign/foreign.c:692 +#: foreign/foreign.c:704 #, c-format msgid "invalid option \"%s\"" msgstr "ungültige Option »%s«" -#: foreign/foreign.c:694 +#: foreign/foreign.c:706 #, c-format msgid "Perhaps you meant the option \"%s\"." msgstr "Vielleicht meinten Sie die Option »%s«." -#: foreign/foreign.c:696 +#: foreign/foreign.c:708 #, c-format msgid "There are no valid options in this context." msgstr "Es gibt keine gültigen Optionen in diesem Zusammenhang." -#: gram.y:1314 +#: gram.y:1313 #, c-format msgid "UNENCRYPTED PASSWORD is no longer supported" msgstr "UNENCRYPTED PASSWORD wird nicht mehr unterstützt" -#: gram.y:1315 +#: gram.y:1314 #, c-format msgid "Remove UNENCRYPTED to store the password in encrypted form instead." msgstr "Lassen Sie UNENCRYPTED weg, um das Passwort stattdessen in verschlüsselter Form zu speichern." -#: gram.y:1642 gram.y:1658 +#: gram.y:1641 gram.y:1657 #, c-format msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" msgstr "CREATE SCHEMA IF NOT EXISTS kann keine Schemaelemente enthalten" -#: gram.y:1842 +#: gram.y:1841 #, c-format msgid "current database cannot be changed" msgstr "aktuelle Datenbank kann nicht geändert werden" -#: gram.y:1983 +#: gram.y:1982 #, c-format msgid "time zone interval must be HOUR or HOUR TO MINUTE" msgstr "Zeitzonenintervall muss HOUR oder HOUR TO MINUTE sein" -#: gram.y:2665 +#: gram.y:2664 #, c-format msgid "column number must be in range from 1 to %d" msgstr "Spaltennummer muss im Bereich 1 bis %d sein" -#: gram.y:2840 +#: gram.y:2839 #, c-format msgid "constraints cannot be altered to be NOT VALID" msgstr "Constraints können nicht in NOT VALID geändert werden" -#: gram.y:3290 +#: gram.y:3289 #, c-format msgid "sequence option \"%s\" not supported here" msgstr "Sequenzoption »%s« wird hier nicht unterstützt" -#: gram.y:3329 +#: gram.y:3328 #, c-format msgid "modulus for hash partition provided more than once" msgstr "Modulus für Hashpartition mehrmals angegeben" -#: gram.y:3338 +#: gram.y:3337 #, c-format msgid "remainder for hash partition provided more than once" msgstr "Rest für Hashpartition mehrmals angegeben" -#: gram.y:3345 +#: gram.y:3344 #, c-format msgid "unrecognized hash partition bound specification \"%s\"" msgstr "unbekannte Hashpartitionsbegrenzungsangabe »%s«" -#: gram.y:3353 +#: gram.y:3352 #, c-format msgid "modulus for hash partition must be specified" msgstr "Modulus für Hashpartition muss angegeben werden" -#: gram.y:3358 +#: gram.y:3357 #, c-format msgid "remainder for hash partition must be specified" msgstr "Rest für Hashpartition muss angegeben werden" -#: gram.y:3567 gram.y:3602 +#: gram.y:3566 gram.y:3601 #, c-format msgid "STDIN/STDOUT not allowed with PROGRAM" msgstr "STDIN/STDOUT sind nicht mit PROGRAM erlaubt" -#: gram.y:3573 +#: gram.y:3572 #, c-format msgid "WHERE clause not allowed with COPY TO" msgstr "mit COPY TO ist keine WHERE-Klausel erlaubt" -#: gram.y:3574 -#, fuzzy, c-format -#| msgid "Try the COPY (SELECT ...) TO variant." +#: gram.y:3573 +#, c-format msgid "Try the COPY (SELECT ... WHERE ...) TO variant." -msgstr "Versuchen Sie die Variante COPY (SELECT ...) TO." +msgstr "Versuchen Sie die Variante COPY (SELECT ... WHERE ...) TO." -#: gram.y:3930 gram.y:3937 gram.y:13976 gram.y:13984 +#: gram.y:3929 gram.y:3936 gram.y:13973 gram.y:13981 #, c-format msgid "GLOBAL is deprecated in temporary table creation" msgstr "die Verwendung von GLOBAL beim Erzeugen einer temporären Tabelle ist veraltet" -#: gram.y:4219 +#: gram.y:4218 #, c-format msgid "for a generated column, GENERATED ALWAYS must be specified" msgstr "für eine generierte Spalte muss GENERATED ALWAYS angegeben werden" -#: gram.y:4628 utils/adt/ri_triggers.c:2413 +#: gram.y:4627 utils/adt/ri_triggers.c:2413 #, c-format msgid "MATCH PARTIAL not yet implemented" msgstr "MATCH PARTIAL ist noch nicht implementiert" -#: gram.y:4720 +#: gram.y:4719 #, c-format msgid "a column list with %s is only supported for ON DELETE actions" msgstr "eine Spaltenliste für %s wird nur für ON-DELETE-Aktionen unterstützt" -#: gram.y:5439 +#: gram.y:5438 #, c-format msgid "CREATE EXTENSION ... FROM is no longer supported" msgstr "CREATE EXTENSION ... FROM wird nicht mehr unterstützt" -#: gram.y:6139 +#: gram.y:6138 #, c-format msgid "unrecognized row security option \"%s\"" msgstr "unbekannte Zeilensicherheitsoption »%s«" -#: gram.y:6140 +#: gram.y:6139 #, c-format msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." msgstr "Aktuell werden nur PERMISSIVE und RESTRICTIVE unterstützt." -#: gram.y:6225 gram.y:6231 gram.y:6237 -#, fuzzy, c-format -#| msgid "%s constraints cannot be marked ENFORCED" +#: gram.y:6224 gram.y:6230 gram.y:6236 +#, c-format msgid "constraint triggers cannot be marked %s" -msgstr "%s-Constraints können nicht als ENFORCED markiert werden" +msgstr "Constraint-Trigger können nicht als %s markiert werden" -#: gram.y:6245 +#: gram.y:6244 #, c-format msgid "CREATE OR REPLACE CONSTRAINT TRIGGER is not supported" msgstr "CREATE OR REPLACE CONSTRAINT TRIGGER wird nicht unterstützt" -#: gram.y:6283 +#: gram.y:6282 msgid "duplicate trigger events specified" msgstr "mehrere Trigger-Ereignisse angegeben" -#: gram.y:6425 parser/parse_utilcmd.c:4271 parser/parse_utilcmd.c:4297 +#: gram.y:6424 parser/parse_utilcmd.c:4271 parser/parse_utilcmd.c:4297 #, c-format msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" msgstr "Constraint, der als INITIALLY DEFERRED deklariert wurde, muss DEFERRABLE sein" -#: gram.y:6433 +#: gram.y:6432 #, c-format msgid "conflicting constraint properties" msgstr "widersprüchliche Constraint-Eigentschaften" -#: gram.y:6534 +#: gram.y:6533 #, c-format msgid "CREATE ASSERTION is not yet implemented" msgstr "CREATE ASSERTION ist noch nicht implementiert" -#: gram.y:6852 +#: gram.y:6851 #, c-format msgid "dropping an enum value is not implemented" msgstr "Löschen eines Enum-Werts ist nicht implementiert" -#: gram.y:8879 +#: gram.y:8878 #, c-format msgid "aggregates cannot have output arguments" msgstr "Aggregatfunktionen können keine OUT-Argumente haben" -#: gram.y:9343 utils/adt/regproc.c:678 +#: gram.y:9342 utils/adt/regproc.c:678 #, c-format msgid "missing argument" msgstr "Argument fehlt" -#: gram.y:9344 utils/adt/regproc.c:679 +#: gram.y:9343 utils/adt/regproc.c:679 #, c-format msgid "Use NONE to denote the missing argument of a unary operator." msgstr "Verwenden Sie NONE, um das fehlende Argument eines unären Operators anzugeben." -#: gram.y:12076 gram.y:12095 +#: gram.y:12075 gram.y:12094 #, c-format msgid "WITH CHECK OPTION not supported on recursive views" msgstr "WITH CHECK OPTION wird für rekursive Sichten nicht unterstützt" -#: gram.y:14123 +#: gram.y:14120 #, c-format msgid "LIMIT #,# syntax is not supported" msgstr "Syntax LIMIT x,y wird nicht unterstützt" -#: gram.y:14124 +#: gram.y:14121 #, c-format msgid "Use separate LIMIT and OFFSET clauses." msgstr "Verwenden Sie die getrennten Klauseln LIMIT und OFFSET." -#: gram.y:15086 +#: gram.y:15073 #, c-format msgid "only one DEFAULT value is allowed" msgstr "nur ein DEFAULT-Wert ist erlaubt" -#: gram.y:15095 +#: gram.y:15082 #, c-format msgid "only one PATH value per column is allowed" msgstr "nur ein PATH-Wert pro Spalte ist erlaubt" -#: gram.y:15104 +#: gram.y:15091 #, c-format msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" msgstr "widersprüchliche oder überflüssige NULL/NOT NULL-Deklarationen für Spalte »%s«" -#: gram.y:15113 +#: gram.y:15100 #, c-format msgid "unrecognized column option \"%s\"" msgstr "unbekannte Spaltenoption »%s«" -#: gram.y:15146 +#: gram.y:15133 #, c-format msgid "option name \"%s\" cannot be used in XMLTABLE" msgstr "Optionsname »%s« kann nicht in XMLTABLE verwendet werden" -#: gram.y:15202 +#: gram.y:15189 #, c-format msgid "only string constants are supported in JSON_TABLE path specification" msgstr "nur Zeichenkettenkonstanten werden in Pfadangaben in JSON_TABLE unterstützt" -#: gram.y:15524 +#: gram.y:15511 #, c-format msgid "precision for type float must be at least 1 bit" msgstr "Präzision von Typ float muss mindestens 1 Bit sein" -#: gram.y:15533 +#: gram.y:15520 #, c-format msgid "precision for type float must be less than 54 bits" msgstr "Präzision von Typ float muss weniger als 54 Bits sein" -#: gram.y:16063 +#: gram.y:16054 #, c-format msgid "wrong number of parameters on left side of OVERLAPS expression" msgstr "falsche Anzahl Parameter auf linker Seite von OVERLAPS-Ausdruck" -#: gram.y:16068 +#: gram.y:16059 #, c-format msgid "wrong number of parameters on right side of OVERLAPS expression" msgstr "falsche Anzahl Parameter auf rechter Seite von OVERLAPS-Ausdruck" -#: gram.y:16246 +#: gram.y:16237 #, c-format msgid "UNIQUE predicate is not yet implemented" msgstr "UNIQUE-Prädikat ist noch nicht implementiert" -#: gram.y:16664 +#: gram.y:16659 #, c-format msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" msgstr "in WITHIN GROUP können nicht mehrere ORDER-BY-Klauseln verwendet werden" -#: gram.y:16669 +#: gram.y:16664 #, c-format msgid "cannot use DISTINCT with WITHIN GROUP" msgstr "DISTINCT kann nicht mit WITHIN GROUP verwendet werden" -#: gram.y:16674 +#: gram.y:16669 #, c-format msgid "cannot use VARIADIC with WITHIN GROUP" msgstr "VARIADIC kann nicht mit WITHIN GROUP verwendet werden" -#: gram.y:17428 gram.y:17452 +#: gram.y:17423 gram.y:17447 #, c-format msgid "frame start cannot be UNBOUNDED FOLLOWING" msgstr "Frame-Beginn kann nicht UNBOUNDED FOLLOWING sein" -#: gram.y:17433 +#: gram.y:17428 #, c-format msgid "frame starting from following row cannot end with current row" msgstr "Frame der in der folgenden Zeile beginnt kann nicht in der aktuellen Zeile enden" -#: gram.y:17457 +#: gram.y:17452 #, c-format msgid "frame end cannot be UNBOUNDED PRECEDING" msgstr "Frame-Ende kann nicht UNBOUNDED PRECEDING sein" -#: gram.y:17463 +#: gram.y:17458 #, c-format msgid "frame starting from current row cannot have preceding rows" msgstr "Frame der in der aktuellen Zeile beginnt kann keine vorhergehenden Zeilen haben" -#: gram.y:17470 +#: gram.y:17465 #, c-format msgid "frame starting from following row cannot have preceding rows" msgstr "Frame der in der folgenden Zeile beginnt kann keine vorhergehenden Zeilen haben" -#: gram.y:18010 +#: gram.y:18005 #, c-format msgid "unrecognized JSON encoding: %s" msgstr "unbekannte JSON-Kodierung: %s" -#: gram.y:18543 +#: gram.y:18538 #, c-format msgid "type modifier cannot have parameter name" msgstr "Typmodifikator kann keinen Parameternamen haben" -#: gram.y:18549 +#: gram.y:18544 #, c-format msgid "type modifier cannot have ORDER BY" msgstr "Typmodifikator kann kein ORDER BY haben" -#: gram.y:18617 gram.y:18624 gram.y:18631 +#: gram.y:18612 gram.y:18619 gram.y:18626 #, c-format msgid "%s cannot be used as a role name here" msgstr "%s kann hier nicht als Rollenname verwendet werden" -#: gram.y:18722 gram.y:20244 +#: gram.y:18716 gram.y:20238 #, c-format msgid "WITH TIES cannot be specified without ORDER BY clause" msgstr "WITH TIES kann nicht ohne ORDER-BY-Klausel angegeben werden" -#: gram.y:19937 gram.y:20112 +#: gram.y:19931 gram.y:20106 msgid "improper use of \"*\"" msgstr "unzulässige Verwendung von »*«" -#: gram.y:20075 gram.y:20092 tsearch/spell.c:972 tsearch/spell.c:989 +#: gram.y:20069 gram.y:20086 tsearch/spell.c:972 tsearch/spell.c:989 #: tsearch/spell.c:1006 tsearch/spell.c:1023 tsearch/spell.c:1088 #, c-format msgid "syntax error" msgstr "Syntaxfehler" -#: gram.y:20176 +#: gram.y:20170 #, c-format msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" msgstr "eine Ordered-Set-Aggregatfunktion mit einem direkten VARIADIC-Argument muss ein aggregiertes VARIADIC-Argument des selben Datentyps haben" -#: gram.y:20213 +#: gram.y:20207 #, c-format msgid "multiple ORDER BY clauses not allowed" msgstr "mehrere ORDER-BY-Klauseln sind nicht erlaubt" -#: gram.y:20224 +#: gram.y:20218 #, c-format msgid "multiple OFFSET clauses not allowed" msgstr "mehrere OFFSET-Klauseln sind nicht erlaubt" -#: gram.y:20233 +#: gram.y:20227 #, c-format msgid "multiple LIMIT clauses not allowed" msgstr "mehrere LIMIT-Klauseln sind nicht erlaubt" -#: gram.y:20257 +#: gram.y:20251 #, c-format msgid "%s and %s options cannot be used together" msgstr "Optionen %s und %s können nicht zusammen verwendet werden" -#: gram.y:20269 +#: gram.y:20263 #, c-format msgid "multiple WITH clauses not allowed" msgstr "mehrere WITH-Klauseln sind nicht erlaubt" -#: gram.y:20465 +#: gram.y:20459 #, c-format msgid "OUT and INOUT arguments aren't allowed in TABLE functions" msgstr "OUT- und INOUT-Argumente sind in TABLE-Funktionen nicht erlaubt" -#: gram.y:20599 +#: gram.y:20593 #, c-format msgid "multiple COLLATE clauses not allowed" msgstr "mehrere COLLATE-Klauseln sind nicht erlaubt" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:20639 gram.y:20652 +#: gram.y:20633 gram.y:20646 #, c-format msgid "%s constraints cannot be marked DEFERRABLE" msgstr "%s-Constraints können nicht als DEFERRABLE markiert werden" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:20665 +#: gram.y:20659 #, c-format msgid "%s constraints cannot be marked NOT VALID" msgstr "%s-Constraints können nicht als NOT VALID markiert werden" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:20678 +#: gram.y:20672 #, c-format msgid "%s constraints cannot be marked NO INHERIT" msgstr "%s-Constraints können nicht als NO INHERIT markiert werden" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:20691 +#: gram.y:20685 #, c-format msgid "%s constraints cannot be marked NOT ENFORCED" msgstr "%s-Constraints können nicht als NOT ENFORCED markiert werden" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:20713 +#: gram.y:20707 #, c-format msgid "%s constraints cannot be marked ENFORCED" msgstr "%s-Constraints können nicht als ENFORCED markiert werden" -#: gram.y:20735 +#: gram.y:20729 #, c-format msgid "unrecognized partitioning strategy \"%s\"" msgstr "unbekannte Partitionierungsstrategie »%s«" -#: gram.y:20763 gram.y:20775 gram.y:20802 +#: gram.y:20757 gram.y:20769 gram.y:20796 #, c-format msgid "invalid publication object list" msgstr "ungültige Publikationsobjektliste" -#: gram.y:20764 -#, fuzzy, c-format -#| msgid "OLD TABLE cannot be specified multiple times" +#: gram.y:20758 +#, c-format msgid "ALL TABLES can be specified only once." -msgstr "OLD TABLE kann nicht mehrmals angegeben werden" +msgstr "ALL TABLES kann nur einmal angegeben werden." -#: gram.y:20776 +#: gram.y:20770 #, c-format msgid "ALL SEQUENCES can be specified only once." -msgstr "" +msgstr "ALL SEQUENCES kann nur einmal angegeben werden." -#: gram.y:20803 +#: gram.y:20797 #, c-format msgid "One of TABLE or TABLES IN SCHEMA must be specified before a standalone table or schema name." msgstr "Entweder TABLE oder TABLES IN SCHEMA muss vor einem alleinstehenden Tabellen- oder Schemanamen angegeben werden." -#: gram.y:20819 +#: gram.y:20813 #, c-format msgid "invalid table name" msgstr "ungültiger Tabellenname" -#: gram.y:20840 +#: gram.y:20834 #, c-format msgid "WHERE clause not allowed for schema" msgstr "für Schemas ist keine WHERE-Klausel erlaubt" -#: gram.y:20847 +#: gram.y:20841 #, c-format msgid "column specification not allowed for schema" msgstr "für Schemas ist keine Spaltenangabe erlaubt" -#: gram.y:20861 +#: gram.y:20855 #, c-format msgid "invalid schema name" msgstr "ungültiger Schemaname" @@ -19421,7 +19187,7 @@ msgstr "Client hat keine kvsep-Antwort gesendet." #: libpq/auth-oauth.c:212 #, c-format msgid "OAuth issuer discovery requested" -msgstr "" +msgstr "OAuth-Issuer-Discovery angefordert" #: libpq/auth-oauth.c:244 #, c-format @@ -19501,13 +19267,12 @@ msgstr "Nachricht enthielt kein abschließendes Endezeichen." #: libpq/auth-oauth.c:544 #, c-format msgid "OAuth is not properly configured for this user" -msgstr "OAuth ist für diesen Benutzer nicht richtig konfiguriert." +msgstr "OAuth ist für diesen Benutzer nicht richtig konfiguriert" #: libpq/auth-oauth.c:545 -#, fuzzy, c-format -#| msgid "The issuer and scope parameters must be set in pg_hba.conf." +#, c-format msgid "The options \"issuer\" and \"scope\" must be set in pg_hba.conf." -msgstr "Die Parameter issuer und scope müssen in pg_hba.conf gesetzt sein." +msgstr "Die Optionen »issuer« und »scope« müssen in pg_hba.conf gesetzt sein." #: libpq/auth-oauth.c:619 libpq/auth-oauth.c:636 libpq/auth-oauth.c:658 #, c-format @@ -19548,16 +19313,14 @@ msgid "Validator provided no identity." msgstr "Validator hat keine Identität angegeben." #: libpq/auth-oauth.c:794 -#, fuzzy, c-format -#| msgid "%s module \"%s\" must define the symbol %s" +#, c-format msgid "OAuth validator module \"%s\" must define the symbol \"%s\"" -msgstr "%s-Modul »%s« muss das Symbol %s definieren" +msgstr "OAuth-Validator-Modul »%s« muss das Symbol »%s« definieren" #: libpq/auth-oauth.c:807 -#, fuzzy, c-format -#| msgid "%s module \"%s\": magic number mismatch" +#, c-format msgid "OAuth validator module \"%s\": magic number mismatch" -msgstr "%s-Modul »%s«: magische Zahl stimmt nicht überein" +msgstr "OAuth-Validator-Modul »%s«: magische Zahl stimmt nicht überein" #: libpq/auth-oauth.c:809 #, c-format @@ -19565,16 +19328,14 @@ msgid "Server has magic number 0x%08X, module has 0x%08X." msgstr "Server hat magische Zahl 0x%08X, Modul hat 0x%08X." #: libpq/auth-oauth.c:818 -#, fuzzy, c-format -#| msgid "%s module \"%s\" must provide a %s callback" +#, c-format msgid "OAuth validator module \"%s\" must provide a \"%s\" callback" -msgstr "%s-Modul »%s« muss einen %s-Callback zur Verfügung stellen" +msgstr "OAuth-Validator-Modul »%s« muss einen »%s«-Callback zur Verfügung stellen" #: libpq/auth-oauth.c:870 -#, fuzzy, c-format -#| msgid "oauth_validator_libraries must be set for authentication method %s" +#, c-format msgid "parameter \"%s\" must be set for authentication method \"%s\"" -msgstr "oauth_validator_libraries muss gesetzt sein für Authentifizierungsmethode \"%s\"" +msgstr "Parameter »%s« muss für Authentifizierungsmethode »%s« gesetzt sein" #: libpq/auth-oauth.c:872 libpq/auth-oauth.c:906 libpq/auth-oauth.c:923 #: libpq/auth-oauth.c:1076 libpq/be-secure-common.c:223 @@ -19600,28 +19361,25 @@ msgid "line %d of configuration file \"%s\"" msgstr "Zeile %d in Konfigurationsdatei »%s«" #: libpq/auth-oauth.c:904 -#, fuzzy, c-format -#| msgid "authentication method \"oauth\" requires argument \"validator\" to be set when oauth_validator_libraries contains multiple options" +#, c-format msgid "authentication method \"oauth\" requires option \"validator\" to be set when \"%s\" contains multiple options" -msgstr "Authentifizierungsmethode »oauth« erfordert, dass das Argument »validator« gesetzt ist, wenn oauth_validator_libraries mehrere Optionen enthält" +msgstr "Authentifizierungsmethode »oauth« erfordert, dass die Option »validator« gesetzt ist, wenn »%s« mehrere Optionen enthält" #: libpq/auth-oauth.c:921 -#, fuzzy, c-format -#| msgid "validator \"%s\" is not permitted by %s" +#, c-format msgid "validator \"%s\" is not permitted by \"%s\"" -msgstr "Validator »%s« ist nicht durch %s erlaubt" +msgstr "Validator »%s« ist nicht durch »%s« erlaubt" #: libpq/auth-oauth.c:973 #, c-format msgid "HBA option name \"%s\" is invalid and will be ignored" -msgstr "" +msgstr "HBA-Optionsname »%s« ist ungültig und wird ignoriert" #. translator: the second %s is a function name #: libpq/auth-oauth.c:976 -#, fuzzy, c-format -#| msgid "validator \"%s\" is not permitted by %s" +#, c-format msgid "validator module \"%s\", in call to %s" -msgstr "Validator »%s« ist nicht durch %s erlaubt" +msgstr "Validator-Modul »%s«, in Aufruf von %s" #: libpq/auth-oauth.c:1066 libpq/auth-oauth.c:1070 libpq/hba.c:2322 #, c-format @@ -19632,12 +19390,12 @@ msgstr "unbekannter Authentifizierungsoptionsname: »%s«" #: libpq/auth-oauth.c:1073 #, c-format msgid "The installed validator module (\"%s\") did not define an option named \"%s\"." -msgstr "" +msgstr "Das installierte Validator-Modul (»%s«) hat keine Option namens »%s« definiert." #: libpq/auth-oauth.c:1075 #, c-format msgid "All OAuth connections matching this line will fail. Correct the option and reload the server configuration." -msgstr "" +msgstr "Alle auf diese Zeile passenden OAuth-Verbindungen werden fehlschlagen. Korrigieren Sie die Option und laden Sie die Serverkonfiguration neu." #: libpq/auth-sasl.c:95 #, c-format @@ -19946,10 +19704,8 @@ msgid "could not generate random MD5 salt" msgstr "konnte zufälliges MD5-Salt nicht erzeugen" #: libpq/auth.c:945 -#, fuzzy -#| msgid "setting an MD5-encrypted password" msgid "authenticated with an MD5-encrypted password" -msgstr "ein MD5-verschlüsseltes Passwort wird gesetzt" +msgstr "authentifiziert mit einem MD5-verschlüsselten Passwort" #: libpq/auth.c:946 libpq/crypt.c:247 #, c-format @@ -20102,10 +19858,9 @@ msgid "could not release PAM authenticator: %s" msgstr "konnte PAM-Authenticator nicht freigeben: %s" #: libpq/auth.c:2281 -#, fuzzy, c-format -#| msgid "could not initialize LDAP: error code %d" +#, c-format msgid "could not initialize LDAP: error code %lu" -msgstr "konnte LDAP nicht initialisieren: Fehlercode %d" +msgstr "konnte LDAP nicht initialisieren: Fehlercode %lu" #: libpq/auth.c:2318 #, c-format @@ -20317,10 +20072,9 @@ msgid "File must have permissions u=rw (0600) or less if owned by the database u msgstr "Dateirechte müssen u=rw (0600) oder weniger sein, wenn der Eigentümer der Datenbankbenutzer ist, oder u=rw,g=r (0640) oder weniger, wenn der Eigentümer »root« ist." #: libpq/be-secure-common.c:222 -#, fuzzy, c-format -#| msgid "option \"%s\" cannot be specified with other options" +#, c-format msgid "default and non-SNI entries cannot be mixed with other entries" -msgstr "Option »%s« kann nicht mit anderen Optionen angegeben werden" +msgstr "Default- und Nicht-SNI-Einträge können nicht mit anderen Einträgen gemischt werden" #: libpq/be-secure-common.c:237 libpq/be-secure-common.c:261 libpq/hba.c:1289 #, c-format @@ -20328,39 +20082,34 @@ msgid "missing entry at end of line" msgstr "fehlender Eintrag am Ende der Zeile" #: libpq/be-secure-common.c:247 -#, fuzzy, c-format -#| msgid "multiple values specified for netmask" +#, c-format msgid "multiple values specified for SSL certificate" -msgstr "mehrere Werte für Netzmaske angegeben" +msgstr "mehrere Werte für SSL-Zertifikat angegeben" #: libpq/be-secure-common.c:271 -#, fuzzy, c-format -#| msgid "multiple values specified for netmask" +#, c-format msgid "multiple values specified for SSL key" -msgstr "mehrere Werte für Netzmaske angegeben" +msgstr "mehrere Werte für SSL-Schlüssel angegeben" #: libpq/be-secure-common.c:288 -#, fuzzy, c-format -#| msgid "multiple values specified for netmask" +#, c-format msgid "multiple values specified for SSL CA" -msgstr "mehrere Werte für Netzmaske angegeben" +msgstr "mehrere Werte für SSL-CA angegeben" #: libpq/be-secure-common.c:305 -#, fuzzy, c-format -#| msgid "multiple values specified for host address" +#, c-format msgid "multiple values specified for SSL passphrase command" -msgstr "mehrere Werte für Hostadresse angegeben" +msgstr "mehrere Werte für SSL-Passphrasen-Befehl angegeben" #: libpq/be-secure-common.c:333 -#, fuzzy, c-format -#| msgid "unexpected end of line" +#, c-format msgid "extra fields at end of line" -msgstr "unerwartetes Ende der Zeile" +msgstr "zusätzliche Felder am Ende der Zeile" #: libpq/be-secure-common.c:343 #, c-format msgid "incorrect syntax for boolean value SSL_passphrase_cmd_reload" -msgstr "" +msgstr "falsche Syntax für Boole’schen Wert SSL_passphrase_cmd_reload" #: libpq/be-secure-gssapi.c:211 msgid "GSSAPI wrap error" @@ -20399,47 +20148,40 @@ msgid "GSSAPI size check error" msgstr "GSSAPI-Fehler bei der Größenprüfung" #: libpq/be-secure-openssl.c:214 -#, fuzzy, c-format -#| msgid "ldaps not supported with this LDAP library" +#, c-format msgid "ssl_sni is not supported with LibreSSL" -msgstr "ldaps wird mit dieser LDAP-Bibliothek nicht unterstützt" +msgstr "ssl_sni wird mit LibreSSL nicht unterstützt" #: libpq/be-secure-openssl.c:231 -#, fuzzy, c-format -#| msgid "could not load library \"%s\": %s" +#, c-format msgid "could not load \"%s\": %s" -msgstr "konnte Bibliothek »%s« nicht laden: %s" +msgstr "konnte »%s« nicht laden: %s" #: libpq/be-secure-openssl.c:269 -#, fuzzy, c-format -#| msgid "multiple recovery targets specified" +#, c-format msgid "multiple default hosts specified" -msgstr "mehrere Wiederherstellungsziele angegeben" +msgstr "mehrere Default-Hosts angegeben" #: libpq/be-secure-openssl.c:283 -#, fuzzy, c-format -#| msgid "multiple recovery targets specified" +#, c-format msgid "multiple no_sni hosts specified" -msgstr "mehrere Wiederherstellungsziele angegeben" +msgstr "mehrere no_sni-Hosts angegeben" #: libpq/be-secure-openssl.c:307 -#, fuzzy, c-format -#| msgid "multiple recovery targets specified" +#, c-format msgid "multiple entries for host \"%s\" specified" -msgstr "mehrere Wiederherstellungsziele angegeben" +msgstr "mehrere Einträge für Host »%s« angegeben" #: libpq/be-secure-openssl.c:365 -#, fuzzy, c-format -#| msgid "SSL configuration was not reloaded" +#, c-format msgid "no SSL configurations loaded" -msgstr "SSL-Konfiguration wurde nicht neu geladen" +msgstr "keine SSL-Konfigurationen geladen" #. translator: The two %s contain filenames #: libpq/be-secure-openssl.c:367 -#, fuzzy, c-format -#| msgid "line %d of configuration file \"%s\": \"%s\"" +#, c-format msgid "If ssl_sni is enabled then add configuration to \"%s\", else \"%s\"" -msgstr "Zeile %d in Konfigurationsdatei »%s«: »%s«" +msgstr "Wenn ssl_sni eingeschaltet ist, fügen Sie die Konfiguration zu »%s« hinzu, sonst zu »%s«" #: libpq/be-secure-openssl.c:388 libpq/be-secure-openssl.c:620 #, c-format @@ -20469,8 +20211,8 @@ msgstr "konnte SSL-Protokollversionsbereich nicht setzen" #: libpq/be-secure-openssl.c:474 #, c-format -msgid "\"%s\" cannot be higher than \"%s\"" -msgstr "»%s« kann nicht höher als »%s« sein" +msgid "\"%s\" cannot be higher than \"%s\"." +msgstr "»%s« kann nicht höher als »%s« sein." #: libpq/be-secure-openssl.c:527 #, c-format @@ -20485,13 +20227,13 @@ msgstr "konnte TLSv1.3-Cipher-Suites nicht setzen (keine gültigen Ciphers verf #: libpq/be-secure-openssl.c:641 #, c-format msgid "SNI is enabled; installed TLS init hook will be ignored" -msgstr "" +msgstr "SNI ist eingeschaltet; installierter TLS-Init-Hook wird ignoriert" #. translator: first %s is a GUC, second %s contains a filename #: libpq/be-secure-openssl.c:643 #, c-format msgid "TLS init hooks are incompatible with SNI. Set \"%s\" to \"off\" to make use of the hook that is currently installed, or remove the hook and use per-host passphrase commands in \"%s\"." -msgstr "" +msgstr "TLS-Init-Hooks sind inkompatibel mit SNI. Setzen Sie »%s« auf »off«, um den aktuell installierten Hook zu verwenden, oder entfernen Sie den Hook und verwenden Sie Passphrase-Befehle pro Host in »%s«." #: libpq/be-secure-openssl.c:695 #, c-format @@ -20636,12 +20378,12 @@ msgstr "unbekannt" #: libpq/be-secure-openssl.c:2030 #, c-format msgid "no hostname provided in callback, and no fallback configured" -msgstr "" +msgstr "kein Hostname im Callback angegeben und kein Fallback konfiguriert" #: libpq/be-secure-openssl.c:2054 #, c-format msgid "failed to switch to SSL configuration for host, terminating connection" -msgstr "" +msgstr "konnte nicht auf SSL-Konfiguration für Host umschalten, Verbindung wird abgebrochen" #: libpq/be-secure-openssl.c:2090 #, c-format @@ -20707,37 +20449,34 @@ msgid "User \"%s\" has an expired password." msgstr "Benutzer »%s« hat ein abgelaufenes Passwort." #: libpq/crypt.c:119 -#, fuzzy -#| msgid "password is required" msgid "role password will expire soon" -msgstr "Passwort wird benötigt" +msgstr "Passwort der Rolle läuft bald ab" #: libpq/crypt.c:122 -#, fuzzy, c-format -#| msgid "password file \"%s\" is empty" +#, c-format msgid "The password for role \"%s\" will expire in %d day." msgid_plural "The password for role \"%s\" will expire in %d days." -msgstr[0] "Passwortdatei »%s« ist leer" -msgstr[1] "Passwortdatei »%s« ist leer" +msgstr[0] "Das Passwort für Rolle »%s« läuft in %d Tag ab." +msgstr[1] "Das Passwort für Rolle »%s« läuft in %d Tagen ab." #: libpq/crypt.c:127 #, c-format msgid "The password for role \"%s\" will expire in %d hour." msgid_plural "The password for role \"%s\" will expire in %d hours." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Das Passwort für Rolle »%s« läuft in %d Stunde ab." +msgstr[1] "Das Passwort für Rolle »%s« läuft in %d Stunden ab." #: libpq/crypt.c:132 #, c-format msgid "The password for role \"%s\" will expire in %d minute." msgid_plural "The password for role \"%s\" will expire in %d minutes." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Das Passwort für Rolle »%s« läuft in %d Minute ab." +msgstr[1] "Das Passwort für Rolle »%s« läuft in %d Minuten ab." #: libpq/crypt.c:137 #, c-format msgid "The password for role \"%s\" will expire in less than 1 minute." -msgstr "" +msgstr "Das Passwort für Rolle »%s« läuft in weniger als 1 Minute ab." #: libpq/crypt.c:237 #, c-format @@ -21039,10 +20778,9 @@ msgid "sspi" msgstr "sspi" #: libpq/hba.c:2301 -#, fuzzy, c-format -#| msgid "invalid value for clientname: \"%s\"" +#, c-format msgid "invalid OAuth validator option name: \"%s\"" -msgstr "ungültiger Wert für clientname: »%s«" +msgstr "ungültiger OAuth-Validator-Optionsname: »%s«" #: libpq/hba.c:2514 #, c-format @@ -21580,7 +21318,7 @@ msgstr "unbenanntes Portal mit Parametern: %s" msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" msgstr "FULL JOIN wird nur für Merge- oder Hash-Verbund-fähige Verbundbedingungen unterstützt" -#: optimizer/plan/createplan.c:7160 parser/parse_merge.c:203 +#: optimizer/plan/createplan.c:7161 parser/parse_merge.c:203 #: rewrite/rewriteHandler.c:1741 #, c-format msgid "cannot execute MERGE on relation \"%s\"" @@ -21593,55 +21331,54 @@ msgid "%s cannot be applied to the nullable side of an outer join" msgstr "%s kann nicht auf die nullbare Seite eines äußeren Verbundes angewendet werden" #: optimizer/plan/planner.c:873 -#, fuzzy, c-format -#| msgid "cannot set generated column \"%s\"" +#, c-format msgid "cannot use generated column \"%s\" in FOR PORTION OF" -msgstr "kann generierte Spalte »%s« nicht setzen" +msgstr "generierte Spalte »%s« kann nicht in FOR PORTION OF verwendet werden" -#: optimizer/plan/planner.c:1114 +#: optimizer/plan/planner.c:1116 #, c-format msgid "FOR PORTION OF bounds cannot contain volatile functions" -msgstr "" +msgstr "FOR-PORTION-OF-Begrenzungen dürfen keine volatilen Funktionen enthalten" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1782 parser/analyze.c:2188 parser/analyze.c:2447 -#: parser/analyze.c:3751 +#: optimizer/plan/planner.c:1784 parser/analyze.c:2185 parser/analyze.c:2444 +#: parser/analyze.c:3748 #, c-format msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" msgstr "%s ist nicht in UNION/INTERSECT/EXCEPT erlaubt" -#: optimizer/plan/planner.c:2528 optimizer/plan/planner.c:4407 +#: optimizer/plan/planner.c:2530 optimizer/plan/planner.c:4409 #, c-format msgid "could not implement GROUP BY" msgstr "konnte GROUP BY nicht implementieren" -#: optimizer/plan/planner.c:2529 optimizer/plan/planner.c:4408 -#: optimizer/plan/planner.c:5089 optimizer/prep/prepunion.c:1127 +#: optimizer/plan/planner.c:2531 optimizer/plan/planner.c:4410 +#: optimizer/plan/planner.c:5091 optimizer/prep/prepunion.c:1127 #, c-format msgid "Some of the datatypes only support hashing, while others only support sorting." msgstr "Einige Datentypen unterstützen nur Hashing, während andere nur Sortieren unterstützen." -#: optimizer/plan/planner.c:5088 +#: optimizer/plan/planner.c:5090 #, c-format msgid "could not implement DISTINCT" msgstr "konnte DISTINCT nicht implementieren" -#: optimizer/plan/planner.c:6553 +#: optimizer/plan/planner.c:6555 #, c-format msgid "could not implement window PARTITION BY" msgstr "konnte PARTITION BY für Fenster nicht implementieren" -#: optimizer/plan/planner.c:6554 +#: optimizer/plan/planner.c:6556 #, c-format msgid "Window partitioning columns must be of sortable datatypes." msgstr "Fensterpartitionierungsspalten müssen sortierbare Datentypen haben." -#: optimizer/plan/planner.c:6558 +#: optimizer/plan/planner.c:6560 #, c-format msgid "could not implement window ORDER BY" msgstr "konnte ORDER BY für Fenster nicht implementieren" -#: optimizer/plan/planner.c:6559 +#: optimizer/plan/planner.c:6561 #, c-format msgid "Window ordering columns must be of sortable datatypes." msgstr "Fenstersortierspalten müssen sortierbare Datentypen haben." @@ -21672,7 +21409,7 @@ msgstr "Attribut »%s« von Relation »%s« stimmt nicht mit dem Typ der Elternt msgid "attribute \"%s\" of relation \"%s\" does not match parent's collation" msgstr "Attribut »%s« von Relation »%s« stimmt nicht mit der Sortierfolge der Elterntabelle überein" -#: optimizer/util/clauses.c:5733 +#: optimizer/util/clauses.c:5742 #, c-format msgid "SQL function \"%s\" during inlining" msgstr "SQL-Funktion »%s« beim Inlining" @@ -21693,22 +21430,21 @@ msgid "constraint in ON CONFLICT clause has no associated index" msgstr "Constraint in der ON-CONFLICT-Klausel hat keinen zugehörigen Index" #: optimizer/util/plancat.c:1022 -#, fuzzy, c-format -#| msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +#, c-format msgid "ON CONFLICT DO %s not supported with exclusion constraints" -msgstr "ON CONFLICT DO UPDATE nicht unterstützt mit Exclusion-Constraints" +msgstr "ON CONFLICT DO %s nicht unterstützt mit Exclusion-Constraints" #: optimizer/util/plancat.c:1190 #, c-format msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" msgstr "es gibt keinen Unique-Constraint oder Exclusion-Constraint, der auf die ON-CONFLICT-Angabe passt" -#: parser/analyze.c:605 parser/analyze.c:2881 +#: parser/analyze.c:605 parser/analyze.c:2878 #, c-format msgid "WHERE CURRENT OF on a view is not implemented" msgstr "WHERE CURRENT OF mit einer Sicht ist nicht implementiert" -#: parser/analyze.c:912 parser/analyze.c:1967 +#: parser/analyze.c:912 parser/analyze.c:1964 #, c-format msgid "VALUES lists must all be the same length" msgstr "VALUES-Listen müssen alle die gleiche Länge haben" @@ -21716,7 +21452,7 @@ msgstr "VALUES-Listen müssen alle die gleiche Länge haben" #: parser/analyze.c:1067 rewrite/rewriteHandler.c:706 #, c-format msgid "ON CONFLICT DO SELECT requires a RETURNING clause" -msgstr "" +msgstr "ON CONFLICT DO SELECT erfordert eine RETURNING-Klausel" #: parser/analyze.c:1123 #, c-format @@ -21734,274 +21470,263 @@ msgid "The insertion source is a row expression containing the same number of co msgstr "Der einzufügende Wert ist ein Zeilenausdruck mit der gleichen Anzahl Spalten wie von INSERT erwartet. Haben Sie versehentlich zu viele Klammern gesetzt?" #: parser/analyze.c:1345 -#, fuzzy, c-format -#| msgid "WHERE CURRENT OF on a view is not implemented" +#, c-format msgid "WHERE CURRENT OF with FOR PORTION OF is not implemented" -msgstr "WHERE CURRENT OF mit einer Sicht ist nicht implementiert" +msgstr "WHERE CURRENT OF mit FOR PORTION OF ist nicht implementiert" #: parser/analyze.c:1401 -#, fuzzy, c-format -#| msgid "could not close target file \"%s\": %m" +#, c-format msgid "could not coerce FOR PORTION OF target from %s to %s" -msgstr "konnte Zieldatei »%s« nicht schließen: %m" +msgstr "konnte FOR-PORTION-OF-Ziel nicht von %s in %s umwandeln" #: parser/analyze.c:1422 -#, fuzzy, c-format -#| msgid "column \"%s\" of relation \"%s\" is not a generated column" +#, c-format msgid "column \"%s\" of relation \"%s\" is not a range or multirange type" -msgstr "Spalte »%s« von Relation »%s« ist keine generierte Spalte" +msgstr "Spalte »%s« von Relation »%s« ist kein Range- oder Multirange-Typ" #: parser/analyze.c:1443 -#, fuzzy, c-format -#| msgid "column \"%s\" of relation \"%s\" is not a generated column" +#, c-format msgid "column \"%s\" of relation \"%s\" is not a range type" -msgstr "Spalte »%s« von Relation »%s« ist keine generierte Spalte" +msgstr "Spalte »%s« von Relation »%s« ist kein Range-Typ" #: parser/analyze.c:1475 parser/analyze.c:1483 -#, fuzzy, c-format -#| msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +#, c-format msgid "could not coerce FOR PORTION OF %s bound from %s to %s" -msgstr "konnte symbolische Verknüpfung von »%s« nach »%s« nicht erzeugen: %m" +msgstr "konnte %s-Begrenzung von FOR PORTION OF nicht von %s in %s umwandeln" #: parser/analyze.c:1507 -#, fuzzy, c-format -#| msgid "You must specify a hash operator class or define a default hash operator class for the data type." +#, c-format msgid "You must define a default operator class for the data type." -msgstr "Sie müssen eine hash-Operatorklasse angeben oder eine hash-Standardoperatorklasse für den Datentyp definieren." +msgstr "Sie müssen eine Standardoperatorklasse für den Datentyp definieren." #: parser/analyze.c:1574 -#, fuzzy, c-format -#| msgid "could not identify a hash function for type %s" +#, c-format msgid "could not identify an intersect function for type %s" -msgstr "konnte keine Hash-Funktion für Typ %s ermitteln" +msgstr "konnte keine Intersect-Funktion für Typ %s ermitteln" -#: parser/analyze.c:1764 parser/analyze.c:2161 +#: parser/analyze.c:1763 parser/analyze.c:2158 #, c-format msgid "SELECT ... INTO is not allowed here" msgstr "SELECT ... INTO ist hier nicht erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2090 parser/analyze.c:3983 +#: parser/analyze.c:2087 parser/analyze.c:3980 #, c-format msgid "%s cannot be applied to VALUES" msgstr "%s kann nicht auf VALUES angewendet werden" -#: parser/analyze.c:2328 +#: parser/analyze.c:2325 #, c-format msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" msgstr "ungültige ORDER-BY-Klausel mit UNION/INTERSECT/EXCEPT" -#: parser/analyze.c:2329 +#: parser/analyze.c:2326 #, c-format msgid "Only result column names can be used, not expressions or functions." msgstr "Es können nur Ergebnisspaltennamen verwendet werden, keine Ausdrücke oder Funktionen." -#: parser/analyze.c:2330 +#: parser/analyze.c:2327 #, c-format msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." msgstr "Fügen Sie den Ausdrück/die Funktion jedem SELECT hinzu oder verlegen Sie die UNION in eine FROM-Klausel." -#: parser/analyze.c:2437 +#: parser/analyze.c:2434 #, c-format msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" msgstr "INTO ist nur im ersten SELECT von UNION/INTERSECT/EXCEPT erlaubt" -#: parser/analyze.c:2507 +#: parser/analyze.c:2504 #, c-format msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" msgstr "Teilanweisung von UNION/INTERSECT/EXCEPT kann nicht auf andere Relationen auf der selben Anfrageebene verweisen" -#: parser/analyze.c:2619 +#: parser/analyze.c:2616 #, c-format msgid "each %s query must have the same number of columns" msgstr "jede %s-Anfrage muss die gleiche Anzahl Spalten haben" -#: parser/analyze.c:2986 +#: parser/analyze.c:2983 #, c-format msgid "SET target columns cannot be qualified with the relation name." msgstr "SET-Zielspalten können nicht mit dem Relationsnamen qualifiziert werden." -#: parser/analyze.c:2998 -#, fuzzy, c-format -#| msgid "cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"" +#: parser/analyze.c:2995 +#, c-format msgid "cannot update column \"%s\" because it is used in FOR PORTION OF" -msgstr "Spalte »%s« kann nicht geändert werden, weil sie Teil des Partitionierungsschlüssels von Relation »%s« ist" +msgstr "Spalte »%s« kann nicht aktualisiert werden, weil sie in FOR PORTION OF verwendet wird" #. translator: %s is OLD or NEW -#: parser/analyze.c:3087 parser/analyze.c:3097 +#: parser/analyze.c:3084 parser/analyze.c:3094 #, c-format msgid "%s cannot be specified multiple times" msgstr "%s kann nicht mehrmals angegeben werden" -#: parser/analyze.c:3109 parser/parse_relation.c:469 +#: parser/analyze.c:3106 parser/parse_relation.c:469 #, c-format msgid "table name \"%s\" specified more than once" msgstr "Tabellenname »%s« mehrmals angegeben" -#: parser/analyze.c:3157 +#: parser/analyze.c:3154 #, c-format msgid "RETURNING must have at least one column" msgstr "RETURNING muss mindestens eine Spalte haben" -#: parser/analyze.c:3281 +#: parser/analyze.c:3278 #, c-format msgid "assignment source returned %d column" msgid_plural "assignment source returned %d columns" msgstr[0] "Quelle der Wertzuweisung hat %d Spalte zurückgegeben" msgstr[1] "Quelle der Wertzuweisung hat %d Spalten zurückgegeben" -#: parser/analyze.c:3342 +#: parser/analyze.c:3339 #, c-format msgid "variable \"%s\" is of type %s but expression is of type %s" msgstr "Variable »%s« hat Typ %s, aber der Ausdruck hat Typ %s" #. translator: %s is a SQL keyword -#: parser/analyze.c:3378 parser/analyze.c:3386 +#: parser/analyze.c:3375 parser/analyze.c:3383 #, c-format msgid "cannot specify both %s and %s" msgstr "%s und %s können nicht beide angegeben werden" -#: parser/analyze.c:3406 +#: parser/analyze.c:3403 #, c-format msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" msgstr "DECLARE CURSOR darf keine datenmodifizierenden Anweisungen in WITH enthalten" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3414 +#: parser/analyze.c:3411 #, c-format msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" msgstr "DECLARE CURSOR WITH HOLD ... %s wird nicht unterstützt" -#: parser/analyze.c:3417 +#: parser/analyze.c:3414 #, c-format msgid "Holdable cursors must be READ ONLY." msgstr "Haltbare Cursor müssen READ ONLY sein." #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3425 +#: parser/analyze.c:3422 #, c-format msgid "DECLARE SCROLL CURSOR ... %s is not supported" msgstr "DECLARE SCROLL CURSOR ... %s wird nicht unterstützt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3436 +#: parser/analyze.c:3433 #, c-format msgid "DECLARE INSENSITIVE CURSOR ... %s is not valid" msgstr "DECLARE INSENSITIVE CURSOR ... %s ist nicht gültig" -#: parser/analyze.c:3439 +#: parser/analyze.c:3436 #, c-format msgid "Insensitive cursors must be READ ONLY." msgstr "Insensitive Cursor müssen READ ONLY sein." -#: parser/analyze.c:3535 +#: parser/analyze.c:3532 #, c-format msgid "materialized views must not use data-modifying statements in WITH" msgstr "materialisierte Sichten dürfen keine datenmodifizierenden Anweisungen in WITH verwenden" -#: parser/analyze.c:3545 -#, fuzzy, c-format -#| msgid "materialized views must not use temporary tables or views" +#: parser/analyze.c:3542 +#, c-format msgid "materialized views must not use temporary objects" -msgstr "materialisierte Sichten dürfen keine temporären Tabellen oder Sichten verwenden" +msgstr "materialisierte Sichten dürfen keine temporären Objekte verwenden" -#: parser/analyze.c:3546 -#, fuzzy, c-format -#| msgid "%s depends on %s" +#: parser/analyze.c:3543 +#, c-format msgid "This view depends on temporary %s." -msgstr "%s hängt von %s ab" +msgstr "Diese Sicht hängt von temporärem %s ab." -#: parser/analyze.c:3557 +#: parser/analyze.c:3554 #, c-format msgid "materialized views may not be defined using bound parameters" msgstr "materialisierte Sichten können nicht unter Verwendung von gebundenen Parametern definiert werden" -#: parser/analyze.c:3569 +#: parser/analyze.c:3566 #, c-format msgid "materialized views cannot be unlogged" msgstr "materialisierte Sichten können nicht ungeloggt sein" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3758 +#: parser/analyze.c:3755 #, c-format msgid "%s is not allowed with DISTINCT clause" msgstr "%s ist nicht mit DISTINCT-Klausel erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3765 +#: parser/analyze.c:3762 #, c-format msgid "%s is not allowed with GROUP BY clause" msgstr "%s ist nicht mit GROUP-BY-Klausel erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3772 +#: parser/analyze.c:3769 #, c-format msgid "%s is not allowed with HAVING clause" msgstr "%s ist nicht mit HAVING-Klausel erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3779 +#: parser/analyze.c:3776 #, c-format msgid "%s is not allowed with aggregate functions" msgstr "%s ist nicht mit Aggregatfunktionen erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3786 +#: parser/analyze.c:3783 #, c-format msgid "%s is not allowed with window functions" msgstr "%s ist nicht mit Fensterfunktionen erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3793 +#: parser/analyze.c:3790 #, c-format msgid "%s is not allowed with set-returning functions in the target list" msgstr "%s ist nicht mit Funktionen mit Ergebnismenge in der Targetliste erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3892 +#: parser/analyze.c:3889 #, c-format msgid "%s must specify unqualified relation names" msgstr "%s muss unqualifizierte Relationsnamen angeben" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3956 +#: parser/analyze.c:3953 #, c-format msgid "%s cannot be applied to a join" msgstr "%s kann nicht auf einen Verbund angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3965 +#: parser/analyze.c:3962 #, c-format msgid "%s cannot be applied to a function" msgstr "%s kann nicht auf eine Funktion angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3974 +#: parser/analyze.c:3971 #, c-format msgid "%s cannot be applied to a table function" msgstr "%s kann nicht auf eine Tabellenfunktion angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:3992 +#: parser/analyze.c:3989 #, c-format msgid "%s cannot be applied to a WITH query" msgstr "%s kann nicht auf eine WITH-Anfrage angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:4001 +#: parser/analyze.c:3998 #, c-format msgid "%s cannot be applied to a named tuplestore" msgstr "%s kann nicht auf einen benannten Tupelstore angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:4010 -#, fuzzy, c-format -#| msgid "%s cannot be applied to VALUES" +#: parser/analyze.c:4007 +#, c-format msgid "%s cannot be applied to GRAPH_TABLE" -msgstr "%s kann nicht auf VALUES angewendet werden" +msgstr "%s kann nicht auf GRAPH_TABLE angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:4030 +#: parser/analyze.c:4027 #, c-format msgid "relation \"%s\" in %s clause not found in FROM clause" msgstr "Relation »%s« in %s nicht in der FROM-Klausel gefunden" @@ -22190,31 +21915,23 @@ msgid "grouping operations are not allowed in COPY FROM WHERE conditions" msgstr "Gruppieroperationen sind in COPY-FROM-WHERE-Bedingungen nicht erlaubt" #: parser/parse_agg.c:589 -#, fuzzy -#| msgid "aggregate functions are not allowed in DEFAULT expressions" msgid "aggregate functions are not allowed in FOR PORTION OF expressions" -msgstr "Aggregatfunktionen sind in DEFAULT-Ausdrücken nicht erlaubt" +msgstr "Aggregatfunktionen sind in FOR-PORTION-OF-Ausdrücken nicht erlaubt" #: parser/parse_agg.c:591 -#, fuzzy -#| msgid "grouping operations are not allowed in DEFAULT expressions" msgid "grouping operations are not allowed in FOR PORTION OF expressions" -msgstr "Gruppieroperationen sind in DEFAULT-Ausdrücken nicht erlaubt" +msgstr "Gruppieroperationen sind in FOR-PORTION-OF-Ausdrücken nicht erlaubt" #: parser/parse_agg.c:597 -#, fuzzy -#| msgid "aggregate functions are not allowed in partition key expressions" msgid "aggregate functions are not allowed in property definition expressions" -msgstr "Aggregatfunktionen sind in Partitionierungsschlüsselausdrücken nicht erlaubt" +msgstr "Aggregatfunktionen sind in Property-Definitionsausdrücken nicht erlaubt" #: parser/parse_agg.c:599 -#, fuzzy -#| msgid "grouping operations are not allowed in partition key expressions" msgid "grouping operations are not allowed in property definition expressions" -msgstr "Gruppieroperationen sind in Partitionierungsschlüsselausdrücken nicht erlaubt" +msgstr "Gruppieroperationen sind in Property-Definitionsausdrücken nicht erlaubt" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:622 parser/parse_clause.c:2110 +#: parser/parse_agg.c:622 parser/parse_clause.c:2140 #, c-format msgid "aggregate functions are not allowed in %s" msgstr "Aggregatfunktionen sind in %s nicht erlaubt" @@ -22329,24 +22046,20 @@ msgid "window functions are not allowed in column generation expressions" msgstr "Fensterfunktionen sind in Spaltengenerierungsausdrücken nicht erlaubt" #: parser/parse_agg.c:1043 -#, fuzzy -#| msgid "window functions are not allowed in partition key expressions" msgid "window functions are not allowed in property definition expressions" -msgstr "Fensterfunktionen sind in Partitionierungsschlüsselausdrücken nicht erlaubt" +msgstr "Fensterfunktionen sind in Property-Definitionsausdrücken nicht erlaubt" #: parser/parse_agg.c:1046 -#, fuzzy -#| msgid "window functions are not allowed in DEFAULT expressions" msgid "window functions are not allowed in FOR PORTION OF expressions" -msgstr "Fensterfunktionen sind in DEFAULT-Ausdrücken nicht erlaubt" +msgstr "Fensterfunktionen sind in FOR-PORTION-OF-Ausdrücken nicht erlaubt" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:1066 parser/parse_clause.c:2119 +#: parser/parse_agg.c:1066 parser/parse_clause.c:2149 #, c-format msgid "window functions are not allowed in %s" msgstr "Fensterfunktionen sind in %s nicht erlaubt" -#: parser/parse_agg.c:1100 parser/parse_clause.c:3012 +#: parser/parse_agg.c:1100 parser/parse_clause.c:2982 #, c-format msgid "window \"%s\" does not exist" msgstr "Fenster »%s« existiert nicht" @@ -22446,221 +22159,233 @@ msgstr "Namensraumname »%s« ist nicht eindeutig" msgid "only one default namespace is allowed" msgstr "nur ein Standardnamensraum ist erlaubt" -#: parser/parse_clause.c:996 +#: parser/parse_clause.c:1006 #, c-format msgid "complex graph table column must specify an explicit column name" -msgstr "" +msgstr "komplexe Graph-Table-Spalte muss einen expliziten Spaltennamen angeben" -#: parser/parse_clause.c:1031 +#: parser/parse_clause.c:1041 #, c-format msgid "subqueries within GRAPH_TABLE reference are not supported" -msgstr "" +msgstr "Unteranfragen innerhalb einer GRAPH_TABLE-Referenz werden nicht unterstützt" -#: parser/parse_clause.c:1069 +#: parser/parse_clause.c:1051 +#, c-format +msgid "aggregate functions in GRAPH_TABLE COLUMNS are not supported" +msgstr "Aggregatfunktionen in GRAPH_TABLE COLUMNS werden nicht unterstützt" + +#: parser/parse_clause.c:1055 +#, c-format +msgid "window functions in GRAPH_TABLE COLUMNS are not supported" +msgstr "Fensterfunktionen in GRAPH_TABLE COLUMNS werden nicht unterstützt" + +#: parser/parse_clause.c:1059 +#, c-format +msgid "set-returning functions in GRAPH_TABLE COLUMNS are not supported" +msgstr "Funktionen mit Ergebnismenge in GRAPH_TABLE COLUMNS werden nicht unterstützt" + +#: parser/parse_clause.c:1099 #, c-format msgid "tablesample method %s does not exist" msgstr "Tablesample-Methode %s existiert nicht" -#: parser/parse_clause.c:1091 +#: parser/parse_clause.c:1121 #, c-format msgid "tablesample method %s requires %d argument, not %d" msgid_plural "tablesample method %s requires %d arguments, not %d" msgstr[0] "Tablesample-Methode %s benötigt %d Argument, nicht %d" msgstr[1] "Tablesample-Methode %s benötigt %d Argumente, nicht %d" -#: parser/parse_clause.c:1125 +#: parser/parse_clause.c:1155 #, c-format msgid "tablesample method %s does not support REPEATABLE" msgstr "Tablesample-Methode %s unterstützt REPEATABLE nicht" -#: parser/parse_clause.c:1290 +#: parser/parse_clause.c:1320 #, c-format msgid "TABLESAMPLE clause can only be applied to tables and materialized views" msgstr "TABLESAMPLE-Klausel kann nur auf Tabellen und materialisierte Sichten angewendet werden" -#: parser/parse_clause.c:1477 +#: parser/parse_clause.c:1507 #, c-format msgid "column name \"%s\" appears more than once in USING clause" msgstr "Spaltenname »%s« erscheint mehrmals in der USING-Klausel" -#: parser/parse_clause.c:1492 +#: parser/parse_clause.c:1522 #, c-format msgid "common column name \"%s\" appears more than once in left table" msgstr "gemeinsamer Spaltenname »%s« erscheint mehrmals in der linken Tabelle" -#: parser/parse_clause.c:1501 +#: parser/parse_clause.c:1531 #, c-format msgid "column \"%s\" specified in USING clause does not exist in left table" msgstr "Spalte »%s« aus der USING-Klausel existiert nicht in der linken Tabelle" -#: parser/parse_clause.c:1516 +#: parser/parse_clause.c:1546 #, c-format msgid "common column name \"%s\" appears more than once in right table" msgstr "gemeinsamer Spaltenname »%s« erscheint mehrmals in der rechten Tabelle" -#: parser/parse_clause.c:1525 +#: parser/parse_clause.c:1555 #, c-format msgid "column \"%s\" specified in USING clause does not exist in right table" msgstr "Spalte »%s« aus der USING-Klausel existiert nicht in der rechten Tabelle" -#: parser/parse_clause.c:2055 +#: parser/parse_clause.c:2085 #, c-format msgid "row count cannot be null in FETCH FIRST ... WITH TIES clause" msgstr "Zeilenzahl in FETCH FIRST ... WITH TIES darf nicht NULL sein" #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_clause.c:2080 +#: parser/parse_clause.c:2110 #, c-format msgid "argument of %s must not contain variables" msgstr "Argument von %s darf keine Variablen enthalten" #. translator: first %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:2245 +#: parser/parse_clause.c:2275 #, c-format msgid "%s \"%s\" is ambiguous" msgstr "%s »%s« ist nicht eindeutig" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:2273 +#: parser/parse_clause.c:2303 #, c-format msgid "non-integer constant in %s" msgstr "Konstante in %s ist keine ganze Zahl" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:2295 +#: parser/parse_clause.c:2325 #, c-format msgid "%s position %d is not in select list" msgstr "%s Position %d ist nicht in der Select-Liste" -#: parser/parse_clause.c:2734 +#: parser/parse_clause.c:2764 #, c-format msgid "CUBE is limited to 12 elements" msgstr "CUBE ist auf 12 Elemente begrenzt" -#: parser/parse_clause.c:3000 +#: parser/parse_clause.c:2970 #, c-format msgid "window \"%s\" is already defined" msgstr "Fenster »%s« ist bereits definiert" -#: parser/parse_clause.c:3062 +#: parser/parse_clause.c:3031 #, c-format msgid "cannot override PARTITION BY clause of window \"%s\"" msgstr "PARTITION-BY-Klausel von Fenster »%s« kann nicht aufgehoben werden" -#: parser/parse_clause.c:3074 +#: parser/parse_clause.c:3043 #, c-format msgid "cannot override ORDER BY clause of window \"%s\"" msgstr "ORDER-BY-Klausel von Fenster »%s« kann nicht aufgehoben werden" -#: parser/parse_clause.c:3104 parser/parse_clause.c:3110 +#: parser/parse_clause.c:3073 parser/parse_clause.c:3079 #, c-format msgid "cannot copy window \"%s\" because it has a frame clause" msgstr "kann Fenster »%s« nicht kopieren, weil es eine Frame-Klausel hat" -#: parser/parse_clause.c:3112 +#: parser/parse_clause.c:3081 #, c-format msgid "Omit the parentheses in this OVER clause." msgstr "Lassen Sie die Klammern in dieser OVER-Klausel weg." -#: parser/parse_clause.c:3132 +#: parser/parse_clause.c:3101 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" msgstr "RANGE mit Offset PRECEDING/FOLLOWING benötigt genau eine ORDER-BY-Spalte" -#: parser/parse_clause.c:3155 +#: parser/parse_clause.c:3124 #, c-format msgid "GROUPS mode requires an ORDER BY clause" msgstr "GROUPS-Modus erfordert eine ORDER-BY-Klausel" -#: parser/parse_clause.c:3225 +#: parser/parse_clause.c:3194 #, c-format msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" msgstr "in einer Aggregatfunktion mit DISTINCT müssen ORDER-BY-Ausdrücke in der Argumentliste erscheinen" -#: parser/parse_clause.c:3226 +#: parser/parse_clause.c:3195 #, c-format msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" msgstr "bei SELECT DISTINCT müssen ORDER-BY-Ausdrücke in der Select-Liste erscheinen" -#: parser/parse_clause.c:3258 +#: parser/parse_clause.c:3227 #, c-format msgid "an aggregate with DISTINCT must have at least one argument" msgstr "eine Aggregatfunktion mit DISTINCT muss mindestens ein Argument haben" -#: parser/parse_clause.c:3259 +#: parser/parse_clause.c:3228 #, c-format msgid "SELECT DISTINCT must have at least one column" msgstr "SELECT DISTINCT muss mindestens eine Spalte haben" -#: parser/parse_clause.c:3325 parser/parse_clause.c:3357 +#: parser/parse_clause.c:3294 parser/parse_clause.c:3326 #, c-format msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" msgstr "Ausdrücke in SELECT DISTINCT ON müssen mit den ersten Ausdrücken in ORDER BY übereinstimmen" -#: parser/parse_clause.c:3435 parser/parse_clause.c:3441 -#, fuzzy, c-format -#| msgid "ASC/DESC is not allowed in ON CONFLICT clause" +#: parser/parse_clause.c:3404 parser/parse_clause.c:3410 +#, c-format msgid "%s is not allowed in ON CONFLICT clause" -msgstr "ASC/DESC ist in der ON-CONFLICT-Klausel nicht erlaubt" +msgstr "%s ist in der ON-CONFLICT-Klausel nicht erlaubt" -#: parser/parse_clause.c:3447 -#, fuzzy, c-format -#| msgid "ASC/DESC is not allowed in ON CONFLICT clause" +#: parser/parse_clause.c:3416 +#, c-format msgid "operator class options are not allowed in ON CONFLICT clause" -msgstr "ASC/DESC ist in der ON-CONFLICT-Klausel nicht erlaubt" +msgstr "Operatorklassenoptionen sind in der ON-CONFLICT-Klausel nicht erlaubt" -#: parser/parse_clause.c:3526 -#, fuzzy, c-format -#| msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" +#: parser/parse_clause.c:3495 +#, c-format msgid "ON CONFLICT DO %s requires inference specification or constraint name" -msgstr "ON CONFLICT DO UPDATE benötigt Inferenzangabe oder Constraint-Namen" +msgstr "ON CONFLICT DO %s benötigt Inferenzangabe oder Constraint-Namen" -#: parser/parse_clause.c:3528 +#: parser/parse_clause.c:3497 #, c-format msgid "For example, ON CONFLICT (column_name)." msgstr "Zum Bespiel ON CONFLICT (Spaltenname)." -#: parser/parse_clause.c:3539 +#: parser/parse_clause.c:3508 #, c-format msgid "ON CONFLICT is not supported with system catalog tables" msgstr "ON CONFLICT wird nicht mit Systemkatalogtabellen unterstützt" -#: parser/parse_clause.c:3547 +#: parser/parse_clause.c:3516 #, c-format msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" msgstr "ON CONFLICT wird nicht unterstützt mit Tabelle »%s«, die als Katalogtabelle verwendet wird" -#: parser/parse_clause.c:3678 +#: parser/parse_clause.c:3647 #, c-format msgid "operator %s is not a valid ordering operator" msgstr "Operator %s ist kein gültiger Sortieroperator" -#: parser/parse_clause.c:3680 +#: parser/parse_clause.c:3649 #, c-format msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." msgstr "Sortieroperatoren müssen die Mitglieder »<« oder »>« einer »btree«-Operatorfamilie sein." -#: parser/parse_clause.c:3994 +#: parser/parse_clause.c:3963 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" msgstr "RANGE mit Offset PRECEDING/FOLLOWING wird für Spaltentyp %s nicht unterstützt" -#: parser/parse_clause.c:4000 +#: parser/parse_clause.c:3969 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" msgstr "RANGE mit Offset PRECEDING/FOLLOWING wird für Spaltentyp %s und Offset-Typ %s nicht unterstützt" -#: parser/parse_clause.c:4003 +#: parser/parse_clause.c:3972 #, c-format msgid "Cast the offset value to an appropriate type." msgstr "Wandeln Sie den Offset-Wert in einen passenden Typ um." -#: parser/parse_clause.c:4008 +#: parser/parse_clause.c:3977 #, c-format msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" msgstr "RANGE mit Offset PRECEDING/FOLLOWING hat mehrere Interpretationen für Spaltentyp %s und Offset-Typ %s" -#: parser/parse_clause.c:4011 +#: parser/parse_clause.c:3980 #, c-format msgid "Cast the offset value to the exact intended type." msgstr "Wandeln Sie den Offset-Wert in den genauen beabsichtigten Typ um." @@ -22668,7 +22393,7 @@ msgstr "Wandeln Sie den Offset-Wert in den genauen beabsichtigten Typ um." #: parser/parse_coerce.c:1048 parser/parse_coerce.c:1086 #: parser/parse_coerce.c:1104 parser/parse_coerce.c:1119 #: parser/parse_expr.c:2186 parser/parse_expr.c:2806 parser/parse_expr.c:3461 -#: parser/parse_expr.c:3690 parser/parse_expr.c:4211 parser/parse_target.c:1006 +#: parser/parse_expr.c:3690 parser/parse_expr.c:4214 parser/parse_target.c:1006 #, c-format msgid "cannot cast type %s to %s" msgstr "kann Typ %s nicht in Typ %s umwandeln" @@ -23049,10 +22774,8 @@ msgid "cannot use column reference in partition bound expression" msgstr "Spaltenverweise können nicht in Partitionsbegrenzungsausdrücken verwendet werden" #: parser/parse_expr.c:592 -#, fuzzy -#| msgid "cannot use column reference in DEFAULT expression" msgid "cannot use column reference in FOR PORTION OF expression" -msgstr "Spaltenverweise können nicht in DEFAULT-Ausdrücken verwendet werden" +msgstr "Spaltenverweise können nicht in FOR-PORTION-OF-Ausdrücken verwendet werden" #: parser/parse_expr.c:861 parser/parse_relation.c:876 #: parser/parse_relation.c:958 parser/parse_target.c:1246 @@ -23152,18 +22875,14 @@ msgid "cannot use subquery in column generation expression" msgstr "Unteranfragen können nicht in Spaltengenerierungsausdrücken verwendet werden" #: parser/parse_expr.c:1890 -#, fuzzy -#| msgid "cannot use subquery in partition key expression" msgid "cannot use subquery in property definition expression" -msgstr "Unteranfragen können nicht in Partitionierungsschlüsselausdrücken verwendet werden" +msgstr "Unteranfragen können nicht in Property-Definitionsausdrücken verwendet werden" #: parser/parse_expr.c:1893 -#, fuzzy -#| msgid "cannot use subquery in DEFAULT expression" msgid "cannot use subquery in FOR PORTION OF expression" -msgstr "Unteranfragen können nicht in DEFAULT-Ausdrücken verwendet werden" +msgstr "Unteranfragen können nicht in FOR-PORTION-OF-Ausdrücken verwendet werden" -#: parser/parse_expr.c:1946 parser/parse_expr.c:3850 +#: parser/parse_expr.c:1946 parser/parse_expr.c:3852 #, c-format msgid "subquery must return only one column" msgstr "Unteranfrage darf nur eine Spalte zurückgeben" @@ -23298,54 +23017,54 @@ msgstr "Rückgabe von SETOF-Typen wird in SQL/JSON-Funktionen nicht unterstützt msgid "returning pseudo-types is not supported in SQL/JSON functions" msgstr "Rückgabe von Pseudotypen wird in SQL/JSON-Funktionen nicht unterstützt" -#: parser/parse_expr.c:3990 parser/parse_func.c:887 +#: parser/parse_expr.c:3993 parser/parse_func.c:887 #, c-format msgid "aggregate ORDER BY is not implemented for window functions" msgstr "ORDER BY in Aggregatfunktion ist für Fensterfunktionen nicht implementiert" -#: parser/parse_expr.c:4223 +#: parser/parse_expr.c:4226 #, c-format msgid "cannot use JSON FORMAT ENCODING clause for non-bytea input types" msgstr "JSON-FORMAT-ENCODING-Klausel kann nur für Eingabetyp bytea verwendet werden" -#: parser/parse_expr.c:4243 +#: parser/parse_expr.c:4246 #, c-format msgid "cannot use type %s in IS JSON predicate" msgstr "Typ %s kann nicht im IS-JSON-Prädikat verwendet werden" -#: parser/parse_expr.c:4270 parser/parse_expr.c:4391 +#: parser/parse_expr.c:4273 parser/parse_expr.c:4394 #, c-format msgid "cannot use type %s in RETURNING clause of %s" msgstr "Typ %s kann nicht in der RETURNING-Klausel von %s verwendet werden" -#: parser/parse_expr.c:4272 +#: parser/parse_expr.c:4275 #, c-format msgid "Try returning json or jsonb." msgstr "Versuchen Sie json oder jsonb zurückzugeben." -#: parser/parse_expr.c:4320 +#: parser/parse_expr.c:4323 #, c-format msgid "cannot use non-string types with WITH UNIQUE KEYS clause" msgstr "Klausel WITH UNIQUE KEYS kann nicht mit Typen verwendet werden, die keine Zeichenketten sind" -#: parser/parse_expr.c:4394 +#: parser/parse_expr.c:4397 #, c-format msgid "Try returning a string type or bytea." msgstr "Versuchen Sie einen Zeichenkettentyp oder bytea zurückzugeben." -#: parser/parse_expr.c:4462 +#: parser/parse_expr.c:4465 #, c-format msgid "cannot specify FORMAT JSON in RETURNING clause of %s()" msgstr "FORMAT JSON kann nicht in der RETURNING-Klausel von %s() angegeben werden" -#: parser/parse_expr.c:4475 +#: parser/parse_expr.c:4478 #, c-format msgid "SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is used" msgstr "SQL/JSON-QUOTES-Verhalten darf nicht angegeben werden, wenn WITH WRAPPER verwendet wird" #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4489 parser/parse_expr.c:4518 parser/parse_expr.c:4549 -#: parser/parse_expr.c:4575 parser/parse_expr.c:4601 +#: parser/parse_expr.c:4492 parser/parse_expr.c:4521 parser/parse_expr.c:4552 +#: parser/parse_expr.c:4578 parser/parse_expr.c:4604 #: parser/parse_jsontable.c:92 #, c-format msgid "invalid %s behavior" @@ -23353,7 +23072,7 @@ msgstr "ungültiges »%s«-Verhalten" #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY), #. second %s is a SQL/JSON function name (e.g. JSON_QUERY) -#: parser/parse_expr.c:4492 parser/parse_expr.c:4521 +#: parser/parse_expr.c:4495 parser/parse_expr.c:4524 #, c-format msgid "Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for %s." msgstr "Nur ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT oder DEFAULT-Ausdruck sind erlaubt in %s für %s." @@ -23361,73 +23080,73 @@ msgstr "Nur ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT oder DEFAULT-Ausdruck sind er #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) #. translator: first %s is name a SQL/JSON clause (eg. ON EMPTY) #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4499 parser/parse_expr.c:4528 parser/parse_expr.c:4557 -#: parser/parse_expr.c:4585 parser/parse_expr.c:4611 +#: parser/parse_expr.c:4502 parser/parse_expr.c:4531 parser/parse_expr.c:4560 +#: parser/parse_expr.c:4588 parser/parse_expr.c:4614 #, c-format msgid "invalid %s behavior for column \"%s\"" msgstr "ungültiges »%s«-Verhalten für Spalte »%s«" #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4502 parser/parse_expr.c:4531 +#: parser/parse_expr.c:4505 parser/parse_expr.c:4534 #, c-format msgid "Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for formatted columns." msgstr "Nur ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT oder DEFAULT-Ausdruck sind erlaubt in %s für formatierte Spalten." -#: parser/parse_expr.c:4550 +#: parser/parse_expr.c:4553 #, c-format msgid "Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for %s." msgstr "Nur ERROR, TRUE, FALSE oder UNKNOWN sind erlaubt in %s für %s." #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4560 +#: parser/parse_expr.c:4563 #, c-format msgid "Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for EXISTS columns." msgstr "Nur ERROR, TRUE, FALSE oder UNKNOWN sind erlaubt in %s für EXISTS-Spalten." #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY), #. second %s is a SQL/JSON function name (e.g. JSON_QUERY) -#: parser/parse_expr.c:4578 parser/parse_expr.c:4604 +#: parser/parse_expr.c:4581 parser/parse_expr.c:4607 #, c-format msgid "Only ERROR, NULL, or DEFAULT expression is allowed in %s for %s." msgstr "Nur ERROR, NULL oder DEFAULT-Ausdruck sind erlaubt in %s für %s." #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4588 parser/parse_expr.c:4614 +#: parser/parse_expr.c:4591 parser/parse_expr.c:4617 #, c-format msgid "Only ERROR, NULL, or DEFAULT expression is allowed in %s for scalar columns." msgstr "Nur ERROR, NULL oder DEFAULT-Ausdruck sind erlaubt in %s für skalare Spalten." -#: parser/parse_expr.c:4648 +#: parser/parse_expr.c:4651 #, c-format msgid "JSON path expression must be of type %s, not of type %s" msgstr "JSON-Pfadausdruck muss Typ %s haben, nicht Typ %s" -#: parser/parse_expr.c:4888 +#: parser/parse_expr.c:4891 #, c-format msgid "can only specify a constant, non-aggregate function, or operator expression for DEFAULT" msgstr "für DEFAULT kann nur eine Konstante, Nicht-Aggregat-Funktion oder ein Operatorausdruck angegeben werden" -#: parser/parse_expr.c:4893 +#: parser/parse_expr.c:4896 #, c-format msgid "DEFAULT expression must not contain column references" msgstr "DEFAULT-Ausdruck darf keine Spaltenverweise enthalten" -#: parser/parse_expr.c:4898 +#: parser/parse_expr.c:4901 #, c-format msgid "DEFAULT expression must not return a set" msgstr "DEFAULT-Ausdruck darf keine Ergebnismenge zurückgeben" -#: parser/parse_expr.c:4913 +#: parser/parse_expr.c:4916 #, c-format msgid "collation of DEFAULT expression conflicts with RETURNING clause" msgstr "Sortierfolge des DEFAULT-Ausdrucks kollidiert mit der RETURNING-Klausel" -#: parser/parse_expr.c:5001 parser/parse_expr.c:5010 +#: parser/parse_expr.c:5004 parser/parse_expr.c:5013 #, c-format msgid "cannot cast behavior expression of type %s to %s" msgstr "kann Verhaltensausdruck nicht von Typ %s in %s umwandeln" -#: parser/parse_expr.c:5004 +#: parser/parse_expr.c:5007 #, c-format msgid "You will need to explicitly cast the expression to type %s." msgstr "Sie werden den Ausdruck ausdrücklich in Typ %s umwandeln müssen." @@ -23494,10 +23213,9 @@ msgstr "OVER angegeben, aber %s ist keine Fensterfunktion oder Aggregatfunktion" #. translator: first %s is a null treatment option, eg IGNORE NULLS #: parser/parse_func.c:358 -#, fuzzy, c-format -#| msgid "%s(*) specified, but %s is not an aggregate function" +#, c-format msgid "%s specified, but %s is not a window function" -msgstr "%s(*) angegeben, aber %s ist keine Aggregatfunktion" +msgstr "%s angegeben, aber %s ist keine Fensterfunktion" #: parser/parse_func.c:396 #, c-format @@ -23534,10 +23252,9 @@ msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" msgstr "%s ist keine Ordered-Set-Aggregatfunktion und kann deshalb kein WITHIN GROUP haben" #: parser/parse_func.c:534 -#, fuzzy, c-format -#| msgid "aggregate functions are not allowed in EXECUTE parameters" +#, c-format msgid "aggregate functions do not accept RESPECT/IGNORE NULLS" -msgstr "Aggregatfunktionen sind in EXECUTE-Parametern nicht erlaubt" +msgstr "Aggregatfunktionen akzeptieren kein RESPECT/IGNORE NULLS" #: parser/parse_func.c:545 #, c-format @@ -23555,17 +23272,15 @@ msgid "procedure %s is not unique" msgstr "Prozedur %s ist nicht eindeutig" #: parser/parse_func.c:584 -#, fuzzy, c-format -#| msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +#, c-format msgid "Could not choose a best candidate procedure." -msgstr "Konnte keine beste Kandidatprozedur auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." +msgstr "Konnte keine beste Kandidatprozedur auswählen." #: parser/parse_func.c:585 parser/parse_func.c:594 parser/parse_func.c:1024 #: parser/parse_oper.c:645 parser/parse_oper.c:694 -#, fuzzy, c-format -#| msgid "You might need to add an explicit cast." +#, c-format msgid "You might need to add explicit type casts." -msgstr "Sie müssen möglicherweise eine ausdrückliche Typumwandlung hinzufügen." +msgstr "Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." #: parser/parse_func.c:590 #, c-format @@ -23573,22 +23288,19 @@ msgid "function %s is not unique" msgstr "Funktion %s ist nicht eindeutig" #: parser/parse_func.c:593 -#, fuzzy, c-format -#| msgid "Could not choose a best candidate function. You might need to add explicit type casts." +#, c-format msgid "Could not choose a best candidate function." -msgstr "Konnte keine beste Kandidatfunktion auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." +msgstr "Konnte keine beste Kandidatfunktion auswählen." #: parser/parse_func.c:634 -#, fuzzy, c-format -#| msgid "No function matches the given name and argument types. You might need to add explicit type casts." +#, c-format msgid "No aggregate function matches the given name and argument types." -msgstr "Keine Funktion stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." +msgstr "Keine Aggregatfunktion stimmt mit dem angegebenen Namen und den Argumenttypen überein." #: parser/parse_func.c:635 -#, fuzzy, c-format -#| msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." +#, c-format msgid "Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." -msgstr "Keine Aggregatfunktion stimmt mit dem angegebenen Namen und den Argumenttypen überein. Mõglicherweise steht ORDER BY an der falschen Stelle; ORDER BY muss hinter allen normalen Argumenten der Aggregatfunktion stehen." +msgstr "Möglicherweise steht ORDER BY an der falschen Stelle; ORDER BY muss hinter allen normalen Argumenten der Aggregatfunktion stehen." #: parser/parse_func.c:642 parser/parse_func.c:2543 #, c-format @@ -23636,83 +23348,74 @@ msgid "window functions cannot return sets" msgstr "Fensterfunktionen können keine Ergebnismengen zurückgeben" #: parser/parse_func.c:956 -#, fuzzy, c-format -#| msgid "There is no previous error." +#, c-format msgid "There is no procedure of that name." -msgstr "Es gibt keinen vorangegangenen Fehler." +msgstr "Es gibt keine Prozedur mit diesem Namen." #: parser/parse_func.c:958 -#, fuzzy, c-format -#| msgid "there is no subtransaction to exit from" +#, c-format msgid "There is no function of that name." -msgstr "es gibt keine Subtransaktion zu beenden" +msgstr "Es gibt keine Funktion mit diesem Namen." #: parser/parse_func.c:963 #, c-format msgid "A procedure of that name exists, but it is not in the search_path." -msgstr "" +msgstr "Eine Prozedur mit diesem Namen existiert, aber sie ist nicht im search_path." #: parser/parse_func.c:965 #, c-format msgid "A function of that name exists, but it is not in the search_path." -msgstr "" +msgstr "Eine Funktion mit diesem Namen existiert, aber sie ist nicht im search_path." #: parser/parse_func.c:977 -#, fuzzy, c-format -#| msgid "procedures cannot accept set arguments" +#, c-format msgid "No procedure of that name accepts the given number of arguments." -msgstr "Prozeduren können keine SETOF-Argumente haben" +msgstr "Keine Prozedur mit diesem Namen akzeptiert die angegebene Anzahl Argumente." #: parser/parse_func.c:979 -#, fuzzy, c-format -#| msgid "cast function must take one to three arguments" +#, c-format msgid "No function of that name accepts the given number of arguments." -msgstr "Typumwandlungsfunktion muss ein bis drei Argumente haben" +msgstr "Keine Funktion mit diesem Namen akzeptiert die angegebene Anzahl Argumente." #: parser/parse_func.c:989 -#, fuzzy, c-format -#| msgid "procedures cannot accept set arguments" +#, c-format msgid "No procedure of that name accepts the given argument names." -msgstr "Prozeduren können keine SETOF-Argumente haben" +msgstr "Keine Prozedur mit diesem Namen akzeptiert die angegebenen Argumentnamen." #: parser/parse_func.c:991 -#, fuzzy, c-format -#| msgid "cast function must take one to three arguments" +#, c-format msgid "No function of that name accepts the given argument names." -msgstr "Typumwandlungsfunktion muss ein bis drei Argumente haben" +msgstr "Keine Funktion mit diesem Namen akzeptiert die angegebenen Argumentnamen." #: parser/parse_func.c:1004 #, c-format msgid "In the closest available match, an argument was specified both positionally and by name." -msgstr "" +msgstr "In der nächstgelegenen verfügbaren Übereinstimmung wurde ein Argument sowohl positionsbezogen als auch per Name angegeben." #: parser/parse_func.c:1008 #, c-format msgid "In the closest available match, not all required arguments were supplied." -msgstr "" +msgstr "In der nächstgelegenen verfügbaren Übereinstimmung wurden nicht alle benötigten Argumente angegeben." #: parser/parse_func.c:1012 #, c-format msgid "This call would be correct if the variadic array were labeled VARIADIC and placed last." -msgstr "" +msgstr "Dieser Aufruf wäre korrekt, wenn das variadische Array mit VARIADIC markiert und als letztes platziert wäre." #: parser/parse_func.c:1015 -#, fuzzy, c-format -#| msgid "VARIADIC parameter must be the last input parameter" +#, c-format msgid "The VARIADIC parameter must be placed last, even when using argument names." -msgstr "VARIADIC-Parameter muss der letzte Eingabeparameter sein" +msgstr "Der VARIADIC-Parameter muss zuletzt stehen, auch wenn Argumentnamen verwendet werden." #: parser/parse_func.c:1021 -#, fuzzy, c-format -#| msgid "procedures cannot accept set arguments" +#, c-format msgid "No procedure of that name accepts the given argument types." -msgstr "Prozeduren können keine SETOF-Argumente haben" +msgstr "Keine Prozedur mit diesem Namen akzeptiert die angegebenen Argumenttypen." #: parser/parse_func.c:1023 -#, fuzzy, c-format -#| msgid "function \"%s\" already exists with same argument types" +#, c-format msgid "No function of that name accepts the given argument types." -msgstr "Funktion »%s« existiert bereits mit den selben Argumenttypen" +msgstr "Keine Funktion mit diesem Namen akzeptiert die angegebenen Argumenttypen." #: parser/parse_func.c:2299 parser/parse_func.c:2572 #, c-format @@ -23865,40 +23568,32 @@ msgid "set-returning functions are not allowed in column generation expressions" msgstr "Funktionen mit Ergebnismenge sind in Spaltengenerierungsausdrücken nicht erlaubt" #: parser/parse_func.c:2791 -#, fuzzy -#| msgid "set-returning functions are not allowed in partition key expressions" msgid "set-returning functions are not allowed in property definition expressions" -msgstr "Funktionen mit Ergebnismenge sind in Partitionierungsschlüsselausdrücken nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in Property-Definitionsausdrücken nicht erlaubt" #: parser/parse_func.c:2794 -#, fuzzy -#| msgid "set-returning functions are not allowed in DEFAULT expressions" msgid "set-returning functions are not allowed in FOR PORTION OF expressions" -msgstr "Funktionen mit Ergebnismenge sind in DEFAULT-Ausdrücken nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in FOR-PORTION-OF-Ausdrücken nicht erlaubt" #: parser/parse_graphtable.c:98 -#, fuzzy, c-format -#| msgid "row expansion via \"*\" is not supported here" +#, c-format msgid "\"*\" is not supported here" -msgstr "Zeilenexpansion mit »*« wird hier nicht unterstützt" +msgstr "»*« wird hier nicht unterstützt" #: parser/parse_graphtable.c:103 -#, fuzzy, c-format -#| msgid "SELECT ... INTO is not allowed here" +#, c-format msgid "\"*\" not allowed here" -msgstr "SELECT ... INTO ist hier nicht erlaubt" +msgstr "»*« ist hier nicht erlaubt" #: parser/parse_graphtable.c:126 -#, fuzzy, c-format -#| msgid "removing elements from multidimensional arrays is not supported" +#, c-format msgid "non-local element variable reference is not supported" -msgstr "Entfernen von Elementen aus mehrdimensionalen Arrays wird nicht unterstützt" +msgstr "nicht-lokaler Verweis auf Elementvariable wird nicht unterstützt" #: parser/parse_graphtable.c:135 -#, fuzzy, c-format -#| msgid "portal \"%s\" does not exist" +#, c-format msgid "property \"%s\" does not exist" -msgstr "Portal »%s« existiert nicht" +msgstr "Property »%s« existiert nicht" #: parser/parse_graphtable.c:191 #, c-format @@ -23906,43 +23601,39 @@ msgid "label \"%s\" does not exist in property graph \"%s\"" msgstr "Label »%s« existiert nicht in Property-Graph »%s«" #: parser/parse_graphtable.c:246 -#, fuzzy, c-format -#| msgid "rules on materialized views are not supported" +#, c-format msgid "element pattern quantifier is not supported" -msgstr "Regeln für materialisierte Sichten werden nicht unterstützt" +msgstr "Elementmuster-Quantor wird nicht unterstützt" #: parser/parse_graphtable.c:281 -#, fuzzy, c-format -#| msgid "unsupported object type \"%s\"" +#, c-format msgid "unsupported element pattern kind: \"%s\"" -msgstr "nicht unterstützter Objekttyp »%s«" +msgstr "nicht unterstützte Elementmusterart: »%s«" #: parser/parse_graphtable.c:289 #, c-format msgid "path pattern cannot start with an edge pattern" -msgstr "" +msgstr "Pfadmuster kann nicht mit einem Kantenmuster beginnen" #: parser/parse_graphtable.c:294 #, c-format msgid "edge pattern must be preceded by a vertex pattern" -msgstr "" +msgstr "einem Kantenmuster muss ein Knotenmuster vorangehen" #: parser/parse_graphtable.c:302 -#, fuzzy, c-format -#| msgid "postfix operators are not supported" +#, c-format msgid "adjacent vertex patterns are not supported" -msgstr "Postfix-Operatoren werden nicht unterstützt" +msgstr "benachbarte Knotenmuster werden nicht unterstützt" #: parser/parse_graphtable.c:318 -#, fuzzy, c-format -#| msgid "LIKE pattern must not end with escape character" +#, c-format msgid "path pattern cannot end with an edge pattern" -msgstr "LIKE-Muster darf nicht mit Escape-Zeichen enden" +msgstr "Pfadmuster darf nicht mit einem Kantenmuster enden" #: parser/parse_graphtable.c:346 #, c-format msgid "multiple path patterns in one GRAPH_TABLE clause not supported" -msgstr "" +msgstr "mehrere Pfadmuster in einer GRAPH_TABLE-Klausel werden nicht unterstützt" #: parser/parse_jsontable.c:93 #, c-format @@ -24000,37 +23691,34 @@ msgid "operator is not unique: %s" msgstr "Operator ist nicht eindeutig: %s" #: parser/parse_oper.c:644 -#, fuzzy, c-format -#| msgid "Could not choose a best candidate operator. You might need to add explicit type casts." +#, c-format msgid "Could not choose a best candidate operator." -msgstr "Konnte keinen besten Kandidatoperator auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." +msgstr "Konnte keinen besten Kandidatoperator auswählen." #: parser/parse_oper.c:678 -#, fuzzy, c-format -#| msgid "List of operators of operator families" +#, c-format msgid "There is no operator of that name." -msgstr "Liste der Operatoren in Operatorfamilien" +msgstr "Es gibt keinen Operator mit diesem Namen." #: parser/parse_oper.c:680 #, c-format msgid "An operator of that name exists, but it is not in the search_path." -msgstr "" +msgstr "Ein Operator mit diesem Namen existiert, aber er ist nicht im search_path." #: parser/parse_oper.c:688 #, c-format msgid "No operator of that name accepts the given argument type." -msgstr "" +msgstr "Kein Operator mit diesem Namen akzeptiert den angegebenen Argumenttyp." #: parser/parse_oper.c:689 -#, fuzzy, c-format -#| msgid "You might need to add an explicit cast." +#, c-format msgid "You might need to add an explicit type cast." msgstr "Sie müssen möglicherweise eine ausdrückliche Typumwandlung hinzufügen." #: parser/parse_oper.c:693 #, c-format msgid "No operator of that name accepts the given argument types." -msgstr "" +msgstr "Kein Operator mit diesem Namen akzeptiert die angegebenen Argumenttypen." #: parser/parse_oper.c:854 #, c-format @@ -24155,10 +23843,9 @@ msgid "%s function has %d columns available but %d columns specified" msgstr "Funktion %s hat %d Spalten verfügbar, aber %d Spalten wurden angegeben" #: parser/parse_relation.c:2216 -#, fuzzy, c-format -#| msgid "table \"%s\" has %d columns available but %d columns specified" +#, c-format msgid "GRAPH_TABLE \"%s\" has %d columns available but %d columns specified" -msgstr "Tabelle »%s« hat %d Spalten, aber %d Spalten wurden angegeben" +msgstr "GRAPH_TABLE »%s« hat %d Spalten, aber %d Spalten wurden angegeben" #: parser/parse_relation.c:2309 #, c-format @@ -24543,78 +24230,69 @@ msgstr "in WITH-Anfrage kann nicht auf NEW verwiesen werden" #: parser/parse_utilcmd.c:3561 #, c-format msgid "ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions." -msgstr "" +msgstr "ALTER TABLE ... MERGE PARTITIONS kann nur Partitionen zusammenführen, die keine Sub-Partitionen haben." #: parser/parse_utilcmd.c:3544 parser/parse_utilcmd.c:3553 #: parser/parse_utilcmd.c:3562 #, c-format msgid "ALTER TABLE ... SPLIT PARTITION can only split partitions that don't have sub-partitions." -msgstr "" +msgstr "ALTER TABLE ... SPLIT PARTITION kann nur Partitionen aufteilen, die keine Sub-Partitionen haben." #: parser/parse_utilcmd.c:3549 -#, fuzzy, c-format -#| msgid "\"%s\" is not a hash partitioned table" +#, c-format msgid "\"%s\" is not a partition of partitioned table \"%s\"" -msgstr "»%s« ist keine Hash-partitionierte Tabelle" +msgstr "»%s« ist keine Partition der partitionierten Tabelle »%s«" #: parser/parse_utilcmd.c:3625 -#, fuzzy, c-format -#| msgid "cannot insert a non-DEFAULT value into column \"%s\"" +#, c-format msgid "cannot specify more than one DEFAULT partition" -msgstr "kann keinen Wert außer DEFAULT in Spalte »%s« einfügen" +msgstr "es kann nicht mehr als eine DEFAULT-Partition angegeben werden" #: parser/parse_utilcmd.c:3637 -#, fuzzy, c-format -#| msgid "partitioned tables cannot be unlogged" +#, c-format msgid "partition of hash-partitioned table cannot be split" -msgstr "partitionierte Tabellen können nicht ungeloggt sein" +msgstr "Partition einer Hash-partitionierten Tabelle kann nicht aufgeteilt werden" #: parser/parse_utilcmd.c:3652 -#, fuzzy, c-format -#| msgid "cannot detach partition \"%s\"" +#, c-format msgid "cannot split DEFAULT partition \"%s\"" -msgstr "Partition »%s« kann nicht abgetrennt werden" +msgstr "DEFAULT-Partition »%s« kann nicht aufgeteilt werden" #: parser/parse_utilcmd.c:3654 #, c-format msgid "To split a DEFAULT partition, one of the new partitions must be DEFAULT." -msgstr "" +msgstr "Um eine DEFAULT-Partition aufzuteilen, muss eine der neuen Partitionen DEFAULT sein." #: parser/parse_utilcmd.c:3668 -#, fuzzy, c-format -#| msgid "cannot insert a non-DEFAULT value into column \"%s\"" +#, c-format msgid "cannot split non-DEFAULT partition \"%s\"" -msgstr "kann keinen Wert außer DEFAULT in Spalte »%s« einfügen" +msgstr "Nicht-DEFAULT-Partition »%s« kann nicht aufgeteilt werden" #: parser/parse_utilcmd.c:3670 -#, fuzzy, c-format -#| msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +#, c-format msgid "New partition cannot be DEFAULT because DEFAULT partition \"%s\" already exists." -msgstr "Partition »%s« kollidiert mit bestehender Standardpartition »%s«" +msgstr "Neue Partition kann nicht DEFAULT sein, weil DEFAULT-Partition »%s« bereits existiert." #: parser/parse_utilcmd.c:3693 parser/parse_utilcmd.c:3701 #: parser/parse_utilcmd.c:3754 parser/parse_utilcmd.c:3783 -#, fuzzy, c-format -#| msgid "transaction identifier \"%s\" is already in use" +#, c-format msgid "partition with name \"%s\" is already used" -msgstr "Transaktionsbezeichner »%s« wird bereits verwendet" +msgstr "Partition mit Namen »%s« wird bereits verwendet" #: parser/parse_utilcmd.c:3737 -#, fuzzy, c-format -#| msgid "partitioned tables cannot be unlogged" +#, c-format msgid "partition of hash-partitioned table cannot be merged" -msgstr "partitionierte Tabellen können nicht ungeloggt sein" +msgstr "Partition einer Hash-partitionierten Tabelle kann nicht zusammengeführt werden" #: parser/parse_utilcmd.c:4090 -#, fuzzy, c-format -#| msgid "unique constraint on partitioned table must include all partitioning columns" +#, c-format msgid "list of partitions to be merged should include at least two partitions" -msgstr "Unique-Constraint für partitionierte Tabelle muss alle Partitionierungsspalten enthalten" +msgstr "Liste der zusammenzuführenden Partitionen muss mindestens zwei Partitionen enthalten" #: parser/parse_utilcmd.c:4104 #, c-format msgid "list of new partitions should contain at least two partitions" -msgstr "" +msgstr "die Liste der neuen Partitionen sollte mindestens zwei Partitionen enthalten" #: parser/parse_utilcmd.c:4243 #, c-format @@ -24842,114 +24520,100 @@ msgid "column %d of the partition key has type \"%s\", but supplied value is of msgstr "Spalte %d des Partitionierungsschlüssels hat Typ »%s«, aber der angegebene Wert hat Typ »%s«" #: partitioning/partbounds.c:5045 -#, fuzzy, c-format -#| msgid "partition \"%s\" would overlap partition \"%s\"" +#, c-format msgid "cannot merge partition \"%s\" together with partition \"%s\"" -msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" +msgstr "kann Partition »%s« nicht mit Partition »%s« zusammenführen" #: partitioning/partbounds.c:5047 partitioning/partbounds.c:5056 -#, fuzzy, c-format -#| msgid "relation \"%s\" is not a partition of relation \"%s\"" +#, c-format msgid "The lower bound of partition \"%s\" is not equal to the upper bound of partition \"%s\"." -msgstr "Relation »%s« ist keine Partition von Relation »%s«" +msgstr "Die Untergrenze von Partition »%s« ist nicht gleich der Obergrenze von Partition »%s«." #: partitioning/partbounds.c:5049 #, c-format msgid "ALTER TABLE ... MERGE PARTITIONS requires the partition bounds to be adjacent." -msgstr "" +msgstr "ALTER TABLE ... MERGE PARTITIONS erfordert, dass die Partitionsbegrenzungen benachbart sind." #: partitioning/partbounds.c:5054 -#, fuzzy, c-format -#| msgid "cannot set options for relation \"%s\"" +#, c-format msgid "cannot split to partition \"%s\" together with partition \"%s\"" -msgstr "für Relation »%s« können keine Optionen gesetzt werden" +msgstr "kann nicht zu Partition »%s« zusammen mit Partition »%s« aufteilen" #: partitioning/partbounds.c:5058 #, c-format msgid "ALTER TABLE ... SPLIT PARTITION requires the partition bounds to be adjacent." -msgstr "" +msgstr "ALTER TABLE ... SPLIT PARTITION erfordert, dass die Partitionsbegrenzungen benachbart sind." #: partitioning/partbounds.c:5303 -#, fuzzy, c-format -#| msgid "partition \"%s\" would overlap partition \"%s\"" +#, c-format msgid "new partition \"%s\" would overlap with another new partition \"%s\"" -msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" +msgstr "neue Partition »%s« würde sich mit anderer neuer Partition »%s« überlappen" #: partitioning/partbounds.c:5417 -#, fuzzy, c-format -#| msgid "partition \"%s\" would overlap partition \"%s\"" +#, c-format msgid "lower bound of partition \"%s\" is not equal to lower bound of split partition \"%s\"" -msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" +msgstr "Untergrenze von Partition »%s« ist nicht gleich der Untergrenze der aufzuteilenden Partition »%s«" #: partitioning/partbounds.c:5420 partitioning/partbounds.c:5462 #: partitioning/partbounds.c:5667 partitioning/partbounds.c:5710 -#, fuzzy, c-format -#| msgid "partition \"%s\" would overlap partition \"%s\"" +#, c-format msgid "%s requires the combined bounds of the new partitions to exactly match the bound of the split partition." -msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" +msgstr "%s erfordert, dass die kombinierten Begrenzungen der neuen Partitionen genau mit der Begrenzung der aufzuteilenden Partition übereinstimmen." #: partitioning/partbounds.c:5427 -#, fuzzy, c-format -#| msgid "partition \"%s\" would overlap partition \"%s\"" +#, c-format msgid "lower bound of partition \"%s\" is less than lower bound of split partition \"%s\"" -msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" +msgstr "Untergrenze von Partition »%s« ist kleiner als die Untergrenze der aufzuteilenden Partition »%s«" #: partitioning/partbounds.c:5430 partitioning/partbounds.c:5472 #, c-format msgid "Explicit partition bounds must be contained within the bounds of the split partition when a DEFAULT partition is specified." -msgstr "" +msgstr "Explizite Partitionsbegrenzungen müssen innerhalb der Begrenzungen der aufzuteilenden Partition liegen, wenn eine DEFAULT-Partition angegeben ist." #: partitioning/partbounds.c:5459 -#, fuzzy, c-format -#| msgid "relation \"%s\" is not a partition of relation \"%s\"" +#, c-format msgid "upper bound of partition \"%s\" is not equal to upper bound of split partition \"%s\"" -msgstr "Relation »%s« ist keine Partition von Relation »%s«" +msgstr "Obergrenze von Partition »%s« ist nicht gleich der Obergrenze der aufzuteilenden Partition »%s«" #: partitioning/partbounds.c:5469 #, c-format msgid "upper bound of partition \"%s\" is greater than upper bound of split partition \"%s\"" -msgstr "" +msgstr "obere Begrenzung von Partition »%s« ist größer als obere Begrenzung der aufzuteilenden Partition »%s«" #: partitioning/partbounds.c:5539 -#, fuzzy, c-format -#| msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +#, c-format msgid "new partition \"%s\" cannot have this value because split partition \"%s\" does not have it" -msgstr "Partition »%s« kollidiert mit bestehender Standardpartition »%s«" +msgstr "neue Partition »%s« kann diesen Wert nicht haben, weil die aufzuteilende Partition »%s« ihn nicht hat" #: partitioning/partbounds.c:5556 -#, fuzzy, c-format -#| msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +#, c-format msgid "new partition \"%s\" cannot have NULL value because split partition \"%s\" does not have it" -msgstr "Partition »%s« kollidiert mit bestehender Standardpartition »%s«" +msgstr "neue Partition »%s« kann keinen NULL-Wert haben, weil die aufzuteilende Partition »%s« ihn nicht hat" #: partitioning/partbounds.c:5567 -#, fuzzy, c-format -#| msgid "partition \"%s\" would overlap partition \"%s\"" +#, c-format msgid "new partition \"%s\" would overlap with another (not split) partition \"%s\"" -msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" +msgstr "neue Partition »%s« würde sich mit einer anderen (nicht aufzuteilenden) Partition »%s« überlappen" #: partitioning/partbounds.c:5664 partitioning/partbounds.c:5707 -#, fuzzy, c-format -#| msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +#, c-format msgid "new partitions' combined partition bounds do not contain value (%s) but split partition \"%s\" does" -msgstr "Partition »%s« kollidiert mit bestehender Standardpartition »%s«" +msgstr "die kombinierten Partitionsbegrenzungen der neuen Partitionen enthalten den Wert (%s) nicht, aber die aufzuteilende Partition »%s« schon" #: partitioning/partbounds.c:5848 -#, fuzzy, c-format -#| msgid "cannot set options for relation \"%s\"" +#, c-format msgid "cannot split partition \"%s\" only to add a DEFAULT partition" -msgstr "für Relation »%s« können keine Optionen gesetzt werden" +msgstr "kann Partition »%s« nicht aufteilen, nur um eine DEFAULT-Partition hinzuzufügen" #: partitioning/partbounds.c:5850 #, c-format msgid "The non-DEFAULT partition would keep the same partition bound." -msgstr "" +msgstr "Die Nicht-DEFAULT-Partition würde die gleiche Partitionsbegrenzung behalten." #: partitioning/partbounds.c:5851 -#, fuzzy, c-format -#| msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation." +#, c-format msgid "Use CREATE TABLE ... PARTITION OF ... DEFAULT to add a DEFAULT partition." -msgstr "Verwendet Sie ALTER TABLE ... DETACH PARTITION ... FINALIZE, um die unerledigte Abtrennoperation abzuschließen." +msgstr "Verwenden Sie CREATE TABLE ... PARTITION OF ... DEFAULT, um eine DEFAULT-Partition hinzuzufügen." #: port/pg_sema.c:211 port/pg_shmem.c:719 port/posix_sema.c:211 #: port/sysv_sema.c:347 port/sysv_shmem.c:719 @@ -25234,10 +24898,9 @@ msgid "background worker \"%s\": cannot request database access if starting at p msgstr "Background-Worker »%s«: kann kein Datenbankzugriff anfordern, wenn er nach Postmaster-Start gestartet hat" #: postmaster/bgworker.c:697 -#, fuzzy, c-format -#| msgid "background worker \"%s\": background workers without shared memory access are not supported" +#, c-format msgid "background worker \"%s\": cannot make background workers interruptible without database access" -msgstr "Background-Worker »%s«: Background-Worker ohne Shared-Memory-Zugriff werden nicht unterstützt" +msgstr "Background-Worker »%s«: Background-Worker können ohne Datenbankzugriff nicht unterbrechbar gemacht werden" #: postmaster/bgworker.c:708 #, c-format @@ -25314,163 +24977,150 @@ msgstr "Checkpoint-Anforderung fehlgeschlagen" msgid "Consult recent messages in the server log for details." msgstr "Einzelheiten finden Sie in den letzten Meldungen im Serverlog." -#: postmaster/datachecksum_state.c:531 -#, fuzzy, c-format -#| msgid "incorrect checksum in control file" +#: postmaster/datachecksum_state.c:533 +#, c-format msgid "incorrect data checksum state %i for target state %i" -msgstr "falsche Prüfsumme in Kontrolldatei" +msgstr "falscher Datenprüfsummen-Zustand %i für Zielzustand %i" -#: postmaster/datachecksum_state.c:551 postmaster/datachecksum_state.c:573 -#, fuzzy, c-format -#| msgid "must be superuser to create a base type" +#: postmaster/datachecksum_state.c:553 postmaster/datachecksum_state.c:575 +#, c-format msgid "must be superuser to change data checksum state" -msgstr "nur Superuser können Basistypen anlegen" +msgstr "nur Superuser können den Datenprüfsummen-Zustand ändern" -#: postmaster/datachecksum_state.c:578 -#, fuzzy, c-format -#| msgid "requested length cannot be negative" +#: postmaster/datachecksum_state.c:580 +#, c-format msgid "cost delay cannot be a negative value" -msgstr "verlangte Länge darf nicht negativ sein" +msgstr "Cost-Delay darf kein negativer Wert sein" -#: postmaster/datachecksum_state.c:583 -#, fuzzy, c-format -#| msgid "count must be greater than zero" +#: postmaster/datachecksum_state.c:585 +#, c-format msgid "cost limit must be greater than zero" -msgstr "Anzahl muss größer als null sein" +msgstr "Cost-Limit muss größer als null sein" -#: postmaster/datachecksum_state.c:651 -#, fuzzy, c-format -#| msgid "data checksums are already disabled in cluster" +#: postmaster/datachecksum_state.c:664 +#, c-format msgid "data checksums already in desired state, exiting" -msgstr "Datenprüfsummen sind im Cluster bereits ausgeschaltet" +msgstr "Datenprüfsummen sind bereits im gewünschten Zustand, beende" -#: postmaster/datachecksum_state.c:672 -#, fuzzy, c-format -#| msgid "could not fork background worker process: %m" +#: postmaster/datachecksum_state.c:685 +#, c-format msgid "failed to start background worker to process data checksums" -msgstr "konnte Background-Worker-Prozess nicht starten (fork-Fehler): %m" +msgstr "konnte Background-Worker zur Verarbeitung von Datenprüfsummen nicht starten" -#: postmaster/datachecksum_state.c:677 -#, fuzzy, c-format -#| msgid "data checksums are already enabled in cluster" +#: postmaster/datachecksum_state.c:690 +#, c-format msgid "data checksum processing already running" -msgstr "Datenprüfsummen sind im Cluster bereits eingeschaltet" +msgstr "Datenprüfsummen-Verarbeitung läuft bereits" -#: postmaster/datachecksum_state.c:871 postmaster/datachecksum_state.c:895 -#, fuzzy, c-format -#| msgid "could not fork background worker process: %m" +#: postmaster/datachecksum_state.c:918 postmaster/datachecksum_state.c:942 +#, c-format msgid "could not start background worker for enabling data checksums in database \"%s\"" -msgstr "konnte Background-Worker-Prozess nicht starten (fork-Fehler): %m" +msgstr "konnte Background-Worker zum Einschalten von Datenprüfsummen in Datenbank »%s« nicht starten" -#: postmaster/datachecksum_state.c:873 +#: postmaster/datachecksum_state.c:920 #, c-format msgid "The \"%s\" setting might be too low." -msgstr "" +msgstr "Die Einstellung »%s« ist möglicherweise zu niedrig." -#: postmaster/datachecksum_state.c:897 -#, fuzzy, c-format -#| msgid "More details may be available in the server log." +#: postmaster/datachecksum_state.c:944 +#, c-format msgid "More details on the error might be found in the server log." -msgstr "Weitere Einzelheiten sind möglicherweise im Serverlog zu finden." +msgstr "Weitere Einzelheiten zum Fehler sind möglicherweise im Serverlog zu finden." -#: postmaster/datachecksum_state.c:919 +#: postmaster/datachecksum_state.c:966 #, c-format msgid "cannot enable data checksums without the postmaster process" -msgstr "" +msgstr "Datenprüfsummen können nicht ohne den Postmaster-Prozess eingeschaltet werden" -#: postmaster/datachecksum_state.c:920 postmaster/datachecksum_state.c:943 +#: postmaster/datachecksum_state.c:967 postmaster/datachecksum_state.c:990 #, c-format msgid "Restart the database and restart data checksum processing by calling pg_enable_data_checksums()." -msgstr "" +msgstr "Starten Sie die Datenbank neu und starten Sie die Datenprüfsummen-Verarbeitung durch Aufruf von pg_enable_data_checksums() neu." -#: postmaster/datachecksum_state.c:924 -#, fuzzy, c-format -#| msgid "%s: processing database \"%s\": %s\n" +#: postmaster/datachecksum_state.c:971 +#, c-format msgid "initiating data checksum processing in database \"%s\"" -msgstr "%s: bearbeite Datenbank »%s«: %s\n" +msgstr "beginne Datenprüfsummen-Verarbeitung in Datenbank »%s«" -#: postmaster/datachecksum_state.c:941 -#, fuzzy, c-format -#| msgid "postmaster exited during a parallel transaction" +#: postmaster/datachecksum_state.c:988 +#, c-format msgid "postmaster exited during data checksum processing in \"%s\"" -msgstr "Postmaster beendete während einer parallelen Transaktion" +msgstr "Postmaster beendete während der Datenprüfsummen-Verarbeitung in »%s«" -#: postmaster/datachecksum_state.c:953 -#, fuzzy, c-format -#| msgid "checksums enabled in file \"%s\"" +#: postmaster/datachecksum_state.c:1009 +#, c-format msgid "data checksums processing was aborted in database \"%s\"" -msgstr "Prüfsummen wurden eingeschaltet in Datei »%s«" +msgstr "Datenprüfsummen-Verarbeitung wurde in Datenbank »%s« abgebrochen" -#: postmaster/datachecksum_state.c:980 +#: postmaster/datachecksum_state.c:1036 #, c-format msgid "data checksums launcher exiting while worker is still running, signalling worker" -msgstr "" +msgstr "Datenprüfsummen-Launcher beendet sich, während der Worker noch läuft, sende Signal an Worker" -#: postmaster/datachecksum_state.c:1070 -#, fuzzy, c-format -#| msgid "postmaster exited during a parallel transaction" +#: postmaster/datachecksum_state.c:1126 +#, c-format msgid "postmaster exited during data checksums processing" -msgstr "Postmaster beendete während einer parallelen Transaktion" +msgstr "Postmaster beendete während der Datenprüfsummen-Verarbeitung" -#: postmaster/datachecksum_state.c:1071 +#: postmaster/datachecksum_state.c:1127 #, c-format msgid "Data checksums processing must be restarted manually after cluster restart." -msgstr "" +msgstr "Die Datenprüfsummen-Verarbeitung muss nach einem Cluster-Neustart manuell neu gestartet werden." -#: postmaster/datachecksum_state.c:1097 +#: postmaster/datachecksum_state.c:1153 #, c-format msgid "background worker \"datachecksums launcher\" started" -msgstr "" +msgstr "Background-Worker »datachecksums launcher« gestartet" -#: postmaster/datachecksum_state.c:1116 +#: postmaster/datachecksum_state.c:1172 #, c-format msgid "background worker \"datachecksums launcher\" already running, exiting" -msgstr "" +msgstr "Background-Worker »datachecksums launcher« läuft bereits, wird beendet" -#: postmaster/datachecksum_state.c:1156 +#: postmaster/datachecksum_state.c:1213 #, c-format msgid "enabling data checksums requested, starting data checksum calculation" -msgstr "" +msgstr "Einschalten der Datenprüfsummen angefordert, Datenprüfsummen-Berechnung wird gestartet" -#: postmaster/datachecksum_state.c:1180 -#, fuzzy, c-format -#| msgid " -e, --enable enable data checksums\n" +#: postmaster/datachecksum_state.c:1237 +#, c-format msgid "unable to enable data checksums in cluster" -msgstr " -e, --enable Datenprüfsummen einschalten\n" +msgstr "konnte Datenprüfsummen im Cluster nicht einschalten" -#: postmaster/datachecksum_state.c:1190 -#, fuzzy, c-format -#| msgid "data checksums are not enabled in cluster" +#: postmaster/datachecksum_state.c:1247 +#, c-format msgid "data checksums are now enabled" -msgstr "Datenprüfsummen sind im Cluster nicht eingeschaltet" +msgstr "Datenprüfsummen sind jetzt eingeschaltet" -#: postmaster/datachecksum_state.c:1195 +#: postmaster/datachecksum_state.c:1252 #, c-format msgid "disabling data checksums requested" -msgstr "" +msgstr "Ausschalten der Datenprüfsummen angefordert" -#: postmaster/datachecksum_state.c:1201 -#, fuzzy, c-format -#| msgid "Data page checksums are disabled.\n" +#: postmaster/datachecksum_state.c:1258 +#, c-format msgid "data checksums are now disabled" -msgstr "Datenseitenprüfsummen sind ausgeschaltet.\n" +msgstr "Datenprüfsummen sind jetzt ausgeschaltet" -#: postmaster/datachecksum_state.c:1319 -#, fuzzy, c-format -#| msgid "data checksums are not enabled in cluster" +#: postmaster/datachecksum_state.c:1367 +#, c-format msgid "data checksums failed to get enabled in all databases, aborting" -msgstr "Datenprüfsummen sind im Cluster nicht eingeschaltet" +msgstr "Datenprüfsummen konnten nicht in allen Datenbanken eingeschaltet werden, breche ab" -#: postmaster/datachecksum_state.c:1320 +#: postmaster/datachecksum_state.c:1368 #, c-format msgid "The server log might have more information on the cause of the error." -msgstr "" +msgstr "Das Server-Log enthält möglicherweise mehr Informationen über die Ursache des Fehlers." -#: postmaster/datachecksum_state.c:1701 postmaster/datachecksum_state.c:1774 -#, fuzzy, c-format -#| msgid "data checksums are not enabled in cluster" +#: postmaster/datachecksum_state.c:1491 +#, c-format +msgid "cannot enable data checksums in a cluster with invalid database \"%s\"" +msgstr "kann Datenprüfsummen nicht in einem Cluster mit ungültiger Datenbank »%s« einschalten" + +#: postmaster/datachecksum_state.c:1799 postmaster/datachecksum_state.c:1872 +#, c-format msgid "data checksum processing aborted in database OID %u" -msgstr "Datenprüfsummen sind im Cluster nicht eingeschaltet" +msgstr "Datenprüfsummen-Verarbeitung in Datenbank OID %u abgebrochen" #: postmaster/launch_backend.c:373 #, c-format @@ -25643,10 +25293,9 @@ msgid "WAL cannot be summarized when \"wal_level\" is \"minimal\"" msgstr "WAL kann nicht zusammengefasst werden, wenn »wal_level« »minimal« ist" #: postmaster/postmaster.c:864 -#, fuzzy, c-format -#| msgid "replication slot synchronization requires \"wal_level\" >= \"logical\"" +#, c-format msgid "replication slot synchronization (\"sync_replication_slots\" = on) requires \"wal_level\" to be \"replica\" or \"logical\"" -msgstr "Replikations-Slot-Synchronisierung erfordert »wal_level« >= »logical«" +msgstr "Replikations-Slot-Synchronisierung (»sync_replication_slots« = on) erfordert, dass »wal_level« »replica« oder »logical« ist" #: postmaster/postmaster.c:872 #, c-format @@ -26024,47 +25673,42 @@ msgstr "konnte Logdatei »%s« nicht öffnen: %m" msgid "disabling automatic rotation (use SIGHUP to re-enable)" msgstr "automatische Rotation abgeschaltet (SIGHUP zum Wiederanschalten verwenden)" -#: postmaster/walsummarizer.c:740 +#: postmaster/walsummarizer.c:780 #, c-format msgid "WAL summarization is not progressing" msgstr "WAL-Zusammenfassung kommt nicht voran" -#: postmaster/walsummarizer.c:741 -#, fuzzy, c-format -#| msgid "Summarization is needed through %X/%X, but is stuck at %X/%X on disk and %X/%X in memory." +#: postmaster/walsummarizer.c:781 +#, c-format msgid "Summarization is needed through %X/%08X, but is stuck at %X/%08X on disk and %X/%08X in memory." -msgstr "Zusammenfassung bis %X/%X wird benötigt, aber sie hängt fest bei %X/%X auf Festplatte und %X/%X im Speicher." +msgstr "Zusammenfassung bis %X/%08X wird benötigt, aber sie hängt fest bei %X/%08X auf Festplatte und %X/%08X im Speicher." -#: postmaster/walsummarizer.c:755 -#, fuzzy, c-format -#| msgid "still waiting for WAL summarization through %X/%X after %ld second" -#| msgid_plural "still waiting for WAL summarization through %X/%X after %ld seconds" +#: postmaster/walsummarizer.c:795 +#, c-format msgid "still waiting for WAL summarization through %X/%08X after %ld second" msgid_plural "still waiting for WAL summarization through %X/%08X after %ld seconds" -msgstr[0] "warte immer noch auf WAL-Zusammenfassung bis %X/%X nach %ld Sekunde" -msgstr[1] "warte immer noch auf WAL-Zusammenfassung bis %X/%X nach %ld Sekunden" +msgstr[0] "warte immer noch auf WAL-Zusammenfassung bis %X/%08X nach %ld Sekunde" +msgstr[1] "warte immer noch auf WAL-Zusammenfassung bis %X/%08X nach %ld Sekunden" -#: postmaster/walsummarizer.c:760 -#, fuzzy, c-format -#| msgid "Summarization has reached %X/%X on disk and %X/%X in memory." +#: postmaster/walsummarizer.c:800 +#, c-format msgid "Summarization has reached %X/%08X on disk and %X/%08X in memory." -msgstr "Zusammenfassung hat %X/%X auf Festplatte und %X/%X im Speicher erreicht." +msgstr "Zusammenfassung hat %X/%08X auf Festplatte und %X/%08X im Speicher erreicht." -#: postmaster/walsummarizer.c:1002 +#: postmaster/walsummarizer.c:1101 #, c-format msgid "could not find a valid record after %X/%08X: %s" msgstr "konnte keinen gültigen Datensatz nach %X/%08X finden: %s" -#: postmaster/walsummarizer.c:1006 +#: postmaster/walsummarizer.c:1105 #, c-format msgid "could not find a valid record after %X/%08X" msgstr "konnte keinen gültigen Datensatz nach %X/%08X finden" -#: postmaster/walsummarizer.c:1057 -#, fuzzy, c-format -#| msgid "could not read WAL from timeline %u at %X/%X" +#: postmaster/walsummarizer.c:1156 +#, c-format msgid "could not read WAL from timeline %u at %X/%08X" -msgstr "konnte WAL aus Zeitleiste %u bei %X/%X nicht lesen" +msgstr "konnte WAL aus Zeitleiste %u bei %X/%08X nicht lesen" #: regex/regc_pg_locale.c:47 #, c-format @@ -26085,142 +25729,153 @@ msgstr "ungültige Zeitleiste %u" msgid "invalid streaming start location" msgstr "ungültige Streaming-Startposition" -#: replication/libpqwalreceiver/libpqwalreceiver.c:246 -#: replication/libpqwalreceiver/libpqwalreceiver.c:338 +#: replication/libpqwalreceiver/libpqwalreceiver.c:247 +#: replication/libpqwalreceiver/libpqwalreceiver.c:339 #, c-format msgid "password is required" msgstr "Passwort wird benötigt" -#: replication/libpqwalreceiver/libpqwalreceiver.c:247 +#: replication/libpqwalreceiver/libpqwalreceiver.c:248 #, c-format msgid "Non-superuser cannot connect if the server does not request a password." msgstr "Nicht-Superuser kann nicht verbinden, wenn der Server kein Passwort anfordert." -#: replication/libpqwalreceiver/libpqwalreceiver.c:248 +#: replication/libpqwalreceiver/libpqwalreceiver.c:249 #, c-format msgid "Target server's authentication method must be changed, or set password_required=false in the subscription parameters." msgstr "Die Authentifizierungsmethode des Zielservers muss geändern werden oder setzen Sie password_required=false in den Subskriptionsparametern." -#: replication/libpqwalreceiver/libpqwalreceiver.c:265 +#: replication/libpqwalreceiver/libpqwalreceiver.c:266 #, c-format msgid "could not clear search path: %s" msgstr "konnte Suchpfad nicht auf leer setzen: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:311 -#: replication/libpqwalreceiver/libpqwalreceiver.c:502 +#: replication/libpqwalreceiver/libpqwalreceiver.c:312 +#: replication/libpqwalreceiver/libpqwalreceiver.c:519 #, c-format msgid "invalid connection string syntax: %s" msgstr "ungültige Syntax für Verbindungszeichenkette: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:339 +#: replication/libpqwalreceiver/libpqwalreceiver.c:340 #, c-format msgid "Non-superusers must provide a password in the connection string." msgstr "Nicht-Superuser müssen ein Passwort in den Verbindungsparametern angeben." -#: replication/libpqwalreceiver/libpqwalreceiver.c:366 +#: replication/libpqwalreceiver/libpqwalreceiver.c:367 #, c-format msgid "could not parse connection string: %s" msgstr "konnte Verbindungsparameter nicht interpretieren: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:439 +#: replication/libpqwalreceiver/libpqwalreceiver.c:441 #, c-format msgid "could not receive database system identifier and timeline ID from the primary server: %s" msgstr "konnte Datenbanksystemidentifikator und Zeitleisten-ID nicht vom Primärserver empfangen: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:450 -#: replication/libpqwalreceiver/libpqwalreceiver.c:764 +#: replication/libpqwalreceiver/libpqwalreceiver.c:452 +#: replication/libpqwalreceiver/libpqwalreceiver.c:781 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1024 #, c-format msgid "invalid response from primary server" msgstr "ungültige Antwort vom Primärserver" -#: replication/libpqwalreceiver/libpqwalreceiver.c:451 +#: replication/libpqwalreceiver/libpqwalreceiver.c:453 #, c-format msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." msgstr "Konnte System nicht identifizieren: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet." -#: replication/libpqwalreceiver/libpqwalreceiver.c:647 +#: replication/libpqwalreceiver/libpqwalreceiver.c:467 +#, c-format +msgid "could not parse WAL location \"%s\"" +msgstr "konnte WAL-Position »%s« nicht parsen" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:664 #, c-format msgid "could not start WAL streaming: %s" msgstr "konnte WAL-Streaming nicht starten: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:670 +#: replication/libpqwalreceiver/libpqwalreceiver.c:687 #, c-format msgid "could not send end-of-streaming message to primary: %s" msgstr "konnte End-of-Streaming-Nachricht nicht an Primärserver senden: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:694 +#: replication/libpqwalreceiver/libpqwalreceiver.c:711 #, c-format msgid "unexpected result set after end-of-streaming" msgstr "unerwartete Ergebnismenge nach End-of-Streaming" -#: replication/libpqwalreceiver/libpqwalreceiver.c:710 +#: replication/libpqwalreceiver/libpqwalreceiver.c:727 #, c-format msgid "error while shutting down streaming COPY: %s" msgstr "Fehler beim Beenden des COPY-Datenstroms: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:721 +#: replication/libpqwalreceiver/libpqwalreceiver.c:738 #, c-format msgid "error reading result of streaming command: %s" msgstr "Fehler beim Lesen des Ergebnisses von Streaming-Befehl: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:731 -#: replication/libpqwalreceiver/libpqwalreceiver.c:858 +#: replication/libpqwalreceiver/libpqwalreceiver.c:748 +#: replication/libpqwalreceiver/libpqwalreceiver.c:875 #, c-format msgid "unexpected result after CommandComplete: %s" msgstr "unerwartetes Ergebnis nach CommandComplete: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:758 +#: replication/libpqwalreceiver/libpqwalreceiver.c:775 #, c-format msgid "could not receive timeline history file from the primary server: %s" msgstr "konnte Zeitleisten-History-Datei nicht vom Primärserver empfangen: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:765 +#: replication/libpqwalreceiver/libpqwalreceiver.c:782 #, c-format msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." msgstr "1 Tupel mit 2 Feldern erwartet, %d Tupel mit %d Feldern erhalten." -#: replication/libpqwalreceiver/libpqwalreceiver.c:819 -#: replication/libpqwalreceiver/libpqwalreceiver.c:872 -#: replication/libpqwalreceiver/libpqwalreceiver.c:878 +#: replication/libpqwalreceiver/libpqwalreceiver.c:836 +#: replication/libpqwalreceiver/libpqwalreceiver.c:889 +#: replication/libpqwalreceiver/libpqwalreceiver.c:895 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "konnte keine Daten vom WAL-Stream empfangen: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:898 +#: replication/libpqwalreceiver/libpqwalreceiver.c:915 #, c-format msgid "could not send data to WAL stream: %s" msgstr "konnte keine Daten an den WAL-Stream senden: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1000 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1017 #, c-format msgid "could not create replication slot \"%s\": %s" msgstr "konnte Replikations-Slot »%s« nicht erzeugen: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1052 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1025 +#, c-format +msgid "Could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields." +msgstr "Konnte Replikations-Slot »%s« nicht erzeugen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1077 #, c-format msgid "could not alter replication slot \"%s\": %s" msgstr "konnte Replikations-Slot »%s« nicht ändern: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1086 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1111 #, c-format msgid "invalid query response" msgstr "ungültige Antwort auf Anfrage" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1087 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1112 #, c-format msgid "Expected %d fields, got %d fields." msgstr "%d Felder erwartet, %d Feldern erhalten." -#: replication/libpqwalreceiver/libpqwalreceiver.c:1158 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1183 #, c-format msgid "the query interface requires a database connection" msgstr "Ausführen von Anfragen benötigt eine Datenbankverbindung" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1192 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1217 msgid "empty query" msgstr "leere Anfrage" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1198 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1223 msgid "unexpected pipeline mode" msgstr "unerwarteter Pipeline-Modus" @@ -26266,206 +25921,169 @@ msgid "conflict detected on relation \"%s.%s\": conflict=%s" msgstr "Konflikt entdeckt für Relation »%s.%s«: Konflikt=%s" #: replication/logical/conflict.c:271 -#, fuzzy, c-format -#| msgid "could not translate name" +#, c-format msgid "Could not apply remote change: %s.\n" -msgstr "konnte Namen nicht umwandeln" +msgstr "Konnte entfernte Änderung nicht anwenden: %s.\n" #: replication/logical/conflict.c:274 -#, fuzzy -#| msgid "could not translate name" msgid "Could not apply remote change.\n" -msgstr "konnte Namen nicht umwandeln" +msgstr "Konnte entfernte Änderung nicht anwenden.\n" #: replication/logical/conflict.c:288 -#, fuzzy, c-format -#| msgid "Key already exists in unique index \"%s\", modified locally in transaction %u at %s." +#, c-format msgid "Key already exists in unique index \"%s\", modified locally in transaction %u at %s: %s." -msgstr "Schlüssel existiert bereits in Unique Index »%s«, lokal modifiziert in Transaktion %u um %s." +msgstr "Schlüssel existiert bereits in Unique Index »%s«, lokal modifiziert in Transaktion %u um %s: %s." #: replication/logical/conflict.c:293 -#, fuzzy, c-format -#| msgid "Key already exists in unique index \"%s\", modified locally in transaction %u at %s." +#, c-format msgid "Key already exists in unique index \"%s\", modified locally in transaction %u at %s." msgstr "Schlüssel existiert bereits in Unique Index »%s«, lokal modifiziert in Transaktion %u um %s." #: replication/logical/conflict.c:300 -#, fuzzy, c-format -#| msgid "Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s." +#, c-format msgid "Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s: %s." -msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert von Origin »%s« in Transaktion %u um %s." +msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert von Origin »%s« in Transaktion %u um %s: %s." #: replication/logical/conflict.c:305 -#, fuzzy, c-format -#| msgid "Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s." +#, c-format msgid "Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s." msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert von Origin »%s« in Transaktion %u um %s." #: replication/logical/conflict.c:320 -#, fuzzy, c-format -#| msgid "Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s." +#, c-format msgid "Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s: %s." -msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert von nicht existierendem Origin in Transaktion %u um %s." +msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert von nicht existierendem Origin in Transaktion %u um %s: %s." #: replication/logical/conflict.c:325 -#, fuzzy, c-format -#| msgid "Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s." +#, c-format msgid "Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s." msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert von nicht existierendem Origin in Transaktion %u um %s." #: replication/logical/conflict.c:333 -#, fuzzy, c-format -#| msgid "Key already exists in unique index \"%s\", modified in transaction %u." +#, c-format msgid "Key already exists in unique index \"%s\", modified in transaction %u: %s." -msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert in Transaktion %u." +msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert in Transaktion %u: %s." #: replication/logical/conflict.c:337 -#, fuzzy, c-format -#| msgid "Key already exists in unique index \"%s\", modified in transaction %u." +#, c-format msgid "Key already exists in unique index \"%s\", modified in transaction %u." msgstr "Schlüssel existiert bereits in Unique Index »%s«, modifiziert in Transaktion %u." #: replication/logical/conflict.c:351 -#, fuzzy, c-format -#| msgid "Updating the row that was modified locally in transaction %u at %s." +#, c-format msgid "Updating the row that was modified locally in transaction %u at %s: %s." -msgstr "Aktualisiere die Zeile, die lokal in Transaktion %u um %s modifiziert wurde." +msgstr "Aktualisiere die Zeile, die lokal in Transaktion %u um %s modifiziert wurde: %s." #: replication/logical/conflict.c:355 -#, fuzzy, c-format -#| msgid "Updating the row that was modified locally in transaction %u at %s." +#, c-format msgid "Updating the row that was modified locally in transaction %u at %s." msgstr "Aktualisiere die Zeile, die lokal in Transaktion %u um %s modifiziert wurde." #: replication/logical/conflict.c:361 -#, fuzzy, c-format -#| msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s." +#, c-format msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s: %s." -msgstr "Aktualisiere die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde." +msgstr "Aktualisiere die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde: %s." #: replication/logical/conflict.c:366 -#, fuzzy, c-format -#| msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s." +#, c-format msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s." msgstr "Aktualisiere die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde." #: replication/logical/conflict.c:375 -#, fuzzy, c-format -#| msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s." +#, c-format msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s: %s." -msgstr "Aktualisiere die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde." +msgstr "Aktualisiere die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde: %s." #: replication/logical/conflict.c:379 -#, fuzzy, c-format -#| msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s." +#, c-format msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s." msgstr "Aktualisiere die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde." #: replication/logical/conflict.c:390 -#, fuzzy, c-format -#| msgid "Could not find the row to be updated." +#, c-format msgid "Could not find the row to be updated: %s.\n" -msgstr "Konnte die zu aktualisierende Zeile nicht finden." +msgstr "Konnte die zu aktualisierende Zeile nicht finden: %s.\n" #: replication/logical/conflict.c:393 -#, fuzzy -#| msgid "Could not find the row to be updated." msgid "Could not find the row to be updated.\n" -msgstr "Konnte die zu aktualisierende Zeile nicht finden." +msgstr "Konnte die zu aktualisierende Zeile nicht finden.\n" #: replication/logical/conflict.c:398 -#, fuzzy, c-format -#| msgid "Updating the row that was modified locally in transaction %u at %s." +#, c-format msgid "The row to be updated was deleted locally in transaction %u at %s" -msgstr "Aktualisiere die Zeile, die lokal in Transaktion %u um %s modifiziert wurde." +msgstr "Die zu aktualisierende Zeile wurde lokal in Transaktion %u um %s gelöscht" #: replication/logical/conflict.c:401 -#, fuzzy, c-format -#| msgid "Updating the row that was modified by a different origin \"%s\" in transaction %u at %s." +#, c-format msgid "The row to be updated was deleted by a different origin \"%s\" in transaction %u at %s" -msgstr "Aktualisiere die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde." +msgstr "Die zu aktualisierende Zeile wurde von einem anderen Origin »%s« in Transaktion %u um %s gelöscht" #: replication/logical/conflict.c:406 -#, fuzzy, c-format -#| msgid "Updating the row that was modified by a non-existent origin in transaction %u at %s." +#, c-format msgid "The row to be updated was deleted by a non-existent origin in transaction %u at %s" -msgstr "Aktualisiere die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde." +msgstr "Die zu aktualisierende Zeile wurde von einem nicht existierenden Origin in Transaktion %u um %s gelöscht" #: replication/logical/conflict.c:410 msgid "The row to be updated was deleted" -msgstr "" +msgstr "Die zu aktualisierende Zeile wurde gelöscht" #: replication/logical/conflict.c:419 -#, fuzzy, c-format -#| msgid "Could not find the row to be updated." +#, c-format msgid "Could not find the row to be updated: %s." -msgstr "Konnte die zu aktualisierende Zeile nicht finden." +msgstr "Konnte die zu aktualisierende Zeile nicht finden: %s." #: replication/logical/conflict.c:422 -#, fuzzy -#| msgid "Could not find the row to be updated." msgid "Could not find the row to be updated." msgstr "Konnte die zu aktualisierende Zeile nicht finden." #: replication/logical/conflict.c:434 -#, fuzzy, c-format -#| msgid "Deleting the row that was modified locally in transaction %u at %s." +#, c-format msgid "Deleting the row that was modified locally in transaction %u at %s: %s." -msgstr "Lösche die Zeile, die lokal in Transaktion %u um %s modifiziert wurde." +msgstr "Lösche die Zeile, die lokal in Transaktion %u um %s modifiziert wurde: %s." #: replication/logical/conflict.c:438 -#, fuzzy, c-format -#| msgid "Deleting the row that was modified locally in transaction %u at %s." +#, c-format msgid "Deleting the row that was modified locally in transaction %u at %s." msgstr "Lösche die Zeile, die lokal in Transaktion %u um %s modifiziert wurde." #: replication/logical/conflict.c:444 -#, fuzzy, c-format -#| msgid "Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s." +#, c-format msgid "Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s: %s." -msgstr "Lösche die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde." +msgstr "Lösche die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde: %s." #: replication/logical/conflict.c:449 -#, fuzzy, c-format -#| msgid "Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s." +#, c-format msgid "Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s." msgstr "Lösche die Zeile, die von einem anderen Origin »%s« in Transaktion %u um %s modifiziert wurde." #: replication/logical/conflict.c:458 -#, fuzzy, c-format -#| msgid "Deleting the row that was modified by a non-existent origin in transaction %u at %s." +#, c-format msgid "Deleting the row that was modified by a non-existent origin in transaction %u at %s: %s." -msgstr "Lösche die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde." +msgstr "Lösche die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde: %s." #: replication/logical/conflict.c:462 -#, fuzzy, c-format -#| msgid "Deleting the row that was modified by a non-existent origin in transaction %u at %s." +#, c-format msgid "Deleting the row that was modified by a non-existent origin in transaction %u at %s." msgstr "Lösche die Zeile, die von einem nicht existierenden Origin in Transaktion %u um %s modifiziert wurde." #: replication/logical/conflict.c:473 -#, fuzzy, c-format -#| msgid "Could not find the row to be deleted." +#, c-format msgid "Could not find the row to be deleted: %s." -msgstr "Konnte die zu löschende Zeile nicht finden." +msgstr "Konnte die zu löschende Zeile nicht finden: %s." #: replication/logical/conflict.c:476 -#, fuzzy -#| msgid "Could not find the row to be deleted." msgid "Could not find the row to be deleted." msgstr "Konnte die zu löschende Zeile nicht finden." #: replication/logical/conflict.c:529 -#, fuzzy, c-format -#| msgid "Key %s" +#, c-format msgid "key %s" msgstr "Schlüssel %s" #: replication/logical/conflict.c:542 -#, fuzzy, c-format -#| msgid "existing local row %s" +#, c-format msgid "local row %s" -msgstr "bestehende lokale Zeile %s" +msgstr "lokale Zeile %s" #: replication/logical/conflict.c:563 #, c-format @@ -26503,26 +26121,24 @@ msgid "logical replication worker slot %d is already used by another worker, can msgstr "Arbeitsprozess-Slot %d für logische Replikation wird schon von einem anderen Arbeitsprozess verwendet, kann nicht zugeteilt werden" #: replication/logical/launcher.c:1576 -#, fuzzy, c-format -#| msgid "Creating the replication conflict detection slot" +#, c-format msgid "creating replication conflict detection slot" -msgstr "Erzeuge den Replikations-Slot zur Entdeckung von Konflikten" +msgstr "erzeuge Replikations-Slot zur Entdeckung von Konflikten" #: replication/logical/logical.c:123 #, c-format msgid "logical decoding requires a database connection" msgstr "logische Dekodierung benötigt eine Datenbankverbindung" -#: replication/logical/logical.c:132 -#, fuzzy, c-format -#| msgid "logical decoding on standby requires \"wal_level\" >= \"logical\" on the primary" +#: replication/logical/logical.c:132 replication/logical/logicalctl.c:321 +#, c-format msgid "logical decoding on standby requires \"effective_wal_level\" >= \"logical\" on the primary" -msgstr "logische Dekodierung auf dem Standby-Server erfordert »wal_level« >= »logical« auf dem Primärserver" +msgstr "logische Dekodierung auf dem Standby-Server erfordert »effective_wal_level« >= »logical« auf dem Primärserver" #: replication/logical/logical.c:133 #, c-format msgid "Set \"wal_level\" >= \"logical\" or create at least one logical slot when \"wal_level\" = \"replica\"." -msgstr "" +msgstr "Setzen Sie »wal_level« >= »logical« oder erzeugen Sie mindestens einen logischen Slot, wenn »wal_level« = »replica«." #: replication/logical/logical.c:358 replication/logical/logical.c:514 #, c-format @@ -26544,8 +26160,8 @@ msgstr "logischer Replikations-Slot kann nicht in einer Transaktion erzeugt werd msgid "cannot use replication slot \"%s\" for logical decoding" msgstr "physischer Replikations-Slot »%s« kann nicht für logisches Dekodieren verwendet werden" -#: replication/logical/logical.c:537 replication/slot.c:927 -#: replication/slot.c:972 +#: replication/logical/logical.c:537 replication/slot.c:929 +#: replication/slot.c:974 #, c-format msgid "This replication slot is being synchronized from the primary server." msgstr "Dieser Replikations-Slot wird vom Primärserver synchronisiert." @@ -26561,16 +26177,14 @@ msgid "starting logical decoding for slot \"%s\"" msgstr "starte logisches Dekodieren für Slot »%s«" #: replication/logical/logical.c:606 -#, fuzzy, c-format -#| msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +#, c-format msgid "Streaming transactions committing after %X/%08X, reading WAL from %X/%08X." -msgstr "Streaming beginnt bei Transaktionen, die nach %X/%X committen; lese WAL ab %X/%X." +msgstr "Streaming beginnt bei Transaktionen, die nach %X/%08X committen; lese WAL ab %X/%08X." #: replication/logical/logical.c:754 -#, fuzzy, c-format -#| msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +#, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%08X" -msgstr "Slot »%s«, Ausgabe-Plugin »%s«, im Callback %s, zugehörige LSN %X/%X" +msgstr "Slot »%s«, Ausgabe-Plugin »%s«, im Callback %s, zugehörige LSN %X/%08X" #: replication/logical/logical.c:760 #, c-format @@ -26595,17 +26209,20 @@ msgstr "logisches Streaming benötigt einen %s-Callback" msgid "logical streaming at prepare time requires a %s callback" msgstr "logisches Streaming bei PREPARE TRANSACTION benötigt einen %s-Callback" -#: replication/logical/logicalctl.c:413 -#, fuzzy, c-format -#| msgid "Logical replication is waiting for correction on replication slot \"%s\"." +#: replication/logical/logicalctl.c:322 +#, c-format +msgid "Logical decoding was concurrently disabled during the logical replication slot creation." +msgstr "Logisches Dekodieren wurde während der Erzeugung des logischen Replikations-Slots gleichzeitig ausgeschaltet." + +#: replication/logical/logicalctl.c:442 +#, c-format msgid "logical decoding is enabled upon creating a new logical replication slot" -msgstr "Logische Replikation wartet auf Korrektur bei Replikations-Slot »%s«." +msgstr "logisches Dekodieren wird beim Erzeugen eines neuen logischen Replikations-Slots eingeschaltet" -#: replication/logical/logicalctl.c:537 -#, fuzzy, c-format -#| msgid "Checking for valid logical replication slots" +#: replication/logical/logicalctl.c:579 +#, c-format msgid "logical decoding is disabled because there are no valid logical replication slots" -msgstr "Prüfe auf gültige logische Replikations-Slots" +msgstr "logisches Dekodieren ist ausgeschaltet, weil es keine gültigen logischen Replikations-Slots gibt" #: replication/logical/logicalfuncs.c:123 #, c-format @@ -26674,10 +26291,9 @@ msgid "could not drop replication origin with ID %d, in use by PID %d" msgstr "konnte Replication-Origin mit ID %d nicht löschen, wird von PID %d verwendet" #: replication/logical/origin.c:414 -#, fuzzy, c-format -#| msgid "could not drop replication origin with ID %d, in use by PID %d" +#, c-format msgid "could not drop replication origin with ID %d, in use by another process" -msgstr "konnte Replication-Origin mit ID %d nicht löschen, wird von PID %d verwendet" +msgstr "konnte Replication-Origin mit ID %d nicht löschen, wird von einem anderen Prozess verwendet" #: replication/logical/origin.c:540 #, c-format @@ -26695,10 +26311,9 @@ msgid "could not find free replication state, increase \"max_active_replication_ msgstr "konnte keinen freien Replication-State finden, erhöhen Sie »max_active_replication_origins«" #: replication/logical/origin.c:846 -#, fuzzy, c-format -#| msgid "recovered replication state of node %d to %X/%X" +#, c-format msgid "recovered replication state of node %d to %X/%08X" -msgstr "Replikationszustand von Knoten %d auf %X/%X wiederhergestellt" +msgstr "Replikationszustand von Knoten %d auf %X/%08X wiederhergestellt" #: replication/logical/origin.c:856 #, c-format @@ -26711,10 +26326,9 @@ msgid "replication origin with ID %d is already active for PID %d" msgstr "Replication-Origin mit ID %d ist bereits aktiv für PID %d" #: replication/logical/origin.c:988 replication/logical/origin.c:1219 -#, fuzzy, c-format -#| msgid "replication origin with ID %d is already active for PID %d" +#, c-format msgid "replication origin with ID %d is already active in another process" -msgstr "Replication-Origin mit ID %d ist bereits aktiv für PID %d" +msgstr "Replication-Origin mit ID %d ist bereits in einem anderen Prozess aktiv" #: replication/logical/origin.c:998 replication/logical/origin.c:1258 #, c-format @@ -26732,16 +26346,14 @@ msgid "cannot setup replication origin when one is already setup" msgstr "kann Replication-Origin nicht einrichten, wenn schon einer eingerichtet ist" #: replication/logical/origin.c:1232 -#, fuzzy, c-format -#| msgid "replication origin with ID %d is already active for PID %d" +#, c-format msgid "replication origin with ID %d is not active for PID %d" -msgstr "Replication-Origin mit ID %d ist bereits aktiv für PID %d" +msgstr "Replication-Origin mit ID %d ist nicht aktiv für PID %d" #: replication/logical/origin.c:1251 -#, fuzzy, c-format -#| msgid "could not find free replication state slot for replication origin with ID %d" +#, c-format msgid "cannot use PID %d for inactive replication origin with ID %d" -msgstr "konnte keinen freien Replication-State-Slot für Replication-Origin mit ID %d finden" +msgstr "kann PID %d nicht für inaktiven Replication-Origin mit ID %d verwenden" #: replication/logical/origin.c:1308 replication/logical/origin.c:1544 #: replication/logical/origin.c:1564 @@ -26750,20 +26362,19 @@ msgid "no replication origin is configured" msgstr "kein Replication-Origin konfiguriert" #: replication/logical/origin.c:1320 -#, fuzzy, c-format -#| msgid "could not drop replication origin with ID %d, in use by PID %d" +#, c-format msgid "cannot reset replication origin with ID %d because it is still in use by other processes" -msgstr "konnte Replication-Origin mit ID %d nicht löschen, wird von PID %d verwendet" +msgstr "kann Replication-Origin mit ID %d nicht zurücksetzen, weil er noch von anderen Prozessen verwendet wird" #: replication/logical/origin.c:1322 #, c-format msgid "This session is the first process for this replication origin, and other processes are currently sharing it." -msgstr "" +msgstr "Diese Sitzung ist der erste Prozess für diesen Replication-Origin und andere Prozesse teilen ihn sich gerade." #: replication/logical/origin.c:1323 #, c-format msgid "Reset the replication origin in all other processes before retrying." -msgstr "" +msgstr "Setzen Sie den Replication-Origin in allen anderen Prozessen zurück, bevor Sie es erneut versuchen." #: replication/logical/origin.c:1414 #, c-format @@ -26799,162 +26410,158 @@ msgstr "Zielrelation für logische Replikation »%s.%s« verwendet Systemspalten msgid "logical replication target relation \"%s.%s\" does not exist" msgstr "Zielrelation für logische Replikation »%s.%s« existiert nicht" -#: replication/logical/reorderbuffer.c:4282 +#: replication/logical/reorderbuffer.c:4308 #, c-format msgid "could not write to data file for XID %u: %m" msgstr "konnte nicht in Datendatei für XID %u schreiben: %m" -#: replication/logical/reorderbuffer.c:4628 -#: replication/logical/reorderbuffer.c:4653 +#: replication/logical/reorderbuffer.c:4654 +#: replication/logical/reorderbuffer.c:4679 #, c-format msgid "could not read from reorderbuffer spill file: %m" msgstr "konnte nicht aus Reorder-Buffer-Spill-Datei lesen: %m" -#: replication/logical/reorderbuffer.c:4632 -#: replication/logical/reorderbuffer.c:4657 +#: replication/logical/reorderbuffer.c:4658 +#: replication/logical/reorderbuffer.c:4683 #, c-format msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" msgstr "konnte nicht aus Reorder-Buffer-Spill-Datei lesen: %d statt %u Bytes gelesen" -#: replication/logical/reorderbuffer.c:4906 +#: replication/logical/reorderbuffer.c:4932 #, c-format msgid "could not remove file \"%s\" during removal of %s/%s/xid*: %m" msgstr "konnte Datei »%s« nicht löschen, beim Löschen von %s/%s/xid*: %m" -#: replication/logical/reorderbuffer.c:5399 +#: replication/logical/reorderbuffer.c:5425 #, c-format msgid "could not read from file \"%s\": read %d instead of %d bytes" msgstr "konnte nicht aus Datei »%s« lesen: %d statt %d Bytes gelesen" #: replication/logical/sequencesync.c:195 -#, fuzzy, c-format -#| msgid "could not reset WAL on subscriber: %s" +#, c-format msgid "mismatched or renamed sequence on subscriber (%s)" msgid_plural "mismatched or renamed sequences on subscriber (%s)" -msgstr[0] "konnte WAL auf dem Subskriptionsserver nicht zurücksetzen: %s" -msgstr[1] "konnte WAL auf dem Subskriptionsserver nicht zurücksetzen: %s" +msgstr[0] "nicht übereinstimmende oder umbenannte Sequenz auf dem Subskriptionsserver (%s)" +msgstr[1] "nicht übereinstimmende oder umbenannte Sequenzen auf dem Subskriptionsserver (%s)" #: replication/logical/sequencesync.c:214 -#, fuzzy, c-format -#| msgid "invalid privilege type %s for sequence" +#, c-format msgid "insufficient privileges on subscriber sequence (%s)" msgid_plural "insufficient privileges on subscriber sequences (%s)" -msgstr[0] "ungültiger Privilegtyp %s für Sequenz" -msgstr[1] "ungültiger Privilegtyp %s für Sequenz" +msgstr[0] "unzureichende Privilegien für Sequenz auf dem Subskriptionsserver (%s)" +msgstr[1] "unzureichende Privilegien für Sequenzen auf dem Subskriptionsserver (%s)" #: replication/logical/sequencesync.c:219 #, c-format msgid "Grant UPDATE on the sequence to the subscription owner on the subscriber." msgid_plural "Grant UPDATE on the sequences to the subscription owner on the subscriber." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Erteilen Sie UPDATE für die Sequenz an den Eigentümer der Subskription auf dem Subskriptionsserver." +msgstr[1] "Erteilen Sie UPDATE für die Sequenzen an den Eigentümer der Subskription auf dem Subskriptionsserver." #: replication/logical/sequencesync.c:231 -#, fuzzy, c-format -#| msgid "invalid privilege type %s for sequence" +#, c-format msgid "insufficient privileges on publisher sequence (%s)" msgid_plural "insufficient privileges on publisher sequences (%s)" -msgstr[0] "ungültiger Privilegtyp %s für Sequenz" -msgstr[1] "ungültiger Privilegtyp %s für Sequenz" +msgstr[0] "unzureichende Privilegien für Sequenz auf dem Publikationsserver (%s)" +msgstr[1] "unzureichende Privilegien für Sequenzen auf dem Publikationsserver (%s)" #: replication/logical/sequencesync.c:235 #, c-format msgid "Grant SELECT on the sequence to the role used for the replication connection on the publisher." msgid_plural "Grant SELECT on the sequences to the role used for the replication connection on the publisher." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Erteilen Sie SELECT für die Sequenz an die Rolle, die für die Replikationsverbindung auf dem Publikationsserver verwendet wird." +msgstr[1] "Erteilen Sie SELECT für die Sequenzen an die Rolle, die für die Replikationsverbindung auf dem Publikationsserver verwendet wird." #: replication/logical/sequencesync.c:247 -#, fuzzy, c-format -#| msgid "checking settings on publisher" +#, c-format msgid "missing sequence on publisher (%s)" msgid_plural "missing sequences on publisher (%s)" -msgstr[0] "prüfe Einstellungen auf dem Publikationsserver" -msgstr[1] "prüfe Einstellungen auf dem Publikationsserver" +msgstr[0] "fehlende Sequenz auf dem Publikationsserver (%s)" +msgstr[1] "fehlende Sequenzen auf dem Publikationsserver (%s)" #: replication/logical/sequencesync.c:255 -#, fuzzy, c-format -#| msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +#, c-format msgid "logical replication sequence synchronization failed for subscription \"%s\"" -msgstr "Arbeitsprozess für logische Replikation für Tabellensynchronisation für Subskription »%s«, Tabelle »%s« hat gestartet" +msgstr "Sequenzsynchronisation für logische Replikation für Subskription »%s« fehlgeschlagen" -#: replication/logical/sequencesync.c:533 -#, fuzzy, c-format -#| msgid "could not receive list of publications from the publisher: %s" +#: replication/logical/sequencesync.c:569 +#, c-format msgid "could not fetch sequence information from the publisher: %s" -msgstr "konnte Liste der Publikationen nicht vom Publikationsserver empfangen: %s" +msgstr "konnte Sequenzinformationen nicht vom Publikationsserver holen: %s" -#: replication/logical/sequencesync.c:616 +#: replication/logical/sequencesync.c:652 #, c-format msgid "skip synchronization of sequence \"%s.%s\" because it has been dropped concurrently" -msgstr "" +msgstr "überspringe Synchronisation von Sequenz »%s.%s«, weil sie nebenläufig gelöscht wurde" -#: replication/logical/sequencesync.c:778 -#, fuzzy, c-format -#| msgid "apply worker for subscription \"%s\" could not connect to the publisher: %s" +#: replication/logical/sequencesync.c:824 +#, c-format msgid "sequencesync worker for subscription \"%s\" could not connect to the publisher: %s" -msgstr "Apply-Worker für Subskription »%s« konnte nicht mit dem Publikationsserver verbinden: %s" +msgstr "Sequencesync-Worker für Subskription »%s« konnte nicht mit dem Publikationsserver verbinden: %s" -#: replication/logical/slotsync.c:245 -#, fuzzy, c-format -#| msgid "skipping slot synchronization because the received slot sync LSN %X/%X for slot \"%s\" is ahead of the standby position %X/%X" +#: replication/logical/slotsync.c:246 +#, c-format msgid "skipping slot synchronization because the received slot sync LSN %X/%08X for slot \"%s\" is ahead of the standby position %X/%08X" -msgstr "Slot-Synchronisierung wird übersprungen, weil die empfangene Slot-Sync-LSN %X/%X für Slot »%s« der Position %X/%X des Standbys voraus ist" +msgstr "Slot-Synchronisierung wird übersprungen, weil die empfangene Slot-Sync-LSN %X/%08X für Slot »%s« der Position %X/%08X des Standbys voraus ist" -#: replication/logical/slotsync.c:288 replication/logical/slotsync.c:366 +#: replication/logical/slotsync.c:289 replication/logical/slotsync.c:367 +#: replication/logical/slotsync.c:737 #, c-format msgid "could not synchronize replication slot \"%s\"" msgstr "konnte Replikations-Slot »%s« nicht synchronisieren" -#: replication/logical/slotsync.c:290 -#, fuzzy, c-format -#| msgid "Synchronization could lead to data loss, because the remote slot needs WAL at LSN %X/%X and catalog xmin %u, but the standby has LSN %X/%X and catalog xmin %u." +#: replication/logical/slotsync.c:291 +#, c-format msgid "Synchronization could lead to data loss, because the remote slot needs WAL at LSN %X/%08X and catalog xmin %u, but the standby has LSN %X/%08X and catalog xmin %u." -msgstr "Synchronisation könnte zu Datenverlust führen, weil der Remote-Slot WAL bei LSN %X/%X und Katalog-xmin %u benötigt, aber der Standby LSN %X/%X und Katalog-xmin %u hat." +msgstr "Synchronisation könnte zu Datenverlust führen, weil der Remote-Slot WAL bei LSN %X/%08X und Katalog-xmin %u benötigt, aber der Standby LSN %X/%08X und Katalog-xmin %u hat." -#: replication/logical/slotsync.c:368 -#, fuzzy, c-format -#| msgid "Synchronization could lead to data loss, because the standby could not build a consistent snapshot to decode WALs at LSN %X/%X." +#: replication/logical/slotsync.c:369 +#, c-format msgid "Synchronization could lead to data loss, because the standby could not build a consistent snapshot to decode WALs at LSN %X/%08X." -msgstr "Synchronisation könnte zu Datenverlust führen, weil der Standby keinen konsistenten Snapshot zum Dekodieren von WAL bei LSN %X/%X bauen konnte." +msgstr "Synchronisation könnte zu Datenverlust führen, weil der Standby keinen konsistenten Snapshot zum Dekodieren von WAL bei LSN %X/%08X bauen konnte." -#: replication/logical/slotsync.c:582 +#: replication/logical/slotsync.c:583 #, c-format msgid "dropped replication slot \"%s\" of database with OID %u" msgstr "Replikations-Slot »%s« von Datenbank mit OID %u wurde gelöscht" -#: replication/logical/slotsync.c:714 +#: replication/logical/slotsync.c:739 +#, c-format +msgid "Logical decoding was concurrently disabled." +msgstr "Logisches Dekodieren wurde gleichzeitig ausgeschaltet." + +#: replication/logical/slotsync.c:750 #, c-format msgid "newly created replication slot \"%s\" is sync-ready now" msgstr "neu erzeugter Replikations-Slot »%s« ist jetzt bereit für die Synchronisierung" -#: replication/logical/slotsync.c:756 +#: replication/logical/slotsync.c:792 #, c-format msgid "exiting from slot synchronization because same name slot \"%s\" already exists on the standby" msgstr "verlasse Slot-Synchronisierung, weil der gleiche Slot »%s« schon auf dem Standby existiert" -#: replication/logical/slotsync.c:949 +#: replication/logical/slotsync.c:985 #, c-format msgid "could not fetch failover logical slots info from the primary server: %s" msgstr "konnte Informationen über logische Failover-Slots nicht vom Primärserver holen: %s" -#: replication/logical/slotsync.c:1114 +#: replication/logical/slotsync.c:1150 #, c-format msgid "could not fetch primary slot name \"%s\" info from the primary server: %s" msgstr "konnte Informationen über primary_slot_name »%s« nicht vom Primärserver holen: %s" -#: replication/logical/slotsync.c:1116 +#: replication/logical/slotsync.c:1152 #, c-format msgid "Check if \"primary_slot_name\" is configured correctly." msgstr "Prüfen Sie, ob »primary_slot_name« korrekt konfiguriert ist." -#: replication/logical/slotsync.c:1136 +#: replication/logical/slotsync.c:1172 #, c-format msgid "cannot synchronize replication slots from a standby server" msgstr "Replikations-Slots können nicht von einem Standby-Server synchronisiert werden" #. translator: second %s is a GUC variable name -#: replication/logical/slotsync.c:1145 +#: replication/logical/slotsync.c:1181 #, c-format msgid "replication slot \"%s\" specified by \"%s\" does not exist on primary server" msgstr "Replikations-Slot »%s«, der in »%s« angegeben ist, existiert auf dem Publikationsserver nicht" @@ -26962,87 +26569,80 @@ msgstr "Replikations-Slot »%s«, der in »%s« angegeben ist, existiert auf dem #. translator: first %s is a connection option; second %s is a GUC #. variable name #. -#: replication/logical/slotsync.c:1178 +#: replication/logical/slotsync.c:1214 #, c-format msgid "replication slot synchronization requires \"%s\" to be specified in \"%s\"" msgstr "Replikations-Slot-Synchronisierung erfordert, dass »%s« in »%s« angegeben wird" -#: replication/logical/slotsync.c:1197 -#, fuzzy, c-format -#| msgid "replication slot synchronization requires \"wal_level\" >= \"logical\"" +#: replication/logical/slotsync.c:1233 +#, c-format msgid "replication slot synchronization requires \"effective_wal_level\" >= \"logical\" on the primary" -msgstr "Replikations-Slot-Synchronisierung erfordert »wal_level« >= »logical«" +msgstr "Replikations-Slot-Synchronisierung erfordert »effective_wal_level« >= »logical« auf dem Primärserver" -#: replication/logical/slotsync.c:1198 +#: replication/logical/slotsync.c:1234 #, c-format msgid "To enable logical decoding on primary, set \"wal_level\" >= \"logical\" or create at least one logical slot when \"wal_level\" = \"replica\"." -msgstr "" +msgstr "Um logisches Dekodieren auf dem Primärserver einzuschalten, setzen Sie »wal_level« >= »logical« oder erzeugen Sie mindestens einen logischen Slot, wenn »wal_level« = »replica«." #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1214 replication/logical/slotsync.c:1242 +#: replication/logical/slotsync.c:1250 replication/logical/slotsync.c:1278 #, c-format msgid "replication slot synchronization requires \"%s\" to be set" msgstr "Replikations-Slot-Synchronisierung erfordert, dass »%s« definiert ist" #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1228 +#: replication/logical/slotsync.c:1264 #, c-format msgid "replication slot synchronization requires \"%s\" to be enabled" msgstr "Replikations-Slot-Synchronisierung erfordert, dass »%s« eingeschaltet ist" #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1285 -#, fuzzy, c-format -#| msgid "replication slot synchronization worker will shut down because \"%s\" is disabled" +#: replication/logical/slotsync.c:1321 +#, c-format msgid "replication slot synchronization worker will stop because \"%s\" is disabled" -msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung wird herunterfahren, weil »%s« deaktiviert ist" +msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung wird anhalten, weil »%s« deaktiviert ist" -#: replication/logical/slotsync.c:1303 +#: replication/logical/slotsync.c:1339 #, c-format msgid "replication slot synchronization worker will restart because of a parameter change" msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung wird neu starten wegen einer Parameteränderung" -#: replication/logical/slotsync.c:1328 -#, fuzzy, c-format -#| msgid "replication slot synchronization worker will restart because of a parameter change" +#: replication/logical/slotsync.c:1364 +#, c-format msgid "replication slot synchronization will stop because of a parameter change" -msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung wird neu starten wegen einer Parameteränderung" +msgstr "Replikations-Slot-Synchronisierung wird wegen einer Parameteränderung anhalten" -#: replication/logical/slotsync.c:1364 -#, fuzzy, c-format -#| msgid "replication slot synchronization worker is shutting down because promotion is triggered" +#: replication/logical/slotsync.c:1400 +#, c-format msgid "replication slot synchronization worker will stop because promotion is triggered" -msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung fährt herunter, weil Beförderung ausgelöst wurde" +msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung wird anhalten, weil Beförderung ausgelöst wurde" -#: replication/logical/slotsync.c:1378 -#, fuzzy, c-format -#| msgid "replication slot synchronization worker is shutting down because promotion is triggered" +#: replication/logical/slotsync.c:1414 +#, c-format msgid "replication slot synchronization will stop because promotion is triggered" -msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung fährt herunter, weil Beförderung ausgelöst wurde" +msgstr "Replikations-Slot-Synchronisierung wird anhalten, weil Beförderung ausgelöst wurde" -#: replication/logical/slotsync.c:1498 -#, fuzzy, c-format -#| msgid "replication slot synchronization worker is shutting down because promotion is triggered" +#: replication/logical/slotsync.c:1534 +#, c-format msgid "replication slot synchronization worker will not start because promotion was triggered" -msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung fährt herunter, weil Beförderung ausgelöst wurde" +msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung wird nicht starten, weil Beförderung ausgelöst wurde" -#: replication/logical/slotsync.c:1510 -#, fuzzy, c-format -#| msgid "replication slot synchronization worker is shutting down because promotion is triggered" +#: replication/logical/slotsync.c:1546 +#, c-format msgid "replication slot synchronization will not start because promotion was triggered" -msgstr "Arbeitsprozess für Replikations-Slot-Synchronisierung fährt herunter, weil Beförderung ausgelöst wurde" +msgstr "Replikations-Slot-Synchronisierung wird nicht starten, weil Beförderung ausgelöst wurde" -#: replication/logical/slotsync.c:1519 +#: replication/logical/slotsync.c:1555 #, c-format msgid "cannot synchronize replication slots concurrently" msgstr "Replikations-Slots können nicht nebenläufig synchronisiert werden" -#: replication/logical/slotsync.c:1639 +#: replication/logical/slotsync.c:1675 #, c-format msgid "slot sync worker started" msgstr "Slot-Sync-Arbeitsprozess gestartet" -#: replication/logical/slotsync.c:1701 replication/slotfuncs.c:953 +#: replication/logical/slotsync.c:1737 replication/slotfuncs.c:962 #, c-format msgid "synchronization worker \"%s\" could not connect to the primary server: %s" msgstr "Synchronisierungs-Arbeitsprozess »%s« konnte nicht mit dem Primärserver verbinden: %s" @@ -27061,10 +26661,9 @@ msgstr[1] "logischer Dekodierungs-Snapshot exportiert: »%s« mit %u Transaktion #: replication/logical/snapbuild.c:1317 replication/logical/snapbuild.c:1414 #: replication/logical/snapbuild.c:1920 -#, fuzzy, c-format -#| msgid "logical decoding found consistent point at %X/%X" +#, c-format msgid "logical decoding found consistent point at %X/%08X" -msgstr "logisches Dekodieren fand konsistenten Punkt bei %X/%X" +msgstr "logisches Dekodieren fand konsistenten Punkt bei %X/%08X" #: replication/logical/snapbuild.c:1319 #, c-format @@ -27072,10 +26671,9 @@ msgid "There are no running transactions." msgstr "Keine laufenden Transaktionen." #: replication/logical/snapbuild.c:1366 -#, fuzzy, c-format -#| msgid "logical decoding found initial starting point at %X/%X" +#, c-format msgid "logical decoding found initial starting point at %X/%08X" -msgstr "logisches Dekodieren fand initialen Startpunkt bei %X/%X" +msgstr "logisches Dekodieren fand initialen Startpunkt bei %X/%08X" #: replication/logical/snapbuild.c:1368 replication/logical/snapbuild.c:1392 #, c-format @@ -27083,10 +26681,9 @@ msgid "Waiting for transactions (approximately %d) older than %u to end." msgstr "Warten auf Abschluss der Transaktionen (ungefähr %d), die älter als %u sind." #: replication/logical/snapbuild.c:1390 -#, fuzzy, c-format -#| msgid "logical decoding found initial consistent point at %X/%X" +#, c-format msgid "logical decoding found initial consistent point at %X/%08X" -msgstr "logisches Dekodieren fand initialen konsistenten Punkt bei %X/%X" +msgstr "logisches Dekodieren fand initialen konsistenten Punkt bei %X/%08X" #: replication/logical/snapbuild.c:1416 #, c-format @@ -27119,10 +26716,9 @@ msgid "could not parse file name \"%s\"" msgstr "konnte Dateinamen »%s« nicht parsen" #: replication/logical/syncutils.c:70 -#, fuzzy, c-format -#| msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +#, c-format msgid "logical replication sequence synchronization worker for subscription \"%s\" has finished" -msgstr "Arbeitsprozess für logische Replikation für Tabellensynchronisation für Subskription »%s«, Tabelle »%s« hat abgeschlossen" +msgstr "Arbeitsprozess für logische Replikation für Sequenzsynchronisation für Subskription »%s« hat abgeschlossen" #: replication/logical/syncutils.c:83 #, c-format @@ -27169,7 +26765,7 @@ msgstr "Arbeitsprozess für Tabellensynchronisation für Subskription »%s« kon msgid "table copy could not start transaction on publisher: %s" msgstr "beim Kopieren der Tabelle konnte die Transaktion auf dem Publikationsserver nicht gestartet werden: %s" -#: replication/logical/tablesync.c:1474 replication/logical/worker.c:2640 +#: replication/logical/tablesync.c:1474 replication/logical/worker.c:2641 #, c-format msgid "user \"%s\" cannot replicate into relation with row-level security enabled: \"%s\"" msgstr "Benutzer »%s« kann nicht in eine Relation mit Sicherheit auf Zeilenebene replizieren: »%s«" @@ -27179,221 +26775,211 @@ msgstr "Benutzer »%s« kann nicht in eine Relation mit Sicherheit auf Zeilenebe msgid "table copy could not finish transaction on publisher: %s" msgstr "beim Kopieren der Tabelle konnte die Transaktion auf dem Publikationsserver nicht beenden werden: %s" -#: replication/logical/worker.c:701 +#: replication/logical/worker.c:702 #, c-format msgid "logical replication parallel apply worker for subscription \"%s\" will stop" msgstr "Parallel-Apply-Worker für logische Replikation für Subskription »%s« wird anhalten" -#: replication/logical/worker.c:703 +#: replication/logical/worker.c:704 #, c-format msgid "Cannot handle streamed replication transactions using parallel apply workers until all tables have been synchronized." msgstr "Gestreamte Replikationstransaktionen können erst mit parallelen Apply-Worker-Prozessen verarbeitet werden, wenn alle Tabellen synchronisiert worden sind." -#: replication/logical/worker.c:1046 replication/logical/worker.c:1163 -#: replication/logical/worker.c:2886 +#: replication/logical/worker.c:1047 replication/logical/worker.c:1164 +#: replication/logical/worker.c:2887 #, c-format msgid "logical replication column %d not found in tuple: only %d column(s) received" -msgstr "" +msgstr "Spalte %d für logische Replikation nicht im Tupel gefunden: nur %d Spalte(n) empfangen" -#: replication/logical/worker.c:1085 replication/logical/worker.c:1204 +#: replication/logical/worker.c:1086 replication/logical/worker.c:1205 #, c-format msgid "incorrect binary data format in logical replication column %d" msgstr "falsches Binärdatenformat in Spalte %d in logischer Replikation" -#: replication/logical/worker.c:2787 +#: replication/logical/worker.c:2788 #, c-format msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" msgstr "Publikationsserver hat nicht die Replikidentitätsspalten gesendet, die von Replikationszielrelation »%s.%s« erwartet wurden" -#: replication/logical/worker.c:2794 +#: replication/logical/worker.c:2795 #, c-format msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" msgstr "Zielrelation für logische Replikation »%s.%s« hat weder REPLICA-IDENTITY-Index noch Primärschlüssel und die publizierte Relation hat kein REPLICA IDENTITY FULL" -#: replication/logical/worker.c:3340 +#: replication/logical/worker.c:3341 #, c-format msgid "could not detect conflict as the leader apply worker has exited" -msgstr "" +msgstr "konnte Konflikt nicht erkennen, weil der Leader-Apply-Worker beendet wurde" -#: replication/logical/worker.c:3896 +#: replication/logical/worker.c:3897 #, c-format msgid "invalid logical replication message type \"??? (%d)\"" msgstr "ungültiger Nachrichtentyp für logische Replikation »??? (%d)«" -#: replication/logical/worker.c:4069 +#: replication/logical/worker.c:4070 #, c-format msgid "data stream from publisher has ended" msgstr "Datenstrom vom Publikationsserver endete" -#: replication/logical/worker.c:4272 +#: replication/logical/worker.c:4273 #, c-format msgid "terminating logical replication worker due to timeout" msgstr "Arbeitsprozess für logische Replikation wird abgebrochen wegen Zeitüberschreitung" -#: replication/logical/worker.c:4844 -#, fuzzy, c-format -#| msgid "logical replication worker for subscription \"%s\" will stop because the subscription was disabled" +#: replication/logical/worker.c:4845 +#, c-format msgid "logical replication worker for subscription \"%s\" has stopped retaining the information for detecting conflicts" -msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird anhalten, weil die Subskription deaktiviert wurde" +msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« hat aufgehört, die Informationen zur Konflikterkennung aufzubewahren" -#: replication/logical/worker.c:4846 +#: replication/logical/worker.c:4847 #, c-format msgid "Retention is stopped because the apply process has not caught up with the publisher within the configured max_retention_duration." -msgstr "" +msgstr "Die Aufbewahrung ist gestoppt, weil der Apply-Prozess nicht innerhalb der konfigurierten max_retention_duration mit dem Publikationsserver aufgeholt hat." -#: replication/logical/worker.c:4871 -#, fuzzy, c-format -#| msgid "logical replication worker for subscription \"%s\" will restart because of a parameter change" +#: replication/logical/worker.c:4872 +#, c-format msgid "logical replication worker for subscription \"%s\" will resume retaining the information for detecting conflicts" -msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird neu starten wegen einer Parameteränderung" +msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird das Aufbewahren der Informationen zur Konflikterkennung wieder aufnehmen" -#: replication/logical/worker.c:4874 +#: replication/logical/worker.c:4875 #, c-format msgid "Retention is re-enabled because the apply process has caught up with the publisher within the configured max_retention_duration." -msgstr "" +msgstr "Die Aufbewahrung ist wieder eingeschaltet, weil der Apply-Prozess innerhalb der konfigurierten max_retention_duration mit dem Publikationsserver aufgeholt hat." -#: replication/logical/worker.c:4875 +#: replication/logical/worker.c:4876 #, c-format msgid "Retention is re-enabled because max_retention_duration has been set to unlimited." -msgstr "" +msgstr "Die Aufbewahrung ist wieder eingeschaltet, weil max_retention_duration auf unbegrenzt gesetzt wurde." -#: replication/logical/worker.c:5090 +#: replication/logical/worker.c:5093 #, c-format msgid "logical replication worker for subscription \"%s\" will stop because the subscription was removed" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird anhalten, weil die Subskription entfernt wurde" -#: replication/logical/worker.c:5104 +#: replication/logical/worker.c:5107 #, c-format msgid "logical replication worker for subscription \"%s\" will stop because the subscription was disabled" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird anhalten, weil die Subskription deaktiviert wurde" -#: replication/logical/worker.c:5135 +#: replication/logical/worker.c:5145 #, c-format msgid "logical replication parallel apply worker for subscription \"%s\" will stop because of a parameter change" msgstr "Parallel-Apply-Worker für logische Replikation für Subskription »%s« wird anhalten wegen einer Parameteränderung" -#: replication/logical/worker.c:5139 +#: replication/logical/worker.c:5149 #, c-format msgid "logical replication worker for subscription \"%s\" will restart because of a parameter change" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird neu starten wegen einer Parameteränderung" -#: replication/logical/worker.c:5153 +#: replication/logical/worker.c:5163 #, c-format msgid "logical replication parallel apply worker for subscription \"%s\" will stop because the subscription owner's superuser privileges have been revoked" msgstr "Parallel-Apply-Worker für logische Replikation für Subskription »%s« wird anhalten, weil die Superuser-Privilegien des Eigentümers der Subskription entzogen wurden" -#: replication/logical/worker.c:5157 +#: replication/logical/worker.c:5167 #, c-format msgid "logical replication worker for subscription \"%s\" will restart because the subscription owner's superuser privileges have been revoked" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird neu starten, weil die Superuser-Privilegien des Eigentümers der Subskription entzogen wurden" -#: replication/logical/worker.c:5703 +#: replication/logical/worker.c:5718 #, c-format msgid "subscription has no replication slot set" msgstr "für die Subskription ist kein Replikations-Slot gesetzt" -#: replication/logical/worker.c:5728 +#: replication/logical/worker.c:5743 #, c-format msgid "apply worker for subscription \"%s\" could not connect to the publisher: %s" msgstr "Apply-Worker für Subskription »%s« konnte nicht mit dem Publikationsserver verbinden: %s" -#: replication/logical/worker.c:5835 +#: replication/logical/worker.c:5865 #, c-format msgid "logical replication worker for subscription %u will not start because the subscription was removed during startup" msgstr "Arbeitsprozess für logische Replikation für Subskription %u« wird nicht starten, weil die Subskription während des Starts entfernt wurde" -#: replication/logical/worker.c:5850 +#: replication/logical/worker.c:5878 #, c-format msgid "logical replication worker for subscription \"%s\" will not start because the subscription was disabled during startup" msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird nicht starten, weil die Subskription während des Starts deaktiviert wurde" -#: replication/logical/worker.c:5875 -#, fuzzy, c-format -#| msgid "logical replication worker for subscription \"%s\" will not start because the subscription was disabled during startup" +#: replication/logical/worker.c:5914 +#, c-format msgid "logical replication worker for subscription \"%s\" will restart because the option %s was enabled during startup" -msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird nicht starten, weil die Subskription während des Starts deaktiviert wurde" +msgstr "Arbeitsprozess für logische Replikation für Subskription »%s« wird neu starten, weil die Option %s während des Starts eingeschaltet wurde" -#: replication/logical/worker.c:5918 +#: replication/logical/worker.c:5957 #, c-format msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" msgstr "Arbeitsprozess für logische Replikation für Tabellensynchronisation für Subskription »%s«, Tabelle »%s« hat gestartet" -#: replication/logical/worker.c:5923 -#, fuzzy, c-format -#| msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +#: replication/logical/worker.c:5962 +#, c-format msgid "logical replication sequence synchronization worker for subscription \"%s\" has started" -msgstr "Arbeitsprozess für logische Replikation für Tabellensynchronisation für Subskription »%s«, Tabelle »%s« hat gestartet" +msgstr "Arbeitsprozess für logische Replikation für Sequenzsynchronisation für Subskription »%s« hat gestartet" -#: replication/logical/worker.c:5927 +#: replication/logical/worker.c:5966 #, c-format msgid "logical replication apply worker for subscription \"%s\" has started" msgstr "Apply-Worker für logische Replikation für Subskription »%s« hat gestartet" -#: replication/logical/worker.c:6062 +#: replication/logical/worker.c:6107 #, c-format msgid "subscription \"%s\" has been disabled because of an error" msgstr "Subskription »%s« wurde wegen eines Fehlers deaktiviert" -#: replication/logical/worker.c:6119 -#, fuzzy, c-format -#| msgid "logical replication starts skipping transaction at LSN %X/%X" +#: replication/logical/worker.c:6164 +#, c-format msgid "logical replication starts skipping transaction at LSN %X/%08X" -msgstr "logische Replikation beginnt Überspringen von Transaktion bei %X/%X" +msgstr "logische Replikation beginnt Überspringen von Transaktion bei %X/%08X" -#: replication/logical/worker.c:6133 -#, fuzzy, c-format -#| msgid "logical replication completed skipping transaction at LSN %X/%X" +#: replication/logical/worker.c:6178 +#, c-format msgid "logical replication completed skipping transaction at LSN %X/%08X" -msgstr "logische Replikation beendet Überspringen von Transaktion bei %X/%X" +msgstr "logische Replikation beendet Überspringen von Transaktion bei %X/%08X" -#: replication/logical/worker.c:6221 +#: replication/logical/worker.c:6266 #, c-format msgid "skip-LSN of subscription \"%s\" cleared" msgstr "Skip-LSN von Subskription »%s« gelöscht" -#: replication/logical/worker.c:6222 -#, fuzzy, c-format -#| msgid "Remote transaction's finish WAL location (LSN) %X/%X did not match skip-LSN %X/%X." +#: replication/logical/worker.c:6267 +#, c-format msgid "Remote transaction's finish WAL location (LSN) %X/%08X did not match skip-LSN %X/%08X." -msgstr "Die WAL-Endposition (LSN) %X/%X der Remote-Transaktion stimmte nicht mit der Skip-LSN %X/%X überein." +msgstr "Die WAL-Endposition (LSN) %X/%08X der Remote-Transaktion stimmte nicht mit der Skip-LSN %X/%08X überein." -#: replication/logical/worker.c:6250 +#: replication/logical/worker.c:6295 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\"" msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s«" -#: replication/logical/worker.c:6254 +#: replication/logical/worker.c:6299 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" in transaction %u" msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« in Transaktion %u" -#: replication/logical/worker.c:6259 -#, fuzzy, c-format -#| msgid "processing remote data for replication origin \"%s\" during message type \"%s\" in transaction %u, finished at %X/%X" +#: replication/logical/worker.c:6304 +#, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" in transaction %u, finished at %X/%08X" -msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« in Transaktion %u, beendet bei %X/%X" +msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« in Transaktion %u, beendet bei %X/%08X" -#: replication/logical/worker.c:6270 +#: replication/logical/worker.c:6315 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" in transaction %u" msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« für Replikationszielrelation »%s.%s« in Transaktion %u" -#: replication/logical/worker.c:6277 -#, fuzzy, c-format -#| msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" in transaction %u, finished at %X/%X" +#: replication/logical/worker.c:6322 +#, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" in transaction %u, finished at %X/%08X" -msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« für Replikationszielrelation »%s.%s« in Transaktion %u, beendet bei %X/%X" +msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« für Replikationszielrelation »%s.%s« in Transaktion %u, beendet bei %X/%08X" -#: replication/logical/worker.c:6288 +#: replication/logical/worker.c:6333 #, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" column \"%s\" in transaction %u" msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« für Replikationszielrelation »%s.%s« Spalte »%s« in Transaktion %u" -#: replication/logical/worker.c:6296 -#, fuzzy, c-format -#| msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" column \"%s\" in transaction %u, finished at %X/%X" +#: replication/logical/worker.c:6341 +#, c-format msgid "processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" column \"%s\" in transaction %u, finished at %X/%08X" -msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« für Replikationszielrelation »%s.%s« Spalte »%s« in Transaktion %u, beendet bei %X/%X" +msgstr "Verarbeiten empfangener Daten für Replication-Origin »%s« bei Nachrichtentyp »%s« für Replikationszielrelation »%s.%s« Spalte »%s« in Transaktion %u, beendet bei %X/%08X" #: replication/pgoutput/pgoutput.c:331 #, c-format @@ -27471,22 +27057,19 @@ msgid "Create the publication if it does not exist." msgstr "Erzeugen Sie die Publikation, wenn sie nicht existiert." #: replication/pgrepack/pgrepack.c:59 -#, fuzzy, c-format -#| msgid "starting logical decoding for slot \"%s\"" +#, c-format msgid "unsupported use of logical decoding plugin \"%s\"" -msgstr "starte logisches Dekodieren für Slot »%s«" +msgstr "nicht unterstützte Verwendung des Plugins »%s« für logisches Dekodieren" #: replication/pgrepack/pgrepack.c:61 -#, fuzzy, c-format -#| msgid "option %s can only be used with %s" +#, c-format msgid "This plugin can only be used by %s." -msgstr "Option %s kann nur mit %s verwendet werden" +msgstr "Dieses Plugin kann nur von %s verwendet werden." #: replication/pgrepack/pgrepack.c:80 -#, fuzzy, c-format -#| msgid "this build does not support compression with %s" +#, c-format msgid "this plugin does not expect any options" -msgstr "diese Installation unterstützt keine Komprimierung mit %s" +msgstr "dieses Plugin erwartet keine Optionen" #: replication/slot.c:318 #, c-format @@ -27508,361 +27091,349 @@ msgid "Replication slot names may only contain lower case letters, numbers, and msgstr "Replikations-Slot-Namen dürfen nur Kleinbuchstaben, Zahlen und Unterstriche enthalten." #: replication/slot.c:347 -#, fuzzy, c-format -#| msgid "replication origin name \"%s\" is reserved" +#, c-format msgid "replication slot name \"%s\" is reserved" -msgstr "Replication-Origin-Name »%s« ist reserviert" +msgstr "Replikations-Slot-Name »%s« ist reserviert" #: replication/slot.c:348 -#, fuzzy, c-format -#| msgid "The prefix \"pg_\" is reserved for system schemas." +#, c-format msgid "The name \"%s\" is reserved for the conflict detection slot." -msgstr "Der Präfix »pg_« ist für Systemschemas reserviert." +msgstr "Der Name »%s« ist für den Slot zur Konflikterkennung reserviert." #: replication/slot.c:408 #, c-format msgid "cannot enable failover for a replication slot created on the standby" msgstr "Failover kann nicht für einen auf dem Standby erzeugten Replikations-Slot eingeschaltet werden" -#: replication/slot.c:420 replication/slot.c:994 +#: replication/slot.c:420 replication/slot.c:996 #, c-format msgid "cannot enable failover for a temporary replication slot" msgstr "Failover kann nicht für einen temporären Replikations-Slot eingeschaltet werden" -#: replication/slot.c:449 +#: replication/slot.c:451 #, c-format msgid "replication slot \"%s\" already exists" msgstr "Replikations-Slot »%s« existiert bereits" -#: replication/slot.c:461 +#: replication/slot.c:463 #, c-format msgid "all replication slots are in use" msgstr "alle Replikations-Slots sind in Benutzung" -#: replication/slot.c:462 -#, fuzzy, c-format -#| msgid "Free one or increase \"max_replication_slots\"." +#: replication/slot.c:464 +#, c-format msgid "Free one or increase \"%s\"." -msgstr "Geben Sie einen frei oder erhöhen Sie »max_replication_slots«." +msgstr "Geben Sie einen frei oder erhöhen Sie »%s«." -#: replication/slot.c:650 replication/slotfuncs.c:689 +#: replication/slot.c:652 replication/slotfuncs.c:698 #: utils/activity/pgstat_replslot.c:55 utils/adt/genfile.c:740 #, c-format msgid "replication slot \"%s\" does not exist" msgstr "Replikations-Slot »%s« existiert nicht" -#: replication/slot.c:662 -#, fuzzy, c-format -#| msgid "cannot alter replication slot \"%s\"" +#: replication/slot.c:664 +#, c-format msgid "cannot acquire replication slot \"%s\"" -msgstr "Replikations-Slot »%s« kann nicht geändert werden" +msgstr "kann Replikations-Slot »%s« nicht akquirieren" -#: replication/slot.c:663 +#: replication/slot.c:665 #, c-format msgid "The slot is reserved for conflict detection and can only be acquired by logical replication launcher." -msgstr "" +msgstr "Der Slot ist für Konflikterkennung reserviert und kann nur vom Launcher für logische Replikation belegt werden." -#: replication/slot.c:717 replication/slot.c:1592 +#: replication/slot.c:719 replication/slot.c:1594 #, c-format msgid "replication slot \"%s\" is active for PID %d" msgstr "Replikations-Slot »%s« ist aktiv für PID %d" -#: replication/slot.c:734 +#: replication/slot.c:736 #, c-format msgid "can no longer access replication slot \"%s\"" msgstr "auf Replikations-Slot »%s« kann nicht mehr zugegriffen werden" -#: replication/slot.c:736 +#: replication/slot.c:738 #, c-format msgid "This replication slot has been invalidated due to \"%s\"." msgstr "Dieser Replikations-Slot wurde wegen »%s« ungültig gemacht." -#: replication/slot.c:755 +#: replication/slot.c:757 #, c-format msgid "acquired logical replication slot \"%s\"" msgstr "logischer Replikations-Slot »%s« wurde akquiriert" -#: replication/slot.c:757 +#: replication/slot.c:759 #, c-format msgid "acquired physical replication slot \"%s\"" msgstr "physischer Replikations-Slot »%s« wurde akquiriert" -#: replication/slot.c:842 +#: replication/slot.c:844 #, c-format msgid "released logical replication slot \"%s\"" msgstr "logischer Replikations-Slot »%s« wurde freigegeben" -#: replication/slot.c:844 +#: replication/slot.c:846 #, c-format msgid "released physical replication slot \"%s\"" msgstr "physischer Replikations-Slot »%s« wurde freigegeben" -#: replication/slot.c:926 +#: replication/slot.c:928 #, c-format msgid "cannot drop replication slot \"%s\"" msgstr "kann Replikations-Slot »%s« nicht löschen" -#: replication/slot.c:959 +#: replication/slot.c:961 #, c-format msgid "cannot use %s with a physical replication slot" msgstr "%s kann nicht mit einem physischem Replikations-Slot verwendet werden" -#: replication/slot.c:971 +#: replication/slot.c:973 #, c-format msgid "cannot alter replication slot \"%s\"" msgstr "Replikations-Slot »%s« kann nicht geändert werden" -#: replication/slot.c:981 +#: replication/slot.c:983 #, c-format msgid "cannot enable failover for a replication slot on the standby" msgstr "Failover kann nicht für einen Replikations-Slot auf dem Standby eingeschaltet werden" -#: replication/slot.c:1139 replication/slot.c:2429 replication/slot.c:2822 +#: replication/slot.c:1141 replication/slot.c:2431 replication/slot.c:2824 #, c-format msgid "could not remove directory \"%s\"" msgstr "konnte Verzeichnis »%s« nicht löschen" -#: replication/slot.c:1671 -#, fuzzy, c-format -#| msgid "replication slots can only be used if \"max_replication_slots\" > 0" +#: replication/slot.c:1673 +#, c-format msgid "replication slots can only be used if \"%s\" > 0" -msgstr "Replikations-Slots können nur verwendet werden, wenn »max_replication_slots« > 0" +msgstr "Replikations-Slots können nur verwendet werden, wenn »%s« > 0" -#: replication/slot.c:1677 -#, fuzzy, c-format -#| msgid "option %s can only be used with %s" +#: replication/slot.c:1679 +#, c-format msgid "REPACK can only be used if \"%s\" > 0" -msgstr "Option %s kann nur mit %s verwendet werden" +msgstr "REPACK kann nur verwendet werden, wenn »%s« > 0" -#: replication/slot.c:1683 +#: replication/slot.c:1685 #, c-format msgid "replication slots can only be used if \"wal_level\" >= \"replica\"" msgstr "Replikations-Slots können nur verwendet werden, wenn »wal_level« >= replica" -#: replication/slot.c:1695 +#: replication/slot.c:1697 #, c-format msgid "permission denied to use replication slots" msgstr "keine Berechtigung, um Replikations-Slots zu verwenden" -#: replication/slot.c:1696 +#: replication/slot.c:1698 #, c-format msgid "Only roles with the %s attribute may use replication slots." msgstr "Nur Rollen mit dem %s-Attribut können Replikations-Slots verwenden." -#: replication/slot.c:1808 -#, fuzzy, c-format -#| msgid "The slot's restart_lsn %X/%X exceeds the limit by % byte." -#| msgid_plural "The slot's restart_lsn %X/%X exceeds the limit by % bytes." +#: replication/slot.c:1810 +#, c-format msgid "The slot's restart_lsn %X/%08X exceeds the limit by % byte." msgid_plural "The slot's restart_lsn %X/%08X exceeds the limit by % bytes." -msgstr[0] "Die restart_lsn des Slots %X/%X überschreitet das Maximum um % Byte." -msgstr[1] "Die restart_lsn des Slots %X/%X überschreitet das Maximum um % Bytes." +msgstr[0] "Die restart_lsn des Slots %X/%08X überschreitet das Maximum um % Byte." +msgstr[1] "Die restart_lsn des Slots %X/%08X überschreitet das Maximum um % Bytes." -#: replication/slot.c:1819 +#: replication/slot.c:1821 #, c-format msgid "The slot conflicted with xid horizon %u." msgstr "Der Slot kollidierte mit dem xid-Horizont %u." -#: replication/slot.c:1824 -#, fuzzy -#| msgid "Logical decoding on standby requires \"wal_level\" >= \"logical\" on the primary server." +#: replication/slot.c:1826 msgid "Logical decoding on standby requires the primary server to either set \"wal_level\" >= \"logical\" or have at least one logical slot when \"wal_level\" = \"replica\"." -msgstr "Logische Dekodierung auf dem Standby-Server erfordert »wal_level« >= »logical« auf dem Primärserver." +msgstr "Logische Dekodierung auf dem Standby-Server erfordert, dass der Primärserver entweder »wal_level« >= »logical« setzt oder mindestens einen logischen Slot hat, wenn »wal_level« = »replica«." #. translator: %s is a GUC variable name -#: replication/slot.c:1830 +#: replication/slot.c:1832 #, c-format msgid "The slot's idle time of %lds exceeds the configured \"%s\" duration of %ds." msgstr "Die Leerlaufzeit des Slots von %lds überschreitet die durch »%s« konfigurierte Dauer von %ds." -#: replication/slot.c:1844 +#: replication/slot.c:1846 #, c-format msgid "terminating process %d to release replication slot \"%s\"" msgstr "Prozess %d wird beendet, um Replikations-Slot »%s« freizugeben" -#: replication/slot.c:1846 +#: replication/slot.c:1848 #, c-format msgid "invalidating obsolete replication slot \"%s\"" msgstr "obsoleter Replikations-Slot »%s« wird ungültig gemacht" -#: replication/slot.c:2760 +#: replication/slot.c:2762 #, c-format msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" msgstr "Replikations-Slot-Datei »%s« hat falsche magische Zahl: %u statt %u" -#: replication/slot.c:2767 +#: replication/slot.c:2769 #, c-format msgid "replication slot file \"%s\" has unsupported version %u" msgstr "Replikations-Slot-Datei »%s« hat nicht unterstützte Version %u" -#: replication/slot.c:2774 +#: replication/slot.c:2776 #, c-format msgid "replication slot file \"%s\" has corrupted length %u" msgstr "Replikations-Slot-Datei »%s« hat falsche Länge %u" -#: replication/slot.c:2810 +#: replication/slot.c:2812 #, c-format msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" msgstr "Prüfsummenfehler bei Replikations-Slot-Datei »%s«: ist %u, sollte %u sein" -#: replication/slot.c:2846 -#, fuzzy, c-format -#| msgid "logical replication slot \"%s\" exists, but \"wal_level\" < \"logical\"" +#: replication/slot.c:2848 +#, c-format msgid "logical replication slot \"%s\" exists, but \"wal_level\" < \"replica\"" -msgstr "logischer Replikations-Slot »%s« existiert, aber »wal_level« < »logical«" +msgstr "logischer Replikations-Slot »%s« existiert, aber »wal_level« < »replica«" -#: replication/slot.c:2848 replication/slot.c:2870 +#: replication/slot.c:2850 replication/slot.c:2872 #, c-format msgid "Change \"wal_level\" to be \"replica\" or higher." msgstr "Ändern Sie »wal_level« in »replica« oder höher." -#: replication/slot.c:2861 +#: replication/slot.c:2863 #, c-format msgid "logical replication slot \"%s\" exists on the standby, but \"hot_standby\" = \"off\"" msgstr "logischer Replikations-Slot »%s« existiert auf dem Standby, aber »hot_standby« = »off«" -#: replication/slot.c:2863 +#: replication/slot.c:2865 #, c-format msgid "Change \"hot_standby\" to be \"on\"." msgstr "Ändern Sie »hot_standby« auf »on«." -#: replication/slot.c:2868 +#: replication/slot.c:2870 #, c-format msgid "physical replication slot \"%s\" exists, but \"wal_level\" < \"replica\"" msgstr "physischer Replikations-Slot »%s« existiert, aber »wal_level« < »replica«" -#: replication/slot.c:2923 +#: replication/slot.c:2925 #, c-format msgid "too many replication slots active before shutdown" msgstr "zu viele aktive Replikations-Slots vor dem Herunterfahren" -#: replication/slot.c:2924 +#: replication/slot.c:2926 #, c-format msgid "Increase \"max_replication_slots\" and try again." msgstr "Erhöhen Sie »max_replication_slots« und versuchen Sie es erneut." -#: replication/slot.c:3161 +#: replication/slot.c:3163 #, c-format msgid "replication slot \"%s\" specified in parameter \"%s\" does not exist" msgstr "Replikations-Slot »%s«, der in Parameter »%s« angegeben ist, existiert nicht" -#: replication/slot.c:3163 replication/slot.c:3197 replication/slot.c:3212 +#: replication/slot.c:3165 replication/slot.c:3199 replication/slot.c:3214 #, c-format msgid "Logical replication is waiting on the standby associated with replication slot \"%s\"." msgstr "Logische Replikation wartet auf den Standby, der zum Replikations-Slot »%s« gehört." -#: replication/slot.c:3165 +#: replication/slot.c:3167 #, c-format msgid "Create the replication slot \"%s\" or amend parameter \"%s\"." msgstr "Erzeugen Sie den Replikations-Slot »%s« oder berichtigen Sie den Parameter »%s«." -#: replication/slot.c:3175 +#: replication/slot.c:3177 #, c-format msgid "cannot specify logical replication slot \"%s\" in parameter \"%s\"" msgstr "logischer Replikations-Slot »%s« kann nicht in Parameter »%s« angegeben werden" -#: replication/slot.c:3177 +#: replication/slot.c:3179 #, c-format msgid "Logical replication is waiting for correction on replication slot \"%s\"." msgstr "Logische Replikation wartet auf Korrektur bei Replikations-Slot »%s«." -#: replication/slot.c:3179 +#: replication/slot.c:3181 #, c-format msgid "Remove the logical replication slot \"%s\" from parameter \"%s\"." msgstr "Entfernen Sie den Replikations-Slot »%s« aus dem Parameter »%s«." -#: replication/slot.c:3195 +#: replication/slot.c:3197 #, c-format msgid "physical replication slot \"%s\" specified in parameter \"%s\" has been invalidated" msgstr "der physische Replikations-Slot »%s«, der in Parameter »%s« angegeben wurde, wurde ungültig gemacht" -#: replication/slot.c:3199 +#: replication/slot.c:3201 #, c-format msgid "Drop and recreate the replication slot \"%s\", or amend parameter \"%s\"." msgstr "Löschen Sie den Replikations-Slot »%s« und erzeugen Sie ihn neu, oder berichtigen Sie den Parameter »%s«." -#: replication/slot.c:3210 +#: replication/slot.c:3212 #, c-format msgid "replication slot \"%s\" specified in parameter \"%s\" does not have active_pid" msgstr "der Replikations-Slot »%s«, der in Parameter »%s« angegeben wurde, hat keine active_pid" -#: replication/slot.c:3214 +#: replication/slot.c:3216 #, c-format msgid "Start the standby associated with the replication slot \"%s\", or amend parameter \"%s\"." msgstr "Starten Sie den zum Replikations-Slot »%s« gehörenden Standby oder berichtigen Sie den Parameter »%s«." -#: replication/slotfuncs.c:554 +#: replication/slotfuncs.c:563 #, c-format msgid "invalid target WAL LSN" msgstr "ungültige Ziel-WAL-LSN" -#: replication/slotfuncs.c:576 +#: replication/slotfuncs.c:585 #, c-format msgid "replication slot \"%s\" cannot be advanced" msgstr "Replikations-Slot »%s« kann nicht vorwärtsgesetzt werden" -#: replication/slotfuncs.c:578 +#: replication/slotfuncs.c:587 #, c-format msgid "This slot has never previously reserved WAL, or it has been invalidated." msgstr "Diese Slot hat nie zuvor WAL reserviert oder er wurde ungültig gemacht." -#: replication/slotfuncs.c:594 -#, fuzzy, c-format -#| msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +#: replication/slotfuncs.c:603 +#, c-format msgid "cannot advance replication slot to %X/%08X, minimum is %X/%08X" -msgstr "Replikations-Slot kann nicht auf %X/%X vorwärtsgesetzt werden, Minimum ist %X/%X" +msgstr "Replikations-Slot kann nicht auf %X/%08X vorwärtsgesetzt werden, Minimum ist %X/%08X" -#: replication/slotfuncs.c:701 +#: replication/slotfuncs.c:710 #, c-format msgid "cannot copy physical replication slot \"%s\" as a logical replication slot" msgstr "physischer Replikations-Slot »%s« kann nicht als logischer Replikations-Slot kopiert werden" -#: replication/slotfuncs.c:703 +#: replication/slotfuncs.c:712 #, c-format msgid "cannot copy logical replication slot \"%s\" as a physical replication slot" msgstr "logischer Replikations-Slot »%s« kann nicht als physischer Replikations-Slot kopiert werden" -#: replication/slotfuncs.c:710 +#: replication/slotfuncs.c:719 #, c-format msgid "cannot copy a replication slot that doesn't reserve WAL" msgstr "ein Replikations-Slot, der kein WAL reserviert, kann nicht kopiert werden" -#: replication/slotfuncs.c:716 +#: replication/slotfuncs.c:725 #, c-format msgid "cannot copy invalidated replication slot \"%s\"" msgstr "ungültig gemachter Replikations-Slot »%s« kann nicht kopiert werden" -#: replication/slotfuncs.c:808 +#: replication/slotfuncs.c:817 #, c-format msgid "could not copy replication slot \"%s\"" msgstr "konnte Replikations-Slot »%s« nicht kopieren" -#: replication/slotfuncs.c:810 +#: replication/slotfuncs.c:819 #, c-format msgid "The source replication slot was modified incompatibly during the copy operation." msgstr "Der Quell-Replikations-Slot wurde während der Kopieroperation inkompatibel geändert." -#: replication/slotfuncs.c:816 +#: replication/slotfuncs.c:825 #, c-format msgid "cannot copy unfinished logical replication slot \"%s\"" msgstr "kann unfertigen Replikations-Slot »%s« nicht kopieren" -#: replication/slotfuncs.c:818 +#: replication/slotfuncs.c:827 #, c-format msgid "Retry when the source replication slot's confirmed_flush_lsn is valid." msgstr "Versuchen Sie es erneut, wenn confirmed_flush_lsn des Quell-Replikations-Slots gültig ist." -#: replication/slotfuncs.c:830 +#: replication/slotfuncs.c:839 #, c-format msgid "cannot copy replication slot \"%s\"" msgstr "kann Replikations-Slot »%s« nicht kopieren" -#: replication/slotfuncs.c:832 +#: replication/slotfuncs.c:841 #, c-format msgid "The source replication slot was invalidated during the copy operation." msgstr "Der Quell-Replikations-Slot wurde während der Kopieroperation ungültig gemacht." -#: replication/slotfuncs.c:931 +#: replication/slotfuncs.c:940 #, c-format msgid "replication slots can only be synchronized to a standby server" msgstr "Replikations-Slots können nur zu einem Standby-Server synchronisiert werden" @@ -27879,10 +27450,9 @@ msgid "The transaction has already committed locally, but might not have been re msgstr "Die Transaktion wurde lokal bereits committet, aber möglicherweise noch nicht zum Standby repliziert." #: replication/syncrep.c:308 -#, fuzzy, c-format -#| msgid "The transaction has already committed locally, but might not have been replicated to the standby." +#, c-format msgid "The transaction has already committed locally, but might not have been replicated to the standby. Signal sent by PID %d, UID %d." -msgstr "Die Transaktion wurde lokal bereits committet, aber möglicherweise noch nicht zum Standby repliziert." +msgstr "Die Transaktion wurde lokal bereits committet, aber möglicherweise noch nicht zum Standby repliziert. Signal gesendet von PID %d, UID %d." #: replication/syncrep.c:331 #, c-format @@ -27910,79 +27480,85 @@ msgstr "Parser für »%s« fehlgeschlagen." msgid "number of synchronous standbys (%d) must be greater than zero" msgstr "Anzahl synchroner Standbys (%d) muss größer als null sein" -#: replication/walreceiver.c:290 +#: replication/walreceiver.c:293 #, c-format msgid "streaming replication receiver \"%s\" could not connect to the primary server: %s" msgstr "Streaming-Replication-Receiver »%s« konnte nicht mit dem Primärserver verbinden: %s" -#: replication/walreceiver.c:335 +#: replication/walreceiver.c:340 #, c-format msgid "database system identifier differs between the primary and standby" msgstr "Datenbanksystemidentifikator unterscheidet sich zwischen Primär- und Standby-Server" -#: replication/walreceiver.c:336 +#: replication/walreceiver.c:341 #, c-format msgid "The primary's identifier is %s, the standby's identifier is %s." msgstr "Identifikator des Primärservers ist %s, Identifikator des Standby ist %s." -#: replication/walreceiver.c:348 +#: replication/walreceiver.c:353 #, c-format msgid "highest timeline %u of the primary is behind recovery timeline %u" msgstr "höchste Zeitleiste %u des primären Servers liegt hinter Wiederherstellungszeitleiste %u zurück" -#: replication/walreceiver.c:401 -#, fuzzy, c-format -#| msgid "started streaming WAL from primary at %X/%X on timeline %u" +#: replication/walreceiver.c:395 +#, c-format +msgid "walreceiver requested start point %X/%08X on timeline %u is ahead of the upstream server's flush position %X/%08X, waiting" +msgstr "vom Walreceiver angeforderter Startpunkt %X/%08X auf Zeitleiste %u ist der Flush-Position %X/%08X des Upstream-Servers voraus, warte" + +#: replication/walreceiver.c:410 +#, c-format +msgid "terminating walreceiver due to timeout while waiting for upstream to catch up" +msgstr "WAL-Receiver-Prozess wird abgebrochen wegen Zeitüberschreitung beim Warten, dass der Upstream-Server aufholt" + +#: replication/walreceiver.c:471 +#, c-format msgid "started streaming WAL from primary at %X/%08X on timeline %u" -msgstr "WAL-Streaming vom Primärserver gestartet bei %X/%X auf Zeitleiste %u" +msgstr "WAL-Streaming vom Primärserver gestartet bei %X/%08X auf Zeitleiste %u" -#: replication/walreceiver.c:405 -#, fuzzy, c-format -#| msgid "restarted WAL streaming at %X/%X on timeline %u" +#: replication/walreceiver.c:475 +#, c-format msgid "restarted WAL streaming at %X/%08X on timeline %u" -msgstr "WAL-Streaming neu gestartet bei %X/%X auf Zeitleiste %u" +msgstr "WAL-Streaming neu gestartet bei %X/%08X auf Zeitleiste %u" -#: replication/walreceiver.c:450 +#: replication/walreceiver.c:520 #, c-format msgid "cannot continue WAL streaming, recovery has already ended" msgstr "kann WAL-Streaming nicht fortsetzen, Wiederherstellung ist bereits beendet" -#: replication/walreceiver.c:494 +#: replication/walreceiver.c:564 #, c-format msgid "replication terminated by primary server" msgstr "Replikation wurde durch Primärserver beendet" -#: replication/walreceiver.c:495 -#, fuzzy, c-format -#| msgid "End of WAL reached on timeline %u at %X/%X." +#: replication/walreceiver.c:565 +#, c-format msgid "End of WAL reached on timeline %u at %X/%08X." -msgstr "WAL-Ende erreicht auf Zeitleiste %u bei %X/%X." +msgstr "WAL-Ende erreicht auf Zeitleiste %u bei %X/%08X." -#: replication/walreceiver.c:595 +#: replication/walreceiver.c:665 #, c-format msgid "terminating walreceiver due to timeout" msgstr "WAL-Receiver-Prozess wird abgebrochen wegen Zeitüberschreitung" -#: replication/walreceiver.c:627 +#: replication/walreceiver.c:697 #, c-format msgid "primary server contains no more WAL on requested timeline %u" msgstr "Primärserver enthält kein WAL mehr auf angeforderter Zeitleiste %u" -#: replication/walreceiver.c:643 replication/walreceiver.c:1098 +#: replication/walreceiver.c:713 replication/walreceiver.c:1168 #, c-format msgid "could not close WAL segment %s: %m" msgstr "konnte WAL-Segment %s nicht schließen: %m" -#: replication/walreceiver.c:762 +#: replication/walreceiver.c:832 #, c-format msgid "fetching timeline history file for timeline %u from primary server" msgstr "hole Zeitleisten-History-Datei für Zeitleiste %u vom Primärserver" -#: replication/walreceiver.c:971 -#, fuzzy, c-format -#| msgid "could not write to WAL segment %s at offset %d, length %lu: %m" +#: replication/walreceiver.c:1041 +#, c-format msgid "could not write to WAL segment %s at offset %d, length %d: %m" -msgstr "konnte nicht in WAL-Segment %s bei Position %d, Länge %lu schreiben: %m" +msgstr "konnte nicht in WAL-Segment %s bei Position %d, Länge %d schreiben: %m" #: replication/walsender.c:553 #, c-format @@ -28005,22 +27581,19 @@ msgid "cannot use a logical replication slot for physical replication" msgstr "logischer Replikations-Slot kann nicht für physische Replikation verwendet werden" #: replication/walsender.c:944 -#, fuzzy, c-format -#| msgid "requested starting point %X/%X on timeline %u is not in this server's history" +#, c-format msgid "requested starting point %X/%08X on timeline %u is not in this server's history" -msgstr "angeforderter Startpunkt %X/%X auf Zeitleiste %u ist nicht in der History dieses Servers" +msgstr "angeforderter Startpunkt %X/%08X auf Zeitleiste %u ist nicht in der History dieses Servers" #: replication/walsender.c:947 -#, fuzzy, c-format -#| msgid "This server's history forked from timeline %u at %X/%X." +#, c-format msgid "This server's history forked from timeline %u at %X/%08X." -msgstr "Die History dieses Servers zweigte von Zeitleiste %u bei %X/%X ab." +msgstr "Die History dieses Servers zweigte von Zeitleiste %u bei %X/%08X ab." #: replication/walsender.c:991 -#, fuzzy, c-format -#| msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" +#, c-format msgid "requested starting point %X/%08X is ahead of the WAL flush position of this server %X/%08X" -msgstr "angeforderter Startpunkt %X/%X ist vor der WAL-Flush-Position dieses Servers %X/%X" +msgstr "angeforderter Startpunkt %X/%08X ist vor der WAL-Flush-Position dieses Servers %X/%08X" #. translator: %s is a CREATE_REPLICATION_SLOT statement #: replication/walsender.c:1315 @@ -28058,63 +27631,62 @@ msgstr "%s muss vor allen Anfragen aufgerufen werden" msgid "%s must not be called in a subtransaction" msgstr "%s darf nicht in einer Subtransaktion aufgerufen werden" -#: replication/walsender.c:1534 +#: replication/walsender.c:1536 #, c-format msgid "terminating walsender process after promotion" msgstr "WAL-Sender-Prozess wird nach Beförderung abgebrochen" -#: replication/walsender.c:2113 +#: replication/walsender.c:2115 #, c-format msgid "cannot execute new commands while WAL sender is in stopping mode" msgstr "während der WAL-Sender im Stoppmodus ist können keine neuen Befehle ausgeführt werden" -#: replication/walsender.c:2167 +#: replication/walsender.c:2169 #, c-format msgid "cannot execute SQL commands in WAL sender for physical replication" msgstr "im WAL-Sender für physische Replikation können keine SQL-Befehle ausgeführt werden" -#: replication/walsender.c:2198 +#: replication/walsender.c:2200 #, c-format msgid "received replication command: %s" msgstr "Replikationsbefehl empfangen: %s" -#: replication/walsender.c:2206 tcop/fastpath.c:208 tcop/postgres.c:1155 +#: replication/walsender.c:2208 tcop/fastpath.c:208 tcop/postgres.c:1155 #: tcop/postgres.c:1511 tcop/postgres.c:1762 tcop/postgres.c:2266 #: tcop/postgres.c:2688 tcop/postgres.c:2764 #, c-format msgid "current transaction is aborted, commands ignored until end of transaction block" msgstr "aktuelle Transaktion wurde abgebrochen, Befehle werden bis zum Ende der Transaktion ignoriert" -#: replication/walsender.c:2366 replication/walsender.c:2401 +#: replication/walsender.c:2368 replication/walsender.c:2403 #, c-format msgid "unexpected EOF on standby connection" msgstr "unerwartetes EOF auf Standby-Verbindung" -#: replication/walsender.c:2389 +#: replication/walsender.c:2391 #, c-format msgid "invalid standby message type \"%c\"" msgstr "ungültiger Standby-Message-Typ »%c«" -#: replication/walsender.c:2485 +#: replication/walsender.c:2487 #, c-format msgid "unexpected message type \"%c\"" msgstr "unerwarteter Message-Typ »%c«" -#: replication/walsender.c:2983 +#: replication/walsender.c:2985 #, c-format msgid "terminating walsender process due to replication timeout" msgstr "WAL-Sender-Prozess wird abgebrochen wegen Zeitüberschreitung bei der Replikation" -#: replication/walsender.c:3776 -#, fuzzy, c-format -#| msgid "terminating walsender process due to replication timeout" +#: replication/walsender.c:3778 +#, c-format msgid "terminating walsender process due to replication shutdown timeout" -msgstr "WAL-Sender-Prozess wird abgebrochen wegen Zeitüberschreitung bei der Replikation" +msgstr "WAL-Sender-Prozess wird abgebrochen wegen Zeitüberschreitung beim Herunterfahren der Replikation" -#: replication/walsender.c:3777 +#: replication/walsender.c:3779 #, c-format msgid "Walsender process might have been terminated before all WAL data was replicated to the receiver." -msgstr "" +msgstr "Der Walsender-Prozess wurde möglicherweise beendet, bevor alle WAL-Daten zum Empfänger repliziert wurden." #: rewrite/rewriteDefine.c:104 rewrite/rewriteDefine.c:819 #, c-format @@ -28295,30 +27867,28 @@ msgstr "Umbenennen einer ON-SELECT-Regel ist nicht erlaubt" #: rewrite/rewriteGraphTable.c:212 #, c-format msgid "element patterns with same variable name \"%s\" but different element pattern types" -msgstr "" +msgstr "Elementmuster mit gleichem Variablennamen »%s« aber verschiedenen Elementmustertypen" #: rewrite/rewriteGraphTable.c:229 -#, fuzzy, c-format -#| msgid "using variable \"%s\" in different declare statements is not supported" +#, c-format msgid "element patterns with same variable name \"%s\" but different label expressions are not supported" -msgstr "Verwendung der Variable »%s« in verschiedenen DECLARE-Anweisungen wird nicht unterstützt" +msgstr "Elementmuster mit gleichem Variablennamen »%s« aber verschiedenen Label-Ausdrücken werden nicht unterstützt" #: rewrite/rewriteGraphTable.c:292 rewrite/rewriteGraphTable.c:301 #: rewrite/rewriteGraphTable.c:316 rewrite/rewriteGraphTable.c:325 #, c-format msgid "an edge cannot connect more than two vertices even in a cyclic pattern" -msgstr "" +msgstr "eine Kante kann nicht mehr als zwei Knoten verbinden, auch nicht in einem zyklischen Muster" #: rewrite/rewriteGraphTable.c:990 #, c-format msgid "no property graph element of type \"%s\" has label \"%s\" associated with it in property graph \"%s\"" -msgstr "" +msgstr "kein Property-Graph-Element vom Typ »%s« hat Label »%s« zugeordnet in Property-Graph »%s«" #: rewrite/rewriteGraphTable.c:1145 -#, fuzzy, c-format -#| msgid "policy \"%s\" for table \"%s\" does not exist" +#, c-format msgid "property \"%s\" for element variable \"%s\" not found" -msgstr "Policy »%s« für Tabelle »%s« existiert nicht" +msgstr "Property »%s« für Elementvariable »%s« nicht gefunden" #: rewrite/rewriteHandler.c:591 #, c-format @@ -28333,7 +27903,7 @@ msgstr "INSERT ... SELECT-Regelaktionen werden für Anfrangen mit datenmodifizie #: rewrite/rewriteHandler.c:707 #, c-format msgid "A rule action is INSERT ... ON CONFLICT DO SELECT, which requires a RETURNING clause." -msgstr "" +msgstr "Eine Regelaktion ist INSERT ... ON CONFLICT DO SELECT, was eine RETURNING-Klausel erfordert." #: rewrite/rewriteHandler.c:722 #, c-format @@ -28375,7 +27945,7 @@ msgstr "MERGE wird für Relationen mit Regeln nicht unterstützt." msgid "access to non-system view \"%s\" is restricted" msgstr "Zugriff auf Nicht-System-Sicht »%s« ist beschränkt" -#: rewrite/rewriteHandler.c:2192 rewrite/rewriteHandler.c:4496 +#: rewrite/rewriteHandler.c:2192 rewrite/rewriteHandler.c:4504 #, c-format msgid "infinite recursion detected in rules for relation \"%s\"" msgstr "unendliche Rekursion entdeckt in Regeln für Relation »%s«" @@ -28511,10 +28081,9 @@ msgid "cannot merge into column \"%s\" of view \"%s\"" msgstr "kann nicht in Spalte »%s« von Sicht »%s« mergen" #: rewrite/rewriteHandler.c:3518 -#, fuzzy, c-format -#| msgid "cannot delete from view \"%s\"" +#, c-format msgid "cannot delete from view \"%s\" using FOR PORTION OF \"%s\"" -msgstr "kann nicht aus Sicht »%s« löschen" +msgstr "kann nicht aus Sicht »%s« mit FOR PORTION OF »%s« löschen" #: rewrite/rewriteHandler.c:3546 #, c-format @@ -28556,46 +28125,51 @@ msgstr "DO-ALSO-Regeln werden für datenmodifizierende Anweisungen in WITH nicht msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "DO-INSTEAD-Regeln mit mehreren Anweisungen werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" -#: rewrite/rewriteHandler.c:4448 +#: rewrite/rewriteHandler.c:4180 +#, c-format +msgid "views with INSTEAD OF triggers do not support FOR PORTION OF" +msgstr "Sichten mit INSTEAD-OF-Triggern unterstützen kein FOR PORTION OF" + +#: rewrite/rewriteHandler.c:4456 msgid "Views with conditional DO INSTEAD rules are not automatically updatable." msgstr "Sichten mit DO-INSTEAD-Regeln mit Bedingung sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:4546 +#: rewrite/rewriteHandler.c:4554 #, c-format msgid "cannot perform INSERT RETURNING on relation \"%s\"" msgstr "INSERT RETURNING kann in Relation »%s« nicht ausgeführt werden" -#: rewrite/rewriteHandler.c:4548 +#: rewrite/rewriteHandler.c:4556 #, c-format msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." msgstr "Sie benötigen eine ON INSERT DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." -#: rewrite/rewriteHandler.c:4553 +#: rewrite/rewriteHandler.c:4561 #, c-format msgid "cannot perform UPDATE RETURNING on relation \"%s\"" msgstr "UPDATE RETURNING kann in Relation »%s« nicht ausgeführt werden" -#: rewrite/rewriteHandler.c:4555 +#: rewrite/rewriteHandler.c:4563 #, c-format msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." msgstr "Sie benötigen eine ON UPDATE DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." -#: rewrite/rewriteHandler.c:4560 +#: rewrite/rewriteHandler.c:4568 #, c-format msgid "cannot perform DELETE RETURNING on relation \"%s\"" msgstr "DELETE RETURNING kann in Relation »%s« nicht ausgeführt werden" -#: rewrite/rewriteHandler.c:4562 +#: rewrite/rewriteHandler.c:4570 #, c-format msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." msgstr "Sie benötigen eine ON DELETE DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." -#: rewrite/rewriteHandler.c:4580 +#: rewrite/rewriteHandler.c:4588 #, c-format msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" msgstr "INSERT mit ON-CONFLICT-Klausel kann nicht mit Tabelle verwendet werden, die INSERT- oder UPDATE-Regeln hat" -#: rewrite/rewriteHandler.c:4637 +#: rewrite/rewriteHandler.c:4645 #, c-format msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" msgstr "WITH kann nicht in einer Anfrage verwendet werden, die durch Regeln in mehrere Anfragen umgeschrieben wird" @@ -28720,65 +28294,63 @@ msgstr "unbekannter Snowball-Parameter: »%s«" msgid "missing Language parameter" msgstr "Parameter »Language« fehlt" -#: statistics/attribute_stats.c:181 statistics/attribute_stats.c:620 +#: statistics/attribute_stats.c:154 statistics/attribute_stats.c:637 #: statistics/extended_stats_funcs.c:371 statistics/extended_stats_funcs.c:1779 -#: statistics/relation_stats.c:98 +#: statistics/relation_stats.c:87 #, c-format msgid "Statistics cannot be modified during recovery." msgstr "Statistiken können nicht während der Wiederherstellung geändert werden." -#: statistics/attribute_stats.c:194 +#: statistics/attribute_stats.c:167 #, c-format msgid "cannot specify both \"%s\" and \"%s\"" msgstr "»%s« und »%s« können nicht beide angegeben werden" -#: statistics/attribute_stats.c:220 +#: statistics/attribute_stats.c:193 #, c-format msgid "must specify either \"%s\" or \"%s\"" msgstr "entweder »%s« oder »%s« muss angegeben werden" -#: statistics/attribute_stats.c:228 +#: statistics/attribute_stats.c:201 #, c-format msgid "cannot modify statistics on system column \"%s\"" msgstr "Statistiken für Systemspalte »%s« können nicht modifiziert werden" -#: statistics/attribute_stats.c:292 +#: statistics/attribute_stats.c:309 #, c-format msgid "could not determine element type of column \"%s\"" msgstr "konnte Elementtyp von Spalte »%s« nicht bestimmen" -#: statistics/attribute_stats.c:293 statistics/attribute_stats.c:310 -#: statistics/attribute_stats.c:325 +#: statistics/attribute_stats.c:310 statistics/attribute_stats.c:327 +#: statistics/attribute_stats.c:342 #, c-format msgid "Cannot set %s or %s." msgstr "Kann %s oder %s nicht setzen." -#: statistics/attribute_stats.c:309 +#: statistics/attribute_stats.c:326 #, c-format msgid "could not determine less-than operator for column \"%s\"" msgstr "konnte Kleiner-Als-Operator für Spalte »%s« nicht bestimmen" -#: statistics/attribute_stats.c:324 +#: statistics/attribute_stats.c:341 #, c-format msgid "column \"%s\" is not a range type" msgstr "Spalte »%s« ist kein Range-Typ" -#: statistics/attribute_stats.c:385 statistics/extended_stats_funcs.c:1359 -#, fuzzy, c-format -#| msgid "could not parse numeric array \"%s\": invalid character in number" +#: statistics/attribute_stats.c:402 statistics/extended_stats_funcs.c:1359 +#, c-format msgid "could not parse \"%s\": incorrect number of elements (same as \"%s\" required)" -msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" +msgstr "konnte »%s« nicht parsen: falsche Anzahl Elemente (gleiche wie »%s« erforderlich)" -#: statistics/attribute_stats.c:632 +#: statistics/attribute_stats.c:649 #, c-format msgid "cannot clear statistics on system column \"%s\"" msgstr "Statistiken für Systemspalte »%s« können nicht geleert werden" #: statistics/dependencies.c:648 statistics/mvdistinct.c:394 -#, fuzzy, c-format -#| msgid "could not parse numeric array \"%s\": invalid character in number" +#, c-format msgid "could not validate \"%s\" object: invalid attribute number %d found" -msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" +msgstr "konnte Objekt »%s« nicht validieren: ungültige Attributnummer %d gefunden" #: statistics/extended_stats.c:176 #, c-format @@ -28786,92 +28358,81 @@ msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" msgstr "Statistikobjekt »%s.%s« konnte für Relation »%s.%s« nicht berechnet werden" #: statistics/extended_stats_funcs.c:404 statistics/extended_stats_funcs.c:1799 -#, fuzzy, c-format -#| msgid "could not find WAL file \"%s\"" +#, c-format msgid "could not find schema \"%s\"" -msgstr "konnte WAL-Datei »%s« nicht finden" +msgstr "konnte Schema »%s« nicht finden" #: statistics/extended_stats_funcs.c:416 statistics/extended_stats_funcs.c:1811 -#, fuzzy, c-format -#| msgid "could not find index attname \"%s\"" +#, c-format msgid "could not find extended statistics object \"%s.%s\"" -msgstr "konnte Index-Attname »%s« nicht finden" +msgstr "konnte erweitertes Statistikobjekt »%s.%s« nicht finden" #: statistics/extended_stats_funcs.c:432 -#, fuzzy, c-format -#| msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +#, c-format msgid "could not restore extended statistics object \"%s.%s\": incorrect relation \"%s.%s\" specified" -msgstr "Statistikobjekt »%s.%s« konnte für Relation »%s.%s« nicht berechnet werden" +msgstr "konnte erweitertes Statistikobjekt »%s.%s« nicht wiederherstellen: falsche Relation »%s.%s« angegeben" #: statistics/extended_stats_funcs.c:484 statistics/extended_stats_funcs.c:501 #: statistics/extended_stats_funcs.c:563 -#, fuzzy, c-format -#| msgid "could not set printing parameter \"%s\"" +#, c-format msgid "cannot specify parameter \"%s\"" -msgstr "konnte Ausgabeparameter »%s« nicht setzen" +msgstr "Parameter »%s« kann nicht angegeben werden" #: statistics/extended_stats_funcs.c:486 statistics/extended_stats_funcs.c:503 #: statistics/extended_stats_funcs.c:527 statistics/extended_stats_funcs.c:565 -#, fuzzy, c-format -#| msgid "statistics object \"%s.%s\" does not exist, skipping" +#, c-format msgid "Extended statistics object \"%s.%s\" does not support statistics of this type." -msgstr "Statistikobjekt »%s.%s« existiert nicht, wird übersprungen" +msgstr "Erweitertes Statistikobjekt »%s.%s« unterstützt keine Statistiken dieses Typs." #: statistics/extended_stats_funcs.c:523 -#, fuzzy, c-format -#| msgid "must specify either \"%s\" or \"%s\"" +#, c-format msgid "cannot specify parameters \"%s\", \"%s\", or \"%s\"" -msgstr "entweder »%s« oder »%s« muss angegeben werden" +msgstr "Parameter »%s«, »%s« oder »%s« können nicht angegeben werden" #: statistics/extended_stats_funcs.c:547 #, c-format msgid "could not use \"%s\", \"%s\", and \"%s\": missing one or more parameters" -msgstr "" +msgstr "konnte »%s«, »%s« und »%s« nicht verwenden: ein oder mehrere Parameter fehlen" #: statistics/extended_stats_funcs.c:780 statistics/extended_stats_funcs.c:833 -#, fuzzy, c-format -#| msgid "could not parse numeric array \"%s\": invalid character in number" +#, c-format msgid "could not parse array \"%s\": incorrect number of dimensions (%d required)" -msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" +msgstr "konnte Array »%s« nicht parsen: falsche Anzahl Dimensionen (%d erforderlich)" #: statistics/extended_stats_funcs.c:789 -#, fuzzy, c-format -#| msgid "could not parse numeric array \"%s\": too many numbers" +#, c-format msgid "could not parse array \"%s\": NULL value found" -msgstr "konnte numerisches Array »%s« nicht parsen: zu viele Zahlen" +msgstr "konnte Array »%s« nicht parsen: NULL-Wert gefunden" #: statistics/extended_stats_funcs.c:798 #, c-format msgid "could not parse array \"%s\": incorrect number of elements (same as \"%s\" required)" -msgstr "" +msgstr "konnte Array »%s« nicht parsen: falsche Anzahl Elemente (gleiche wie »%s« erforderlich)" #: statistics/extended_stats_funcs.c:842 -#, fuzzy, c-format -#| msgid "could not parse numeric array \"%s\": invalid character in number" +#, c-format msgid "could not parse array \"%s\": found %d attributes but expected %d" -msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" +msgstr "konnte Array »%s« nicht parsen: %d Attribute gefunden, aber %d erwartet" #: statistics/extended_stats_funcs.c:863 -#, fuzzy, c-format -#| msgid "could not parse numeric array \"%s\": invalid character in number" +#, c-format msgid "could not parse array \"%s\": number of items (%d) exceeds maximum (%d)" -msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" +msgstr "konnte Array »%s« nicht parsen: Anzahl Elemente (%d) überschreitet Maximum (%d)" #: statistics/extended_stats_funcs.c:967 #, c-format msgid "could not import element in expression %d: invalid key name" -msgstr "" +msgstr "konnte Element in Ausdruck %d nicht importieren: ungültiger Schlüsselname" #: statistics/extended_stats_funcs.c:1082 -#, fuzzy, c-format -#| msgid "thresholds must be one-dimensional array" +#, c-format msgid "could not import element \"%s\" in expression %d: must be a one-dimensional array" -msgstr "Parameter »thresholds« muss ein eindimensionales Array sein" +msgstr "konnte Element »%s« in Ausdruck %d nicht importieren: muss ein eindimensionales Array sein" #: statistics/extended_stats_funcs.c:1091 #, c-format msgid "could not import element \"%s\" in expression %d: null value found" -msgstr "" +msgstr "konnte Element »%s« in Ausdruck %d nicht importieren: NULL-Wert gefunden" #: statistics/extended_stats_funcs.c:1136 #: statistics/extended_stats_funcs.c:1166 @@ -28879,61 +28440,55 @@ msgstr "" #: statistics/extended_stats_funcs.c:1197 #: statistics/extended_stats_funcs.c:1214 #: statistics/extended_stats_funcs.c:1659 -#, fuzzy, c-format -#| msgid "could not parse numeric array \"%s\": invalid character in number" +#, c-format msgid "could not parse \"%s\": invalid element in expression %d" -msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" +msgstr "konnte »%s« nicht parsen: ungültiges Element in Ausdruck %d" #: statistics/extended_stats_funcs.c:1167 -#, fuzzy, c-format -#| msgid "field \"%s\" must be an array of strings" +#, c-format msgid "Value of element \"%s\" must be a null or a string." -msgstr "Feld »%s« muss ein Array von Zeichenketten sein" +msgstr "Wert von Element »%s« muss ein NULL-Wert oder eine Zeichenkette sein." #: statistics/extended_stats_funcs.c:1188 #: statistics/extended_stats_funcs.c:1199 #, c-format msgid "\"%s\" and \"%s\" must be both either strings or nulls." -msgstr "" +msgstr "»%s« und »%s« müssen entweder beide Zeichenketten oder beide NULL sein." #: statistics/extended_stats_funcs.c:1216 #, c-format msgid "\"%s\", \"%s\", and \"%s\" must be all either strings or all nulls." -msgstr "" +msgstr "»%s«, »%s« und »%s« müssen entweder alle Zeichenketten oder alle NULL sein." #: statistics/extended_stats_funcs.c:1248 -#, fuzzy, c-format -#| msgid "could not parse numeric array \"%s\": invalid character in number" +#, c-format msgid "could not parse \"%s\": invalid element type in expression %d" -msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" +msgstr "konnte »%s« nicht parsen: ungültiger Elementtyp in Ausdruck %d" #: statistics/extended_stats_funcs.c:1267 -#, fuzzy, c-format -#| msgid "could not parse numeric array \"%s\": invalid character in number" +#, c-format msgid "could not parse \"%s\": invalid data in expression %d" -msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" +msgstr "konnte »%s« nicht parsen: ungültige Daten in Ausdruck %d" #: statistics/extended_stats_funcs.c:1269 #, c-format msgid "\"%s\", \"%s\", and \"%s\" can only be set for a range type." -msgstr "" +msgstr "»%s«, »%s« und »%s« können nur für einen Range-Typ gesetzt werden." #: statistics/extended_stats_funcs.c:1584 -#, fuzzy, c-format -#| msgid "could not parse %s array" +#, c-format msgid "could not parse \"%s\": root-level array required" -msgstr "konnte %s-Array nicht interpretieren" +msgstr "konnte »%s« nicht parsen: Array auf Wurzelebene erforderlich" #: statistics/extended_stats_funcs.c:1599 #, c-format msgid "could not parse \"%s\": incorrect number of elements (%d required)" -msgstr "" +msgstr "konnte »%s« nicht parsen: falsche Anzahl Elemente (%d erforderlich)" #: statistics/extended_stats_funcs.c:1828 -#, fuzzy, c-format -#| msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +#, c-format msgid "could not clear extended statistics object \"%s.%s\": incorrect relation \"%s.%s\" specified" -msgstr "Statistikobjekt »%s.%s« konnte für Relation »%s.%s« nicht berechnet werden" +msgstr "konnte erweitertes Statistikobjekt »%s.%s« nicht leeren: falsche Relation »%s.%s« angegeben" #: statistics/mcv.c:1366 #, c-format @@ -28941,18 +28496,21 @@ msgid "function returning record called in context that cannot accept type recor msgstr "Funktion, die einen Record zurückgibt, in einem Zusammenhang aufgerufen, der Typ record nicht verarbeiten kann" #: statistics/mcv.c:2274 -#, fuzzy, c-format -#| msgid "could not parse function return value: %s" +#, c-format msgid "could not parse MCV element \"%s\": incorrect value" -msgstr "konnte Rückgabewert der Funktion nicht parsen: %s" +msgstr "konnte MCV-Element »%s« nicht parsen: falscher Wert" #: statistics/mcv.c:2325 -#, fuzzy, c-format -#| msgid "could not import \"%s\" module" +#, c-format msgid "could not import MCV list" -msgstr "konnte Modul »%s« nicht importieren" +msgstr "konnte MCV-Liste nicht importieren" + +#: statistics/relation_stats.c:132 +#, c-format +msgid "argument \"%s\" must be a finite value" +msgstr "Argument »%s« muss ein endlicher Wert sein" -#: statistics/relation_stats.c:117 +#: statistics/relation_stats.c:139 #, c-format msgid "argument \"%s\" must not be less than -1.0" msgstr "Argument »%s« darf nicht kleiner als -1.0 sein" @@ -29023,10 +28581,9 @@ msgid "name at variadic position %d has type %s, expected type %s" msgstr "Name auf variadischer Position %d hat Typ %s, erwarteter Typ %s" #: statistics/stat_utils.c:596 -#, fuzzy, c-format -#| msgid "thresholds must be one-dimensional array" +#, c-format msgid "\"%s\" must be a one-dimensional array" -msgstr "Parameter »thresholds« muss ein eindimensionales Array sein" +msgstr "»%s« muss ein eindimensionales Array sein" #: statistics/stat_utils.c:605 #, c-format @@ -29457,10 +29014,9 @@ msgid "DSM segment size must be nonzero" msgstr "DSM-Segmentgröße darf nicht null sein" #: storage/ipc/dsm_registry.c:230 -#, fuzzy, c-format -#| msgid "requested DSM segment size does not match size of existing segment" +#, c-format msgid "requested DSM segment does not match type of existing entry" -msgstr "angeforderte DSM-Segmentgröße stimmt nicht mit der Größe des existierenden Segments überein" +msgstr "angefordertes DSM-Segment stimmt nicht mit Typ des existierenden Eintrags überein" #: storage/ipc/dsm_registry.c:233 #, c-format @@ -29468,50 +29024,44 @@ msgid "requested DSM segment size does not match size of existing segment" msgstr "angeforderte DSM-Segmentgröße stimmt nicht mit der Größe des existierenden Segments überein" #: storage/ipc/dsm_registry.c:290 -#, fuzzy, c-format -#| msgid "DSM segment name cannot be empty" +#, c-format msgid "DSA name cannot be empty" -msgstr "DSM-Segmentname kann nicht leer sein" +msgstr "DSA-Name kann nicht leer sein" #: storage/ipc/dsm_registry.c:294 -#, fuzzy, c-format -#| msgid "realm name too long" +#, c-format msgid "DSA name too long" -msgstr "Realm-Name zu lang" +msgstr "DSA-Name zu lang" #: storage/ipc/dsm_registry.c:312 -#, fuzzy, c-format -#| msgid "requested DSM segment size does not match size of existing segment" +#, c-format msgid "requested DSA does not match type of existing entry" -msgstr "angeforderte DSM-Segmentgröße stimmt nicht mit der Größe des existierenden Segments überein" +msgstr "angeforderte DSA stimmt nicht mit Typ des existierenden Eintrags überein" #: storage/ipc/dsm_registry.c:336 #, c-format msgid "requested DSA already attached to current process" -msgstr "" +msgstr "angeforderte DSA ist bereits an den aktuellen Prozess angefügt" #: storage/ipc/dsm_registry.c:372 -#, fuzzy, c-format -#| msgid "DSM segment name cannot be empty" +#, c-format msgid "DSHash name cannot be empty" -msgstr "DSM-Segmentname kann nicht leer sein" +msgstr "DSHash-Name kann nicht leer sein" #: storage/ipc/dsm_registry.c:376 -#, fuzzy, c-format -#| msgid "realm name too long" +#, c-format msgid "DSHash name too long" -msgstr "Realm-Name zu lang" +msgstr "DSHash-Name zu lang" #: storage/ipc/dsm_registry.c:395 -#, fuzzy, c-format -#| msgid "requested DSM segment size does not match size of existing segment" +#, c-format msgid "requested DSHash does not match type of existing entry" -msgstr "angeforderte DSM-Segmentgröße stimmt nicht mit der Größe des existierenden Segments überein" +msgstr "angefordertes DSHash stimmt nicht mit Typ des existierenden Eintrags überein" #: storage/ipc/dsm_registry.c:429 #, c-format msgid "requested DSHash already attached to current process" -msgstr "" +msgstr "angefordertes DSHash ist bereits an den aktuellen Prozess angefügt" #: storage/ipc/procarray.c:484 storage/lmgr/proc.c:459 #: tcop/backend_startup.c:343 @@ -29582,10 +29132,9 @@ msgid "out of shared memory" msgstr "Shared Memory aufgebraucht" #: storage/ipc/shmem.c:372 -#, fuzzy, c-format -#| msgid "%s: service \"%s\" already registered\n" +#, c-format msgid "shared memory struct \"%s\" is already registered" -msgstr "%s: Systemdienst »%s« ist bereits registriert\n" +msgstr "Shared-Memory-Struct »%s« ist bereits registriert" #: storage/ipc/shmem.c:529 #, c-format @@ -29593,21 +29142,19 @@ msgid "could not create ShmemIndex entry for data structure \"%s\"" msgstr "konnte ShmemIndex-Eintrag für Datenstruktur »%s« nicht erzeugen" #: storage/ipc/shmem.c:546 -#, fuzzy, c-format -#| msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +#, c-format msgid "not enough shared memory for data structure \"%s\" (%zd bytes requested)" -msgstr "nicht genug Shared-Memory für Datenstruktur »%s« (%zu Bytes angefordert)" +msgstr "nicht genug Shared-Memory für Datenstruktur »%s« (%zd Bytes angefordert)" #: storage/ipc/shmem.c:592 -#, fuzzy, c-format -#| msgid "could not create ShmemIndex entry for data structure \"%s\"" +#, c-format msgid "could not find ShmemIndex entry for data structure \"%s\"" -msgstr "konnte ShmemIndex-Eintrag für Datenstruktur »%s« nicht erzeugen" +msgstr "konnte ShmemIndex-Eintrag für Datenstruktur »%s« nicht finden" #: storage/ipc/shmem.c:602 #, c-format msgid "shared memory struct \"%s\" was created with different size: existing %zu, requested %zd" -msgstr "" +msgstr "Shared-Memory-Struct »%s« wurde mit anderer Größe erzeugt: vorhanden %zu, angefordert %zd" #: storage/ipc/shmem.c:675 storage/ipc/shmem.c:772 #, c-format @@ -29718,10 +29265,8 @@ msgid "recovery conflict on replication slot" msgstr "Konflikt bei der Wiederherstellung wegen Replikations-Slot" #: storage/ipc/standby.c:1517 -#, fuzzy -#| msgid "recovery conflict on lock" msgid "recovery conflict on deadlock" -msgstr "Konflikt bei Wiederherstellung wegen Sperre" +msgstr "Konflikt bei Wiederherstellung wegen Deadlock" #: storage/ipc/standby.c:1520 msgid "recovery conflict on buffer deadlock" @@ -29899,10 +29444,9 @@ msgid "process %d could not obtain %s on %s" msgstr "Prozess %d konnte Sperre %s für %s nicht setzen" #: storage/lmgr/lock.c:2038 -#, fuzzy, c-format -#| msgid "trigger %s on %s" +#, c-format msgid "waiting for %s on %s" -msgstr "Trigger %s für %s" +msgstr "warte auf %s für %s" #: storage/lmgr/lock.c:3464 storage/lmgr/lock.c:3532 storage/lmgr/lock.c:3648 #, c-format @@ -29910,34 +29454,29 @@ msgid "cannot PREPARE while holding both session-level and transaction-level loc msgstr "PREPARE kann nicht ausgeführt werden, wenn für das selbe Objekt Sperren auf Sitzungsebene und auf Transaktionsebene gehalten werden" #: storage/lmgr/lwlock.c:569 storage/lmgr/lwlock.c:631 -#, fuzzy, c-format -#| msgid "step size cannot be NaN" +#, c-format msgid "tranche name cannot be NULL" -msgstr "Schrittgröße kann nicht NaN sein" +msgstr "Tranche-Name kann nicht NULL sein" #: storage/lmgr/lwlock.c:574 storage/lmgr/lwlock.c:636 -#, fuzzy, c-format -#| msgid "channel name too long" +#, c-format msgid "tranche name too long" -msgstr "Kanalname zu lang" +msgstr "Tranche-Name zu lang" #: storage/lmgr/lwlock.c:575 storage/lmgr/lwlock.c:637 -#, fuzzy, c-format -#| msgid "Replication origin names must be no longer than %d bytes." +#, c-format msgid "LWLock tranche names must be no longer than %d bytes." -msgstr "Replication-Origin-Namen dürfen nicht länger als %d Bytes sein." +msgstr "LWLock-Tranche-Namen dürfen nicht länger als %d Bytes sein." #: storage/lmgr/lwlock.c:585 storage/lmgr/lwlock.c:642 -#, fuzzy, c-format -#| msgid "maximum number of prepared transactions reached" +#, c-format msgid "maximum number of tranches already registered" -msgstr "maximale Anzahl vorbereiteter Transaktionen erreicht" +msgstr "maximale Anzahl Tranchen bereits registriert" #: storage/lmgr/lwlock.c:586 storage/lmgr/lwlock.c:643 -#, fuzzy, c-format -#| msgid "Words longer than %d characters are ignored." +#, c-format msgid "No more than %d tranches may be registered." -msgstr "Wörter, die länger als %d Zeichen sind, werden ignoriert." +msgstr "Es dürfen nicht mehr als %d Tranchen registriert werden." #: storage/lmgr/predicate.c:667 #, c-format @@ -29955,10 +29494,9 @@ msgid "not enough elements in RWConflictPool to record a potential read/write co msgstr "nicht genügend Elemente in RWConflictPool, um einen möglichen Lese-/Schreibkonflikt aufzuzeichnen" #: storage/lmgr/predicate.c:764 -#, fuzzy, c-format -#| msgid "could not access status of transaction %u" +#, c-format msgid "Could not access serializable CSN of transaction %u." -msgstr "konnte auf den Status von Transaktion %u nicht zugreifen" +msgstr "Konnte nicht auf die serialisierbare CSN von Transaktion %u zugreifen." #: storage/lmgr/predicate.c:1625 #, c-format @@ -30035,10 +29573,9 @@ msgid "process %d failed to acquire %s on %s after %ld.%03d ms" msgstr "Prozess %d konnte %s-Sperre auf %s nach %ld,%03d ms nicht erlangen" #: storage/page/bufpage.c:163 -#, fuzzy, c-format -#| msgid "page verification failed, calculated checksum %u but expected %u" +#, c-format msgid "page verification failed, calculated checksum %u but expected %u%s" -msgstr "Seitenüberprüfung fehlgeschlagen, berechnete Prüfsumme %u, aber erwartet %u" +msgstr "Seitenüberprüfung fehlgeschlagen, berechnete Prüfsumme %u, aber erwartet %u%s" #: storage/page/bufpage.c:226 storage/page/bufpage.c:739 #: storage/page/bufpage.c:1082 storage/page/bufpage.c:1217 @@ -30053,23 +29590,20 @@ msgid "corrupted line pointer: %u" msgstr "verfälschter Line-Pointer: %u" #: storage/page/bufpage.c:798 storage/page/bufpage.c:1275 -#, fuzzy, c-format -#| msgid "corrupted item lengths: total %u, available space %u" +#, c-format msgid "corrupted item lengths: total %zu, available space %u" -msgstr "verfälschte Item-Längen: gesamt %u, verfügbarer Platz %u" +msgstr "verfälschte Item-Längen: gesamt %zu, verfügbarer Platz %u" #: storage/page/bufpage.c:1101 storage/page/bufpage.c:1242 #: storage/page/bufpage.c:1339 -#, fuzzy, c-format -#| msgid "corrupted line pointer: offset = %u, size = %u" +#, c-format msgid "corrupted line pointer: offset = %u, size = %zu" -msgstr "verfälschter Line-Pointer: offset = %u, size = %u" +msgstr "verfälschter Line-Pointer: offset = %u, size = %zu" #: storage/page/bufpage.c:1451 -#, fuzzy, c-format -#| msgid "corrupted line pointer: offset = %u, size = %u" +#, c-format msgid "corrupted line pointer: offset = %u, size = %d" -msgstr "verfälschter Line-Pointer: offset = %u, size = %u" +msgstr "verfälschter Line-Pointer: offset = %u, size = %d" #: storage/smgr/md.c:513 storage/smgr/md.c:575 #, c-format @@ -30360,7 +29894,7 @@ msgstr "falsches Binärdatenformat in Funktionsargument %d" #: tcop/postgres.c:120 #, c-format msgid "Signal sent by PID %d, UID %d." -msgstr "" +msgstr "Signal gesendet von PID %d, UID %d." #: tcop/postgres.c:468 tcop/postgres.c:5108 #, c-format @@ -30471,8 +30005,7 @@ msgid "User was using a logical replication slot that must be invalidated." msgstr "Benutzer verwendete einen logischen Replikations-Slot, der ungültig gemacht werden muss." #: tcop/postgres.c:2573 -#, fuzzy, c-format -#| msgid "User transaction caused buffer deadlock with recovery." +#, c-format msgid "User transaction caused deadlock with recovery." msgstr "Benutzertransaktion hat Verklemmung (Deadlock) mit Wiederherstellung verursacht." @@ -30877,33 +30410,38 @@ msgstr "ungültiges Affix-Flag »%s« mit Flag-Wert »long«" msgid "could not open dictionary file \"%s\": %m" msgstr "konnte Wörterbuchdatei »%s« nicht öffnen: %m" -#: tsearch/spell.c:1182 tsearch/spell.c:1194 tsearch/spell.c:1758 -#: tsearch/spell.c:1763 tsearch/spell.c:1768 +#: tsearch/spell.c:1182 tsearch/spell.c:1189 tsearch/spell.c:1200 +#: tsearch/spell.c:1773 tsearch/spell.c:1778 tsearch/spell.c:1783 #, c-format msgid "invalid affix alias \"%s\"" msgstr "ungültiges Affixalias »%s«" -#: tsearch/spell.c:1235 tsearch/spell.c:1306 tsearch/spell.c:1455 +#: tsearch/spell.c:1241 tsearch/spell.c:1312 tsearch/spell.c:1470 #, c-format msgid "could not open affix file \"%s\": %m" msgstr "konnte Affixdatei »%s« nicht öffnen: %m" -#: tsearch/spell.c:1289 +#: tsearch/spell.c:1295 #, c-format msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" msgstr "Ispell-Wörterbuch unterstützt nur die Flag-Werte »default«, »long« und »num«" -#: tsearch/spell.c:1333 +#: tsearch/spell.c:1339 #, c-format msgid "invalid number of flag vector aliases" msgstr "ungültige Anzahl Flag-Vektor-Aliasse" -#: tsearch/spell.c:1356 +#: tsearch/spell.c:1362 #, c-format msgid "number of aliases exceeds specified number %d" msgstr "Anzahl der Aliasse überschreitet angegebene Zahl %d" -#: tsearch/spell.c:1570 +#: tsearch/spell.c:1436 +#, c-format +msgid "number of aliases is less than specified number %d" +msgstr "Anzahl der Aliasse ist kleiner als angegebene Zahl %d" + +#: tsearch/spell.c:1585 #, c-format msgid "affix file contains both old-style and new-style commands" msgstr "Affixdatei enthält Befehle im alten und im neuen Stil" @@ -30967,10 +30505,9 @@ msgstr "%s muss >= 0 sein" #: tsearch/wparser_def.c:2684 tsearch/wparser_def.c:2688 #: tsearch/wparser_def.c:2692 -#, fuzzy, c-format -#| msgid "tablespace location \"%s\" is too long" +#, c-format msgid "value for \"%s\" is too long" -msgstr "Tablespace-Pfad »%s« ist zu lang" +msgstr "Wert für »%s« ist zu lang" #: utils/activity/pgstat.c:555 #, c-format @@ -31024,10 +30561,9 @@ msgid "Custom cumulative statistics require a shared memory size for fixed-numbe msgstr "Benutzerdefinierte kumulative Statistiken benötigen eine Shared-Memory-Größe für Objekte mit fester Zahl." #: utils/activity/pgstat.c:1539 -#, fuzzy, c-format -#| msgid "Custom cumulative statistics require a shared memory size for fixed-numbered objects." +#, c-format msgid "Custom cumulative statistics cannot use entry count tracking for fixed-numbered objects." -msgstr "Benutzerdefinierte kumulative Statistiken benötigen eine Shared-Memory-Größe für Objekte mit fester Zahl." +msgstr "Benutzerdefinierte kumulative Statistiken können kein Entry-Count-Tracking für Objekte mit fester Zahl verwenden." #: utils/activity/pgstat.c:1556 #, c-format @@ -31044,27 +30580,27 @@ msgstr "Bestehende kumulative Statistik mit ID %u hat den gleichen Namen." msgid "registered custom cumulative statistics \"%s\" with ID %u" msgstr "benutzerdefinierte kumulative Statistik »%s« mit ID %u wurde registriert" -#: utils/activity/pgstat.c:1642 +#: utils/activity/pgstat.c:1646 #, c-format msgid "could not open temporary statistics file \"%s\": %m" msgstr "konnte temporäre Statistikdatei »%s« nicht öffnen: %m" -#: utils/activity/pgstat.c:1767 +#: utils/activity/pgstat.c:1785 #, c-format msgid "could not write temporary statistics file \"%s\": %m" msgstr "konnte temporäre Statistikdatei »%s« nicht schreiben: %m" -#: utils/activity/pgstat.c:1776 +#: utils/activity/pgstat.c:1795 #, c-format msgid "could not close temporary statistics file \"%s\": %m" msgstr "konnte temporäre Statistikdatei »%s« nicht schließen: %m" -#: utils/activity/pgstat.c:1837 +#: utils/activity/pgstat.c:1859 #, c-format msgid "could not open statistics file \"%s\": %m" msgstr "konnte Statistikdatei »%s« nicht öffnen: %m" -#: utils/activity/pgstat.c:2111 +#: utils/activity/pgstat.c:2135 #, c-format msgid "corrupted statistics file \"%s\"" msgstr "verfälschte Statistikdatei »%s«" @@ -31195,10 +30731,9 @@ msgid "must be able to SET ROLE \"%s\"" msgstr "Berechtigung nur für Rollen, die SET ROLE \"%s\" ausführen können" #: utils/adt/acl.c:5532 -#, fuzzy, c-format -#| msgid "initial privileges for %s" +#, c-format msgid "must inherit privileges of role \"%s\"" -msgstr "initiale Privilegien für %s" +msgstr "muss Privilegien von Rolle »%s« erben" #: utils/adt/array_expanded.c:276 utils/adt/array_userfuncs.c:1073 #: utils/adt/arrayfuncs.c:339 utils/adt/arrayfuncs.c:498 @@ -31210,10 +30745,9 @@ msgstr "initiale Privilegien für %s" #: utils/adt/arrayfuncs.c:3552 utils/adt/arrayfuncs.c:5392 #: utils/adt/arrayfuncs.c:5614 utils/adt/arrayfuncs.c:6240 #: utils/adt/arrayfuncs.c:6586 -#, fuzzy, c-format -#| msgid "array size exceeds the maximum allowed (%d)" +#, c-format msgid "array size exceeds the maximum allowed (%zu)" -msgstr "Arraygröße überschreitet erlaubtes Maximum (%d)" +msgstr "Arraygröße überschreitet erlaubtes Maximum (%zu)" #: utils/adt/array_userfuncs.c:119 utils/adt/array_userfuncs.c:566 #: utils/adt/array_userfuncs.c:943 utils/adt/json.c:611 utils/adt/json.c:718 @@ -31588,7 +31122,7 @@ msgid "encoding conversion from %s to ASCII not supported" msgstr "Kodierungsumwandlung zwischen %s und ASCII wird nicht unterstützt" #. translator: first %s is inet or cidr -#: utils/adt/bool.c:150 utils/adt/cash.c:356 utils/adt/datetime.c:4291 +#: utils/adt/bool.c:150 utils/adt/cash.c:372 utils/adt/datetime.c:4291 #: utils/adt/float.c:248 utils/adt/float.c:335 utils/adt/float.c:349 #: utils/adt/float.c:454 utils/adt/float.c:537 utils/adt/float.c:551 #: utils/adt/geo_ops.c:251 utils/adt/geo_ops.c:336 utils/adt/geo_ops.c:1020 @@ -31602,7 +31136,7 @@ msgstr "Kodierungsumwandlung zwischen %s und ASCII wird nicht unterstützt" #: utils/adt/numutils.c:938 utils/adt/numutils.c:1002 utils/adt/numutils.c:1024 #: utils/adt/pg_lsn.c:59 utils/adt/tid.c:71 utils/adt/tid.c:79 #: utils/adt/tid.c:93 utils/adt/tid.c:102 utils/adt/timestamp.c:508 -#: utils/adt/uuid.c:176 utils/adt/xid8funcs.c:324 +#: utils/adt/uuid.c:193 utils/adt/xid8funcs.c:324 #, c-format msgid "invalid input syntax for type %s: \"%s\"" msgstr "ungültige Eingabesyntax für Typ %s: »%s«" @@ -31638,7 +31172,7 @@ msgstr "neues Bit muss 0 oder 1 sein" msgid "smallint out of range" msgstr "smallint ist außerhalb des gültigen Bereichs" -#: utils/adt/bytea.c:1309 utils/adt/cash.c:1196 utils/adt/cash.c:1229 +#: utils/adt/bytea.c:1309 utils/adt/cash.c:1212 utils/adt/cash.c:1245 #: utils/adt/int8.c:455 utils/adt/int8.c:478 utils/adt/int8.c:492 #: utils/adt/int8.c:506 utils/adt/int8.c:537 utils/adt/int8.c:562 #: utils/adt/int8.c:645 utils/adt/int8.c:713 utils/adt/int8.c:719 @@ -31655,24 +31189,22 @@ msgid "bigint out of range" msgstr "bigint ist außerhalb des gültigen Bereichs" #: utils/adt/bytea.c:1354 -#, fuzzy, c-format -#| msgid "invalid input syntax for type %s" +#, c-format msgid "invalid input length for type %s" -msgstr "ungültige Eingabesyntax für Typ %s" +msgstr "ungültige Eingabelänge für Typ %s" #: utils/adt/bytea.c:1355 -#, fuzzy, c-format -#| msgid "Expected %d fields, got %d fields." +#, c-format msgid "Expected %d bytes, got %d." -msgstr "%d Felder erwartet, %d Feldern erhalten." +msgstr "%d Bytes erwartet, %d erhalten." #: utils/adt/cash.c:99 utils/adt/cash.c:112 utils/adt/cash.c:125 -#: utils/adt/cash.c:138 utils/adt/cash.c:151 +#: utils/adt/cash.c:138 utils/adt/cash.c:151 utils/adt/cash.c:175 #, c-format msgid "money out of range" msgstr "money ist außerhalb des gültigen Bereichs" -#: utils/adt/cash.c:162 utils/adt/cash.c:731 utils/adt/float.c:123 +#: utils/adt/cash.c:162 utils/adt/cash.c:747 utils/adt/float.c:123 #: utils/adt/float.c:147 utils/adt/int.c:872 utils/adt/int.c:988 #: utils/adt/int.c:1068 utils/adt/int.c:1130 utils/adt/int.c:1168 #: utils/adt/int.c:1196 utils/adt/int8.c:521 utils/adt/int8.c:581 @@ -31685,8 +31217,8 @@ msgstr "money ist außerhalb des gültigen Bereichs" msgid "division by zero" msgstr "Division durch Null" -#: utils/adt/cash.c:294 utils/adt/cash.c:319 utils/adt/cash.c:329 -#: utils/adt/cash.c:369 utils/adt/int.c:204 utils/adt/numutils.c:349 +#: utils/adt/cash.c:310 utils/adt/cash.c:335 utils/adt/cash.c:345 +#: utils/adt/cash.c:385 utils/adt/int.c:204 utils/adt/numutils.c:349 #: utils/adt/numutils.c:610 utils/adt/numutils.c:871 utils/adt/numutils.c:922 #: utils/adt/numutils.c:961 utils/adt/numutils.c:1008 #, c-format @@ -31719,9 +31251,9 @@ msgstr "Präzision von TIME(%d)%s darf nicht negativ sein" msgid "TIME(%d)%s precision reduced to maximum allowed, %d" msgstr "Präzision von TIME(%d)%s auf erlaubten Höchstwert %d reduziert" -#: utils/adt/date.c:162 utils/adt/date.c:170 utils/adt/formatting.c:4128 -#: utils/adt/formatting.c:4136 utils/adt/formatting.c:4240 -#: utils/adt/formatting.c:4249 +#: utils/adt/date.c:162 utils/adt/date.c:170 utils/adt/formatting.c:4240 +#: utils/adt/formatting.c:4248 utils/adt/formatting.c:4352 +#: utils/adt/formatting.c:4361 #, c-format msgid "date out of range: \"%s\"" msgstr "date ist außerhalb des gültigen Bereichs: »%s«" @@ -31777,9 +31309,9 @@ msgstr "Einheit »%s« nicht erkannt für Typ %s" #: utils/adt/date.c:1378 utils/adt/date.c:1460 utils/adt/date.c:2029 #: utils/adt/date.c:2061 utils/adt/date.c:2091 utils/adt/date.c:2994 #: utils/adt/date.c:3229 utils/adt/datetime.c:433 utils/adt/datetime.c:1833 -#: utils/adt/ddlutils.c:247 utils/adt/formatting.c:3976 -#: utils/adt/formatting.c:4012 utils/adt/formatting.c:4097 -#: utils/adt/formatting.c:4216 utils/adt/json.c:374 utils/adt/json.c:413 +#: utils/adt/ddlutils.c:247 utils/adt/formatting.c:4088 +#: utils/adt/formatting.c:4124 utils/adt/formatting.c:4209 +#: utils/adt/formatting.c:4328 utils/adt/json.c:374 utils/adt/json.c:413 #: utils/adt/timestamp.c:243 utils/adt/timestamp.c:275 #: utils/adt/timestamp.c:703 utils/adt/timestamp.c:712 #: utils/adt/timestamp.c:791 utils/adt/timestamp.c:824 @@ -31809,7 +31341,7 @@ msgstr "Einheit »%s« nicht erkannt für Typ %s" msgid "timestamp out of range" msgstr "timestamp ist außerhalb des gültigen Bereichs" -#: utils/adt/date.c:1641 utils/adt/date.c:2471 utils/adt/formatting.c:4297 +#: utils/adt/date.c:1641 utils/adt/date.c:2471 utils/adt/formatting.c:4409 #, c-format msgid "time out of range" msgstr "time ist außerhalb des gültigen Bereichs" @@ -31921,58 +31453,49 @@ msgid "role with OID %u does not exist" msgstr "Rolle mit OID %u existiert nicht" #: utils/adt/ddlutils.c:177 -#, fuzzy, c-format -#| msgid "permission denied for routine %s" +#, c-format msgid "permission denied for role %s" -msgstr "keine Berechtigung für Routine %s" +msgstr "keine Berechtigung für Rolle %s" #: utils/adt/ddlutils.c:188 -#, fuzzy, c-format -#| msgid "Role names starting with \"pg_\" are reserved." +#, c-format msgid "Role names starting with \"pg_\" are reserved for system roles." -msgstr "Rollennamen, die mit »pg_« anfangen, sind reserviert." +msgstr "Rollennamen, die mit »pg_« anfangen, sind für Systemrollen reserviert." #: utils/adt/ddlutils.c:515 -#, fuzzy, c-format -#| msgid "role name \"%s\" is reserved" +#, c-format msgid "tablespace name \"%s\" is reserved" -msgstr "Rollenname »%s« ist reserviert" +msgstr "Tablespace-Name »%s« ist reserviert" #: utils/adt/ddlutils.c:516 -#, fuzzy, c-format -#| msgid "The prefix \"pg_\" is reserved for system tablespaces." +#, c-format msgid "Tablespace names starting with \"pg_\" are reserved for system tablespaces." -msgstr "Der Präfix »pg_« ist für System-Tablespaces reserviert." +msgstr "Tablespace-Namen, die mit »pg_« anfangen, sind für System-Tablespaces reserviert." #: utils/adt/ddlutils.c:695 -#, fuzzy, c-format -#| msgid "cannot alter invalid database \"%s\"" +#, c-format msgid "cannot generate DDL for invalid database \"%s\"" -msgstr "ungültige Datenbank »%s« kann nicht geändert werden" +msgstr "kann keine DDL für ungültige Datenbank »%s« generieren" #: utils/adt/ddlutils.c:705 -#, fuzzy, c-format -#| msgid "database \"%s\" has disappeared from pg_database" +#, c-format msgid "database \"%s\" is a system database" -msgstr "Datenbank »%s« ist aus pg_database verschwunden" +msgstr "Datenbank »%s« ist eine Systemdatenbank" #: utils/adt/ddlutils.c:706 -#, fuzzy, c-format -#| msgid "This operation is not supported for temporary tables." +#, c-format msgid "DDL generation is not supported for template0 and template1." -msgstr "Diese Operation wird für temporäre Tabellen nicht unterstützt." +msgstr "DDL-Generierung wird für template0 und template1 nicht unterstützt." #: utils/adt/ddlutils.c:735 -#, fuzzy, c-format -#| msgid "unrecognized locale provider: %s" +#, c-format msgid "unrecognized locale provider: %c" -msgstr "unbekannter Locale-Provider: %s" +msgstr "unbekannter Locale-Provider: %c" #: utils/adt/ddlutils.c:792 -#, fuzzy, c-format -#| msgid "database %u was concurrently dropped" +#, c-format msgid "It may have been concurrently dropped." -msgstr "Datenbank %u wurde gleichzeitig gelöscht" +msgstr "Sie wurde möglicherweise gleichzeitig gelöscht." #: utils/adt/domains.c:95 #, c-format @@ -31985,10 +31508,9 @@ msgid "unrecognized encoding: \"%s\"" msgstr "unbekannte Kodierung: »%s«" #: utils/adt/encode.c:68 utils/adt/encode.c:118 -#, fuzzy, c-format -#| msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +#, c-format msgid "Valid encodings are \"%s\", \"%s\", \"%s\", \"%s\", and \"%s\"." -msgstr "Gültige Objekttypen sind »%c«, »%c«, »%c«, »%c«, »%c«, »%c«." +msgstr "Gültige Kodierungen sind »%s«, »%s«, »%s«, »%s« und »%s«." #: utils/adt/encode.c:83 #, c-format @@ -32011,22 +31533,19 @@ msgid "invalid hexadecimal data: odd number of digits" msgstr "ungültige hexadezimale Daten: ungerade Anzahl Ziffern" #: utils/adt/encode.c:551 -#, fuzzy, c-format -#| msgid "unexpected \"=\" while decoding base64 sequence" +#, c-format msgid "unexpected \"=\" while decoding %s sequence" -msgstr "unerwartetes »=« beim Dekodieren von Base64-Sequenz" +msgstr "unerwartetes »=« beim Dekodieren von %s-Sequenz" #: utils/adt/encode.c:566 -#, fuzzy, c-format -#| msgid "invalid symbol \"%.*s\" found while decoding base64 sequence" +#, c-format msgid "invalid symbol \"%.*s\" found while decoding %s sequence" -msgstr "ungültiges Symbol »%.*s« beim Dekodieren von Base64-Sequenz" +msgstr "ungültiges Symbol »%.*s« beim Dekodieren von %s-Sequenz" #: utils/adt/encode.c:602 -#, fuzzy, c-format -#| msgid "invalid base64 end sequence" +#, c-format msgid "invalid %s end sequence" -msgstr "ungültige Base64-Endsequenz" +msgstr "ungültige %s-Endsequenz" #: utils/adt/encode.c:603 #, c-format @@ -32034,16 +31553,14 @@ msgid "Input data is missing padding, is truncated, or is otherwise corrupted." msgstr "Die Eingabedaten haben fehlendes Padding, sind zu kurz oder sind anderweitig verfälscht." #: utils/adt/encode.c:929 -#, fuzzy, c-format -#| msgid "unexpected \"=\" while decoding base64 sequence" +#, c-format msgid "unexpected \"=\" while decoding base32hex sequence" -msgstr "unerwartetes »=« beim Dekodieren von Base64-Sequenz" +msgstr "unerwartetes »=« beim Dekodieren von Base32hex-Sequenz" #: utils/adt/encode.c:940 utils/adt/encode.c:950 -#, fuzzy, c-format -#| msgid "invalid symbol \"%.*s\" found while decoding base64 sequence" +#, c-format msgid "invalid symbol \"%.*s\" found while decoding base32hex sequence" -msgstr "ungültiges Symbol »%.*s« beim Dekodieren von Base64-Sequenz" +msgstr "ungültiges Symbol »%.*s« beim Dekodieren von Base32hex-Sequenz" #: utils/adt/enum.c:99 #, c-format @@ -32139,10 +31656,9 @@ msgid "count must be greater than zero" msgstr "Anzahl muss größer als null sein" #: utils/adt/float.c:4313 utils/adt/numeric.c:1978 -#, fuzzy, c-format -#| msgid "lower bound cannot be NaN" +#, c-format msgid "lower and upper bounds cannot be NaN" -msgstr "Untergrenze kann nicht NaN sein" +msgstr "Unter- und Obergrenze können nicht NaN sein" #: utils/adt/float.c:4318 utils/adt/numeric.c:1983 #: utils/adt/pseudorandomfuncs.c:214 utils/adt/pseudorandomfuncs.c:240 @@ -32156,277 +31672,275 @@ msgstr "Untergrenze und Obergrenze müssen endlich sein" msgid "lower bound cannot equal upper bound" msgstr "Untergrenze kann nicht gleich der Obergrenze sein" -#: utils/adt/formatting.c:539 +#: utils/adt/formatting.c:540 #, c-format msgid "invalid format specification for an interval value" msgstr "ungültige Formatangabe für Intervall-Wert" -#: utils/adt/formatting.c:540 +#: utils/adt/formatting.c:541 #, c-format msgid "Intervals are not tied to specific calendar dates." msgstr "Intervalle beziehen sich nicht auf bestimmte Kalenderdaten." -#: utils/adt/formatting.c:1194 +#: utils/adt/formatting.c:1195 #, c-format msgid "\"EEEE\" must be the last pattern used" msgstr "»EEEE« muss das letzte Muster sein" -#: utils/adt/formatting.c:1202 +#: utils/adt/formatting.c:1203 #, c-format msgid "\"9\" must be ahead of \"PR\"" msgstr "»9« muss vor »PR« stehen" -#: utils/adt/formatting.c:1218 +#: utils/adt/formatting.c:1219 #, c-format msgid "\"0\" must be ahead of \"PR\"" msgstr "»0« muss vor »PR« stehen" -#: utils/adt/formatting.c:1245 +#: utils/adt/formatting.c:1246 #, c-format msgid "multiple decimal points" msgstr "mehrere Dezimalpunkte" -#: utils/adt/formatting.c:1249 utils/adt/formatting.c:1336 +#: utils/adt/formatting.c:1250 utils/adt/formatting.c:1337 #, c-format msgid "cannot use \"V\" and decimal point together" msgstr "»V« und Dezimalpunkt können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1261 +#: utils/adt/formatting.c:1262 #, c-format msgid "cannot use \"S\" twice" msgstr "»S« kann nicht zweimal verwendet werden" -#: utils/adt/formatting.c:1265 +#: utils/adt/formatting.c:1266 #, c-format msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" msgstr "»S« und »PL«/»MI«/»SG«/»PR« können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1285 +#: utils/adt/formatting.c:1286 #, c-format msgid "cannot use \"S\" and \"MI\" together" msgstr "»S« und »MI« können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1295 +#: utils/adt/formatting.c:1296 #, c-format msgid "cannot use \"S\" and \"PL\" together" msgstr "»S« und »PL« können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1305 +#: utils/adt/formatting.c:1306 #, c-format msgid "cannot use \"S\" and \"SG\" together" msgstr "»S« und »SG« können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1314 +#: utils/adt/formatting.c:1315 #, c-format msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" msgstr "»PR« und »S«/»PL«/»MI«/»SG« können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1323 +#: utils/adt/formatting.c:1324 #, c-format msgid "cannot use \"RN\" twice" msgstr "»RN« kann nicht zweimal verwendet werden" -#: utils/adt/formatting.c:1344 +#: utils/adt/formatting.c:1345 #, c-format msgid "cannot use \"EEEE\" twice" msgstr "»EEEE« kann nicht zweimal verwendet werden" -#: utils/adt/formatting.c:1350 +#: utils/adt/formatting.c:1351 #, c-format msgid "\"EEEE\" is incompatible with other formats" msgstr "»EEEE« ist mit anderen Formaten inkompatibel" -#: utils/adt/formatting.c:1351 +#: utils/adt/formatting.c:1352 #, c-format msgid "\"EEEE\" may only be used together with digit and decimal point patterns." msgstr "»EEEE« kann nur zusammen mit Platzhaltern für Ziffern oder Dezimalpunkt verwendet werden." -#: utils/adt/formatting.c:1360 +#: utils/adt/formatting.c:1361 #, c-format msgid "\"RN\" is incompatible with other formats" msgstr "»RN« ist mit anderen Formaten inkompatibel" -#: utils/adt/formatting.c:1361 +#: utils/adt/formatting.c:1362 #, c-format msgid "\"RN\" may only be used together with \"FM\"." msgstr "»RN« kann nur zusammen mit »FM« verwendet werden." -#: utils/adt/formatting.c:1441 +#: utils/adt/formatting.c:1442 #, c-format msgid "invalid datetime format separator: \"%s\"" msgstr "ungültiges Datum-/Zeit-Formattrennzeichen: »%s«" -#: utils/adt/formatting.c:1567 +#: utils/adt/formatting.c:1568 #, c-format msgid "\"%s\" is not a number" msgstr "»%s« ist keine Zahl" -#: utils/adt/formatting.c:1636 utils/adt/formatting.c:1700 -#: utils/adt/formatting.c:1764 utils/adt/formatting.c:1828 +#: utils/adt/formatting.c:1637 utils/adt/formatting.c:1701 +#: utils/adt/formatting.c:1765 utils/adt/formatting.c:1829 #, c-format msgid "could not determine which collation to use for %s function" msgstr "konnte die für die Funktion %s zu verwendende Sortierfolge nicht bestimmen" -#: utils/adt/formatting.c:1836 +#: utils/adt/formatting.c:1837 #, c-format msgid "Unicode case folding can only be performed if server encoding is UTF8" msgstr "Unicode-Case-Folding kann nur durchgeführt werden, wenn die Serverkodierung UTF8 ist" -#: utils/adt/formatting.c:2126 +#: utils/adt/formatting.c:2127 #, c-format msgid "invalid combination of date conventions" msgstr "ungültige Kombination von Datumskonventionen" -#: utils/adt/formatting.c:2127 +#: utils/adt/formatting.c:2128 #, c-format msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." msgstr "Die Gregorianische und die ISO-Konvention für Wochendaten können nicht einer Formatvorlage gemischt werden." -#: utils/adt/formatting.c:2148 +#: utils/adt/formatting.c:2149 #, c-format msgid "conflicting values for \"%s\" field in formatting string" msgstr "widersprüchliche Werte für das Feld »%s« in Formatzeichenkette" -#: utils/adt/formatting.c:2150 +#: utils/adt/formatting.c:2151 #, c-format msgid "This value contradicts a previous setting for the same field type." msgstr "Der Wert widerspricht einer vorherigen Einstellung für den selben Feldtyp." -#: utils/adt/formatting.c:2216 +#: utils/adt/formatting.c:2217 #, c-format msgid "source string too short for \"%s\" formatting field" msgstr "Quellzeichenkette zu kurz für Formatfeld »%s»" -#: utils/adt/formatting.c:2218 -#, fuzzy, c-format -#| msgid "Field requires %d characters, but only %d remain." +#: utils/adt/formatting.c:2219 +#, c-format msgid "Field requires %zu characters, but only %zu remain." -msgstr "Feld benötigt %d Zeichen, aber nur %d verbleiben." +msgstr "Feld benötigt %zu Zeichen, aber nur %zu verbleiben." -#: utils/adt/formatting.c:2220 utils/adt/formatting.c:2233 +#: utils/adt/formatting.c:2221 utils/adt/formatting.c:2234 #, c-format msgid "If your source string is not fixed-width, try using the \"FM\" modifier." msgstr "Wenn die Quellzeichenkette keine feste Breite hat, versuchen Sie den Modifikator »FM«." -#: utils/adt/formatting.c:2229 utils/adt/formatting.c:2241 -#: utils/adt/formatting.c:2456 utils/adt/formatting.c:3353 -#: utils/adt/formatting.c:3555 +#: utils/adt/formatting.c:2230 utils/adt/formatting.c:2242 +#: utils/adt/formatting.c:2568 utils/adt/formatting.c:3465 +#: utils/adt/formatting.c:3667 #, c-format msgid "invalid value \"%s\" for \"%s\"" msgstr "ungültiger Wert »%s« für »%s«" -#: utils/adt/formatting.c:2231 -#, fuzzy, c-format -#| msgid "Field requires %d characters, but only %d could be parsed." +#: utils/adt/formatting.c:2232 +#, c-format msgid "Field requires %zu characters, but only %zu could be parsed." -msgstr "Feld benötigt %d Zeichen, aber nur %d konnten geparst werden." +msgstr "Feld benötigt %zu Zeichen, aber nur %zu konnten geparst werden." -#: utils/adt/formatting.c:2243 +#: utils/adt/formatting.c:2244 #, c-format msgid "Value must be an integer." msgstr "Der Wert muss eine ganze Zahl sein." -#: utils/adt/formatting.c:2248 utils/adt/formatting.c:3562 +#: utils/adt/formatting.c:2249 utils/adt/formatting.c:3674 #, c-format msgid "value for \"%s\" in source string is out of range" msgstr "Wert für »%s« in der Eingabezeichenkette ist außerhalb des gültigen Bereichs" -#: utils/adt/formatting.c:2250 +#: utils/adt/formatting.c:2251 #, c-format msgid "Value must be in the range %d to %d." msgstr "Der Wert muss im Bereich %d bis %d sein." -#: utils/adt/formatting.c:2458 +#: utils/adt/formatting.c:2570 #, c-format msgid "The given value did not match any of the allowed values for this field." msgstr "Der angegebene Wert stimmte mit keinem der für dieses Feld zulässigen Werte überein." -#: utils/adt/formatting.c:2671 utils/adt/formatting.c:2691 -#: utils/adt/formatting.c:2711 utils/adt/formatting.c:2731 -#: utils/adt/formatting.c:2750 utils/adt/formatting.c:2769 -#: utils/adt/formatting.c:2793 utils/adt/formatting.c:2811 -#: utils/adt/formatting.c:2829 utils/adt/formatting.c:2847 -#: utils/adt/formatting.c:2864 utils/adt/formatting.c:2881 +#: utils/adt/formatting.c:2783 utils/adt/formatting.c:2803 +#: utils/adt/formatting.c:2823 utils/adt/formatting.c:2843 +#: utils/adt/formatting.c:2862 utils/adt/formatting.c:2881 +#: utils/adt/formatting.c:2905 utils/adt/formatting.c:2923 +#: utils/adt/formatting.c:2941 utils/adt/formatting.c:2959 +#: utils/adt/formatting.c:2976 utils/adt/formatting.c:2993 #, c-format msgid "localized string format value too long" msgstr "lokalisierter Formatwert ist zu lang" -#: utils/adt/formatting.c:3161 +#: utils/adt/formatting.c:3273 #, c-format msgid "unmatched format separator \"%c\"" msgstr "Formattrennzeichen »%c« ohne passende Eingabe" -#: utils/adt/formatting.c:3222 +#: utils/adt/formatting.c:3334 #, c-format msgid "unmatched format character \"%s\"" msgstr "Formatzeichen »%s« ohne passende Eingabe" -#: utils/adt/formatting.c:3354 +#: utils/adt/formatting.c:3466 #, c-format msgid "Time zone abbreviation is not recognized." msgstr "Zeitzonenabkürzung wird nicht erkannt." -#: utils/adt/formatting.c:3651 +#: utils/adt/formatting.c:3763 #, c-format msgid "input string is too short for datetime format" msgstr "Eingabezeichenkette ist zu kurz für Datum-/Zeitformat" -#: utils/adt/formatting.c:3659 +#: utils/adt/formatting.c:3771 #, c-format msgid "trailing characters remain in input string after datetime format" msgstr "nach dem Datum-/Zeitformat bleiben noch Zeichen in der Eingabezeichenkette" -#: utils/adt/formatting.c:4196 +#: utils/adt/formatting.c:4308 #, c-format msgid "missing time zone in input string for type timestamptz" msgstr "Zeitzone fehlt in Eingabezeichenkette für Typ timestamptz" -#: utils/adt/formatting.c:4202 +#: utils/adt/formatting.c:4314 #, c-format msgid "timestamptz out of range" msgstr "timestamptz ist außerhalb des gültigen Bereichs" -#: utils/adt/formatting.c:4230 +#: utils/adt/formatting.c:4342 #, c-format msgid "datetime format is zoned but not timed" msgstr "Datum-/Zeitformat hat Zeitzone aber keine Zeit" -#: utils/adt/formatting.c:4277 +#: utils/adt/formatting.c:4389 #, c-format msgid "missing time zone in input string for type timetz" msgstr "Zeitzone fehlt in Eingabezeichenkette für Typ timetz" -#: utils/adt/formatting.c:4283 +#: utils/adt/formatting.c:4395 #, c-format msgid "timetz out of range" msgstr "timetz ist außerhalb des gültigen Bereichs" -#: utils/adt/formatting.c:4309 +#: utils/adt/formatting.c:4421 #, c-format msgid "datetime format is not dated and not timed" msgstr "Datum-/Zeitformat hat kein Datum und keine Zeit" -#: utils/adt/formatting.c:4485 +#: utils/adt/formatting.c:4597 #, c-format msgid "hour \"%d\" is invalid for the 12-hour clock" msgstr "Stunde »%d« ist bei einer 12-Stunden-Uhr ungültig" -#: utils/adt/formatting.c:4486 +#: utils/adt/formatting.c:4598 #, c-format msgid "Use the 24-hour clock, or give an hour between 1 and 12." msgstr "Verwenden Sie die 24-Stunden-Uhr oder geben Sie eine Stunde zwischen 1 und 12 an." -#: utils/adt/formatting.c:4663 +#: utils/adt/formatting.c:4775 #, c-format msgid "cannot calculate day of year without year information" msgstr "kann Tag des Jahres nicht berechnen ohne Jahrinformationen" -#: utils/adt/formatting.c:5781 +#: utils/adt/formatting.c:5893 #, c-format msgid "\"EEEE\" not supported for input" msgstr "»E« wird nicht bei der Eingabe unterstützt" -#: utils/adt/formatting.c:6071 +#: utils/adt/formatting.c:6183 #, c-format msgid "invalid Roman numeral" msgstr "ungültige römische Zahl" @@ -33026,16 +32540,14 @@ msgid "time precision of jsonpath item method .%s() is invalid" msgstr "Zeitpräzision der JSON-Path-Item-Methode .%s() ist ungültig" #: utils/adt/jsonpath_exec.c:3026 -#, fuzzy, c-format -#| msgid "time precision of jsonpath item method .%s() is out of range for type integer" +#, c-format msgid "field position of jsonpath item method .%s() is out of range for type integer" -msgstr "Zeitpräzision der JSON-Path-Item-Methode .%s() ist außerhalb des gültigen Bereichs für Typ integer" +msgstr "Feldposition der JSON-Path-Item-Methode .%s() ist außerhalb des gültigen Bereichs für Typ integer" #: utils/adt/jsonpath_exec.c:3032 -#, fuzzy, c-format -#| msgid "time precision of jsonpath item method .%s() is invalid" +#, c-format msgid "field position of jsonpath item method .%s() must not be zero" -msgstr "Zeitpräzision der JSON-Path-Item-Methode .%s() ist ungültig" +msgstr "Feldposition der JSON-Path-Item-Methode .%s() darf nicht null sein" #: utils/adt/jsonpath_exec.c:3105 #, c-format @@ -33174,10 +32686,9 @@ msgid "PID %d is not a PostgreSQL server process" msgstr "PID %d ist kein PostgreSQL-Serverprozess" #: utils/adt/misc.c:201 -#, fuzzy, c-format -#| msgid "null value not allowed for object key" +#, c-format msgid "null value not allowed" -msgstr "NULL-Werte sind nicht als Objektschlüssel erlaubt" +msgstr "NULL-Wert nicht erlaubt" #: utils/adt/misc.c:253 #, c-format @@ -33287,10 +32798,9 @@ msgid "invalid MultiXactId: %u" msgstr "ungültige MultiXactId: %u" #: utils/adt/multixactfuncs.c:109 -#, fuzzy, c-format -#| msgid "first argument of %s must be a row type" +#, c-format msgid "return type must be a row type" -msgstr "erstes Argument von %s muss ein Zeilentyp sein" +msgstr "Rückgabetyp muss ein Zeilentyp sein" #: utils/adt/network.c:108 #, c-format @@ -33552,153 +33062,136 @@ msgstr "Perzentilwert %g ist nicht zwischen 0 und 1" #: utils/adt/pg_dependencies.c:579 utils/adt/pg_dependencies.c:672 #: utils/adt/pg_dependencies.c:680 utils/adt/pg_dependencies.c:715 #: utils/adt/pg_dependencies.c:802 -#, fuzzy, c-format -#| msgid "malformed range literal: \"%s\"" +#, c-format msgid "malformed pg_dependencies: \"%s\"" -msgstr "fehlerhafte Bereichskonstante: »%s«" +msgstr "fehlerhafte pg_dependencies: »%s«" #: utils/adt/pg_dependencies.c:80 utils/adt/pg_ndistinct.c:76 -#, fuzzy, c-format -#| msgid "VARIADIC argument must be an array" +#, c-format msgid "Initial element must be an array." -msgstr "VARIADIC-Argument muss ein Array sein" +msgstr "Das erste Element muss ein Array sein." #: utils/adt/pg_dependencies.c:88 utils/adt/pg_ndistinct.c:84 #, c-format msgid "A key was expected." -msgstr "" +msgstr "Ein Schlüssel wurde erwartet." #: utils/adt/pg_dependencies.c:96 utils/adt/pg_ndistinct.c:92 -#, fuzzy, c-format -#| msgid "field \"%s\" must be an array of strings" +#, c-format msgid "Value of \"%s\" must be an array of attribute numbers." -msgstr "Feld »%s« muss ein Array von Zeichenketten sein" +msgstr "Wert von »%s« muss ein Array von Attributnummern sein." #: utils/adt/pg_dependencies.c:105 utils/adt/pg_ndistinct.c:101 #, c-format msgid "Attribute lists can only contain attribute numbers." -msgstr "" +msgstr "Attributlisten können nur Attributnummern enthalten." #: utils/adt/pg_dependencies.c:113 utils/adt/pg_dependencies.c:122 #: utils/adt/pg_ndistinct.c:109 -#, fuzzy, c-format -#| msgid "Value must be an integer." +#, c-format msgid "Value of \"%s\" must be an integer." -msgstr "Der Wert muss eine ganze Zahl sein." +msgstr "Wert von »%s« muss eine ganze Zahl sein." #: utils/adt/pg_dependencies.c:160 utils/adt/pg_dependencies.c:170 #: utils/adt/pg_dependencies.c:180 utils/adt/pg_ndistinct.c:147 #: utils/adt/pg_ndistinct.c:157 -#, fuzzy, c-format -#| msgid "Extension names must not contain \"--\"." +#, c-format msgid "Item must contain \"%s\" key." -msgstr "Erweiterungsnamen dürfen nicht »--« enthalten." +msgstr "Item muss den Schlüssel »%s« enthalten." #: utils/adt/pg_dependencies.c:195 #, c-format msgid "The \"%s\" key must contain an array of at least %d and no more than %d elements." -msgstr "" +msgstr "Der Schlüssel »%s« muss ein Array mit mindestens %d und höchstens %d Elementen enthalten." #: utils/adt/pg_dependencies.c:223 #, c-format msgid "Item \"%s\" with value %d has been found in the \"%s\" list." -msgstr "" +msgstr "Element »%s« mit Wert %d wurde in der Liste »%s« gefunden." #: utils/adt/pg_dependencies.c:271 utils/adt/pg_ndistinct.c:226 #, c-format msgid "Array has been found at an unexpected location." -msgstr "" +msgstr "Array wurde an einer unerwarteten Stelle gefunden." #: utils/adt/pg_dependencies.c:300 utils/adt/pg_ndistinct.c:260 -#, fuzzy, c-format -#| msgid "field \"%s\" must be a number" +#, c-format msgid "The \"%s\" key must be a non-empty array." -msgstr "Feld »%s« muss eine Zahl sein" +msgstr "Der Schlüssel »%s« muss ein nicht leeres Array sein." #: utils/adt/pg_dependencies.c:314 utils/adt/pg_ndistinct.c:275 -#, fuzzy, c-format -#| msgid "\"%s\" cannot be empty." +#, c-format msgid "Item array cannot be empty." -msgstr "»%s« kann nicht leer sein." +msgstr "Item-Array kann nicht leer sein." #: utils/adt/pg_dependencies.c:351 utils/adt/pg_dependencies.c:368 #: utils/adt/pg_dependencies.c:385 utils/adt/pg_ndistinct.c:312 #: utils/adt/pg_ndistinct.c:328 -#, fuzzy, c-format -#| msgid "multiple WITH clauses not allowed" +#, c-format msgid "Multiple \"%s\" keys are not allowed." -msgstr "mehrere WITH-Klauseln sind nicht erlaubt" +msgstr "Mehrere »%s«-Schlüssel sind nicht erlaubt." #: utils/adt/pg_dependencies.c:398 -#, fuzzy, c-format -#| msgid "Valid values are \"%s\" and \"%s\"." +#, c-format msgid "Only allowed keys are \"%s\", \"%s\", and \"%s\"." -msgstr "Gültige Werte sind »%s« und »%s«." +msgstr "Die einzigen erlaubten Schlüssel sind »%s«, »%s« und »%s«." #: utils/adt/pg_dependencies.c:425 utils/adt/pg_ndistinct.c:366 -#, fuzzy, c-format -#| msgid "options array must not be null" +#, c-format msgid "Attribute number array cannot be null." -msgstr "Optionen-Array darf nicht NULL sein" +msgstr "Attributnummern-Array darf nicht NULL sein." #: utils/adt/pg_dependencies.c:435 utils/adt/pg_ndistinct.c:376 -#, fuzzy, c-format -#| msgid "RAISE statement option cannot be null" +#, c-format msgid "Item list elements cannot be null." -msgstr "Option einer RAISE-Anweisung darf nicht NULL sein" +msgstr "Elemente der Item-Liste dürfen nicht NULL sein." #: utils/adt/pg_dependencies.c:494 utils/adt/pg_dependencies.c:539 #: utils/adt/pg_dependencies.c:569 utils/adt/pg_ndistinct.c:436 #: utils/adt/pg_ndistinct.c:490 -#, fuzzy, c-format -#| msgid "Column \"%s\" has no default value." +#, c-format msgid "Key \"%s\" has an incorrect value." -msgstr "Spalte »%s« hat keinen Vorgabewert." +msgstr "Schlüssel »%s« hat einen falschen Wert." #: utils/adt/pg_dependencies.c:507 utils/adt/pg_ndistinct.c:449 #, c-format msgid "Invalid \"%s\" element has been found: %d." -msgstr "" +msgstr "Ungültiges »%s«-Element wurde gefunden: %d." #: utils/adt/pg_dependencies.c:521 utils/adt/pg_ndistinct.c:463 #, c-format msgid "Invalid \"%s\" element has been found: %d cannot follow %d." -msgstr "" +msgstr "Ungültiges »%s«-Element wurde gefunden: %d kann nicht auf %d folgen." #: utils/adt/pg_dependencies.c:552 -#, fuzzy, c-format -#| msgid "Column \"%s\" has no default value." +#, c-format msgid "Key \"%s\" has an incorrect value: %d." -msgstr "Spalte »%s« hat keinen Vorgabewert." +msgstr "Schlüssel »%s« hat einen falschen Wert: %d." #: utils/adt/pg_dependencies.c:580 utils/adt/pg_ndistinct.c:498 -#, fuzzy, c-format -#| msgid "Unexpected array element." +#, c-format msgid "Unexpected scalar has been found." -msgstr "Unerwartetes Arrayelement." +msgstr "Unerwarteter Skalar wurde gefunden." #: utils/adt/pg_dependencies.c:673 utils/adt/pg_ndistinct.c:615 -#, fuzzy, c-format -#| msgid "\"%s\" cannot be empty." +#, c-format msgid "Value cannot be empty." -msgstr "»%s« kann nicht leer sein." +msgstr "Wert kann nicht leer sein." #: utils/adt/pg_dependencies.c:681 utils/adt/pg_ndistinct.c:623 -#, fuzzy, c-format -#| msgid "expected %d check constraint on table \"%s\" but found %d" -#| msgid_plural "expected %d check constraints on table \"%s\" but found %d" +#, c-format msgid "Unexpected end state has been found: %d." -msgstr "%d Check-Constraint für Tabelle %s erwartet, aber %d gefunden" +msgstr "Unerwarteter Endzustand wurde gefunden: %d." #: utils/adt/pg_dependencies.c:716 #, c-format msgid "Duplicated \"%s\" array has been found: [%s] for key \"%s\" and value %d." -msgstr "" +msgstr "Dupliziertes »%s«-Array wurde gefunden: [%s] für Schlüssel »%s« und Wert %d." #: utils/adt/pg_dependencies.c:803 utils/adt/pg_ndistinct.c:780 #, c-format msgid "Input data must be valid JSON." -msgstr "" +msgstr "Eingabedaten müssen gültiges JSON sein." #: utils/adt/pg_locale.c:285 utils/adt/pg_locale.c:317 #, c-format @@ -33768,10 +33261,9 @@ msgid "could not open collator for locale \"%s\": %s" msgstr "konnte Collator für Locale »%s« nicht öffnen: %s" #: utils/adt/pg_locale_icu.c:543 -#, fuzzy, c-format -#| msgid "could not open collator for locale \"%s\": %s" +#, c-format msgid "could not open casemap for locale \"%s\": %s" -msgstr "konnte Collator für Locale »%s« nicht öffnen: %s" +msgstr "konnte Casemap für Locale »%s« nicht öffnen: %s" #: utils/adt/pg_locale_icu.c:611 #, c-format @@ -33879,31 +33371,29 @@ msgstr "NaN kann nicht von pg_lsn subtrahiert werden" #: utils/adt/pg_ndistinct.c:497 utils/adt/pg_ndistinct.c:614 #: utils/adt/pg_ndistinct.c:622 utils/adt/pg_ndistinct.c:650 #: utils/adt/pg_ndistinct.c:700 utils/adt/pg_ndistinct.c:779 -#, fuzzy, c-format -#| msgid "malformed range literal: \"%s\"" +#, c-format msgid "malformed pg_ndistinct: \"%s\"" -msgstr "fehlerhafte Bereichskonstante: »%s«" +msgstr "fehlerhafte pg_ndistinct: »%s«" #: utils/adt/pg_ndistinct.c:172 #, c-format msgid "The \"%s\" key must contain an array of at least %d and no more than %d attributes." -msgstr "" +msgstr "Der Schlüssel »%s« muss ein Array mit mindestens %d und höchstens %d Attributen enthalten." #: utils/adt/pg_ndistinct.c:340 -#, fuzzy, c-format -#| msgid "Valid values are \"%s\" and \"%s\"." +#, c-format msgid "Only allowed keys are \"%s\" and \"%s\"." -msgstr "Gültige Werte sind »%s« und »%s«." +msgstr "Die einzigen erlaubten Schlüssel sind »%s« und »%s«." #: utils/adt/pg_ndistinct.c:651 #, c-format msgid "Duplicated \"%s\" array has been found: [%s]." -msgstr "" +msgstr "Dupliziertes »%s«-Array wurde gefunden: [%s]." #: utils/adt/pg_ndistinct.c:701 #, c-format msgid "\"%s\" array [%s] must be a subset of array [%s]." -msgstr "" +msgstr "»%s«-Array [%s] muss eine Teilmenge von Array [%s] sein." #: utils/adt/pg_upgrade_support.c:39 #, c-format @@ -33921,10 +33411,9 @@ msgid "unrecognized reset target: \"%s\"" msgstr "unbekanntes Reset-Ziel: »%s«" #: utils/adt/pgstatfuncs.c:1990 -#, fuzzy, c-format -#| msgid "Target must be \"archiver\", \"bgwriter\", \"checkpointer\", \"io\", \"recovery_prefetch\", \"slru\", or \"wal\"." +#, c-format msgid "Target must be \"archiver\", \"bgwriter\", \"checkpointer\", \"io\", \"lock\", \"recovery_prefetch\", \"slru\", or \"wal\"." -msgstr "Das Reset-Ziel muss »archiver«, »bgwriter«, »checkpointer«, »io«, »recovery_prefetch«, »slru« oder »wal« sein." +msgstr "Das Reset-Ziel muss »archiver«, »bgwriter«, »checkpointer«, »io«, »lock«, »recovery_prefetch«, »slru« oder »wal« sein." #: utils/adt/pgstatfuncs.c:2107 #, c-format @@ -34072,8 +33561,8 @@ msgstr "es gibt mehrere Funktionen namens »%s«" msgid "more than one operator named %s" msgstr "es gibt mehrere Operatoren namens %s" -#: utils/adt/regproc.c:683 utils/adt/regproc.c:2154 utils/adt/ruleutils.c:11426 -#: utils/adt/ruleutils.c:11639 +#: utils/adt/regproc.c:683 utils/adt/regproc.c:2154 utils/adt/ruleutils.c:11425 +#: utils/adt/ruleutils.c:11638 #, c-format msgid "too many arguments" msgstr "zu viele Argumente" @@ -34259,22 +33748,22 @@ msgstr "kann unterschiedliche Spaltentyp %s und %s in Record-Spalte %d nicht ver msgid "cannot compare record types with different numbers of columns" msgstr "kann Record-Typen mit unterschiedlicher Anzahl Spalten nicht vergleichen" -#: utils/adt/ruleutils.c:3100 +#: utils/adt/ruleutils.c:3101 #, c-format msgid "input is a query, not an expression" msgstr "Eingabe ist eine Anfrage, kein Ausdruck" -#: utils/adt/ruleutils.c:3112 +#: utils/adt/ruleutils.c:3113 #, c-format msgid "expression contains variables of more than one relation" msgstr "Ausdruck enthält Verweise auf Variablen von mehr als einer Relation" -#: utils/adt/ruleutils.c:3119 +#: utils/adt/ruleutils.c:3120 #, c-format msgid "expression contains variables" msgstr "Ausdruck enthält Variablen" -#: utils/adt/ruleutils.c:5797 +#: utils/adt/ruleutils.c:5798 #, c-format msgid "rule \"%s\" has unsupported event type %d" msgstr "Regel »%s« hat nicht unterstützten Ereignistyp %d" @@ -34511,10 +34000,9 @@ msgid "weight out of range" msgstr "Gewichtung ist außerhalb des gültigen Bereichs" #: utils/adt/tsvector.c:213 -#, fuzzy, c-format -#| msgid "word is too long (%ld bytes, max %ld bytes)" +#, c-format msgid "word is too long (%d bytes, max %d bytes)" -msgstr "Wort ist zu lang (%ld Bytes, maximal %ld Bytes)" +msgstr "Wort ist zu lang (%d Bytes, maximal %d Bytes)" #: utils/adt/tsvector.c:220 #, c-format @@ -34527,10 +34015,9 @@ msgid "unrecognized weight: \"%c\"" msgstr "unbekannte Gewichtung: »%c«" #: utils/adt/tsvector_op.c:242 -#, fuzzy, c-format -#| msgid "unrecognized weight: \"%c\"" +#, c-format msgid "unrecognized weight: \"\\%03o\"" -msgstr "unbekannte Gewichtung: »%c«" +msgstr "unbekannte Gewichtung: »\\%03o«" #: utils/adt/tsvector_op.c:767 #, c-format @@ -34602,11 +34089,31 @@ msgstr "es gibt kein escaptes Zeichen: »%s«" msgid "wrong position info in tsvector: \"%s\"" msgstr "falsche Positionsinformationen in tsvector: »%s«" -#: utils/adt/uuid.c:531 utils/adt/uuid.c:628 +#: utils/adt/uuid.c:548 utils/adt/uuid.c:645 #, c-format msgid "could not generate random values" msgstr "konnte keine Zufallswerte erzeugen" +#: utils/adt/uuid.c:696 +#, c-format +msgid "interval out of range for UUID version 7" +msgstr "interval-Wert ist außerhalb des gültigen Bereichs für UUID Version 7" + +#: utils/adt/uuid.c:697 +#, c-format +msgid "UUID version 7 does not support infinite intervals." +msgstr "UUID Version 7 unterstützt keine unendlichen Intervalle." + +#: utils/adt/uuid.c:721 +#, c-format +msgid "timestamp out of range for UUID version 7" +msgstr "timestamp ist außerhalb des gültigen Bereichs für UUID Version 7" + +#: utils/adt/uuid.c:722 +#, c-format +msgid "UUID version 7 supports timestamps from 1970-01-01 to approximately year 10889." +msgstr "UUID Version 7 unterstützt Timestamps von 1970-01-01 bis ungefähr zum Jahr 10889." + #: utils/adt/varbit.c:110 utils/adt/varchar.c:53 #, c-format msgid "length for type %s must be at least 1" @@ -34668,10 +34175,9 @@ msgid "bit index %d out of valid range (0..%d)" msgstr "Bitindex %d ist außerhalb des gültigen Bereichs (0..%d)" #: utils/adt/varchar.c:161 -#, fuzzy, c-format -#| msgid "value too long for type character(%d)" +#, c-format msgid "value too long for type character(%zu)" -msgstr "Wert zu lang für Typ character(%d)" +msgstr "Wert zu lang für Typ character(%zu)" #: utils/adt/varchar.c:312 #, c-format @@ -34679,10 +34185,9 @@ msgid "value too long for type character(%d)" msgstr "Wert zu lang für Typ character(%d)" #: utils/adt/varchar.c:478 -#, fuzzy, c-format -#| msgid "value too long for type character varying(%d)" +#, c-format msgid "value too long for type character varying(%zu)" -msgstr "Wert zu lang für Typ character varying(%d)" +msgstr "Wert zu lang für Typ character varying(%zu)" #: utils/adt/varchar.c:642 #, c-format @@ -34979,27 +34484,27 @@ msgstr "keine Ausgabefunktion verfügbar für Typ %s" msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" msgstr "in Operatorklasse »%s« für Zugriffsmethode %s fehlt Support-Funktion %d für Typ %s" -#: utils/cache/relcache.c:3809 +#: utils/cache/relcache.c:3811 #, c-format msgid "heap relfilenumber value not set when in binary upgrade mode" msgstr "Heap-Relfile-Nummer-Wert ist im Binary-Upgrade-Modus nicht gesetzt" -#: utils/cache/relcache.c:3817 +#: utils/cache/relcache.c:3819 #, c-format msgid "unexpected request for new relfilenumber in binary upgrade mode" msgstr "unerwartete Anforderung einer neuen Relfile-Nummer im Binary-Upgrade-Modus" -#: utils/cache/relcache.c:6668 +#: utils/cache/relcache.c:6670 #, c-format msgid "could not create relation-cache initialization file \"%s\": %m" msgstr "konnte Initialisierungsdatei für Relationscache »%s« nicht erzeugen: %m" -#: utils/cache/relcache.c:6670 +#: utils/cache/relcache.c:6672 #, c-format msgid "Continuing anyway, but there's something wrong." msgstr "Setze trotzdem fort, aber irgendwas stimmt nicht." -#: utils/cache/relcache.c:7000 +#: utils/cache/relcache.c:7002 #, c-format msgid "could not remove cache file \"%s\": %m" msgstr "konnte Cache-Datei »%s« nicht löschen: %m" @@ -35050,38 +34555,34 @@ msgid "could not reopen file \"%s\" as stdout: %m" msgstr "konnte Datei »%s« nicht als stdout neu öffnen: %m" #: utils/error/elog.c:2412 -#, fuzzy, c-format -#| msgid "interval specification not allowed here" +#, c-format msgid "Redundant specification of default log level." -msgstr "Intervallangabe hier nicht erlaubt" +msgstr "Redundante Angabe des Standard-Log-Levels." #: utils/error/elog.c:2430 -#, fuzzy, c-format -#| msgid "unrecognized origin value: \"%s\"" +#, c-format msgid "Unrecognized log level: \"%s\"." -msgstr "unbekannter Origin-Wert: »%s«" +msgstr "Unbekannter Log-Level: »%s«." #: utils/error/elog.c:2462 -#, fuzzy, c-format -#| msgid "unrecognized value for role option \"%s\": \"%s\"" +#, c-format msgid "Unrecognized log level for process type \"%s\": \"%s\"." -msgstr "unbekannter Wert für Rollenoption »%s«: »%s«" +msgstr "Unbekannter Log-Level für Prozesstyp »%s«: »%s«." #: utils/error/elog.c:2476 #, c-format msgid "Redundant log level specification for process type \"%s\"." -msgstr "" +msgstr "Redundante Log-Level-Angabe für Prozesstyp »%s«." #: utils/error/elog.c:2494 -#, fuzzy, c-format -#| msgid "unrecognized object type \"%s\"" +#, c-format msgid "Unrecognized process type \"%s\"." -msgstr "unbekannter Objekttyp »%s«" +msgstr "Unbekannter Prozesstyp »%s«." #: utils/error/elog.c:2516 #, c-format msgid "Default log level was not defined." -msgstr "" +msgstr "Standard-Log-Level wurde nicht definiert." #: utils/error/elog.c:2627 #, c-format @@ -35844,16 +35345,13 @@ msgstr "" "Kommandozeilenoption -D oder der Umgebungsvariable PGDATA angeben.\n" #: utils/misc/guc.c:1864 -#, fuzzy, c-format -#| msgid "" -#| "%s does not know where to find the \"hba\" configuration file.\n" -#| "This can be specified as \"hba_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +#, c-format msgid "" "%s does not know where to find the \"hosts\" configuration file.\n" "This can be specified as \"hosts_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" msgstr "" -"%s weiß nicht, wo die »hba«-Konfigurationsdatei zu finden ist.\n" -"Sie können dies mit »hba_file« in »%s«, mit der\n" +"%s weiß nicht, wo die »hosts«-Konfigurationsdatei zu finden ist.\n" +"Sie können dies mit »hosts_file« in »%s«, mit der\n" "Kommandozeilenoption -D oder der Umgebungsvariable PGDATA angeben.\n" #: utils/misc/guc.c:2845 @@ -35871,17 +35369,15 @@ msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g%s%s .. %g%s%s) msgstr "%g%s%s ist außerhalb des gültigen Bereichs für Parameter »%s« (%g%s%s ... %g%s%s)" #: utils/misc/guc.c:3170 -#, fuzzy -#| msgid "Available help:\n" msgid "Available values: " -msgstr "Verfügbare Hilfe:\n" +msgstr "Verfügbare Werte: " #. translator: This is the terminator of a list of entity #. names. #. #: utils/misc/guc.c:3176 msgid "." -msgstr "" +msgstr "." #. translator: This is a separator in a list of entity #. names. @@ -36012,10 +35508,9 @@ msgid "SET %s takes only one argument" msgstr "SET %s darf nur ein Argument haben" #: utils/misc/guc_funcs.c:272 -#, fuzzy, c-format -#| msgid "invalid value \"%s\" for \"%s\"" +#, c-format msgid "NULL is an invalid value for %s" -msgstr "ungültiger Wert »%s« für »%s«" +msgstr "NULL ist ein ungültiger Wert für %s" #: utils/misc/guc_funcs.c:370 #, c-format @@ -36047,10 +35542,8 @@ msgid "Connections and Authentication / SSL" msgstr "Verbindungen und Authentifizierung / SSL" #: utils/misc/guc_tables.c:744 -#, fuzzy -#| msgid "Resource Usage / Disk" msgid "Resource Usage / Time" -msgstr "Resourcenbenutzung / Festplatte" +msgstr "Resourcenbenutzung / Zeit" #: utils/misc/guc_tables.c:745 msgid "Resource Usage / Memory" @@ -36226,7 +35719,7 @@ msgid "internal error: unrecognized run-time parameter type\n" msgstr "interner Fehler: unbekannter Parametertyp\n" #: utils/misc/pg_controldata.c:50 utils/misc/pg_controldata.c:90 -#: utils/misc/pg_controldata.c:181 utils/misc/pg_controldata.c:222 +#: utils/misc/pg_controldata.c:184 utils/misc/pg_controldata.c:225 #, c-format msgid "calculated CRC checksum does not match value stored in file" msgstr "berechnete CRC-Prüfsumme stimmt nicht mit dem Wert in der Datei überein" @@ -36357,17 +35850,15 @@ msgstr "Fehler bei Anfrage mit Größe %zu im Speicherkontext »%s«." msgid "logging memory contexts of PID %d" msgstr "logge Speicherkontexte von PID %d" -#: utils/mmgr/mcxt.c:1747 -#, fuzzy, c-format -#| msgid "invalid memory allocation request size %zu + %zu\n" +#: utils/mmgr/mcxt.c:1754 +#, c-format msgid "invalid memory allocation request size %zu + %zu" -msgstr "ungültige Speicheranforderungsgröße %zu + %zu\n" +msgstr "ungültige Speicheranforderungsgröße %zu + %zu" -#: utils/mmgr/mcxt.c:1766 -#, fuzzy, c-format -#| msgid "invalid memory allocation request size %zu * %zu\n" +#: utils/mmgr/mcxt.c:1773 +#, c-format msgid "invalid memory allocation request size %zu * %zu" -msgstr "ungültige Speicheranforderungsgröße %zu * %zu\n" +msgstr "ungültige Speicheranforderungsgröße %zu * %zu" #: utils/mmgr/portalmem.c:189 #, c-format @@ -36502,59 +35993,3 @@ msgstr "eine serialisierbare Transaktion, die nicht im Read-Only-Modus ist, kann #, c-format msgid "cannot import a snapshot from a different database" msgstr "kann keinen Snapshot aus einer anderen Datenbank importieren" - -#, fuzzy, c-format -#~| msgid "This operation is not supported for partitioned tables." -#~ msgid "REPACK (CONCURRENTLY) is not supported for partitioned tables" -#~ msgstr "Diese Operation wird für partitionierte Tabellen nicht unterstützt." - -#, fuzzy, c-format -#~| msgid "column \"%s\" is in index used as replica identity" -#~ msgid "Relation \"%s\" has insufficient replication identity." -#~ msgstr "Spalte »%s« ist in einem Index, der als Replik-Identität verwendet wird" - -#, c-format -#~ msgid "The owner of a FOR ALL TABLES publication must be a superuser." -#~ msgstr "Der Eigentümer einer FOR-ALL-TABLES-Publikation muss ein Superuser sein." - -#, fuzzy, c-format -#~| msgid "cannot open relation \"%s\"" -#~ msgid "cannot process relation \"%s\"" -#~ msgstr "kann Relation »%s« nicht öffnen" - -#, fuzzy, c-format -#~| msgid "cannot lock relation \"%s\"" -#~ msgid "cannot repack relation \"%s\"" -#~ msgstr "kann Relation »%s« nicht sperren" - -#, c-format -#~ msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" -#~ msgstr "Spalte »%s« kann nicht in Statistiken verwendet werden, weil ihr Typ %s keine Standardoperatorklasse für btree hat" - -#, c-format -#~ msgid "expression cannot be used in multivariate statistics because its type %s has no default btree operator class" -#~ msgstr "Ausdruck kann nicht in multivariaten Statistiken verwendet werden, weil sein Typ %s keine Standardoperatorklasse für btree hat" - -#, fuzzy, c-format -#~| msgid "column \"%s\" specified more than once" -#~ msgid "option \"%s\" is specified more than once" -#~ msgstr "Spalte »%s« mehrmals angegeben" - -#, fuzzy, c-format -#~| msgid "name at variadic position %d is null" -#~ msgid "option name at variadic position %d is null" -#~ msgstr "Name auf variadischer Position %d ist NULL" - -#, c-format -#~ msgid "requested shared memory size overflows size_t" -#~ msgstr "angeforderte Shared-Memory-Größe übersteigt Kapazität von size_t" - -#, fuzzy, c-format -#~| msgid "unrecognized %s option \"%s\"" -#~ msgid "unrecognized option: \"%s\"" -#~ msgstr "unbekannte %s-Option »%s«" - -#, fuzzy, c-format -#~| msgid "argument \"%s\" must not be null" -#~ msgid "value for option \"%s\" must not be null" -#~ msgstr "Argument »%s« darf nicht NULL sein" diff --git a/src/backend/po/ru.po b/src/backend/po/ru.po index 9b2e7fbf9eb..5f4e6fd9b82 100644 --- a/src/backend/po/ru.po +++ b/src/backend/po/ru.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: postgres (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-10 08:01+0300\n" -"PO-Revision-Date: 2026-05-10 08:36+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-06 07:17+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -99,12 +99,12 @@ msgstr "не удалось открыть файл \"%s\" для чтения: #: access/transam/twophase.c:1354 access/transam/xlog.c:3478 #: access/transam/xlog.c:4369 access/transam/xlogrecovery.c:1257 #: access/transam/xlogrecovery.c:1355 access/transam/xlogrecovery.c:1392 -#: access/transam/xlogrecovery.c:1459 backup/basebackup.c:2128 +#: access/transam/xlogrecovery.c:1459 backup/basebackup.c:2126 #: backup/walsummary.c:283 commands/extension.c:3970 libpq/hba.c:769 #: replication/logical/origin.c:768 replication/logical/origin.c:804 -#: replication/logical/reorderbuffer.c:5366 -#: replication/logical/snapbuild.c:1951 replication/slot.c:2546 -#: replication/slot.c:2587 replication/walsender.c:643 +#: replication/logical/reorderbuffer.c:5390 +#: replication/logical/snapbuild.c:1951 replication/slot.c:2548 +#: replication/slot.c:2589 replication/walsender.c:643 #: storage/file/buffile.c:470 storage/file/copydir.c:201 #: utils/adt/genfile.c:197 utils/adt/misc.c:1028 utils/cache/relmapper.c:829 #, c-format @@ -114,8 +114,8 @@ msgstr "не удалось прочитать файл \"%s\": %m" #: ../common/controldata_utils.c:116 ../common/controldata_utils.c:119 #: access/transam/xlog.c:3483 access/transam/xlog.c:4374 #: replication/logical/origin.c:773 replication/logical/origin.c:812 -#: replication/logical/snapbuild.c:1956 replication/slot.c:2550 -#: replication/slot.c:2591 replication/walsender.c:648 +#: replication/logical/snapbuild.c:1956 replication/slot.c:2552 +#: replication/slot.c:2593 replication/walsender.c:648 #: utils/cache/relmapper.c:833 #, c-format msgid "could not read file \"%s\": read %d of %zu" @@ -132,9 +132,9 @@ msgstr "не удалось прочитать файл \"%s\" (прочитан #: access/transam/xlog.c:5311 commands/copyfrom.c:1929 commands/copyto.c:598 #: libpq/be-fsstubs.c:475 libpq/be-fsstubs.c:545 #: replication/logical/origin.c:706 replication/logical/origin.c:845 -#: replication/logical/reorderbuffer.c:5418 +#: replication/logical/reorderbuffer.c:5442 #: replication/logical/snapbuild.c:1696 replication/logical/snapbuild.c:1822 -#: replication/slot.c:2432 replication/slot.c:2598 replication/walsender.c:658 +#: replication/slot.c:2434 replication/slot.c:2600 replication/walsender.c:658 #: storage/file/copydir.c:224 storage/file/copydir.c:229 #: storage/file/copydir.c:284 storage/file/copydir.c:289 storage/file/fd.c:828 #: storage/file/fd.c:3818 storage/file/fd.c:3924 utils/cache/relmapper.c:841 @@ -169,16 +169,16 @@ msgstr "" #: access/transam/twophase.c:1310 access/transam/xlog.c:3214 #: access/transam/xlog.c:3394 access/transam/xlog.c:3433 #: access/transam/xlog.c:3626 access/transam/xlog.c:4359 -#: access/transam/xlogrecovery.c:4307 access/transam/xlogrecovery.c:4408 -#: access/transam/xlogutils.c:825 backup/basebackup.c:549 -#: backup/basebackup.c:1600 backup/walsummary.c:220 libpq/hba.c:626 -#: postmaster/syslogger.c:1512 replication/logical/origin.c:758 -#: replication/logical/reorderbuffer.c:4019 -#: replication/logical/reorderbuffer.c:4573 -#: replication/logical/reorderbuffer.c:5346 +#: access/transam/xlogrecovery.c:4309 access/transam/xlogrecovery.c:4410 +#: access/transam/xlogutils.c:849 backup/basebackup.c:549 +#: backup/basebackup.c:1598 backup/walsummary.c:220 libpq/hba.c:626 +#: postmaster/syslogger.c:1512 postmaster/walsummarizer.c:1617 +#: replication/logical/origin.c:758 replication/logical/reorderbuffer.c:4043 +#: replication/logical/reorderbuffer.c:4597 +#: replication/logical/reorderbuffer.c:5370 #: replication/logical/snapbuild.c:1651 replication/logical/snapbuild.c:1763 -#: replication/slot.c:2518 replication/walsender.c:616 -#: replication/walsender.c:3103 storage/file/copydir.c:167 +#: replication/slot.c:2520 replication/walsender.c:616 +#: replication/walsender.c:3125 storage/file/copydir.c:167 #: storage/file/copydir.c:255 storage/file/fd.c:803 storage/file/fd.c:3575 #: storage/file/fd.c:3805 storage/file/fd.c:3895 storage/smgr/md.c:686 #: utils/cache/relmapper.c:818 utils/cache/relmapper.c:935 @@ -191,7 +191,7 @@ msgstr "не удалось открыть файл \"%s\": %m" #: ../common/controldata_utils.c:246 ../common/controldata_utils.c:249 #: access/transam/twophase.c:1757 access/transam/twophase.c:1766 -#: access/transam/xlog.c:9340 access/transam/xlogfuncs.c:699 +#: access/transam/xlog.c:9342 access/transam/xlogfuncs.c:699 #: backup/basebackup_server.c:173 backup/basebackup_server.c:266 #: backup/walsummary.c:304 postmaster/postmaster.c:4087 #: postmaster/syslogger.c:1523 postmaster/syslogger.c:1536 @@ -206,10 +206,10 @@ msgstr "не удалось записать файл \"%s\": %m" #: access/heap/rewriteheap.c:1240 access/transam/timeline.c:432 #: access/transam/timeline.c:506 access/transam/twophase.c:1778 #: access/transam/xlog.c:3314 access/transam/xlog.c:3512 -#: access/transam/xlog.c:4332 access/transam/xlog.c:8726 -#: access/transam/xlog.c:8770 backup/basebackup_server.c:207 +#: access/transam/xlog.c:4332 access/transam/xlog.c:8728 +#: access/transam/xlog.c:8772 backup/basebackup_server.c:207 #: commands/dbcommands.c:515 replication/logical/snapbuild.c:1689 -#: replication/slot.c:2416 replication/slot.c:2528 storage/file/fd.c:820 +#: replication/slot.c:2418 replication/slot.c:2530 storage/file/fd.c:820 #: storage/file/fd.c:3916 storage/smgr/md.c:1469 storage/smgr/md.c:1529 #: storage/sync/sync.c:446 utils/misc/guc.c:4527 #, c-format @@ -222,13 +222,13 @@ msgstr "не удалось синхронизировать с ФС файл \" #: ../common/hmac_openssl.c:151 ../common/hmac_openssl.c:339 #: ../common/jsonapi.c:2459 ../common/md5_common.c:156 #: ../common/parse_manifest.c:157 ../common/parse_manifest.c:852 -#: ../common/psprintf.c:140 ../common/scram-common.c:268 ../port/path.c:829 -#: ../port/path.c:866 ../port/path.c:883 access/transam/twophase.c:1419 +#: ../common/psprintf.c:140 ../common/scram-common.c:268 ../port/path.c:846 +#: ../port/path.c:883 ../port/path.c:900 access/transam/twophase.c:1419 #: access/transam/xlogrecovery.c:571 lib/dshash.c:253 libpq/auth.c:1353 #: libpq/auth.c:1397 libpq/auth.c:1959 libpq/be-secure-gssapi.c:537 #: libpq/be-secure-gssapi.c:717 postmaster/bgworker.c:355 #: postmaster/bgworker.c:1023 postmaster/postmaster.c:3557 -#: postmaster/walsummarizer.c:939 +#: postmaster/walsummarizer.c:1038 #: replication/libpqwalreceiver/libpqwalreceiver.c:364 #: replication/logical/logical.c:212 replication/walsender.c:825 #: storage/buffer/localbuf.c:745 storage/file/fd.c:912 storage/file/fd.c:1447 @@ -245,7 +245,7 @@ msgstr "не удалось синхронизировать с ФС файл \" #: utils/misc/guc.c:672 utils/misc/guc.c:1060 utils/misc/guc.c:4505 #: utils/misc/tzparser.c:479 utils/mmgr/aset.c:451 utils/mmgr/bump.c:183 #: utils/mmgr/dsa.c:707 utils/mmgr/dsa.c:729 utils/mmgr/dsa.c:810 -#: utils/mmgr/generation.c:215 utils/mmgr/mcxt.c:1162 utils/mmgr/slab.c:370 +#: utils/mmgr/generation.c:215 utils/mmgr/mcxt.c:1165 utils/mmgr/slab.c:370 #, c-format msgid "out of memory" msgstr "нехватка памяти" @@ -309,20 +309,30 @@ msgstr "команда \"%s\" не выдала данные" msgid "%s() failed: %m" msgstr "ошибка в %s(): %m" -#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 -#: ../common/fe_memutils.c:98 ../common/fe_memutils.c:161 -#: ../common/psprintf.c:142 ../port/path.c:831 ../port/path.c:868 -#: ../port/path.c:885 utils/misc/ps_status.c:195 utils/misc/ps_status.c:203 +#: ../common/fe_memutils.c:41 ../common/fe_memutils.c:81 +#: ../common/fe_memutils.c:104 ../common/fe_memutils.c:167 +#: ../common/psprintf.c:142 ../port/path.c:848 ../port/path.c:885 +#: ../port/path.c:902 utils/misc/ps_status.c:195 utils/misc/ps_status.c:203 #: utils/misc/ps_status.c:230 utils/misc/ps_status.c:238 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../common/fe_memutils.c:92 ../common/fe_memutils.c:153 +#: ../common/fe_memutils.c:98 ../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../common/file_utils.c:75 storage/file/fd.c:3581 #, c-format msgid "could not synchronize file system for file \"%s\": %m" @@ -365,8 +375,8 @@ msgstr "не удалось прочитать каталог \"%s\": %m" #: ../common/file_utils.c:520 access/transam/xlogarchive.c:389 #: postmaster/pgarch.c:836 postmaster/syslogger.c:1560 -#: replication/logical/snapbuild.c:1708 replication/slot.c:1027 -#: replication/slot.c:2299 replication/slot.c:2448 storage/file/fd.c:838 +#: replication/logical/snapbuild.c:1708 replication/slot.c:1029 +#: replication/slot.c:2301 replication/slot.c:2450 storage/file/fd.c:838 #: utils/time/snapmgr.c:1273 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" @@ -601,7 +611,7 @@ msgstr "не удалось декодировать имя файла" msgid "file size is not an integer" msgstr "размер файла не является целочисленным" -#: ../common/parse_manifest.c:699 backup/basebackup.c:872 +#: ../common/parse_manifest.c:699 backup/basebackup.c:870 #, c-format msgid "unrecognized checksum algorithm: \"%s\"" msgstr "нераспознанный алгоритм расчёта контрольных сумм: \"%s\"" @@ -670,7 +680,7 @@ msgstr "не удалось разобрать манифест копии: %s" #: ../common/percentrepl.c:79 ../common/percentrepl.c:85 #: ../common/percentrepl.c:118 ../common/percentrepl.c:124 -#: tcop/backend_startup.c:769 utils/misc/guc.c:3164 utils/misc/guc.c:3205 +#: tcop/backend_startup.c:788 utils/misc/guc.c:3164 utils/misc/guc.c:3205 #: utils/misc/guc.c:3280 utils/misc/guc.c:4709 utils/misc/guc.c:6940 #: utils/misc/guc.c:6981 #, c-format @@ -737,9 +747,9 @@ msgstr "не удалось получить код выхода от подпр #: access/transam/twophase.c:1717 access/transam/xlogarchive.c:119 #: access/transam/xlogarchive.c:399 backup/walsummary.c:254 #: postmaster/postmaster.c:1070 postmaster/syslogger.c:1489 -#: replication/logical/origin.c:614 replication/logical/reorderbuffer.c:4841 +#: replication/logical/origin.c:614 replication/logical/reorderbuffer.c:4865 #: replication/logical/snapbuild.c:1589 replication/logical/snapbuild.c:2045 -#: replication/slot.c:2502 storage/file/fd.c:878 storage/file/fd.c:3443 +#: replication/slot.c:2504 storage/file/fd.c:878 storage/file/fd.c:3443 #: storage/file/fd.c:3505 storage/file/reinit.c:261 storage/ipc/dsm.c:343 #: storage/smgr/md.c:401 storage/smgr/md.c:460 storage/sync/sync.c:243 #: utils/time/snapmgr.c:1609 @@ -891,7 +901,7 @@ msgstr "" "Возможно, работе СУБД мешает антивирус, программа резервного копирования или " "что-то подобное." -#: ../port/path.c:853 +#: ../port/path.c:870 #, c-format msgid "could not get current working directory: %m\n" msgstr "не удалось определить текущий рабочий каталог: %m\n" @@ -932,8 +942,8 @@ msgstr "" #: access/transam/xlogfuncs.c:242 access/transam/xlogfuncs.c:281 #: access/transam/xlogfuncs.c:302 access/transam/xlogfuncs.c:323 #: access/transam/xlogfuncs.c:389 access/transam/xlogfuncs.c:447 -#: statistics/attribute_stats.c:191 statistics/attribute_stats.c:936 -#: statistics/relation_stats.c:97 +#: statistics/attribute_stats.c:191 statistics/attribute_stats.c:962 +#: statistics/relation_stats.c:99 #, c-format msgid "recovery is in progress" msgstr "идёт процесс восстановления" @@ -1265,7 +1275,7 @@ msgstr "не удалось повторно найти кортеж в инде #: access/gin/gininsert.c:1310 access/gin/ginutil.c:152 #: executor/execExpr.c:2244 utils/adt/array_userfuncs.c:1972 -#: utils/adt/arrayfuncs.c:4034 utils/adt/arrayfuncs.c:6732 +#: utils/adt/arrayfuncs.c:4034 utils/adt/arrayfuncs.c:6739 #: utils/adt/rowtypes.c:974 utils/sort/tuplesortvariants.c:646 #, c-format msgid "could not identify a comparison function for type %s" @@ -1389,11 +1399,11 @@ msgstr "" #: access/hash/hashfunc.c:281 access/hash/hashfunc.c:336 catalog/heap.c:702 #: catalog/heap.c:708 commands/createas.c:203 commands/createas.c:515 -#: commands/indexcmds.c:2092 commands/tablecmds.c:19999 commands/view.c:80 +#: commands/indexcmds.c:2092 commands/tablecmds.c:19998 commands/view.c:80 #: regex/regc_pg_locale.c:242 utils/adt/formatting.c:1657 #: utils/adt/formatting.c:1721 utils/adt/formatting.c:1785 #: utils/adt/formatting.c:1849 utils/adt/like.c:163 utils/adt/like.c:194 -#: utils/adt/like_support.c:1020 utils/adt/varchar.c:738 +#: utils/adt/like_support.c:1032 utils/adt/varchar.c:738 #: utils/adt/varchar.c:1001 utils/adt/varchar.c:1057 utils/adt/varlena.c:1648 #, c-format msgid "Use the COLLATE clause to set the collation explicitly." @@ -1451,39 +1461,39 @@ msgid "" msgstr "" "в семействе операторов \"%s\" метода доступа %s нет межтипового оператора(ов)" -#: access/heap/heapam.c:2283 +#: access/heap/heapam.c:2310 #, c-format msgid "cannot insert tuples in a parallel worker" msgstr "вставлять кортежи в параллельном исполнителе нельзя" -#: access/heap/heapam.c:2806 +#: access/heap/heapam.c:2862 #, c-format msgid "cannot delete tuples during a parallel operation" msgstr "удалять кортежи во время параллельных операций нельзя" -#: access/heap/heapam.c:2853 +#: access/heap/heapam.c:2909 #, c-format msgid "attempted to delete invisible tuple" msgstr "попытка удаления невидимого кортежа" -#: access/heap/heapam.c:3303 access/index/genam.c:829 +#: access/heap/heapam.c:3387 access/index/genam.c:829 #, c-format msgid "cannot update tuples during a parallel operation" msgstr "изменять кортежи во время параллельных операций нельзя" -#: access/heap/heapam.c:3480 +#: access/heap/heapam.c:3564 #, c-format msgid "attempted to update invisible tuple" msgstr "попытка изменения невидимого кортежа" -#: access/heap/heapam.c:4993 access/heap/heapam.c:5031 -#: access/heap/heapam.c:5298 access/heap/heapam_handler.c:470 +#: access/heap/heapam.c:5196 access/heap/heapam.c:5234 +#: access/heap/heapam.c:5524 access/heap/heapam_handler.c:470 #, c-format msgid "could not obtain lock on row in relation \"%s\"" msgstr "не удалось получить блокировку строки в таблице \"%s\"" -#: access/heap/heapam.c:6425 commands/trigger.c:3401 -#: executor/nodeModifyTable.c:2568 executor/nodeModifyTable.c:2658 +#: access/heap/heapam.c:6678 commands/trigger.c:3401 +#: executor/nodeModifyTable.c:2587 executor/nodeModifyTable.c:2677 #, c-format msgid "" "tuple to be updated was already modified by an operation triggered by the " @@ -1514,12 +1524,12 @@ msgstr "не удалось записать в файл \"%s\" (записан #: access/heap/rewriteheap.c:977 access/heap/rewriteheap.c:1094 #: access/transam/timeline.c:329 access/transam/timeline.c:481 #: access/transam/xlog.c:3239 access/transam/xlog.c:3447 -#: access/transam/xlog.c:4311 access/transam/xlog.c:9329 +#: access/transam/xlog.c:4311 access/transam/xlog.c:9331 #: access/transam/xlogfuncs.c:693 backup/basebackup_server.c:149 #: backup/basebackup_server.c:242 commands/dbcommands.c:495 #: postmaster/launch_backend.c:354 postmaster/postmaster.c:4074 -#: postmaster/walsummarizer.c:1216 replication/logical/origin.c:626 -#: replication/slot.c:2360 storage/file/copydir.c:173 +#: postmaster/walsummarizer.c:1315 replication/logical/origin.c:626 +#: replication/slot.c:2362 storage/file/copydir.c:173 #: storage/file/copydir.c:261 storage/smgr/md.c:252 utils/time/snapmgr.c:1252 #, c-format msgid "could not create file \"%s\": %m" @@ -1532,12 +1542,12 @@ msgstr "не удалось обрезать файл \"%s\" до нужного #: access/heap/rewriteheap.c:1122 access/transam/timeline.c:384 #: access/transam/timeline.c:424 access/transam/timeline.c:498 -#: access/transam/xlog.c:3300 access/transam/xlog.c:3503 +#: access/transam/xlog.c:3292 access/transam/xlog.c:3503 #: access/transam/xlog.c:4323 commands/dbcommands.c:507 #: postmaster/launch_backend.c:365 postmaster/launch_backend.c:377 #: replication/logical/origin.c:638 replication/logical/origin.c:680 #: replication/logical/origin.c:699 replication/logical/snapbuild.c:1665 -#: replication/slot.c:2396 storage/file/buffile.c:545 +#: replication/slot.c:2398 storage/file/buffile.c:545 #: storage/file/copydir.c:213 utils/init/miscinit.c:1661 #: utils/init/miscinit.c:1672 utils/init/miscinit.c:1680 utils/misc/guc.c:4488 #: utils/misc/guc.c:4519 utils/misc/guc.c:5678 utils/misc/guc.c:5696 @@ -1871,7 +1881,7 @@ msgstr "индекс \"%s\" перестраивается, обращаться #: access/index/indexam.c:203 catalog/objectaddress.c:1361 #: commands/indexcmds.c:3018 commands/tablecmds.c:284 commands/tablecmds.c:308 -#: commands/tablecmds.c:19678 commands/tablecmds.c:21620 +#: commands/tablecmds.c:19677 commands/tablecmds.c:21619 #, c-format msgid "\"%s\" is not an index" msgstr "\"%s\" - это не индекс" @@ -2005,7 +2015,7 @@ msgid "\"%s\" cannot be empty." msgstr "Значение \"%s\" не может быть пустым." # well-spelled: симв -#: access/table/tableamapi.c:113 access/transam/xlogrecovery.c:4912 +#: access/table/tableamapi.c:113 access/transam/xlogrecovery.c:4914 #, c-format msgid "\"%s\" is too long (maximum %d characters)." msgstr "Длина \"%s\" превышает предел (%d симв.)." @@ -2058,16 +2068,14 @@ msgstr "" #: access/transam/multixact.c:1268 access/transam/multixact.c:1275 #: access/transam/multixact.c:1299 access/transam/multixact.c:1308 -#: access/transam/varsup.c:158 access/transam/varsup.c:165 #, c-format msgid "" "Execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions, or " -"drop stale replication slots." +"You might also need to commit or roll back old prepared transactions." msgstr "" "Выполните очистку (VACUUM) всей базы данных.\n" -"Возможно, вам также придётся зафиксировать или откатить старые " -"подготовленные транзакции и удалить неиспользуемые слоты репликации." +"Возможно, вам также придётся зафиксировать или откатить старые\n" +"подготовленные транзакции." #: access/transam/multixact.c:1273 #, c-format @@ -2189,13 +2197,12 @@ msgstr "для мультитранзакции %u получено некорр msgid "" "To avoid MultiXactId assignment failures, execute a database-wide VACUUM in " "that database.\n" -"You might also need to commit or roll back old prepared transactions, or " -"drop stale replication slots." +"You might also need to commit or roll back old prepared transactions." msgstr "" "Во избежание сбоев при назначении MultiXactId, выполните очистку (VACUUM) " "всей базы.\n" "Возможно, вам также придётся зафиксировать или откатить старые " -"подготовленные транзакции и удалить неиспользуемые слоты репликации." +"подготовленные транзакции." #: access/transam/multixact.c:2947 #, c-format @@ -2443,7 +2450,7 @@ msgid "Timeline IDs must be less than child timeline's ID." msgstr "" "Идентификаторы линий времени должны быть меньше идентификатора линии-потомка." -#: access/transam/timeline.c:589 +#: access/transam/timeline.c:589 postmaster/walsummarizer.c:930 #, c-format msgid "requested timeline %u is not in this server's history" msgstr "в истории сервера нет запрошенной линии времени %u" @@ -2556,7 +2563,7 @@ msgstr "" "в файле \"%s\"" #: access/transam/twophase.c:1420 access/transam/xlogrecovery.c:572 -#: postmaster/walsummarizer.c:940 replication/logical/logical.c:213 +#: postmaster/walsummarizer.c:1039 replication/logical/logical.c:213 #: replication/walsender.c:826 #, c-format msgid "Failed while allocating a WAL reading processor." @@ -2661,6 +2668,17 @@ msgstr "" "транзакций, во избежание потери данных из-за зацикливания в базе данных " "\"%s\"" +#: access/transam/varsup.c:158 access/transam/varsup.c:165 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." +msgstr "" +"Выполните очистку (VACUUM) всей базы данных.\n" +"Возможно, вам также придётся зафиксировать или откатить старые " +"подготовленные транзакции и удалить неиспользуемые слоты репликации." + #: access/transam/varsup.c:163 #, c-format msgid "" @@ -2851,14 +2869,14 @@ msgid "The WAL segment size must be a power of two between 1 MB and 1 GB." msgstr "" "Размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 ГБ." -#: access/transam/xlog.c:2454 +#: access/transam/xlog.c:2451 #, c-format msgid "could not write to log file \"%s\" at offset %u, length %zu: %m" msgstr "" "не удалось записать в файл журнала \"%s\" (смещение: %u, длина: %zu): %m" -#: access/transam/xlog.c:3740 access/transam/xlogutils.c:820 -#: replication/walsender.c:3097 +#: access/transam/xlog.c:3740 access/transam/xlogutils.c:844 +#: postmaster/walsummarizer.c:1631 replication/walsender.c:3119 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "запрошенный сегмент WAL %s уже удалён" @@ -3006,7 +3024,7 @@ msgstr "\"%s\" должно быть как минимум вдвое больш #: access/transam/xlog.c:4725 catalog/namespace.c:4699 #: commands/tablespace.c:1210 commands/user.c:2531 commands/variable.c:72 -#: replication/slot.c:2768 tcop/postgres.c:3630 utils/error/elog.c:2257 +#: replication/slot.c:2770 tcop/postgres.c:3630 utils/error/elog.c:2257 #, c-format msgid "List syntax is invalid." msgstr "Ошибка синтаксиса в списке." @@ -3143,25 +3161,25 @@ msgstr "выбранный ID новой линии времени: %u" msgid "archive recovery complete" msgstr "восстановление архива завершено" -#: access/transam/xlog.c:6653 +#: access/transam/xlog.c:6655 #, c-format msgid "shutting down" msgstr "выключение" #. translator: the placeholders show checkpoint options -#: access/transam/xlog.c:6692 +#: access/transam/xlog.c:6694 #, c-format msgid "restartpoint starting:%s%s%s%s%s%s%s%s" msgstr "начата точка перезапуска:%s%s%s%s%s%s%s%s" #. translator: the placeholders show checkpoint options -#: access/transam/xlog.c:6704 +#: access/transam/xlog.c:6706 #, c-format msgid "checkpoint starting:%s%s%s%s%s%s%s%s" msgstr "начата контрольная точка:%s%s%s%s%s%s%s%s" # well-spelled: синхр -#: access/transam/xlog.c:6769 +#: access/transam/xlog.c:6771 #, c-format msgid "" "restartpoint complete: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d " @@ -3176,7 +3194,7 @@ msgstr "" "%03d сек.; расстояние=%d КБ, ожидалось=%d КБ; lsn=%X/%X, lsn redo=%X/%X" # well-spelled: синхр -#: access/transam/xlog.c:6793 +#: access/transam/xlog.c:6795 #, c-format msgid "" "checkpoint complete: wrote %d buffers (%.1f%%), wrote %d SLRU buffers; %d " @@ -3190,7 +3208,7 @@ msgstr "" "синхронизировано_файлов=%d, самая_долгая_синхр.=%ld.%03d сек., средняя=%ld." "%03d сек.; расстояние=%d КБ, ожидалось=%d КБ; lsn=%X/%X, lsn redo=%X/%X" -#: access/transam/xlog.c:7279 +#: access/transam/xlog.c:7281 #, c-format msgid "" "concurrent write-ahead log activity while database system is shutting down" @@ -3198,64 +3216,64 @@ msgstr "" "во время выключения системы баз данных отмечена активность в журнале " "предзаписи" -#: access/transam/xlog.c:7871 +#: access/transam/xlog.c:7873 #, c-format msgid "recovery restart point at %X/%X" msgstr "точка перезапуска восстановления в позиции %X/%X" -#: access/transam/xlog.c:7873 +#: access/transam/xlog.c:7875 #, c-format msgid "Last completed transaction was at log time %s." msgstr "Последняя завершённая транзакция была выполнена в %s." -#: access/transam/xlog.c:8137 +#: access/transam/xlog.c:8139 #, c-format msgid "restore point \"%s\" created at %X/%X" msgstr "точка восстановления \"%s\" создана в позиции %X/%X" -#: access/transam/xlog.c:8344 +#: access/transam/xlog.c:8346 #, c-format msgid "online backup was canceled, recovery cannot continue" msgstr "" "резервное копирование \"на ходу\" было отменено, продолжить восстановление " "нельзя" -#: access/transam/xlog.c:8402 +#: access/transam/xlog.c:8404 #, c-format msgid "unexpected timeline ID %u (should be %u) in shutdown checkpoint record" msgstr "" "неожиданный ID линии времени %u (должен быть %u) в записи точки выключения" -#: access/transam/xlog.c:8468 +#: access/transam/xlog.c:8470 #, c-format msgid "unexpected timeline ID %u (should be %u) in online checkpoint record" msgstr "" "неожиданный ID линии времени %u (должен быть %u) в записи точки активности" -#: access/transam/xlog.c:8505 +#: access/transam/xlog.c:8507 #, c-format msgid "unexpected timeline ID %u (should be %u) in end-of-recovery record" msgstr "" "неожиданный ID линии времени %u (должен быть %u) в записи конец-" "восстановления" -#: access/transam/xlog.c:8775 +#: access/transam/xlog.c:8777 #, c-format msgid "could not fsync write-through file \"%s\": %m" msgstr "не удалось синхронизировать с ФС файл сквозной записи %s: %m" -#: access/transam/xlog.c:8780 +#: access/transam/xlog.c:8782 #, c-format msgid "could not fdatasync file \"%s\": %m" msgstr "не удалось синхронизировать с ФС данные (fdatasync) файла \"%s\": %m" -#: access/transam/xlog.c:8857 access/transam/xlog.c:9193 +#: access/transam/xlog.c:8859 access/transam/xlog.c:9195 #, c-format msgid "WAL level not sufficient for making an online backup" msgstr "" "Выбранный уровень WAL недостаточен для резервного копирования \"на ходу\"" -#: access/transam/xlog.c:8858 access/transam/xlog.c:9194 +#: access/transam/xlog.c:8860 access/transam/xlog.c:9196 #: access/transam/xlogfuncs.c:249 #, c-format msgid "" @@ -3264,12 +3282,12 @@ msgstr "" "Параметр \"wal_level\" должен иметь значение \"replica\" или \"logical\" при " "запуске сервера." -#: access/transam/xlog.c:8863 +#: access/transam/xlog.c:8865 #, c-format msgid "backup label too long (max %d bytes)" msgstr "длина метки резервной копии превышает предел (%d байт)" -#: access/transam/xlog.c:8984 +#: access/transam/xlog.c:8986 #, c-format msgid "" "WAL generated with \"full_page_writes=off\" was replayed since last " @@ -3278,7 +3296,7 @@ msgstr "" "после последней точки перезапуска был воспроизведён WAL, созданный в режиме " "\"full_page_writes=off\"" -#: access/transam/xlog.c:8986 access/transam/xlog.c:9282 +#: access/transam/xlog.c:8988 access/transam/xlog.c:9284 #, c-format msgid "" "This means that the backup being taken on the standby is corrupt and should " @@ -3290,23 +3308,23 @@ msgstr "" "CHECKPOINT на ведущем сервере, а затем попробуйте резервное копирование \"на " "ходу\" ещё раз." -#: access/transam/xlog.c:9066 backup/basebackup.c:1419 utils/adt/misc.c:354 +#: access/transam/xlog.c:9068 backup/basebackup.c:1417 utils/adt/misc.c:354 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "не удалось прочитать символическую ссылку \"%s\": %m" -#: access/transam/xlog.c:9073 backup/basebackup.c:1424 utils/adt/misc.c:359 +#: access/transam/xlog.c:9075 backup/basebackup.c:1422 utils/adt/misc.c:359 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "целевой путь символической ссылки \"%s\" слишком длинный" -#: access/transam/xlog.c:9232 backup/basebackup.c:1283 +#: access/transam/xlog.c:9234 backup/basebackup.c:1281 #, c-format msgid "the standby was promoted during online backup" msgstr "" "ведомый сервер был повышен в процессе резервного копирования \"на ходу\"" -#: access/transam/xlog.c:9233 backup/basebackup.c:1284 +#: access/transam/xlog.c:9235 backup/basebackup.c:1282 #, c-format msgid "" "This means that the backup being taken is corrupt and should not be used. " @@ -3315,7 +3333,7 @@ msgstr "" "Это означает, что создаваемая резервная копия испорчена и использовать её не " "следует. Попробуйте резервное копирование \"на ходу\" ещё раз." -#: access/transam/xlog.c:9280 +#: access/transam/xlog.c:9282 #, c-format msgid "" "WAL generated with \"full_page_writes=off\" was replayed during online backup" @@ -3323,13 +3341,13 @@ msgstr "" "в процессе резервного копирования \"на ходу\" был воспроизведён WAL, " "созданный в режиме \"full_page_writes=off\"" -#: access/transam/xlog.c:9396 +#: access/transam/xlog.c:9398 #, c-format msgid "base backup done, waiting for required WAL segments to be archived" msgstr "" "базовое копирование выполнено, ожидается архивация нужных сегментов WAL" -#: access/transam/xlog.c:9410 +#: access/transam/xlog.c:9412 #, c-format msgid "" "still waiting for all required WAL segments to be archived (%d seconds " @@ -3337,7 +3355,7 @@ msgid "" msgstr "" "продолжается ожидание архивации всех нужных сегментов WAL (прошло %d сек.)" -#: access/transam/xlog.c:9412 +#: access/transam/xlog.c:9414 #, c-format msgid "" "Check that your \"archive_command\" is executing properly. You can safely " @@ -3348,12 +3366,12 @@ msgstr "" "копирования можно отменить безопасно, но резервная копия базы будет " "непригодна без всех сегментов WAL." -#: access/transam/xlog.c:9419 +#: access/transam/xlog.c:9421 #, c-format msgid "all required WAL segments have been archived" msgstr "все нужные сегменты WAL заархивированы" -#: access/transam/xlog.c:9423 +#: access/transam/xlog.c:9425 #, c-format msgid "" "WAL archiving is not enabled; you must ensure that all required WAL segments " @@ -3362,7 +3380,7 @@ msgstr "" "архивация WAL не настроена; вы должны обеспечить копирование всех требуемых " "сегментов WAL другими средствами для получения резервной копии" -#: access/transam/xlog.c:9462 +#: access/transam/xlog.c:9464 #, c-format msgid "aborting backup due to backend exiting before pg_backup_stop was called" msgstr "" @@ -3409,7 +3427,7 @@ msgstr "не удалось создать файл состояния архи msgid "could not write archive status file \"%s\": %m" msgstr "не удалось записать файл состояния архива \"%s\": %m" -#: access/transam/xlogfuncs.c:70 backup/basebackup.c:999 +#: access/transam/xlogfuncs.c:70 backup/basebackup.c:997 #, c-format msgid "a backup is already in progress in this session" msgstr "резервное копирование уже выполняется в этом сеансе" @@ -3621,23 +3639,23 @@ msgstr "" "нарушение последовательности ID линии времени %u (после %u) в сегменте WAL " "%s, LSN %X/%X, смещение %u" -#: access/transam/xlogreader.c:1769 +#: access/transam/xlogreader.c:1771 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "идентификатор блока %u идёт не по порядку в позиции %X/%X" -#: access/transam/xlogreader.c:1793 +#: access/transam/xlogreader.c:1795 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA установлен, но данных в позиции %X/%X нет" -#: access/transam/xlogreader.c:1800 +#: access/transam/xlogreader.c:1802 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "" "BKPBLOCK_HAS_DATA не установлен, но длина данных равна %u в позиции %X/%X" -#: access/transam/xlogreader.c:1836 +#: access/transam/xlogreader.c:1838 #, c-format msgid "" "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at " @@ -3646,21 +3664,21 @@ msgstr "" "BKPIMAGE_HAS_HOLE установлен, но для пропуска заданы смещение %u и длина %u " "при длине образа блока %u в позиции %X/%X" -#: access/transam/xlogreader.c:1852 +#: access/transam/xlogreader.c:1854 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "" "BKPIMAGE_HAS_HOLE не установлен, но для пропуска заданы смещение %u и длина " "%u в позиции %X/%X" -#: access/transam/xlogreader.c:1866 +#: access/transam/xlogreader.c:1868 #, c-format msgid "BKPIMAGE_COMPRESSED set, but block image length %u at %X/%X" msgstr "" "BKPIMAGE_COMPRESSED установлен, но длина образа блока равна %u в позиции %X/" "%X" -#: access/transam/xlogreader.c:1881 +#: access/transam/xlogreader.c:1883 #, c-format msgid "" "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image " @@ -3669,41 +3687,41 @@ msgstr "" "ни BKPIMAGE_HAS_HOLE, ни BKPIMAGE_COMPRESSED не установлены, но длина образа " "блока равна %u в позиции %X/%X" -#: access/transam/xlogreader.c:1897 +#: access/transam/xlogreader.c:1899 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "" "BKPBLOCK_SAME_REL установлен, но предыдущее значение не задано в позиции %X/" "%X" -#: access/transam/xlogreader.c:1909 +#: access/transam/xlogreader.c:1911 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "неверный идентификатор блока %u в позиции %X/%X" -#: access/transam/xlogreader.c:1976 +#: access/transam/xlogreader.c:1978 #, c-format msgid "record with invalid length at %X/%X" msgstr "запись с неверной длиной в позиции %X/%X" -#: access/transam/xlogreader.c:2002 +#: access/transam/xlogreader.c:2004 #, c-format msgid "could not locate backup block with ID %d in WAL record" msgstr "не удалось найти копию блока с ID %d в записи журнала WAL" -#: access/transam/xlogreader.c:2086 +#: access/transam/xlogreader.c:2088 #, c-format msgid "could not restore image at %X/%X with invalid block %d specified" msgstr "" "не удалось восстановить образ в позиции %X/%X с указанным неверным блоком %d" -#: access/transam/xlogreader.c:2093 +#: access/transam/xlogreader.c:2095 #, c-format msgid "could not restore image at %X/%X with invalid state, block %d" msgstr "" "не удалось восстановить образ в позиции %X/%X с неверным состоянием, блок %d" -#: access/transam/xlogreader.c:2120 access/transam/xlogreader.c:2137 +#: access/transam/xlogreader.c:2122 access/transam/xlogreader.c:2139 #, c-format msgid "" "could not restore image at %X/%X compressed with %s not supported by build, " @@ -3712,7 +3730,7 @@ msgstr "" "не удалось восстановить образ в позиции %X/%X, сжатый методом %s, который не " "поддерживается этой сборкой, блок %d" -#: access/transam/xlogreader.c:2146 +#: access/transam/xlogreader.c:2148 #, c-format msgid "" "could not restore image at %X/%X compressed with unknown method, block %d" @@ -3720,7 +3738,7 @@ msgstr "" "не удалось восстановить образ в позиции %X/%X, сжатый неизвестным методом, " "блок %d" -#: access/transam/xlogreader.c:2154 +#: access/transam/xlogreader.c:2156 #, c-format msgid "could not decompress image at %X/%X, block %d" msgstr "не удалось развернуть образ в позиции %X/%X, блок %d" @@ -4133,7 +4151,7 @@ msgstr "остановка в конце восстановления" msgid "Execute pg_wal_replay_resume() to promote." msgstr "Выполните pg_wal_replay_resume() для повышения." -#: access/transam/xlogrecovery.c:2963 access/transam/xlogrecovery.c:4720 +#: access/transam/xlogrecovery.c:2963 access/transam/xlogrecovery.c:4722 #, c-format msgid "recovery has paused" msgstr "восстановление приостановлено" @@ -4149,12 +4167,12 @@ msgid "unexpected timeline ID %u in WAL segment %s, LSN %X/%X, offset %u" msgstr "" "неожиданный ID линии времени %u в сегменте WAL %s, LSN %X/%X, смещение %u" -#: access/transam/xlogrecovery.c:3443 +#: access/transam/xlogrecovery.c:3445 #, c-format msgid "could not read from WAL segment %s, LSN %X/%X, offset %u: %m" msgstr "не удалось прочитать сегмент WAL %s, LSN %X/%X, смещение %u: %m" -#: access/transam/xlogrecovery.c:3450 +#: access/transam/xlogrecovery.c:3452 #, c-format msgid "" "could not read from WAL segment %s, LSN %X/%X, offset %u: read %d of %zu" @@ -4162,38 +4180,38 @@ msgstr "" "не удалось прочитать сегмент WAL %s, LSN %X/%X, смещение %u (прочитано байт: " "%d из %zu)" -#: access/transam/xlogrecovery.c:4104 +#: access/transam/xlogrecovery.c:4106 #, c-format msgid "invalid checkpoint location" msgstr "неверное положение контрольной точки" -#: access/transam/xlogrecovery.c:4114 +#: access/transam/xlogrecovery.c:4116 #, c-format msgid "invalid checkpoint record" msgstr "неверная запись контрольной точки" -#: access/transam/xlogrecovery.c:4120 +#: access/transam/xlogrecovery.c:4122 #, c-format msgid "invalid resource manager ID in checkpoint record" msgstr "неверный ID менеджера ресурсов в записи контрольной точки" -#: access/transam/xlogrecovery.c:4128 +#: access/transam/xlogrecovery.c:4130 #, c-format msgid "invalid xl_info in checkpoint record" msgstr "неверные флаги xl_info в записи контрольной точки" -#: access/transam/xlogrecovery.c:4134 +#: access/transam/xlogrecovery.c:4136 #, c-format msgid "invalid length of checkpoint record" msgstr "неверная длина записи контрольной точки" -#: access/transam/xlogrecovery.c:4188 +#: access/transam/xlogrecovery.c:4190 #, c-format msgid "new timeline %u is not a child of database system timeline %u" msgstr "" "новая линия времени %u не является ответвлением линии времени системы БД %u" -#: access/transam/xlogrecovery.c:4202 +#: access/transam/xlogrecovery.c:4204 #, c-format msgid "" "new timeline %u forked off current database system timeline %u before " @@ -4202,30 +4220,30 @@ msgstr "" "новая линия времени %u ответвилась от текущей линии времени базы данных %u " "до текущей точки восстановления %X/%X" -#: access/transam/xlogrecovery.c:4221 +#: access/transam/xlogrecovery.c:4223 #, c-format msgid "new target timeline is %u" msgstr "новая целевая линия времени %u" -#: access/transam/xlogrecovery.c:4422 +#: access/transam/xlogrecovery.c:4424 #, c-format msgid "WAL receiver process shutdown requested" msgstr "получен запрос на выключение процесса приёмника WAL" -#: access/transam/xlogrecovery.c:4482 +#: access/transam/xlogrecovery.c:4484 #, c-format msgid "received promote request" msgstr "получен запрос повышения статуса" -#: access/transam/xlogrecovery.c:4711 +#: access/transam/xlogrecovery.c:4713 #, c-format msgid "hot standby is not possible because of insufficient parameter settings" msgstr "" "режим горячего резерва невозможен из-за отсутствия достаточных значений " "параметров" -#: access/transam/xlogrecovery.c:4712 access/transam/xlogrecovery.c:4739 -#: access/transam/xlogrecovery.c:4769 +#: access/transam/xlogrecovery.c:4714 access/transam/xlogrecovery.c:4741 +#: access/transam/xlogrecovery.c:4771 #, c-format msgid "" "%s = %d is a lower setting than on the primary server, where its value was " @@ -4233,12 +4251,12 @@ msgid "" msgstr "" "Параметр %s = %d меньше, чем на ведущем сервере, где его значение было %d." -#: access/transam/xlogrecovery.c:4721 +#: access/transam/xlogrecovery.c:4723 #, c-format msgid "If recovery is unpaused, the server will shut down." msgstr "В случае возобновления восстановления сервер отключится." -#: access/transam/xlogrecovery.c:4722 +#: access/transam/xlogrecovery.c:4724 #, c-format msgid "" "You can then restart the server after making the necessary configuration " @@ -4247,24 +4265,24 @@ msgstr "" "Затем вы можете перезапустить сервер после внесения необходимых изменений " "конфигурации." -#: access/transam/xlogrecovery.c:4733 +#: access/transam/xlogrecovery.c:4735 #, c-format msgid "promotion is not possible because of insufficient parameter settings" msgstr "повышение невозможно из-за отсутствия достаточных значений параметров" -#: access/transam/xlogrecovery.c:4743 +#: access/transam/xlogrecovery.c:4745 #, c-format msgid "Restart the server after making the necessary configuration changes." msgstr "" "Перезапустите сервер после внесения необходимых изменений конфигурации." -#: access/transam/xlogrecovery.c:4767 +#: access/transam/xlogrecovery.c:4769 #, c-format msgid "recovery aborted because of insufficient parameter settings" msgstr "" "восстановление прервано из-за отсутствия достаточных значений параметров" -#: access/transam/xlogrecovery.c:4773 +#: access/transam/xlogrecovery.c:4775 #, c-format msgid "" "You can restart the server after making the necessary configuration changes." @@ -4272,28 +4290,28 @@ msgstr "" "Вы можете перезапустить сервер после внесения необходимых изменений " "конфигурации." -#: access/transam/xlogrecovery.c:4793 access/transam/xlogrecovery.c:4795 +#: access/transam/xlogrecovery.c:4795 access/transam/xlogrecovery.c:4797 #: catalog/dependency.c:1153 catalog/dependency.c:1160 #: catalog/dependency.c:1171 commands/tablecmds.c:1529 -#: commands/tablecmds.c:16752 commands/tablespace.c:460 commands/user.c:1302 +#: commands/tablecmds.c:16751 commands/tablespace.c:460 commands/user.c:1302 #: commands/vacuum.c:226 commands/view.c:441 executor/execExprInterp.c:5282 #: executor/execExprInterp.c:5290 libpq/auth.c:320 -#: replication/logical/applyparallelworker.c:1057 replication/slot.c:1705 -#: replication/slot.c:2783 replication/slot.c:2785 replication/syncrep.c:1079 +#: replication/logical/applyparallelworker.c:1057 replication/slot.c:1707 +#: replication/slot.c:2785 replication/slot.c:2787 replication/syncrep.c:1079 #: storage/aio/method_io_uring.c:389 storage/lmgr/deadlock.c:1137 -#: storage/lmgr/proc.c:1525 utils/misc/guc.c:3166 utils/misc/guc.c:3207 +#: storage/lmgr/proc.c:1558 utils/misc/guc.c:3166 utils/misc/guc.c:3207 #: utils/misc/guc.c:3282 utils/misc/guc.c:6834 utils/misc/guc.c:6868 #: utils/misc/guc.c:6902 utils/misc/guc.c:6945 utils/misc/guc.c:6987 #, c-format msgid "%s" msgstr "%s" -#: access/transam/xlogrecovery.c:4825 +#: access/transam/xlogrecovery.c:4827 #, c-format msgid "multiple recovery targets specified" msgstr "указано несколько целей восстановления" -#: access/transam/xlogrecovery.c:4826 +#: access/transam/xlogrecovery.c:4828 #, c-format msgid "" "At most one of \"recovery_target\", \"recovery_target_lsn\", " @@ -4304,27 +4322,27 @@ msgstr "" "\"recovery_target_lsn\", \"recovery_target_name\", \"recovery_target_time\", " "\"recovery_target_xid\"." -#: access/transam/xlogrecovery.c:4837 +#: access/transam/xlogrecovery.c:4839 #, c-format msgid "The only allowed value is \"immediate\"." msgstr "Единственное допустимое значение: \"immediate\"." -#: access/transam/xlogrecovery.c:4991 +#: access/transam/xlogrecovery.c:4993 #, c-format msgid "Timestamp out of range: \"%s\"." msgstr "Timestamp вне диапазона: \"%s\"." -#: access/transam/xlogrecovery.c:5036 +#: access/transam/xlogrecovery.c:5038 #, c-format msgid "\"recovery_target_timeline\" is not a valid number." msgstr "Значение \"recovery_target_timeline\" не является допустимым числом." -#: access/transam/xlogutils.c:1023 +#: access/transam/xlogutils.c:1059 #, c-format msgid "could not read from WAL segment %s, offset %d: %m" msgstr "не удалось прочитать из сегмента WAL %s по смещению %d: %m" -#: access/transam/xlogutils.c:1030 +#: access/transam/xlogutils.c:1066 #, c-format msgid "could not read from WAL segment %s, offset %d: read %d of %d" msgstr "" @@ -4413,90 +4431,90 @@ msgstr[2] "всего ошибок контрольных сумм: %lld" msgid "checksum verification failure during base backup" msgstr "при базовом резервном копировании выявлены ошибки контрольных сумм" -#: backup/basebackup.c:735 backup/basebackup.c:744 backup/basebackup.c:755 -#: backup/basebackup.c:772 backup/basebackup.c:781 backup/basebackup.c:790 -#: backup/basebackup.c:805 backup/basebackup.c:822 backup/basebackup.c:831 -#: backup/basebackup.c:843 backup/basebackup.c:867 backup/basebackup.c:881 -#: backup/basebackup.c:892 backup/basebackup.c:903 backup/basebackup.c:916 +#: backup/basebackup.c:733 backup/basebackup.c:742 backup/basebackup.c:753 +#: backup/basebackup.c:770 backup/basebackup.c:779 backup/basebackup.c:788 +#: backup/basebackup.c:803 backup/basebackup.c:820 backup/basebackup.c:829 +#: backup/basebackup.c:841 backup/basebackup.c:865 backup/basebackup.c:879 +#: backup/basebackup.c:890 backup/basebackup.c:901 backup/basebackup.c:914 #, c-format msgid "duplicate option \"%s\"" msgstr "повторяющийся параметр \"%s\"" -#: backup/basebackup.c:763 +#: backup/basebackup.c:761 #, c-format msgid "unrecognized checkpoint type: \"%s\"" msgstr "нераспознанный тип контрольной точки: \"%s\"" -#: backup/basebackup.c:795 +#: backup/basebackup.c:793 #, c-format msgid "incremental backups cannot be taken unless WAL summarization is enabled" msgstr "" "сделать инкрементальную копию можно, только когда включено обобщение WAL" -#: backup/basebackup.c:811 +#: backup/basebackup.c:809 #, c-format msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" msgstr "%d вне диапазона, допустимого для параметра \"%s\" (%d .. %d)" -#: backup/basebackup.c:856 +#: backup/basebackup.c:854 #, c-format msgid "unrecognized manifest option: \"%s\"" msgstr "нераспознанный параметр в манифесте: \"%s\"" -#: backup/basebackup.c:907 +#: backup/basebackup.c:905 #, c-format msgid "unrecognized compression algorithm: \"%s\"" msgstr "нераспознанный алгоритм сжатия: \"%s\"" -#: backup/basebackup.c:923 +#: backup/basebackup.c:921 #, c-format msgid "unrecognized base backup option: \"%s\"" msgstr "нераспознанный параметр операции базового копирования: \"%s\"" -#: backup/basebackup.c:934 +#: backup/basebackup.c:932 #, c-format msgid "manifest checksums require a backup manifest" msgstr "контрольные суммы не могут рассчитываться без манифеста копии" # skip-rule: capital-letter-first -#: backup/basebackup.c:943 +#: backup/basebackup.c:941 #, c-format msgid "target detail cannot be used without target" msgstr "доп. информацию о получателе нельзя задать без указания получателя" # skip-rule: capital-letter-first -#: backup/basebackup.c:952 backup/basebackup_target.c:218 +#: backup/basebackup.c:950 backup/basebackup_target.c:218 #, c-format msgid "target \"%s\" does not accept a target detail" msgstr "получатель \"%s\" не принимает доп. информацию" -#: backup/basebackup.c:963 +#: backup/basebackup.c:961 #, c-format msgid "compression detail cannot be specified unless compression is enabled" msgstr "параметры сжатия нельзя указывать, если не включено сжатие" -#: backup/basebackup.c:976 +#: backup/basebackup.c:974 #, c-format msgid "invalid compression specification: %s" msgstr "неправильное указание сжатия: %s" -#: backup/basebackup.c:1026 +#: backup/basebackup.c:1024 #, c-format msgid "must UPLOAD_MANIFEST before performing an incremental BASE_BACKUP" msgstr "" "инкрементальной команде BASE_BACKUP должна предшествовать UPLOAD_MANIFEST" -#: backup/basebackup.c:1159 backup/basebackup.c:1360 +#: backup/basebackup.c:1157 backup/basebackup.c:1358 #, c-format msgid "could not stat file or directory \"%s\": %m" msgstr "не удалось получить информацию о файле или каталоге \"%s\": %m" -#: backup/basebackup.c:1546 +#: backup/basebackup.c:1544 #, c-format msgid "skipping special file \"%s\"" msgstr "специальный файл \"%s\" пропускается" -#: backup/basebackup.c:1753 +#: backup/basebackup.c:1751 #, c-format msgid "" "could not verify checksum in file \"%s\", block %u: read buffer size %d and " @@ -4505,7 +4523,7 @@ msgstr "" "не удалось проверить контрольную сумму в файле \"%s\", блоке %u: размер " "прочитанного буфера (%d) отличается от размера страницы (%d)" -#: backup/basebackup.c:1815 +#: backup/basebackup.c:1813 #, c-format msgid "file \"%s\" has a total of %d checksum verification failure" msgid_plural "file \"%s\" has a total of %d checksum verification failures" @@ -4513,7 +4531,7 @@ msgstr[0] "всего в файле \"%s\" обнаружено ошибок к msgstr[1] "всего в файле \"%s\" обнаружено ошибок контрольных сумм: %d" msgstr[2] "всего в файле \"%s\" обнаружено ошибок контрольных сумм: %d" -#: backup/basebackup.c:1920 +#: backup/basebackup.c:1918 #, c-format msgid "" "checksum verification failed in file \"%s\", block %u: calculated %X but " @@ -4522,19 +4540,19 @@ msgstr "" "ошибка контрольной суммы в файле \"%s\", блоке %u: вычислено значение %X, но " "ожидалось %X" -#: backup/basebackup.c:1927 +#: backup/basebackup.c:1925 #, c-format msgid "" "further checksum verification failures in file \"%s\" will not be reported" msgstr "" "о дальнейших ошибках контрольных сумм в файле \"%s\" сообщаться не будет" -#: backup/basebackup.c:2052 +#: backup/basebackup.c:2050 #, c-format msgid "file name too long for tar format: \"%s\"" msgstr "слишком длинное имя файла для формата tar: \"%s\"" -#: backup/basebackup.c:2058 +#: backup/basebackup.c:2056 #, c-format msgid "" "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" @@ -4542,7 +4560,7 @@ msgstr "" "цель символической ссылки слишком длинная для формата tar: имя файла \"%s\", " "цель \"%s\"" -#: backup/basebackup.c:2132 +#: backup/basebackup.c:2130 #, c-format msgid "could not read file \"%s\": read %zd of %zu" msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %zd из %zu)" @@ -4678,7 +4696,7 @@ msgstr "" #: backup/basebackup_server.c:102 commands/dbcommands.c:478 #: commands/tablespace.c:157 commands/tablespace.c:173 -#: commands/tablespace.c:593 commands/tablespace.c:638 replication/slot.c:2287 +#: commands/tablespace.c:593 commands/tablespace.c:638 replication/slot.c:2289 #: storage/file/copydir.c:58 #, c-format msgid "could not create directory \"%s\": %m" @@ -4703,11 +4721,10 @@ msgid "Check free disk space." msgstr "Проверьте, есть ли место на диске." #: backup/basebackup_server.c:179 backup/basebackup_server.c:272 -#: backup/walsummary.c:309 #, c-format -msgid "could not write file \"%s\": wrote only %d of %d bytes at offset %u" +msgid "could not write file \"%s\": wrote only %d of %d bytes at offset %lld" msgstr "" -"не удалось записать файл \"%s\" (записано байт: %d из %d по смещению %u)" +"не удалось записать файл \"%s\" (записано байт: %d из %d по смещению %lld)" #: backup/basebackup_target.c:146 #, c-format @@ -4735,6 +4752,12 @@ msgstr "не удалось установить число потоков сж msgid "could not enable long-distance mode: %s" msgstr "не удалось включить режим большой дистанции: %s" +#: backup/walsummary.c:309 +#, c-format +msgid "could not write file \"%s\": wrote only %d of %d bytes at offset %u" +msgstr "" +"не удалось записать файл \"%s\" (записано байт: %d из %d по смещению %u)" + #: backup/walsummaryfuncs.c:95 #, c-format msgid "invalid timeline %" @@ -4913,23 +4936,23 @@ msgstr "нет полномочий для изменения прав дост msgid "cannot use IN SCHEMA clause when using %s" msgstr "предложение IN SCHEMA нельзя использовать в %s" -#: catalog/aclchk.c:1577 catalog/catalog.c:684 catalog/heap.c:2635 -#: catalog/heap.c:2957 catalog/objectaddress.c:1528 +#: catalog/aclchk.c:1577 catalog/catalog.c:684 catalog/heap.c:2638 +#: catalog/heap.c:2960 catalog/objectaddress.c:1528 #: catalog/pg_publication.c:570 commands/analyze.c:388 commands/copy.c:1040 -#: commands/sequence.c:1655 commands/tablecmds.c:7761 commands/tablecmds.c:7939 -#: commands/tablecmds.c:8140 commands/tablecmds.c:8269 -#: commands/tablecmds.c:8423 commands/tablecmds.c:8517 -#: commands/tablecmds.c:8620 commands/tablecmds.c:8786 -#: commands/tablecmds.c:8816 commands/tablecmds.c:8971 -#: commands/tablecmds.c:9074 commands/tablecmds.c:9208 -#: commands/tablecmds.c:9321 commands/tablecmds.c:14409 -#: commands/tablecmds.c:14612 commands/tablecmds.c:14773 -#: commands/tablecmds.c:16001 commands/tablecmds.c:18768 commands/trigger.c:948 -#: parser/analyze.c:2591 parser/parse_relation.c:749 parser/parse_target.c:1070 +#: commands/sequence.c:1655 commands/tablecmds.c:7761 commands/tablecmds.c:7935 +#: commands/tablecmds.c:8136 commands/tablecmds.c:8265 +#: commands/tablecmds.c:8419 commands/tablecmds.c:8513 +#: commands/tablecmds.c:8616 commands/tablecmds.c:8777 +#: commands/tablecmds.c:8807 commands/tablecmds.c:8962 +#: commands/tablecmds.c:9065 commands/tablecmds.c:9199 +#: commands/tablecmds.c:9312 commands/tablecmds.c:14408 +#: commands/tablecmds.c:14611 commands/tablecmds.c:14772 +#: commands/tablecmds.c:16000 commands/tablecmds.c:18767 commands/trigger.c:948 +#: parser/analyze.c:2591 parser/parse_relation.c:781 parser/parse_target.c:1070 #: parser/parse_type.c:144 parser/parse_utilcmd.c:3671 #: parser/parse_utilcmd.c:3711 parser/parse_utilcmd.c:3753 -#: statistics/attribute_stats.c:212 statistics/attribute_stats.c:955 -#: utils/adt/acl.c:2938 utils/adt/ruleutils.c:2858 +#: statistics/attribute_stats.c:212 statistics/attribute_stats.c:981 +#: utils/adt/acl.c:2938 utils/adt/ruleutils.c:2860 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" msgstr "столбец \"%s\" в таблице \"%s\" не существует" @@ -4939,13 +4962,13 @@ msgstr "столбец \"%s\" в таблице \"%s\" не существует msgid "\"%s\" is an index" msgstr "\"%s\" - это индекс" -#: catalog/aclchk.c:1829 commands/tablecmds.c:16158 commands/tablecmds.c:19687 +#: catalog/aclchk.c:1829 commands/tablecmds.c:16157 commands/tablecmds.c:19686 #, c-format msgid "\"%s\" is a composite type" msgstr "\"%s\" - это составной тип" #: catalog/aclchk.c:1837 catalog/objectaddress.c:1368 commands/tablecmds.c:266 -#: commands/tablecmds.c:19651 utils/adt/acl.c:2122 utils/adt/acl.c:2152 +#: commands/tablecmds.c:19650 utils/adt/acl.c:2122 utils/adt/acl.c:2152 #: utils/adt/acl.c:2185 utils/adt/acl.c:2221 utils/adt/acl.c:2252 #: utils/adt/acl.c:2283 #, c-format @@ -5507,19 +5530,19 @@ msgstr[0] "удаление распространяется на ещё %d об msgstr[1] "удаление распространяется на ещё %d объекта" msgstr[2] "удаление распространяется на ещё %d объектов" -#: catalog/dependency.c:1850 +#: catalog/dependency.c:1853 #, c-format msgid "constant of the type %s cannot be used here" msgstr "константу типа %s здесь использовать нельзя" -#: catalog/dependency.c:2205 +#: catalog/dependency.c:2208 #, c-format msgid "transition table \"%s\" cannot be referenced in a persistent object" msgstr "на переходную таблицу \"%s\" нельзя ссылаться в постоянном объекте" -#: catalog/dependency.c:2390 parser/parse_relation.c:3513 -#: parser/parse_relation.c:3523 statistics/attribute_stats.c:224 -#: statistics/attribute_stats.c:596 statistics/attribute_stats.c:604 +#: catalog/dependency.c:2393 parser/parse_relation.c:3545 +#: parser/parse_relation.c:3555 statistics/attribute_stats.c:224 +#: statistics/attribute_stats.c:613 statistics/attribute_stats.c:621 #, c-format msgid "column %d of relation \"%s\" does not exist" msgstr "столбец %d отношения \"%s\" не существует" @@ -5577,7 +5600,7 @@ msgid "virtual generated column \"%s\" cannot have a user-defined type" msgstr "" "виртуальный генерируемый столбец \"%s\" не может иметь пользовательский тип" -#: catalog/heap.c:688 catalog/heap.c:3311 +#: catalog/heap.c:688 catalog/heap.c:3314 #, c-format msgid "" "Virtual generated columns that make use of user-defined types are not yet " @@ -5602,21 +5625,21 @@ msgstr "" "для столбца \"%s\" с сортируемым типом %s не удалось получить правило " "сортировки" -#: catalog/heap.c:1193 catalog/index.c:901 commands/createas.c:408 +#: catalog/heap.c:1196 catalog/index.c:905 commands/createas.c:408 #: commands/tablecmds.c:4306 #, c-format msgid "relation \"%s\" already exists" msgstr "отношение \"%s\" уже существует" -#: catalog/heap.c:1209 catalog/pg_type.c:434 catalog/pg_type.c:805 +#: catalog/heap.c:1212 catalog/pg_type.c:434 catalog/pg_type.c:805 #: catalog/pg_type.c:977 commands/typecmds.c:253 commands/typecmds.c:265 #: commands/typecmds.c:758 commands/typecmds.c:1213 commands/typecmds.c:1439 -#: commands/typecmds.c:1619 commands/typecmds.c:2594 +#: commands/typecmds.c:1626 commands/typecmds.c:2601 #, c-format msgid "type \"%s\" already exists" msgstr "тип \"%s\" уже существует" -#: catalog/heap.c:1210 +#: catalog/heap.c:1213 #, c-format msgid "" "A relation has an associated type of the same name, so you must use a name " @@ -5625,59 +5648,59 @@ msgstr "" "С отношением уже связан тип с таким же именем; выберите имя, не " "конфликтующее с существующими типами." -#: catalog/heap.c:1250 +#: catalog/heap.c:1253 #, c-format msgid "toast relfilenumber value not set when in binary upgrade mode" msgstr "" "значение relfilenumber для TOAST не задано в режиме двоичного обновления" -#: catalog/heap.c:1261 +#: catalog/heap.c:1264 #, c-format msgid "pg_class heap OID value not set when in binary upgrade mode" msgstr "значение OID кучи в pg_class не задано в режиме двоичного обновления" -#: catalog/heap.c:1271 +#: catalog/heap.c:1274 #, c-format msgid "relfilenumber value not set when in binary upgrade mode" msgstr "значение relfilenumber не задано в режиме двоичного обновления" -#: catalog/heap.c:2216 +#: catalog/heap.c:2219 #, c-format msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" msgstr "" "добавить ограничение NO INHERIT к секционированной таблице \"%s\" нельзя" -#: catalog/heap.c:2539 +#: catalog/heap.c:2542 #, c-format msgid "check constraint \"%s\" already exists" msgstr "ограничение-проверка \"%s\" уже существует" -#: catalog/heap.c:2640 catalog/heap.c:2963 +#: catalog/heap.c:2643 catalog/heap.c:2966 #, c-format msgid "cannot add not-null constraint on system column \"%s\"" msgstr "добавить ограничение NOT NULL для системного столбца \"%s\" нельзя" -#: catalog/heap.c:2668 catalog/heap.c:2794 catalog/heap.c:3047 -#: catalog/index.c:915 catalog/pg_constraint.c:1025 commands/tablecmds.c:9831 +#: catalog/heap.c:2671 catalog/heap.c:2797 catalog/heap.c:3050 +#: catalog/index.c:919 catalog/pg_constraint.c:1025 commands/tablecmds.c:9822 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" msgstr "ограничение \"%s\" для отношения \"%s\" уже существует" -#: catalog/heap.c:2801 +#: catalog/heap.c:2804 #, c-format msgid "" "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" msgstr "" "ограничение \"%s\" конфликтует с ненаследуемым ограничением таблицы \"%s\"" -#: catalog/heap.c:2812 +#: catalog/heap.c:2815 #, c-format msgid "" "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" msgstr "" "ограничение \"%s\" конфликтует с наследуемым ограничением таблицы \"%s\"" -#: catalog/heap.c:2822 +#: catalog/heap.c:2825 #, c-format msgid "" "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" @@ -5685,7 +5708,7 @@ msgstr "" "ограничение \"%s\" конфликтует с непроверенным (NOT VALID) ограничением " "таблицы \"%s\"" -#: catalog/heap.c:2834 +#: catalog/heap.c:2837 #, c-format msgid "" "constraint \"%s\" conflicts with NOT ENFORCED constraint on relation \"%s\"" @@ -5693,74 +5716,74 @@ msgstr "" "ограничение \"%s\" конфликтует с неконтролируемым (NOT ENFORCED) " "ограничением таблицы \"%s\"" -#: catalog/heap.c:2839 +#: catalog/heap.c:2842 #, c-format msgid "merging constraint \"%s\" with inherited definition" msgstr "слияние ограничения \"%s\" с унаследованным определением" -#: catalog/heap.c:2863 catalog/pg_constraint.c:803 catalog/pg_constraint.c:1154 +#: catalog/heap.c:2866 catalog/pg_constraint.c:803 catalog/pg_constraint.c:1154 #: commands/tablecmds.c:3189 commands/tablecmds.c:3509 -#: commands/tablecmds.c:7296 commands/tablecmds.c:7977 -#: commands/tablecmds.c:17595 commands/tablecmds.c:17777 +#: commands/tablecmds.c:7296 commands/tablecmds.c:7973 +#: commands/tablecmds.c:17594 commands/tablecmds.c:17776 #, c-format msgid "too many inheritance parents" msgstr "слишком много родителей в иерархии наследования" -#: catalog/heap.c:2982 parser/parse_utilcmd.c:2659 +#: catalog/heap.c:2985 parser/parse_utilcmd.c:2659 #, c-format msgid "" "conflicting NO INHERIT declaration for not-null constraint on column \"%s\"" msgstr "" "конфликтующее объявление NO INHERIT для ограничения NOT NULL столбца \"%s\"" -#: catalog/heap.c:2996 +#: catalog/heap.c:2999 #, c-format msgid "conflicting not-null constraint names \"%s\" and \"%s\"" msgstr "конфликтующие имена ограничений NOT NULL \"%s\" и \"%s\"" -#: catalog/heap.c:3026 +#: catalog/heap.c:3029 #, c-format msgid "cannot define not-null constraint with NO INHERIT on column \"%s\"" msgstr "" "добавить ограничение NOT NULL со свойством NO INHERIT для столбца \"%s\" " "нельзя" -#: catalog/heap.c:3028 +#: catalog/heap.c:3031 #, c-format msgid "The column has an inherited not-null constraint." msgstr "Столбец имеет наследуемое ограничение NOT NULL." -#: catalog/heap.c:3218 +#: catalog/heap.c:3221 #, c-format msgid "cannot use generated column \"%s\" in column generation expression" msgstr "" "использовать генерируемый столбец \"%s\" в выражении генерируемого столбца " "нельзя" -#: catalog/heap.c:3220 +#: catalog/heap.c:3223 #, c-format msgid "A generated column cannot reference another generated column." msgstr "" "Генерируемый столбец не может ссылаться на другой генерируемый столбец." -#: catalog/heap.c:3226 +#: catalog/heap.c:3229 #, c-format msgid "cannot use whole-row variable in column generation expression" msgstr "" "в выражении генерируемого столбца нельзя использовать переменные «вся строка»" -#: catalog/heap.c:3227 +#: catalog/heap.c:3230 #, c-format msgid "This would cause the generated column to depend on its own value." msgstr "" "Это сделало бы генерируемый столбец зависимым от собственного значения." -#: catalog/heap.c:3294 +#: catalog/heap.c:3297 #, c-format msgid "generation expression uses user-defined function" msgstr "генерирующее выражение использует пользовательскую функцию" -#: catalog/heap.c:3295 +#: catalog/heap.c:3298 #, c-format msgid "" "Virtual generated columns that make use of user-defined functions are not " @@ -5769,39 +5792,39 @@ msgstr "" "Виртуальные генерируемые столбцы, использующие пользовательские функции, на " "данный момент не поддерживаются." -#: catalog/heap.c:3310 +#: catalog/heap.c:3313 #, c-format msgid "generation expression uses user-defined type" msgstr "генерирующее выражение использует пользовательский тип" -#: catalog/heap.c:3362 +#: catalog/heap.c:3365 #, c-format msgid "generation expression is not immutable" msgstr "генерирующее выражение не является постоянным" -#: catalog/heap.c:3394 rewrite/rewriteHandler.c:1321 +#: catalog/heap.c:3397 rewrite/rewriteHandler.c:1321 #, c-format msgid "column \"%s\" is of type %s but default expression is of type %s" msgstr "столбец \"%s\" имеет тип %s, но тип выражения по умолчанию %s" -#: catalog/heap.c:3399 commands/prepare.c:334 parser/analyze.c:2922 +#: catalog/heap.c:3402 commands/prepare.c:334 parser/analyze.c:2922 #: parser/parse_target.c:595 parser/parse_target.c:885 #: parser/parse_target.c:895 rewrite/rewriteHandler.c:1326 #, c-format msgid "You will need to rewrite or cast the expression." msgstr "Перепишите выражение или преобразуйте его тип." -#: catalog/heap.c:3446 +#: catalog/heap.c:3449 #, c-format msgid "only table \"%s\" can be referenced in check constraint" msgstr "в ограничении-проверке можно ссылаться только на таблицу \"%s\"" -#: catalog/heap.c:3752 +#: catalog/heap.c:3755 #, c-format msgid "unsupported ON COMMIT and foreign key combination" msgstr "неподдерживаемое сочетание внешнего ключа с ON COMMIT" -#: catalog/heap.c:3753 +#: catalog/heap.c:3756 #, c-format msgid "" "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT " @@ -5809,17 +5832,17 @@ msgid "" msgstr "" "Таблица \"%s\" ссылается на \"%s\", и для них задан разный режим ON COMMIT." -#: catalog/heap.c:3758 +#: catalog/heap.c:3761 #, c-format msgid "cannot truncate a table referenced in a foreign key constraint" msgstr "опустошить таблицу, на которую ссылается внешний ключ, нельзя" -#: catalog/heap.c:3759 +#: catalog/heap.c:3762 #, c-format msgid "Table \"%s\" references \"%s\"." msgstr "Таблица \"%s\" ссылается на \"%s\"." -#: catalog/heap.c:3761 +#: catalog/heap.c:3764 #, c-format msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." msgstr "" @@ -5845,82 +5868,82 @@ msgstr "первичные ключи не могут быть выражени msgid "primary key column \"%s\" is not marked NOT NULL" msgstr "столбец первичного ключа \"%s\" не помечен как NOT NULL" -#: catalog/index.c:800 catalog/index.c:1921 +#: catalog/index.c:804 catalog/index.c:1935 #, c-format msgid "user-defined indexes on system catalog tables are not supported" msgstr "" "пользовательские индексы в таблицах системного каталога не поддерживаются" -#: catalog/index.c:840 +#: catalog/index.c:844 #, c-format msgid "nondeterministic collations are not supported for operator class \"%s\"" msgstr "" "недетерминированные правила сортировки не поддерживаются для класса " "операторов \"%s\"" -#: catalog/index.c:855 +#: catalog/index.c:859 #, c-format msgid "concurrent index creation on system catalog tables is not supported" msgstr "" "параллельное создание индекса в таблицах системного каталога не " "поддерживается" -#: catalog/index.c:864 catalog/index.c:1333 +#: catalog/index.c:868 catalog/index.c:1340 #, c-format msgid "concurrent index creation for exclusion constraints is not supported" msgstr "" "параллельное создание индекса для ограничений-исключений не поддерживается" -#: catalog/index.c:873 +#: catalog/index.c:877 #, c-format msgid "shared indexes cannot be created after initdb" msgstr "нельзя создать разделяемые индексы после initdb" -#: catalog/index.c:893 commands/createas.c:423 commands/sequence.c:159 +#: catalog/index.c:897 commands/createas.c:423 commands/sequence.c:159 #: parser/parse_utilcmd.c:210 #, c-format msgid "relation \"%s\" already exists, skipping" msgstr "отношение \"%s\" уже существует, пропускается" -#: catalog/index.c:943 +#: catalog/index.c:947 #, c-format msgid "pg_class index OID value not set when in binary upgrade mode" msgstr "" "значение OID индекса в pg_class не задано в режиме двоичного обновления" -#: catalog/index.c:953 utils/cache/relcache.c:3795 +#: catalog/index.c:957 utils/cache/relcache.c:3797 #, c-format msgid "index relfilenumber value not set when in binary upgrade mode" msgstr "" "значение relfilenumber для индекса не задано в режиме двоичного обновления" -#: catalog/index.c:2222 +#: catalog/index.c:2236 #, c-format msgid "DROP INDEX CONCURRENTLY must be first action in transaction" msgstr "DROP INDEX CONCURRENTLY должен быть первым действием в транзакции" -#: catalog/index.c:3729 +#: catalog/index.c:3755 #, c-format msgid "cannot reindex temporary tables of other sessions" msgstr "переиндексировать временные таблицы других сеансов нельзя" -#: catalog/index.c:3740 commands/indexcmds.c:3793 +#: catalog/index.c:3766 commands/indexcmds.c:3793 #, c-format msgid "cannot reindex invalid index on TOAST table" msgstr "перестроить нерабочий индекс в таблице TOAST нельзя" -#: catalog/index.c:3756 commands/indexcmds.c:3671 commands/indexcmds.c:3817 +#: catalog/index.c:3782 commands/indexcmds.c:3671 commands/indexcmds.c:3817 #: commands/tablecmds.c:3713 #, c-format msgid "cannot move system relation \"%s\"" msgstr "переместить системную таблицу \"%s\" нельзя" -#: catalog/index.c:3893 +#: catalog/index.c:3919 #, c-format msgid "index \"%s\" was reindexed" msgstr "индекс \"%s\" был перестроен" -#: catalog/index.c:4059 +#: catalog/index.c:4085 #, c-format msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" msgstr "" @@ -5948,13 +5971,13 @@ msgstr "не удалось получить блокировку таблицы msgid "could not obtain lock on relation \"%s\"" msgstr "не удалось получить блокировку таблицы \"%s\"" -#: catalog/namespace.c:633 parser/parse_relation.c:1447 +#: catalog/namespace.c:633 parser/parse_relation.c:1479 #, c-format msgid "relation \"%s.%s\" does not exist" msgstr "отношение \"%s.%s\" не существует" -#: catalog/namespace.c:638 parser/parse_relation.c:1460 -#: parser/parse_relation.c:1468 utils/adt/regproc.c:913 +#: catalog/namespace.c:638 parser/parse_relation.c:1492 +#: parser/parse_relation.c:1500 utils/adt/regproc.c:913 #, c-format msgid "relation \"%s\" does not exist" msgstr "отношение \"%s\" не существует" @@ -6001,7 +6024,7 @@ msgid "text search template \"%s\" does not exist" msgstr "шаблон текстового поиска \"%s\" не существует" #: catalog/namespace.c:3200 commands/tsearchcmds.c:1168 -#: utils/adt/regproc.c:1349 utils/cache/ts_cache.c:635 +#: utils/adt/regproc.c:1349 utils/cache/ts_cache.c:648 #, c-format msgid "text search configuration \"%s\" does not exist" msgstr "конфигурация текстового поиска \"%s\" не существует" @@ -6065,25 +6088,25 @@ msgstr "создавать временные таблицы во время п #: catalog/objectaddress.c:1376 commands/policy.c:93 commands/policy.c:373 #: commands/tablecmds.c:260 commands/tablecmds.c:302 commands/tablecmds.c:2397 -#: commands/tablecmds.c:14547 +#: commands/tablecmds.c:14546 #, c-format msgid "\"%s\" is not a table" msgstr "\"%s\" - это не таблица" #: catalog/objectaddress.c:1383 commands/tablecmds.c:272 -#: commands/tablecmds.c:19656 commands/view.c:113 +#: commands/tablecmds.c:19655 commands/view.c:113 #, c-format msgid "\"%s\" is not a view" msgstr "\"%s\" - это не представление" #: catalog/objectaddress.c:1390 commands/matview.c:201 commands/tablecmds.c:278 -#: commands/tablecmds.c:19661 +#: commands/tablecmds.c:19660 #, c-format msgid "\"%s\" is not a materialized view" msgstr "\"%s\" - это не материализованное представление" #: catalog/objectaddress.c:1397 commands/tablecmds.c:296 -#: commands/tablecmds.c:19666 +#: commands/tablecmds.c:19665 #, c-format msgid "\"%s\" is not a foreign table" msgstr "\"%s\" - это не сторонняя таблица" @@ -6105,7 +6128,7 @@ msgstr "" "значение по умолчанию для столбца \"%s\" отношения \"%s\" не существует" #: catalog/objectaddress.c:1623 commands/functioncmds.c:132 -#: commands/tablecmds.c:288 commands/typecmds.c:278 commands/typecmds.c:3842 +#: commands/tablecmds.c:288 commands/typecmds.c:278 commands/typecmds.c:3849 #: parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:801 #: utils/adt/acl.c:4575 #, c-format @@ -6380,7 +6403,7 @@ msgstr "конфигурация текстового поиска %s" msgid "role %s" msgstr "роль %s" -#: catalog/objectaddress.c:3665 catalog/objectaddress.c:5589 +#: catalog/objectaddress.c:3665 #, c-format msgid "membership of role %s in role %s" msgstr "членство роли %s в роли %s" @@ -6708,12 +6731,12 @@ msgid "cannot change number of direct arguments of an aggregate function" msgstr "изменить число непосредственных аргументов агрегатной функции нельзя" #: catalog/pg_aggregate.c:859 commands/functioncmds.c:701 -#: commands/typecmds.c:2023 commands/typecmds.c:2069 commands/typecmds.c:2121 -#: commands/typecmds.c:2158 commands/typecmds.c:2192 commands/typecmds.c:2226 -#: commands/typecmds.c:2260 commands/typecmds.c:2289 commands/typecmds.c:2376 -#: commands/typecmds.c:2418 parser/parse_func.c:417 parser/parse_func.c:448 +#: commands/typecmds.c:2030 commands/typecmds.c:2076 commands/typecmds.c:2128 +#: commands/typecmds.c:2165 commands/typecmds.c:2199 commands/typecmds.c:2233 +#: commands/typecmds.c:2267 commands/typecmds.c:2296 commands/typecmds.c:2383 +#: commands/typecmds.c:2425 parser/parse_func.c:417 parser/parse_func.c:448 #: parser/parse_func.c:475 parser/parse_func.c:489 parser/parse_func.c:611 -#: parser/parse_func.c:631 parser/parse_func.c:2172 parser/parse_func.c:2445 +#: parser/parse_func.c:631 parser/parse_func.c:2170 parser/parse_func.c:2443 #, c-format msgid "function %s does not exist" msgstr "функция %s не существует" @@ -6811,7 +6834,7 @@ msgstr "правило сортировки \"%s\" уже существует" msgid "collation \"%s\" for encoding \"%s\" already exists" msgstr "правило сортировки \"%s\" для кодировки \"%s\" уже существует" -#: catalog/pg_constraint.c:764 commands/tablecmds.c:7962 +#: catalog/pg_constraint.c:764 commands/tablecmds.c:7958 #, c-format msgid "" "cannot change NO INHERIT status of NOT NULL constraint \"%s\" on relation " @@ -6820,20 +6843,20 @@ msgstr "" "изменить статус NO INHERIT ограничения NOT NULL \"%s\" для отношения \"%s\" " "нельзя" -#: catalog/pg_constraint.c:766 commands/tablecmds.c:9594 +#: catalog/pg_constraint.c:766 commands/tablecmds.c:9585 #, c-format msgid "You might need to make the existing constraint inheritable using %s." msgstr "" "Возможно, существующее ограничение нужно сделать наследуемым, выполнив %s." -#: catalog/pg_constraint.c:776 commands/tablecmds.c:8311 +#: catalog/pg_constraint.c:776 commands/tablecmds.c:8307 #, c-format msgid "incompatible NOT VALID constraint \"%s\" on relation \"%s\"" msgstr "" "несовместимое непроверенное (NOT VALID) ограничение \"%s\" в отношении \"%s\"" -#: catalog/pg_constraint.c:778 commands/tablecmds.c:8313 -#: commands/tablecmds.c:9606 +#: catalog/pg_constraint.c:778 commands/tablecmds.c:8309 +#: commands/tablecmds.c:9597 #, c-format msgid "You might need to validate it using %s." msgstr "Возможно, следует проверить его, выполнив %s." @@ -6885,23 +6908,23 @@ msgstr "преобразование \"%s\" уже существует" msgid "default conversion for %s to %s already exists" msgstr "преобразование по умолчанию из %s в %s уже существует" -#: catalog/pg_depend.c:225 commands/extension.c:3818 +#: catalog/pg_depend.c:236 commands/extension.c:3818 #, c-format msgid "%s is already a member of extension \"%s\"" msgstr "%s уже относится к расширению \"%s\"" -#: catalog/pg_depend.c:232 catalog/pg_depend.c:283 commands/extension.c:3858 +#: catalog/pg_depend.c:243 catalog/pg_depend.c:294 commands/extension.c:3858 #, c-format msgid "%s is not a member of extension \"%s\"" msgstr "%s не относится к расширению \"%s\"" -#: catalog/pg_depend.c:235 +#: catalog/pg_depend.c:246 #, c-format msgid "An extension is not allowed to replace an object that it does not own." msgstr "" "Расширениям не разрешается заменять объекты, которые им не принадлежат." -#: catalog/pg_depend.c:286 +#: catalog/pg_depend.c:297 #, c-format msgid "" "An extension may only use CREATE ... IF NOT EXISTS to skip object creation " @@ -6910,12 +6933,22 @@ msgstr "" "Расширение может выполнять CREATE ... IF NOT EXISTS только для того, чтобы " "не создавать объект, когда оно уже владеет конфликтующим объектом." -#: catalog/pg_depend.c:649 +#: catalog/pg_depend.c:667 #, c-format msgid "cannot remove dependency on %s because it is a system object" msgstr "" "ликвидировать зависимость от объекта %s нельзя, так как это системный объект" +#: catalog/pg_depend.c:812 +#, c-format +msgid "referenced %s was concurrently dropped" +msgstr "зависимый объект %s был удалён другим процессом" + +#: catalog/pg_depend.c:844 +#, c-format +msgid "referenced relation was concurrently dropped" +msgstr "зависимое отношение было удалено другим процессом" + #: catalog/pg_enum.c:175 catalog/pg_enum.c:314 catalog/pg_enum.c:624 #, c-format msgid "invalid enum label \"%s\"" @@ -6967,7 +7000,7 @@ msgstr "" "отсоединения." #: catalog/pg_inherits.c:595 commands/tablecmds.c:4926 -#: commands/tablecmds.c:17903 +#: commands/tablecmds.c:17902 #, c-format msgid "" "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending " @@ -7082,7 +7115,7 @@ msgstr "обратный оператор %s уже является обрат msgid "parameter ACL \"%s\" does not exist" msgstr "ACL параметра \"%s\" не существует" -#: catalog/pg_proc.c:158 parser/parse_func.c:2234 +#: catalog/pg_proc.c:158 parser/parse_func.c:2232 #, c-format msgid "functions cannot have more than %d argument" msgid_plural "functions cannot have more than %d arguments" @@ -7378,7 +7411,7 @@ msgstr "внутренний размер %d не подходит для тип msgid "alignment \"%c\" is invalid for variable-length type" msgstr "выравнивание \"%c\" не подходит для типа переменной длины" -#: catalog/pg_type.c:325 commands/typecmds.c:4362 +#: catalog/pg_type.c:325 commands/typecmds.c:4369 #, c-format msgid "fixed-size types must have storage PLAIN" msgstr "для типов постоянного размера применим только режим хранения PLAIN" @@ -7397,7 +7430,7 @@ msgstr "" "Имя мультидиапазонного типа можно указать вручную, воспользовавшись " "атрибутом \"multirange_type_name\"." -#: catalog/storage.c:549 storage/buffer/bufmgr.c:7338 +#: catalog/storage.c:549 storage/buffer/bufmgr.c:7361 #, c-format msgid "invalid page in block %u of relation \"%s\"" msgstr "некорректная страница в блоке %u отношения \"%s\"" @@ -7525,7 +7558,7 @@ msgstr "язык \"%s\" уже существует" msgid "publication \"%s\" already exists" msgstr "публикация \"%s\" уже существует" -#: commands/alter.c:98 commands/subscriptioncmds.c:629 +#: commands/alter.c:98 commands/subscriptioncmds.c:655 #, c-format msgid "subscription \"%s\" already exists" msgstr "подписка \"%s\" уже существует" @@ -7565,16 +7598,16 @@ msgstr "конфигурация текстового поиска \"%s\" уже msgid "must be superuser to rename %s" msgstr "переименовать \"%s\" может только суперпользователь" -#: commands/alter.c:256 commands/subscriptioncmds.c:608 -#: commands/subscriptioncmds.c:1147 commands/subscriptioncmds.c:1231 -#: commands/subscriptioncmds.c:1991 +#: commands/alter.c:256 commands/subscriptioncmds.c:634 +#: commands/subscriptioncmds.c:1173 commands/subscriptioncmds.c:1257 +#: commands/subscriptioncmds.c:2019 #, c-format msgid "password_required=false is superuser-only" msgstr "задать password_required=false может только суперпользователь" -#: commands/alter.c:257 commands/subscriptioncmds.c:609 -#: commands/subscriptioncmds.c:1148 commands/subscriptioncmds.c:1232 -#: commands/subscriptioncmds.c:1992 +#: commands/alter.c:257 commands/subscriptioncmds.c:635 +#: commands/subscriptioncmds.c:1174 commands/subscriptioncmds.c:1258 +#: commands/subscriptioncmds.c:2020 #, c-format msgid "" "Subscriptions with the password_required option set to false may only be " @@ -7753,7 +7786,7 @@ msgstr "кластеризовать временные таблицы друг msgid "there is no previously clustered index for table \"%s\"" msgstr "таблица \"%s\" ранее не кластеризовалась по какому-либо индексу" -#: commands/cluster.c:190 commands/tablecmds.c:16459 commands/tablecmds.c:18525 +#: commands/cluster.c:190 commands/tablecmds.c:16458 commands/tablecmds.c:18524 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "индекс \"%s\" для таблицы \"%s\" не существует" @@ -7768,7 +7801,7 @@ msgstr "кластеризовать разделяемый каталог не msgid "cannot vacuum temporary tables of other sessions" msgstr "очищать временные таблицы других сеансов нельзя" -#: commands/cluster.c:507 commands/tablecmds.c:18535 +#: commands/cluster.c:507 commands/tablecmds.c:18534 #, c-format msgid "\"%s\" is not an index for table \"%s\"" msgstr "\"%s\" не является индексом таблицы \"%s\"" @@ -7840,14 +7873,14 @@ msgid "collation attribute \"%s\" not recognized" msgstr "атрибут COLLATION \"%s\" не распознан" #: commands/collationcmds.c:123 commands/collationcmds.c:129 -#: commands/define.c:375 commands/tablecmds.c:8404 +#: commands/define.c:375 commands/tablecmds.c:8400 #: replication/pgoutput/pgoutput.c:321 replication/pgoutput/pgoutput.c:344 #: replication/pgoutput/pgoutput.c:362 replication/pgoutput/pgoutput.c:372 #: replication/pgoutput/pgoutput.c:382 replication/pgoutput/pgoutput.c:392 -#: replication/pgoutput/pgoutput.c:404 replication/walsender.c:1137 -#: replication/walsender.c:1159 replication/walsender.c:1169 -#: replication/walsender.c:1178 replication/walsender.c:1420 -#: replication/walsender.c:1429 +#: replication/pgoutput/pgoutput.c:404 replication/walsender.c:1159 +#: replication/walsender.c:1181 replication/walsender.c:1191 +#: replication/walsender.c:1200 replication/walsender.c:1442 +#: replication/walsender.c:1451 #, c-format msgid "conflicting or redundant options" msgstr "конфликтующие или избыточные параметры" @@ -7917,11 +7950,11 @@ msgstr "нельзя обновить версию правила сортиро #. translator: %s is an SQL command #. translator: %s is an SQL ALTER command -#: commands/collationcmds.c:443 commands/subscriptioncmds.c:1445 -#: commands/tablecmds.c:8156 commands/tablecmds.c:8166 -#: commands/tablecmds.c:8168 commands/tablecmds.c:16161 -#: commands/tablecmds.c:19689 commands/tablecmds.c:19710 -#: commands/typecmds.c:3786 commands/typecmds.c:3871 commands/typecmds.c:4225 +#: commands/collationcmds.c:443 commands/subscriptioncmds.c:1471 +#: commands/tablecmds.c:8152 commands/tablecmds.c:8162 +#: commands/tablecmds.c:8164 commands/tablecmds.c:16160 +#: commands/tablecmds.c:19688 commands/tablecmds.c:19709 +#: commands/typecmds.c:3793 commands/typecmds.c:3878 commands/typecmds.c:4232 #, c-format msgid "Use %s instead." msgstr "Выполните %s." @@ -8066,8 +8099,8 @@ msgstr "" msgid "generated columns are not supported in COPY FROM WHERE conditions" msgstr "генерируемые столбцы не поддерживаются в условиях COPY FROM WHERE" -#: commands/copy.c:184 commands/tablecmds.c:14430 commands/tablecmds.c:19836 -#: commands/tablecmds.c:19918 commands/trigger.c:660 +#: commands/copy.c:184 commands/tablecmds.c:14429 commands/tablecmds.c:19835 +#: commands/tablecmds.c:19917 commands/trigger.c:660 #: rewrite/rewriteHandler.c:985 rewrite/rewriteHandler.c:1020 #, c-format msgid "Column \"%s\" is a generated column." @@ -8240,10 +8273,10 @@ msgstr "Генерируемые столбцы нельзя использов #: commands/copy.c:1045 commands/indexcmds.c:1961 commands/statscmds.c:260 #: commands/tablecmds.c:2603 commands/tablecmds.c:3111 -#: commands/tablecmds.c:3940 parser/parse_relation.c:3798 -#: parser/parse_relation.c:3808 parser/parse_relation.c:3826 -#: parser/parse_relation.c:3833 parser/parse_relation.c:3847 -#: utils/adt/tsvector_op.c:2857 +#: commands/tablecmds.c:3940 parser/parse_relation.c:3830 +#: parser/parse_relation.c:3840 parser/parse_relation.c:3858 +#: parser/parse_relation.c:3865 parser/parse_relation.c:3879 +#: utils/adt/tsvector_op.c:2830 #, c-format msgid "column \"%s\" does not exist" msgstr "столбец \"%s\" не существует" @@ -9014,7 +9047,7 @@ msgid "data directory with the specified OID %u already exists" msgstr "каталог данных с указанным OID %u уже существует" #: commands/dbcommands.c:1610 commands/dbcommands.c:1625 -#: utils/adt/pg_locale.c:1532 +#: utils/adt/pg_locale.c:1538 #, c-format msgid "encoding \"%s\" does not match locale \"%s\"" msgstr "кодировка \"%s\" не соответствует локали \"%s\"" @@ -9202,7 +9235,7 @@ msgid "invalid argument for %s: \"%s\"" msgstr "неверный аргумент для %s: \"%s\"" #: commands/dropcmds.c:96 commands/functioncmds.c:1400 -#: utils/adt/ruleutils.c:2956 +#: utils/adt/ruleutils.c:2958 #, c-format msgid "\"%s\" is an aggregate function" msgstr "функция \"%s\" является агрегатной" @@ -9214,7 +9247,7 @@ msgstr "Используйте DROP AGGREGATE для удаления агрег #: commands/dropcmds.c:153 commands/sequence.c:462 commands/tablecmds.c:4024 #: commands/tablecmds.c:4185 commands/tablecmds.c:4237 -#: commands/tablecmds.c:18966 tcop/utility.c:1328 +#: commands/tablecmds.c:18965 tcop/utility.c:1328 #, c-format msgid "relation \"%s\" does not exist, skipping" msgstr "отношение \"%s\" не существует, пропускается" @@ -9425,23 +9458,23 @@ msgstr "нет прав для изменения владельца событ msgid "The owner of an event trigger must be a superuser." msgstr "Владельцем событийного триггера должен быть суперпользователь." -#: commands/event_trigger.c:1536 +#: commands/event_trigger.c:1544 #, c-format msgid "%s can only be called in a sql_drop event trigger function" msgstr "%s можно вызывать только в событийной триггерной функции sql_drop" -#: commands/event_trigger.c:1629 commands/event_trigger.c:1650 +#: commands/event_trigger.c:1637 commands/event_trigger.c:1658 #, c-format msgid "%s can only be called in a table_rewrite event trigger function" msgstr "%s можно вызывать только в событийной триггерной функции table_rewrite" -#: commands/event_trigger.c:2066 +#: commands/event_trigger.c:2074 #, c-format msgid "%s can only be called in an event trigger function" msgstr "%s можно вызывать только в событийной триггерной функции" #: commands/explain_state.c:133 commands/explain_state.c:158 -#: replication/walsender.c:1151 +#: replication/walsender.c:1173 #, c-format msgid "unrecognized value for %s option \"%s\": \"%s\"" msgstr "нераспознанное значение для параметра %s \"%s\": \"%s\"" @@ -9777,7 +9810,7 @@ msgstr "" "добавить схему \"%s\" к расширению \"%s\" нельзя, так как схема содержит " "расширение" -#: commands/extension.c:3912 commands/typecmds.c:4041 utils/fmgr/funcapi.c:725 +#: commands/extension.c:3912 commands/typecmds.c:4048 utils/fmgr/funcapi.c:725 #, c-format msgid "could not find multirange type for data type %s" msgstr "тип мультидиапазона для типа данных %s не найден" @@ -10392,7 +10425,7 @@ msgstr "" #: parser/parse_cte.c:303 parser/parse_oper.c:221 #: utils/adt/array_userfuncs.c:1419 utils/adt/array_userfuncs.c:1562 #: utils/adt/arrayfuncs.c:3870 utils/adt/arrayfuncs.c:4425 -#: utils/adt/arrayfuncs.c:6446 utils/adt/rowtypes.c:1220 +#: utils/adt/arrayfuncs.c:6453 utils/adt/rowtypes.c:1220 #, c-format msgid "could not identify an equality operator for type %s" msgstr "не удалось найти оператор равенства для типа %s" @@ -10511,7 +10544,7 @@ msgstr "включаемые столбцы не поддерживают ука msgid "could not determine which collation to use for index expression" msgstr "не удалось определить правило сортировки для индексного выражения" -#: commands/indexcmds.c:2099 commands/tablecmds.c:20006 commands/typecmds.c:812 +#: commands/indexcmds.c:2099 commands/tablecmds.c:20005 commands/typecmds.c:812 #: parser/parse_expr.c:2815 parser/parse_type.c:568 parser/parse_utilcmd.c:4073 #: utils/adt/misc.c:630 #, c-format @@ -10554,8 +10587,8 @@ msgstr "метод доступа \"%s\" не поддерживает сорт msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "метод доступа \"%s\" не поддерживает параметр NULLS FIRST/LAST" -#: commands/indexcmds.c:2279 commands/tablecmds.c:20031 -#: commands/tablecmds.c:20037 commands/typecmds.c:2349 +#: commands/indexcmds.c:2279 commands/tablecmds.c:20030 +#: commands/tablecmds.c:20036 commands/typecmds.c:2356 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" msgstr "" @@ -10577,7 +10610,7 @@ msgstr "" msgid "operator class \"%s\" does not exist for access method \"%s\"" msgstr "класс операторов \"%s\" для метода доступа \"%s\" не существует" -#: commands/indexcmds.c:2332 commands/typecmds.c:2337 +#: commands/indexcmds.c:2332 commands/typecmds.c:2344 #, c-format msgid "operator class \"%s\" does not accept data type %s" msgstr "класс операторов \"%s\" не принимает тип данных %s" @@ -10598,7 +10631,7 @@ msgstr "для типа %s не удалось найти оператор пе msgid "could not identify a contained-by operator for type %s" msgstr "не удалось найти оператор «содержится в» для типа %s" -#: commands/indexcmds.c:2474 commands/tablecmds.c:10368 +#: commands/indexcmds.c:2474 commands/tablecmds.c:10358 #, c-format msgid "" "Could not translate compare type %d for operator family \"%s\" of access " @@ -10652,7 +10685,7 @@ msgstr "при переиндексировании секционированн msgid "while reindexing partitioned index \"%s.%s\"" msgstr "при перестроении секционированного индекса \"%s.%s\"" -#: commands/indexcmds.c:3532 commands/indexcmds.c:4424 +#: commands/indexcmds.c:3532 commands/indexcmds.c:4426 #, c-format msgid "table \"%s.%s\" was reindexed" msgstr "таблица \"%s.%s\" переиндексирована" @@ -10687,12 +10720,12 @@ msgstr "" "переместить отношение, не являющееся разделяемым, в табличное пространство " "\"%s\" нельзя" -#: commands/indexcmds.c:4405 commands/indexcmds.c:4417 +#: commands/indexcmds.c:4407 commands/indexcmds.c:4419 #, c-format msgid "index \"%s.%s\" was reindexed" msgstr "индекс \"%s.%s\" был перестроен" -#: commands/indexcmds.c:4407 commands/indexcmds.c:4426 +#: commands/indexcmds.c:4409 commands/indexcmds.c:4428 #, c-format msgid "%s." msgstr "%s." @@ -11100,10 +11133,10 @@ msgstr "атрибут оператора \"%s\" нельзя изменить, #: commands/policy.c:86 commands/policy.c:379 commands/statscmds.c:152 #: commands/tablecmds.c:1810 commands/tablecmds.c:2410 #: commands/tablecmds.c:3834 commands/tablecmds.c:6803 -#: commands/tablecmds.c:10124 commands/tablecmds.c:19577 -#: commands/tablecmds.c:19612 commands/trigger.c:319 commands/trigger.c:1338 +#: commands/tablecmds.c:10114 commands/tablecmds.c:19576 +#: commands/tablecmds.c:19611 commands/trigger.c:319 commands/trigger.c:1338 #: commands/trigger.c:1448 rewrite/rewriteDefine.c:268 -#: rewrite/rewriteDefine.c:779 rewrite/rewriteRemove.c:74 +#: rewrite/rewriteDefine.c:764 rewrite/rewriteRemove.c:74 #, c-format msgid "permission denied: \"%s\" is a system catalog" msgstr "доступ запрещён: \"%s\" - это системный каталог" @@ -11377,7 +11410,7 @@ msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." msgstr "В публикации всех таблиц нельзя добавлять или удалять таблицы." #: commands/publicationcmds.c:1497 commands/publicationcmds.c:1536 -#: commands/publicationcmds.c:2073 utils/cache/lsyscache.c:3812 +#: commands/publicationcmds.c:2073 utils/cache/lsyscache.c:3936 #, c-format msgid "publication \"%s\" does not exist" msgstr "публикация \"%s\" не существует" @@ -11621,8 +11654,8 @@ msgstr "" msgid "cannot change ownership of identity sequence" msgstr "сменить владельца последовательности идентификации нельзя" -#: commands/sequence.c:1671 commands/tablecmds.c:16148 -#: commands/tablecmds.c:18986 +#: commands/sequence.c:1671 commands/tablecmds.c:16147 +#: commands/tablecmds.c:18985 #, c-format msgid "Sequence \"%s\" is linked to table \"%s\"." msgstr "Последовательность \"%s\" связана с таблицей \"%s\"." @@ -11710,12 +11743,12 @@ msgstr "повторяющееся имя столбца в определени msgid "duplicate expression in statistics definition" msgstr "повторяющееся выражение в определении статистики" -#: commands/statscmds.c:667 commands/tablecmds.c:8949 +#: commands/statscmds.c:667 commands/tablecmds.c:8940 #, c-format msgid "statistics target %d is too low" msgstr "ориентир статистики слишком мал (%d)" -#: commands/statscmds.c:675 commands/tablecmds.c:8957 +#: commands/statscmds.c:675 commands/tablecmds.c:8948 #, c-format msgid "lowering statistics target to %d" msgstr "ориентир статистики снижается до %d" @@ -11754,12 +11787,12 @@ msgstr "указания %s и %s являются взаимоисключаю msgid "subscription with %s must also set %s" msgstr "для подписки с параметром %s необходимо также задать %s" -#: commands/subscriptioncmds.c:466 +#: commands/subscriptioncmds.c:492 #, c-format msgid "could not receive list of publications from the publisher: %s" msgstr "не удалось получить список публикаций с публикующего сервера: %s" -#: commands/subscriptioncmds.c:498 +#: commands/subscriptioncmds.c:524 #, c-format msgid "publication %s does not exist on the publisher" msgid_plural "publications %s do not exist on the publisher" @@ -11767,33 +11800,33 @@ msgstr[0] "публикация %s не существует на публику msgstr[1] "публикации %s не существуют на публикующем сервере" msgstr[2] "публикации %s не существуют на публикующем сервере" -#: commands/subscriptioncmds.c:586 +#: commands/subscriptioncmds.c:612 #, c-format msgid "permission denied to create subscription" msgstr "нет прав для создания подписки" -#: commands/subscriptioncmds.c:587 +#: commands/subscriptioncmds.c:613 #, c-format msgid "Only roles with privileges of the \"%s\" role may create subscriptions." msgstr "Создавать подписки могут только роли с правами роли \"%s\"." -#: commands/subscriptioncmds.c:718 commands/subscriptioncmds.c:852 -#: commands/subscriptioncmds.c:1594 +#: commands/subscriptioncmds.c:744 commands/subscriptioncmds.c:878 +#: commands/subscriptioncmds.c:1620 #, c-format msgid "subscription \"%s\" could not connect to the publisher: %s" msgstr "подключить подписку \"%s\" к серверу публикации не удалось: %s" -#: commands/subscriptioncmds.c:790 +#: commands/subscriptioncmds.c:816 #, c-format msgid "created replication slot \"%s\" on publisher" msgstr "на сервере публикации создан слот репликации \"%s\"" -#: commands/subscriptioncmds.c:802 +#: commands/subscriptioncmds.c:828 #, c-format msgid "subscription was created, but is not connected" msgstr "подписка создана, но не подключена" -#: commands/subscriptioncmds.c:803 +#: commands/subscriptioncmds.c:829 #, c-format msgid "" "To initiate replication, you must manually create the replication slot, " @@ -11802,35 +11835,35 @@ msgstr "" "Чтобы начать репликацию, вы должны вручную создать слот репликации, включить " "подписку, а затем обновить её." -#: commands/subscriptioncmds.c:1070 +#: commands/subscriptioncmds.c:1096 #, c-format msgid "cannot set option \"%s\" for enabled subscription" msgstr "для включённой подписки нельзя задать параметр \"%s\"" -#: commands/subscriptioncmds.c:1084 +#: commands/subscriptioncmds.c:1110 #, c-format msgid "" "cannot set option \"%s\" for a subscription that does not have a slot name" msgstr "" "задать параметр \"%s\" для подписки, для которой не задано имя слота, нельзя" -#: commands/subscriptioncmds.c:1127 commands/subscriptioncmds.c:1665 -#: commands/subscriptioncmds.c:2046 utils/cache/lsyscache.c:3862 +#: commands/subscriptioncmds.c:1153 commands/subscriptioncmds.c:1691 +#: commands/subscriptioncmds.c:2074 utils/cache/lsyscache.c:3986 #, c-format msgid "subscription \"%s\" does not exist" msgstr "подписка \"%s\" не существует" -#: commands/subscriptioncmds.c:1185 +#: commands/subscriptioncmds.c:1211 #, c-format msgid "cannot set %s for enabled subscription" msgstr "для включённой подписки нельзя задать %s" -#: commands/subscriptioncmds.c:1270 +#: commands/subscriptioncmds.c:1296 #, c-format msgid "\"slot_name\" and \"two_phase\" cannot be altered at the same time" msgstr "параметры \"slot_name\" и \"two_phase\" нельзя изменить одновременно" -#: commands/subscriptioncmds.c:1286 +#: commands/subscriptioncmds.c:1312 #, c-format msgid "" "cannot alter \"two_phase\" when logical replication worker is still running" @@ -11838,41 +11871,41 @@ msgstr "" "изменить параметр \"two_phase\", пока выполняется рабочий процесс логической " "репликации, нельзя" -#: commands/subscriptioncmds.c:1287 +#: commands/subscriptioncmds.c:1313 #, c-format msgid "Try again after some time." msgstr "Повторите попытку позже." -#: commands/subscriptioncmds.c:1300 +#: commands/subscriptioncmds.c:1326 #, c-format msgid "cannot disable \"two_phase\" when prepared transactions exist" msgstr "" "отключить \"two_phase\" нельзя, когда существуют подготовленные транзакции" -#: commands/subscriptioncmds.c:1301 +#: commands/subscriptioncmds.c:1327 #, c-format msgid "Resolve these transactions and try again." msgstr "Повторите попытку после завершения этих транзакций." -#: commands/subscriptioncmds.c:1348 +#: commands/subscriptioncmds.c:1374 #, c-format msgid "cannot enable subscription that does not have a slot name" msgstr "включить подписку, для которой не задано имя слота, нельзя" -#: commands/subscriptioncmds.c:1392 commands/subscriptioncmds.c:1443 +#: commands/subscriptioncmds.c:1418 commands/subscriptioncmds.c:1469 #, c-format msgid "" "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" msgstr "" "ALTER SUBSCRIPTION с обновлением для отключённых подписок не допускается" -#: commands/subscriptioncmds.c:1393 +#: commands/subscriptioncmds.c:1419 #, c-format msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." msgstr "" "Выполните ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." -#: commands/subscriptioncmds.c:1402 commands/subscriptioncmds.c:1457 +#: commands/subscriptioncmds.c:1428 commands/subscriptioncmds.c:1483 #, c-format msgid "" "ALTER SUBSCRIPTION with refresh and copy_data is not allowed when two_phase " @@ -11881,7 +11914,7 @@ msgstr "" "ALTER SUBSCRIPTION с параметром публикации refresh в режиме copy_data не " "допускается, когда включён параметр two_phase" -#: commands/subscriptioncmds.c:1403 +#: commands/subscriptioncmds.c:1429 #, c-format msgid "" "Use ALTER SUBSCRIPTION ... SET PUBLICATION with refresh = false, or with " @@ -11891,7 +11924,7 @@ msgstr "" "copy_data = false либо выполните DROP/CREATE SUBSCRIPTION." #. translator: %s is an SQL ALTER command -#: commands/subscriptioncmds.c:1459 +#: commands/subscriptioncmds.c:1485 #, c-format msgid "" "Use %s with refresh = false, or with copy_data = false, or use DROP/CREATE " @@ -11900,13 +11933,13 @@ msgstr "" "Выполните %s с refresh = false или с copy_data = false либо выполните DROP/" "CREATE SUBSCRIPTION." -#: commands/subscriptioncmds.c:1481 +#: commands/subscriptioncmds.c:1507 #, c-format msgid "" "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" msgstr "ALTER SUBSCRIPTION ... REFRESH для отключённых подписок не допускается" -#: commands/subscriptioncmds.c:1506 +#: commands/subscriptioncmds.c:1532 #, c-format msgid "" "ALTER SUBSCRIPTION ... REFRESH with copy_data is not allowed when two_phase " @@ -11915,7 +11948,7 @@ msgstr "" "ALTER SUBSCRIPTION ... REFRESH в режиме copy_data не допускается, когда " "включён параметр two_phase" -#: commands/subscriptioncmds.c:1507 +#: commands/subscriptioncmds.c:1533 #, c-format msgid "" "Use ALTER SUBSCRIPTION ... REFRESH with copy_data = false, or use DROP/" @@ -11924,39 +11957,39 @@ msgstr "" "Выполните ALTER SUBSCRIPTION ... REFRESH с copy_data = false либо выполните " "DROP/CREATE SUBSCRIPTION." -#: commands/subscriptioncmds.c:1542 +#: commands/subscriptioncmds.c:1568 #, c-format msgid "skip WAL location (LSN %X/%X) must be greater than origin LSN %X/%X" msgstr "" "позиция пропуска в WAL (LSN %X/%X) должна быть больше начального LSN %X/%X" -#: commands/subscriptioncmds.c:1669 +#: commands/subscriptioncmds.c:1695 #, c-format msgid "subscription \"%s\" does not exist, skipping" msgstr "подписка \"%s\" не существует, пропускается" -#: commands/subscriptioncmds.c:1936 +#: commands/subscriptioncmds.c:1964 #, c-format msgid "dropped replication slot \"%s\" on publisher" msgstr "слот репликации \"%s\" удалён на сервере репликации" -#: commands/subscriptioncmds.c:1945 commands/subscriptioncmds.c:1953 +#: commands/subscriptioncmds.c:1973 commands/subscriptioncmds.c:1981 #, c-format msgid "could not drop replication slot \"%s\" on publisher: %s" msgstr "слот репликации \"%s\" на сервере публикации не был удалён: %s" -#: commands/subscriptioncmds.c:2078 +#: commands/subscriptioncmds.c:2106 #, c-format msgid "subscription with OID %u does not exist" msgstr "подписка с OID %u не существует" -#: commands/subscriptioncmds.c:2152 commands/subscriptioncmds.c:2276 +#: commands/subscriptioncmds.c:2185 commands/subscriptioncmds.c:2309 #, c-format msgid "could not receive list of replicated tables from the publisher: %s" msgstr "" "не удалось получить список реплицируемых таблиц с сервера репликации: %s" -#: commands/subscriptioncmds.c:2188 +#: commands/subscriptioncmds.c:2221 #, c-format msgid "" "subscription \"%s\" requested copy_data with origin = NONE but might copy " @@ -11965,7 +11998,7 @@ msgstr "" "для подписки \"%s\" выбран режим copy_data с origin = NONE, но в неё могут " "попасть данные из другого источника" -#: commands/subscriptioncmds.c:2190 +#: commands/subscriptioncmds.c:2223 #, c-format msgid "" "The subscription being created subscribes to a publication (%s) that " @@ -11983,7 +12016,7 @@ msgstr[2] "" "Создаваемая подписка связана с публикациями (%s), содержащими таблицы, в " "которые записывают другие подписки." -#: commands/subscriptioncmds.c:2193 +#: commands/subscriptioncmds.c:2226 #, c-format msgid "" "Verify that initial data copied from the publisher tables did not come from " @@ -11992,7 +12025,7 @@ msgstr "" "Убедитесь, что начальные данные, скопированные из таблиц публикации, " "поступили не из других источников." -#: commands/subscriptioncmds.c:2298 replication/logical/tablesync.c:933 +#: commands/subscriptioncmds.c:2331 replication/logical/tablesync.c:933 #: replication/pgoutput/pgoutput.c:1189 #, c-format msgid "" @@ -12002,7 +12035,7 @@ msgstr "" "использовать различные списки столбцов таблицы \"%s.%s\" в разных " "публикациях нельзя" -#: commands/subscriptioncmds.c:2348 +#: commands/subscriptioncmds.c:2381 #, c-format msgid "" "could not connect to publisher when attempting to drop replication slot " @@ -12012,7 +12045,7 @@ msgstr "" "\"%s\": %s" #. translator: %s is an SQL ALTER command -#: commands/subscriptioncmds.c:2351 +#: commands/subscriptioncmds.c:2384 #, c-format msgid "" "Use %s to disable the subscription, and then use %s to disassociate it from " @@ -12021,27 +12054,27 @@ msgstr "" "Выполните %s, чтобы отключить подписку, а затем выполните %s, чтобы отвязать " "её от слота." -#: commands/subscriptioncmds.c:2382 +#: commands/subscriptioncmds.c:2415 #, c-format msgid "publication name \"%s\" used more than once" msgstr "имя публикации \"%s\" используется неоднократно" -#: commands/subscriptioncmds.c:2426 +#: commands/subscriptioncmds.c:2459 #, c-format msgid "publication \"%s\" is already in subscription \"%s\"" msgstr "публикация \"%s\" уже имеется в подписке \"%s\"" -#: commands/subscriptioncmds.c:2440 +#: commands/subscriptioncmds.c:2473 #, c-format msgid "publication \"%s\" is not in subscription \"%s\"" msgstr "публикация \"%s\" отсутствует в подписке \"%s\"" -#: commands/subscriptioncmds.c:2451 +#: commands/subscriptioncmds.c:2484 #, c-format msgid "cannot drop all the publications from a subscription" msgstr "удалить все публикации из подписки нельзя" -#: commands/subscriptioncmds.c:2508 +#: commands/subscriptioncmds.c:2541 #, c-format msgid "%s requires a Boolean value or \"parallel\"" msgstr "%s требует логическое значение или \"parallel\"" @@ -12104,7 +12137,7 @@ msgstr "" "Выполните DROP MATERIALIZED VIEW для удаления материализованного " "представления." -#: commands/tablecmds.c:282 commands/tablecmds.c:306 commands/tablecmds.c:21663 +#: commands/tablecmds.c:282 commands/tablecmds.c:306 commands/tablecmds.c:21662 #: parser/parse_utilcmd.c:2432 #, c-format msgid "index \"%s\" does not exist" @@ -12128,8 +12161,8 @@ msgstr "\"%s\" - это не тип" msgid "Use DROP TYPE to remove a type." msgstr "Выполните DROP TYPE для удаления типа." -#: commands/tablecmds.c:294 commands/tablecmds.c:15987 -#: commands/tablecmds.c:18688 +#: commands/tablecmds.c:294 commands/tablecmds.c:15986 +#: commands/tablecmds.c:18687 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "сторонняя таблица \"%s\" не существует" @@ -12160,7 +12193,7 @@ msgstr "" "в рамках операции с ограничениями по безопасности нельзя создать временную " "таблицу" -#: commands/tablecmds.c:876 commands/tablecmds.c:17412 +#: commands/tablecmds.c:876 commands/tablecmds.c:17411 #, c-format msgid "relation \"%s\" would be inherited from more than once" msgstr "отношение \"%s\" наследуется неоднократно" @@ -12185,13 +12218,13 @@ msgstr "создать стороннюю секцию для секционир msgid "Table \"%s\" contains indexes that are unique." msgstr "Таблица \"%s\" содержит индексы, являющиеся уникальными." -#: commands/tablecmds.c:1425 commands/tablecmds.c:14964 +#: commands/tablecmds.c:1425 commands/tablecmds.c:14963 #, c-format msgid "too many array dimensions" msgstr "слишком много размерностей массива" #: commands/tablecmds.c:1430 parser/parse_clause.c:772 -#: parser/parse_relation.c:1929 +#: parser/parse_relation.c:1961 #, c-format msgid "column \"%s\" cannot be declared SETOF" msgstr "столбец \"%s\" не может быть объявлен как SETOF" @@ -12240,7 +12273,7 @@ msgstr "опустошить стороннюю таблицу \"%s\" нельз msgid "cannot truncate temporary tables of other sessions" msgstr "временные таблицы других сеансов нельзя опустошить" -#: commands/tablecmds.c:2685 commands/tablecmds.c:17309 +#: commands/tablecmds.c:2685 commands/tablecmds.c:17308 #, c-format msgid "cannot inherit from partitioned table \"%s\"" msgstr "наследование от секционированной таблицы \"%s\" не допускается" @@ -12265,18 +12298,18 @@ msgstr "" "создать временное отношение в качестве секции постоянного отношения \"%s\" " "нельзя" -#: commands/tablecmds.c:2719 commands/tablecmds.c:17288 +#: commands/tablecmds.c:2719 commands/tablecmds.c:17287 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "временное отношение \"%s\" не может наследоваться" -#: commands/tablecmds.c:2729 commands/tablecmds.c:17296 +#: commands/tablecmds.c:2729 commands/tablecmds.c:17295 #, c-format msgid "cannot inherit from temporary relation of another session" msgstr "наследование от временного отношения другого сеанса невозможно" #: commands/tablecmds.c:2884 commands/tablecmds.c:2938 -#: commands/tablecmds.c:14647 parser/parse_utilcmd.c:1440 +#: commands/tablecmds.c:14646 parser/parse_utilcmd.c:1440 #: parser/parse_utilcmd.c:1484 parser/parse_utilcmd.c:1916 #: parser/parse_utilcmd.c:2024 #, c-format @@ -12324,13 +12357,13 @@ msgstr "" "является таковым." #: commands/tablecmds.c:3082 commands/tablecmds.c:3376 -#: commands/tablecmds.c:17574 +#: commands/tablecmds.c:17573 #, c-format msgid "column \"%s\" inherits from generated column of different kind" msgstr "столбец \"%s\" наследуется от генерируемого столбца другого вида" #: commands/tablecmds.c:3084 commands/tablecmds.c:3378 -#: commands/tablecmds.c:17575 +#: commands/tablecmds.c:17574 #, c-format msgid "Parent column is %s, child column is %s." msgstr "Родительский столбец: %s, дочерний столбец: %s." @@ -12388,11 +12421,11 @@ msgstr "конфликт типов в столбце \"%s\"" #: commands/tablecmds.c:3278 commands/tablecmds.c:3312 #: commands/tablecmds.c:3328 commands/tablecmds.c:3444 #: commands/tablecmds.c:3472 commands/tablecmds.c:3488 -#: parser/parse_coerce.c:2190 parser/parse_coerce.c:2210 -#: parser/parse_coerce.c:2230 parser/parse_coerce.c:2251 -#: parser/parse_coerce.c:2306 parser/parse_coerce.c:2340 -#: parser/parse_coerce.c:2416 parser/parse_coerce.c:2447 -#: parser/parse_coerce.c:2486 parser/parse_coerce.c:2553 +#: parser/parse_coerce.c:2189 parser/parse_coerce.c:2209 +#: parser/parse_coerce.c:2229 parser/parse_coerce.c:2250 +#: parser/parse_coerce.c:2305 parser/parse_coerce.c:2339 +#: parser/parse_coerce.c:2415 parser/parse_coerce.c:2446 +#: parser/parse_coerce.c:2485 parser/parse_coerce.c:2552 #: parser/parse_param.c:224 #, c-format msgid "%s versus %s" @@ -12404,7 +12437,7 @@ msgid "column \"%s\" has a collation conflict" msgstr "конфликт правил сортировки в столбце \"%s\"" #: commands/tablecmds.c:3292 commands/tablecmds.c:3458 -#: commands/tablecmds.c:7287 parser/parse_expr.c:4792 +#: commands/tablecmds.c:7287 parser/parse_expr.c:4802 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "\"%s\" и \"%s\"" @@ -12630,12 +12663,12 @@ msgstr "добавить столбец в типизированную табл msgid "cannot add column to a partition" msgstr "добавить столбец в секцию нельзя" -#: commands/tablecmds.c:7279 commands/tablecmds.c:17530 +#: commands/tablecmds.c:7279 commands/tablecmds.c:17529 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" msgstr "дочерняя таблица \"%s\" имеет другой тип для столбца \"%s\"" -#: commands/tablecmds.c:7285 commands/tablecmds.c:17536 +#: commands/tablecmds.c:7285 commands/tablecmds.c:17535 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" msgstr "" @@ -12667,19 +12700,19 @@ msgstr "столбец \"%s\" отношения \"%s\" уже существу msgid "column \"%s\" of relation \"%s\" already exists" msgstr "столбец \"%s\" отношения \"%s\" уже существует" -#: commands/tablecmds.c:7779 commands/tablecmds.c:7946 -#: commands/tablecmds.c:8147 commands/tablecmds.c:8278 -#: commands/tablecmds.c:8432 commands/tablecmds.c:8526 -#: commands/tablecmds.c:8629 commands/tablecmds.c:8825 -#: commands/tablecmds.c:8991 commands/tablecmds.c:9082 -#: commands/tablecmds.c:9216 commands/tablecmds.c:14419 -#: commands/tablecmds.c:16010 commands/tablecmds.c:18777 +#: commands/tablecmds.c:7779 commands/tablecmds.c:7942 +#: commands/tablecmds.c:8143 commands/tablecmds.c:8274 +#: commands/tablecmds.c:8428 commands/tablecmds.c:8522 +#: commands/tablecmds.c:8625 commands/tablecmds.c:8816 +#: commands/tablecmds.c:8982 commands/tablecmds.c:9073 +#: commands/tablecmds.c:9207 commands/tablecmds.c:14418 +#: commands/tablecmds.c:16009 commands/tablecmds.c:18776 #, c-format msgid "cannot alter system column \"%s\"" msgstr "системный столбец \"%s\" нельзя изменить" -#: commands/tablecmds.c:7785 commands/tablecmds.c:8153 -#: commands/tablecmds.c:14180 +#: commands/tablecmds.c:7785 commands/tablecmds.c:8149 +#: commands/tablecmds.c:14179 #, c-format msgid "column \"%s\" of relation \"%s\" is an identity column" msgstr "столбец \"%s\" отношения \"%s\" является столбцом идентификации" @@ -12689,36 +12722,36 @@ msgstr "столбец \"%s\" отношения \"%s\" является сто msgid "column \"%s\" is marked NOT NULL in parent table" msgstr "столбец \"%s\" в родительской таблице помечен как NOT NULL" -#: commands/tablecmds.c:8024 commands/tablecmds.c:10023 +#: commands/tablecmds.c:8020 commands/tablecmds.c:10013 #, c-format msgid "constraint must be added to child tables too" msgstr "ограничение также должно быть добавлено к дочерним таблицам" -#: commands/tablecmds.c:8025 commands/tablecmds.c:8256 -#: commands/tablecmds.c:8388 commands/tablecmds.c:8505 -#: commands/tablecmds.c:9389 commands/tablecmds.c:12217 +#: commands/tablecmds.c:8021 commands/tablecmds.c:8252 +#: commands/tablecmds.c:8384 commands/tablecmds.c:8501 +#: commands/tablecmds.c:9380 commands/tablecmds.c:12207 #, c-format msgid "Do not specify the ONLY keyword." msgstr "Не указывайте ключевое слово ONLY." -#: commands/tablecmds.c:8162 +#: commands/tablecmds.c:8158 #, c-format msgid "column \"%s\" of relation \"%s\" is a generated column" msgstr "столбец \"%s\" отношения \"%s\" является генерируемым" -#: commands/tablecmds.c:8255 +#: commands/tablecmds.c:8251 #, c-format msgid "cannot add identity to a column of only the partitioned table" msgstr "" "сделать столбцом идентификации столбец одной лишь секционированной таблицы " "нельзя" -#: commands/tablecmds.c:8261 +#: commands/tablecmds.c:8257 #, c-format msgid "cannot add identity to a column of a partition" msgstr "сделать столбцом идентификации столбец одной секции нельзя" -#: commands/tablecmds.c:8289 +#: commands/tablecmds.c:8285 #, c-format msgid "" "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity " @@ -12727,57 +12760,57 @@ msgstr "" "столбец \"%s\" отношения \"%s\" должен быть объявлен как NOT NULL, чтобы его " "можно было сделать столбцом идентификации" -#: commands/tablecmds.c:8320 +#: commands/tablecmds.c:8316 #, c-format msgid "column \"%s\" of relation \"%s\" is already an identity column" msgstr "столбец \"%s\" отношения \"%s\" уже является столбцом идентификации" -#: commands/tablecmds.c:8326 +#: commands/tablecmds.c:8322 #, c-format msgid "column \"%s\" of relation \"%s\" already has a default value" msgstr "столбец \"%s\" отношения \"%s\" уже имеет значение по умолчанию" -#: commands/tablecmds.c:8387 +#: commands/tablecmds.c:8383 #, c-format msgid "cannot change identity column of only the partitioned table" msgstr "" "изменить столбец идентификации для одной лишь секционированной таблицы нельзя" -#: commands/tablecmds.c:8393 +#: commands/tablecmds.c:8389 #, c-format msgid "cannot change identity column of a partition" msgstr "изменить столбец идентификации для одной секции нельзя" -#: commands/tablecmds.c:8438 commands/tablecmds.c:8534 +#: commands/tablecmds.c:8434 commands/tablecmds.c:8530 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column" msgstr "столбец \"%s\" отношения \"%s\" не является столбцом идентификации" -#: commands/tablecmds.c:8504 +#: commands/tablecmds.c:8500 #, c-format msgid "cannot drop identity from a column of only the partitioned table" msgstr "" "лишить свойства идентификации столбец одной лишь секционированной таблицы " "нельзя" -#: commands/tablecmds.c:8510 +#: commands/tablecmds.c:8506 #, c-format msgid "cannot drop identity from a column of a partition" msgstr "лишить свойства идентификации столбец одной секции нельзя" -#: commands/tablecmds.c:8539 +#: commands/tablecmds.c:8535 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" msgstr "" "столбец \"%s\" отношения \"%s\" не является столбцом идентификации, " "пропускается" -#: commands/tablecmds.c:8636 commands/tablecmds.c:8846 +#: commands/tablecmds.c:8632 commands/tablecmds.c:8837 #, c-format msgid "column \"%s\" of relation \"%s\" is not a generated column" msgstr "столбец \"%s\" отношения \"%s\" не является генерируемым столбцом" -#: commands/tablecmds.c:8647 +#: commands/tablecmds.c:8643 #, c-format msgid "" "ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns " @@ -12786,14 +12819,14 @@ msgstr "" "ALTER TABLE / SET EXPRESSION не поддерживается для виртуальных генерируемых " "столбцов в таблицах с ограничениями-проверками" -#: commands/tablecmds.c:8648 commands/tablecmds.c:8666 -#: commands/tablecmds.c:8838 +#: commands/tablecmds.c:8644 commands/tablecmds.c:8662 +#: commands/tablecmds.c:8829 #, c-format msgid "Column \"%s\" of relation \"%s\" is a virtual generated column." msgstr "" "Столбец \"%s\" отношения \"%s\" является виртуальным генерируемым столбцом." -#: commands/tablecmds.c:8665 +#: commands/tablecmds.c:8661 #, c-format msgid "" "ALTER TABLE / SET EXPRESSION is not supported for virtual generated columns " @@ -12802,18 +12835,18 @@ msgstr "" "ALTER TABLE / SET EXPRESSION не поддерживается для виртуальных генерируемых " "столбцов в таблицах, включённых в публикацию" -#: commands/tablecmds.c:8772 +#: commands/tablecmds.c:8763 #, c-format msgid "ALTER TABLE / DROP EXPRESSION must be applied to child tables too" msgstr "" "ALTER TABLE / DROP EXPRESSION нужно применять также к дочерним таблицам" -#: commands/tablecmds.c:8794 +#: commands/tablecmds.c:8785 #, c-format msgid "cannot drop generation expression from inherited column" msgstr "нельзя удалить генерирующее выражение из наследуемого столбца" -#: commands/tablecmds.c:8837 +#: commands/tablecmds.c:8828 #, c-format msgid "" "ALTER TABLE / DROP EXPRESSION is not supported for virtual generated columns" @@ -12821,65 +12854,65 @@ msgstr "" "ALTER TABLE / DROP EXPRESSION не поддерживается для виртуальных генерируемых " "столбцов" -#: commands/tablecmds.c:8851 +#: commands/tablecmds.c:8842 #, c-format msgid "column \"%s\" of relation \"%s\" is not a generated column, skipping" msgstr "" "столбец \"%s\" отношения \"%s\" пропускается, так как не является " "генерируемым столбцом" -#: commands/tablecmds.c:8929 +#: commands/tablecmds.c:8920 #, c-format msgid "cannot refer to non-index column by number" msgstr "по номеру можно ссылаться только на столбец в индексе" -#: commands/tablecmds.c:8981 +#: commands/tablecmds.c:8972 #, c-format msgid "column number %d of relation \"%s\" does not exist" msgstr "столбец с номером %d отношения \"%s\" не существует" -#: commands/tablecmds.c:9001 +#: commands/tablecmds.c:8992 #, c-format msgid "cannot alter statistics on virtual generated column \"%s\"" msgstr "изменить статистику виртуального генерируемого столбца \"%s\" нельзя" -#: commands/tablecmds.c:9010 +#: commands/tablecmds.c:9001 #, c-format msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" msgstr "изменить статистику включённого столбца \"%s\" индекса \"%s\" нельзя" -#: commands/tablecmds.c:9015 +#: commands/tablecmds.c:9006 #, c-format msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" msgstr "" "изменить статистику столбца \"%s\" (не выражения) индекса \"%s\" нельзя" -#: commands/tablecmds.c:9017 +#: commands/tablecmds.c:9008 #, c-format msgid "Alter statistics on table column instead." msgstr "Вместо этого измените статистику для столбца в таблице." -#: commands/tablecmds.c:9263 +#: commands/tablecmds.c:9254 #, c-format msgid "cannot drop column from typed table" msgstr "нельзя удалить столбец в типизированной таблице" -#: commands/tablecmds.c:9327 +#: commands/tablecmds.c:9318 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" msgstr "столбец \"%s\" в таблице\"%s\" не существует, пропускается" -#: commands/tablecmds.c:9340 +#: commands/tablecmds.c:9331 #, c-format msgid "cannot drop system column \"%s\"" msgstr "нельзя удалить системный столбец \"%s\"" -#: commands/tablecmds.c:9350 +#: commands/tablecmds.c:9341 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "нельзя удалить наследованный столбец \"%s\"" -#: commands/tablecmds.c:9363 +#: commands/tablecmds.c:9354 #, c-format msgid "" "cannot drop column \"%s\" because it is part of the partition key of " @@ -12888,7 +12921,7 @@ msgstr "" "удалить столбец \"%s\" нельзя, так как он входит в ключ разбиения отношения " "\"%s\"" -#: commands/tablecmds.c:9388 +#: commands/tablecmds.c:9379 #, c-format msgid "" "cannot drop column from only the partitioned table when partitions exist" @@ -12896,18 +12929,18 @@ msgstr "" "удалить столбец только из секционированной таблицы, когда существуют секции, " "нельзя" -#: commands/tablecmds.c:9553 +#: commands/tablecmds.c:9544 #, c-format msgid "column \"%s\" of table \"%s\" is not marked NOT NULL" msgstr "столбец \"%s\" таблицы \"%s\" не помечен как NOT NULL" -#: commands/tablecmds.c:9589 commands/tablecmds.c:9601 +#: commands/tablecmds.c:9580 commands/tablecmds.c:9592 #, c-format msgid "cannot create primary key on column \"%s\"" msgstr "создать первичный ключ со столбцом \"%s\" нельзя" #. translator: fourth %s is a constraint characteristic such as NOT VALID -#: commands/tablecmds.c:9591 commands/tablecmds.c:9603 +#: commands/tablecmds.c:9582 commands/tablecmds.c:9594 #, c-format msgid "" "The constraint \"%s\" on column \"%s\" of table \"%s\", marked %s, is " @@ -12916,7 +12949,7 @@ msgstr "" "Ограничение \"%s\" для столбца \"%s\" таблицы \"%s\", помеченное %s, " "несовместимо с первичным ключом." -#: commands/tablecmds.c:9727 +#: commands/tablecmds.c:9718 #, c-format msgid "" "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned " @@ -12925,14 +12958,14 @@ msgstr "" "ALTER TABLE / ADD CONSTRAINT USING INDEX не поддерживается с " "секционированными таблицами" -#: commands/tablecmds.c:9752 +#: commands/tablecmds.c:9743 #, c-format msgid "" "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" msgstr "" "ALTER TABLE / ADD CONSTRAINT USING INDEX переименует индекс \"%s\" в \"%s\"" -#: commands/tablecmds.c:10110 +#: commands/tablecmds.c:10100 #, c-format msgid "" "cannot use ONLY for foreign key on partitioned table \"%s\" referencing " @@ -12941,19 +12974,19 @@ msgstr "" "нельзя использовать ONLY для стороннего ключа в секционированной таблице " "\"%s\", ссылающегося на отношение \"%s\"" -#: commands/tablecmds.c:10118 commands/tablecmds.c:10745 +#: commands/tablecmds.c:10108 commands/tablecmds.c:10735 #, c-format msgid "referenced relation \"%s\" is not a table" msgstr "указанный объект \"%s\" не является таблицей" -#: commands/tablecmds.c:10141 +#: commands/tablecmds.c:10131 #, c-format msgid "constraints on permanent tables may reference only permanent tables" msgstr "" "ограничения в постоянных таблицах могут ссылаться только на постоянные " "таблицы" -#: commands/tablecmds.c:10148 +#: commands/tablecmds.c:10138 #, c-format msgid "" "constraints on unlogged tables may reference only permanent or unlogged " @@ -12962,13 +12995,13 @@ msgstr "" "ограничения в нежурналируемых таблицах могут ссылаться только на постоянные " "или нежурналируемые таблицы" -#: commands/tablecmds.c:10154 +#: commands/tablecmds.c:10144 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "" "ограничения во временных таблицах могут ссылаться только на временные таблицы" -#: commands/tablecmds.c:10158 +#: commands/tablecmds.c:10148 #, c-format msgid "" "constraints on temporary tables must involve temporary tables of this session" @@ -12976,19 +13009,19 @@ msgstr "" "ограничения во временных таблицах должны ссылаться только на временные " "таблицы текущего сеанса" -#: commands/tablecmds.c:10173 commands/tablecmds.c:10201 +#: commands/tablecmds.c:10163 commands/tablecmds.c:10191 #, c-format msgid "" "foreign key uses PERIOD on the referenced table but not the referencing table" msgstr "внешний ключ использует PERIOD в целевой таблице, но не в ссылающейся" -#: commands/tablecmds.c:10213 +#: commands/tablecmds.c:10203 #, c-format msgid "" "foreign key uses PERIOD on the referencing table but not the referenced table" msgstr "внешний ключ использует PERIOD в ссылающейся таблице, но не в целевой" -#: commands/tablecmds.c:10227 +#: commands/tablecmds.c:10217 #, c-format msgid "" "foreign key must use PERIOD when referencing a primary key using WITHOUT " @@ -12997,7 +13030,7 @@ msgstr "" "внешний ключ должен использовать PERIOD, ссылаясь на первичный ключ, " "использующий WITHOUT OVERLAPS" -#: commands/tablecmds.c:10251 commands/tablecmds.c:10257 +#: commands/tablecmds.c:10241 commands/tablecmds.c:10247 #, c-format msgid "" "invalid %s action for foreign key constraint containing generated column" @@ -13005,41 +13038,41 @@ msgstr "" "некорректное действие %s для ограничения внешнего ключа, содержащего " "генерируемый столбец" -#: commands/tablecmds.c:10272 +#: commands/tablecmds.c:10262 #, c-format msgid "foreign key constraints on virtual generated columns are not supported" msgstr "" "ограничения внешних ключей с виртуальными генерируемыми столбцами не " "поддерживаются" -#: commands/tablecmds.c:10286 commands/tablecmds.c:10295 +#: commands/tablecmds.c:10276 commands/tablecmds.c:10285 #, c-format msgid "unsupported %s action for foreign key constraint using PERIOD" msgstr "" "неподдерживаемое действие %s для ограничения внешнего ключа с указанием " "PERIOD" -#: commands/tablecmds.c:10310 +#: commands/tablecmds.c:10300 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "число столбцов в источнике и назначении внешнего ключа не совпадает" -#: commands/tablecmds.c:10366 +#: commands/tablecmds.c:10356 #, c-format msgid "could not identify an overlaps operator for foreign key" msgstr "не удалось найти оператор пересечения для внешнего ключа" -#: commands/tablecmds.c:10367 +#: commands/tablecmds.c:10357 #, c-format msgid "could not identify an equality operator for foreign key" msgstr "не удалось найти оператор равенства для внешнего ключа" -#: commands/tablecmds.c:10432 commands/tablecmds.c:10466 +#: commands/tablecmds.c:10422 commands/tablecmds.c:10456 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "ограничение внешнего ключа \"%s\" нельзя реализовать" -#: commands/tablecmds.c:10434 +#: commands/tablecmds.c:10424 #, c-format msgid "" "Key columns \"%s\" of the referencing table and \"%s\" of the referenced " @@ -13048,7 +13081,7 @@ msgstr "" "Столбцы ключа \"%s\" ссылающейся таблицы и \"%s\" целевой таблицы имеют " "несовместимые типы: %s и %s." -#: commands/tablecmds.c:10467 +#: commands/tablecmds.c:10457 #, c-format msgid "" "Key columns \"%s\" of the referencing table and \"%s\" of the referenced " @@ -13060,7 +13093,7 @@ msgstr "" "сортировки является недетерминированным, оба правила сортировки должны " "совпадать." -#: commands/tablecmds.c:10673 +#: commands/tablecmds.c:10663 #, c-format msgid "" "column \"%s\" referenced in ON DELETE SET action must be part of foreign key" @@ -13068,13 +13101,13 @@ msgstr "" "столбец \"%s\", фигурирующий в действии ON DELETE SET, должен входить во " "внешний ключ" -#: commands/tablecmds.c:11057 commands/tablecmds.c:11490 +#: commands/tablecmds.c:11047 commands/tablecmds.c:11480 #: parser/parse_utilcmd.c:941 parser/parse_utilcmd.c:1086 #, c-format msgid "foreign key constraints are not supported on foreign tables" msgstr "ограничения внешнего ключа для сторонних таблиц не поддерживаются" -#: commands/tablecmds.c:11473 +#: commands/tablecmds.c:11463 #, c-format msgid "" "cannot attach table \"%s\" as a partition because it is referenced by " @@ -13083,7 +13116,7 @@ msgstr "" "присоединить таблицу \"%s\" в качестве секции нельзя, так как на неё " "ссылается внешний ключ \"%s\"" -#: commands/tablecmds.c:11754 +#: commands/tablecmds.c:11744 #, c-format msgid "" "constraint \"%s\" enforceability conflicts with constraint \"%s\" on " @@ -13092,114 +13125,122 @@ msgstr "" "ограничение \"%s\" имеет свойство контролируемости, отличное от ограничения " "\"%s\" в отношении \"%s\"" -#: commands/tablecmds.c:12216 +#: commands/tablecmds.c:12206 #, c-format msgid "constraint must be altered in child tables too" msgstr "ограничение должно быть изменено также и в дочерних таблицах" -#: commands/tablecmds.c:12245 commands/tablecmds.c:12944 -#: commands/tablecmds.c:14059 commands/tablecmds.c:14288 +#: commands/tablecmds.c:12235 commands/tablecmds.c:12940 +#: commands/tablecmds.c:14058 commands/tablecmds.c:14287 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "ограничение \"%s\" в таблице \"%s\" не существует" -#: commands/tablecmds.c:12252 +#: commands/tablecmds.c:12242 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "ограничение \"%s\" в таблице \"%s\" не является внешним ключом" -#: commands/tablecmds.c:12257 +#: commands/tablecmds.c:12247 #, c-format msgid "cannot alter enforceability of constraint \"%s\" of relation \"%s\"" msgstr "" "изменить свойство контролируемости ограничения \"%s\" отношения \"%s\" нельзя" -#: commands/tablecmds.c:12263 +#: commands/tablecmds.c:12253 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a not-null constraint" msgstr "ограничение \"%s\" в таблице \"%s\" не является ограничением NOT NULL" -#: commands/tablecmds.c:12271 +#: commands/tablecmds.c:12259 +#, c-format +msgid "" +"not-null constraint \"%s\" on partitioned table \"%s\" cannot be NO INHERIT" +msgstr "" +"ограничение NOT NULL \"%s\" для секционированной таблицы \"%s\" не может " +"иметь свойства NO INHERIT" + +#: commands/tablecmds.c:12267 #, c-format msgid "cannot alter inherited constraint \"%s\" on relation \"%s\"" msgstr "изменить наследуемое ограничение \"%s\" в отношении \"%s\" нельзя" -#: commands/tablecmds.c:12311 +#: commands/tablecmds.c:12307 #, c-format msgid "cannot alter constraint \"%s\" on relation \"%s\"" msgstr "изменить ограничение \"%s\" таблицы \"%s\" нельзя" -#: commands/tablecmds.c:12314 +#: commands/tablecmds.c:12310 #, c-format msgid "Constraint \"%s\" is derived from constraint \"%s\" of relation \"%s\"." msgstr "" "Ограничение \"%s\" является производным от ограничения \"%s\" таблицы \"%s\"." -#: commands/tablecmds.c:12316 +#: commands/tablecmds.c:12312 #, c-format msgid "You may alter the constraint it derives from instead." msgstr "Вместо этого вы можете изменить родительское ограничение." -#: commands/tablecmds.c:12953 +#: commands/tablecmds.c:12949 #, c-format msgid "cannot validate constraint \"%s\" of relation \"%s\"" msgstr "проверить ограничение \"%s\" отношения \"%s\" нельзя" -#: commands/tablecmds.c:12955 +#: commands/tablecmds.c:12951 #, c-format msgid "This operation is not supported for this type of constraint." msgstr "Эта операция не поддерживается для ограничений данного типа." -#: commands/tablecmds.c:12960 +#: commands/tablecmds.c:12956 #, c-format msgid "cannot validate NOT ENFORCED constraint" msgstr "проверить отношение NOT ENFORCED нельзя" -#: commands/tablecmds.c:13169 commands/tablecmds.c:13269 +#: commands/tablecmds.c:13168 commands/tablecmds.c:13268 #, c-format msgid "constraint must be validated on child tables too" msgstr "ограничение также должно соблюдаться в дочерних таблицах" -#: commands/tablecmds.c:13346 +#: commands/tablecmds.c:13345 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" msgstr "столбец \"%s\", указанный в ограничении внешнего ключа, не существует" -#: commands/tablecmds.c:13352 +#: commands/tablecmds.c:13351 #, c-format msgid "system columns cannot be used in foreign keys" msgstr "системные столбцы нельзя использовать во внешних ключах" -#: commands/tablecmds.c:13356 +#: commands/tablecmds.c:13355 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "во внешнем ключе не может быть больше %d столбцов" -#: commands/tablecmds.c:13424 +#: commands/tablecmds.c:13423 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "" "использовать откладываемый первичный ключ в целевой внешней таблице \"%s\" " "нельзя" -#: commands/tablecmds.c:13441 +#: commands/tablecmds.c:13440 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "в целевой внешней таблице \"%s\" нет первичного ключа" -#: commands/tablecmds.c:13514 +#: commands/tablecmds.c:13513 #, c-format msgid "foreign key referenced-columns list must not contain duplicates" msgstr "в списке столбцов внешнего ключа не должно быть повторений" -#: commands/tablecmds.c:13617 +#: commands/tablecmds.c:13616 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "" "использовать откладываемое ограничение уникальности в целевой внешней " "таблице \"%s\" нельзя" -#: commands/tablecmds.c:13622 +#: commands/tablecmds.c:13621 #, c-format msgid "" "there is no unique constraint matching given keys for referenced table \"%s\"" @@ -13207,42 +13248,42 @@ msgstr "" "в целевой внешней таблице \"%s\" нет ограничения уникальности, " "соответствующего данным ключам" -#: commands/tablecmds.c:14063 +#: commands/tablecmds.c:14062 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" msgstr "ограничение \"%s\" в таблице \"%s\" не существует, пропускается" -#: commands/tablecmds.c:14108 +#: commands/tablecmds.c:14107 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "удалить наследованное ограничение \"%s\" таблицы \"%s\" нельзя" -#: commands/tablecmds.c:14160 +#: commands/tablecmds.c:14159 #, c-format msgid "column \"%s\" is in a primary key" msgstr "столбец \"%s\" входит в первичный ключ" -#: commands/tablecmds.c:14168 +#: commands/tablecmds.c:14167 #, c-format msgid "column \"%s\" is in index used as replica identity" msgstr "столбец \"%s\" входит в индекс, используемый для идентификации реплики" -#: commands/tablecmds.c:14401 +#: commands/tablecmds.c:14400 #, c-format msgid "cannot alter column type of typed table" msgstr "изменить тип столбца в типизированной таблице нельзя" -#: commands/tablecmds.c:14429 +#: commands/tablecmds.c:14428 #, c-format msgid "cannot specify USING when altering type of generated column" msgstr "изменяя тип генерируемого столбца, нельзя указывать USING" -#: commands/tablecmds.c:14441 +#: commands/tablecmds.c:14440 #, c-format msgid "cannot alter inherited column \"%s\"" msgstr "изменить наследованный столбец \"%s\" нельзя" -#: commands/tablecmds.c:14450 +#: commands/tablecmds.c:14449 #, c-format msgid "" "cannot alter column \"%s\" because it is part of the partition key of " @@ -13251,7 +13292,7 @@ msgstr "" "изменить столбец \"%s\" нельзя, так как он входит в ключ разбиения отношения " "\"%s\"" -#: commands/tablecmds.c:14505 +#: commands/tablecmds.c:14504 #, c-format msgid "" "result of USING clause for column \"%s\" cannot be cast automatically to " @@ -13259,45 +13300,45 @@ msgid "" msgstr "" "результат USING для столбца \"%s\" нельзя автоматически привести к типу %s" -#: commands/tablecmds.c:14508 +#: commands/tablecmds.c:14507 #, c-format msgid "You might need to add an explicit cast." msgstr "Возможно, необходимо добавить явное приведение." -#: commands/tablecmds.c:14512 +#: commands/tablecmds.c:14511 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" msgstr "столбец \"%s\" нельзя автоматически привести к типу %s" # skip-rule: double-colons #. translator: USING is SQL, don't translate it -#: commands/tablecmds.c:14516 +#: commands/tablecmds.c:14515 #, c-format msgid "You might need to specify \"USING %s::%s\"." msgstr "Возможно, необходимо указать \"USING %s::%s\"." -#: commands/tablecmds.c:14619 +#: commands/tablecmds.c:14618 #, c-format msgid "cannot alter inherited column \"%s\" of relation \"%s\"" msgstr "изменить наследованный столбец \"%s\" отношения \"%s\" нельзя" -#: commands/tablecmds.c:14648 +#: commands/tablecmds.c:14647 #, c-format msgid "USING expression contains a whole-row table reference." msgstr "Выражение USING ссылается на тип всей строки таблицы." -#: commands/tablecmds.c:14659 +#: commands/tablecmds.c:14658 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" msgstr "" "тип наследованного столбца \"%s\" должен быть изменён и в дочерних таблицах" -#: commands/tablecmds.c:14784 +#: commands/tablecmds.c:14783 #, c-format msgid "cannot alter type of column \"%s\" twice" msgstr "нельзя изменить тип столбца \"%s\" дважды" -#: commands/tablecmds.c:14822 +#: commands/tablecmds.c:14821 #, c-format msgid "" "generation expression for column \"%s\" cannot be cast automatically to type " @@ -13306,160 +13347,160 @@ msgstr "" "генерирующее выражение для столбца \"%s\" нельзя автоматически привести к " "типу %s" -#: commands/tablecmds.c:14827 +#: commands/tablecmds.c:14826 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "" "значение по умолчанию для столбца \"%s\" нельзя автоматически привести к " "типу %s" -#: commands/tablecmds.c:15131 +#: commands/tablecmds.c:15130 #, c-format msgid "cannot alter type of a column used by a function or procedure" msgstr "изменить тип столбца, задействованного в функции или процедуре, нельзя" -#: commands/tablecmds.c:15132 commands/tablecmds.c:15147 -#: commands/tablecmds.c:15167 commands/tablecmds.c:15186 -#: commands/tablecmds.c:15245 +#: commands/tablecmds.c:15131 commands/tablecmds.c:15146 +#: commands/tablecmds.c:15166 commands/tablecmds.c:15185 +#: commands/tablecmds.c:15244 #, c-format msgid "%s depends on column \"%s\"" msgstr "%s зависит от столбца \"%s\"" -#: commands/tablecmds.c:15146 +#: commands/tablecmds.c:15145 #, c-format msgid "cannot alter type of a column used by a view or rule" msgstr "" "изменить тип столбца, задействованного в представлении или правиле, нельзя" -#: commands/tablecmds.c:15166 +#: commands/tablecmds.c:15165 #, c-format msgid "cannot alter type of a column used in a trigger definition" msgstr "изменить тип столбца, задействованного в определении триггера, нельзя" -#: commands/tablecmds.c:15185 +#: commands/tablecmds.c:15184 #, c-format msgid "cannot alter type of a column used in a policy definition" msgstr "изменить тип столбца, задействованного в определении политики, нельзя" -#: commands/tablecmds.c:15216 +#: commands/tablecmds.c:15215 #, c-format msgid "cannot alter type of a column used by a generated column" msgstr "изменить тип столбца, задействованного в генерируемом столбце, нельзя" -#: commands/tablecmds.c:15217 +#: commands/tablecmds.c:15216 #, c-format msgid "Column \"%s\" is used by generated column \"%s\"." msgstr "Столбец \"%s\" используется генерируемым столбцом \"%s\"." -#: commands/tablecmds.c:15244 +#: commands/tablecmds.c:15243 #, c-format msgid "cannot alter type of a column used by a publication WHERE clause" msgstr "" "изменить тип столбца, задействованного в заданном для публикации предложении " "WHERE, нельзя" -#: commands/tablecmds.c:16118 commands/tablecmds.c:16130 +#: commands/tablecmds.c:16117 commands/tablecmds.c:16129 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "сменить владельца индекса \"%s\" нельзя" -#: commands/tablecmds.c:16120 commands/tablecmds.c:16132 +#: commands/tablecmds.c:16119 commands/tablecmds.c:16131 #, c-format msgid "Change the ownership of the index's table instead." msgstr "Однако возможно сменить владельца таблицы, содержащей этот индекс." -#: commands/tablecmds.c:16146 +#: commands/tablecmds.c:16145 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "сменить владельца последовательности \"%s\" нельзя" -#: commands/tablecmds.c:16171 +#: commands/tablecmds.c:16170 #, c-format msgid "cannot change owner of relation \"%s\"" msgstr "сменить владельца отношения \"%s\" нельзя" -#: commands/tablecmds.c:16638 +#: commands/tablecmds.c:16637 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "в одной инструкции не может быть несколько подкоманд SET TABLESPACE" -#: commands/tablecmds.c:16717 +#: commands/tablecmds.c:16716 #, c-format msgid "cannot set options for relation \"%s\"" msgstr "задать параметры отношения \"%s\" нельзя" -#: commands/tablecmds.c:16751 commands/view.c:440 +#: commands/tablecmds.c:16750 commands/view.c:440 #, c-format msgid "WITH CHECK OPTION is supported only on automatically updatable views" msgstr "" "WITH CHECK OPTION поддерживается только с автообновляемыми представлениями" -#: commands/tablecmds.c:17004 +#: commands/tablecmds.c:17003 #, c-format msgid "only tables, indexes, and materialized views exist in tablespaces" msgstr "" "в табличных пространствах есть только таблицы, индексы и материализованные " "представления" -#: commands/tablecmds.c:17016 +#: commands/tablecmds.c:17015 #, c-format msgid "cannot move relations in to or out of pg_global tablespace" msgstr "перемещать объекты в/из табличного пространства pg_global нельзя" -#: commands/tablecmds.c:17108 +#: commands/tablecmds.c:17107 #, c-format msgid "aborting because lock on relation \"%s.%s\" is not available" msgstr "" "обработка прерывается из-за невозможности заблокировать отношение \"%s.%s\"" -#: commands/tablecmds.c:17124 +#: commands/tablecmds.c:17123 #, c-format msgid "no matching relations in tablespace \"%s\" found" msgstr "в табличном пространстве \"%s\" не найдены подходящие отношения" -#: commands/tablecmds.c:17246 +#: commands/tablecmds.c:17245 #, c-format msgid "cannot change inheritance of typed table" msgstr "изменить наследование типизированной таблицы нельзя" -#: commands/tablecmds.c:17251 commands/tablecmds.c:17835 +#: commands/tablecmds.c:17250 commands/tablecmds.c:17834 #, c-format msgid "cannot change inheritance of a partition" msgstr "изменить наследование секции нельзя" -#: commands/tablecmds.c:17256 +#: commands/tablecmds.c:17255 #, c-format msgid "cannot change inheritance of partitioned table" msgstr "изменить наследование секционированной таблицы нельзя" -#: commands/tablecmds.c:17303 +#: commands/tablecmds.c:17302 #, c-format msgid "cannot inherit to temporary relation of another session" msgstr "наследование для временного отношения другого сеанса невозможно" -#: commands/tablecmds.c:17316 +#: commands/tablecmds.c:17315 #, c-format msgid "cannot inherit from a partition" msgstr "наследование от секции невозможно" -#: commands/tablecmds.c:17338 commands/tablecmds.c:20359 +#: commands/tablecmds.c:17337 commands/tablecmds.c:20358 #, c-format msgid "circular inheritance not allowed" msgstr "циклическое наследование недопустимо" -#: commands/tablecmds.c:17339 commands/tablecmds.c:20360 +#: commands/tablecmds.c:17338 commands/tablecmds.c:20359 #, c-format msgid "\"%s\" is already a child of \"%s\"." msgstr "\"%s\" уже является потомком \"%s\"." -#: commands/tablecmds.c:17352 +#: commands/tablecmds.c:17351 #, c-format msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" msgstr "" "триггер \"%s\" не позволяет таблице \"%s\" стать потомком в иерархии " "наследования" -#: commands/tablecmds.c:17354 +#: commands/tablecmds.c:17353 #, c-format msgid "" "ROW triggers with transition tables are not supported in inheritance " @@ -13468,35 +13509,35 @@ msgstr "" "Триггеры ROW с переходными таблицами не поддерживаются в иерархиях " "наследования." -#: commands/tablecmds.c:17555 commands/tablecmds.c:17804 +#: commands/tablecmds.c:17554 commands/tablecmds.c:17803 #, c-format msgid "column \"%s\" in child table \"%s\" must be marked NOT NULL" msgstr "" "столбец \"%s\" в дочерней таблице \"%s\" должен быть помечен как NOT NULL" -#: commands/tablecmds.c:17565 +#: commands/tablecmds.c:17564 #, c-format msgid "column \"%s\" in child table must be a generated column" msgstr "столбец \"%s\" в дочерней таблице должен быть генерируемым" -#: commands/tablecmds.c:17569 +#: commands/tablecmds.c:17568 #, c-format msgid "column \"%s\" in child table must not be a generated column" msgstr "столбец \"%s\" в дочерней таблице должен быть не генерируемым" -#: commands/tablecmds.c:17615 +#: commands/tablecmds.c:17614 #, c-format msgid "child table is missing column \"%s\"" msgstr "в дочерней таблице не хватает столбца \"%s\"" -#: commands/tablecmds.c:17732 +#: commands/tablecmds.c:17731 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" msgstr "" "дочерняя таблица \"%s\" содержит другое определение ограничения-проверки " "\"%s\"" -#: commands/tablecmds.c:17741 +#: commands/tablecmds.c:17740 #, c-format msgid "" "constraint \"%s\" conflicts with non-inherited constraint on child table " @@ -13505,7 +13546,7 @@ msgstr "" "ограничение \"%s\" конфликтует с ненаследуемым ограничением дочерней таблицы " "\"%s\"" -#: commands/tablecmds.c:17752 +#: commands/tablecmds.c:17751 #, c-format msgid "" "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" @@ -13513,7 +13554,7 @@ msgstr "" "ограничение \"%s\" конфликтует с непроверенным (NOT VALID) ограничением " "дочерней таблицы \"%s\"" -#: commands/tablecmds.c:17763 +#: commands/tablecmds.c:17762 #, c-format msgid "" "constraint \"%s\" conflicts with NOT ENFORCED constraint on child table " @@ -13522,82 +13563,82 @@ msgstr "" "ограничение \"%s\" конфликтует с неконтролируемым (NOT ENFORCED) " "ограничением дочерней таблицы \"%s\"" -#: commands/tablecmds.c:17812 +#: commands/tablecmds.c:17811 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "в дочерней таблице не хватает ограничения \"%s\"" -#: commands/tablecmds.c:17899 +#: commands/tablecmds.c:17898 #, c-format msgid "partition \"%s\" already pending detach in partitioned table \"%s.%s\"" msgstr "" "секция \"%s\" уже ожидает отсоединения от секционированной таблицы \"%s.%s\"" -#: commands/tablecmds.c:17928 commands/tablecmds.c:17976 +#: commands/tablecmds.c:17927 commands/tablecmds.c:17975 #, c-format msgid "relation \"%s\" is not a partition of relation \"%s\"" msgstr "отношение \"%s\" не является секцией отношения \"%s\"" -#: commands/tablecmds.c:17982 +#: commands/tablecmds.c:17981 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "отношение \"%s\" не является предком отношения \"%s\"" -#: commands/tablecmds.c:18253 +#: commands/tablecmds.c:18252 #, c-format msgid "typed tables cannot inherit" msgstr "типизированные таблицы не могут наследоваться" -#: commands/tablecmds.c:18283 +#: commands/tablecmds.c:18282 #, c-format msgid "table is missing column \"%s\"" msgstr "в таблице не хватает столбца \"%s\"" -#: commands/tablecmds.c:18294 +#: commands/tablecmds.c:18293 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" msgstr "таблица содержит столбец \"%s\", тогда как тип требует \"%s\"" -#: commands/tablecmds.c:18303 +#: commands/tablecmds.c:18302 #, c-format msgid "table \"%s\" has different type for column \"%s\"" msgstr "таблица \"%s\" содержит столбец \"%s\" другого типа" -#: commands/tablecmds.c:18317 +#: commands/tablecmds.c:18316 #, c-format msgid "table has extra column \"%s\"" msgstr "таблица содержит лишний столбец \"%s\"" -#: commands/tablecmds.c:18369 +#: commands/tablecmds.c:18368 #, c-format msgid "\"%s\" is not a typed table" msgstr "\"%s\" - это не типизированная таблица" -#: commands/tablecmds.c:18549 +#: commands/tablecmds.c:18548 #, c-format msgid "cannot use non-unique index \"%s\" as replica identity" msgstr "" "для идентификации реплики нельзя использовать неуникальный индекс \"%s\"" -#: commands/tablecmds.c:18555 +#: commands/tablecmds.c:18554 #, c-format msgid "cannot use non-immediate index \"%s\" as replica identity" msgstr "" "для идентификации реплики нельзя использовать не непосредственный индекс " "\"%s\"" -#: commands/tablecmds.c:18561 +#: commands/tablecmds.c:18560 #, c-format msgid "cannot use expression index \"%s\" as replica identity" msgstr "" "для идентификации реплики нельзя использовать индекс с выражением \"%s\"" -#: commands/tablecmds.c:18567 +#: commands/tablecmds.c:18566 #, c-format msgid "cannot use partial index \"%s\" as replica identity" msgstr "для идентификации реплики нельзя использовать частичный индекс \"%s\"" -#: commands/tablecmds.c:18584 +#: commands/tablecmds.c:18583 #, c-format msgid "" "index \"%s\" cannot be used as replica identity because column %d is a " @@ -13606,7 +13647,7 @@ msgstr "" "индекс \"%s\" нельзя использовать для идентификации реплики, так как столбец " "%d - системный" -#: commands/tablecmds.c:18591 +#: commands/tablecmds.c:18590 #, c-format msgid "" "index \"%s\" cannot be used as replica identity because column \"%s\" is " @@ -13615,13 +13656,13 @@ msgstr "" "индекс \"%s\" нельзя использовать для идентификации реплики, так как столбец " "\"%s\" допускает NULL" -#: commands/tablecmds.c:18840 +#: commands/tablecmds.c:18839 #, c-format msgid "cannot change logged status of table \"%s\" because it is temporary" msgstr "" "изменить состояние журналирования таблицы %s нельзя, так как она временная" -#: commands/tablecmds.c:18864 +#: commands/tablecmds.c:18863 #, c-format msgid "" "cannot change table \"%s\" to unlogged because it is part of a publication" @@ -13629,12 +13670,12 @@ msgstr "" "таблицу \"%s\" нельзя сделать нежурналируемой, так как она включена в " "публикацию" -#: commands/tablecmds.c:18866 +#: commands/tablecmds.c:18865 #, c-format msgid "Unlogged relations cannot be replicated." msgstr "Нежурналируемые отношения не поддерживают репликацию." -#: commands/tablecmds.c:18911 +#: commands/tablecmds.c:18910 #, c-format msgid "" "could not change table \"%s\" to logged because it references unlogged table " @@ -13643,7 +13684,7 @@ msgstr "" "не удалось сделать таблицу \"%s\" журналируемой, так как она ссылается на " "нежурналируемую таблицу \"%s\"" -#: commands/tablecmds.c:18921 +#: commands/tablecmds.c:18920 #, c-format msgid "" "could not change table \"%s\" to unlogged because it references logged table " @@ -13652,91 +13693,91 @@ msgstr "" "не удалось сделать таблицу \"%s\" нежурналируемой, так как она ссылается на " "журналируемую таблицу \"%s\"" -#: commands/tablecmds.c:18985 +#: commands/tablecmds.c:18984 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "переместить последовательность с владельцем в другую схему нельзя" -#: commands/tablecmds.c:19093 +#: commands/tablecmds.c:19092 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "отношение \"%s\" уже существует в схеме \"%s\"" -#: commands/tablecmds.c:19518 +#: commands/tablecmds.c:19517 #, c-format msgid "\"%s\" is not a table or materialized view" msgstr "\"%s\" - это не таблица и не материализованное представление" -#: commands/tablecmds.c:19671 +#: commands/tablecmds.c:19670 #, c-format msgid "\"%s\" is not a composite type" msgstr "\"%s\" - это не составной тип" -#: commands/tablecmds.c:19701 +#: commands/tablecmds.c:19700 #, c-format msgid "cannot change schema of index \"%s\"" msgstr "сменить схему индекса \"%s\" нельзя" -#: commands/tablecmds.c:19703 commands/tablecmds.c:19717 +#: commands/tablecmds.c:19702 commands/tablecmds.c:19716 #, c-format msgid "Change the schema of the table instead." msgstr "Однако возможно сменить владельца таблицы." -#: commands/tablecmds.c:19707 +#: commands/tablecmds.c:19706 #, c-format msgid "cannot change schema of composite type \"%s\"" msgstr "сменить схему составного типа \"%s\" нельзя" -#: commands/tablecmds.c:19715 +#: commands/tablecmds.c:19714 #, c-format msgid "cannot change schema of TOAST table \"%s\"" msgstr "сменить схему TOAST-таблицы \"%s\" нельзя" -#: commands/tablecmds.c:19747 +#: commands/tablecmds.c:19746 #, c-format msgid "cannot use \"list\" partition strategy with more than one column" msgstr "стратегия секционирования по списку не поддерживает несколько столбцов" -#: commands/tablecmds.c:19813 +#: commands/tablecmds.c:19812 #, c-format msgid "column \"%s\" named in partition key does not exist" msgstr "столбец \"%s\", упомянутый в ключе секционирования, не существует" -#: commands/tablecmds.c:19821 +#: commands/tablecmds.c:19820 #, c-format msgid "cannot use system column \"%s\" in partition key" msgstr "системный столбец \"%s\" нельзя использовать в ключе секционирования" -#: commands/tablecmds.c:19835 commands/tablecmds.c:19917 +#: commands/tablecmds.c:19834 commands/tablecmds.c:19916 #, c-format msgid "cannot use generated column in partition key" msgstr "генерируемый столбец нельзя использовать в ключе секционирования" -#: commands/tablecmds.c:19904 +#: commands/tablecmds.c:19903 #, c-format msgid "partition key expressions cannot contain system column references" msgstr "" "выражения ключей секционирования не могут содержать ссылки на системный " "столбец" -#: commands/tablecmds.c:19968 +#: commands/tablecmds.c:19967 #, c-format msgid "functions in partition key expression must be marked IMMUTABLE" msgstr "" "функции в выражении ключа секционирования должны быть помечены как IMMUTABLE" -#: commands/tablecmds.c:19977 +#: commands/tablecmds.c:19976 #, c-format msgid "cannot use constant expression as partition key" msgstr "" "в качестве ключа секционирования нельзя использовать константное выражение" -#: commands/tablecmds.c:19998 +#: commands/tablecmds.c:19997 #, c-format msgid "could not determine which collation to use for partition expression" msgstr "не удалось определить правило сортировки для выражения секционирования" -#: commands/tablecmds.c:20033 +#: commands/tablecmds.c:20032 #, c-format msgid "" "You must specify a hash operator class or define a default hash operator " @@ -13745,7 +13786,7 @@ msgstr "" "Вы должны указать класс операторов хеширования или определить класс " "операторов хеширования по умолчанию для этого типа данных." -#: commands/tablecmds.c:20039 +#: commands/tablecmds.c:20038 #, c-format msgid "" "You must specify a btree operator class or define a default btree operator " @@ -13754,27 +13795,27 @@ msgstr "" "Вы должны указать класс операторов B-дерева или определить класс операторов " "B-дерева по умолчанию для этого типа данных." -#: commands/tablecmds.c:20299 +#: commands/tablecmds.c:20298 #, c-format msgid "\"%s\" is already a partition" msgstr "\"%s\" уже является секцией" -#: commands/tablecmds.c:20305 +#: commands/tablecmds.c:20304 #, c-format msgid "cannot attach a typed table as partition" msgstr "подключить типизированную таблицу в качестве секции нельзя" -#: commands/tablecmds.c:20321 +#: commands/tablecmds.c:20320 #, c-format msgid "cannot attach inheritance child as partition" msgstr "подключить потомок в иерархии наследования в качестве секции нельзя" -#: commands/tablecmds.c:20335 +#: commands/tablecmds.c:20334 #, c-format msgid "cannot attach inheritance parent as partition" msgstr "подключить родитель в иерархии наследования в качестве секции нельзя" -#: commands/tablecmds.c:20369 +#: commands/tablecmds.c:20368 #, c-format msgid "" "cannot attach a temporary relation as partition of permanent relation \"%s\"" @@ -13782,7 +13823,7 @@ msgstr "" "подключить временное отношение в качестве секции постоянного отношения " "\"%s\" нельзя" -#: commands/tablecmds.c:20377 +#: commands/tablecmds.c:20376 #, c-format msgid "" "cannot attach a permanent relation as partition of temporary relation \"%s\"" @@ -13790,102 +13831,102 @@ msgstr "" "подключить постоянное отношение в качестве секции временного отношения " "\"%s\" нельзя" -#: commands/tablecmds.c:20385 +#: commands/tablecmds.c:20384 #, c-format msgid "cannot attach as partition of temporary relation of another session" msgstr "подключить секцию к временному отношению в другом сеансе нельзя" -#: commands/tablecmds.c:20392 +#: commands/tablecmds.c:20391 #, c-format msgid "cannot attach temporary relation of another session as partition" msgstr "" "подключить временное отношение из другого сеанса в качестве секции нельзя" -#: commands/tablecmds.c:20412 +#: commands/tablecmds.c:20411 #, c-format msgid "table \"%s\" being attached contains an identity column \"%s\"" msgstr "присоединяемая таблица \"%s\" содержит столбец идентификации \"%s\"" -#: commands/tablecmds.c:20414 +#: commands/tablecmds.c:20413 #, c-format msgid "The new partition may not contain an identity column." msgstr "Новая секция не может содержать столбец идентификации." -#: commands/tablecmds.c:20422 +#: commands/tablecmds.c:20421 #, c-format msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" msgstr "" "таблица \"%s\" содержит столбец \"%s\", отсутствующий в родителе \"%s\"" -#: commands/tablecmds.c:20425 +#: commands/tablecmds.c:20424 #, c-format msgid "The new partition may contain only the columns present in parent." msgstr "" "Новая секция может содержать только столбцы, имеющиеся в родительской " "таблице." -#: commands/tablecmds.c:20437 +#: commands/tablecmds.c:20436 #, c-format msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" msgstr "триггер \"%s\" не позволяет сделать таблицу \"%s\" секцией" -#: commands/tablecmds.c:20439 +#: commands/tablecmds.c:20438 #, c-format msgid "ROW triggers with transition tables are not supported on partitions." msgstr "Триггеры ROW с переходными таблицами для секций не поддерживаются." -#: commands/tablecmds.c:20621 +#: commands/tablecmds.c:20620 #, c-format msgid "" "cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"" msgstr "" "нельзя присоединить стороннюю таблицу \"%s\" в качестве секции таблицы \"%s\"" -#: commands/tablecmds.c:20624 +#: commands/tablecmds.c:20623 #, c-format msgid "Partitioned table \"%s\" contains unique indexes." msgstr "Секционированная таблица \"%s\" содержит уникальные индексы." -#: commands/tablecmds.c:20948 +#: commands/tablecmds.c:20947 #, c-format msgid "cannot detach partitions concurrently when a default partition exists" msgstr "" "секции нельзя отсоединять в режиме CONCURRENTLY, когда существует секция по " "умолчанию" -#: commands/tablecmds.c:21060 +#: commands/tablecmds.c:21059 #, c-format msgid "partitioned table \"%s\" was removed concurrently" msgstr "секционированная таблица \"%s\" была параллельно удалена" -#: commands/tablecmds.c:21066 +#: commands/tablecmds.c:21065 #, c-format msgid "partition \"%s\" was removed concurrently" msgstr "секция \"%s\" была параллельно удалена" -#: commands/tablecmds.c:21700 commands/tablecmds.c:21720 -#: commands/tablecmds.c:21741 commands/tablecmds.c:21760 -#: commands/tablecmds.c:21817 +#: commands/tablecmds.c:21699 commands/tablecmds.c:21719 +#: commands/tablecmds.c:21740 commands/tablecmds.c:21759 +#: commands/tablecmds.c:21816 #, c-format msgid "cannot attach index \"%s\" as a partition of index \"%s\"" msgstr "нельзя присоединить индекс \"%s\" в качестве секции индекса \"%s\"" -#: commands/tablecmds.c:21703 +#: commands/tablecmds.c:21702 #, c-format msgid "Index \"%s\" is already attached to another index." msgstr "Индекс \"%s\" уже присоединён к другому индексу." -#: commands/tablecmds.c:21723 +#: commands/tablecmds.c:21722 #, c-format msgid "Index \"%s\" is not an index on any partition of table \"%s\"." msgstr "Индекс \"%s\" не является индексом какой-либо секции таблицы \"%s\"." -#: commands/tablecmds.c:21744 +#: commands/tablecmds.c:21743 #, c-format msgid "The index definitions do not match." msgstr "Определения индексов не совпадают." -#: commands/tablecmds.c:21763 +#: commands/tablecmds.c:21762 #, c-format msgid "" "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint " @@ -13894,37 +13935,37 @@ msgstr "" "Индекс \"%s\" принадлежит ограничению в таблице \"%s\", но для индекса " "\"%s\" ограничения нет." -#: commands/tablecmds.c:21820 +#: commands/tablecmds.c:21819 #, c-format msgid "Another index is already attached for partition \"%s\"." msgstr "К секции \"%s\" уже присоединён другой индекс." -#: commands/tablecmds.c:21943 +#: commands/tablecmds.c:21942 #, c-format msgid "invalid primary key definition" msgstr "неверная определение первичного ключа" -#: commands/tablecmds.c:21944 +#: commands/tablecmds.c:21943 #, c-format msgid "Column \"%s\" of relation \"%s\" is not marked NOT NULL." msgstr "Столбец \"%s\" отношения \"%s\" не имеет свойства NOT NULL." -#: commands/tablecmds.c:22079 +#: commands/tablecmds.c:22078 #, c-format msgid "column data type %s does not support compression" msgstr "тим данных столбца %s не поддерживает сжатие" -#: commands/tablecmds.c:22086 +#: commands/tablecmds.c:22085 #, c-format msgid "invalid compression method \"%s\"" msgstr "неверный метод сжатия \"%s\"" -#: commands/tablecmds.c:22112 +#: commands/tablecmds.c:22111 #, c-format msgid "invalid storage type \"%s\"" msgstr "неверный тип хранилища \"%s\"" -#: commands/tablecmds.c:22122 +#: commands/tablecmds.c:22121 #, c-format msgid "column data type %s can only have storage PLAIN" msgstr "тип данных столбца %s совместим только с хранилищем PLAIN" @@ -14326,9 +14367,9 @@ msgid "cannot collect transition tuples from child foreign tables" msgstr "собрать переходные кортежи из дочерних сторонних таблиц нельзя" #: commands/trigger.c:3402 executor/nodeModifyTable.c:1687 -#: executor/nodeModifyTable.c:1761 executor/nodeModifyTable.c:2569 -#: executor/nodeModifyTable.c:2659 executor/nodeModifyTable.c:3322 -#: executor/nodeModifyTable.c:3519 +#: executor/nodeModifyTable.c:1761 executor/nodeModifyTable.c:2588 +#: executor/nodeModifyTable.c:2678 executor/nodeModifyTable.c:3341 +#: executor/nodeModifyTable.c:3538 #, c-format msgid "" "Consider using an AFTER trigger instead of a BEFORE trigger to propagate " @@ -14339,15 +14380,15 @@ msgstr "" #: commands/trigger.c:3444 executor/nodeLockRows.c:228 #: executor/nodeLockRows.c:237 executor/nodeModifyTable.c:389 -#: executor/nodeModifyTable.c:1703 executor/nodeModifyTable.c:2585 -#: executor/nodeModifyTable.c:2810 executor/nodeModifyTable.c:3360 +#: executor/nodeModifyTable.c:1703 executor/nodeModifyTable.c:2604 +#: executor/nodeModifyTable.c:2829 executor/nodeModifyTable.c:3379 #, c-format msgid "could not serialize access due to concurrent update" msgstr "не удалось сериализовать доступ из-за параллельного изменения" #: commands/trigger.c:3452 executor/nodeModifyTable.c:1793 -#: executor/nodeModifyTable.c:2676 executor/nodeModifyTable.c:2826 -#: executor/nodeModifyTable.c:3340 +#: executor/nodeModifyTable.c:2695 executor/nodeModifyTable.c:2845 +#: executor/nodeModifyTable.c:3359 #, c-format msgid "could not serialize access due to concurrent delete" msgstr "не удалось сериализовать доступ из-за параллельного удаления" @@ -14479,7 +14520,7 @@ msgstr "" "Создайте тип в виде оболочки, затем определите для него функции ввода-вывода " "и в завершение выполните полноценную команду CREATE TYPE." -#: commands/typecmds.c:331 commands/typecmds.c:1494 commands/typecmds.c:4479 +#: commands/typecmds.c:331 commands/typecmds.c:1501 commands/typecmds.c:4486 #, c-format msgid "type attribute \"%s\" not recognized" msgstr "атрибут типа \"%s\" не распознан" @@ -14499,7 +14540,7 @@ msgstr "типом элемента массива не может быть %s" msgid "alignment \"%s\" not recognized" msgstr "тип выравнивания \"%s\" не распознан" -#: commands/typecmds.c:454 commands/typecmds.c:4353 +#: commands/typecmds.c:454 commands/typecmds.c:4360 #, c-format msgid "storage \"%s\" not recognized" msgstr "неизвестная стратегия хранения \"%s\"" @@ -14598,36 +14639,36 @@ msgstr "" "возможность определения контролируемости ограничения для доменов не " "поддерживается" -#: commands/typecmds.c:1361 utils/cache/typcache.c:2757 +#: commands/typecmds.c:1361 utils/cache/typcache.c:2750 #, c-format msgid "%s is not an enum" msgstr "\"%s\" не является перечислением" -#: commands/typecmds.c:1502 +#: commands/typecmds.c:1509 #, c-format msgid "type attribute \"subtype\" is required" msgstr "требуется атрибут типа \"subtype\"" -#: commands/typecmds.c:1507 +#: commands/typecmds.c:1514 #, c-format msgid "range subtype cannot be %s" msgstr "%s не может быть подтипом диапазона" -#: commands/typecmds.c:1526 +#: commands/typecmds.c:1533 #, c-format msgid "range collation specified but subtype does not support collation" msgstr "" "указано правило сортировки для диапазона, но подтип не поддерживает " "сортировку" -#: commands/typecmds.c:1536 +#: commands/typecmds.c:1543 #, c-format msgid "cannot specify a canonical function without a pre-created shell type" msgstr "" "функцию получения канонического диапазона нельзя задать без предварительно " "созданного типа-пустышки" -#: commands/typecmds.c:1537 +#: commands/typecmds.c:1544 #, c-format msgid "" "Create the type as a shell type, then create its canonicalization function, " @@ -14636,96 +14677,96 @@ msgstr "" "Создайте тип в виде оболочки, затем определите для него функции приведения к " "каноническому виду и в завершение выполните полноценную команду CREATE TYPE." -#: commands/typecmds.c:2013 +#: commands/typecmds.c:2020 #, c-format msgid "type input function %s has multiple matches" msgstr "функция ввода типа %s присутствует в нескольких экземплярах" -#: commands/typecmds.c:2031 +#: commands/typecmds.c:2038 #, c-format msgid "type input function %s must return type %s" msgstr "функция ввода типа %s должна возвращать тип %s" -#: commands/typecmds.c:2047 +#: commands/typecmds.c:2054 #, c-format msgid "type input function %s should not be volatile" msgstr "функция ввода типа %s не должна быть изменчивой" -#: commands/typecmds.c:2075 +#: commands/typecmds.c:2082 #, c-format msgid "type output function %s must return type %s" msgstr "функция вывода типа %s должна возвращать тип %s" -#: commands/typecmds.c:2082 +#: commands/typecmds.c:2089 #, c-format msgid "type output function %s should not be volatile" msgstr "функция вывода типа %s не должна быть изменчивой" -#: commands/typecmds.c:2111 +#: commands/typecmds.c:2118 #, c-format msgid "type receive function %s has multiple matches" msgstr "функция получения типа %s присутствует в нескольких экземплярах" -#: commands/typecmds.c:2129 +#: commands/typecmds.c:2136 #, c-format msgid "type receive function %s must return type %s" msgstr "функция получения типа %s должна возвращать тип %s" -#: commands/typecmds.c:2136 +#: commands/typecmds.c:2143 #, c-format msgid "type receive function %s should not be volatile" msgstr "функция получения типа %s не должна быть изменчивой" -#: commands/typecmds.c:2164 +#: commands/typecmds.c:2171 #, c-format msgid "type send function %s must return type %s" msgstr "функция отправки типа %s должна возвращать тип %s" -#: commands/typecmds.c:2171 +#: commands/typecmds.c:2178 #, c-format msgid "type send function %s should not be volatile" msgstr "функция отправки типа %s не должна быть изменчивой" -#: commands/typecmds.c:2198 +#: commands/typecmds.c:2205 #, c-format msgid "typmod_in function %s must return type %s" msgstr "функция TYPMOD_IN %s должна возвращать тип %s" -#: commands/typecmds.c:2205 +#: commands/typecmds.c:2212 #, c-format msgid "type modifier input function %s should not be volatile" msgstr "функция ввода модификатора типа %s не должна быть изменчивой" -#: commands/typecmds.c:2232 +#: commands/typecmds.c:2239 #, c-format msgid "typmod_out function %s must return type %s" msgstr "функция TYPMOD_OUT %s должна возвращать тип %s" -#: commands/typecmds.c:2239 +#: commands/typecmds.c:2246 #, c-format msgid "type modifier output function %s should not be volatile" msgstr "функция вывода модификатора типа %s не должна быть изменчивой" -#: commands/typecmds.c:2266 +#: commands/typecmds.c:2273 #, c-format msgid "type analyze function %s must return type %s" msgstr "функция анализа типа %s должна возвращать тип %s" -#: commands/typecmds.c:2295 +#: commands/typecmds.c:2302 #, c-format msgid "type subscripting function %s must return type %s" msgstr "" "функция %s, реализующая для типа обращение по индексу, должна возвращать тип " "%s" -#: commands/typecmds.c:2305 +#: commands/typecmds.c:2312 #, c-format msgid "user-defined types cannot use subscripting function %s" msgstr "" "для пользовательских типов нельзя использовать функцию-обработчик обращения " "по индексу %s" -#: commands/typecmds.c:2351 +#: commands/typecmds.c:2358 #, c-format msgid "" "You must specify an operator class for the range type or define a default " @@ -14734,141 +14775,141 @@ msgstr "" "Вы должны указать класс операторов для типа диапазона или определить класс " "операторов по умолчанию для этого подтипа." -#: commands/typecmds.c:2382 +#: commands/typecmds.c:2389 #, c-format msgid "range canonical function %s must return range type" msgstr "" "функция получения канонического диапазона %s должна возвращать диапазон" -#: commands/typecmds.c:2388 +#: commands/typecmds.c:2395 #, c-format msgid "range canonical function %s must be immutable" msgstr "" "функция получения канонического диапазона %s должна быть постоянной " "(IMMUTABLE)" -#: commands/typecmds.c:2424 +#: commands/typecmds.c:2431 #, c-format msgid "range subtype diff function %s must return type %s" msgstr "функция различий для подтипа диапазона (%s) должна возвращать тип %s" -#: commands/typecmds.c:2431 +#: commands/typecmds.c:2438 #, c-format msgid "range subtype diff function %s must be immutable" msgstr "" "функция различий для подтипа диапазона (%s) должна быть постоянной " "(IMMUTABLE)" -#: commands/typecmds.c:2458 +#: commands/typecmds.c:2465 #, c-format msgid "pg_type array OID value not set when in binary upgrade mode" msgstr "значение OID массива в pg_type не задано в режиме двоичного обновления" -#: commands/typecmds.c:2491 +#: commands/typecmds.c:2498 #, c-format msgid "pg_type multirange OID value not set when in binary upgrade mode" msgstr "" "значение OID мультидиапазона в pg_type не задано в режиме двоичного " "обновления" -#: commands/typecmds.c:2524 +#: commands/typecmds.c:2531 #, c-format msgid "pg_type multirange array OID value not set when in binary upgrade mode" msgstr "" "значение OID массива мультидиапазонов в pg_type не задано в режиме двоичного " "обновления" -#: commands/typecmds.c:2906 commands/typecmds.c:3088 +#: commands/typecmds.c:2913 commands/typecmds.c:3095 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist" msgstr "ограничение \"%s\" для домена \"%s\" не существует" -#: commands/typecmds.c:2910 +#: commands/typecmds.c:2917 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" msgstr "ограничение \"%s\" для домена \"%s\" не существует, пропускается" -#: commands/typecmds.c:3095 +#: commands/typecmds.c:3102 #, c-format msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" msgstr "" "ограничение \"%s\" для домена \"%s\" не является ограничением-проверкой" -#: commands/typecmds.c:3175 +#: commands/typecmds.c:3182 #, c-format msgid "column \"%s\" of table \"%s\" contains null values" msgstr "столбец \"%s\" таблицы \"%s\" содержит значения NULL" -#: commands/typecmds.c:3264 +#: commands/typecmds.c:3271 #, c-format msgid "" "column \"%s\" of table \"%s\" contains values that violate the new constraint" msgstr "" "столбец \"%s\" таблицы \"%s\" содержит значения, нарушающие новое ограничение" -#: commands/typecmds.c:3493 commands/typecmds.c:3771 commands/typecmds.c:3856 -#: commands/typecmds.c:4072 +#: commands/typecmds.c:3500 commands/typecmds.c:3778 commands/typecmds.c:3863 +#: commands/typecmds.c:4079 #, c-format msgid "%s is not a domain" msgstr "\"%s\" - это не домен" -#: commands/typecmds.c:3527 commands/typecmds.c:3683 +#: commands/typecmds.c:3534 commands/typecmds.c:3690 #, c-format msgid "constraint \"%s\" for domain \"%s\" already exists" msgstr "ограничение \"%s\" для домена \"%s\" уже существует" -#: commands/typecmds.c:3578 +#: commands/typecmds.c:3585 #, c-format msgid "cannot use table references in domain check constraint" msgstr "в ограничении-проверке для домена нельзя ссылаться на таблицы" -#: commands/typecmds.c:3783 commands/typecmds.c:3868 commands/typecmds.c:4222 +#: commands/typecmds.c:3790 commands/typecmds.c:3875 commands/typecmds.c:4229 #, c-format msgid "%s is a table's row type" msgstr "%s - это тип строк таблицы" -#: commands/typecmds.c:3793 commands/typecmds.c:3878 commands/typecmds.c:4120 +#: commands/typecmds.c:3800 commands/typecmds.c:3885 commands/typecmds.c:4127 #, c-format msgid "cannot alter array type %s" msgstr "изменить тип массива \"%s\" нельзя" -#: commands/typecmds.c:3795 commands/typecmds.c:3880 commands/typecmds.c:4122 +#: commands/typecmds.c:3802 commands/typecmds.c:3887 commands/typecmds.c:4129 #, c-format msgid "You can alter type %s, which will alter the array type as well." msgstr "Однако можно изменить тип %s, что повлечёт изменение типа массива." -#: commands/typecmds.c:3891 +#: commands/typecmds.c:3898 #, c-format msgid "cannot alter multirange type %s" msgstr "изменить мультидиапазонный тип %s нельзя" -#: commands/typecmds.c:3894 +#: commands/typecmds.c:3901 #, c-format msgid "You can alter type %s, which will alter the multirange type as well." msgstr "" "Однако можно изменить тип %s, что повлечёт изменение мультидиапазонного типа." -#: commands/typecmds.c:4201 +#: commands/typecmds.c:4208 #, c-format msgid "type \"%s\" already exists in schema \"%s\"" msgstr "тип \"%s\" уже существует в схеме \"%s\"" -#: commands/typecmds.c:4381 +#: commands/typecmds.c:4388 #, c-format msgid "cannot change type's storage to PLAIN" msgstr "сменить вариант хранения типа на PLAIN нельзя" -#: commands/typecmds.c:4474 +#: commands/typecmds.c:4481 #, c-format msgid "type attribute \"%s\" cannot be changed" msgstr "у типа нельзя изменить атрибут \"%s\"" -#: commands/typecmds.c:4492 +#: commands/typecmds.c:4499 #, c-format msgid "must be superuser to alter a type" msgstr "для модификации типа нужно быть суперпользователем" -#: commands/typecmds.c:4513 commands/typecmds.c:4522 +#: commands/typecmds.c:4520 commands/typecmds.c:4529 #, c-format msgid "%s is not a base type" msgstr "%s — не базовый тип" @@ -15338,7 +15379,7 @@ msgstr "VACUUM ONLY для секционированной таблицы \"%s\ msgid "cutoff for removing and freezing tuples is far in the past" msgstr "момент отсечки для удаления и замораживания кортежей далеко в прошлом" -#: commands/vacuum.c:1184 commands/vacuum.c:1189 +#: commands/vacuum.c:1184 #, c-format msgid "" "Close open transactions soon to avoid wraparound problems.\n" @@ -15355,6 +15396,17 @@ msgstr "" msgid "cutoff for freezing multixacts is far in the past" msgstr "момент отсечки для замораживания мультитранзакций далеко в прошлом" +#: commands/vacuum.c:1189 +#, c-format +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions." +msgstr "" +"Завершите открытые транзакции как можно быстрее во избежание проблемы " +"зацикливания.\n" +"Возможно, вам также придётся зафиксировать или откатить старые " +"подготовленные транзакции." + #: commands/vacuum.c:1950 #, c-format msgid "some databases have not been vacuumed in over 2 billion transactions" @@ -15755,8 +15807,8 @@ msgid "Table has type %s, but query expects %s." msgstr "В таблице задан тип %s, а в запросе ожидается %s." #: executor/execExprInterp.c:2511 utils/adt/expandedrecord.c:99 -#: utils/adt/expandedrecord.c:231 utils/cache/typcache.c:1841 -#: utils/cache/typcache.c:2000 utils/cache/typcache.c:2147 +#: utils/adt/expandedrecord.c:231 utils/cache/typcache.c:1834 +#: utils/cache/typcache.c:1993 utils/cache/typcache.c:2140 #: utils/fmgr/funcapi.c:569 #, c-format msgid "type %s is not composite" @@ -15782,8 +15834,8 @@ msgstr "" "элементов %s." #: executor/execExprInterp.c:3509 utils/adt/arrayfuncs.c:1305 -#: utils/adt/arrayfuncs.c:3515 utils/adt/arrayfuncs.c:5611 -#: utils/adt/arrayfuncs.c:6130 utils/adt/arraysubs.c:151 +#: utils/adt/arrayfuncs.c:3515 utils/adt/arrayfuncs.c:5620 +#: utils/adt/arrayfuncs.c:6137 utils/adt/arraysubs.c:151 #: utils/adt/arraysubs.c:489 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" @@ -15805,7 +15857,7 @@ msgstr "" #: utils/adt/arrayfuncs.c:2895 utils/adt/arrayfuncs.c:2949 #: utils/adt/arrayfuncs.c:2964 utils/adt/arrayfuncs.c:3305 #: utils/adt/arrayfuncs.c:3545 utils/adt/arrayfuncs.c:5383 -#: utils/adt/arrayfuncs.c:6222 utils/adt/arrayfuncs.c:6566 +#: utils/adt/arrayfuncs.c:6229 utils/adt/arrayfuncs.c:6573 #: utils/adt/arrayutils.c:83 utils/adt/arrayutils.c:92 #: utils/adt/arrayutils.c:99 #, c-format @@ -16348,7 +16400,7 @@ msgstr "нестандартное сканирование \"%s\" не подд msgid "could not rewind hash-join temporary file" msgstr "не удалось переместиться во временном файле хеш-соединения" -#: executor/nodeIndexonlyscan.c:240 +#: executor/nodeIndexonlyscan.c:222 #, c-format msgid "lossy distance functions are not supported in index-only scans" msgstr "" @@ -16434,13 +16486,13 @@ msgid "Consider defining the foreign key on table \"%s\"." msgstr "Возможно, имеет смысл перенацелить внешний ключ на таблицу \"%s\"." #. translator: %s is a SQL command name -#: executor/nodeModifyTable.c:2788 executor/nodeModifyTable.c:3328 -#: executor/nodeModifyTable.c:3525 +#: executor/nodeModifyTable.c:2807 executor/nodeModifyTable.c:3347 +#: executor/nodeModifyTable.c:3544 #, c-format msgid "%s command cannot affect row a second time" msgstr "команда %s не может подействовать на строку дважды" -#: executor/nodeModifyTable.c:2790 +#: executor/nodeModifyTable.c:2809 #, c-format msgid "" "Ensure that no rows proposed for insertion within the same command have " @@ -16449,7 +16501,7 @@ msgstr "" "Проверьте, не содержат ли строки, которые должна добавить команда, " "дублирующиеся значения, подпадающие под ограничения." -#: executor/nodeModifyTable.c:3321 executor/nodeModifyTable.c:3518 +#: executor/nodeModifyTable.c:3340 executor/nodeModifyTable.c:3537 #, c-format msgid "" "tuple to be updated or deleted was already modified by an operation " @@ -16458,14 +16510,14 @@ msgstr "" "кортеж, который должен быть изменён или удалён, уже модифицирован в " "операции, вызванной текущей командой" -#: executor/nodeModifyTable.c:3330 executor/nodeModifyTable.c:3527 +#: executor/nodeModifyTable.c:3349 executor/nodeModifyTable.c:3546 #, c-format msgid "Ensure that not more than one source row matches any one target row." msgstr "" "Проверьте, не может ли какой-либо целевой строке соответствовать более одной " "исходной строки." -#: executor/nodeModifyTable.c:3404 +#: executor/nodeModifyTable.c:3423 #, c-format msgid "" "tuple to be merged was already moved to another partition due to concurrent " @@ -18072,12 +18124,12 @@ msgid "User \"%s\" has a password that cannot be used with MD5 authentication." msgstr "" "Пользователь \"%s\" имеет пароль, неподходящий для аутентификации по MD5." -#: libpq/crypt.c:237 libpq/crypt.c:279 libpq/crypt.c:299 +#: libpq/crypt.c:238 libpq/crypt.c:280 libpq/crypt.c:301 #, c-format msgid "Password does not match for user \"%s\"." msgstr "Пароль не подходит для пользователя \"%s\"." -#: libpq/crypt.c:318 +#: libpq/crypt.c:320 #, c-format msgid "Password of user \"%s\" is in unrecognized format." msgstr "Пароль пользователя \"%s\" представлен в неизвестном формате." @@ -18982,8 +19034,8 @@ msgstr "методы расширенного узла \"%s\" не зареги msgid "relation \"%s\" does not have a composite type" msgstr "отношение \"%s\" не имеет составного типа" -#: nodes/nodeFuncs.c:118 nodes/nodeFuncs.c:149 parser/parse_coerce.c:2602 -#: parser/parse_coerce.c:2740 parser/parse_coerce.c:2787 +#: nodes/nodeFuncs.c:118 nodes/nodeFuncs.c:149 parser/parse_coerce.c:2601 +#: parser/parse_coerce.c:2739 parser/parse_coerce.c:2786 #: parser/parse_expr.c:2130 parser/parse_func.c:710 parser/parse_oper.c:869 #: utils/adt/array_userfuncs.c:1959 utils/fmgr/funcapi.c:669 #, c-format @@ -19022,19 +19074,19 @@ msgid "%s cannot be applied to the nullable side of an outer join" msgstr "%s не может применяться к NULL-содержащей стороне внешнего соединения" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1754 parser/analyze.c:1823 parser/analyze.c:2082 +#: optimizer/plan/planner.c:1645 parser/analyze.c:1823 parser/analyze.c:2082 #: parser/analyze.c:3412 #, c-format msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" msgstr "%s несовместимо с UNION/INTERSECT/EXCEPT" -#: optimizer/plan/planner.c:2500 optimizer/plan/planner.c:4386 +#: optimizer/plan/planner.c:2391 optimizer/plan/planner.c:4277 #, c-format msgid "could not implement GROUP BY" msgstr "не удалось реализовать GROUP BY" -#: optimizer/plan/planner.c:2501 optimizer/plan/planner.c:4387 -#: optimizer/plan/planner.c:5068 optimizer/prep/prepunion.c:1073 +#: optimizer/plan/planner.c:2392 optimizer/plan/planner.c:4278 +#: optimizer/plan/planner.c:4959 optimizer/prep/prepunion.c:1073 #, c-format msgid "" "Some of the datatypes only support hashing, while others only support " @@ -19043,27 +19095,27 @@ msgstr "" "Одни типы данных поддерживают только хеширование, а другие - только " "сортировку." -#: optimizer/plan/planner.c:5067 +#: optimizer/plan/planner.c:4958 #, c-format msgid "could not implement DISTINCT" msgstr "не удалось реализовать DISTINCT" -#: optimizer/plan/planner.c:6564 +#: optimizer/plan/planner.c:6455 #, c-format msgid "could not implement window PARTITION BY" msgstr "не удалось реализовать PARTITION BY для окна" -#: optimizer/plan/planner.c:6565 +#: optimizer/plan/planner.c:6456 #, c-format msgid "Window partitioning columns must be of sortable datatypes." msgstr "Столбцы, разбивающие окна, должны иметь сортируемые типы данных." -#: optimizer/plan/planner.c:6569 +#: optimizer/plan/planner.c:6460 #, c-format msgid "could not implement window ORDER BY" msgstr "не удалось реализовать ORDER BY для окна" -#: optimizer/plan/planner.c:6570 +#: optimizer/plan/planner.c:6461 #, c-format msgid "Window ordering columns must be of sortable datatypes." msgstr "Столбцы, сортирующие окна, должны иметь сортируемые типы данных." @@ -19096,7 +19148,7 @@ msgstr "" "атрибут \"%s\" отношения \"%s\" не соответствует родительскому правилу " "сортировки" -#: optimizer/util/clauses.c:4965 +#: optimizer/util/clauses.c:4992 #, c-format msgid "SQL function \"%s\" during inlining" msgstr "внедрённая в код SQL-функция \"%s\"" @@ -19764,7 +19816,7 @@ msgstr "" msgid "relation \"%s\" cannot be the target of a modifying statement" msgstr "отношение \"%s\" не может быть целевым в операторе, изменяющем данные" -#: parser/parse_clause.c:567 parser/parse_clause.c:595 parser/parse_func.c:2553 +#: parser/parse_clause.c:567 parser/parse_clause.c:595 parser/parse_func.c:2551 #, c-format msgid "set-returning functions must appear at top level of FROM" msgstr "" @@ -20076,150 +20128,150 @@ msgstr "" msgid "Cast the offset value to the exact intended type." msgstr "Приведите значение смещения в точности к желаемому типу." -#: parser/parse_coerce.c:1048 parser/parse_coerce.c:1086 -#: parser/parse_coerce.c:1104 parser/parse_coerce.c:1119 +#: parser/parse_coerce.c:1047 parser/parse_coerce.c:1085 +#: parser/parse_coerce.c:1103 parser/parse_coerce.c:1118 #: parser/parse_expr.c:2164 parser/parse_expr.c:2784 parser/parse_expr.c:3435 -#: parser/parse_expr.c:3664 parser/parse_target.c:1001 +#: parser/parse_expr.c:3664 parser/parse_expr.c:4100 parser/parse_target.c:1001 #, c-format msgid "cannot cast type %s to %s" msgstr "привести тип %s к %s нельзя" -#: parser/parse_coerce.c:1089 +#: parser/parse_coerce.c:1088 #, c-format msgid "Input has too few columns." msgstr "Во входных данных недостаточно столбцов." -#: parser/parse_coerce.c:1107 +#: parser/parse_coerce.c:1106 #, c-format msgid "Cannot cast type %s to %s in column %d." msgstr "Не удалось привести тип %s к %s в столбце %d." -#: parser/parse_coerce.c:1122 +#: parser/parse_coerce.c:1121 #, c-format msgid "Input has too many columns." msgstr "Во входных данных больше столбцов." #. translator: first %s is name of a SQL construct, eg WHERE #. translator: first %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1177 parser/parse_coerce.c:1225 +#: parser/parse_coerce.c:1176 parser/parse_coerce.c:1224 #, c-format msgid "argument of %s must be type %s, not type %s" msgstr "аргумент конструкции %s должен иметь тип %s, а не %s" #. translator: %s is name of a SQL construct, eg WHERE #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1188 parser/parse_coerce.c:1237 +#: parser/parse_coerce.c:1187 parser/parse_coerce.c:1236 #, c-format msgid "argument of %s must not return a set" msgstr "аргумент конструкции %s не должен возвращать множество" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1418 +#: parser/parse_coerce.c:1417 #, c-format msgid "%s types %s and %s cannot be matched" msgstr "в конструкции %s типы %s и %s не имеют общего" -#: parser/parse_coerce.c:1534 +#: parser/parse_coerce.c:1533 #, c-format msgid "argument types %s and %s cannot be matched" msgstr "типы аргументов %s и %s не имеют общего" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1586 +#: parser/parse_coerce.c:1585 #, c-format msgid "%s could not convert type %s to %s" msgstr "в конструкции %s нельзя преобразовать тип %s в %s" -#: parser/parse_coerce.c:2189 parser/parse_coerce.c:2209 -#: parser/parse_coerce.c:2229 parser/parse_coerce.c:2250 -#: parser/parse_coerce.c:2305 parser/parse_coerce.c:2339 +#: parser/parse_coerce.c:2188 parser/parse_coerce.c:2208 +#: parser/parse_coerce.c:2228 parser/parse_coerce.c:2249 +#: parser/parse_coerce.c:2304 parser/parse_coerce.c:2338 #, c-format msgid "arguments declared \"%s\" are not all alike" msgstr "аргументы, объявленные как \"%s\", должны быть однотипными" -#: parser/parse_coerce.c:2284 parser/parse_coerce.c:2397 +#: parser/parse_coerce.c:2283 parser/parse_coerce.c:2396 #: utils/fmgr/funcapi.c:600 #, c-format msgid "argument declared %s is not an array but type %s" msgstr "аргумент, объявленный как \"%s\", оказался не массивом, а типом %s" -#: parser/parse_coerce.c:2317 parser/parse_coerce.c:2467 +#: parser/parse_coerce.c:2316 parser/parse_coerce.c:2466 #: utils/fmgr/funcapi.c:614 #, c-format msgid "argument declared %s is not a range type but type %s" msgstr "аргумент, объявленный как \"%s\", имеет не диапазонный тип, а %s" -#: parser/parse_coerce.c:2351 parser/parse_coerce.c:2431 -#: parser/parse_coerce.c:2564 utils/fmgr/funcapi.c:632 utils/fmgr/funcapi.c:697 +#: parser/parse_coerce.c:2350 parser/parse_coerce.c:2430 +#: parser/parse_coerce.c:2563 utils/fmgr/funcapi.c:632 utils/fmgr/funcapi.c:697 #, c-format msgid "argument declared %s is not a multirange type but type %s" msgstr "аргумент, объявленный как \"%s\", имеет не мультидиапазонный тип, а %s" -#: parser/parse_coerce.c:2388 +#: parser/parse_coerce.c:2387 #, c-format msgid "cannot determine element type of \"anyarray\" argument" msgstr "тип элемента аргумента \"anyarray\" определить нельзя" -#: parser/parse_coerce.c:2414 parser/parse_coerce.c:2445 -#: parser/parse_coerce.c:2484 parser/parse_coerce.c:2550 +#: parser/parse_coerce.c:2413 parser/parse_coerce.c:2444 +#: parser/parse_coerce.c:2483 parser/parse_coerce.c:2549 #, c-format msgid "argument declared %s is not consistent with argument declared %s" msgstr "аргумент, объявленный как \"%s\", не согласуется с аргументом %s" -#: parser/parse_coerce.c:2509 +#: parser/parse_coerce.c:2508 #, c-format msgid "could not determine polymorphic type because input has type %s" msgstr "" "не удалось определить полиморфный тип, так как входные аргументы имеют тип %s" -#: parser/parse_coerce.c:2523 +#: parser/parse_coerce.c:2522 #, c-format msgid "type matched to anynonarray is an array type: %s" msgstr "" "в нарушение объявления \"anynonarray\" соответствующий аргумент оказался " "массивом: %s" -#: parser/parse_coerce.c:2533 +#: parser/parse_coerce.c:2532 #, c-format msgid "type matched to anyenum is not an enum type: %s" msgstr "" "в нарушение объявления \"anyenum\" соответствующий аргумент оказался не " "перечислением: %s" -#: parser/parse_coerce.c:2594 +#: parser/parse_coerce.c:2593 #, c-format msgid "arguments of anycompatible family cannot be cast to a common type" msgstr "" "аргументы семейства anycompatible не могут быть приведены к общему типу" -#: parser/parse_coerce.c:2612 parser/parse_coerce.c:2633 -#: parser/parse_coerce.c:2683 parser/parse_coerce.c:2688 -#: parser/parse_coerce.c:2752 parser/parse_coerce.c:2764 +#: parser/parse_coerce.c:2611 parser/parse_coerce.c:2632 +#: parser/parse_coerce.c:2682 parser/parse_coerce.c:2687 +#: parser/parse_coerce.c:2751 parser/parse_coerce.c:2763 #, c-format msgid "could not determine polymorphic type %s because input has type %s" msgstr "" "не удалось определить полиморфный тип %s, так как входные аргументы имеют " "тип %s" -#: parser/parse_coerce.c:2622 +#: parser/parse_coerce.c:2621 #, c-format msgid "anycompatiblerange type %s does not match anycompatible type %s" msgstr "тип %s (anycompatiblerange) не соответствует типу %s (anycompatible)" -#: parser/parse_coerce.c:2643 +#: parser/parse_coerce.c:2642 #, c-format msgid "anycompatiblemultirange type %s does not match anycompatible type %s" msgstr "" "тип %s (anycompatiblemultirange) не соответствует типу %s (anycompatible)" -#: parser/parse_coerce.c:2657 +#: parser/parse_coerce.c:2656 #, c-format msgid "type matched to anycompatiblenonarray is an array type: %s" msgstr "" "в нарушение объявления \"anycompatiblenonarray\" соответствующий аргумент " "оказался массивом: %s" -#: parser/parse_coerce.c:2892 +#: parser/parse_coerce.c:2891 #, c-format msgid "" "A result of type %s requires at least one input of type anyrange or " @@ -20228,7 +20280,7 @@ msgstr "" "Для результата типа %s требуется минимум один аргумент типа anyrange или " "anymultirange." -#: parser/parse_coerce.c:2909 +#: parser/parse_coerce.c:2908 #, c-format msgid "" "A result of type %s requires at least one input of type anycompatiblerange " @@ -20237,7 +20289,7 @@ msgstr "" "Для результата типа %s требуется минимум один аргумент типа " "anycompatiblerange или anycompatiblemultirange." -#: parser/parse_coerce.c:2921 +#: parser/parse_coerce.c:2920 #, c-format msgid "" "A result of type %s requires at least one input of type anyelement, " @@ -20246,7 +20298,7 @@ msgstr "" "Для результата типа %s требуется минимум один аргумент типа anyelement, " "anyarray, anynonarray, anyenum, anyrange или anymultirange." -#: parser/parse_coerce.c:2933 +#: parser/parse_coerce.c:2932 #, c-format msgid "" "A result of type %s requires at least one input of type anycompatible, " @@ -20257,7 +20309,7 @@ msgstr "" "anycompatiblearray, anycompatiblenonarray, anycompatiblerange или " "anycompatiblemultirange." -#: parser/parse_coerce.c:2963 +#: parser/parse_coerce.c:2962 msgid "A result of type internal requires at least one input of type internal." msgstr "" "Для результата типа internal требуется минимум один аргумент типа internal." @@ -20497,9 +20549,9 @@ msgstr "рекурсивная ссылка на запрос \"%s\" указа msgid "DEFAULT is not allowed in this context" msgstr "DEFAULT не допускается в данном контексте" -#: parser/parse_expr.c:405 parser/parse_relation.c:3797 -#: parser/parse_relation.c:3807 parser/parse_relation.c:3825 -#: parser/parse_relation.c:3832 parser/parse_relation.c:3846 +#: parser/parse_expr.c:405 parser/parse_relation.c:3829 +#: parser/parse_relation.c:3839 parser/parse_relation.c:3857 +#: parser/parse_relation.c:3864 parser/parse_relation.c:3878 #, c-format msgid "column %s.%s does not exist" msgstr "столбец %s.%s не существует" @@ -20534,8 +20586,8 @@ msgstr "в выражении DEFAULT (по умолчанию) нельзя с msgid "cannot use column reference in partition bound expression" msgstr "в выражении границы секции нельзя ссылаться на столбцы" -#: parser/parse_expr.c:845 parser/parse_relation.c:848 -#: parser/parse_relation.c:930 parser/parse_target.c:1241 +#: parser/parse_expr.c:845 parser/parse_relation.c:880 +#: parser/parse_relation.c:962 parser/parse_target.c:1241 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "неоднозначная ссылка на столбец \"%s\"" @@ -20580,7 +20632,7 @@ msgstr "" "SELECT или выражение ROW()" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_expr.c:1770 parser/parse_expr.c:2263 parser/parse_func.c:2679 +#: parser/parse_expr.c:1770 parser/parse_expr.c:2263 parser/parse_func.c:2677 #, c-format msgid "set-returning functions are not allowed in %s" msgstr "функции, возвращающие множества, нельзя применять в конструкции %s" @@ -20785,45 +20837,45 @@ msgstr "функции SQL/JSON не могут возвращать псевд msgid "aggregate ORDER BY is not implemented for window functions" msgstr "агрегатное предложение ORDER BY для оконных функций не реализовано" -#: parser/parse_expr.c:4102 +#: parser/parse_expr.c:4112 #, c-format msgid "cannot use JSON FORMAT ENCODING clause for non-bytea input types" msgstr "" "предложение JSON FORMAT ENCODING можно использовать только с типом bytea" -#: parser/parse_expr.c:4122 +#: parser/parse_expr.c:4132 #, c-format msgid "cannot use type %s in IS JSON predicate" msgstr "в предикате IS JSON нельзя использовать тип %s" -#: parser/parse_expr.c:4148 parser/parse_expr.c:4269 +#: parser/parse_expr.c:4158 parser/parse_expr.c:4279 #, c-format msgid "cannot use type %s in RETURNING clause of %s" msgstr "тип %s нельзя использовать в предложении RETURNING функции %s" -#: parser/parse_expr.c:4150 +#: parser/parse_expr.c:4160 #, c-format msgid "Try returning json or jsonb." msgstr "Попробуйте возвратить тип json или jsonb." -#: parser/parse_expr.c:4198 +#: parser/parse_expr.c:4208 #, c-format msgid "cannot use non-string types with WITH UNIQUE KEYS clause" msgstr "" "с предложением WITH UNIQUE KEYS можно использовать только строковые типы " "данных" -#: parser/parse_expr.c:4272 +#: parser/parse_expr.c:4282 #, c-format msgid "Try returning a string type or bytea." msgstr "Попробуйте возвратить строковый тип или bytea." -#: parser/parse_expr.c:4340 +#: parser/parse_expr.c:4350 #, c-format msgid "cannot specify FORMAT JSON in RETURNING clause of %s()" msgstr "FORMAT JSON не может указываться в предложении RETURNING %s()" -#: parser/parse_expr.c:4353 +#: parser/parse_expr.c:4363 #, c-format msgid "" "SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is used" @@ -20831,8 +20883,8 @@ msgstr "" "когда используется WITH WRAPPER, поведение QUOTES в SQL/JSON задать нельзя" #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4367 parser/parse_expr.c:4396 parser/parse_expr.c:4427 -#: parser/parse_expr.c:4453 parser/parse_expr.c:4479 +#: parser/parse_expr.c:4377 parser/parse_expr.c:4406 parser/parse_expr.c:4437 +#: parser/parse_expr.c:4463 parser/parse_expr.c:4489 #: parser/parse_jsontable.c:92 #, c-format msgid "invalid %s behavior" @@ -20840,7 +20892,7 @@ msgstr "неверное поведение %s" #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY), #. second %s is a SQL/JSON function name (e.g. JSON_QUERY) -#: parser/parse_expr.c:4370 parser/parse_expr.c:4399 +#: parser/parse_expr.c:4380 parser/parse_expr.c:4409 #, c-format msgid "" "Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is " @@ -20852,14 +20904,14 @@ msgstr "" #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) #. translator: first %s is name a SQL/JSON clause (eg. ON EMPTY) #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4377 parser/parse_expr.c:4406 parser/parse_expr.c:4435 -#: parser/parse_expr.c:4463 parser/parse_expr.c:4489 +#: parser/parse_expr.c:4387 parser/parse_expr.c:4416 parser/parse_expr.c:4445 +#: parser/parse_expr.c:4473 parser/parse_expr.c:4499 #, c-format msgid "invalid %s behavior for column \"%s\"" msgstr "неверное поведение %s для столбца \"%s\"" #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4380 parser/parse_expr.c:4409 +#: parser/parse_expr.c:4390 parser/parse_expr.c:4419 #, c-format msgid "" "Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is " @@ -20868,13 +20920,13 @@ msgstr "" "В %s для форматируемых столбцов допускается только ERROR, NULL, EMPTY ARRAY, " "EMPTY OBJECT или выражение DEFAULT." -#: parser/parse_expr.c:4428 +#: parser/parse_expr.c:4438 #, c-format msgid "Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for %s." msgstr "В %s для %s допускается только ERROR, TRUE, FALSE или UNKNOWN." #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4438 +#: parser/parse_expr.c:4448 #, c-format msgid "" "Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for EXISTS columns." @@ -20883,13 +20935,13 @@ msgstr "" #. translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY), #. second %s is a SQL/JSON function name (e.g. JSON_QUERY) -#: parser/parse_expr.c:4456 parser/parse_expr.c:4482 +#: parser/parse_expr.c:4466 parser/parse_expr.c:4492 #, c-format msgid "Only ERROR, NULL, or DEFAULT expression is allowed in %s for %s." msgstr "В %s для %s допускается только ERROR, NULL или выражение DEFAULT." #. translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) -#: parser/parse_expr.c:4466 parser/parse_expr.c:4492 +#: parser/parse_expr.c:4476 parser/parse_expr.c:4502 #, c-format msgid "" "Only ERROR, NULL, or DEFAULT expression is allowed in %s for scalar columns." @@ -20897,12 +20949,12 @@ msgstr "" "В %s для скалярных столбцов допускается только ERROR, NULL или выражение " "DEFAULT." -#: parser/parse_expr.c:4526 +#: parser/parse_expr.c:4536 #, c-format msgid "JSON path expression must be of type %s, not of type %s" msgstr "выражение пути JSON должно быть типа %s, а не типа %s" -#: parser/parse_expr.c:4766 +#: parser/parse_expr.c:4776 #, c-format msgid "" "can only specify a constant, non-aggregate function, or operator expression " @@ -20911,28 +20963,28 @@ msgstr "" "в DEFAULT может задаваться только константа, вызов не агрегатной функции или " "выражение с оператором" -#: parser/parse_expr.c:4771 +#: parser/parse_expr.c:4781 #, c-format msgid "DEFAULT expression must not contain column references" msgstr "выражения в DEFAULT не могут содержать ссылки на столбцы" -#: parser/parse_expr.c:4776 +#: parser/parse_expr.c:4786 #, c-format msgid "DEFAULT expression must not return a set" msgstr "выражение в DEFAULT не может возвращать множество" -#: parser/parse_expr.c:4791 +#: parser/parse_expr.c:4801 #, c-format msgid "collation of DEFAULT expression conflicts with RETURNING clause" msgstr "" "правило сортировки выражения DEFAULT конфликтует с предложением RETURNING" -#: parser/parse_expr.c:4870 parser/parse_expr.c:4879 +#: parser/parse_expr.c:4889 parser/parse_expr.c:4898 #, c-format msgid "cannot cast behavior expression of type %s to %s" msgstr "привести выражение поведения, имеющее тип %s, к типу %s нельзя" -#: parser/parse_expr.c:4873 +#: parser/parse_expr.c:4892 #, c-format msgid "You will need to explicitly cast the expression to type %s." msgstr "Приведите выражение к типу %s явно." @@ -20947,7 +20999,7 @@ msgstr "имя аргумента \"%s\" используется неоднок msgid "positional argument cannot follow named argument" msgstr "нумерованный аргумент не может следовать за именованным аргументом" -#: parser/parse_func.c:287 parser/parse_func.c:2368 +#: parser/parse_func.c:287 parser/parse_func.c:2366 #, c-format msgid "%s is not a procedure" msgstr "\"%s\" — не процедура" @@ -21109,7 +21161,7 @@ msgstr "" "Возможно, неверно расположено предложение ORDER BY - оно должно следовать за " "всеми обычными аргументами функции." -#: parser/parse_func.c:622 parser/parse_func.c:2411 +#: parser/parse_func.c:622 parser/parse_func.c:2409 #, c-format msgid "procedure %s does not exist" msgstr "процедура %s не существует" @@ -21174,22 +21226,22 @@ msgstr "" msgid "window functions cannot return sets" msgstr "оконные функции не могут возвращать множества" -#: parser/parse_func.c:2167 parser/parse_func.c:2440 +#: parser/parse_func.c:2165 parser/parse_func.c:2438 #, c-format msgid "could not find a function named \"%s\"" msgstr "не удалось найти функцию с именем \"%s\"" -#: parser/parse_func.c:2181 parser/parse_func.c:2458 +#: parser/parse_func.c:2179 parser/parse_func.c:2456 #, c-format msgid "function name \"%s\" is not unique" msgstr "имя функции \"%s\" не уникально" -#: parser/parse_func.c:2183 parser/parse_func.c:2461 +#: parser/parse_func.c:2181 parser/parse_func.c:2459 #, c-format msgid "Specify the argument list to select the function unambiguously." msgstr "Задайте список аргументов для однозначного выбора функции." -#: parser/parse_func.c:2227 +#: parser/parse_func.c:2225 #, c-format msgid "procedures cannot have more than %d argument" msgid_plural "procedures cannot have more than %d arguments" @@ -21197,143 +21249,143 @@ msgstr[0] "процедуры допускают не более %d аргуме msgstr[1] "процедуры допускают не более %d аргументов" msgstr[2] "процедуры допускают не более %d аргументов" -#: parser/parse_func.c:2358 +#: parser/parse_func.c:2356 #, c-format msgid "%s is not a function" msgstr "%s — не функция" -#: parser/parse_func.c:2378 +#: parser/parse_func.c:2376 #, c-format msgid "function %s is not an aggregate" msgstr "функция \"%s\" не является агрегатной" -#: parser/parse_func.c:2406 +#: parser/parse_func.c:2404 #, c-format msgid "could not find a procedure named \"%s\"" msgstr "не удалось найти процедуру с именем \"%s\"" -#: parser/parse_func.c:2420 +#: parser/parse_func.c:2418 #, c-format msgid "could not find an aggregate named \"%s\"" msgstr "не удалось найти агрегат с именем \"%s\"" -#: parser/parse_func.c:2425 +#: parser/parse_func.c:2423 #, c-format msgid "aggregate %s(*) does not exist" msgstr "агрегатная функция %s(*) не существует" -#: parser/parse_func.c:2430 +#: parser/parse_func.c:2428 #, c-format msgid "aggregate %s does not exist" msgstr "агрегатная функция %s не существует" -#: parser/parse_func.c:2466 +#: parser/parse_func.c:2464 #, c-format msgid "procedure name \"%s\" is not unique" msgstr "имя процедуры \"%s\" не уникально" -#: parser/parse_func.c:2469 +#: parser/parse_func.c:2467 #, c-format msgid "Specify the argument list to select the procedure unambiguously." msgstr "Задайте список аргументов для однозначного выбора процедуры." -#: parser/parse_func.c:2474 +#: parser/parse_func.c:2472 #, c-format msgid "aggregate name \"%s\" is not unique" msgstr "имя агрегатной функции \"%s\" не уникально" -#: parser/parse_func.c:2477 +#: parser/parse_func.c:2475 #, c-format msgid "Specify the argument list to select the aggregate unambiguously." msgstr "Задайте список аргументов для однозначного выбора агрегатной функции." -#: parser/parse_func.c:2482 +#: parser/parse_func.c:2480 #, c-format msgid "routine name \"%s\" is not unique" msgstr "имя подпрограммы \"%s\" не уникально" -#: parser/parse_func.c:2485 +#: parser/parse_func.c:2483 #, c-format msgid "Specify the argument list to select the routine unambiguously." msgstr "Задайте список аргументов для однозначного выбора подпрограммы." -#: parser/parse_func.c:2540 +#: parser/parse_func.c:2538 msgid "set-returning functions are not allowed in JOIN conditions" msgstr "функции, возвращающие множества, нельзя применять в условиях JOIN" -#: parser/parse_func.c:2561 +#: parser/parse_func.c:2559 msgid "set-returning functions are not allowed in policy expressions" msgstr "функции, возвращающие множества, нельзя применять в выражениях политик" -#: parser/parse_func.c:2577 +#: parser/parse_func.c:2575 msgid "set-returning functions are not allowed in window definitions" msgstr "функции, возвращающие множества, нельзя применять в определении окна" -#: parser/parse_func.c:2615 +#: parser/parse_func.c:2613 msgid "set-returning functions are not allowed in MERGE WHEN conditions" msgstr "" "функции, возвращающие множества, нельзя применять в условиях MERGE WHEN" -#: parser/parse_func.c:2619 +#: parser/parse_func.c:2617 msgid "set-returning functions are not allowed in check constraints" msgstr "" "функции, возвращающие множества, нельзя применять в ограничениях-проверках" -#: parser/parse_func.c:2623 +#: parser/parse_func.c:2621 msgid "set-returning functions are not allowed in DEFAULT expressions" msgstr "функции, возвращающие множества, нельзя применять в выражениях DEFAULT" -#: parser/parse_func.c:2626 +#: parser/parse_func.c:2624 msgid "set-returning functions are not allowed in index expressions" msgstr "" "функции, возвращающие множества, нельзя применять в выражениях индексов" -#: parser/parse_func.c:2629 +#: parser/parse_func.c:2627 msgid "set-returning functions are not allowed in index predicates" msgstr "" "функции, возвращающие множества, нельзя применять в предикатах индексов" -#: parser/parse_func.c:2632 +#: parser/parse_func.c:2630 msgid "set-returning functions are not allowed in statistics expressions" msgstr "" "функции, возвращающие множества, нельзя применять в выражениях статистики" -#: parser/parse_func.c:2635 +#: parser/parse_func.c:2633 msgid "set-returning functions are not allowed in transform expressions" msgstr "" "функции, возвращающие множества, нельзя применять в выражениях преобразований" -#: parser/parse_func.c:2638 +#: parser/parse_func.c:2636 msgid "set-returning functions are not allowed in EXECUTE parameters" msgstr "функции, возвращающие множества, нельзя применять в параметрах EXECUTE" -#: parser/parse_func.c:2641 +#: parser/parse_func.c:2639 msgid "set-returning functions are not allowed in trigger WHEN conditions" msgstr "" "функции, возвращающие множества, нельзя применять в условиях WHEN для " "триггеров" -#: parser/parse_func.c:2644 +#: parser/parse_func.c:2642 msgid "set-returning functions are not allowed in partition bound" msgstr "" "функции, возвращающие множества, нельзя применять в выражении границы секции" -#: parser/parse_func.c:2647 +#: parser/parse_func.c:2645 msgid "set-returning functions are not allowed in partition key expressions" msgstr "" "функции, возвращающие множества, нельзя применять в выражениях ключа " "секционирования" -#: parser/parse_func.c:2650 +#: parser/parse_func.c:2648 msgid "set-returning functions are not allowed in CALL arguments" msgstr "функции, возвращающие множества, нельзя применять в аргументах CALL" -#: parser/parse_func.c:2653 +#: parser/parse_func.c:2651 msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" msgstr "" "функции, возвращающие множества, нельзя применять в условиях COPY FROM WHERE" -#: parser/parse_func.c:2656 +#: parser/parse_func.c:2654 msgid "" "set-returning functions are not allowed in column generation expressions" msgstr "" @@ -21465,13 +21517,13 @@ msgstr "ссылка на таблицу \"%s\" неоднозначна" msgid "table reference %u is ambiguous" msgstr "ссылка на таблицу %u неоднозначна" -#: parser/parse_relation.c:502 parser/parse_relation.c:3739 -#: parser/parse_relation.c:3748 +#: parser/parse_relation.c:502 parser/parse_relation.c:3771 +#: parser/parse_relation.c:3780 #, c-format msgid "invalid reference to FROM-clause entry for table \"%s\"" msgstr "в элементе предложения FROM неверная ссылка на таблицу \"%s\"" -#: parser/parse_relation.c:506 parser/parse_relation.c:3750 +#: parser/parse_relation.c:506 parser/parse_relation.c:3782 #, c-format msgid "" "There is an entry for table \"%s\", but it cannot be referenced from this " @@ -21485,30 +21537,30 @@ msgstr "" msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." msgstr "Для ссылки LATERAL тип JOIN должен быть INNER или LEFT." -#: parser/parse_relation.c:711 +#: parser/parse_relation.c:743 #, c-format msgid "system column \"%s\" reference in check constraint is invalid" msgstr "в ограничении-проверке указан недопустимый системный столбец \"%s\"" -#: parser/parse_relation.c:724 +#: parser/parse_relation.c:756 #, c-format msgid "cannot use system column \"%s\" in column generation expression" msgstr "" "системный столбец \"%s\" нельзя использовать в выражении генерируемого " "столбца" -#: parser/parse_relation.c:735 +#: parser/parse_relation.c:767 #, c-format msgid "cannot use system column \"%s\" in MERGE WHEN condition" msgstr "системный столбец \"%s\" нельзя использовать в условии MERGE WHEN" -#: parser/parse_relation.c:1251 parser/parse_relation.c:1708 -#: parser/parse_relation.c:2402 +#: parser/parse_relation.c:1283 parser/parse_relation.c:1740 +#: parser/parse_relation.c:2434 #, c-format msgid "table \"%s\" has %d columns available but %d columns specified" msgstr "в таблице \"%s\" содержится столбцов: %d, но указано: %d" -#: parser/parse_relation.c:1462 +#: parser/parse_relation.c:1494 #, c-format msgid "" "There is a WITH item named \"%s\", but it cannot be referenced from this " @@ -21517,7 +21569,7 @@ msgstr "" "В WITH есть элемент \"%s\", но на него нельзя ссылаться из этой части " "запроса." -#: parser/parse_relation.c:1464 +#: parser/parse_relation.c:1496 #, c-format msgid "" "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." @@ -21525,13 +21577,13 @@ msgstr "" "Используйте WITH RECURSIVE или исключите ссылки вперёд, переупорядочив " "элементы WITH." -#: parser/parse_relation.c:1850 +#: parser/parse_relation.c:1882 #, c-format msgid "" "a column definition list is redundant for a function with OUT parameters" msgstr "список определений столбцов не нужен для функции с параметрами OUT" -#: parser/parse_relation.c:1856 +#: parser/parse_relation.c:1888 #, c-format msgid "" "a column definition list is redundant for a function returning a named " @@ -21540,79 +21592,79 @@ msgstr "" "список определений столбцов не нужен для функции, возвращающий именованный " "составной тип" -#: parser/parse_relation.c:1863 +#: parser/parse_relation.c:1895 #, c-format msgid "" "a column definition list is only allowed for functions returning \"record\"" msgstr "" "список определений столбцов может быть только у функций, возвращающих запись" -#: parser/parse_relation.c:1874 +#: parser/parse_relation.c:1906 #, c-format msgid "a column definition list is required for functions returning \"record\"" msgstr "" "у функций, возвращающих запись, должен быть список определений столбцов" -#: parser/parse_relation.c:1911 +#: parser/parse_relation.c:1943 #, c-format msgid "column definition lists can have at most %d entries" msgstr "число элементов в списках определения столбцов ограничено %d" -#: parser/parse_relation.c:1971 +#: parser/parse_relation.c:2003 #, c-format msgid "function \"%s\" in FROM has unsupported return type %s" msgstr "" "функция \"%s\", используемая во FROM, возвращает неподдерживаемый тип %s" -#: parser/parse_relation.c:1998 parser/parse_relation.c:2083 +#: parser/parse_relation.c:2030 parser/parse_relation.c:2115 #, c-format msgid "functions in FROM can return at most %d columns" msgstr "число столбцов, возвращаемых функциями во FROM, ограничено %d" -#: parser/parse_relation.c:2113 +#: parser/parse_relation.c:2145 #, c-format msgid "%s function has %d columns available but %d columns specified" msgstr "функция %s выдаёт столбцов: %d, но указано: %d" -#: parser/parse_relation.c:2194 +#: parser/parse_relation.c:2226 #, c-format msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" msgstr "в списках VALUES \"%s\" содержится столбцов: %d, но указано: %d" -#: parser/parse_relation.c:2259 +#: parser/parse_relation.c:2291 #, c-format msgid "joins can have at most %d columns" msgstr "число столбцов в соединениях ограничено %d" -#: parser/parse_relation.c:2284 +#: parser/parse_relation.c:2316 #, c-format msgid "" "join expression \"%s\" has %d columns available but %d columns specified" msgstr "в выражении соединения \"%s\" имеется столбцов: %d, но указано: %d" -#: parser/parse_relation.c:2375 +#: parser/parse_relation.c:2407 #, c-format msgid "WITH query \"%s\" does not have a RETURNING clause" msgstr "в запросе \"%s\" в WITH нет предложения RETURNING" -#: parser/parse_relation.c:3741 +#: parser/parse_relation.c:3773 #, c-format msgid "Perhaps you meant to reference the table alias \"%s\"." msgstr "Возможно, предполагалась ссылка на псевдоним таблицы \"%s\"." -#: parser/parse_relation.c:3753 +#: parser/parse_relation.c:3785 #, c-format msgid "To reference that table, you must mark this subquery with LATERAL." msgstr "" "Чтобы обратиться к этой таблице, нужно добавить для данного подзапроса " "пометку LATERAL." -#: parser/parse_relation.c:3759 +#: parser/parse_relation.c:3791 #, c-format msgid "missing FROM-clause entry for table \"%s\"" msgstr "таблица \"%s\" отсутствует в предложении FROM" -#: parser/parse_relation.c:3799 +#: parser/parse_relation.c:3831 #, c-format msgid "" "There are columns named \"%s\", but they are in tables that cannot be " @@ -21621,12 +21673,12 @@ msgstr "" "Имеются столбцы с именем \"%s\", но они относятся к таблицам, к которым " "нельзя обратиться из этой части запроса." -#: parser/parse_relation.c:3801 +#: parser/parse_relation.c:3833 #, c-format msgid "Try using a table-qualified name." msgstr "Попробуйте использовать имя с указанием таблицы." -#: parser/parse_relation.c:3809 +#: parser/parse_relation.c:3841 #, c-format msgid "" "There is a column named \"%s\" in table \"%s\", but it cannot be referenced " @@ -21635,25 +21687,25 @@ msgstr "" "Столбец \"%s\" есть в таблице \"%s\", но на него нельзя ссылаться из этой " "части запроса." -#: parser/parse_relation.c:3812 +#: parser/parse_relation.c:3844 #, c-format msgid "To reference that column, you must mark this subquery with LATERAL." msgstr "" "Чтобы обратиться к этому столбцу, нужно добавить для данного подзапроса " "пометку LATERAL." -#: parser/parse_relation.c:3814 +#: parser/parse_relation.c:3846 #, c-format msgid "To reference that column, you must use a table-qualified name." msgstr "" "Чтобы обратиться к этому столбцу, нужно использовать имя с указанием таблицы." -#: parser/parse_relation.c:3834 +#: parser/parse_relation.c:3866 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\"." msgstr "Возможно, предполагалась ссылка на столбец \"%s.%s\"." -#: parser/parse_relation.c:3848 +#: parser/parse_relation.c:3880 #, c-format msgid "" "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." @@ -22247,7 +22299,7 @@ msgstr "значение остатка для хеш-секции должно msgid "\"%s\" is not a hash partitioned table" msgstr "\"%s\" не является таблицей, секционированной по хешу" -#: partitioning/partbounds.c:4841 partitioning/partbounds.c:4958 +#: partitioning/partbounds.c:4841 partitioning/partbounds.c:4970 #, c-format msgid "" "number of partitioning columns (%d) does not match number of partition keys " @@ -22264,7 +22316,7 @@ msgstr "" "столбец %d ключа секционирования имеет тип %s, но для него передано значение " "типа %s" -#: partitioning/partbounds.c:4895 +#: partitioning/partbounds.c:4901 #, c-format msgid "" "column %d of the partition key has type \"%s\", but supplied value is of " @@ -23317,12 +23369,12 @@ msgstr "не удалось открыть файл протокола \"%s\": % msgid "disabling automatic rotation (use SIGHUP to re-enable)" msgstr "отключение автопрокрутки (чтобы включить, передайте SIGHUP)" -#: postmaster/walsummarizer.c:744 +#: postmaster/walsummarizer.c:784 #, c-format msgid "WAL summarization is not progressing" msgstr "процесс обобщения WAL не продвигается" -#: postmaster/walsummarizer.c:745 +#: postmaster/walsummarizer.c:785 #, c-format msgid "" "Summarization is needed through %X/%X, but is stuck at %X/%X on disk and %X/" @@ -23331,7 +23383,7 @@ msgstr "" "Обобщение должно охватить %X/%X, но оно остановилось на позиции %X/%X на " "диске и %X/%X в памяти." -#: postmaster/walsummarizer.c:759 +#: postmaster/walsummarizer.c:799 #, c-format msgid "still waiting for WAL summarization through %X/%X after %ld second" msgid_plural "" @@ -23340,22 +23392,22 @@ msgstr[0] "ожидание обобщения позиции %X/%X продол msgstr[1] "ожидание обобщения позиции %X/%X продолжается %ld сек." msgstr[2] "ожидание обобщения позиции %X/%X продолжается %ld сек." -#: postmaster/walsummarizer.c:764 +#: postmaster/walsummarizer.c:804 #, c-format msgid "Summarization has reached %X/%X on disk and %X/%X in memory." msgstr "Процесс обобщения достиг позиции %X/%X на диске и %X/%X в памяти." -#: postmaster/walsummarizer.c:1004 +#: postmaster/walsummarizer.c:1103 #, c-format msgid "could not find a valid record after %X/%X" msgstr "не удалось найти корректную запись после %X/%X" -#: postmaster/walsummarizer.c:1049 +#: postmaster/walsummarizer.c:1148 #, c-format msgid "could not read WAL from timeline %u at %X/%X: %s" msgstr "не удалось прочитать WAL с линии времени %u в позиции %X/%X: %s" -#: postmaster/walsummarizer.c:1055 +#: postmaster/walsummarizer.c:1154 #, c-format msgid "could not read WAL from timeline %u at %X/%X" msgstr "не удалось прочитать WAL с линии времени %u в позиции %X/%X" @@ -23401,7 +23453,7 @@ msgid "could not clear search path: %s" msgstr "не удалось очистить путь поиска: %s" #: replication/libpqwalreceiver/libpqwalreceiver.c:308 -#: replication/libpqwalreceiver/libpqwalreceiver.c:508 +#: replication/libpqwalreceiver/libpqwalreceiver.c:522 #, c-format msgid "invalid connection string syntax: %s" msgstr "ошибочный синтаксис строки подключения: %s" @@ -23428,7 +23480,8 @@ msgstr "" "сервера: %s" #: replication/libpqwalreceiver/libpqwalreceiver.c:455 -#: replication/libpqwalreceiver/libpqwalreceiver.c:762 +#: replication/libpqwalreceiver/libpqwalreceiver.c:795 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1045 #, c-format msgid "invalid response from primary server" msgstr "неверный ответ главного сервера" @@ -23442,91 +23495,103 @@ msgstr "" "Не удалось идентифицировать систему, получено строк: %d, полей: %d " "(ожидалось: %d и %d (или более))." -#: replication/libpqwalreceiver/libpqwalreceiver.c:597 -#: replication/libpqwalreceiver/libpqwalreceiver.c:604 -#: replication/libpqwalreceiver/libpqwalreceiver.c:636 +#: replication/libpqwalreceiver/libpqwalreceiver.c:470 +#, c-format +msgid "could not parse WAL location \"%s\"" +msgstr "не удалось разобрать позицию в WAL \"%s\"" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:669 #, c-format msgid "could not start WAL streaming: %s" msgstr "не удалось начать трансляцию WAL: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:660 +#: replication/libpqwalreceiver/libpqwalreceiver.c:693 #, c-format msgid "could not send end-of-streaming message to primary: %s" msgstr "не удалось отправить главному серверу сообщение о конце передачи: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:684 +#: replication/libpqwalreceiver/libpqwalreceiver.c:717 #, c-format msgid "unexpected result set after end-of-streaming" msgstr "неожиданный набор данных после конца передачи" -#: replication/libpqwalreceiver/libpqwalreceiver.c:700 +#: replication/libpqwalreceiver/libpqwalreceiver.c:733 #, c-format msgid "error while shutting down streaming COPY: %s" msgstr "ошибка при остановке потоковой операции COPY: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:711 +#: replication/libpqwalreceiver/libpqwalreceiver.c:744 #, c-format msgid "error reading result of streaming command: %s" msgstr "ошибка при чтении результата команды передачи: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:721 -#: replication/libpqwalreceiver/libpqwalreceiver.c:857 +#: replication/libpqwalreceiver/libpqwalreceiver.c:754 +#: replication/libpqwalreceiver/libpqwalreceiver.c:890 #, c-format msgid "unexpected result after CommandComplete: %s" msgstr "неожиданный результат после CommandComplete: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:750 +#: replication/libpqwalreceiver/libpqwalreceiver.c:783 #, c-format msgid "could not receive timeline history file from the primary server: %s" msgstr "не удалось получить файл истории линии времени с главного сервера: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:763 +#: replication/libpqwalreceiver/libpqwalreceiver.c:796 #, c-format msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." msgstr "Ожидался 1 кортеж с 2 полями, однако получено кортежей: %d, полей: %d." -#: replication/libpqwalreceiver/libpqwalreceiver.c:818 -#: replication/libpqwalreceiver/libpqwalreceiver.c:873 -#: replication/libpqwalreceiver/libpqwalreceiver.c:880 +#: replication/libpqwalreceiver/libpqwalreceiver.c:851 +#: replication/libpqwalreceiver/libpqwalreceiver.c:906 +#: replication/libpqwalreceiver/libpqwalreceiver.c:913 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "не удалось получить данные из потока WAL: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:900 +#: replication/libpqwalreceiver/libpqwalreceiver.c:933 #, c-format msgid "could not send data to WAL stream: %s" msgstr "не удалось отправить данные в поток WAL: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1003 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1037 #, c-format msgid "could not create replication slot \"%s\": %s" msgstr "не удалось создать слот репликации \"%s\": %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1055 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1046 +#, c-format +msgid "" +"Could not create replication slot \"%s\": got %d rows and %d fields, " +"expected %d rows and %d fields." +msgstr "" +"Создать слот репликации \"%s\" не удалось; получено строк: %d, полей: %d " +"(ожидалось: %d и %d)." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1098 #, c-format msgid "could not alter replication slot \"%s\": %s" msgstr "не удалось изменить свойства слота репликации \"%s\": %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1089 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1132 #, c-format msgid "invalid query response" msgstr "неверный ответ на запрос" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1090 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1133 #, c-format msgid "Expected %d fields, got %d fields." msgstr "Ожидалось полей: %d, получено: %d." -#: replication/libpqwalreceiver/libpqwalreceiver.c:1160 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1203 #, c-format msgid "the query interface requires a database connection" msgstr "для интерфейса запросов требуется подключение к БД" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1194 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1237 msgid "empty query" msgstr "пустой запрос" -#: replication/libpqwalreceiver/libpqwalreceiver.c:1200 +#: replication/libpqwalreceiver/libpqwalreceiver.c:1243 msgid "unexpected pipeline mode" msgstr "неожиданный режим канала" @@ -23739,7 +23804,7 @@ msgstr "недостаточно слотов для процессов логи #. translator: %s is a GUC variable name #: replication/logical/launcher.c:438 replication/logical/launcher.c:524 -#: replication/slot.c:1670 replication/slot.c:1690 storage/lmgr/lock.c:1042 +#: replication/slot.c:1672 replication/slot.c:1692 storage/lmgr/lock.c:1042 #: storage/lmgr/lock.c:1080 storage/lmgr/lock.c:2969 storage/lmgr/lock.c:4374 #: storage/lmgr/lock.c:4439 storage/lmgr/lock.c:4789 #: storage/lmgr/predicate.c:2479 storage/lmgr/predicate.c:2494 @@ -23803,8 +23868,8 @@ msgid "cannot use replication slot \"%s\" for logical decoding" msgstr "" "слот репликации \"%s\" нельзя использовать для логического декодирования" -#: replication/logical/logical.c:546 replication/slot.c:858 -#: replication/slot.c:903 +#: replication/logical/logical.c:546 replication/slot.c:860 +#: replication/slot.c:905 #, c-format msgid "This replication slot is being synchronized from the primary server." msgstr "Этот слот репликации синхронизируется с ведущего сервера." @@ -24066,19 +24131,19 @@ msgstr "" msgid "logical replication target relation \"%s.%s\" does not exist" msgstr "целевое отношение логической репликации \"%s.%s\" не существует" -#: replication/logical/reorderbuffer.c:4252 +#: replication/logical/reorderbuffer.c:4276 #, c-format msgid "could not write to data file for XID %u: %m" msgstr "не удалось записать в файл данных для XID %u: %m" -#: replication/logical/reorderbuffer.c:4598 -#: replication/logical/reorderbuffer.c:4623 +#: replication/logical/reorderbuffer.c:4622 +#: replication/logical/reorderbuffer.c:4647 #, c-format msgid "could not read from reorderbuffer spill file: %m" msgstr "не удалось прочитать файл подкачки буфера пересортировки: %m" -#: replication/logical/reorderbuffer.c:4602 -#: replication/logical/reorderbuffer.c:4627 +#: replication/logical/reorderbuffer.c:4626 +#: replication/logical/reorderbuffer.c:4651 #, c-format msgid "" "could not read from reorderbuffer spill file: read %d instead of %u bytes" @@ -24086,17 +24151,17 @@ msgstr "" "не удалось прочитать файл подкачки буфера пересортировки (прочитано байт: " "%d, требовалось: %u)" -#: replication/logical/reorderbuffer.c:4876 +#: replication/logical/reorderbuffer.c:4900 #, c-format msgid "could not remove file \"%s\" during removal of %s/%s/xid*: %m" msgstr "ошибка при удалении файла \"%s\" в процессе удаления %s/%s/xid*: %m" -#: replication/logical/reorderbuffer.c:5373 +#: replication/logical/reorderbuffer.c:5397 #, c-format msgid "could not read from file \"%s\": read %d instead of %d bytes" msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d, требовалось: %d)" -#: replication/logical/slotsync.c:225 replication/logical/slotsync.c:620 +#: replication/logical/slotsync.c:225 replication/logical/slotsync.c:623 #, c-format msgid "could not synchronize replication slot \"%s\"" msgstr "не удалось синхронизировать слот репликации \"%s\"" @@ -24112,12 +24177,12 @@ msgstr "" "WAL в позиции LSN %X/%X и xmin каталога %u, но на резервном сервере текущий " "LSN %X/%X и xmin каталога %u." -#: replication/logical/slotsync.c:499 +#: replication/logical/slotsync.c:498 #, c-format msgid "dropped replication slot \"%s\" of database with OID %u" msgstr "слот репликации \"%s\" базы данных с OID %u удалён" -#: replication/logical/slotsync.c:621 +#: replication/logical/slotsync.c:624 #, c-format msgid "" "Synchronization could lead to data loss, because the standby could not build " @@ -24126,12 +24191,12 @@ msgstr "" "Синхронизация могла привести к потере данных, так как резервный сервер не " "смог получить согласованный снимок для декодирования WAL в позиции LSN %X/%X." -#: replication/logical/slotsync.c:630 +#: replication/logical/slotsync.c:633 #, c-format msgid "newly created replication slot \"%s\" is sync-ready now" msgstr "созданный слот репликации \"%s\" сейчас готов к синхронизации" -#: replication/logical/slotsync.c:669 +#: replication/logical/slotsync.c:672 #, c-format msgid "" "skipping slot synchronization because the received slot sync LSN %X/%X for " @@ -24140,7 +24205,7 @@ msgstr "" "синхронизация слота пропускается, потому что полученная позиция LSN %X/%X " "для слота \"%s\" предшествует позиции %X/%X на резервном сервере" -#: replication/logical/slotsync.c:691 +#: replication/logical/slotsync.c:694 #, c-format msgid "" "exiting from slot synchronization because same name slot \"%s\" already " @@ -24149,32 +24214,32 @@ msgstr "" "синхронизация слота отменяется, потому что слот с таким же именем \"%s\" уже " "существует на резервном сервере" -#: replication/logical/slotsync.c:862 +#: replication/logical/slotsync.c:865 #, c-format msgid "could not fetch failover logical slots info from the primary server: %s" msgstr "" "не удалось получить информацию о переносимых логических слотах с главного " "сервера: %s" -#: replication/logical/slotsync.c:1011 +#: replication/logical/slotsync.c:1014 #, c-format msgid "" "could not fetch primary slot name \"%s\" info from the primary server: %s" msgstr "не удалось получить информацию о слоте \"%s\" с главного сервера: %s" # skip-rule: nastroy1 -#: replication/logical/slotsync.c:1013 +#: replication/logical/slotsync.c:1016 #, c-format msgid "Check if \"primary_slot_name\" is configured correctly." msgstr "Проверьте правильность настройки \"primary_slot_name\"." -#: replication/logical/slotsync.c:1033 +#: replication/logical/slotsync.c:1036 #, c-format msgid "cannot synchronize replication slots from a standby server" msgstr "синхронизировать слоты репликации с резервного сервера нельзя" #. translator: second %s is a GUC variable name -#: replication/logical/slotsync.c:1042 +#: replication/logical/slotsync.c:1045 #, c-format msgid "" "replication slot \"%s\" specified by \"%s\" does not exist on primary server" @@ -24184,32 +24249,32 @@ msgstr "" #. translator: first %s is a connection option; second %s is a GUC #. variable name #. -#: replication/logical/slotsync.c:1075 +#: replication/logical/slotsync.c:1078 #, c-format msgid "" "replication slot synchronization requires \"%s\" to be specified in \"%s\"" msgstr "для синхронизации слотов репликации требуется указание \"%s\" в \"%s\"" -#: replication/logical/slotsync.c:1094 +#: replication/logical/slotsync.c:1097 #, c-format msgid "replication slot synchronization requires \"wal_level\" >= \"logical\"" msgstr "" "для синхронизации слотов репликации требуется \"wal_level\" >= \"logical\"" #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1109 replication/logical/slotsync.c:1137 +#: replication/logical/slotsync.c:1112 replication/logical/slotsync.c:1140 #, c-format msgid "replication slot synchronization requires \"%s\" to be set" msgstr "для синхронизации слотов репликации требуется установить \"%s\"" #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1123 +#: replication/logical/slotsync.c:1126 #, c-format msgid "replication slot synchronization requires \"%s\" to be enabled" msgstr "для синхронизации слотов репликации требуется включить \"%s\"" #. translator: %s is a GUC variable name -#: replication/logical/slotsync.c:1180 +#: replication/logical/slotsync.c:1183 #, c-format msgid "" "replication slot synchronization worker will stop because \"%s\" is disabled" @@ -24217,7 +24282,7 @@ msgstr "" "процесс синхронизации слотов репликации будет остановлен, так как \"%s\" " "отключён" -#: replication/logical/slotsync.c:1198 +#: replication/logical/slotsync.c:1201 #, c-format msgid "" "replication slot synchronization worker will restart because of a parameter " @@ -24226,7 +24291,7 @@ msgstr "" "процесс синхронизации слотов репликации будет перезапущен вследствие " "изменения параметров" -#: replication/logical/slotsync.c:1223 +#: replication/logical/slotsync.c:1226 #, c-format msgid "" "replication slot synchronization will stop because of a parameter change" @@ -24234,7 +24299,7 @@ msgstr "" "процесс синхронизации слотов репликации будет остановлен вследствие " "изменения параметров" -#: replication/logical/slotsync.c:1259 +#: replication/logical/slotsync.c:1262 #, c-format msgid "" "replication slot synchronization worker will stop because promotion is " @@ -24243,7 +24308,7 @@ msgstr "" "процесс синхронизации слотов репликации будет остановлен, так как вызвана " "процедура повышения сервера" -#: replication/logical/slotsync.c:1273 +#: replication/logical/slotsync.c:1276 #, c-format msgid "" "replication slot synchronization will stop because promotion is triggered" @@ -24251,7 +24316,7 @@ msgstr "" "синхронизация слотов репликации будет остановлена, так как вызвана процедура " "повышения сервера" -#: replication/logical/slotsync.c:1393 +#: replication/logical/slotsync.c:1396 #, c-format msgid "" "replication slot synchronization worker will not start because promotion was " @@ -24260,7 +24325,7 @@ msgstr "" "процесс синхронизации слотов репликации не будет запущен, так как вызвана " "процедура повышения сервера" -#: replication/logical/slotsync.c:1405 +#: replication/logical/slotsync.c:1408 #, c-format msgid "" "replication slot synchronization will not start because promotion was " @@ -24269,17 +24334,17 @@ msgstr "" "синхронизация слотов репликации не будет запущена, так как вызвана процедура " "повышения сервера" -#: replication/logical/slotsync.c:1414 +#: replication/logical/slotsync.c:1417 #, c-format msgid "cannot synchronize replication slots concurrently" msgstr "многопоточная синхронизация слотов репликации не поддерживается" -#: replication/logical/slotsync.c:1526 +#: replication/logical/slotsync.c:1529 #, c-format msgid "slot sync worker started" msgstr "рабочий процесс синхронизации слотов запущен" -#: replication/logical/slotsync.c:1588 replication/slotfuncs.c:928 +#: replication/logical/slotsync.c:1591 replication/slotfuncs.c:928 #, c-format msgid "" "synchronization worker \"%s\" could not connect to the primary server: %s" @@ -24417,7 +24482,7 @@ msgid "could not start initial contents copy for table \"%s.%s\": %s" msgstr "" "не удалось начать копирование начального содержимого таблицы \"%s.%s\": %s" -#: replication/logical/tablesync.c:1380 +#: replication/logical/tablesync.c:1381 #, c-format msgid "" "table synchronization worker for subscription \"%s\" could not connect to " @@ -24426,14 +24491,14 @@ msgstr "" "процесс синхронизации таблицы для подписки \"%s\" не смог подключиться к " "серверу публикации: %s" -#: replication/logical/tablesync.c:1480 +#: replication/logical/tablesync.c:1481 #, c-format msgid "table copy could not start transaction on publisher: %s" msgstr "" "при копировании таблицы не удалось начать транзакцию на сервере публикации: " "%s" -#: replication/logical/tablesync.c:1540 replication/logical/worker.c:2378 +#: replication/logical/tablesync.c:1541 replication/logical/worker.c:2388 #, c-format msgid "" "user \"%s\" cannot replicate into relation with row-level security enabled: " @@ -24442,7 +24507,7 @@ msgstr "" "пользователь \"%s\" не может реплицировать данные в отношение с включённой " "защитой на уровне строк: \"%s\"" -#: replication/logical/tablesync.c:1553 +#: replication/logical/tablesync.c:1554 #, c-format msgid "table copy could not finish transaction on publisher: %s" msgstr "" @@ -24467,13 +24532,22 @@ msgstr "" "транзакций репликации, передаваемых в потоке, пока все таблицы не " "синхронизированы." -#: replication/logical/worker.c:846 replication/logical/worker.c:961 +#: replication/logical/worker.c:813 replication/logical/worker.c:930 +#: replication/logical/worker.c:2634 +#, c-format +msgid "" +"logical replication column %d not found in tuple: only %d column(s) received" +msgstr "" +"столбец %d для логической репликации не найден в кортеже; всего получено " +"столбцов: %d" + +#: replication/logical/worker.c:852 replication/logical/worker.c:971 #, c-format msgid "incorrect binary data format in logical replication column %d" msgstr "" "неправильный формат двоичных данных для столбца логической репликации %d" -#: replication/logical/worker.c:2525 +#: replication/logical/worker.c:2535 #, c-format msgid "" "publisher did not send replica identity column expected by the logical " @@ -24482,7 +24556,7 @@ msgstr "" "сервер публикации не передал столбец идентификации реплики, ожидаемый для " "целевого отношения логической репликации \"%s.%s\"" -#: replication/logical/worker.c:2532 +#: replication/logical/worker.c:2542 #, c-format msgid "" "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY " @@ -24493,22 +24567,22 @@ msgstr "" "IDENTITY, ни ключа PRIMARY KEY, и публикуемое отношение не имеет " "характеристики REPLICA IDENTITY FULL" -#: replication/logical/worker.c:3467 +#: replication/logical/worker.c:3482 #, c-format msgid "invalid logical replication message type \"??? (%d)\"" msgstr "неверный тип сообщения логической репликации \"??? (%d)\"" -#: replication/logical/worker.c:3639 +#: replication/logical/worker.c:3654 #, c-format msgid "data stream from publisher has ended" msgstr "поток данных с сервера публикации закончился" -#: replication/logical/worker.c:3793 +#: replication/logical/worker.c:3808 #, c-format msgid "terminating logical replication worker due to timeout" msgstr "завершение обработчика логической репликации из-за тайм-аута" -#: replication/logical/worker.c:3990 +#: replication/logical/worker.c:4005 #, c-format msgid "" "logical replication worker for subscription \"%s\" will stop because the " @@ -24517,7 +24591,7 @@ msgstr "" "процесс логической репликации для подписки \"%s\" будет остановлен, так как " "подписка была удалена" -#: replication/logical/worker.c:4004 +#: replication/logical/worker.c:4019 #, c-format msgid "" "logical replication worker for subscription \"%s\" will stop because the " @@ -24526,7 +24600,7 @@ msgstr "" "процесс логической репликации для подписки \"%s\" будет остановлен, так как " "подписка была отключена" -#: replication/logical/worker.c:4035 +#: replication/logical/worker.c:4050 #, c-format msgid "" "logical replication parallel apply worker for subscription \"%s\" will stop " @@ -24535,7 +24609,7 @@ msgstr "" "параллельный применяющий процесс логической репликации для подписки \"%s\" " "будет остановлен вследствие изменения параметров" -#: replication/logical/worker.c:4039 +#: replication/logical/worker.c:4054 #, c-format msgid "" "logical replication worker for subscription \"%s\" will restart because of a " @@ -24544,7 +24618,7 @@ msgstr "" "процесс логической репликации для подписки \"%s\" будет перезапущен " "вследствие изменения параметров" -#: replication/logical/worker.c:4053 +#: replication/logical/worker.c:4068 #, c-format msgid "" "logical replication parallel apply worker for subscription \"%s\" will stop " @@ -24554,7 +24628,7 @@ msgstr "" "подписки \"%s\" будет остановлен, потому что владелец подписки был лишён " "прав суперпользователя" -#: replication/logical/worker.c:4057 +#: replication/logical/worker.c:4072 #, c-format msgid "" "logical replication worker for subscription \"%s\" will restart because the " @@ -24563,12 +24637,12 @@ msgstr "" "процесс логической репликации для подписки \"%s\" будет перезапущен, потому " "что владелец подписки был лишён прав суперпользователя" -#: replication/logical/worker.c:4567 +#: replication/logical/worker.c:4582 #, c-format msgid "subscription has no replication slot set" msgstr "для подписки не задан слот репликации" -#: replication/logical/worker.c:4592 +#: replication/logical/worker.c:4607 #, c-format msgid "" "apply worker for subscription \"%s\" could not connect to the publisher: %s" @@ -24576,7 +24650,7 @@ msgstr "" "процесс применения изменений для подписки \"%s\" не смог подключиться к " "серверу публикации: %s" -#: replication/logical/worker.c:4696 +#: replication/logical/worker.c:4711 #, c-format msgid "" "logical replication worker for subscription %u will not start because the " @@ -24585,7 +24659,7 @@ msgstr "" "процесс логической репликации для подписки %u не будет запущен, так как " "подписка была удалена при старте" -#: replication/logical/worker.c:4712 +#: replication/logical/worker.c:4727 #, c-format msgid "" "logical replication worker for subscription \"%s\" will not start because " @@ -24594,7 +24668,7 @@ msgstr "" "процесс логической репликации для подписки \"%s\" не будет запущен, так как " "подписка была отключена при старте" -#: replication/logical/worker.c:4736 +#: replication/logical/worker.c:4751 #, c-format msgid "" "logical replication table synchronization worker for subscription \"%s\", " @@ -24603,35 +24677,35 @@ msgstr "" "процесс синхронизации таблицы при логической репликации для подписки \"%s\", " "таблицы \"%s\" запущен" -#: replication/logical/worker.c:4741 +#: replication/logical/worker.c:4756 #, c-format msgid "logical replication apply worker for subscription \"%s\" has started" msgstr "" "запускается применяющий процесс логической репликации для подписки \"%s\"" -#: replication/logical/worker.c:4875 +#: replication/logical/worker.c:4886 #, c-format msgid "subscription \"%s\" has been disabled because of an error" msgstr "подписка \"%s\" была отключена из-за ошибки" -#: replication/logical/worker.c:4923 +#: replication/logical/worker.c:4934 #, c-format msgid "logical replication starts skipping transaction at LSN %X/%X" msgstr "" "обработчик логической репликации начинает пропускать транзакцию с LSN %X/%X" -#: replication/logical/worker.c:4937 +#: replication/logical/worker.c:4948 #, c-format msgid "logical replication completed skipping transaction at LSN %X/%X" msgstr "" "обработчик логической репликации завершил пропуск транзакции с LSN %X/%X" -#: replication/logical/worker.c:5025 +#: replication/logical/worker.c:5036 #, c-format msgid "skip-LSN of subscription \"%s\" cleared" msgstr "значение skip-LSN для подписки \"%s\" очищено" -#: replication/logical/worker.c:5026 +#: replication/logical/worker.c:5037 #, c-format msgid "" "Remote transaction's finish WAL location (LSN) %X/%X did not match skip-LSN " @@ -24640,7 +24714,7 @@ msgstr "" "Позиция завершения удалённой транзакции в WAL (LSN) %X/%X не совпала со " "значением skip-LSN %X/%X." -#: replication/logical/worker.c:5054 +#: replication/logical/worker.c:5065 #, c-format msgid "" "processing remote data for replication origin \"%s\" during message type " @@ -24649,7 +24723,7 @@ msgstr "" "обработка внешних данных для источника репликации \"%s\" в контексте " "сообщения типа \"%s\"" -#: replication/logical/worker.c:5058 +#: replication/logical/worker.c:5069 #, c-format msgid "" "processing remote data for replication origin \"%s\" during message type " @@ -24658,7 +24732,7 @@ msgstr "" "обработка внешних данных из источника репликации \"%s\" в контексте " "сообщения типа \"%s\" в транзакции %u" -#: replication/logical/worker.c:5063 +#: replication/logical/worker.c:5074 #, c-format msgid "" "processing remote data for replication origin \"%s\" during message type " @@ -24667,7 +24741,7 @@ msgstr "" "обработка внешних данных для источника репликации \"%s\" в контексте " "сообщения типа \"%s\" в транзакции %u, конечная позиция %X/%X" -#: replication/logical/worker.c:5074 +#: replication/logical/worker.c:5085 #, c-format msgid "" "processing remote data for replication origin \"%s\" during message type " @@ -24677,7 +24751,7 @@ msgstr "" "сообщения типа \"%s\" для целевого отношения репликации \"%s.%s\" в " "транзакции %u" -#: replication/logical/worker.c:5081 +#: replication/logical/worker.c:5092 #, c-format msgid "" "processing remote data for replication origin \"%s\" during message type " @@ -24688,7 +24762,7 @@ msgstr "" "сообщения типа \"%s\" для целевого отношения репликации \"%s.%s\" в " "транзакции %u, конечная позиция %X/%X" -#: replication/logical/worker.c:5092 +#: replication/logical/worker.c:5103 #, c-format msgid "" "processing remote data for replication origin \"%s\" during message type " @@ -24699,7 +24773,7 @@ msgstr "" "сообщения типа \"%s\" для целевого отношения репликации \"%s.%s\", столбца " "\"%s\", в транзакции %u" -#: replication/logical/worker.c:5100 +#: replication/logical/worker.c:5111 #, c-format msgid "" "processing remote data for replication origin \"%s\" during message type " @@ -24835,7 +24909,7 @@ msgid "cannot enable failover for a replication slot created on the standby" msgstr "" "слот репликации, созданный на ведомом сервере, не может быть переносимым" -#: replication/slot.c:389 replication/slot.c:925 +#: replication/slot.c:389 replication/slot.c:927 #, c-format msgid "cannot enable failover for a temporary replication slot" msgstr "временный слот репликации не может быть переносимым" @@ -24861,7 +24935,7 @@ msgstr "Освободите ненужный или увеличьте пара msgid "replication slot \"%s\" does not exist" msgstr "слот репликации \"%s\" не существует" -#: replication/slot.c:664 replication/slot.c:1499 +#: replication/slot.c:664 replication/slot.c:1501 #, c-format msgid "replication slot \"%s\" is active for PID %d" msgstr "слот репликации \"%s\" занят процессом с PID %d" @@ -24886,65 +24960,65 @@ msgstr "получен слот логической репликации \"%s\" msgid "acquired physical replication slot \"%s\"" msgstr "получен слот физической репликации \"%s\"" -#: replication/slot.c:789 +#: replication/slot.c:791 #, c-format msgid "released logical replication slot \"%s\"" msgstr "освобождён слот логической репликации \"%s\"" -#: replication/slot.c:791 +#: replication/slot.c:793 #, c-format msgid "released physical replication slot \"%s\"" msgstr "освобождён слот физической репликации \"%s\"" -#: replication/slot.c:857 +#: replication/slot.c:859 #, c-format msgid "cannot drop replication slot \"%s\"" msgstr "удалить слот репликации \"%s\" нельзя" -#: replication/slot.c:890 +#: replication/slot.c:892 #, c-format msgid "cannot use %s with a physical replication slot" msgstr "выполнить %s со слотом физической репликации нельзя" -#: replication/slot.c:902 +#: replication/slot.c:904 #, c-format msgid "cannot alter replication slot \"%s\"" msgstr "изменить слот репликации \"%s\" нельзя" -#: replication/slot.c:912 +#: replication/slot.c:914 #, c-format msgid "cannot enable failover for a replication slot on the standby" msgstr "сделать переносимым слот репликации на ведомом сервере нельзя" -#: replication/slot.c:1060 replication/slot.c:2228 replication/slot.c:2621 +#: replication/slot.c:1062 replication/slot.c:2230 replication/slot.c:2623 #, c-format msgid "could not remove directory \"%s\"" msgstr "ошибка при удалении каталога \"%s\"" -#: replication/slot.c:1534 +#: replication/slot.c:1536 #, c-format msgid "replication slots can only be used if \"max_replication_slots\" > 0" msgstr "" "слоты репликации можно использовать, только если \"max_replication_slots\" > " "0" -#: replication/slot.c:1539 +#: replication/slot.c:1541 #, c-format msgid "replication slots can only be used if \"wal_level\" >= \"replica\"" msgstr "" "слоты репликации можно использовать, только если \"wal_level\" >= \"replica\"" -#: replication/slot.c:1551 +#: replication/slot.c:1553 #, c-format msgid "permission denied to use replication slots" msgstr "нет прав для использования слотов репликации" -#: replication/slot.c:1552 +#: replication/slot.c:1554 #, c-format msgid "Only roles with the %s attribute may use replication slots." msgstr "Использовать слоты репликации могут только роли с атрибутом %s." -#: replication/slot.c:1664 +#: replication/slot.c:1666 #, c-format msgid "The slot's restart_lsn %X/%X exceeds the limit by % byte." msgid_plural "" @@ -24953,12 +25027,12 @@ msgstr[0] "Позиция restart_lsn %X/%X слота превысила пре msgstr[1] "Позиция restart_lsn %X/%X слота превысила предел на % Б." msgstr[2] "Позиция restart_lsn %X/%X слота превысила предел на % Б." -#: replication/slot.c:1675 +#: replication/slot.c:1677 #, c-format msgid "The slot conflicted with xid horizon %u." msgstr "Слот конфликтует с горизонтом xid %u." -#: replication/slot.c:1680 +#: replication/slot.c:1682 msgid "" "Logical decoding on standby requires \"wal_level\" >= \"logical\" on the " "primary server." @@ -24967,7 +25041,7 @@ msgstr "" "\"logical\" на ведущем." #. translator: %s is a GUC variable name -#: replication/slot.c:1686 +#: replication/slot.c:1688 #, c-format msgid "" "The slot's idle time of %lds exceeds the configured \"%s\" duration of %ds." @@ -24975,50 +25049,50 @@ msgstr "" "Время простоя слота %ld сек. превышает настроенную в \"%s\" длительность %d " "сек." -#: replication/slot.c:1700 +#: replication/slot.c:1702 #, c-format msgid "terminating process %d to release replication slot \"%s\"" msgstr "завершение процесса %d для освобождения слота репликации \"%s\"" -#: replication/slot.c:1702 +#: replication/slot.c:1704 #, c-format msgid "invalidating obsolete replication slot \"%s\"" msgstr "аннулирование устаревшего слота репликации \"%s\"" -#: replication/slot.c:2559 +#: replication/slot.c:2561 #, c-format msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" msgstr "" "файл слота репликации \"%s\" имеет неправильную сигнатуру (%u вместо %u)" -#: replication/slot.c:2566 +#: replication/slot.c:2568 #, c-format msgid "replication slot file \"%s\" has unsupported version %u" msgstr "файл состояния snapbuild \"%s\" имеет неподдерживаемую версию %u" -#: replication/slot.c:2573 +#: replication/slot.c:2575 #, c-format msgid "replication slot file \"%s\" has corrupted length %u" msgstr "у файла слота репликации \"%s\" неверная длина: %u" -#: replication/slot.c:2609 +#: replication/slot.c:2611 #, c-format msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" msgstr "" "в файле слота репликации \"%s\" неверная контрольная сумма (%u вместо %u)" -#: replication/slot.c:2645 +#: replication/slot.c:2647 #, c-format msgid "logical replication slot \"%s\" exists, but \"wal_level\" < \"logical\"" msgstr "" "существует слот логической репликации \"%s\", но \"wal_level\" < \"logical\"" -#: replication/slot.c:2647 +#: replication/slot.c:2649 #, c-format msgid "Change \"wal_level\" to be \"logical\" or higher." msgstr "Смените \"wal_level\" на \"logical\" или более высокий уровень." -#: replication/slot.c:2659 +#: replication/slot.c:2661 #, c-format msgid "" "logical replication slot \"%s\" exists on the standby, but \"hot_standby\" = " @@ -25027,39 +25101,39 @@ msgstr "" "на ведомом сервере существует слот логической репликации \"%s\", но " "\"hot_standby\" = \"off\"" -#: replication/slot.c:2661 +#: replication/slot.c:2663 #, c-format msgid "Change \"hot_standby\" to be \"on\"." msgstr "Смените значение \"hot_standby\" на \"on\"." -#: replication/slot.c:2666 +#: replication/slot.c:2668 #, c-format msgid "" "physical replication slot \"%s\" exists, but \"wal_level\" < \"replica\"" msgstr "" "существует слот физической репликации \"%s\", но \"wal_level\" < \"replica\"" -#: replication/slot.c:2668 +#: replication/slot.c:2670 #, c-format msgid "Change \"wal_level\" to be \"replica\" or higher." msgstr "Смените \"wal_level\" на \"replica\" или более высокий уровень." -#: replication/slot.c:2715 +#: replication/slot.c:2717 #, c-format msgid "too many replication slots active before shutdown" msgstr "перед завершением активно слишком много слотов репликации" -#: replication/slot.c:2716 +#: replication/slot.c:2718 #, c-format msgid "Increase \"max_replication_slots\" and try again." msgstr "Увеличьте параметр \"max_replication_slots\" и повторите попытку." -#: replication/slot.c:2953 +#: replication/slot.c:2955 #, c-format msgid "replication slot \"%s\" specified in parameter \"%s\" does not exist" msgstr "слот репликации \"%s\", указанный в параметре \"%s\", не существует" -#: replication/slot.c:2955 replication/slot.c:2989 replication/slot.c:3004 +#: replication/slot.c:2957 replication/slot.c:2991 replication/slot.c:3006 #, c-format msgid "" "Logical replication is waiting on the standby associated with replication " @@ -25068,30 +25142,30 @@ msgstr "" "Логическая репликация ожидает резервного сервера, связанного со слотом " "репликации \"%s\"." -#: replication/slot.c:2957 +#: replication/slot.c:2959 #, c-format msgid "Create the replication slot \"%s\" or amend parameter \"%s\"." msgstr "Создайте слот репликации \"%s\" или опустите параметр \"%s\"." -#: replication/slot.c:2967 +#: replication/slot.c:2969 #, c-format msgid "cannot specify logical replication slot \"%s\" in parameter \"%s\"" msgstr "" "слот логической репликации \"%s\" не может быть указан в параметре \"%s\"" -#: replication/slot.c:2969 +#: replication/slot.c:2971 #, c-format msgid "" "Logical replication is waiting for correction on replication slot \"%s\"." msgstr "Логическая репликация ожидает исправления слота репликации \"%s\"." -#: replication/slot.c:2971 +#: replication/slot.c:2973 #, c-format msgid "Remove the logical replication slot \"%s\" from parameter \"%s\"." msgstr "" "Удалите указание слота логической репликации \"%s\" из параметра \"%s\"." -#: replication/slot.c:2987 +#: replication/slot.c:2989 #, c-format msgid "" "physical replication slot \"%s\" specified in parameter \"%s\" has been " @@ -25100,14 +25174,14 @@ msgstr "" "слот физической репликации \"%s\", указанный в параметре \"%s\", был " "аннулирован" -#: replication/slot.c:2991 +#: replication/slot.c:2993 #, c-format msgid "" "Drop and recreate the replication slot \"%s\", or amend parameter \"%s\"." msgstr "" "Удалите и пересоздайте слот репликации \"%s\" или опустите параметр \"%s\"." -#: replication/slot.c:3002 +#: replication/slot.c:3004 #, c-format msgid "" "replication slot \"%s\" specified in parameter \"%s\" does not have " @@ -25116,7 +25190,7 @@ msgstr "" "у слота репликации \"%s\", указанного в параметре \"%s\", нулевое значение " "active_pid" -#: replication/slot.c:3006 +#: replication/slot.c:3008 #, c-format msgid "" "Start the standby associated with the replication slot \"%s\", or amend " @@ -25262,7 +25336,7 @@ msgstr "Разобрать \"%s\" не удалось." msgid "number of synchronous standbys (%d) must be greater than zero" msgstr "число синхронных резервных серверов (%d) должно быть больше нуля" -#: replication/walreceiver.c:276 +#: replication/walreceiver.c:285 #, c-format msgid "" "streaming replication receiver \"%s\" could not connect to the primary " @@ -25271,72 +25345,90 @@ msgstr "" "приёмник потоковой репликации \"%s\" не смог подключиться к главному " "серверу: %s" -#: replication/walreceiver.c:324 +#: replication/walreceiver.c:335 #, c-format msgid "database system identifier differs between the primary and standby" msgstr "идентификаторы СУБД на главном и резервном серверах различаются" -#: replication/walreceiver.c:325 +#: replication/walreceiver.c:336 #, c-format msgid "The primary's identifier is %s, the standby's identifier is %s." msgstr "Идентификатор на главном сервере: %s, на резервном: %s." -#: replication/walreceiver.c:336 +#: replication/walreceiver.c:347 #, c-format msgid "highest timeline %u of the primary is behind recovery timeline %u" msgstr "" "последняя линия времени %u на главном сервере отстаёт от восстанавливаемой " "линии времени %u" -#: replication/walreceiver.c:389 +#: replication/walreceiver.c:390 +#, c-format +msgid "" +"walreceiver requested start point %X/%08X on timeline %u is ahead of the " +"upstream server's flush position %X/%08X, waiting" +msgstr "" +"walreceiver запросил начальную точку %X/%08X на линии времени %u, " +"опережающую позицию сброшенных данных на вышестоящем сервере %X/%08X, " +"требуется ожидание" + +#: replication/walreceiver.c:405 +#, c-format +msgid "" +"terminating walreceiver due to timeout while waiting for upstream to catch up" +msgstr "" +"завершение приёма журнала из-за тайм-аута при ожидании достижения требуемой " +"позиции вышестоящим сервером" + +#: replication/walreceiver.c:466 #, c-format msgid "started streaming WAL from primary at %X/%X on timeline %u" msgstr "" "начало передачи журнала с главного сервера, с позиции %X/%X на линии времени " "%u" -#: replication/walreceiver.c:393 +#: replication/walreceiver.c:470 #, c-format msgid "restarted WAL streaming at %X/%X on timeline %u" msgstr "перезапуск передачи журнала с позиции %X/%X на линии времени %u" -#: replication/walreceiver.c:428 +#: replication/walreceiver.c:505 #, c-format msgid "cannot continue WAL streaming, recovery has already ended" msgstr "продолжить передачу WAL нельзя, восстановление уже окончено" -#: replication/walreceiver.c:472 +#: replication/walreceiver.c:549 #, c-format msgid "replication terminated by primary server" msgstr "репликация прекращена главным сервером" -#: replication/walreceiver.c:473 +#: replication/walreceiver.c:550 #, c-format msgid "End of WAL reached on timeline %u at %X/%X." msgstr "На линии времени %u в %X/%X достигнут конец журнала." -#: replication/walreceiver.c:573 +#: replication/walreceiver.c:650 #, c-format msgid "terminating walreceiver due to timeout" msgstr "завершение приёма журнала из-за тайм-аута" -#: replication/walreceiver.c:605 +#: replication/walreceiver.c:682 #, c-format msgid "primary server contains no more WAL on requested timeline %u" msgstr "" "на главном сервере больше нет журналов для запрошенной линии времени %u" -#: replication/walreceiver.c:621 replication/walreceiver.c:1063 +#: replication/walreceiver.c:698 replication/walreceiver.c:1140 #, c-format msgid "could not close WAL segment %s: %m" msgstr "не удалось закрыть сегмент WAL %s: %m" -#: replication/walreceiver.c:740 +#: replication/walreceiver.c:817 #, c-format msgid "fetching timeline history file for timeline %u from primary server" msgstr "загрузка файла истории для линии времени %u с главного сервера" -#: replication/walreceiver.c:951 +#: replication/walreceiver.c:1025 #, c-format msgid "could not write to WAL segment %s at offset %d, length %lu: %m" msgstr "не удалось записать в сегмент WAL %s (смещение %d, длина %lu): %m" @@ -25384,66 +25476,66 @@ msgstr "" "на этом сервере (%X/%X)" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1257 +#: replication/walsender.c:1279 #, c-format msgid "%s must not be called inside a transaction" msgstr "%s требуется выполнять не в транзакции" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1267 +#: replication/walsender.c:1289 #, c-format msgid "%s must be called inside a transaction" msgstr "%s требуется выполнять внутри транзакции" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1273 +#: replication/walsender.c:1295 #, c-format msgid "%s must be called in REPEATABLE READ isolation mode transaction" msgstr "%s требуется выполнять в транзакции уровня изоляции REPEATABLE READ" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1278 +#: replication/walsender.c:1300 #, c-format msgid "%s must be called in a read-only transaction" msgstr "%s требуется выполнять внутри транзакции только для чтения" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1284 +#: replication/walsender.c:1306 #, c-format msgid "%s must be called before any query" msgstr "%s требуется выполнять до каких-либо запросов" #. translator: %s is a CREATE_REPLICATION_SLOT statement -#: replication/walsender.c:1290 +#: replication/walsender.c:1312 #, c-format msgid "%s must not be called in a subtransaction" msgstr "%s требуется вызывать не в подтранзакции" -#: replication/walsender.c:1467 +#: replication/walsender.c:1489 #, c-format msgid "terminating walsender process after promotion" msgstr "завершение процесса передачи журнала после повышения" -#: replication/walsender.c:2016 +#: replication/walsender.c:2038 #, c-format msgid "cannot execute new commands while WAL sender is in stopping mode" msgstr "" "нельзя выполнять новые команды, пока процесс передачи WAL находится в режиме " "остановки" -#: replication/walsender.c:2070 +#: replication/walsender.c:2092 #, c-format msgid "cannot execute SQL commands in WAL sender for physical replication" msgstr "" "нельзя выполнять команды SQL в процессе, передающем WAL для физической " "репликации" -#: replication/walsender.c:2101 +#: replication/walsender.c:2123 #, c-format msgid "received replication command: %s" msgstr "получена команда репликации: %s" -#: replication/walsender.c:2109 tcop/fastpath.c:208 tcop/postgres.c:1138 +#: replication/walsender.c:2131 tcop/fastpath.c:208 tcop/postgres.c:1138 #: tcop/postgres.c:1495 tcop/postgres.c:1747 tcop/postgres.c:2252 #: tcop/postgres.c:2689 tcop/postgres.c:2766 #, c-format @@ -25453,32 +25545,32 @@ msgid "" msgstr "" "текущая транзакция прервана, команды до конца блока транзакции игнорируются" -#: replication/walsender.c:2269 replication/walsender.c:2304 +#: replication/walsender.c:2291 replication/walsender.c:2326 #, c-format msgid "unexpected EOF on standby connection" msgstr "неожиданный обрыв соединения с резервным сервером" -#: replication/walsender.c:2292 +#: replication/walsender.c:2314 #, c-format msgid "invalid standby message type \"%c\"" msgstr "неверный тип сообщения резервного сервера: \"%c\"" -#: replication/walsender.c:2381 +#: replication/walsender.c:2403 #, c-format msgid "unexpected message type \"%c\"" msgstr "неожиданный тип сообщения \"%c\"" -#: replication/walsender.c:2798 +#: replication/walsender.c:2820 #, c-format msgid "terminating walsender process due to replication timeout" msgstr "завершение процесса передачи журнала из-за тайм-аута репликации" -#: rewrite/rewriteDefine.c:104 rewrite/rewriteDefine.c:835 +#: rewrite/rewriteDefine.c:104 rewrite/rewriteDefine.c:820 #, c-format msgid "rule \"%s\" for relation \"%s\" already exists" msgstr "правило \"%s\" для отношения \"%s\" уже существует" -#: rewrite/rewriteDefine.c:261 rewrite/rewriteDefine.c:773 +#: rewrite/rewriteDefine.c:261 rewrite/rewriteDefine.c:758 #, c-format msgid "relation \"%s\" cannot have rules" msgstr "к отношению \"%s\" не могут применяться правила" @@ -25544,56 +25636,56 @@ msgstr "в правилах для SELECT не может быть услови msgid "\"%s\" is already a view" msgstr "\"%s\" уже является представлением" -#: rewrite/rewriteDefine.c:408 +#: rewrite/rewriteDefine.c:395 #, c-format msgid "view rule for \"%s\" must be named \"%s\"" msgstr "правило представления для \"%s\" должно называться \"%s\"" -#: rewrite/rewriteDefine.c:435 +#: rewrite/rewriteDefine.c:420 #, c-format msgid "cannot have multiple RETURNING lists in a rule" msgstr "в правиле нельзя указать несколько списков RETURNING" -#: rewrite/rewriteDefine.c:440 +#: rewrite/rewriteDefine.c:425 #, c-format msgid "RETURNING lists are not supported in conditional rules" msgstr "списки RETURNING в условных правилах не поддерживаются" -#: rewrite/rewriteDefine.c:444 +#: rewrite/rewriteDefine.c:429 #, c-format msgid "RETURNING lists are not supported in non-INSTEAD rules" msgstr "списки RETURNING поддерживаются только в правилах INSTEAD" -#: rewrite/rewriteDefine.c:458 +#: rewrite/rewriteDefine.c:443 rewrite/rewriteDefine.c:839 #, c-format msgid "non-view rule for \"%s\" must not be named \"%s\"" msgstr "" "не относящееся к представлению правило для \"%s\" не может называться \"%s\"" -#: rewrite/rewriteDefine.c:532 +#: rewrite/rewriteDefine.c:517 #, c-format msgid "SELECT rule's target list has too many entries" msgstr "список результата правила для SELECT содержит слишком много столбцов" -#: rewrite/rewriteDefine.c:533 +#: rewrite/rewriteDefine.c:518 #, c-format msgid "RETURNING list has too many entries" msgstr "список RETURNING содержит слишком много столбцов" -#: rewrite/rewriteDefine.c:560 +#: rewrite/rewriteDefine.c:545 #, c-format msgid "cannot convert relation containing dropped columns to view" msgstr "" "преобразовать отношение, содержащее удалённые столбцы, в представление нельзя" -#: rewrite/rewriteDefine.c:561 +#: rewrite/rewriteDefine.c:546 #, c-format msgid "" "cannot create a RETURNING list for a relation containing dropped columns" msgstr "" "создать список RETURNING для отношения, содержащего удалённые столбцы, нельзя" -#: rewrite/rewriteDefine.c:567 +#: rewrite/rewriteDefine.c:552 #, c-format msgid "" "SELECT rule's target entry %d has different column name from column \"%s\"" @@ -25601,62 +25693,62 @@ msgstr "" "элементу %d результата правила для SELECT присвоено имя, отличное от имени " "столбца \"%s\"" -#: rewrite/rewriteDefine.c:569 +#: rewrite/rewriteDefine.c:554 #, c-format msgid "SELECT target entry is named \"%s\"." msgstr "Имя элемента результата SELECT: \"%s\"." -#: rewrite/rewriteDefine.c:578 +#: rewrite/rewriteDefine.c:563 #, c-format msgid "SELECT rule's target entry %d has different type from column \"%s\"" msgstr "" "элемент %d результата правила для SELECT имеет тип, отличный от типа столбца " "\"%s\"" -#: rewrite/rewriteDefine.c:580 +#: rewrite/rewriteDefine.c:565 #, c-format msgid "RETURNING list's entry %d has different type from column \"%s\"" msgstr "элемент %d списка RETURNING имеет тип, отличный от типа столбца \"%s\"" -#: rewrite/rewriteDefine.c:583 rewrite/rewriteDefine.c:607 +#: rewrite/rewriteDefine.c:568 rewrite/rewriteDefine.c:592 #, c-format msgid "SELECT target entry has type %s, but column has type %s." msgstr "Элемент результата SELECT имеет тип %s, тогда как тип столбца - %s." -#: rewrite/rewriteDefine.c:586 rewrite/rewriteDefine.c:611 +#: rewrite/rewriteDefine.c:571 rewrite/rewriteDefine.c:596 #, c-format msgid "RETURNING list entry has type %s, but column has type %s." msgstr "Элемент списка RETURNING имеет тип %s, тогда как тип столбца - %s." -#: rewrite/rewriteDefine.c:602 +#: rewrite/rewriteDefine.c:587 #, c-format msgid "SELECT rule's target entry %d has different size from column \"%s\"" msgstr "" "элемент %d результата правила для SELECT имеет размер, отличный от столбца " "\"%s\"" -#: rewrite/rewriteDefine.c:604 +#: rewrite/rewriteDefine.c:589 #, c-format msgid "RETURNING list's entry %d has different size from column \"%s\"" msgstr "элемент %d списка RETURNING имеет размер, отличный от столбца \"%s\"" -#: rewrite/rewriteDefine.c:621 +#: rewrite/rewriteDefine.c:606 #, c-format msgid "SELECT rule's target list has too few entries" msgstr "список результата правила для SELECT содержит недостаточно элементов" -#: rewrite/rewriteDefine.c:622 +#: rewrite/rewriteDefine.c:607 #, c-format msgid "RETURNING list has too few entries" msgstr "список RETURNING содержит недостаточно элементов" -#: rewrite/rewriteDefine.c:711 rewrite/rewriteDefine.c:826 +#: rewrite/rewriteDefine.c:696 rewrite/rewriteDefine.c:811 #: rewrite/rewriteSupport.c:108 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist" msgstr "правило \"%s\" для отношения\"%s\" не существует" -#: rewrite/rewriteDefine.c:845 +#: rewrite/rewriteDefine.c:830 #, c-format msgid "renaming an ON SELECT rule is not allowed" msgstr "переименовывать правило ON SELECT нельзя" @@ -26072,8 +26164,8 @@ msgstr "нераспознанный параметр Snowball: \"%s\"" msgid "missing Language parameter" msgstr "отсутствует параметр Language" -#: statistics/attribute_stats.c:192 statistics/attribute_stats.c:937 -#: statistics/relation_stats.c:98 +#: statistics/attribute_stats.c:192 statistics/attribute_stats.c:963 +#: statistics/relation_stats.c:100 #, c-format msgid "Statistics cannot be modified during recovery." msgstr "Статистика не может меняться в режиме восстановления." @@ -26114,17 +26206,31 @@ msgstr "не удалось определить оператор «меньше msgid "column \"%s\" is not a range type" msgstr "столбец \"%s\" не диапазонного типа" -#: statistics/attribute_stats.c:738 +#: statistics/attribute_stats.c:396 +#, c-format +msgid "" +"could not parse \"%s\": incorrect number of elements (same as \"%s\" " +"required)" +msgstr "" +"не удалось разобрать \"%s\": число элементов должно совпадать с числом " +"элементов в \"%s\"" + +#: statistics/attribute_stats.c:755 +#, c-format +msgid "\"%s\" must be a one-dimensional array" +msgstr "значение \"%s\" должно быть одномерным массивом" + +#: statistics/attribute_stats.c:764 #, c-format msgid "\"%s\" array must not contain null values" msgstr "массив \"%s\" не должен содержать значения NULL" -#: statistics/attribute_stats.c:781 +#: statistics/attribute_stats.c:807 #, c-format msgid "maximum number of statistics slots exceeded: %d" msgstr "превышен предел числа слотов статистики: %d" -#: statistics/attribute_stats.c:949 +#: statistics/attribute_stats.c:975 #, c-format msgid "cannot clear statistics on system column \"%s\"" msgstr "очистить статистику для системного столбца \"%s\" нельзя" @@ -26143,7 +26249,12 @@ msgid "" msgstr "" "функция, возвращающая запись, вызвана в контексте, не допускающем этот тип" -#: statistics/relation_stats.c:117 +#: statistics/relation_stats.c:119 +#, c-format +msgid "argument \"%s\" must be a finite value" +msgstr "аргумент \"%s\" должен быть конечным значением" + +#: statistics/relation_stats.c:126 #, c-format msgid "argument \"%s\" must not be less than -1.0" msgstr "аргумент \"%s\" не должен быть меньше -1.0" @@ -26257,22 +26368,24 @@ msgstr "завершение ввода/вывода за процесс %d" msgid "I/O worker executing I/O on behalf of process %d" msgstr "обработчик ввода/вывода, выполняющий ввод/вывод за процесс %d" -#: storage/buffer/bufmgr.c:662 storage/buffer/bufmgr.c:818 +#: storage/aio/read_stream.c:566 storage/buffer/bufmgr.c:662 +#: storage/buffer/bufmgr.c:1204 storage/buffer/bufmgr.c:1284 +#: storage/buffer/bufmgr.c:2600 #, c-format msgid "cannot access temporary tables of other sessions" msgstr "обращаться к временным таблицам других сеансов нельзя" -#: storage/buffer/bufmgr.c:2703 storage/buffer/localbuf.c:393 +#: storage/buffer/bufmgr.c:2726 storage/buffer/localbuf.c:393 #, c-format msgid "cannot extend relation %s beyond %u blocks" msgstr "не удалось увеличить отношение \"%s\" до блока %u" -#: storage/buffer/bufmgr.c:2774 +#: storage/buffer/bufmgr.c:2797 #, c-format msgid "unexpected data beyond EOF in block %u of relation \"%s\"" msgstr "неожиданные данные после EOF в блоке %u отношения \"%s\"" -#: storage/buffer/bufmgr.c:2777 +#: storage/buffer/bufmgr.c:2800 #, c-format msgid "" "This has been seen to occur with buggy kernels; consider updating your " @@ -26281,22 +26394,22 @@ msgstr "" "Эта ситуация может возникать из-за ошибок в ядре; возможно, вам следует " "обновить ОС." -#: storage/buffer/bufmgr.c:6178 +#: storage/buffer/bufmgr.c:6201 #, c-format msgid "could not write block %u of %s" msgstr "не удалось запись блок %u файла %s" -#: storage/buffer/bufmgr.c:6182 +#: storage/buffer/bufmgr.c:6205 #, c-format msgid "Multiple failures --- write error might be permanent." msgstr "Множественные сбои - возможно, постоянная ошибка записи." -#: storage/buffer/bufmgr.c:6199 storage/buffer/bufmgr.c:6214 +#: storage/buffer/bufmgr.c:6222 storage/buffer/bufmgr.c:6237 #, c-format msgid "writing block %u of relation \"%s\"" msgstr "запись блока %u отношения \"%s\"" -#: storage/buffer/bufmgr.c:7317 +#: storage/buffer/bufmgr.c:7340 #, c-format msgid "" "zeroing %u page(s) and ignoring %u checksum failure(s) among blocks %u..%u " @@ -26305,12 +26418,12 @@ msgstr "" "обнуление %u страниц без реакции на ошибки контрольных сумм (%u) в блоках " "%u..%u отношения \"%s\"" -#: storage/buffer/bufmgr.c:7320 storage/buffer/bufmgr.c:7348 +#: storage/buffer/bufmgr.c:7343 storage/buffer/bufmgr.c:7371 #, c-format msgid "Block %u held the first zeroed page." msgstr "Первую обнулённую страницу содержал блок %u." -#: storage/buffer/bufmgr.c:7322 +#: storage/buffer/bufmgr.c:7345 #, c-format msgid "See server log for details about the other %d invalid block." msgid_plural "See server log for details about the other %d invalid blocks." @@ -26323,55 +26436,55 @@ msgstr[1] "" msgstr[2] "" "Подробные сведения о ещё %d некорректных блоках найти в протоколе сервера." -#: storage/buffer/bufmgr.c:7339 +#: storage/buffer/bufmgr.c:7362 #, c-format msgid "%u invalid pages among blocks %u..%u of relation \"%s\"" msgstr "%u некорректных страниц в блоках %u..%u отношения \"%s\"" -#: storage/buffer/bufmgr.c:7340 +#: storage/buffer/bufmgr.c:7363 #, c-format msgid "Block %u held the first invalid page." msgstr "Первую некорректную страницу содержал блок %u." -#: storage/buffer/bufmgr.c:7341 +#: storage/buffer/bufmgr.c:7364 #, c-format msgid "See server log for the other %u invalid block(s)." msgstr "" "Сведения об остальных %u некорректных блоках можно найти в протоколе сервера." -#: storage/buffer/bufmgr.c:7346 +#: storage/buffer/bufmgr.c:7369 #, c-format msgid "invalid page in block %u of relation \"%s\"; zeroing out page" msgstr "некорректная страница в блоке %u отношения \"%s\"; страница обнуляется" -#: storage/buffer/bufmgr.c:7347 +#: storage/buffer/bufmgr.c:7370 #, c-format msgid "zeroing out %u invalid pages among blocks %u..%u of relation \"%s\"" msgstr "обнуление %u некорректных страниц в блоках %u..%u отношения \"%s\"" -#: storage/buffer/bufmgr.c:7349 +#: storage/buffer/bufmgr.c:7372 #, c-format msgid "See server log for the other %u zeroed block(s)." msgstr "" "Сведения об остальных %u обнулённых блоках можно найти в протоколе сервера." -#: storage/buffer/bufmgr.c:7354 +#: storage/buffer/bufmgr.c:7377 #, c-format msgid "ignoring checksum failure in block %u of relation \"%s\"" msgstr "ошибка контрольной суммы в блоке %u отношения \"%s\" игнорируется" -#: storage/buffer/bufmgr.c:7355 +#: storage/buffer/bufmgr.c:7378 #, c-format msgid "ignoring %u checksum failures among blocks %u..%u of relation \"%s\"" msgstr "" "%u ошибок контрольных сумм в блоках %u..%u отношения \"%s\" игнорируются" -#: storage/buffer/bufmgr.c:7356 +#: storage/buffer/bufmgr.c:7379 #, c-format msgid "Block %u held the first ignored page." msgstr "Первую игнорируемую некорректную страницу содержал блок %u." -#: storage/buffer/bufmgr.c:7357 +#: storage/buffer/bufmgr.c:7380 #, c-format msgid "See server log for the other %u ignored block(s)." msgstr "" @@ -26566,12 +26679,12 @@ msgstr "" msgid "\"%s\" is not supported on this platform." msgstr "\"%s\" не поддерживается на этой платформе." -#: storage/file/fd.c:4030 tcop/backend_startup.c:1080 +#: storage/file/fd.c:4030 tcop/backend_startup.c:1099 #, c-format msgid "Invalid list syntax in parameter \"%s\"." msgstr "Неверный формат списка в параметре \"%s\"." -#: storage/file/fd.c:4050 tcop/backend_startup.c:1054 +#: storage/file/fd.c:4050 tcop/backend_startup.c:1073 #, c-format msgid "Invalid option \"%s\"." msgstr "Неверный параметр \"%s\"." @@ -26739,24 +26852,24 @@ msgstr "" "Только роли с правами роли, которой принадлежит процесс, или с правами роли " "\"%s\" могут завершить этот процесс." -#: storage/ipc/procsignal.c:452 +#: storage/ipc/procsignal.c:460 #, c-format msgid "still waiting for backend with PID %d to accept ProcSignalBarrier" msgstr "" "продолжается ожидание получения сигнала ProcSignalBarrier обслуживающим " "процессом с PID %d" -#: storage/ipc/procsignal.c:737 +#: storage/ipc/procsignal.c:745 #, c-format msgid "invalid cancel request with PID 0" msgstr "неправильный запрос отмены с PID 0" -#: storage/ipc/procsignal.c:792 +#: storage/ipc/procsignal.c:800 #, c-format msgid "wrong key in cancel request for process %d" msgstr "неправильный ключ в запросе на отмену процесса %d" -#: storage/ipc/procsignal.c:801 +#: storage/ipc/procsignal.c:809 #, c-format msgid "PID %d in cancel request did not match any process" msgstr "процесс с кодом %d, полученным в запросе на отмену, не найден" @@ -26809,17 +26922,12 @@ msgstr "" "недостаточно разделяемой памяти для структуры данных \"%s\" (требовалось " "байт: %zu)" -#: storage/ipc/shmem.c:502 storage/ipc/shmem.c:521 -#, c-format -msgid "requested shared memory size overflows size_t" -msgstr "запрошенный размер разделяемой памяти не умещается в size_t" - #: storage/ipc/signalfuncs.c:74 #, c-format msgid "PID %d is not a PostgreSQL backend process" msgstr "PID %d не относится к обслуживающему процессу PostgreSQL" -#: storage/ipc/signalfuncs.c:123 storage/lmgr/proc.c:1546 +#: storage/ipc/signalfuncs.c:123 storage/lmgr/proc.c:1579 #: utils/adt/mcxtfuncs.c:302 #, c-format msgid "could not send signal to process %d: %m" @@ -27215,7 +27323,7 @@ msgstr "" "число запрошенных подключений резервных серверов превышает " "\"max_wal_senders\" (сейчас: %d)" -#: storage/lmgr/proc.c:1591 +#: storage/lmgr/proc.c:1624 #, c-format msgid "" "process %d avoided deadlock for %s on %s by rearranging queue order after " @@ -27224,7 +27332,7 @@ msgstr "" "процесс %d избежал взаимоблокировки, ожидая в режиме %s блокировку \"%s\", " "изменив порядок очереди через %ld.%03d мс" -#: storage/lmgr/proc.c:1606 +#: storage/lmgr/proc.c:1639 #, c-format msgid "" "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" @@ -27232,19 +27340,19 @@ msgstr "" "процесс %d обнаружил взаимоблокировку, ожидая в режиме %s блокировку \"%s\" " "в течение %ld.%03d мс" -#: storage/lmgr/proc.c:1615 +#: storage/lmgr/proc.c:1648 #, c-format msgid "process %d still waiting for %s on %s after %ld.%03d ms" msgstr "" "процесс %d продолжает ожидать в режиме %s блокировку \"%s\" в течение %ld." "%03d мс" -#: storage/lmgr/proc.c:1622 +#: storage/lmgr/proc.c:1655 #, c-format msgid "process %d acquired %s on %s after %ld.%03d ms" msgstr "процесс %d получил в режиме %s блокировку \"%s\" через %ld.%03d мс" -#: storage/lmgr/proc.c:1639 +#: storage/lmgr/proc.c:1672 #, c-format msgid "process %d failed to acquire %s on %s after %ld.%03d ms" msgstr "" @@ -27443,37 +27551,37 @@ msgstr "запрос прямого SSL-соединения принят" msgid "direct SSL connection rejected" msgstr "запрос прямого SSL-соединения отвергнут" -#: tcop/backend_startup.c:528 tcop/backend_startup.c:556 +#: tcop/backend_startup.c:529 tcop/backend_startup.c:557 #, c-format msgid "incomplete startup packet" msgstr "неполный стартовый пакет" -#: tcop/backend_startup.c:540 +#: tcop/backend_startup.c:541 #, c-format msgid "invalid length of startup packet" msgstr "неверная длина стартового пакета" -#: tcop/backend_startup.c:597 +#: tcop/backend_startup.c:598 #, c-format msgid "SSLRequest accepted" msgstr "SSLRequest принят" -#: tcop/backend_startup.c:600 +#: tcop/backend_startup.c:601 #, c-format msgid "SSLRequest rejected" msgstr "SSLRequest отвергнут" -#: tcop/backend_startup.c:609 +#: tcop/backend_startup.c:610 #, c-format msgid "failed to send SSL negotiation response: %m" msgstr "не удалось отправить ответ в процессе SSL-согласования: %m" -#: tcop/backend_startup.c:627 +#: tcop/backend_startup.c:628 #, c-format msgid "received unencrypted data after SSL request" msgstr "после запроса SSL получены незашифрованные данные" -#: tcop/backend_startup.c:628 tcop/backend_startup.c:682 +#: tcop/backend_startup.c:629 tcop/backend_startup.c:692 #, c-format msgid "" "This could be either a client-software bug or evidence of an attempted man-" @@ -27482,60 +27590,60 @@ msgstr "" "Это может свидетельствовать об ошибке в клиентском ПО или о попытке атаки " "MITM." -#: tcop/backend_startup.c:651 +#: tcop/backend_startup.c:661 #, c-format msgid "GSSENCRequest accepted" msgstr "GSSENCRequest принят" -#: tcop/backend_startup.c:654 +#: tcop/backend_startup.c:664 #, c-format msgid "GSSENCRequest rejected" msgstr "GSSENCRequest отвергнут" -#: tcop/backend_startup.c:663 +#: tcop/backend_startup.c:673 #, c-format msgid "failed to send GSSAPI negotiation response: %m" msgstr "не удалось отправить ответ в процессе согласования GSSAPI: %m" -#: tcop/backend_startup.c:681 +#: tcop/backend_startup.c:691 #, c-format msgid "received unencrypted data after GSSAPI encryption request" msgstr "после запроса шифрования GSSAPI получены незашифрованные данные" -#: tcop/backend_startup.c:709 +#: tcop/backend_startup.c:728 #, c-format msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" msgstr "" "неподдерживаемый протокол клиентского приложения %u.%u; сервер поддерживает " "%u.0 - %u.%u" -#: tcop/backend_startup.c:772 +#: tcop/backend_startup.c:791 #, c-format msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." msgstr "Допустимые значения: \"false\", 0, \"true\", 1, \"database\"." -#: tcop/backend_startup.c:813 +#: tcop/backend_startup.c:832 #, c-format msgid "invalid startup packet layout: expected terminator as last byte" msgstr "" "неверная структура стартового пакета: последним байтом должен быть терминатор" -#: tcop/backend_startup.c:830 +#: tcop/backend_startup.c:849 #, c-format msgid "no PostgreSQL user name specified in startup packet" msgstr "в стартовом пакете не указано имя пользователя PostgreSQL" -#: tcop/backend_startup.c:884 +#: tcop/backend_startup.c:903 #, c-format msgid "invalid length of cancel request packet" msgstr "неверная длина пакета отмены запроса" -#: tcop/backend_startup.c:892 +#: tcop/backend_startup.c:911 #, c-format msgid "invalid length of cancel key in cancel request packet" msgstr "неверная длина ключа отмены в пакете отмены запроса" -#: tcop/backend_startup.c:1022 +#: tcop/backend_startup.c:1041 #, c-format msgid "" "Cannot specify log_connections option \"%s\" in a list with other options." @@ -28049,17 +28157,17 @@ msgstr "повторяющийся параметр Accept" msgid "unrecognized simple dictionary parameter: \"%s\"" msgstr "нераспознанный параметр словаря simple: \"%s\"" -#: tsearch/dict_synonym.c:120 +#: tsearch/dict_synonym.c:119 #, c-format msgid "unrecognized synonym parameter: \"%s\"" msgstr "нераспознанный параметр функции синонимов: \"%s\"" -#: tsearch/dict_synonym.c:127 +#: tsearch/dict_synonym.c:126 #, c-format msgid "missing Synonyms parameter" msgstr "отсутствует параметр Synonyms" -#: tsearch/dict_synonym.c:134 +#: tsearch/dict_synonym.c:133 #, c-format msgid "could not open synonym file \"%s\": %m" msgstr "не удалось открыть файл синонимов \"%s\": %m" @@ -28175,18 +28283,18 @@ msgstr "неверное регулярное выражение: %s" msgid "syntax error" msgstr "ошибка синтаксиса" -#: tsearch/spell.c:1182 tsearch/spell.c:1194 tsearch/spell.c:1758 -#: tsearch/spell.c:1763 tsearch/spell.c:1768 +#: tsearch/spell.c:1182 tsearch/spell.c:1189 tsearch/spell.c:1200 +#: tsearch/spell.c:1773 tsearch/spell.c:1778 tsearch/spell.c:1783 #, c-format msgid "invalid affix alias \"%s\"" msgstr "неверное указание аффикса \"%s\"" -#: tsearch/spell.c:1235 tsearch/spell.c:1306 tsearch/spell.c:1455 +#: tsearch/spell.c:1241 tsearch/spell.c:1312 tsearch/spell.c:1470 #, c-format msgid "could not open affix file \"%s\": %m" msgstr "не удалось открыть файл аффиксов \"%s\": %m" -#: tsearch/spell.c:1289 +#: tsearch/spell.c:1295 #, c-format msgid "" "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag " @@ -28195,22 +28303,27 @@ msgstr "" "словарь Ispell поддерживает для флага только значения \"default\", \"long\" " "и \"num\"" -#: tsearch/spell.c:1333 +#: tsearch/spell.c:1339 #, c-format msgid "invalid number of flag vector aliases" msgstr "неверное количество векторов флагов" -#: tsearch/spell.c:1356 +#: tsearch/spell.c:1362 #, c-format msgid "number of aliases exceeds specified number %d" msgstr "количество псевдонимов превышает заданное число %d" -#: tsearch/spell.c:1570 +#: tsearch/spell.c:1436 +#, c-format +msgid "number of aliases is less than specified number %d" +msgstr "количество псевдонимов меньше заданного числа %d" + +#: tsearch/spell.c:1585 #, c-format msgid "affix file contains both old-style and new-style commands" msgstr "файл аффиксов содержит команды и в старом, и в новом стиле" -#: tsearch/to_tsany.c:194 utils/adt/tsvector.c:274 utils/adt/tsvector_op.c:1126 +#: tsearch/to_tsany.c:194 utils/adt/tsvector.c:274 utils/adt/tsvector_op.c:1099 #, c-format msgid "string is too long for tsvector (%d bytes, max %d bytes)" msgstr "строка слишком длинна для tsvector (%d Б, при максимуме %d)" @@ -28247,26 +28360,32 @@ msgstr "не удалось открыть файл стоп-слов \"%s\": %m msgid "text search parser does not support headline creation" msgstr "анализатор текстового поиска не поддерживает создание выдержек" -#: tsearch/wparser_def.c:2665 +#: tsearch/wparser_def.c:2668 #, c-format msgid "unrecognized headline parameter: \"%s\"" msgstr "нераспознанный параметр функции выдержки: \"%s\"" -#: tsearch/wparser_def.c:2675 +#: tsearch/wparser_def.c:2678 #, c-format msgid "%s must be less than %s" msgstr "%s должно быть меньше %s" -#: tsearch/wparser_def.c:2679 +#: tsearch/wparser_def.c:2682 #, c-format msgid "%s must be positive" msgstr "%s должно быть больше нуля" -#: tsearch/wparser_def.c:2683 tsearch/wparser_def.c:2687 +#: tsearch/wparser_def.c:2686 tsearch/wparser_def.c:2690 #, c-format msgid "%s must be >= 0" msgstr "%s должно быть >= 0" +#: tsearch/wparser_def.c:2729 tsearch/wparser_def.c:2733 +#: tsearch/wparser_def.c:2737 +#, c-format +msgid "value for \"%s\" is too long" +msgstr "значение для \"%s\" слишком длинное" + #: utils/activity/pgstat.c:534 #, c-format msgid "could not unlink permanent statistics file \"%s\": %m" @@ -28524,7 +28643,7 @@ msgstr "тип входных данных не является массиво #: utils/adt/int.c:1054 utils/adt/int.c:1087 utils/adt/int.c:1101 #: utils/adt/int.c:1115 utils/adt/int.c:1146 utils/adt/int.c:1228 #: utils/adt/int.c:1292 utils/adt/int.c:1360 utils/adt/int.c:1366 -#: utils/adt/int8.c:1256 utils/adt/numeric.c:2040 utils/adt/numeric.c:4558 +#: utils/adt/int8.c:1286 utils/adt/numeric.c:2046 utils/adt/numeric.c:4564 #: utils/adt/rangetypes.c:1552 utils/adt/rangetypes.c:1565 #: utils/adt/varbit.c:1195 utils/adt/varbit.c:1596 utils/adt/varlena.c:1186 #: utils/adt/varlena.c:3240 utils/adt/varlena.c:4174 @@ -28568,12 +28687,12 @@ msgid "Arrays with differing dimensions are not compatible for concatenation." msgstr "Массивы с разными размерностями несовместимы для соединения." #: utils/adt/array_userfuncs.c:1053 utils/adt/array_userfuncs.c:1061 -#: utils/adt/arrayfuncs.c:5634 utils/adt/arrayfuncs.c:5640 +#: utils/adt/arrayfuncs.c:5643 utils/adt/arrayfuncs.c:5649 #, c-format msgid "cannot accumulate arrays of different dimensionality" msgstr "аккумулировать массивы различной размерности нельзя" -#: utils/adt/array_userfuncs.c:1073 +#: utils/adt/array_userfuncs.c:1073 utils/adt/arrayfuncs.c:5605 #, c-format msgid "array size exceeds the maximum allowed (%zu)" msgstr "размер массива превышает предел (%zu)" @@ -28693,7 +28812,7 @@ msgid "Unexpected end of input." msgstr "Неожиданный конец ввода." #: utils/adt/arrayfuncs.c:1301 utils/adt/arrayfuncs.c:3511 -#: utils/adt/arrayfuncs.c:6126 +#: utils/adt/arrayfuncs.c:6133 #, c-format msgid "invalid number of dimensions: %d" msgstr "неверное число размерностей: %d" @@ -28710,8 +28829,8 @@ msgstr "" "с бинарными данными связан тип элемента массива %u (%s) вместо ожидаемого %u " "(%s)" -#: utils/adt/arrayfuncs.c:1378 utils/adt/multirangetypes.c:450 -#: utils/adt/rangetypes.c:353 utils/cache/lsyscache.c:3136 +#: utils/adt/arrayfuncs.c:1378 utils/adt/multirangetypes.c:451 +#: utils/adt/rangetypes.c:353 utils/cache/lsyscache.c:3260 #, c-format msgid "no binary input function available for type %s" msgstr "для типа %s нет функции ввода двоичных данных" @@ -28721,8 +28840,8 @@ msgstr "для типа %s нет функции ввода двоичных д msgid "improper binary format in array element %d" msgstr "неподходящий двоичный формат в элементе массива %d" -#: utils/adt/arrayfuncs.c:1588 utils/adt/multirangetypes.c:455 -#: utils/adt/rangetypes.c:358 utils/cache/lsyscache.c:3169 +#: utils/adt/arrayfuncs.c:1588 utils/adt/multirangetypes.c:456 +#: utils/adt/rangetypes.c:358 utils/cache/lsyscache.c:3293 #, c-format msgid "no binary output function available for type %s" msgstr "для типа %s нет функции вывода двоичных данных" @@ -28734,8 +28853,8 @@ msgstr "разрезание массивов постоянной длины н #: utils/adt/arrayfuncs.c:2245 utils/adt/arrayfuncs.c:2267 #: utils/adt/arrayfuncs.c:2316 utils/adt/arrayfuncs.c:2570 -#: utils/adt/arrayfuncs.c:2915 utils/adt/arrayfuncs.c:6112 -#: utils/adt/arrayfuncs.c:6138 utils/adt/arrayfuncs.c:6149 +#: utils/adt/arrayfuncs.c:2915 utils/adt/arrayfuncs.c:6119 +#: utils/adt/arrayfuncs.c:6145 utils/adt/arrayfuncs.c:6156 #: utils/adt/json.c:1441 utils/adt/json.c:1509 utils/adt/jsonb.c:1317 #: utils/adt/jsonb.c:1401 utils/adt/jsonfuncs.c:4734 utils/adt/jsonfuncs.c:4887 #: utils/adt/jsonfuncs.c:4998 utils/adt/jsonfuncs.c:5046 @@ -28789,8 +28908,8 @@ msgstr "элемент массива null недопустим в данном msgid "cannot compare arrays of different element types" msgstr "нельзя сравнивать массивы с элементами разных типов" -#: utils/adt/arrayfuncs.c:4195 utils/adt/multirangetypes.c:2806 -#: utils/adt/multirangetypes.c:2878 utils/adt/rangetypes.c:1425 +#: utils/adt/arrayfuncs.c:4195 utils/adt/multirangetypes.c:2807 +#: utils/adt/multirangetypes.c:2879 utils/adt/rangetypes.c:1425 #: utils/adt/rangetypes.c:1489 utils/adt/rowtypes.c:1893 #, c-format msgid "could not identify a hash function for type %s" @@ -28806,52 +28925,52 @@ msgstr "не удалось найти функцию расширенного msgid "data type %s is not an array type" msgstr "тип данных %s не является типом массива" -#: utils/adt/arrayfuncs.c:5579 +#: utils/adt/arrayfuncs.c:5580 #, c-format msgid "cannot accumulate null arrays" msgstr "аккумулировать NULL-массивы нельзя" -#: utils/adt/arrayfuncs.c:5607 +#: utils/adt/arrayfuncs.c:5616 #, c-format msgid "cannot accumulate empty arrays" msgstr "аккумулировать пустые массивы нельзя" -#: utils/adt/arrayfuncs.c:6010 utils/adt/arrayfuncs.c:6050 +#: utils/adt/arrayfuncs.c:6017 utils/adt/arrayfuncs.c:6057 #, c-format msgid "dimension array or low bound array cannot be null" msgstr "массив размерностей или массив нижних границ не может быть null" -#: utils/adt/arrayfuncs.c:6113 utils/adt/arrayfuncs.c:6139 +#: utils/adt/arrayfuncs.c:6120 utils/adt/arrayfuncs.c:6146 #, c-format msgid "Dimension array must be one dimensional." msgstr "Массив размерностей должен быть одномерным." -#: utils/adt/arrayfuncs.c:6118 utils/adt/arrayfuncs.c:6144 +#: utils/adt/arrayfuncs.c:6125 utils/adt/arrayfuncs.c:6151 #, c-format msgid "dimension values cannot be null" msgstr "значения размерностей не могут быть null" -#: utils/adt/arrayfuncs.c:6150 +#: utils/adt/arrayfuncs.c:6157 #, c-format msgid "Low bound array has different size than dimensions array." msgstr "Массив нижних границ и массив размерностей имеют разные размеры." -#: utils/adt/arrayfuncs.c:6431 +#: utils/adt/arrayfuncs.c:6438 #, c-format msgid "removing elements from multidimensional arrays is not supported" msgstr "удаление элементов из многомерных массивов не поддерживается" -#: utils/adt/arrayfuncs.c:6708 +#: utils/adt/arrayfuncs.c:6715 #, c-format msgid "thresholds must be one-dimensional array" msgstr "границы должны задаваться одномерным массивом" -#: utils/adt/arrayfuncs.c:6713 +#: utils/adt/arrayfuncs.c:6720 #, c-format msgid "thresholds array must not contain NULLs" msgstr "массив границ не должен содержать NULL" -#: utils/adt/arrayfuncs.c:6946 +#: utils/adt/arrayfuncs.c:6953 #, c-format msgid "number of elements to trim must be between 0 and %d" msgstr "число удаляемых элементов должно быть от 0 до %d" @@ -28892,7 +29011,7 @@ msgid "encoding conversion from %s to ASCII not supported" msgstr "преобразование кодировки из %s в ASCII не поддерживается" #. translator: first %s is inet or cidr -#: utils/adt/bool.c:150 utils/adt/cash.c:354 utils/adt/datetime.c:4264 +#: utils/adt/bool.c:150 utils/adt/cash.c:370 utils/adt/datetime.c:4264 #: utils/adt/float.c:207 utils/adt/float.c:294 utils/adt/float.c:308 #: utils/adt/float.c:413 utils/adt/float.c:496 utils/adt/float.c:510 #: utils/adt/geo_ops.c:250 utils/adt/geo_ops.c:335 utils/adt/geo_ops.c:974 @@ -28900,38 +29019,38 @@ msgstr "преобразование кодировки из %s в ASCII не п #: utils/adt/geo_ops.c:3428 utils/adt/geo_ops.c:4650 utils/adt/geo_ops.c:4665 #: utils/adt/geo_ops.c:4672 utils/adt/int.c:198 utils/adt/int.c:210 #: utils/adt/jsonpath.c:185 utils/adt/mac.c:94 utils/adt/mac8.c:226 -#: utils/adt/network.c:99 utils/adt/numeric.c:805 utils/adt/numeric.c:7325 -#: utils/adt/numeric.c:7528 utils/adt/numeric.c:8475 utils/adt/numutils.c:356 +#: utils/adt/network.c:99 utils/adt/numeric.c:805 utils/adt/numeric.c:7331 +#: utils/adt/numeric.c:7534 utils/adt/numeric.c:8481 utils/adt/numutils.c:356 #: utils/adt/numutils.c:617 utils/adt/numutils.c:878 utils/adt/numutils.c:917 #: utils/adt/numutils.c:939 utils/adt/numutils.c:1003 utils/adt/numutils.c:1025 #: utils/adt/pg_lsn.c:73 utils/adt/tid.c:72 utils/adt/tid.c:80 #: utils/adt/tid.c:94 utils/adt/tid.c:103 utils/adt/timestamp.c:512 -#: utils/adt/uuid.c:176 utils/adt/xid8funcs.c:323 +#: utils/adt/uuid.c:193 utils/adt/xid8funcs.c:323 #, c-format msgid "invalid input syntax for type %s: \"%s\"" msgstr "неверный синтаксис для типа %s: \"%s\"" #: utils/adt/cash.c:98 utils/adt/cash.c:111 utils/adt/cash.c:124 -#: utils/adt/cash.c:137 utils/adt/cash.c:150 +#: utils/adt/cash.c:137 utils/adt/cash.c:150 utils/adt/cash.c:174 #, c-format msgid "money out of range" msgstr "денежное значение вне диапазона" -#: utils/adt/cash.c:161 utils/adt/cash.c:725 utils/adt/float.c:106 +#: utils/adt/cash.c:161 utils/adt/cash.c:741 utils/adt/float.c:106 #: utils/adt/int.c:872 utils/adt/int.c:988 utils/adt/int.c:1068 #: utils/adt/int.c:1130 utils/adt/int.c:1168 utils/adt/int.c:1196 -#: utils/adt/int8.c:514 utils/adt/int8.c:572 utils/adt/int8.c:942 -#: utils/adt/int8.c:1022 utils/adt/int8.c:1084 utils/adt/int8.c:1164 -#: utils/adt/numeric.c:3295 utils/adt/numeric.c:3318 utils/adt/numeric.c:3403 -#: utils/adt/numeric.c:3421 utils/adt/numeric.c:3517 utils/adt/numeric.c:9400 -#: utils/adt/numeric.c:9924 utils/adt/numeric.c:10040 utils/adt/numeric.c:11551 -#: utils/adt/timestamp.c:3772 +#: utils/adt/int8.c:514 utils/adt/int8.c:572 utils/adt/int8.c:972 +#: utils/adt/int8.c:1052 utils/adt/int8.c:1114 utils/adt/int8.c:1194 +#: utils/adt/numeric.c:3301 utils/adt/numeric.c:3324 utils/adt/numeric.c:3409 +#: utils/adt/numeric.c:3427 utils/adt/numeric.c:3523 utils/adt/numeric.c:9406 +#: utils/adt/numeric.c:9930 utils/adt/numeric.c:10046 utils/adt/numeric.c:11557 +#: utils/adt/timestamp.c:3776 #, c-format msgid "division by zero" msgstr "деление на ноль" -#: utils/adt/cash.c:292 utils/adt/cash.c:317 utils/adt/cash.c:327 -#: utils/adt/cash.c:367 utils/adt/int.c:204 utils/adt/numutils.c:350 +#: utils/adt/cash.c:308 utils/adt/cash.c:333 utils/adt/cash.c:343 +#: utils/adt/cash.c:383 utils/adt/int.c:204 utils/adt/numutils.c:350 #: utils/adt/numutils.c:611 utils/adt/numutils.c:872 utils/adt/numutils.c:923 #: utils/adt/numutils.c:962 utils/adt/numutils.c:1009 #, c-format @@ -28999,22 +29118,22 @@ msgid "date out of range for timestamp" msgstr "дата вне диапазона для типа timestamp" #: utils/adt/date.c:1187 utils/adt/date.c:1270 utils/adt/date.c:1286 -#: utils/adt/date.c:2280 utils/adt/date.c:3076 utils/adt/timestamp.c:4724 -#: utils/adt/timestamp.c:4815 utils/adt/timestamp.c:4963 -#: utils/adt/timestamp.c:5064 utils/adt/timestamp.c:5179 -#: utils/adt/timestamp.c:5231 utils/adt/timestamp.c:5488 -#: utils/adt/timestamp.c:5689 utils/adt/timestamp.c:5736 -#: utils/adt/timestamp.c:5960 utils/adt/timestamp.c:6007 -#: utils/adt/timestamp.c:6088 utils/adt/timestamp.c:6232 +#: utils/adt/date.c:2280 utils/adt/date.c:3076 utils/adt/timestamp.c:4728 +#: utils/adt/timestamp.c:4819 utils/adt/timestamp.c:4967 +#: utils/adt/timestamp.c:5068 utils/adt/timestamp.c:5183 +#: utils/adt/timestamp.c:5235 utils/adt/timestamp.c:5492 +#: utils/adt/timestamp.c:5693 utils/adt/timestamp.c:5740 +#: utils/adt/timestamp.c:5964 utils/adt/timestamp.c:6011 +#: utils/adt/timestamp.c:6092 utils/adt/timestamp.c:6236 #, c-format msgid "unit \"%s\" not supported for type %s" msgstr "единица \"%s\" для типа %s не поддерживается" #: utils/adt/date.c:1295 utils/adt/date.c:2296 utils/adt/date.c:3096 -#: utils/adt/timestamp.c:4829 utils/adt/timestamp.c:5081 -#: utils/adt/timestamp.c:5245 utils/adt/timestamp.c:5448 -#: utils/adt/timestamp.c:5745 utils/adt/timestamp.c:6016 -#: utils/adt/timestamp.c:6057 utils/adt/timestamp.c:6293 +#: utils/adt/timestamp.c:4833 utils/adt/timestamp.c:5085 +#: utils/adt/timestamp.c:5249 utils/adt/timestamp.c:5452 +#: utils/adt/timestamp.c:5749 utils/adt/timestamp.c:6020 +#: utils/adt/timestamp.c:6061 utils/adt/timestamp.c:6297 #, c-format msgid "unit \"%s\" not recognized for type %s" msgstr "единица \"%s\" для типа %s не распознана" @@ -29027,27 +29146,27 @@ msgstr "единица \"%s\" для типа %s не распознана" #: utils/adt/json.c:414 utils/adt/timestamp.c:250 utils/adt/timestamp.c:282 #: utils/adt/timestamp.c:707 utils/adt/timestamp.c:716 #: utils/adt/timestamp.c:794 utils/adt/timestamp.c:827 -#: utils/adt/timestamp.c:3125 utils/adt/timestamp.c:3134 -#: utils/adt/timestamp.c:3151 utils/adt/timestamp.c:3156 -#: utils/adt/timestamp.c:3175 utils/adt/timestamp.c:3188 -#: utils/adt/timestamp.c:3199 utils/adt/timestamp.c:3205 -#: utils/adt/timestamp.c:3211 utils/adt/timestamp.c:3216 -#: utils/adt/timestamp.c:3269 utils/adt/timestamp.c:3278 -#: utils/adt/timestamp.c:3299 utils/adt/timestamp.c:3304 -#: utils/adt/timestamp.c:3325 utils/adt/timestamp.c:3338 -#: utils/adt/timestamp.c:3352 utils/adt/timestamp.c:3360 -#: utils/adt/timestamp.c:3366 utils/adt/timestamp.c:3371 -#: utils/adt/timestamp.c:4439 utils/adt/timestamp.c:4591 -#: utils/adt/timestamp.c:4667 utils/adt/timestamp.c:4733 -#: utils/adt/timestamp.c:4823 utils/adt/timestamp.c:4902 -#: utils/adt/timestamp.c:4972 utils/adt/timestamp.c:5075 -#: utils/adt/timestamp.c:5553 utils/adt/timestamp.c:5827 -#: utils/adt/timestamp.c:6361 utils/adt/timestamp.c:6371 -#: utils/adt/timestamp.c:6376 utils/adt/timestamp.c:6382 -#: utils/adt/timestamp.c:6422 utils/adt/timestamp.c:6509 -#: utils/adt/timestamp.c:6550 utils/adt/timestamp.c:6554 -#: utils/adt/timestamp.c:6608 utils/adt/timestamp.c:6612 -#: utils/adt/timestamp.c:6618 utils/adt/timestamp.c:6659 utils/adt/xml.c:2575 +#: utils/adt/timestamp.c:3129 utils/adt/timestamp.c:3138 +#: utils/adt/timestamp.c:3155 utils/adt/timestamp.c:3160 +#: utils/adt/timestamp.c:3179 utils/adt/timestamp.c:3192 +#: utils/adt/timestamp.c:3203 utils/adt/timestamp.c:3209 +#: utils/adt/timestamp.c:3215 utils/adt/timestamp.c:3220 +#: utils/adt/timestamp.c:3273 utils/adt/timestamp.c:3282 +#: utils/adt/timestamp.c:3303 utils/adt/timestamp.c:3308 +#: utils/adt/timestamp.c:3329 utils/adt/timestamp.c:3342 +#: utils/adt/timestamp.c:3356 utils/adt/timestamp.c:3364 +#: utils/adt/timestamp.c:3370 utils/adt/timestamp.c:3375 +#: utils/adt/timestamp.c:4443 utils/adt/timestamp.c:4595 +#: utils/adt/timestamp.c:4671 utils/adt/timestamp.c:4737 +#: utils/adt/timestamp.c:4827 utils/adt/timestamp.c:4906 +#: utils/adt/timestamp.c:4976 utils/adt/timestamp.c:5079 +#: utils/adt/timestamp.c:5557 utils/adt/timestamp.c:5831 +#: utils/adt/timestamp.c:6365 utils/adt/timestamp.c:6375 +#: utils/adt/timestamp.c:6380 utils/adt/timestamp.c:6386 +#: utils/adt/timestamp.c:6426 utils/adt/timestamp.c:6513 +#: utils/adt/timestamp.c:6554 utils/adt/timestamp.c:6558 +#: utils/adt/timestamp.c:6612 utils/adt/timestamp.c:6616 +#: utils/adt/timestamp.c:6622 utils/adt/timestamp.c:6663 utils/adt/xml.c:2575 #: utils/adt/xml.c:2582 utils/adt/xml.c:2602 utils/adt/xml.c:2609 #, c-format msgid "timestamp out of range" @@ -29080,9 +29199,9 @@ msgstr "бесконечный интервал нельзя вычесть из #: utils/adt/date.c:2180 utils/adt/date.c:2732 utils/adt/float.c:1043 #: utils/adt/float.c:1119 utils/adt/int.c:664 utils/adt/int.c:711 -#: utils/adt/int.c:746 utils/adt/int8.c:413 utils/adt/numeric.c:2699 -#: utils/adt/timestamp.c:3869 utils/adt/timestamp.c:3906 -#: utils/adt/timestamp.c:3947 +#: utils/adt/int.c:746 utils/adt/int8.c:413 utils/adt/numeric.c:2705 +#: utils/adt/timestamp.c:3873 utils/adt/timestamp.c:3910 +#: utils/adt/timestamp.c:3951 #, c-format msgid "invalid preceding or following size in window function" msgstr "неверное смещение PRECEDING или FOLLOWING в оконной функции" @@ -29092,12 +29211,12 @@ msgstr "неверное смещение PRECEDING или FOLLOWING в окон msgid "time zone displacement out of range" msgstr "смещение часового пояса вне диапазона" -#: utils/adt/date.c:3197 utils/adt/timestamp.c:6404 utils/adt/timestamp.c:6641 +#: utils/adt/date.c:3197 utils/adt/timestamp.c:6408 utils/adt/timestamp.c:6645 #, c-format msgid "interval time zone \"%s\" must be finite" msgstr "задающий часовой пояс интервал \"%s\" должен быть конечным" -#: utils/adt/date.c:3204 utils/adt/timestamp.c:6411 utils/adt/timestamp.c:6648 +#: utils/adt/date.c:3204 utils/adt/timestamp.c:6415 utils/adt/timestamp.c:6652 #, c-format msgid "interval time zone \"%s\" must not include months or days" msgstr "" @@ -29281,35 +29400,35 @@ msgstr "\"%s\" вне диапазона для типа double precision" #: utils/adt/float.c:1254 utils/adt/float.c:1328 utils/adt/int.c:384 #: utils/adt/int.c:922 utils/adt/int.c:944 utils/adt/int.c:958 #: utils/adt/int.c:972 utils/adt/int.c:1004 utils/adt/int.c:1242 -#: utils/adt/int8.c:1277 utils/adt/numeric.c:4697 utils/adt/numeric.c:4702 +#: utils/adt/int8.c:1307 utils/adt/numeric.c:4703 utils/adt/numeric.c:4708 #: utils/adt/varlena.c:4149 #, c-format msgid "smallint out of range" msgstr "smallint вне диапазона" -#: utils/adt/float.c:1454 utils/adt/numeric.c:3813 utils/adt/numeric.c:10455 +#: utils/adt/float.c:1454 utils/adt/numeric.c:3819 utils/adt/numeric.c:10461 #, c-format msgid "cannot take square root of a negative number" msgstr "извлечь квадратный корень отрицательного числа нельзя" -#: utils/adt/float.c:1522 utils/adt/numeric.c:4101 utils/adt/numeric.c:4213 +#: utils/adt/float.c:1522 utils/adt/numeric.c:4107 utils/adt/numeric.c:4219 #, c-format msgid "zero raised to a negative power is undefined" msgstr "ноль в отрицательной степени даёт неопределённость" -#: utils/adt/float.c:1526 utils/adt/numeric.c:4105 utils/adt/numeric.c:11346 +#: utils/adt/float.c:1526 utils/adt/numeric.c:4111 utils/adt/numeric.c:11352 #, c-format msgid "a negative number raised to a non-integer power yields a complex result" msgstr "отрицательное число в дробной степени даёт комплексный результат" -#: utils/adt/float.c:1702 utils/adt/float.c:1735 utils/adt/numeric.c:4013 -#: utils/adt/numeric.c:11126 +#: utils/adt/float.c:1702 utils/adt/float.c:1735 utils/adt/numeric.c:4019 +#: utils/adt/numeric.c:11132 #, c-format msgid "cannot take logarithm of zero" msgstr "вычислить логарифм нуля нельзя" -#: utils/adt/float.c:1706 utils/adt/float.c:1739 utils/adt/numeric.c:3951 -#: utils/adt/numeric.c:4008 utils/adt/numeric.c:11130 +#: utils/adt/float.c:1706 utils/adt/float.c:1739 utils/adt/numeric.c:3957 +#: utils/adt/numeric.c:4014 utils/adt/numeric.c:11136 #, c-format msgid "cannot take logarithm of a negative number" msgstr "вычислить логарифм отрицательного числа нельзя" @@ -29323,22 +29442,22 @@ msgstr "вычислить логарифм отрицательного чис msgid "input is out of range" msgstr "введённое значение вне диапазона" -#: utils/adt/float.c:4085 utils/adt/numeric.c:1980 +#: utils/adt/float.c:4085 utils/adt/numeric.c:1986 #, c-format msgid "count must be greater than zero" msgstr "счётчик должен быть больше нуля" -#: utils/adt/float.c:4090 utils/adt/numeric.c:1991 +#: utils/adt/float.c:4090 utils/adt/numeric.c:1997 #, c-format msgid "operand, lower bound, and upper bound cannot be NaN" msgstr "операнд, нижняя и верхняя границы не могут быть NaN" -#: utils/adt/float.c:4096 utils/adt/numeric.c:1996 +#: utils/adt/float.c:4096 utils/adt/numeric.c:2002 #, c-format msgid "lower and upper bounds must be finite" msgstr "нижняя и верхняя границы должны быть конечными" -#: utils/adt/float.c:4162 utils/adt/numeric.c:2010 +#: utils/adt/float.c:4162 utils/adt/numeric.c:2016 #, c-format msgid "lower bound cannot equal upper bound" msgstr "нижняя граница не может равняться верхней" @@ -29715,8 +29834,8 @@ msgstr "массив не подходит для типа int2vector" msgid "invalid int2vector data" msgstr "неверные данные int2vector" -#: utils/adt/int.c:1558 utils/adt/int8.c:1403 utils/adt/numeric.c:1767 -#: utils/adt/timestamp.c:6708 utils/adt/timestamp.c:6794 +#: utils/adt/int.c:1558 utils/adt/int8.c:1433 utils/adt/numeric.c:1773 +#: utils/adt/timestamp.c:6712 utils/adt/timestamp.c:6798 #, c-format msgid "step size cannot equal zero" msgstr "размер шага не может быть нулевым" @@ -29725,19 +29844,19 @@ msgstr "размер шага не может быть нулевым" #: utils/adt/int8.c:499 utils/adt/int8.c:530 utils/adt/int8.c:554 #: utils/adt/int8.c:636 utils/adt/int8.c:704 utils/adt/int8.c:710 #: utils/adt/int8.c:736 utils/adt/int8.c:750 utils/adt/int8.c:774 -#: utils/adt/int8.c:787 utils/adt/int8.c:899 utils/adt/int8.c:913 -#: utils/adt/int8.c:927 utils/adt/int8.c:958 utils/adt/int8.c:980 -#: utils/adt/int8.c:994 utils/adt/int8.c:1008 utils/adt/int8.c:1041 -#: utils/adt/int8.c:1055 utils/adt/int8.c:1069 utils/adt/int8.c:1100 -#: utils/adt/int8.c:1122 utils/adt/int8.c:1136 utils/adt/int8.c:1150 -#: utils/adt/int8.c:1312 utils/adt/int8.c:1347 utils/adt/numeric.c:4646 +#: utils/adt/int8.c:787 utils/adt/int8.c:929 utils/adt/int8.c:943 +#: utils/adt/int8.c:957 utils/adt/int8.c:988 utils/adt/int8.c:1010 +#: utils/adt/int8.c:1024 utils/adt/int8.c:1038 utils/adt/int8.c:1071 +#: utils/adt/int8.c:1085 utils/adt/int8.c:1099 utils/adt/int8.c:1130 +#: utils/adt/int8.c:1152 utils/adt/int8.c:1166 utils/adt/int8.c:1180 +#: utils/adt/int8.c:1342 utils/adt/int8.c:1377 utils/adt/numeric.c:4652 #: utils/adt/rangetypes.c:1599 utils/adt/rangetypes.c:1612 #: utils/adt/varbit.c:1676 utils/adt/varlena.c:4199 #, c-format msgid "bigint out of range" msgstr "bigint вне диапазона" -#: utils/adt/int8.c:1360 +#: utils/adt/int8.c:1390 #, c-format msgid "OID out of range" msgstr "OID вне диапазона" @@ -30198,8 +30317,8 @@ msgstr "метод .%s() в jsonpath может применяться толь #: utils/adt/jsonpath_exec.c:1165 utils/adt/jsonpath_exec.c:1191 #: utils/adt/jsonpath_exec.c:1279 utils/adt/jsonpath_exec.c:1304 #: utils/adt/jsonpath_exec.c:1356 utils/adt/jsonpath_exec.c:1376 -#: utils/adt/jsonpath_exec.c:1438 utils/adt/jsonpath_exec.c:1527 -#: utils/adt/jsonpath_exec.c:1560 utils/adt/jsonpath_exec.c:1584 +#: utils/adt/jsonpath_exec.c:1438 utils/adt/jsonpath_exec.c:1516 +#: utils/adt/jsonpath_exec.c:1548 utils/adt/jsonpath_exec.c:1572 #, c-format msgid "argument \"%s\" of jsonpath item method .%s() is invalid for type %s" msgstr "аргумент \"%s\" метода элемента jsonpath .%s() не подходит для типа %s" @@ -30212,7 +30331,7 @@ msgstr "метод элемента jsonpath .%s() не принимает зн # skip-rule: space-before-period #: utils/adt/jsonpath_exec.c:1209 utils/adt/jsonpath_exec.c:1312 -#: utils/adt/jsonpath_exec.c:1454 utils/adt/jsonpath_exec.c:1592 +#: utils/adt/jsonpath_exec.c:1454 utils/adt/jsonpath_exec.c:1580 #, c-format msgid "" "jsonpath item method .%s() can only be applied to a string or numeric value" @@ -30230,20 +30349,20 @@ msgstr "" "метод .%s() в jsonpath может применяться только к булевскому, строковому или " "числовому значению" -#: utils/adt/jsonpath_exec.c:1486 +#: utils/adt/jsonpath_exec.c:1482 #, c-format msgid "" "precision of jsonpath item method .%s() is out of range for type integer" msgstr "точность в аргументе метода jsonpath .%s() вне диапазона типа integer" -#: utils/adt/jsonpath_exec.c:1500 +#: utils/adt/jsonpath_exec.c:1496 #, c-format msgid "scale of jsonpath item method .%s() is out of range for type integer" msgstr "" "масштаб в аргументе метода элемента jsonpath .%s() вне диапазона типа integer" # skip-rule: space-before-period -#: utils/adt/jsonpath_exec.c:1647 +#: utils/adt/jsonpath_exec.c:1635 #, c-format msgid "" "jsonpath item method .%s() can only be applied to a boolean, string, " @@ -30252,84 +30371,84 @@ msgstr "" "метод .%s() в jsonpath может применяться только к булевскому, строковому, " "числовому значению или к дате/времени" -#: utils/adt/jsonpath_exec.c:2136 +#: utils/adt/jsonpath_exec.c:2124 #, c-format msgid "left operand of jsonpath operator %s is not a single numeric value" msgstr "" "левый операнд оператора %s в jsonpath не является одним числовым значением" -#: utils/adt/jsonpath_exec.c:2143 +#: utils/adt/jsonpath_exec.c:2131 #, c-format msgid "right operand of jsonpath operator %s is not a single numeric value" msgstr "" "правый операнд оператора %s в jsonpath не является одним числовым значением" -#: utils/adt/jsonpath_exec.c:2211 +#: utils/adt/jsonpath_exec.c:2199 #, c-format msgid "operand of unary jsonpath operator %s is not a numeric value" msgstr "" "операнд унарного оператора %s в jsonpath не является числовым значением" # skip-rule: space-before-period -#: utils/adt/jsonpath_exec.c:2310 +#: utils/adt/jsonpath_exec.c:2298 #, c-format msgid "jsonpath item method .%s() can only be applied to a numeric value" msgstr "метод .%s() в jsonpath может применяться только к числовому значению" # skip-rule: space-before-period -#: utils/adt/jsonpath_exec.c:2356 +#: utils/adt/jsonpath_exec.c:2344 #, c-format msgid "jsonpath item method .%s() can only be applied to a string" msgstr "метод .%s() в jsonpath может применяться только к строке" -#: utils/adt/jsonpath_exec.c:2449 +#: utils/adt/jsonpath_exec.c:2437 #, c-format msgid "" "time precision of jsonpath item method .%s() is out of range for type integer" msgstr "" "точность времени в аргументе метода jsonpath .%s() вне диапазона типа integer" -#: utils/adt/jsonpath_exec.c:2483 utils/adt/jsonpath_exec.c:2489 -#: utils/adt/jsonpath_exec.c:2516 utils/adt/jsonpath_exec.c:2544 -#: utils/adt/jsonpath_exec.c:2597 utils/adt/jsonpath_exec.c:2648 -#: utils/adt/jsonpath_exec.c:2719 +#: utils/adt/jsonpath_exec.c:2471 utils/adt/jsonpath_exec.c:2477 +#: utils/adt/jsonpath_exec.c:2504 utils/adt/jsonpath_exec.c:2532 +#: utils/adt/jsonpath_exec.c:2585 utils/adt/jsonpath_exec.c:2636 +#: utils/adt/jsonpath_exec.c:2707 #, c-format msgid "%s format is not recognized: \"%s\"" msgstr "формат %s не распознан: \"%s\"" -#: utils/adt/jsonpath_exec.c:2485 +#: utils/adt/jsonpath_exec.c:2473 #, c-format msgid "Use a datetime template argument to specify the input data format." msgstr "" "Воспользуйтесь аргументом datetime для указания формата входных данных." -#: utils/adt/jsonpath_exec.c:2678 utils/adt/jsonpath_exec.c:2759 +#: utils/adt/jsonpath_exec.c:2666 utils/adt/jsonpath_exec.c:2747 #, c-format msgid "time precision of jsonpath item method .%s() is invalid" msgstr "точность времени в аргументе метода jsonpath .%s() некорректная" # skip-rule: space-before-period -#: utils/adt/jsonpath_exec.c:2839 +#: utils/adt/jsonpath_exec.c:2827 #, c-format msgid "jsonpath item method .%s() can only be applied to an object" msgstr "метод .%s() в jsonpath может применяться только к объекту" -#: utils/adt/jsonpath_exec.c:3123 +#: utils/adt/jsonpath_exec.c:3111 #, c-format msgid "could not convert value of type %s to jsonpath" msgstr "преобразовать значение типа %s в jsonpath не удалось" -#: utils/adt/jsonpath_exec.c:3157 +#: utils/adt/jsonpath_exec.c:3145 #, c-format msgid "could not find jsonpath variable \"%s\"" msgstr "не удалось найти в jsonpath переменную \"%s\"" -#: utils/adt/jsonpath_exec.c:3210 +#: utils/adt/jsonpath_exec.c:3198 #, c-format msgid "\"vars\" argument is not an object" msgstr "аргумент \"vars\" не является объектом" -#: utils/adt/jsonpath_exec.c:3211 +#: utils/adt/jsonpath_exec.c:3199 #, c-format msgid "" "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." @@ -30337,27 +30456,27 @@ msgstr "" "Параметры jsonpath должны передаваться в виде пар ключ-значение в объекте " "\"vars\"." -#: utils/adt/jsonpath_exec.c:3474 +#: utils/adt/jsonpath_exec.c:3462 #, c-format msgid "jsonpath array subscript is not a single numeric value" msgstr "индекс элемента в jsonpath не является одним числовым значением" -#: utils/adt/jsonpath_exec.c:3486 +#: utils/adt/jsonpath_exec.c:3474 #, c-format msgid "jsonpath array subscript is out of integer range" msgstr "индекс массива в jsonpath вне целочисленного диапазона" -#: utils/adt/jsonpath_exec.c:3670 +#: utils/adt/jsonpath_exec.c:3658 #, c-format msgid "cannot convert value from %s to %s without time zone usage" msgstr "значение %s нельзя преобразовать в %s без сведений о часовом поясе" -#: utils/adt/jsonpath_exec.c:3672 +#: utils/adt/jsonpath_exec.c:3660 #, c-format msgid "Use *_tz() function for time zone support." msgstr "Для передачи часового пояса используйте функцию *_tz()." -#: utils/adt/jsonpath_exec.c:3980 +#: utils/adt/jsonpath_exec.c:3968 #, c-format msgid "" "JSON path expression for column \"%s\" must return single item when no " @@ -30366,14 +30485,14 @@ msgstr "" "выражение пути JSON для столбца \"%s\" в отсутствие обёртки должно " "возвращать одиночный элемент" -#: utils/adt/jsonpath_exec.c:3982 utils/adt/jsonpath_exec.c:3987 +#: utils/adt/jsonpath_exec.c:3970 utils/adt/jsonpath_exec.c:3975 #, c-format msgid "Use the WITH WRAPPER clause to wrap SQL/JSON items into an array." msgstr "" "Используйте предложение WITH WRAPPER, чтобы обернуть элементы SQL/JSON в " "массив." -#: utils/adt/jsonpath_exec.c:3986 +#: utils/adt/jsonpath_exec.c:3974 #, c-format msgid "" "JSON path expression in JSON_QUERY must return single item when no wrapper " @@ -30382,14 +30501,14 @@ msgstr "" "выражение пути JSON в JSON_QUERY в отсутствие обёртки должно возвращать " "одиночный элемент" -#: utils/adt/jsonpath_exec.c:4044 utils/adt/jsonpath_exec.c:4068 +#: utils/adt/jsonpath_exec.c:4032 utils/adt/jsonpath_exec.c:4056 #, c-format msgid "JSON path expression for column \"%s\" must return single scalar item" msgstr "" "выражение пути JSON для столбца \"%s\" должно возвращать один скалярный " "элемент" -#: utils/adt/jsonpath_exec.c:4049 utils/adt/jsonpath_exec.c:4073 +#: utils/adt/jsonpath_exec.c:4037 utils/adt/jsonpath_exec.c:4061 #, c-format msgid "JSON path expression in JSON_VALUE must return single scalar item" msgstr "" @@ -30406,7 +30525,7 @@ msgstr "длина аргумента levenshtein() превышает макс msgid "could not determine which collation to use for LIKE" msgstr "не удалось определить, какой порядок сортировки использовать для LIKE" -#: utils/adt/like.c:193 utils/adt/like_support.c:1019 +#: utils/adt/like.c:193 utils/adt/like_support.c:1031 #, c-format msgid "could not determine which collation to use for ILIKE" msgstr "не удалось определить, какой порядок сортировки использовать для ILIKE" @@ -30416,28 +30535,28 @@ msgstr "не удалось определить, какой порядок со msgid "nondeterministic collations are not supported for ILIKE" msgstr "недетерминированные правила сортировки не поддерживаются для ILIKE" -#: utils/adt/like_match.c:107 utils/adt/like_match.c:169 -#: utils/adt/like_match.c:237 +#: utils/adt/like_match.c:164 utils/adt/like_match.c:232 +#: utils/adt/like_match.c:352 #, c-format msgid "LIKE pattern must not end with escape character" msgstr "шаблон LIKE не должен заканчиваться защитным символом" -#: utils/adt/like_match.c:437 utils/adt/regexp.c:804 +#: utils/adt/like_match.c:448 utils/adt/regexp.c:804 #, c-format msgid "invalid escape string" msgstr "неверный защитный символ" -#: utils/adt/like_match.c:438 utils/adt/regexp.c:805 +#: utils/adt/like_match.c:449 utils/adt/regexp.c:805 #, c-format msgid "Escape string must be empty or one character." msgstr "Защитный символ должен быть пустым или состоять из одного байта." -#: utils/adt/like_support.c:1009 +#: utils/adt/like_support.c:1021 #, c-format msgid "case insensitive matching not supported on type bytea" msgstr "регистронезависимое сравнение не поддерживается для типа bytea" -#: utils/adt/like_support.c:1106 +#: utils/adt/like_support.c:1118 #, c-format msgid "regular-expression matching not supported on type bytea" msgstr "сравнение с регулярными выражениями не поддерживается для типа bytea" @@ -30559,12 +30678,12 @@ msgstr "Ожидалось начало диапазона." msgid "Expected comma or end of multirange." msgstr "Ожидалась запятая или конец мультидиапазона." -#: utils/adt/multirangetypes.c:982 +#: utils/adt/multirangetypes.c:983 #, c-format msgid "multiranges cannot be constructed from multidimensional arrays" msgstr "мультидиапазоны нельзя получить из массивов мультидиапазонов" -#: utils/adt/multirangetypes.c:1008 +#: utils/adt/multirangetypes.c:1009 #, c-format msgid "multirange values cannot contain null members" msgstr "мультидиапазоны не могут содержать элементы NULL" @@ -30643,10 +30762,10 @@ msgstr "результат вне диапазона" msgid "cannot subtract inet values of different sizes" msgstr "нельзя вычитать значения inet разного размера" -#: utils/adt/numeric.c:795 utils/adt/numeric.c:3763 utils/adt/numeric.c:7320 -#: utils/adt/numeric.c:7523 utils/adt/numeric.c:7995 utils/adt/numeric.c:10929 -#: utils/adt/numeric.c:11404 utils/adt/numeric.c:11498 -#: utils/adt/numeric.c:11633 +#: utils/adt/numeric.c:795 utils/adt/numeric.c:3769 utils/adt/numeric.c:7326 +#: utils/adt/numeric.c:7529 utils/adt/numeric.c:8001 utils/adt/numeric.c:10935 +#: utils/adt/numeric.c:11410 utils/adt/numeric.c:11504 +#: utils/adt/numeric.c:11639 #, c-format msgid "value overflows numeric format" msgstr "значение переполняет формат numeric" @@ -30666,99 +30785,99 @@ msgstr "неверный порядок числа во внешнем знач msgid "invalid digit in external \"numeric\" value" msgstr "неверная цифра во внешнем значении \"numeric\"" -#: utils/adt/numeric.c:1338 utils/adt/numeric.c:1352 +#: utils/adt/numeric.c:1335 #, c-format msgid "NUMERIC precision %d must be between 1 and %d" msgstr "точность NUMERIC %d должна быть между 1 и %d" -#: utils/adt/numeric.c:1343 +#: utils/adt/numeric.c:1340 #, c-format msgid "NUMERIC scale %d must be between %d and %d" msgstr "порядок NUMERIC %d должен быть между %d и %d" -#: utils/adt/numeric.c:1361 +#: utils/adt/numeric.c:1367 #, c-format msgid "invalid NUMERIC type modifier" msgstr "неверный модификатор типа NUMERIC" -#: utils/adt/numeric.c:1727 +#: utils/adt/numeric.c:1733 #, c-format msgid "start value cannot be NaN" msgstr "начальное значение не может быть NaN" -#: utils/adt/numeric.c:1731 +#: utils/adt/numeric.c:1737 #, c-format msgid "start value cannot be infinity" msgstr "начальное значение не может быть бесконечностью" -#: utils/adt/numeric.c:1738 +#: utils/adt/numeric.c:1744 #, c-format msgid "stop value cannot be NaN" msgstr "конечное значение не может быть NaN" -#: utils/adt/numeric.c:1742 +#: utils/adt/numeric.c:1748 #, c-format msgid "stop value cannot be infinity" msgstr "конечное значение не может быть бесконечностью" -#: utils/adt/numeric.c:1755 +#: utils/adt/numeric.c:1761 #, c-format msgid "step size cannot be NaN" msgstr "размер шага не может быть NaN" -#: utils/adt/numeric.c:1759 +#: utils/adt/numeric.c:1765 #, c-format msgid "step size cannot be infinity" msgstr "размер шага не может быть бесконечностью" -#: utils/adt/numeric.c:3753 +#: utils/adt/numeric.c:3759 #, c-format msgid "factorial of a negative number is undefined" msgstr "факториал отрицательного числа даёт неопределённость" -#: utils/adt/numeric.c:4360 +#: utils/adt/numeric.c:4366 #, c-format msgid "lower bound cannot be NaN" msgstr "нижняя граница не может быть NaN" -#: utils/adt/numeric.c:4364 +#: utils/adt/numeric.c:4370 #, c-format msgid "lower bound cannot be infinity" msgstr "нижняя граница не может быть бесконечностью" -#: utils/adt/numeric.c:4371 +#: utils/adt/numeric.c:4377 #, c-format msgid "upper bound cannot be NaN" msgstr "верхняя граница не может быть NaN" -#: utils/adt/numeric.c:4375 +#: utils/adt/numeric.c:4381 #, c-format msgid "upper bound cannot be infinity" msgstr "верхняя граница не может быть бесконечностью" -#: utils/adt/numeric.c:4536 utils/adt/numeric.c:4624 utils/adt/numeric.c:4684 -#: utils/adt/numeric.c:4880 +#: utils/adt/numeric.c:4542 utils/adt/numeric.c:4630 utils/adt/numeric.c:4690 +#: utils/adt/numeric.c:4886 #, c-format msgid "cannot convert NaN to %s" msgstr "нельзя преобразовать NaN в %s" -#: utils/adt/numeric.c:4540 utils/adt/numeric.c:4628 utils/adt/numeric.c:4688 -#: utils/adt/numeric.c:4884 +#: utils/adt/numeric.c:4546 utils/adt/numeric.c:4634 utils/adt/numeric.c:4694 +#: utils/adt/numeric.c:4890 #, c-format msgid "cannot convert infinity to %s" msgstr "нельзя представить бесконечность в %s" -#: utils/adt/numeric.c:4893 +#: utils/adt/numeric.c:4899 #, c-format msgid "pg_lsn out of range" msgstr "pg_lsn вне диапазона" -#: utils/adt/numeric.c:8085 utils/adt/numeric.c:8136 +#: utils/adt/numeric.c:8091 utils/adt/numeric.c:8142 #, c-format msgid "numeric field overflow" msgstr "переполнение поля numeric" -#: utils/adt/numeric.c:8086 +#: utils/adt/numeric.c:8092 #, c-format msgid "" "A field with precision %d, scale %d must round to an absolute value less " @@ -30767,13 +30886,13 @@ msgstr "" "Поле с точностью %d, порядком %d должно округляться до абсолютного значения " "меньше чем %s%d." -#: utils/adt/numeric.c:8137 +#: utils/adt/numeric.c:8143 #, c-format msgid "A field with precision %d, scale %d cannot hold an infinite value." msgstr "" "Поле с точностью %d, порядком %d не может содержать значение бесконечности." -#: utils/adt/numeric.c:11702 utils/adt/pseudorandomfuncs.c:135 +#: utils/adt/numeric.c:11708 utils/adt/pseudorandomfuncs.c:135 #: utils/adt/pseudorandomfuncs.c:159 #, c-format msgid "lower bound must be less than or equal to upper bound" @@ -30854,36 +30973,36 @@ msgstr "" "ALTER COLLATION %s REFRESH VERSION либо соберите PostgreSQL с правильной " "версией библиотеки." -#: utils/adt/pg_locale.c:1498 utils/adt/pg_locale.c:1525 -#: utils/adt/pg_locale_builtin.c:188 +#: utils/adt/pg_locale.c:1504 utils/adt/pg_locale.c:1531 +#: utils/adt/pg_locale_builtin.c:200 #, c-format msgid "invalid locale name \"%s\" for builtin provider" msgstr "неверное имя локали \"%s\" для встроенного провайдера" -#: utils/adt/pg_locale.c:1590 +#: utils/adt/pg_locale.c:1596 #, c-format msgid "could not convert locale name \"%s\" to language tag: %s" msgstr "не удалось получить из названия локали \"%s\" метку языка: %s" -#: utils/adt/pg_locale.c:1599 utils/adt/pg_locale.c:1674 +#: utils/adt/pg_locale.c:1605 utils/adt/pg_locale.c:1680 #: utils/adt/pg_locale_icu.c:215 #, c-format msgid "ICU is not supported in this build" msgstr "ICU не поддерживается в данной сборке" -#: utils/adt/pg_locale.c:1632 +#: utils/adt/pg_locale.c:1638 #, c-format msgid "could not get language from ICU locale \"%s\": %s" msgstr "не удалось определить язык для локали ICU \"%s\": %s" -#: utils/adt/pg_locale.c:1634 utils/adt/pg_locale.c:1664 +#: utils/adt/pg_locale.c:1640 utils/adt/pg_locale.c:1670 #, c-format msgid "To disable ICU locale validation, set the parameter \"%s\" to \"%s\"." msgstr "" "Чтобы отключить проверку локалей ICU, установите для параметра \"%s\" " "значение \"%s\"." -#: utils/adt/pg_locale.c:1662 +#: utils/adt/pg_locale.c:1668 #, c-format msgid "ICU locale \"%s\" has unknown language \"%s\"" msgstr "для локали ICU \"%s\" получен неизвестный язык \"%s\"" @@ -30909,28 +31028,28 @@ msgstr "" msgid "collation failed: %s" msgstr "ошибка в библиотеке сортировки: %s" -#: utils/adt/pg_locale_icu.c:569 utils/adt/pg_locale_icu.c:833 +#: utils/adt/pg_locale_icu.c:563 utils/adt/pg_locale_icu.c:819 #, c-format msgid "sort key generation failed: %s" msgstr "не удалось сгенерировать ключ сортировки: %s" -#: utils/adt/pg_locale_icu.c:643 utils/adt/pg_locale_icu.c:655 -#: utils/adt/pg_locale_icu.c:883 utils/adt/pg_locale_icu.c:904 +#: utils/adt/pg_locale_icu.c:637 utils/adt/pg_locale_icu.c:649 +#: utils/adt/pg_locale_icu.c:873 utils/adt/pg_locale_icu.c:893 #, c-format msgid "%s failed: %s" msgstr "ошибка %s: %s" -#: utils/adt/pg_locale_icu.c:684 +#: utils/adt/pg_locale_icu.c:678 #, c-format msgid "case conversion failed: %s" msgstr "преобразовать регистр не удалось: %s" -#: utils/adt/pg_locale_icu.c:856 +#: utils/adt/pg_locale_icu.c:842 #, c-format msgid "encoding \"%s\" not supported by ICU" msgstr "ICU не поддерживает кодировку \"%s\"" -#: utils/adt/pg_locale_icu.c:863 +#: utils/adt/pg_locale_icu.c:849 #, c-format msgid "could not open ICU converter for encoding \"%s\": %s" msgstr "не удалось открыть преобразователь ICU для кодировки \"%s\": %s" @@ -30956,34 +31075,34 @@ msgstr "" "не удалось получить версию правила сортировки для локали \"%s\" (код ошибки: " "%lu)" -#: utils/adt/pg_locale_libc.c:771 utils/adt/pg_locale_libc.c:784 +#: utils/adt/pg_locale_libc.c:777 utils/adt/pg_locale_libc.c:790 #, c-format msgid "could not convert string to UTF-16: error code %lu" msgstr "не удалось преобразовать строку в UTF-16 (код ошибки: %lu)" -#: utils/adt/pg_locale_libc.c:793 +#: utils/adt/pg_locale_libc.c:799 #, c-format msgid "could not compare Unicode strings: %m" msgstr "не удалось сравнить строки в Unicode: %m" -#: utils/adt/pg_locale_libc.c:825 +#: utils/adt/pg_locale_libc.c:831 #, c-format msgid "could not create locale \"%s\": %m" msgstr "не удалось создать локаль \"%s\": %m" -#: utils/adt/pg_locale_libc.c:828 +#: utils/adt/pg_locale_libc.c:834 #, c-format msgid "" "The operating system could not find any locale data for the locale name " "\"%s\"." msgstr "Операционная система не может найти данные локали с именем \"%s\"." -#: utils/adt/pg_locale_libc.c:1000 +#: utils/adt/pg_locale_libc.c:1006 #, c-format msgid "invalid multibyte character for locale" msgstr "неверный многобайтный символ для локали" -#: utils/adt/pg_locale_libc.c:1001 +#: utils/adt/pg_locale_libc.c:1007 #, c-format msgid "" "The server's LC_CTYPE locale is probably incompatible with the database " @@ -31191,8 +31310,8 @@ msgid "Use NONE to denote the missing argument of a unary operator." msgstr "" "Чтобы обозначить отсутствующий аргумент унарного оператора, укажите NONE." -#: utils/adt/regproc.c:675 utils/adt/regproc.c:2029 utils/adt/ruleutils.c:10836 -#: utils/adt/ruleutils.c:11049 +#: utils/adt/regproc.c:675 utils/adt/regproc.c:2029 utils/adt/ruleutils.c:10838 +#: utils/adt/ruleutils.c:11051 #, c-format msgid "too many arguments" msgstr "слишком много аргументов" @@ -31403,22 +31522,22 @@ msgstr "не удалось сравнить различные типы сто msgid "cannot compare record types with different numbers of columns" msgstr "сравнивать типы записей с разным числом столбцов нельзя" -#: utils/adt/ruleutils.c:2740 +#: utils/adt/ruleutils.c:2742 #, c-format msgid "input is a query, not an expression" msgstr "на вход поступил запрос, а не выражение" -#: utils/adt/ruleutils.c:2752 +#: utils/adt/ruleutils.c:2754 #, c-format msgid "expression contains variables of more than one relation" msgstr "выражение содержит переменные из нескольких отношений" -#: utils/adt/ruleutils.c:2759 +#: utils/adt/ruleutils.c:2761 #, c-format msgid "expression contains variables" msgstr "выражение содержит переменные" -#: utils/adt/ruleutils.c:5433 +#: utils/adt/ruleutils.c:5435 #, c-format msgid "rule \"%s\" has unsupported event type %d" msgstr "правило \"%s\" имеет неподдерживаемый тип событий %d" @@ -31496,21 +31615,21 @@ msgstr "timestamp вне диапазона: \"%g\"" #: utils/adt/timestamp.c:948 utils/adt/timestamp.c:1507 #: utils/adt/timestamp.c:1517 utils/adt/timestamp.c:1578 -#: utils/adt/timestamp.c:2866 utils/adt/timestamp.c:2875 -#: utils/adt/timestamp.c:2890 utils/adt/timestamp.c:2964 -#: utils/adt/timestamp.c:2981 utils/adt/timestamp.c:3038 -#: utils/adt/timestamp.c:3081 utils/adt/timestamp.c:3459 -#: utils/adt/timestamp.c:3517 utils/adt/timestamp.c:3540 -#: utils/adt/timestamp.c:3549 utils/adt/timestamp.c:3573 -#: utils/adt/timestamp.c:3596 utils/adt/timestamp.c:3605 -#: utils/adt/timestamp.c:3740 utils/adt/timestamp.c:3841 -#: utils/adt/timestamp.c:4248 utils/adt/timestamp.c:4285 -#: utils/adt/timestamp.c:4333 utils/adt/timestamp.c:4342 -#: utils/adt/timestamp.c:4434 utils/adt/timestamp.c:4481 -#: utils/adt/timestamp.c:4490 utils/adt/timestamp.c:4586 -#: utils/adt/timestamp.c:4639 utils/adt/timestamp.c:4649 -#: utils/adt/timestamp.c:4874 utils/adt/timestamp.c:4884 -#: utils/adt/timestamp.c:5239 +#: utils/adt/timestamp.c:2870 utils/adt/timestamp.c:2879 +#: utils/adt/timestamp.c:2894 utils/adt/timestamp.c:2968 +#: utils/adt/timestamp.c:2985 utils/adt/timestamp.c:3042 +#: utils/adt/timestamp.c:3085 utils/adt/timestamp.c:3463 +#: utils/adt/timestamp.c:3521 utils/adt/timestamp.c:3544 +#: utils/adt/timestamp.c:3553 utils/adt/timestamp.c:3577 +#: utils/adt/timestamp.c:3600 utils/adt/timestamp.c:3609 +#: utils/adt/timestamp.c:3744 utils/adt/timestamp.c:3845 +#: utils/adt/timestamp.c:4252 utils/adt/timestamp.c:4289 +#: utils/adt/timestamp.c:4337 utils/adt/timestamp.c:4346 +#: utils/adt/timestamp.c:4438 utils/adt/timestamp.c:4485 +#: utils/adt/timestamp.c:4494 utils/adt/timestamp.c:4590 +#: utils/adt/timestamp.c:4643 utils/adt/timestamp.c:4653 +#: utils/adt/timestamp.c:4878 utils/adt/timestamp.c:4888 +#: utils/adt/timestamp.c:5243 #, c-format msgid "interval out of range" msgstr "interval вне диапазона" @@ -31535,33 +31654,33 @@ msgstr "INTERVAL(%d): точность уменьшена до максимал msgid "interval(%d) precision must be between %d and %d" msgstr "точность interval(%d) должна быть между %d и %d" -#: utils/adt/timestamp.c:4623 utils/adt/timestamp.c:4858 +#: utils/adt/timestamp.c:4627 utils/adt/timestamp.c:4862 #, c-format msgid "origin out of range" msgstr "начало вне диапазона" -#: utils/adt/timestamp.c:4628 utils/adt/timestamp.c:4863 +#: utils/adt/timestamp.c:4632 utils/adt/timestamp.c:4867 #, c-format msgid "timestamps cannot be binned into infinite intervals" msgstr "значения timestamp нельзя подогнать под бесконечные интервалы" -#: utils/adt/timestamp.c:4633 utils/adt/timestamp.c:4868 +#: utils/adt/timestamp.c:4637 utils/adt/timestamp.c:4872 #, c-format msgid "timestamps cannot be binned into intervals containing months or years" msgstr "" "значения timestamp нельзя подогнать под интервалы, содержащие месяцы или годы" -#: utils/adt/timestamp.c:4644 utils/adt/timestamp.c:4879 +#: utils/adt/timestamp.c:4648 utils/adt/timestamp.c:4883 #, c-format msgid "stride must be greater than zero" msgstr "шаг должен быть больше нуля" -#: utils/adt/timestamp.c:5181 utils/adt/timestamp.c:5233 +#: utils/adt/timestamp.c:5185 utils/adt/timestamp.c:5237 #, c-format msgid "Months usually have fractional weeks." msgstr "В месяцах обычно дробное количество недель." -#: utils/adt/timestamp.c:6713 utils/adt/timestamp.c:6799 +#: utils/adt/timestamp.c:6717 utils/adt/timestamp.c:6803 #, c-format msgid "step size cannot be infinite" msgstr "размер шага не может быть бесконечным" @@ -31680,62 +31799,67 @@ msgstr "слово слишком длинное (%ld Б, при максиму msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" msgstr "строка слишком длинна для tsvector (%ld Б, при максимуме %ld)" -#: utils/adt/tsvector_op.c:771 +#: utils/adt/tsvector_op.c:238 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "нераспознанный вес: \"%c\"" + +#: utils/adt/tsvector_op.c:242 +#, c-format +msgid "unrecognized weight: \"\\%03o\"" +msgstr "нераспознанный вес: \"\\%03o\"" + +#: utils/adt/tsvector_op.c:766 #, c-format msgid "lexeme array may not contain nulls" msgstr "массив лексем не может содержать элементы null" -#: utils/adt/tsvector_op.c:776 +#: utils/adt/tsvector_op.c:771 #, c-format msgid "lexeme array may not contain empty strings" msgstr "массив лексем не должен содержать пустые строки" -#: utils/adt/tsvector_op.c:845 +#: utils/adt/tsvector_op.c:840 #, c-format msgid "weight array may not contain nulls" msgstr "массив весов не может содержать элементы null" -#: utils/adt/tsvector_op.c:869 -#, c-format -msgid "unrecognized weight: \"%c\"" -msgstr "нераспознанный вес: \"%c\"" - -#: utils/adt/tsvector_op.c:2599 +#: utils/adt/tsvector_op.c:2572 #, c-format msgid "ts_stat query must return one tsvector column" msgstr "запрос ts_stat должен вернуть один столбец tsvector" -#: utils/adt/tsvector_op.c:2792 +#: utils/adt/tsvector_op.c:2765 #, c-format msgid "tsvector column \"%s\" does not exist" msgstr "столбец \"%s\" типа tsvector не существует" -#: utils/adt/tsvector_op.c:2799 +#: utils/adt/tsvector_op.c:2772 #, c-format msgid "column \"%s\" is not of tsvector type" msgstr "столбец \"%s\" должен иметь тип tsvector" -#: utils/adt/tsvector_op.c:2811 +#: utils/adt/tsvector_op.c:2784 #, c-format msgid "configuration column \"%s\" does not exist" msgstr "столбец конфигурации \"%s\" не существует" -#: utils/adt/tsvector_op.c:2817 +#: utils/adt/tsvector_op.c:2790 #, c-format msgid "column \"%s\" is not of regconfig type" msgstr "столбец \"%s\" должен иметь тип regconfig" -#: utils/adt/tsvector_op.c:2824 +#: utils/adt/tsvector_op.c:2797 #, c-format msgid "configuration column \"%s\" must not be null" msgstr "значение столбца конфигурации \"%s\" не должно быть null" -#: utils/adt/tsvector_op.c:2837 +#: utils/adt/tsvector_op.c:2810 #, c-format msgid "text search configuration name \"%s\" must be schema-qualified" msgstr "имя конфигурации текстового поиска \"%s\" должно указываться со схемой" -#: utils/adt/tsvector_op.c:2862 +#: utils/adt/tsvector_op.c:2835 #, c-format msgid "column \"%s\" is not of a character type" msgstr "столбец \"%s\" имеет не символьный тип" @@ -31756,11 +31880,34 @@ msgstr "нет спец. символа \"%s\"" msgid "wrong position info in tsvector: \"%s\"" msgstr "неверная информация о позиции в tsvector: \"%s\"" -#: utils/adt/uuid.c:535 utils/adt/uuid.c:632 +#: utils/adt/uuid.c:552 utils/adt/uuid.c:649 #, c-format msgid "could not generate random values" msgstr "не удалось сгенерировать случайные значения" +#: utils/adt/uuid.c:700 +#, c-format +msgid "interval out of range for UUID version 7" +msgstr "интервал вне диапазона для UUID версии 7" + +#: utils/adt/uuid.c:701 +#, c-format +msgid "UUID version 7 does not support infinite intervals." +msgstr "В UUID версии 7 бесконечные интервалы не поддерживаются." + +#: utils/adt/uuid.c:725 +#, c-format +msgid "timestamp out of range for UUID version 7" +msgstr "дата/время вне диапазона для UUID версии 7" + +#: utils/adt/uuid.c:726 +#, c-format +msgid "" +"UUID version 7 supports timestamps from 1970-01-01 to approximately year " +"10889." +msgstr "" +"В UUID версии 7 поддерживаются даты с 1970-01-01 до примерно 10889 года." + #: utils/adt/varbit.c:110 utils/adt/varchar.c:53 #, c-format msgid "length for type %s must be at least 1" @@ -32082,50 +32229,50 @@ msgstr "неверный запрос" msgid "portal \"%s\" does not return tuples" msgstr "портал \"%s\" не возвращает кортежи" -#: utils/adt/xml.c:4363 +#: utils/adt/xml.c:4365 #, c-format msgid "invalid array for XML namespace mapping" msgstr "неправильный массив с сопоставлениями пространств имён XML" -#: utils/adt/xml.c:4364 +#: utils/adt/xml.c:4366 #, c-format msgid "" "The array must be two-dimensional with length of the second axis equal to 2." msgstr "Массив должен быть двухмерным и содержать 2 элемента по второй оси." -#: utils/adt/xml.c:4388 +#: utils/adt/xml.c:4390 #, c-format msgid "empty XPath expression" msgstr "пустое выражение XPath" -#: utils/adt/xml.c:4440 +#: utils/adt/xml.c:4442 #, c-format msgid "neither namespace name nor URI may be null" msgstr "ни префикс, ни URI пространства имён не может быть null" -#: utils/adt/xml.c:4447 +#: utils/adt/xml.c:4449 #, c-format msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" msgstr "" "не удалось зарегистрировать пространство имён XML с префиксом \"%s\" и URI " "\"%s\"" -#: utils/adt/xml.c:4796 +#: utils/adt/xml.c:4798 #, c-format msgid "DEFAULT namespace is not supported" msgstr "пространство имён DEFAULT не поддерживается" -#: utils/adt/xml.c:4825 +#: utils/adt/xml.c:4827 #, c-format msgid "row path filter must not be empty string" msgstr "путь отбираемых строк не должен быть пустым" -#: utils/adt/xml.c:4859 +#: utils/adt/xml.c:4861 #, c-format msgid "column path filter must not be empty string" msgstr "путь отбираемого столбца не должен быть пустым" -#: utils/adt/xml.c:5006 +#: utils/adt/xml.c:5008 #, c-format msgid "more than one value returned by column XPath expression" msgstr "выражение XPath, отбирающее столбец, возвратило более одного значения" @@ -32138,23 +32285,23 @@ msgstr "" "не удалось определить фактический тип аргумента для полиморфной функции " "\"%s\"" -#: utils/cache/lsyscache.c:1147 +#: utils/cache/lsyscache.c:1257 #, c-format msgid "cast from type %s to type %s does not exist" msgstr "приведение типа %s к типу %s не существует" -#: utils/cache/lsyscache.c:3065 utils/cache/lsyscache.c:3098 -#: utils/cache/lsyscache.c:3131 utils/cache/lsyscache.c:3164 +#: utils/cache/lsyscache.c:3189 utils/cache/lsyscache.c:3222 +#: utils/cache/lsyscache.c:3255 utils/cache/lsyscache.c:3288 #, c-format msgid "type %s is only a shell" msgstr "тип %s является пустышкой" -#: utils/cache/lsyscache.c:3070 +#: utils/cache/lsyscache.c:3194 #, c-format msgid "no input function available for type %s" msgstr "для типа %s нет функции ввода" -#: utils/cache/lsyscache.c:3103 +#: utils/cache/lsyscache.c:3227 #, c-format msgid "no output function available for type %s" msgstr "для типа %s нет функции вывода" @@ -32168,30 +32315,30 @@ msgstr "" "в классе операторов \"%s\" метода доступа %s нет опорной функции %d для типа " "%s" -#: utils/cache/relcache.c:3805 +#: utils/cache/relcache.c:3807 #, c-format msgid "heap relfilenumber value not set when in binary upgrade mode" msgstr "" "значение relfilenumber для кучи не задано в режиме двоичного обновления" -#: utils/cache/relcache.c:3813 +#: utils/cache/relcache.c:3815 #, c-format msgid "unexpected request for new relfilenumber in binary upgrade mode" msgstr "" "неожиданный запрос нового значения relfilenumber в режиме двоичного " "обновления" -#: utils/cache/relcache.c:6633 +#: utils/cache/relcache.c:6635 #, c-format msgid "could not create relation-cache initialization file \"%s\": %m" msgstr "создать файл инициализации для кеша отношений \"%s\" не удалось: %m" -#: utils/cache/relcache.c:6635 +#: utils/cache/relcache.c:6637 #, c-format msgid "Continuing anyway, but there's something wrong." msgstr "Продолжаем всё равно, хотя что-то не так." -#: utils/cache/relcache.c:6965 +#: utils/cache/relcache.c:6967 #, c-format msgid "could not remove cache file \"%s\": %m" msgstr "не удалось стереть файл кеша \"%s\": %m" @@ -32212,7 +32359,7 @@ msgstr "файл сопоставления отношений \"%s\" содер msgid "relation mapping file \"%s\" contains incorrect checksum" msgstr "ошибка контрольной суммы в файле сопоставления отношений \"%s\"" -#: utils/cache/typcache.c:1901 utils/fmgr/funcapi.c:574 +#: utils/cache/typcache.c:1894 utils/fmgr/funcapi.c:574 #, c-format msgid "record type has not been registered" msgstr "тип записи не зарегистрирован" @@ -36351,12 +36498,12 @@ msgstr "" "Чтобы отключить политику для владельца таблицы, воспользуйтесь командой " "ALTER TABLE NO FORCE ROW LEVEL SECURITY." -#: utils/misc/stack_depth.c:101 +#: utils/misc/stack_depth.c:102 #, c-format msgid "stack depth limit exceeded" msgstr "превышен предел глубины стека" -#: utils/misc/stack_depth.c:102 +#: utils/misc/stack_depth.c:103 #, c-format msgid "" "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), " @@ -36366,12 +36513,12 @@ msgstr "" "КБ), предварительно убедившись, что ОС предоставляет достаточный размер " "стека." -#: utils/misc/stack_depth.c:149 +#: utils/misc/stack_depth.c:165 #, c-format msgid "\"max_stack_depth\" must not exceed %zdkB." msgstr "Значение \"max_stack_depth\" не должно превышать %zd КБ." -#: utils/misc/stack_depth.c:151 +#: utils/misc/stack_depth.c:167 #, c-format msgid "" "Increase the platform's stack depth limit via \"ulimit -s\" or local " @@ -36477,16 +36624,26 @@ msgstr "Ошибка при создании контекста памяти \"% msgid "could not attach to dynamic shared area" msgstr "не удалось подключиться к динамической разделяемой области" -#: utils/mmgr/mcxt.c:1163 +#: utils/mmgr/mcxt.c:1166 #, c-format msgid "Failed on request of size %zu in memory context \"%s\"." msgstr "Ошибка при запросе блока размером %zu в контексте памяти \"%s\"." -#: utils/mmgr/mcxt.c:1319 +#: utils/mmgr/mcxt.c:1322 #, c-format msgid "logging memory contexts of PID %d" msgstr "вывод информации о памяти процесса с PID %d" +#: utils/mmgr/mcxt.c:1698 +#, c-format +msgid "invalid memory allocation request size %zu + %zu" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu" + +#: utils/mmgr/mcxt.c:1717 +#, c-format +msgid "invalid memory allocation request size %zu * %zu" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu" + #: utils/mmgr/portalmem.c:187 #, c-format msgid "cursor \"%s\" already exists" @@ -37101,7 +37258,7 @@ msgstr "неверная последовательность шестнадца msgid "unexpected end after backslash" msgstr "неожиданный конец строки после обратной косой черты" -#: jsonpath_scan.l:201 repl_scanner.l:217 scan.l:742 +#: jsonpath_scan.l:201 repl_scanner.l:221 scan.l:742 msgid "unterminated quoted string" msgstr "незавершённая строка в кавычках" @@ -37283,6 +37440,10 @@ msgstr "нестандартное использование спецсимво msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." msgstr "Используйте для записи спецсимволов синтаксис спецстрок E'\\r\\n'." +#, c-format +#~ msgid "requested shared memory size overflows size_t" +#~ msgstr "запрошенный размер разделяемой памяти не умещается в size_t" + #, c-format #~ msgid "aborting startup due to startup process failure" #~ msgstr "прерывание запуска из-за ошибки в стартовом процессе" diff --git a/src/bin/initdb/po/ru.po b/src/bin/initdb/po/ru.po index d97f5a0d232..6ebd156791b 100644 --- a/src/bin/initdb/po/ru.po +++ b/src/bin/initdb/po/ru.po @@ -6,13 +6,13 @@ # Sergey Burladyan , 2009. # Andrey Sudnik , 2010. # Dmitriy Olshevskiy , 2014. -# SPDX-FileCopyrightText: 2012-2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025 Alexander Lakhin +# SPDX-FileCopyrightText: 2012-2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: initdb (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" -"PO-Revision-Date: 2025-09-13 16:55+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:32+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -88,17 +88,27 @@ msgstr "ошибка в %s(): %m" msgid "out of memory" msgstr "нехватка памяти" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/file_utils.c:69 ../../common/file_utils.c:370 #: ../../common/file_utils.c:428 ../../common/file_utils.c:502 #, c-format diff --git a/src/bin/initdb/po/sv.po b/src/bin/initdb/po/sv.po index ac9aea5cf97..c605680077e 100644 --- a/src/bin/initdb/po/sv.po +++ b/src/bin/initdb/po/sv.po @@ -1,5 +1,5 @@ # Swedish message translation file for initdb -# Dennis Björklund , 2004, 2005, 2006, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025. +# Dennis Björklund , 2004, 2005, 2006, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026. # Magnus Hagander , 2007. # Peter Eisentraut , 2009. # Mats Erik Andersson , 2014. @@ -8,10 +8,10 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 18\n" +"Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-05-11 00:51+0000\n" -"PO-Revision-Date: 2025-05-11 14:26+0200\n" +"POT-Creation-Date: 2026-08-08 19:53+0000\n" +"PO-Revision-Date: 2026-08-09 22:15+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -20,83 +20,93 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ../../../src/common/logging.c:279 +#: ../../../src/common/logging.c:293 ../../../src/common/logging.c:295 #, c-format msgid "error: " msgstr "fel: " -#: ../../../src/common/logging.c:286 +#: ../../../src/common/logging.c:302 ../../../src/common/logging.c:304 #, c-format msgid "warning: " msgstr "varning: " -#: ../../../src/common/logging.c:297 +#: ../../../src/common/logging.c:315 ../../../src/common/logging.c:317 #, c-format msgid "detail: " msgstr "detalj: " -#: ../../../src/common/logging.c:304 +#: ../../../src/common/logging.c:324 ../../../src/common/logging.c:326 #, c-format msgid "hint: " msgstr "tips: " -#: ../../common/exec.c:174 +#: ../../common/exec.c:175 #, c-format msgid "invalid binary \"%s\": %m" msgstr "ogiltig binär \"%s\": %m" -#: ../../common/exec.c:217 +#: ../../common/exec.c:218 #, c-format msgid "could not read binary \"%s\": %m" msgstr "kunde inte läsa binär \"%s\": %m" -#: ../../common/exec.c:225 +#: ../../common/exec.c:226 #, c-format msgid "could not find a \"%s\" to execute" msgstr "kunde inte hitta en \"%s\" att köra" -#: ../../common/exec.c:252 +#: ../../common/exec.c:253 #, c-format msgid "could not resolve path \"%s\" to absolute form: %m" msgstr "kunde inte konvertera sökvägen \"%s\" till en absolut sökväg: %m" -#: ../../common/exec.c:363 initdb.c:753 +#: ../../common/exec.c:364 initdb.c:767 #, c-format msgid "could not execute command \"%s\": %m" msgstr "kunde inte köra kommandot \"%s\": %m" -#: ../../common/exec.c:375 +#: ../../common/exec.c:376 #, c-format msgid "could not read from command \"%s\": %m" msgstr "kunde inte läsa från kommando \"%s\": %m" -#: ../../common/exec.c:378 +#: ../../common/exec.c:379 #, c-format msgid "no data was returned by command \"%s\"" msgstr "ingen data returnerades från kommandot \"%s\"" -#: ../../common/exec.c:405 +#: ../../common/exec.c:406 #, c-format msgid "%s() failed: %m" msgstr "%s() misslyckades: %m" -#: ../../common/exec.c:543 ../../common/exec.c:588 ../../common/exec.c:680 -#: initdb.c:375 initdb.c:411 +#: ../../common/exec.c:544 ../../common/exec.c:589 ../../common/exec.c:681 +#: initdb.c:376 initdb.c:412 #, c-format msgid "out of memory" msgstr "slut på minne" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "slut på minne\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "kan inte duplicera null-pekare (internt fel)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "ogiltig storlek %zu + %zu för minnesallokering\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "ogiltig storlek %zu * %zu för minnesallokering\n" + #: ../../common/file_utils.c:69 ../../common/file_utils.c:370 #: ../../common/file_utils.c:428 ../../common/file_utils.c:502 #, c-format @@ -126,7 +136,7 @@ msgid "could not open directory \"%s\": %m" msgstr "kunde inte öppna katalog \"%s\": %m" #: ../../common/file_utils.c:174 ../../common/file_utils.c:338 -#: ../../common/pgfnames.c:69 ../../common/rmtree.c:106 +#: ../../common/pgfnames.c:68 ../../common/rmtree.c:106 #, c-format msgid "could not read directory \"%s\": %m" msgstr "kunde inte läsa katalog \"%s\": %m" @@ -141,7 +151,7 @@ msgstr "kunde inte fsync:a fil \"%s\": %m" msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "kunde inte döpa om fil \"%s\" till \"%s\": %m" -#: ../../common/pgfnames.c:74 +#: ../../common/pgfnames.c:73 #, c-format msgid "could not close directory \"%s\": %m" msgstr "kunde inte stänga katalog \"%s\": %m" @@ -245,12 +255,17 @@ msgstr "%s måste vara i intervallet %d..%d" msgid "unrecognized sync method: %s" msgstr "okänd synkmetod: %s" -#: ../../fe_utils/string_utils.c:587 +#: ../../fe_utils/option_utils.c:139 +#, c-format +msgid "options %s and %s cannot be used together" +msgstr "flaggorna %s och %s kan inte användas tillsammans" + +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "shell-kommandots argument innehåller nyrad eller vagnretur: \"%s\"\n" -#: ../../fe_utils/string_utils.c:760 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "databasnamnet innehåller nyrad eller vagnretur: \"%s\"\n" @@ -265,166 +280,166 @@ msgstr "kunde inte sätta en knutpunkt (junction) för \"%s\": %s\n" msgid "could not get junction for \"%s\": %s\n" msgstr "kunde inte få en knutpunkt (junction) för \"%s\": %s\n" -#: initdb.c:372 +#: initdb.c:373 #, c-format msgid "_wsetlocale() failed" msgstr "_wsetlocale() misslyckades" -#: initdb.c:379 +#: initdb.c:380 #, c-format msgid "setlocale() failed" msgstr "setlocale() misslyckades" -#: initdb.c:393 +#: initdb.c:394 #, c-format msgid "failed to restore old locale" msgstr "misslyckades med att återställa gamla lokalen" -#: initdb.c:396 +#: initdb.c:397 #, c-format msgid "failed to restore old locale \"%s\"" msgstr "misslyckades med att återställa gamla lokalen \"%s\"" -#: initdb.c:685 initdb.c:1692 +#: initdb.c:699 initdb.c:1715 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "kunde inte öppna filen \"%s\" för läsning: %m" -#: initdb.c:729 initdb.c:1035 initdb.c:1055 +#: initdb.c:743 initdb.c:1051 initdb.c:1071 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "kunde inte öppna fil \"%s\" för skrivning: %m" -#: initdb.c:733 initdb.c:1038 initdb.c:1057 +#: initdb.c:747 initdb.c:1054 initdb.c:1073 #, c-format msgid "could not write file \"%s\": %m" msgstr "kunde inte skriva fil \"%s\": %m" -#: initdb.c:737 +#: initdb.c:751 #, c-format msgid "could not close file \"%s\": %m" msgstr "kunde inte stänga fil \"%s\": %m" -#: initdb.c:771 +#: initdb.c:785 #, c-format msgid "removing data directory \"%s\"" msgstr "tar bort datakatalog \"%s\"" -#: initdb.c:773 +#: initdb.c:787 #, c-format msgid "failed to remove data directory" msgstr "misslyckades med att ta bort datakatalog" -#: initdb.c:777 +#: initdb.c:791 #, c-format msgid "removing contents of data directory \"%s\"" msgstr "tar bort innehållet i datakatalog \"%s\"" -#: initdb.c:780 +#: initdb.c:794 #, c-format msgid "failed to remove contents of data directory" msgstr "misslyckades med att ta bort innehållet i datakatalogen" -#: initdb.c:785 +#: initdb.c:799 #, c-format msgid "removing WAL directory \"%s\"" msgstr "tar bort WAL-katalog \"%s\"" -#: initdb.c:787 +#: initdb.c:801 #, c-format msgid "failed to remove WAL directory" msgstr "misslyckades med att ta bort WAL-katalog" -#: initdb.c:791 +#: initdb.c:805 #, c-format msgid "removing contents of WAL directory \"%s\"" msgstr "tar bort innehållet i WAL-katalog \"%s\"" -#: initdb.c:793 +#: initdb.c:807 #, c-format msgid "failed to remove contents of WAL directory" msgstr "misslyckades med att ta bort innehållet i WAL-katalogen" -#: initdb.c:800 +#: initdb.c:814 #, c-format msgid "data directory \"%s\" not removed at user's request" msgstr "datakatalog \"%s\" är ej borttagen på användares begäran" -#: initdb.c:804 +#: initdb.c:818 #, c-format msgid "WAL directory \"%s\" not removed at user's request" msgstr "WAL-katalog \"%s\" är ej borttagen på användares begäran" -#: initdb.c:822 +#: initdb.c:836 #, c-format msgid "cannot be run as root" msgstr "kan inte köras som root" -#: initdb.c:823 +#: initdb.c:837 #, c-format msgid "Please log in (using, e.g., \"su\") as the (unprivileged) user that will own the server process." msgstr "Logga in (t.ex. med \"su\") som den (opriviligerade) användare som skall äga serverprocessen." -#: initdb.c:855 +#: initdb.c:869 #, c-format msgid "\"%s\" is not a valid server encoding name" msgstr "\"%s\" är inte en giltig teckenkodning för servern" -#: initdb.c:1001 +#: initdb.c:1017 #, c-format msgid "file \"%s\" does not exist" msgstr "filen \"%s\" finns inte" -#: initdb.c:1002 initdb.c:1007 initdb.c:1014 +#: initdb.c:1018 initdb.c:1023 initdb.c:1030 #, c-format msgid "This might mean you have a corrupted installation or identified the wrong directory with the invocation option -L." msgstr "Detta kan betyda att du har en korrupt installation eller att du har angivit felaktig katalog till flaggan -L." -#: initdb.c:1006 +#: initdb.c:1022 #, c-format msgid "could not access file \"%s\": %m" msgstr "kunde inte komma åt filen \"%s\": %m" -#: initdb.c:1013 +#: initdb.c:1029 #, c-format msgid "file \"%s\" is not a regular file" msgstr "filen \"%s\" är inte en normal fil" -#: initdb.c:1157 +#: initdb.c:1173 #, c-format msgid "selecting dynamic shared memory implementation ... " msgstr "väljer mekanism för dynamiskt, delat minne ... " -#: initdb.c:1167 +#: initdb.c:1183 #, c-format msgid "selecting default \"max_connections\" ... " msgstr "sätter förvalt värde för \"max_connections\" ... " -#: initdb.c:1188 +#: initdb.c:1204 #, c-format msgid "selecting default \"shared_buffers\" ... " msgstr "sätter förvalt värde för \"shared_buffers\" ... " -#: initdb.c:1211 +#: initdb.c:1227 #, c-format msgid "selecting default time zone ... " msgstr "sätter förvalt värde för tidszon ... " -#: initdb.c:1291 +#: initdb.c:1307 msgid "creating configuration files ... " msgstr "skapar konfigurationsfiler ... " -#: initdb.c:1443 initdb.c:1457 initdb.c:1524 initdb.c:1535 +#: initdb.c:1464 initdb.c:1478 initdb.c:1542 initdb.c:1553 initdb.c:1561 #, c-format msgid "could not change permissions of \"%s\": %m" msgstr "kunde inte ändra rättigheter på \"%s\": %m" -#: initdb.c:1554 +#: initdb.c:1580 #, c-format msgid "running bootstrap script ... " msgstr "kör uppsättningsskript..." -#: initdb.c:1566 +#: initdb.c:1592 #, c-format msgid "input file \"%s\" does not belong to PostgreSQL %s" msgstr "indatafil \"%s\" tillhör inte PostgreSQL %s" @@ -433,125 +448,125 @@ msgstr "indatafil \"%s\" tillhör inte PostgreSQL %s" # with a standard directory "/usr/local/pgsql", is such that # the translated message string produces a reasonable output. # -#: initdb.c:1568 +#: initdb.c:1594 #, c-format msgid "Specify the correct path using the option -L." msgstr "Ange korrekt sökväg med flaggan -L." -#: initdb.c:1670 +#: initdb.c:1693 msgid "Enter new superuser password: " msgstr "Mata in ett nytt lösenord för superuser: " -#: initdb.c:1671 +#: initdb.c:1694 msgid "Enter it again: " msgstr "Mata in det igen: " -#: initdb.c:1674 +#: initdb.c:1697 #, c-format msgid "Passwords didn't match.\n" msgstr "Lösenorden stämde inte överens.\n" -#: initdb.c:1698 +#: initdb.c:1721 #, c-format msgid "could not read password from file \"%s\": %m" msgstr "kunde inte läsa lösenord i filen \"%s\": %m" -#: initdb.c:1701 +#: initdb.c:1724 #, c-format msgid "password file \"%s\" is empty" msgstr "lösenordsfilen \"%s\" är tom" -#: initdb.c:2113 +#: initdb.c:2136 #, c-format msgid "caught signal\n" msgstr "mottog signal\n" -#: initdb.c:2119 +#: initdb.c:2142 #, c-format msgid "could not write to child process: %s\n" msgstr "kunde inte skriva till barnprocess: %s\n" -#: initdb.c:2127 +#: initdb.c:2150 #, c-format msgid "ok\n" msgstr "ok\n" -#: initdb.c:2209 initdb.c:2255 +#: initdb.c:2232 initdb.c:2278 #, c-format msgid "locale name \"%s\" contains non-ASCII characters" msgstr "lokalnamn \"%s\" innehåller tecken som ej är ASCII" -#: initdb.c:2235 +#: initdb.c:2258 #, c-format msgid "invalid locale name \"%s\"" msgstr "ogiltigt lokalnamn \"%s\"" -#: initdb.c:2236 +#: initdb.c:2259 #, c-format msgid "If the locale name is specific to ICU, use --icu-locale." msgstr "Om lokalnamnet är specifikt för ICU, använd --icu-locale." -#: initdb.c:2249 +#: initdb.c:2272 #, c-format msgid "invalid locale settings; check LANG and LC_* environment variables" msgstr "ogiltig lokalinställning. Kontrollera miljövariablerna LANG och LC_*" -#: initdb.c:2280 initdb.c:2304 +#: initdb.c:2303 initdb.c:2327 #, c-format msgid "encoding mismatch" msgstr "teckenkodning matchar inte" -#: initdb.c:2281 +#: initdb.c:2304 #, c-format msgid "The encoding you selected (%s) and the encoding that the selected locale uses (%s) do not match. This would lead to misbehavior in various character string processing functions." msgstr "Teckenkodningen du har valt (%s) och teckenkodningen som valda lokalen använder (%s) passar inte ihop. Detta kommer leda till problem för funktioner som arbetar med strängar." -#: initdb.c:2286 initdb.c:2307 +#: initdb.c:2309 initdb.c:2330 #, c-format msgid "Rerun %s and either do not specify an encoding explicitly, or choose a matching combination." msgstr "Kör %s igen och ange antingen ingen explicit kodning eller välj en matchande kombination." -#: initdb.c:2305 +#: initdb.c:2328 #, c-format msgid "The encoding you selected (%s) is not supported with the ICU provider." msgstr "Den valda teckenkodningen (%s) stöds inte av ICU." -#: initdb.c:2356 +#: initdb.c:2379 #, c-format msgid "could not convert locale name \"%s\" to language tag: %s" msgstr "kunde inte konvertera lokalnamn \"%s\" till språktagg: %s" -#: initdb.c:2362 initdb.c:2414 initdb.c:2508 +#: initdb.c:2385 initdb.c:2437 initdb.c:2531 #, c-format msgid "ICU is not supported in this build" msgstr "ICU stöds inte av detta bygge" -#: initdb.c:2385 +#: initdb.c:2408 #, c-format msgid "could not get language from locale \"%s\": %s" msgstr "kunde inte härleda språk från lokalen \"%s\": %s" -#: initdb.c:2411 +#: initdb.c:2434 #, c-format msgid "locale \"%s\" has unknown language \"%s\"" msgstr "lokalen \"%s\" har ett okänt språk \"%s\"" -#: initdb.c:2472 +#: initdb.c:2495 #, c-format msgid "locale must be specified if provider is %s" msgstr "lokal måste anges när leverantören är %s" -#: initdb.c:2485 +#: initdb.c:2508 #, c-format msgid "invalid locale name \"%s\" for builtin provider" msgstr "ogiltigt lokalnamn \"%s\" för inbyggd leverantör" -#: initdb.c:2496 +#: initdb.c:2519 #, c-format msgid "Using language tag \"%s\" for ICU locale \"%s\".\n" msgstr "Använder språktagg \"%s\" för ICU-lokal \"%s\".\n" -#: initdb.c:2519 +#: initdb.c:2542 #, c-format msgid "" "%s initializes a PostgreSQL database cluster.\n" @@ -560,17 +575,17 @@ msgstr "" "%s initierar ett databaskluster för PostgreSQL.\n" "\n" -#: initdb.c:2520 +#: initdb.c:2543 #, c-format msgid "Usage:\n" msgstr "Användning:\n" -#: initdb.c:2521 +#: initdb.c:2544 #, c-format msgid " %s [OPTION]... [DATADIR]\n" msgstr " %s [FLAGGA]... [DATAKATALOG]\n" -#: initdb.c:2522 +#: initdb.c:2545 #, c-format msgid "" "\n" @@ -579,57 +594,57 @@ msgstr "" "\n" "Flaggor:\n" -#: initdb.c:2523 +#: initdb.c:2546 #, c-format msgid " -A, --auth=METHOD default authentication method for local connections\n" msgstr " -A, --auth=METOD förvald autentiseringsmetod för alla anslutningar\n" -#: initdb.c:2524 +#: initdb.c:2547 #, c-format msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" msgstr " --auth-host=METOD autentiseringsmetod för TCP/IP-anslutningar\n" -#: initdb.c:2525 +#: initdb.c:2548 #, c-format msgid " --auth-local=METHOD default authentication method for local-socket connections\n" msgstr " --auth-local=METOD autentiseringsmetod för anslutningar via unix-uttag\n" -#: initdb.c:2526 +#: initdb.c:2549 #, c-format msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" msgstr " [-D, --pgdata=]DATAKATALOG läge för detta databaskluster\n" -#: initdb.c:2527 +#: initdb.c:2550 #, c-format msgid " -E, --encoding=ENCODING set default encoding for new databases\n" msgstr " -E, --encoding=KODNING sätter teckenkodning för nya databaser\n" -#: initdb.c:2528 +#: initdb.c:2551 #, c-format msgid " -g, --allow-group-access allow group read/execute on data directory\n" msgstr " -g, --allow-group-access tillåt läs/kör för grupp på datakatalogen\n" -#: initdb.c:2529 +#: initdb.c:2552 #, c-format msgid " --icu-locale=LOCALE set ICU locale ID for new databases\n" msgstr " --icu-locale=LOKAL sätt ID för ICU-lokal för nya databaser\n" -#: initdb.c:2530 +#: initdb.c:2553 #, c-format msgid " --icu-rules=RULES set additional ICU collation rules for new databases\n" msgstr " --icu-rules=REGLER sätt ytterligare ICU-jämförelseregler för nya databaser\n" -#: initdb.c:2531 +#: initdb.c:2554 #, c-format msgid " -k, --data-checksums use data page checksums\n" msgstr " -k, --data-checksums använd checksummor på datablock\n" -#: initdb.c:2532 +#: initdb.c:2555 #, c-format msgid " --locale=LOCALE set default locale for new databases\n" msgstr " --locale=LOKAL sätt standardlokal för nya databaser\n" -#: initdb.c:2533 +#: initdb.c:2556 #, c-format msgid "" " --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" @@ -642,12 +657,12 @@ msgstr "" " sätter standardlokal i utvald kategori för\n" " nya databaser (förval hämtas ur omgivningen)\n" -#: initdb.c:2537 +#: initdb.c:2560 #, c-format msgid " --no-locale equivalent to --locale=C\n" msgstr " --no-locale samma som --locale=C\n" -#: initdb.c:2538 +#: initdb.c:2561 #, c-format msgid "" " --builtin-locale=LOCALE\n" @@ -656,7 +671,7 @@ msgstr "" " --builtin-locale=LOKAL\n" " sätt standard lokalnamn för nya databaser\n" -#: initdb.c:2540 +#: initdb.c:2563 #, c-format msgid "" " --locale-provider={builtin|libc|icu}\n" @@ -665,17 +680,17 @@ msgstr "" " --locale-provider={builtin|libc|icu}\n" " sätt standard lokalleverantör för nya databaser\n" -#: initdb.c:2542 +#: initdb.c:2565 #, c-format msgid " --no-data-checksums do not use data page checksums\n" msgstr " --no data-checksums använd inte checksummor på datablock\n" -#: initdb.c:2543 +#: initdb.c:2566 #, c-format msgid " --pwfile=FILE read password for the new superuser from file\n" msgstr " --pwfile=FIL läser lösenord för superuser från fil\n" -#: initdb.c:2544 +#: initdb.c:2567 #, c-format msgid "" " -T, --text-search-config=CFG\n" @@ -684,27 +699,27 @@ msgstr "" " -T, --text-search-config=CFG\n" " standardkonfiguration för textsökning\n" -#: initdb.c:2546 +#: initdb.c:2569 #, c-format msgid " -U, --username=NAME database superuser name\n" msgstr " -U, --username=NAMN namn på databasens superuser\n" -#: initdb.c:2547 +#: initdb.c:2570 #, c-format msgid " -W, --pwprompt prompt for a password for the new superuser\n" msgstr " -W, --pwprompt efterfråga lösenord för superuser\n" -#: initdb.c:2548 +#: initdb.c:2571 #, c-format msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" msgstr " -X, --waldir=WALDIR katalog för write-ahead-log (WAL)\n" -#: initdb.c:2549 +#: initdb.c:2572 #, c-format msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" msgstr " --wal-segsize=STORLEK storlek på WAL-segment i megabyte\n" -#: initdb.c:2550 +#: initdb.c:2573 #, c-format msgid "" "\n" @@ -713,62 +728,62 @@ msgstr "" "\n" "Mindre vanliga flaggor:\n" -#: initdb.c:2551 +#: initdb.c:2574 #, c-format msgid " -c, --set NAME=VALUE override default setting for server parameter\n" msgstr " -c, --set NAMN=VÄRDE ersätt standardinställning för serverparameter\n" -#: initdb.c:2552 +#: initdb.c:2575 #, c-format msgid " -d, --debug generate lots of debugging output\n" msgstr " -d, --debug generera massor med debug-utskrifter\n" -#: initdb.c:2553 +#: initdb.c:2576 #, c-format msgid " --discard-caches set debug_discard_caches=1\n" msgstr " --discard-caches sätt debug_discard_caches=1\n" -#: initdb.c:2554 +#: initdb.c:2577 #, c-format msgid " -L DIRECTORY where to find the input files\n" msgstr " -L KATALOG katalog där indatafiler skall sökas\n" -#: initdb.c:2555 +#: initdb.c:2578 #, c-format msgid " -n, --no-clean do not clean up after errors\n" msgstr " -n, --no-clean städa inte upp efter fel\n" -#: initdb.c:2556 +#: initdb.c:2579 #, c-format msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgstr " -N, --no-sync vänta inte på att ändingar säkert skrivits till disk\n" -#: initdb.c:2557 +#: initdb.c:2580 #, c-format msgid " --no-sync-data-files do not sync files within database directories\n" msgstr " --no-sync-data-files synka inte filer i databaskataloger\n" -#: initdb.c:2558 +#: initdb.c:2581 #, c-format msgid " --no-instructions do not print instructions for next steps\n" msgstr " --no-instructions skriv inte instruktioner för nästa steg\n" -#: initdb.c:2559 +#: initdb.c:2582 #, c-format msgid " -s, --show show internal settings, then exit\n" msgstr " -s, --show visa interna inställningar, avsluta sedan\n" -#: initdb.c:2560 +#: initdb.c:2583 #, c-format msgid " --sync-method=METHOD set method for syncing files to disk\n" msgstr " --sync-method=METOD sätt synkmetod för att synka filer till disk\n" -#: initdb.c:2561 +#: initdb.c:2584 #, c-format msgid " -S, --sync-only only sync database files to disk, then exit\n" msgstr " -S, --sync-only synka bara databasfiler till disk, avsluta seden\n" -#: initdb.c:2562 +#: initdb.c:2585 #, c-format msgid "" "\n" @@ -777,17 +792,17 @@ msgstr "" "\n" "Andra flaggor:\n" -#: initdb.c:2563 +#: initdb.c:2586 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: initdb.c:2564 +#: initdb.c:2587 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa denna hjälp, avsluta sedan\n" -#: initdb.c:2565 +#: initdb.c:2588 #, c-format msgid "" "\n" @@ -797,7 +812,7 @@ msgstr "" "\n" "Om datakatalogen inte anges så tas den från omgivningsvariabeln PGDATA.\n" -#: initdb.c:2567 +#: initdb.c:2590 #, c-format msgid "" "\n" @@ -806,72 +821,72 @@ msgstr "" "\n" "Rapportera fel till <%s>.\n" -#: initdb.c:2568 +#: initdb.c:2591 #, c-format msgid "%s home page: <%s>\n" msgstr "hemsida för %s: <%s>\n" -#: initdb.c:2592 +#: initdb.c:2615 #, c-format msgid "invalid authentication method \"%s\" for \"%s\" connections" msgstr "ogiltig autentiseringsmetod \"%s\" för anslutning av typen \"%s\"" -#: initdb.c:2606 +#: initdb.c:2629 #, c-format msgid "must specify a password for the superuser to enable password authentication" msgstr "du måste ange ett lösenord för superuser för att kunna slå på lösenordsautentisering" -#: initdb.c:2625 +#: initdb.c:2648 #, c-format msgid "no data directory specified" msgstr "ingen datakatalog angiven" -#: initdb.c:2626 +#: initdb.c:2649 #, c-format msgid "You must identify the directory where the data for this database system will reside. Do this with either the invocation option -D or the environment variable PGDATA." msgstr "Du måste uppge den katalog där data för detta databassystem skall lagras. Gör det antingen med flaggan -D eller genom att sätta omgivningsvariabeln PGDATA." -#: initdb.c:2643 +#: initdb.c:2666 #, c-format msgid "could not set environment" msgstr "kunde inte sätta omgivningen" -#: initdb.c:2661 +#: initdb.c:2684 #, c-format msgid "program \"%s\" is needed by %s but was not found in the same directory as \"%s\"" msgstr "programmet \"%s\" behövs av %s men hittades inte i samma katalog som \"%s\"" -#: initdb.c:2664 +#: initdb.c:2687 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "programmet \"%s\" hittades av \"%s\" men är inte av samma version som %s" -#: initdb.c:2679 +#: initdb.c:2702 #, c-format msgid "input file location must be an absolute path" msgstr "plats för indatafiler måste vara en absolut sökväg" -#: initdb.c:2696 +#: initdb.c:2719 #, c-format msgid "The database cluster will be initialized with locale \"%s\".\n" msgstr "Databasklustret kommer att skapas med lokalnamn \"%s\".\n" -#: initdb.c:2699 +#: initdb.c:2722 #, c-format msgid "The database cluster will be initialized with this locale configuration:\n" msgstr "Databasklustret kommer att initieras med denna lokalkonfiguration:\n" -#: initdb.c:2700 +#: initdb.c:2723 #, c-format msgid " locale provider: %s\n" msgstr " lokalleverantör: %s\n" -#: initdb.c:2702 +#: initdb.c:2725 #, c-format msgid " default collation: %s\n" msgstr " standardjämförelse: %s\n" -#: initdb.c:2703 +#: initdb.c:2726 #, c-format msgid "" " LC_COLLATE: %s\n" @@ -888,22 +903,22 @@ msgstr "" " LC_NUMERIC: %s\n" " LC_TIME: %s\n" -#: initdb.c:2733 +#: initdb.c:2756 #, c-format msgid "could not find suitable encoding for locale \"%s\"" msgstr "kunde inte välja en lämplig kodning för lokal \"%s\"" -#: initdb.c:2735 +#: initdb.c:2758 #, c-format msgid "Rerun %s with the -E option." msgstr "Kör %s igen men med flaggan -E." -#: initdb.c:2736 initdb.c:3274 initdb.c:3400 initdb.c:3420 +#: initdb.c:2759 initdb.c:3299 initdb.c:3425 initdb.c:3445 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Försök med \"%s --help\" för mer information." -#: initdb.c:2748 +#: initdb.c:2771 #, c-format msgid "" "Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" @@ -912,112 +927,112 @@ msgstr "" "Teckenkodning \"%s\", tagen ur lokalnamnet, är inte godtagbar för servern.\n" "I dess ställe sättes databasens förvalda teckenkodning till \"%s\".\n" -#: initdb.c:2753 +#: initdb.c:2776 #, c-format msgid "locale \"%s\" requires unsupported encoding \"%s\"" msgstr "lokalen \"%s\" kräver ej supportad teckenkodning \"%s\"" -#: initdb.c:2755 +#: initdb.c:2778 #, c-format msgid "Encoding \"%s\" is not allowed as a server-side encoding." msgstr "Teckenkodning \"%s\" tillåts inte som serverteckenkodning." -#: initdb.c:2757 +#: initdb.c:2780 #, c-format msgid "Rerun %s with a different locale selection." msgstr "Kör %s igen men välj en annan lokal." -#: initdb.c:2765 +#: initdb.c:2788 #, c-format msgid "The default database encoding has accordingly been set to \"%s\".\n" msgstr "Förvald teckenkodning för databaser är satt till \"%s\".\n" -#: initdb.c:2781 +#: initdb.c:2804 #, c-format msgid "builtin provider locale \"%s\" requires encoding \"%s\"" msgstr "lokal \"%s\" för inbyggd leverantör kräver teckenkodning \"%s\"" -#: initdb.c:2843 +#: initdb.c:2868 #, c-format msgid "could not find suitable text search configuration for locale \"%s\"" msgstr "kunde inte hitta en lämplig textsökningskonfiguration för lokalnamn \"%s\"" -#: initdb.c:2854 +#: initdb.c:2879 #, c-format msgid "suitable text search configuration for locale \"%s\" is unknown" msgstr "ingen lämplig textsökningskonfiguration för lokalnamn \"%s\"" -#: initdb.c:2859 +#: initdb.c:2884 #, c-format msgid "specified text search configuration \"%s\" might not match locale \"%s\"" msgstr "uppgiven textsökningskonfiguration \"%s\" passar kanske inte till lokalnamn \"%s\"" -#: initdb.c:2864 +#: initdb.c:2889 #, c-format msgid "The default text search configuration will be set to \"%s\".\n" msgstr "Förvald textsökningskonfiguration för databaser är satt till \"%s\".\n" -#: initdb.c:2898 initdb.c:2969 +#: initdb.c:2923 initdb.c:2994 #, c-format msgid "creating directory %s ... " msgstr "skapar katalog %s ... " -#: initdb.c:2903 initdb.c:2974 initdb.c:3022 initdb.c:3079 +#: initdb.c:2928 initdb.c:2999 initdb.c:3047 initdb.c:3104 #, c-format msgid "could not create directory \"%s\": %m" msgstr "kunde inte skapa katalog \"%s\": %m" -#: initdb.c:2912 initdb.c:2984 +#: initdb.c:2937 initdb.c:3009 #, c-format msgid "fixing permissions on existing directory %s ... " msgstr "sätter rättigheter på existerande katalog %s ... " -#: initdb.c:2917 initdb.c:2989 +#: initdb.c:2942 initdb.c:3014 #, c-format msgid "could not change permissions of directory \"%s\": %m" msgstr "kunde inte ändra rättigheter på katalogen \"%s\": %m" -#: initdb.c:2929 initdb.c:3001 +#: initdb.c:2954 initdb.c:3026 #, c-format msgid "directory \"%s\" exists but is not empty" msgstr "katalogen \"%s\" existerar men är inte tom" -#: initdb.c:2933 +#: initdb.c:2958 #, c-format msgid "If you want to create a new database system, either remove or empty the directory \"%s\" or run %s with an argument other than \"%s\"." msgstr "Om du vill skapa ett nytt databassystem, tag då antingen bort eller töm katalogen \"%s\" eller kör %s med annat argument än \"%s\"." -#: initdb.c:2941 initdb.c:3011 initdb.c:3445 +#: initdb.c:2966 initdb.c:3036 initdb.c:3470 #, c-format msgid "could not access directory \"%s\": %m" msgstr "kunde inte komma åt katalog \"%s\": %m" -#: initdb.c:2962 +#: initdb.c:2987 #, c-format msgid "WAL directory location must be an absolute path" msgstr "WAL-katalogen måste vara en absolut sökväg" -#: initdb.c:3005 +#: initdb.c:3030 #, c-format msgid "If you want to store the WAL there, either remove or empty the directory \"%s\"." msgstr "Om du vill spara WAL där, antingen radera eller töm katalogen \"%s\"." -#: initdb.c:3015 +#: initdb.c:3040 #, c-format msgid "could not create symbolic link \"%s\": %m" msgstr "kan inte skapa symbolisk länk \"%s\": %m" -#: initdb.c:3034 +#: initdb.c:3059 #, c-format msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point." msgstr "Den innehåller en gömd fil, med inledande punkt i namnet; kanske är detta en monteringspunkt." -#: initdb.c:3036 +#: initdb.c:3061 #, c-format msgid "It contains a lost+found directory, perhaps due to it being a mount point." msgstr "Den innehåller \"lost+found\"; kanske är detta en monteringspunkt." -#: initdb.c:3038 +#: initdb.c:3063 #, c-format msgid "" "Using a mount point directly as the data directory is not recommended.\n" @@ -1026,65 +1041,65 @@ msgstr "" "Att använda en monteringspunkt som datakatalog rekommenderas inte.\n" "Skapa först en underkatalog under monteringspunkten." -#: initdb.c:3065 +#: initdb.c:3090 #, c-format msgid "creating subdirectories ... " msgstr "Skapar underkataloger ... " -#: initdb.c:3108 +#: initdb.c:3133 msgid "performing post-bootstrap initialization ... " msgstr "utför initiering efter uppstättning..." -#: initdb.c:3273 +#: initdb.c:3298 #, c-format msgid "-c %s requires a value" msgstr "-c %s kräver ett värde" -#: initdb.c:3298 +#: initdb.c:3323 #, c-format msgid "Running in debug mode.\n" msgstr "Kör i debug-läge.\n" -#: initdb.c:3302 +#: initdb.c:3327 #, c-format msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" msgstr "Kör i no-clean-läge. Misstag kommer inte städas bort.\n" -#: initdb.c:3375 +#: initdb.c:3400 #, c-format msgid "unrecognized locale provider: %s" msgstr "okänd lokalleverantör: %s" -#: initdb.c:3418 +#: initdb.c:3443 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "för många kommandoradsargument (första är \"%s\")" -#: initdb.c:3425 initdb.c:3429 initdb.c:3433 +#: initdb.c:3450 initdb.c:3454 initdb.c:3458 #, c-format msgid "%s cannot be specified unless locale provider \"%s\" is chosen" msgstr "%s kan inte anges om inte lokalleverantör \"%s\" valts" -#: initdb.c:3447 initdb.c:3510 +#: initdb.c:3472 initdb.c:3535 msgid "syncing data to disk ... " msgstr "synkar data till disk ... " -#: initdb.c:3455 +#: initdb.c:3480 #, c-format msgid "password prompt and password file cannot be specified together" msgstr "lösenordsfråga och lösenordsfil kan inte anges samtidigt" -#: initdb.c:3466 +#: initdb.c:3491 #, c-format msgid "argument of %s must be a power of two between 1 and 1024" msgstr "argumentet till %s måste vara en tvåpotens mellan 1 och 1024" -#: initdb.c:3479 +#: initdb.c:3504 #, c-format msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" msgstr "superuser-namn \"%s\" tillåts inte; rollnamn får inte börja på \"pg_\"" -#: initdb.c:3481 +#: initdb.c:3506 #, c-format msgid "" "The files belonging to this database system will be owned by user \"%s\".\n" @@ -1095,17 +1110,17 @@ msgstr "" "Denna användare måste också vara ägare av server-processen.\n" "\n" -#: initdb.c:3497 +#: initdb.c:3522 #, c-format msgid "Data page checksums are enabled.\n" msgstr "Checksummor för datablock är aktiva.\n" -#: initdb.c:3499 +#: initdb.c:3524 #, c-format msgid "Data page checksums are disabled.\n" msgstr "Checksummor för datablock är avstängda.\n" -#: initdb.c:3516 +#: initdb.c:3541 #, c-format msgid "" "\n" @@ -1116,22 +1131,22 @@ msgstr "" "Avstod från synkning mot lagringsmedium.\n" "Datakatalogen kan komma att fördärvas om operativsystemet störtar.\n" -#: initdb.c:3521 +#: initdb.c:3546 #, c-format msgid "enabling \"trust\" authentication for local connections" msgstr "slår på autentiseringsmetod \"trust\" för lokala anslutningar" -#: initdb.c:3522 +#: initdb.c:3547 #, c-format msgid "You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb." msgstr "Du kan ändra detta genom att redigera pg_hba.conf eller genom att sätta flaggor -A eller --auth-local och --auth-host nästa gång du kör initdb." #. translator: This is a placeholder in a shell command. -#: initdb.c:3552 +#: initdb.c:3577 msgid "logfile" msgstr "loggfil" -#: initdb.c:3554 +#: initdb.c:3579 #, c-format msgid "" "\n" diff --git a/src/bin/pg_amcheck/po/ru.po b/src/bin/pg_amcheck/po/ru.po index 4d7da795e2a..3cd913997a9 100644 --- a/src/bin/pg_amcheck/po/ru.po +++ b/src/bin/pg_amcheck/po/ru.po @@ -1,10 +1,10 @@ -# Alexander Lakhin , 2021, 2022, 2024. +# SPDX-FileCopyrightText: 2021, 2022, 2024, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: pg_amcheck (PostgreSQL) 14\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" -"PO-Revision-Date: 2024-09-05 08:23+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:46+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -32,17 +32,27 @@ msgstr "подробности: " msgid "hint: " msgstr "подсказка: " -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/file_utils.c:69 ../../common/file_utils.c:370 #: ../../common/file_utils.c:428 ../../common/file_utils.c:502 #, c-format diff --git a/src/bin/pg_archivecleanup/po/ru.po b/src/bin/pg_archivecleanup/po/ru.po index ccefe2163c4..b6ef88fcefa 100644 --- a/src/bin/pg_archivecleanup/po/ru.po +++ b/src/bin/pg_archivecleanup/po/ru.po @@ -1,13 +1,13 @@ # Russian message translation file for pg_archivecleanup # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# SPDX-FileCopyrightText: 2017, 2019, 2020, 2022, 2024, 2025 Alexander Lakhin +# SPDX-FileCopyrightText: 2017, 2019, 2020, 2022, 2024, 2025, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" -"PO-Revision-Date: 2025-09-13 21:08+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:46+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -37,17 +37,27 @@ msgstr "подробности: " msgid "hint: " msgstr "подсказка: " -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: pg_archivecleanup.c:69 #, c-format msgid "archive location \"%s\" does not exist" diff --git a/src/bin/pg_basebackup/po/ru.po b/src/bin/pg_basebackup/po/ru.po index f795081d011..310411111cf 100644 --- a/src/bin/pg_basebackup/po/ru.po +++ b/src/bin/pg_basebackup/po/ru.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_basebackup (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-10 08:01+0300\n" -"PO-Revision-Date: 2026-05-10 08:12+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:48+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -111,8 +111,8 @@ msgid "could not read file \"%s\": read %d of %zu" msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d из %zu)" #: ../../common/controldata_utils.c:132 ../../common/controldata_utils.c:280 -#: ../../fe_utils/astreamer_file.c:141 ../../fe_utils/astreamer_file.c:270 -#: pg_recvlogical.c:653 +#: ../../fe_utils/astreamer_file.c:141 ../../fe_utils/astreamer_file.c:282 +#: pg_recvlogical.c:657 #, c-format msgid "could not close file \"%s\": %m" msgstr "не удалось закрыть файл \"%s\": %m" @@ -154,24 +154,34 @@ msgstr "не удалось записать файл \"%s\": %m" msgid "could not fsync file \"%s\": %m" msgstr "не удалось синхронизировать с ФС файл \"%s\": %m" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/file_utils.c:75 #, c-format msgid "could not synchronize file system for file \"%s\": %m" msgstr "не удалось синхронизировать с ФС файл \"%s\": %m" #: ../../common/file_utils.c:123 ../../common/file_utils.c:588 -#: pg_receivewal.c:319 pg_recvlogical.c:354 +#: pg_receivewal.c:319 pg_recvlogical.c:358 #, c-format msgid "could not stat file \"%s\": %m" msgstr "не удалось получить информацию о файле \"%s\": %m" @@ -229,40 +239,50 @@ msgstr "не удалось перезапуститься с ограничен msgid "could not get exit code from subprocess: error code %lu" msgstr "не удалось получить код выхода от подпроцесса (код ошибки: %lu)" -#: ../../fe_utils/astreamer_file.c:96 ../../fe_utils/astreamer_file.c:366 +#: ../../fe_utils/astreamer_file.c:96 ../../fe_utils/astreamer_file.c:378 #: ../../fe_utils/recovery_gen.c:153 pg_basebackup.c:1498 pg_basebackup.c:1707 #, c-format msgid "could not create file \"%s\": %m" msgstr "не удалось создать файл \"%s\": %m" -#: ../../fe_utils/astreamer_file.c:124 ../../fe_utils/astreamer_file.c:261 +#: ../../fe_utils/astreamer_file.c:124 ../../fe_utils/astreamer_file.c:273 #: ../../fe_utils/recovery_gen.c:144 pg_basebackup.c:1434 pg_basebackup.c:1728 #, c-format msgid "could not write to file \"%s\": %m" msgstr "не удалось записать в файл \"%s\": %m" -#: ../../fe_utils/astreamer_file.c:280 +#: ../../fe_utils/astreamer_file.c:222 ../../fe_utils/astreamer_tar.c:309 +#, c-format +msgid "tar member has unsafe path name: \"%s\"" +msgstr "компонент tar имеет небезопасный путь: \"%s\"" + +#: ../../fe_utils/astreamer_file.c:251 +#, c-format +msgid "link target has unsafe path name: \"%s\"" +msgstr "цель ссылки имеет небезопасный путь: \"%s\"" + +#: ../../fe_utils/astreamer_file.c:292 #, c-format msgid "unexpected state while extracting archive" msgstr "неожиданное состояние при извлечении архива" -#: ../../fe_utils/astreamer_file.c:326 pg_basebackup.c:699 pg_basebackup.c:713 +#: ../../fe_utils/astreamer_file.c:338 pg_basebackup.c:699 pg_basebackup.c:713 #: pg_basebackup.c:758 #, c-format msgid "could not create directory \"%s\": %m" msgstr "не удалось создать каталог \"%s\": %m" -#: ../../fe_utils/astreamer_file.c:331 +#: ../../fe_utils/astreamer_file.c:343 #, c-format msgid "could not set permissions on directory \"%s\": %m" msgstr "не удалось установить права для каталога \"%s\": %m" -#: ../../fe_utils/astreamer_file.c:350 +#: ../../fe_utils/astreamer_file.c:362 #, c-format msgid "could not create symbolic link from \"%s\" to \"%s\": %m" msgstr "не удалось создать символическую ссылку \"%s\" в \"%s\": %m" -#: ../../fe_utils/astreamer_file.c:370 +#: ../../fe_utils/astreamer_file.c:382 #, c-format msgid "could not set permissions on file \"%s\": %m" msgstr "не удалось установить права доступа для файла \"%s\": %m" @@ -349,12 +369,12 @@ msgstr "входной файл не похож на архив tar" msgid "tar member has empty name" msgstr "пустое имя у компонента tar" -#: ../../fe_utils/astreamer_tar.c:328 +#: ../../fe_utils/astreamer_tar.c:332 #, c-format msgid "pax extensions to tar format are not supported" msgstr "расширения PAX для формата tar не поддерживаются" -#: ../../fe_utils/astreamer_tar.c:357 +#: ../../fe_utils/astreamer_tar.c:361 #, c-format msgid "COPY stream ended before last file was finished" msgstr "поток COPY закончился до завершения последнего файла" @@ -526,13 +546,13 @@ msgstr "" "%s делает базовую резервную копию работающего сервера PostgreSQL.\n" "\n" -#: pg_basebackup.c:394 pg_createsubscriber.c:246 pg_receivewal.c:79 +#: pg_basebackup.c:394 pg_createsubscriber.c:245 pg_receivewal.c:79 #: pg_recvlogical.c:85 #, c-format msgid "Usage:\n" msgstr "Использование:\n" -#: pg_basebackup.c:395 pg_createsubscriber.c:247 pg_receivewal.c:80 +#: pg_basebackup.c:395 pg_createsubscriber.c:246 pg_receivewal.c:80 #: pg_recvlogical.c:86 #, c-format msgid " %s [OPTION]...\n" @@ -827,7 +847,7 @@ msgid "" msgstr "" " -W, --password запрашивать пароль всегда (обычно не требуется)\n" -#: pg_basebackup.c:448 pg_createsubscriber.c:270 pg_receivewal.c:106 +#: pg_basebackup.c:448 pg_createsubscriber.c:269 pg_receivewal.c:106 #: pg_recvlogical.c:120 #, c-format msgid "" @@ -837,7 +857,7 @@ msgstr "" "\n" "Об ошибках сообщайте по адресу <%s>.\n" -#: pg_basebackup.c:449 pg_createsubscriber.c:271 pg_receivewal.c:107 +#: pg_basebackup.c:449 pg_createsubscriber.c:270 pg_receivewal.c:107 #: pg_recvlogical.c:121 #, c-format msgid "%s home page: <%s>\n" @@ -889,7 +909,7 @@ msgstr "не удалось создать фоновый поток выпол msgid "directory \"%s\" exists but is not empty" msgstr "каталог \"%s\" существует, но он не пуст" -#: pg_basebackup.c:783 pg_createsubscriber.c:420 +#: pg_basebackup.c:783 pg_createsubscriber.c:419 #, c-format msgid "could not access directory \"%s\": %m" msgstr "ошибка при обращении к каталогу \"%s\": %m" @@ -953,8 +973,8 @@ msgstr "скорость передачи \"%s\" вне диапазона" msgid "could not get COPY data stream: %s" msgstr "не удалось получить поток данных COPY: %s" -#: pg_basebackup.c:1040 pg_recvlogical.c:451 pg_recvlogical.c:627 -#: receivelog.c:980 +#: pg_basebackup.c:1040 pg_recvlogical.c:455 pg_recvlogical.c:631 +#: receivelog.c:986 #, c-format msgid "could not read COPY data: %s" msgstr "не удалось прочитать данные COPY: %s" @@ -1049,9 +1069,9 @@ msgstr "Укажите -X none или -X fetch для отключения тр msgid "server does not support incremental backup" msgstr "сервер не поддерживает инкрементальное копирование" -#: pg_basebackup.c:1851 pg_basebackup.c:2009 pg_recvlogical.c:274 -#: receivelog.c:542 receivelog.c:581 streamutil.c:296 streamutil.c:370 -#: streamutil.c:422 streamutil.c:510 streamutil.c:667 streamutil.c:712 +#: pg_basebackup.c:1851 pg_basebackup.c:2009 pg_recvlogical.c:278 +#: receivelog.c:541 receivelog.c:587 streamutil.c:296 streamutil.c:370 +#: streamutil.c:422 streamutil.c:511 streamutil.c:672 streamutil.c:717 #, c-format msgid "could not send replication command \"%s\": %s" msgstr "не удалось передать команду репликации \"%s\": %s" @@ -1256,21 +1276,21 @@ msgstr "" #: pg_basebackup.c:2713 pg_basebackup.c:2725 pg_basebackup.c:2737 #: pg_basebackup.c:2745 pg_basebackup.c:2758 pg_basebackup.c:2764 #: pg_basebackup.c:2773 pg_basebackup.c:2785 pg_basebackup.c:2796 -#: pg_basebackup.c:2804 pg_createsubscriber.c:2238 pg_createsubscriber.c:2261 -#: pg_createsubscriber.c:2271 pg_createsubscriber.c:2279 -#: pg_createsubscriber.c:2307 pg_createsubscriber.c:2350 pg_receivewal.c:748 +#: pg_basebackup.c:2804 pg_createsubscriber.c:2237 pg_createsubscriber.c:2260 +#: pg_createsubscriber.c:2270 pg_createsubscriber.c:2278 +#: pg_createsubscriber.c:2306 pg_createsubscriber.c:2349 pg_receivewal.c:748 #: pg_receivewal.c:760 pg_receivewal.c:767 pg_receivewal.c:776 -#: pg_receivewal.c:783 pg_receivewal.c:793 pg_recvlogical.c:861 -#: pg_recvlogical.c:873 pg_recvlogical.c:883 pg_recvlogical.c:890 -#: pg_recvlogical.c:897 pg_recvlogical.c:904 pg_recvlogical.c:911 -#: pg_recvlogical.c:918 pg_recvlogical.c:925 pg_recvlogical.c:934 -#: pg_recvlogical.c:941 +#: pg_receivewal.c:783 pg_receivewal.c:793 pg_recvlogical.c:865 +#: pg_recvlogical.c:877 pg_recvlogical.c:887 pg_recvlogical.c:894 +#: pg_recvlogical.c:901 pg_recvlogical.c:908 pg_recvlogical.c:915 +#: pg_recvlogical.c:922 pg_recvlogical.c:929 pg_recvlogical.c:938 +#: pg_recvlogical.c:945 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Для дополнительной информации попробуйте \"%s --help\"." -#: pg_basebackup.c:2585 pg_createsubscriber.c:2269 pg_receivewal.c:758 -#: pg_recvlogical.c:871 +#: pg_basebackup.c:2585 pg_createsubscriber.c:2268 pg_receivewal.c:758 +#: pg_recvlogical.c:875 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "слишком много аргументов командной строки (первый: \"%s\")" @@ -1377,32 +1397,32 @@ msgstr "" "Целевой сервер больше не может использоваться как физическая реплика. Чтобы " "продолжить, физическую реплику необходимо пересоздать." -#: pg_createsubscriber.c:221 +#: pg_createsubscriber.c:220 #, c-format msgid "" "publication \"%s\" created in database \"%s\" on primary was left behind" msgstr "на главном сервере осталась публикация \"%s\", созданная в базе \"%s\"" -#: pg_createsubscriber.c:224 +#: pg_createsubscriber.c:223 #, c-format msgid "Drop this publication before trying again." msgstr "Удалите эту публикацию и попробуйте повторить операцию." -#: pg_createsubscriber.c:228 +#: pg_createsubscriber.c:227 #, c-format msgid "" "replication slot \"%s\" created in database \"%s\" on primary was left behind" msgstr "" "на главном сервере остался слот репликации \"%s\", созданный в базе \"%s\"" -#: pg_createsubscriber.c:231 pg_createsubscriber.c:1324 +#: pg_createsubscriber.c:230 pg_createsubscriber.c:1328 #, c-format msgid "Drop this replication slot soon to avoid retention of WAL files." msgstr "" "Удалите этот слот репликации незамедлительно во избежание накопления файлов " "WAL." -#: pg_createsubscriber.c:244 +#: pg_createsubscriber.c:243 #, c-format msgid "" "%s creates a new logical replica from a standby server.\n" @@ -1411,7 +1431,7 @@ msgstr "" "%s превращает резервный сервер в логическую реплику.\n" "\n" -#: pg_createsubscriber.c:248 pg_receivewal.c:81 pg_recvlogical.c:91 +#: pg_createsubscriber.c:247 pg_receivewal.c:81 pg_recvlogical.c:91 #, c-format msgid "" "\n" @@ -1420,7 +1440,7 @@ msgstr "" "\n" "Параметры:\n" -#: pg_createsubscriber.c:249 +#: pg_createsubscriber.c:248 #, c-format msgid "" " -a, --all create subscriptions for all databases " @@ -1432,7 +1452,7 @@ msgstr "" "кроме шаблонов\n" " и баз данных, не допускающих подключения\n" -#: pg_createsubscriber.c:251 +#: pg_createsubscriber.c:250 #, c-format msgid "" " -d, --database=DBNAME database in which to create a " @@ -1440,7 +1460,7 @@ msgid "" msgstr "" " -d, --database=ИМЯ_БД база, в которой будет создана подписка\n" -#: pg_createsubscriber.c:252 +#: pg_createsubscriber.c:251 #, c-format msgid "" " -D, --pgdata=DATADIR location for the subscriber data " @@ -1448,7 +1468,7 @@ msgid "" msgstr "" " -D, --pgdata=КАТ_ДАННЫХ расположение каталога данных подписчика\n" -#: pg_createsubscriber.c:253 +#: pg_createsubscriber.c:252 #, c-format msgid "" " -n, --dry-run dry run, just show what would be done\n" @@ -1456,19 +1476,19 @@ msgstr "" " -n, --dry-run холостой запуск — только показать, какие\n" " действия будут выполнены\n" -#: pg_createsubscriber.c:254 +#: pg_createsubscriber.c:253 #, c-format msgid " -p, --subscriber-port=PORT subscriber port number (default %s)\n" msgstr "" " -p, --subscriber-port=ПОРТ номер порта подписчика (по умолчанию: %s)\n" -#: pg_createsubscriber.c:255 +#: pg_createsubscriber.c:254 #, c-format msgid " -P, --publisher-server=CONNSTR publisher connection string\n" msgstr "" " -P, --publisher-server=СТРОКА строка подключения к серверу публикации\n" -#: pg_createsubscriber.c:256 +#: pg_createsubscriber.c:255 #, c-format msgid "" " -s, --socketdir=DIR socket directory to use (default current " @@ -1476,13 +1496,13 @@ msgid "" msgstr "" " -s, --socketdir=КАТАЛОГ каталог сокетов (по умолчанию текущий)\n" -#: pg_createsubscriber.c:257 +#: pg_createsubscriber.c:256 #, c-format msgid " -t, --recovery-timeout=SECS seconds to wait for recovery to end\n" msgstr "" " -t, --recovery-timeout=СЕК время ожидания окончания восстановления\n" -#: pg_createsubscriber.c:258 +#: pg_createsubscriber.c:257 #, c-format msgid "" " -T, --enable-two-phase enable two-phase commit for all " @@ -1491,19 +1511,19 @@ msgstr "" " -T, --enable-two-phase включить двухфазную фиксацию для всех " "подписок\n" -#: pg_createsubscriber.c:259 +#: pg_createsubscriber.c:258 #, c-format msgid " -U, --subscriber-username=NAME user name for subscriber connection\n" msgstr "" " -U, --subscriber-username=ИМЯ имя пользователя для подключения " "подписчика\n" -#: pg_createsubscriber.c:260 +#: pg_createsubscriber.c:259 #, c-format msgid " -v, --verbose output verbose messages\n" msgstr " -v, --verbose выводить подробные сообщения\n" -#: pg_createsubscriber.c:261 +#: pg_createsubscriber.c:260 #, c-format msgid "" " --clean=OBJECTTYPE drop all objects of the specified type " @@ -1515,7 +1535,7 @@ msgstr "" "указанных\n" " баз на подписчике; принимает: \"%s\"\n" -#: pg_createsubscriber.c:263 +#: pg_createsubscriber.c:262 #, c-format msgid "" " --config-file=FILENAME use specified main server configuration\n" @@ -1525,215 +1545,215 @@ msgstr "" " конфигурации сервера при запуске целевого\n" " кластера\n" -#: pg_createsubscriber.c:265 +#: pg_createsubscriber.c:264 #, c-format msgid " --publication=NAME publication name\n" msgstr " --publication=ИМЯ имя публикации\n" -#: pg_createsubscriber.c:266 +#: pg_createsubscriber.c:265 #, c-format msgid " --replication-slot=NAME replication slot name\n" msgstr " --replication-slot=ИМЯ имя слота репликации\n" -#: pg_createsubscriber.c:267 +#: pg_createsubscriber.c:266 #, c-format msgid " --subscription=NAME subscription name\n" msgstr " --subscription=ИМЯ имя подписки\n" -#: pg_createsubscriber.c:268 +#: pg_createsubscriber.c:267 #, c-format msgid "" " -V, --version output version information, then exit\n" msgstr " -V, --version показать версию и выйти\n" -#: pg_createsubscriber.c:269 +#: pg_createsubscriber.c:268 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показать эту справку и выйти\n" -#: pg_createsubscriber.c:312 +#: pg_createsubscriber.c:311 #, c-format msgid "could not parse connection string: %s" msgstr "не удалось разобрать строку подключения: %s" -#: pg_createsubscriber.c:389 +#: pg_createsubscriber.c:388 #, c-format msgid "" "program \"%s\" is needed by %s but was not found in the same directory as " "\"%s\"" msgstr "программа \"%s\" нужна для %s, но она не найдена в каталоге \"%s\"" -#: pg_createsubscriber.c:392 +#: pg_createsubscriber.c:391 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "" "программа \"%s\" найдена программой \"%s\", но её версия отличается от " "версии %s" -#: pg_createsubscriber.c:412 +#: pg_createsubscriber.c:411 #, c-format msgid "checking if directory \"%s\" is a cluster data directory" msgstr "проверяется, является ли каталог \"%s\" каталогом данных кластера" -#: pg_createsubscriber.c:418 +#: pg_createsubscriber.c:417 #, c-format msgid "data directory \"%s\" does not exist" msgstr "каталог данных \"%s\" не существует" -#: pg_createsubscriber.c:426 +#: pg_createsubscriber.c:425 #, c-format msgid "directory \"%s\" is not a database cluster directory" msgstr "каталог \"%s\" не является каталогом кластера баз данных" -#: pg_createsubscriber.c:544 +#: pg_createsubscriber.c:543 #, c-format msgid "connection to database failed: %s" msgstr "не удалось подключиться к базе: %s" -#: pg_createsubscriber.c:557 streamutil.c:230 +#: pg_createsubscriber.c:556 streamutil.c:230 #, c-format msgid "could not clear \"search_path\": %s" msgstr "не удалось очистить \"search_path\": %s" -#: pg_createsubscriber.c:597 +#: pg_createsubscriber.c:596 #, c-format msgid "getting system identifier from publisher" msgstr "получение идентификатора системы с сервера публикации" -#: pg_createsubscriber.c:604 +#: pg_createsubscriber.c:603 #, c-format msgid "could not get system identifier: %s" msgstr "не удалось получить идентификатор системы: %s" -#: pg_createsubscriber.c:610 +#: pg_createsubscriber.c:609 #, c-format msgid "could not get system identifier: got %d rows, expected %d row" msgstr "" "не удалось получить идентификатор системы; получено строк: %d, ожидалось: %d" -#: pg_createsubscriber.c:617 +#: pg_createsubscriber.c:616 #, c-format msgid "system identifier is % on publisher" msgstr "идентификатор системы на стороне публикации: %" -#: pg_createsubscriber.c:637 +#: pg_createsubscriber.c:636 #, c-format msgid "getting system identifier from subscriber" msgstr "получение идентификатора системы с подписчика" -#: pg_createsubscriber.c:641 pg_createsubscriber.c:670 +#: pg_createsubscriber.c:640 pg_createsubscriber.c:669 #, c-format msgid "control file appears to be corrupt" msgstr "управляющий файл, по-видимому, испорчен" -#: pg_createsubscriber.c:645 pg_createsubscriber.c:688 +#: pg_createsubscriber.c:644 pg_createsubscriber.c:687 #, c-format msgid "system identifier is % on subscriber" msgstr "идентификатор системы на подписчике: %" -#: pg_createsubscriber.c:666 +#: pg_createsubscriber.c:665 #, c-format msgid "modifying system identifier of subscriber" msgstr "изменение идентификатора системы на подписчике" -#: pg_createsubscriber.c:683 +#: pg_createsubscriber.c:682 #, c-format msgid "dry-run: would set system identifier to % on subscriber" msgstr "" "холостой запуск: на подписчике будет установлен идентификатор системы " "%" -#: pg_createsubscriber.c:693 +#: pg_createsubscriber.c:692 #, c-format msgid "dry-run: would run pg_resetwal on the subscriber" msgstr "холостой запуск: будет выполнен сброс WAL (pg_resetwal) на подписчике" -#: pg_createsubscriber.c:695 +#: pg_createsubscriber.c:694 #, c-format msgid "running pg_resetwal on the subscriber" msgstr "запуск pg_resetwal на подписчике" -#: pg_createsubscriber.c:707 +#: pg_createsubscriber.c:706 #, c-format msgid "successfully reset WAL on the subscriber" msgstr "WAL на подписчике сброшен успешно" -#: pg_createsubscriber.c:709 +#: pg_createsubscriber.c:708 #, c-format msgid "could not reset WAL on subscriber: %s" msgstr "не удалось сбросить WAL на подписчике: %s" -#: pg_createsubscriber.c:733 +#: pg_createsubscriber.c:732 #, c-format msgid "could not obtain database OID: %s" msgstr "получить OID базы данных не удалось: %s" -#: pg_createsubscriber.c:740 +#: pg_createsubscriber.c:739 #, c-format msgid "could not obtain database OID: got %d rows, expected %d row" msgstr "получить OID базы данных не удалось; получено строк: %d, ожидалось: %d" -#: pg_createsubscriber.c:812 +#: pg_createsubscriber.c:811 #, c-format msgid "create replication slot \"%s\" on publisher" msgstr "создаётся слот репликации \"%s\" на подписчике" -#: pg_createsubscriber.c:832 +#: pg_createsubscriber.c:831 #, c-format msgid "could not write an additional WAL record: %s" msgstr "не удалось записать дополнительную запись WAL: %s" -#: pg_createsubscriber.c:858 +#: pg_createsubscriber.c:857 #, c-format msgid "could not obtain recovery progress: %s" msgstr "не удалось получить состояние восстановления: %s" -#: pg_createsubscriber.c:891 +#: pg_createsubscriber.c:890 #, c-format msgid "checking settings on publisher" msgstr "проверка параметров на стороне публикации" -#: pg_createsubscriber.c:901 +#: pg_createsubscriber.c:900 #, c-format msgid "primary server cannot be in recovery" msgstr "главный сервер не должен быть в состоянии восстановления" -#: pg_createsubscriber.c:927 +#: pg_createsubscriber.c:926 #, c-format msgid "could not obtain publisher settings: %s" msgstr "не удалось получить параметры с сервера публикации: %s" -#: pg_createsubscriber.c:956 +#: pg_createsubscriber.c:955 #, c-format msgid "publisher requires \"wal_level\" >= \"logical\"" msgstr "на стороне публикации требуется значение \"wal_level\" >= \"logical\"" -#: pg_createsubscriber.c:962 +#: pg_createsubscriber.c:961 #, c-format msgid "publisher requires %d replication slots, but only %d remain" msgstr "" "на стороне публикации требуется слотов репликации: %d, но доступно всего %d" -#: pg_createsubscriber.c:964 pg_createsubscriber.c:973 -#: pg_createsubscriber.c:1083 pg_createsubscriber.c:1092 -#: pg_createsubscriber.c:1101 +#: pg_createsubscriber.c:963 pg_createsubscriber.c:972 +#: pg_createsubscriber.c:1082 pg_createsubscriber.c:1091 +#: pg_createsubscriber.c:1100 #, c-format msgid "Increase the configuration parameter \"%s\" to at least %d." msgstr "Увеличьте значение параметра конфигурации \"%s\" как минимум до %d." -#: pg_createsubscriber.c:971 +#: pg_createsubscriber.c:970 #, c-format msgid "publisher requires %d WAL sender processes, but only %d remain" msgstr "" "на стороне публикации требуется процессов-передатчиков WAL: %d, но доступно " "всего %d" -#: pg_createsubscriber.c:980 +#: pg_createsubscriber.c:979 #, c-format msgid "two_phase option will not be enabled for replication slots" msgstr "параметр two_phase для слотов репликации не будет включён" -#: pg_createsubscriber.c:981 +#: pg_createsubscriber.c:980 #, c-format msgid "" "Subscriptions will be created with the two_phase option disabled. Prepared " @@ -1742,7 +1762,7 @@ msgstr "" "Подписки будут созданы с отключённым параметром two_phase. Подготовленные " "транзакции будут реплицироваться в момент выполнения COMMIT PREPARED." -#: pg_createsubscriber.c:983 +#: pg_createsubscriber.c:982 #, c-format msgid "" "You can use the command-line option --enable-two-phase to enable two_phase." @@ -1750,12 +1770,12 @@ msgstr "" "Для включения режима two_phase можно использовать параметр командной строки " "--enable-two-phase." -#: pg_createsubscriber.c:993 +#: pg_createsubscriber.c:992 #, c-format msgid "required WAL could be removed from the publisher" msgstr "нужные файлы WAL могли быть удалены с сервера публикации" -#: pg_createsubscriber.c:994 +#: pg_createsubscriber.c:993 #, c-format msgid "" "Set the configuration parameter \"%s\" to -1 to ensure that required WAL " @@ -1764,70 +1784,70 @@ msgstr "" "Чтобы необходимые файлы WAL не были удалены преждевременно, присвойте " "параметру конфигурации \"%s\" -1." -#: pg_createsubscriber.c:1026 +#: pg_createsubscriber.c:1025 #, c-format msgid "checking settings on subscriber" msgstr "проверка параметров на подписчике" -#: pg_createsubscriber.c:1033 +#: pg_createsubscriber.c:1032 #, c-format msgid "target server must be a standby" msgstr "целевой сервер должен быть резервным" -#: pg_createsubscriber.c:1057 +#: pg_createsubscriber.c:1056 #, c-format msgid "could not obtain subscriber settings: %s" msgstr "получить параметры подписчика не удалось: %s" -#: pg_createsubscriber.c:1081 +#: pg_createsubscriber.c:1080 #, c-format msgid "subscriber requires %d active replication origins, but only %d remain" msgstr "" "подписчику требуется активных слотов репликации: %d, но доступно всего %d" -#: pg_createsubscriber.c:1090 +#: pg_createsubscriber.c:1089 #, c-format msgid "subscriber requires %d logical replication workers, but only %d remain" msgstr "" "подписчику требуется процессов логической репликации: %d, но доступно всего " "%d" -#: pg_createsubscriber.c:1099 +#: pg_createsubscriber.c:1098 #, c-format msgid "subscriber requires %d worker processes, but only %d remain" msgstr "подписчику требуется рабочих процессов: %d, но доступно всего %d" -#: pg_createsubscriber.c:1135 +#: pg_createsubscriber.c:1139 #, c-format msgid "dry-run: would drop subscription \"%s\" in database \"%s\"" msgstr "холостой запуск: будет удалена подписка \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1139 +#: pg_createsubscriber.c:1143 #, c-format msgid "dropping subscription \"%s\" in database \"%s\"" msgstr "удаление подписки \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1146 +#: pg_createsubscriber.c:1150 #, c-format msgid "could not drop subscription \"%s\": %s" msgstr "удалить подписку \"%s\" не получилось: %s" -#: pg_createsubscriber.c:1181 +#: pg_createsubscriber.c:1185 #, c-format msgid "could not obtain pre-existing subscriptions: %s" msgstr "получить уже существующие подписки не удалось: %s" -#: pg_createsubscriber.c:1322 +#: pg_createsubscriber.c:1326 #, c-format msgid "could not drop replication slot \"%s\" on primary" msgstr "удалить слот репликации \"%s\" на главном сервере не получилось" -#: pg_createsubscriber.c:1356 +#: pg_createsubscriber.c:1360 #, c-format msgid "could not obtain failover replication slot information: %s" msgstr "получить информацию о переносимом слоте репликации не удалось: %s" -#: pg_createsubscriber.c:1358 pg_createsubscriber.c:1367 +#: pg_createsubscriber.c:1362 pg_createsubscriber.c:1371 #, c-format msgid "" "Drop the failover replication slots on subscriber soon to avoid retention of " @@ -1836,12 +1856,12 @@ msgstr "" "Удалите переносимые слоты репликации на подписчике незамедлительно во " "избежание накопления файлов WAL." -#: pg_createsubscriber.c:1366 +#: pg_createsubscriber.c:1370 #, c-format msgid "could not drop failover replication slot" msgstr "удалить переносимый слот репликации не получилось" -#: pg_createsubscriber.c:1389 +#: pg_createsubscriber.c:1393 #, c-format msgid "" "dry-run: would create the replication slot \"%s\" in database \"%s\" on " @@ -1850,42 +1870,42 @@ msgstr "" "холостой запуск: будет создан слот репликации \"%s\" в базе \"%s\" на " "стороне публикации" -#: pg_createsubscriber.c:1392 +#: pg_createsubscriber.c:1396 #, c-format msgid "creating the replication slot \"%s\" in database \"%s\" on publisher" msgstr "создание слота репликации \"%s\" в базе \"%s\" на стороне публикации" -#: pg_createsubscriber.c:1411 +#: pg_createsubscriber.c:1415 #, c-format msgid "could not create replication slot \"%s\" in database \"%s\": %s" msgstr "создать слот репликации \"%s\" в базе \"%s\" не удалось: %s" -#: pg_createsubscriber.c:1442 +#: pg_createsubscriber.c:1446 #, c-format msgid "dry-run: would drop the replication slot \"%s\" in database \"%s\"" msgstr "холостой запуск: будет удалён слот репликации \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1445 +#: pg_createsubscriber.c:1449 #, c-format msgid "dropping the replication slot \"%s\" in database \"%s\"" msgstr "удаление слота репликации \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1461 +#: pg_createsubscriber.c:1465 #, c-format msgid "could not drop replication slot \"%s\" in database \"%s\": %s" msgstr "удалить слот репликации \"%s\" в базе \"%s\" не получилось: %s" -#: pg_createsubscriber.c:1482 +#: pg_createsubscriber.c:1485 #, c-format msgid "pg_ctl failed with exit code %d" msgstr "команда pg_ctl завершилась с кодом ошибки %d" -#: pg_createsubscriber.c:1487 +#: pg_createsubscriber.c:1490 #, c-format msgid "pg_ctl was terminated by exception 0x%X" msgstr "команда pg_ctl была прервана исключением 0x%X" -#: pg_createsubscriber.c:1489 +#: pg_createsubscriber.c:1492 #, c-format msgid "" "See C include file \"ntstatus.h\" for a description of the hexadecimal value." @@ -1893,52 +1913,52 @@ msgstr "" "Описание этого шестнадцатеричного значения ищите во включаемом C-файле " "\"ntstatus.h\"" -#: pg_createsubscriber.c:1491 +#: pg_createsubscriber.c:1494 #, c-format msgid "pg_ctl was terminated by signal %d: %s" msgstr "команда pg_ctl была завершена сигналом %d: %s" -#: pg_createsubscriber.c:1497 +#: pg_createsubscriber.c:1500 #, c-format msgid "pg_ctl exited with unrecognized status %d" msgstr "команда pg_ctl завершилась с нераспознанным кодом состояния %d" -#: pg_createsubscriber.c:1500 +#: pg_createsubscriber.c:1503 #, c-format msgid "The failed command was: %s" msgstr "Ошибку вызвала команда: %s" -#: pg_createsubscriber.c:1550 +#: pg_createsubscriber.c:1553 #, c-format msgid "server was started" msgstr "сервер был запущен" -#: pg_createsubscriber.c:1565 +#: pg_createsubscriber.c:1568 #, c-format msgid "server was stopped" msgstr "сервер был остановлен" -#: pg_createsubscriber.c:1584 +#: pg_createsubscriber.c:1587 #, c-format msgid "waiting for the target server to reach the consistent state" msgstr "ожидание достижения целевым сервером согласованного состояния" -#: pg_createsubscriber.c:1602 +#: pg_createsubscriber.c:1605 #, c-format msgid "recovery timed out" msgstr "тайм-аут при восстановлении" -#: pg_createsubscriber.c:1615 +#: pg_createsubscriber.c:1618 #, c-format msgid "server did not end recovery" msgstr "сервер не завершил восстановление" -#: pg_createsubscriber.c:1617 +#: pg_createsubscriber.c:1620 #, c-format msgid "target server reached the consistent state" msgstr "целевой сервер достиг согласованного состояния" -#: pg_createsubscriber.c:1618 +#: pg_createsubscriber.c:1621 #, c-format msgid "" "If pg_createsubscriber fails after this point, you must recreate the " @@ -1947,82 +1967,82 @@ msgstr "" "Если в работе pg_createsubscriber произойдёт сбой после этого момента, " "продолжение возможно только после пересоздания физической реплики." -#: pg_createsubscriber.c:1645 pg_createsubscriber.c:1776 +#: pg_createsubscriber.c:1648 pg_createsubscriber.c:1777 #, c-format msgid "could not obtain publication information: %s" msgstr "получить информацию о публикации не удалось: %s" -#: pg_createsubscriber.c:1659 +#: pg_createsubscriber.c:1662 #, c-format msgid "publication \"%s\" already exists" msgstr "публикация \"%s\" уже существует" -#: pg_createsubscriber.c:1660 +#: pg_createsubscriber.c:1663 #, c-format msgid "Consider renaming this publication before continuing." msgstr "Чтобы продолжить, её можно переименовать." -#: pg_createsubscriber.c:1668 +#: pg_createsubscriber.c:1671 #, c-format msgid "dry-run: would create publication \"%s\" in database \"%s\"" msgstr "холостой запуск: будет создана публикация \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1671 +#: pg_createsubscriber.c:1674 #, c-format msgid "creating publication \"%s\" in database \"%s\"" msgstr "создаётся публикация \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1684 +#: pg_createsubscriber.c:1687 #, c-format msgid "could not create publication \"%s\" in database \"%s\": %s" msgstr "создать публикацию \"%s\" в базе \"%s\" не удалось: %s" -#: pg_createsubscriber.c:1715 +#: pg_createsubscriber.c:1717 #, c-format msgid "dry-run: would drop publication \"%s\" in database \"%s\"" msgstr "холостой запуск: будет удалена публикация \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1718 +#: pg_createsubscriber.c:1720 #, c-format msgid "dropping publication \"%s\" in database \"%s\"" msgstr "удаляется публикация \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1732 +#: pg_createsubscriber.c:1734 #, c-format msgid "could not drop publication \"%s\" in database \"%s\": %s" msgstr "удалить публикацию \"%s\" в базе \"%s\" не получилось: %s" -#: pg_createsubscriber.c:1769 +#: pg_createsubscriber.c:1770 #, c-format msgid "dropping all existing publications in database \"%s\"" msgstr "удаление всех существующих публикаций в базе \"%s\"" -#: pg_createsubscriber.c:1828 +#: pg_createsubscriber.c:1827 #, c-format msgid "dry-run: would create subscription \"%s\" in database \"%s\"" msgstr "холостой запуск: будет удалена подписка \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1831 +#: pg_createsubscriber.c:1830 #, c-format msgid "creating subscription \"%s\" in database \"%s\"" msgstr "создаётся подписка \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1853 +#: pg_createsubscriber.c:1852 #, c-format msgid "could not create subscription \"%s\" in database \"%s\": %s" msgstr "создать подписку \"%s\" в базе \"%s\" не удалось: %s" -#: pg_createsubscriber.c:1898 +#: pg_createsubscriber.c:1897 #, c-format msgid "could not obtain subscription OID: %s" msgstr "получить OID подписки не удалось: %s" -#: pg_createsubscriber.c:1905 +#: pg_createsubscriber.c:1904 #, c-format msgid "could not obtain subscription OID: got %d rows, expected %d row" msgstr "получить OID подписки не удалось; получено строк: %d, ожидалось: %d" -#: pg_createsubscriber.c:1930 +#: pg_createsubscriber.c:1929 #, c-format msgid "" "dry-run: would set the replication progress (node name \"%s\", LSN %s) in " @@ -2031,124 +2051,124 @@ msgstr "" "холостой запуск: будет установлено состояние репликации (имя узла \"%s\", " "LSN %s) в базе \"%s\"" -#: pg_createsubscriber.c:1933 +#: pg_createsubscriber.c:1932 #, c-format msgid "" "setting the replication progress (node name \"%s\", LSN %s) in database " "\"%s\"" msgstr "отражение состояния репликации (имя узла \"%s\", LSN %s) в базе \"%s\"" -#: pg_createsubscriber.c:1948 +#: pg_createsubscriber.c:1947 #, c-format msgid "could not set replication progress for subscription \"%s\": %s" msgstr "не удалось передать состояние репликации для подписки \"%s\": %s" -#: pg_createsubscriber.c:1980 +#: pg_createsubscriber.c:1979 #, c-format msgid "dry-run: would enable subscription \"%s\" in database \"%s\"" msgstr "холостой запуск: будет включена подписка \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1983 +#: pg_createsubscriber.c:1982 #, c-format msgid "enabling subscription \"%s\" in database \"%s\"" msgstr "включение подписки \"%s\" в базе \"%s\"" -#: pg_createsubscriber.c:1995 +#: pg_createsubscriber.c:1994 #, c-format msgid "could not enable subscription \"%s\": %s" msgstr "включить подписку \"%s\" не удалось: %s" -#: pg_createsubscriber.c:2041 +#: pg_createsubscriber.c:2040 #, c-format msgid "could not obtain a list of databases: %s" msgstr "не удалось получить список баз данных: %s" -#: pg_createsubscriber.c:2145 +#: pg_createsubscriber.c:2144 #, c-format msgid "cannot be executed by \"root\"" msgstr "программу не должен запускать root" -#: pg_createsubscriber.c:2146 +#: pg_createsubscriber.c:2145 #, c-format msgid "You must run %s as the PostgreSQL superuser." msgstr "Запускать %s нужно от имени суперпользователя PostgreSQL." -#: pg_createsubscriber.c:2169 +#: pg_createsubscriber.c:2168 #, c-format msgid "database \"%s\" specified more than once for -d/--database" msgstr "база \"%s\" указана в -d/--database неоднократно" -#: pg_createsubscriber.c:2210 +#: pg_createsubscriber.c:2209 #, c-format msgid "publication \"%s\" specified more than once for --publication" msgstr "публикация \"%s\" указана в --publication неоднократно" -#: pg_createsubscriber.c:2219 +#: pg_createsubscriber.c:2218 #, c-format msgid "replication slot \"%s\" specified more than once for --replication-slot" msgstr "слот репликации \"%s\" указан в --replication-slot неоднократно" -#: pg_createsubscriber.c:2228 +#: pg_createsubscriber.c:2227 #, c-format msgid "subscription \"%s\" specified more than once for --subscription" msgstr "подписка \"%s\" указана в --subscription неоднократно" -#: pg_createsubscriber.c:2234 +#: pg_createsubscriber.c:2233 #, c-format msgid "object type \"%s\" specified more than once for --clean" msgstr "тип объекта \"%s\" указан в --clean неоднократно" -#: pg_createsubscriber.c:2259 +#: pg_createsubscriber.c:2258 #, c-format msgid "options %s and %s cannot be used together" msgstr "параметры %s и %s исключают друг друга" -#: pg_createsubscriber.c:2278 +#: pg_createsubscriber.c:2277 #, c-format msgid "no subscriber data directory specified" msgstr "каталог данных подписчика не указан" -#: pg_createsubscriber.c:2289 +#: pg_createsubscriber.c:2288 #, c-format msgid "could not determine current directory" msgstr "не удалось определить текущий каталог" -#: pg_createsubscriber.c:2306 +#: pg_createsubscriber.c:2305 #, c-format msgid "no publisher connection string specified" msgstr "строка подключения к серверу публикации не указана" -#: pg_createsubscriber.c:2310 +#: pg_createsubscriber.c:2309 #, c-format msgid "validating publisher connection string" msgstr "проверяется строка подключения к серверу публикации" -#: pg_createsubscriber.c:2316 +#: pg_createsubscriber.c:2315 #, c-format msgid "validating subscriber connection string" msgstr "проверяется строка подключения к подписчику" -#: pg_createsubscriber.c:2333 +#: pg_createsubscriber.c:2332 #, c-format msgid "no database was specified" msgstr "база данных не указана" -#: pg_createsubscriber.c:2344 +#: pg_createsubscriber.c:2343 #, c-format msgid "database name \"%s\" was extracted from the publisher connection string" msgstr "имя базы \"%s\" извлечено из строки подключения к серверу публикации" -#: pg_createsubscriber.c:2349 +#: pg_createsubscriber.c:2348 #, c-format msgid "no database name specified" msgstr "имя базы данных не указано" -#: pg_createsubscriber.c:2359 +#: pg_createsubscriber.c:2358 #, c-format msgid "wrong number of publication names specified" msgstr "указано неверное количество имён публикаций" -#: pg_createsubscriber.c:2360 +#: pg_createsubscriber.c:2359 #, c-format msgid "" "The number of specified publication names (%d) must match the number of " @@ -2157,12 +2177,12 @@ msgstr "" "Количество указанных имён публикаций (%d) должно совпадать с количеством " "указанных имён баз (%d)." -#: pg_createsubscriber.c:2366 +#: pg_createsubscriber.c:2365 #, c-format msgid "wrong number of subscription names specified" msgstr "указано неверное количество имён подписок" -#: pg_createsubscriber.c:2367 +#: pg_createsubscriber.c:2366 #, c-format msgid "" "The number of specified subscription names (%d) must match the number of " @@ -2171,12 +2191,12 @@ msgstr "" "Количество указанных имён подписок (%d) должно совпадать с количеством " "указанных имён баз (%d)." -#: pg_createsubscriber.c:2373 +#: pg_createsubscriber.c:2372 #, c-format msgid "wrong number of replication slot names specified" msgstr "указано неверное количество имён слотов репликации" -#: pg_createsubscriber.c:2374 +#: pg_createsubscriber.c:2373 #, c-format msgid "" "The number of specified replication slot names (%d) must match the number of " @@ -2185,48 +2205,48 @@ msgstr "" "Количество указанных имён слотов репликации (%d) должно совпадать с " "количеством указанных имён баз (%d)." -#: pg_createsubscriber.c:2386 +#: pg_createsubscriber.c:2385 #, c-format msgid "invalid object type \"%s\" specified for %s" msgstr "неправильный тип объекта \"%s\" указан в %s" -#: pg_createsubscriber.c:2388 +#: pg_createsubscriber.c:2387 #, c-format msgid "The valid value is: \"%s\"" msgstr "Допустимое значение: \"%s\"" -#: pg_createsubscriber.c:2419 +#: pg_createsubscriber.c:2418 #, c-format msgid "subscriber data directory is not a copy of the source database cluster" msgstr "" "каталог данных подписчика не является копией исходного кластера баз данных" -#: pg_createsubscriber.c:2432 +#: pg_createsubscriber.c:2431 #, c-format msgid "standby server is running" msgstr "резервный сервер запущен" -#: pg_createsubscriber.c:2433 +#: pg_createsubscriber.c:2432 #, c-format msgid "Stop the standby server and try again." msgstr "Остановите резервный сервер и повторите попытку." -#: pg_createsubscriber.c:2442 +#: pg_createsubscriber.c:2441 #, c-format msgid "starting the standby server with command-line options" msgstr "резервный сервер запускается с параметрами командной строки" -#: pg_createsubscriber.c:2458 pg_createsubscriber.c:2493 +#: pg_createsubscriber.c:2457 pg_createsubscriber.c:2492 #, c-format msgid "stopping the subscriber" msgstr "подписчик останавливается" -#: pg_createsubscriber.c:2472 +#: pg_createsubscriber.c:2471 #, c-format msgid "starting the subscriber" msgstr "подписчик запускается" -#: pg_createsubscriber.c:2501 +#: pg_createsubscriber.c:2500 #, c-format msgid "Done!" msgstr "Готово!" @@ -2347,7 +2367,7 @@ msgstr "завершена передача журнала с позиции %X/ msgid "switched to timeline %u at %X/%X" msgstr "переключение на линию времени %u (позиция %X/%X)" -#: pg_receivewal.c:224 pg_recvlogical.c:1075 +#: pg_receivewal.c:224 pg_recvlogical.c:1079 #, c-format msgid "received interrupt signal, exiting" msgstr "получен сигнал прерывания, работа завершается" @@ -2426,7 +2446,7 @@ msgstr "" msgid "starting log streaming at %X/%X (timeline %u)" msgstr "начало передачи журнала с позиции %X/%X (линия времени %u)" -#: pg_receivewal.c:693 pg_recvlogical.c:809 +#: pg_receivewal.c:693 pg_recvlogical.c:813 #, c-format msgid "could not parse end position \"%s\"" msgstr "не удалось разобрать конечную позицию \"%s\"" @@ -2459,23 +2479,23 @@ msgstr "" "подключение для репликации через слот \"%s\" оказалось привязано к базе " "данных" -#: pg_receivewal.c:878 pg_recvlogical.c:993 +#: pg_receivewal.c:878 pg_recvlogical.c:997 #, c-format msgid "dropping replication slot \"%s\"" msgstr "удаление слота репликации \"%s\"" -#: pg_receivewal.c:889 pg_recvlogical.c:1003 +#: pg_receivewal.c:889 pg_recvlogical.c:1007 #, c-format msgid "creating replication slot \"%s\"" msgstr "создание слота репликации \"%s\"" -#: pg_receivewal.c:918 pg_recvlogical.c:1028 +#: pg_receivewal.c:918 pg_recvlogical.c:1032 #, c-format msgid "disconnected" msgstr "отключение" #. translator: check source for value for %d -#: pg_receivewal.c:922 pg_recvlogical.c:1032 +#: pg_receivewal.c:922 pg_recvlogical.c:1036 #, c-format msgid "disconnected; waiting %d seconds to try again" msgstr "отключение; через %d сек. последует повторное подключение" @@ -2602,109 +2622,109 @@ msgstr "не удалось отправить пакет ответа: %s" msgid "starting log streaming at %X/%X (slot %s)" msgstr "начало передачи журнала с позиции %X/%X (слот %s)" -#: pg_recvlogical.c:283 +#: pg_recvlogical.c:287 #, c-format msgid "streaming initiated" msgstr "передача запущена" -#: pg_recvlogical.c:348 +#: pg_recvlogical.c:352 #, c-format msgid "could not open log file \"%s\": %m" msgstr "не удалось открыть файл протокола \"%s\": %m" -#: pg_recvlogical.c:377 receivelog.c:889 +#: pg_recvlogical.c:381 receivelog.c:895 #, c-format msgid "invalid socket: %s" msgstr "неверный сокет: %s" -#: pg_recvlogical.c:430 receivelog.c:917 +#: pg_recvlogical.c:434 receivelog.c:923 #, c-format msgid "%s() failed: %m" msgstr "ошибка в %s(): %m" -#: pg_recvlogical.c:437 receivelog.c:966 +#: pg_recvlogical.c:441 receivelog.c:972 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "не удалось получить данные из потока WAL: %s" -#: pg_recvlogical.c:479 pg_recvlogical.c:530 receivelog.c:1010 -#: receivelog.c:1073 +#: pg_recvlogical.c:483 pg_recvlogical.c:534 receivelog.c:1016 +#: receivelog.c:1079 #, c-format msgid "streaming header too small: %d" msgstr "заголовок потока слишком мал: %d" -#: pg_recvlogical.c:514 receivelog.c:846 +#: pg_recvlogical.c:518 receivelog.c:852 #, c-format msgid "unrecognized streaming header: \"%c\"" msgstr "нераспознанный заголовок потока: \"%c\"" -#: pg_recvlogical.c:568 pg_recvlogical.c:580 +#: pg_recvlogical.c:572 pg_recvlogical.c:584 #, c-format msgid "could not write %d bytes to log file \"%s\": %m" msgstr "не удалось записать %d Б в файл журнала \"%s\": %m" -#: pg_recvlogical.c:638 receivelog.c:641 receivelog.c:678 +#: pg_recvlogical.c:642 receivelog.c:647 receivelog.c:684 #, c-format msgid "unexpected termination of replication stream: %s" msgstr "неожиданный конец потока репликации: %s" -#: pg_recvlogical.c:804 +#: pg_recvlogical.c:808 #, c-format msgid "could not parse start position \"%s\"" msgstr "не удалось разобрать начальную позицию \"%s\"" -#: pg_recvlogical.c:882 +#: pg_recvlogical.c:886 #, c-format msgid "no slot specified" msgstr "слот не указан" -#: pg_recvlogical.c:889 +#: pg_recvlogical.c:893 #, c-format msgid "no target file specified" msgstr "целевой файл не задан" -#: pg_recvlogical.c:896 +#: pg_recvlogical.c:900 #, c-format msgid "no database specified" msgstr "база данных не задана" -#: pg_recvlogical.c:903 +#: pg_recvlogical.c:907 #, c-format msgid "at least one action needs to be specified" msgstr "необходимо задать минимум одно действие" -#: pg_recvlogical.c:910 +#: pg_recvlogical.c:914 #, c-format msgid "cannot use --create-slot or --start together with --drop-slot" msgstr "--create-slot или --start нельзя применять вместе с --drop-slot" -#: pg_recvlogical.c:917 +#: pg_recvlogical.c:921 #, c-format msgid "cannot use --create-slot or --drop-slot together with --startpos" msgstr "--create-slot или --drop-slot нельзя применять вместе с --startpos" -#: pg_recvlogical.c:924 +#: pg_recvlogical.c:928 #, c-format msgid "--endpos may only be specified with --start" msgstr "--endpos можно задать только вместе с --start" -#: pg_recvlogical.c:933 pg_recvlogical.c:940 +#: pg_recvlogical.c:937 pg_recvlogical.c:944 #, c-format msgid "%s may only be specified with --create-slot" msgstr "%s можно задать только вместе с --create-slot" -#: pg_recvlogical.c:977 +#: pg_recvlogical.c:981 #, c-format msgid "could not establish database-specific replication connection" msgstr "" "не удалось установить подключение для репликации к определённой базе данных" -#: pg_recvlogical.c:1078 +#: pg_recvlogical.c:1082 #, c-format msgid "end position %X/%X reached by keepalive" msgstr "конечная позиция %X/%X достигнута при обработке keepalive" -#: pg_recvlogical.c:1083 +#: pg_recvlogical.c:1087 #, c-format msgid "end position %X/%X reached by WAL record at %X/%X" msgstr "конечная позиция %X/%X достигнута при обработке записи WAL %X/%X" @@ -2756,7 +2776,7 @@ msgstr "не удалось открыть файл журнала предза msgid "not renaming \"%s\", segment is not complete" msgstr "файл сегмента \"%s\" не переименовывается, так как он неполный" -#: receivelog.c:226 receivelog.c:316 receivelog.c:687 +#: receivelog.c:226 receivelog.c:316 receivelog.c:693 #, c-format msgid "could not close file \"%s\": %s" msgstr "не удалось закрыть файл \"%s\": %s" @@ -2794,7 +2814,7 @@ msgstr "" "несовместимая версия сервера %s; клиент не поддерживает репликацию с " "серверов версии выше %s" -#: receivelog.c:507 +#: receivelog.c:504 #, c-format msgid "" "system identifier does not match between base backup and streaming connection" @@ -2802,12 +2822,12 @@ msgstr "" "системный идентификатор базовой резервной копии отличается от идентификатора " "потоковой передачи" -#: receivelog.c:515 +#: receivelog.c:512 #, c-format msgid "starting timeline %u is not present in the server" msgstr "на сервере нет начальной линии времени %u" -#: receivelog.c:554 +#: receivelog.c:553 #, c-format msgid "" "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, " @@ -2816,12 +2836,12 @@ msgstr "" "сервер вернул неожиданный ответ на команду TIMELINE_HISTORY; получено строк: " "%d, полей: %d, а ожидалось строк: %d, полей: %d" -#: receivelog.c:625 +#: receivelog.c:631 #, c-format msgid "server reported unexpected next timeline %u, following timeline %u" msgstr "сервер неожиданно сообщил линию времени %u после линии времени %u" -#: receivelog.c:631 +#: receivelog.c:637 #, c-format msgid "" "server stopped streaming timeline %u at %X/%X, but reported next timeline %u " @@ -2830,12 +2850,12 @@ msgstr "" "сервер прекратил передачу линии времени %u в %X/%X, но сообщил, что " "следующая линии времени %u начнётся в %X/%X" -#: receivelog.c:671 +#: receivelog.c:677 #, c-format msgid "replication stream was terminated before stop point" msgstr "поток репликации закончился до точки остановки" -#: receivelog.c:717 +#: receivelog.c:723 #, c-format msgid "" "unexpected result set after end-of-timeline: got %d rows and %d fields, " @@ -2844,32 +2864,32 @@ msgstr "" "сервер вернул неожиданный набор данных после конца линии времени; получено " "строк: %d, полей: %d, а ожидалось строк: %d, полей: %d" -#: receivelog.c:726 +#: receivelog.c:732 #, c-format msgid "could not parse next timeline's starting point \"%s\"" msgstr "не удалось разобрать начальную точку следующей линии времени \"%s\"" -#: receivelog.c:774 receivelog.c:1029 walmethods.c:1206 +#: receivelog.c:780 receivelog.c:1035 walmethods.c:1206 #, c-format msgid "could not fsync file \"%s\": %s" msgstr "не удалось синхронизировать с ФС файл \"%s\": %s" -#: receivelog.c:1090 +#: receivelog.c:1096 #, c-format msgid "received write-ahead log record for offset %u with no file open" msgstr "получена запись журнала предзаписи по смещению %u, но файл не открыт" -#: receivelog.c:1100 +#: receivelog.c:1106 #, c-format msgid "got WAL data offset %08x, expected %08x" msgstr "получено смещение данных WAL %08x, но ожидалось %08x" -#: receivelog.c:1135 +#: receivelog.c:1141 #, c-format msgid "could not write %d bytes to WAL file \"%s\": %s" msgstr "не удалось записать %d Б в файл WAL \"%s\": %s" -#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1228 +#: receivelog.c:1166 receivelog.c:1206 receivelog.c:1234 #, c-format msgid "could not send copy-end packet: %s" msgstr "не удалось отправить пакет \"конец COPY\": %s" @@ -2945,7 +2965,7 @@ msgstr "" "не удалось идентифицировать систему; получено строк: %d, полей: %d " "(ожидалось: %d и %d (или более))" -#: streamutil.c:519 +#: streamutil.c:520 #, c-format msgid "" "could not read replication slot \"%s\": got %d rows and %d fields, expected " @@ -2954,23 +2974,23 @@ msgstr "" "прочитать из слота репликации \"%s\" не удалось; получено строк: %d, полей: " "%d (ожидалось: %d и %d)" -#: streamutil.c:531 +#: streamutil.c:532 #, c-format msgid "replication slot \"%s\" does not exist" msgstr "слот репликации \"%s\" не существует" -#: streamutil.c:542 +#: streamutil.c:543 #, c-format msgid "expected a physical replication slot, got type \"%s\" instead" msgstr "ожидался слот физической репликации, вместо этого получен тип \"%s\"" -#: streamutil.c:556 +#: streamutil.c:557 #, c-format msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\"" msgstr "" "не удалось разобрать позицию restart_lsn \"%s\" для слота репликации \"%s\"" -#: streamutil.c:678 +#: streamutil.c:683 #, c-format msgid "" "could not create replication slot \"%s\": got %d rows and %d fields, " @@ -2979,7 +2999,7 @@ msgstr "" "создать слот репликации \"%s\" не удалось; получено строк: %d, полей: %d " "(ожидалось: %d и %d)" -#: streamutil.c:722 +#: streamutil.c:727 #, c-format msgid "" "could not drop replication slot \"%s\": got %d rows and %d fields, expected " @@ -3076,9 +3096,6 @@ msgstr "не удалось закрыть поток сжатых данных" #~ msgstr "" #~ " -Z, --compress=0-9 установить уровень сжатия выходного архива\n" -#~ msgid "invalid tar block header size: %zu" -#~ msgstr "неверный размер заголовка блока tar: %zu" - #~ msgid "unrecognized link indicator \"%c\"" #~ msgstr "нераспознанный индикатор связи \"%c\"" diff --git a/src/bin/pg_checksums/po/ru.po b/src/bin/pg_checksums/po/ru.po index a0cbfa15d6b..148ac6fdb4e 100644 --- a/src/bin/pg_checksums/po/ru.po +++ b/src/bin/pg_checksums/po/ru.po @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2019, 2020, 2021, 2022, 2024, 2025 Alexander Lakhin +# SPDX-FileCopyrightText: 2019, 2020, 2021, 2022, 2024, 2025, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: pg_verify_checksums (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" -"PO-Revision-Date: 2025-08-31 07:39+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:48+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -88,17 +88,27 @@ msgstr "не удалось записать файл \"%s\": %m" msgid "could not fsync file \"%s\": %m" msgstr "не удалось синхронизировать с ФС файл \"%s\": %m" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/file_utils.c:75 #, c-format msgid "could not synchronize file system for file \"%s\": %m" diff --git a/src/bin/pg_combinebackup/po/ru.po b/src/bin/pg_combinebackup/po/ru.po index c02e8ab86a2..43e607181f2 100644 --- a/src/bin/pg_combinebackup/po/ru.po +++ b/src/bin/pg_combinebackup/po/ru.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_combinebackup (PostgreSQL) 17\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-10 08:01+0300\n" -"PO-Revision-Date: 2026-02-07 09:22+0200\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:49+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -53,7 +53,7 @@ msgstr "не удалось прочитать файл \"%s\" (прочитан #: ../../common/controldata_utils.c:132 ../../common/controldata_utils.c:280 #: backup_label.c:174 copy_file.c:71 pg_combinebackup.c:548 -#: pg_combinebackup.c:1185 reconstruct.c:369 reconstruct.c:742 +#: pg_combinebackup.c:1185 reconstruct.c:369 reconstruct.c:745 #: write_manifest.c:187 #, c-format msgid "could not close file \"%s\": %m" @@ -88,7 +88,7 @@ msgstr "" msgid "could not open file \"%s\": %m" msgstr "не удалось открыть файл \"%s\": %m" -#: ../../common/controldata_utils.c:249 backup_label.c:160 reconstruct.c:761 +#: ../../common/controldata_utils.c:249 backup_label.c:160 reconstruct.c:764 #: write_manifest.c:260 #, c-format msgid "could not write file \"%s\": %m" @@ -120,17 +120,27 @@ msgstr "буфер назначения слишком мал" msgid "OpenSSL failure" msgstr "ошибка OpenSSL" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/file_utils.c:75 #, c-format msgid "could not synchronize file system for file \"%s\": %m" @@ -479,13 +489,13 @@ msgstr "%s: не удалось найти %s" msgid "%s: %s requires %s" msgstr "%s: %s требует %s" -#: backup_label.c:162 reconstruct.c:763 write_manifest.c:262 +#: backup_label.c:162 reconstruct.c:766 write_manifest.c:262 #, c-format msgid "could not write file \"%s\": wrote %d of %d" msgstr "не удалось записать файл \"%s\" (записано байт: %d из %d)" -#: backup_label.c:166 copy_file.c:160 copy_file.c:207 reconstruct.c:723 -#: reconstruct.c:769 write_manifest.c:270 +#: backup_label.c:166 copy_file.c:160 copy_file.c:207 reconstruct.c:726 +#: reconstruct.c:772 write_manifest.c:270 #, c-format msgid "could not update checksum of file \"%s\"" msgstr "не удалось изменить контекст контрольной суммы файла \"%s\"" @@ -501,7 +511,7 @@ msgid "could not write to file \"%s\", offset %u: wrote %d of %d" msgstr "" "не удалось записать в файл \"%s\" (смещение %u, записано байт: %d из %d)" -#: copy_file.c:213 reconstruct.c:786 +#: copy_file.c:213 reconstruct.c:789 #, c-format msgid "could not read from file \"%s\": %m" msgstr "не удалось прочитать файл \"%s\": %m" @@ -531,7 +541,7 @@ msgstr "клонирование файлов не поддерживается msgid "error while copying file range from \"%s\" to \"%s\": %m" msgstr "ошибка при копировании фрагмента файла \"%s\" в \"%s\": %m" -#: copy_file.c:299 pg_combinebackup.c:269 reconstruct.c:726 +#: copy_file.c:299 pg_combinebackup.c:269 reconstruct.c:729 #, c-format msgid "copy_file_range not supported on this platform" msgstr "copy_file_range не поддерживается в этой ОС" @@ -971,7 +981,13 @@ msgstr "" msgid "could not read file \"%s\": read %d of %u" msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d из %u)" -#: reconstruct.c:788 +#: reconstruct.c:709 +#, c-format +msgid "unexpected end of file while copying file range from \"%s\" to \"%s\"" +msgstr "" +"неожиданный конец файла при копировании фрагмента файла из \"%s\" в \"%s\"" + +#: reconstruct.c:791 #, c-format msgid "could not read from file \"%s\", offset %llu: read %d of %d" msgstr "" diff --git a/src/bin/pg_config/po/ru.po b/src/bin/pg_config/po/ru.po index 35580c39bcc..43d60994020 100644 --- a/src/bin/pg_config/po/ru.po +++ b/src/bin/pg_config/po/ru.po @@ -5,13 +5,13 @@ # Serguei A. Mokhov , 2004-2005. # Sergey Burladyan , 2009, 2012. # Andrey Sudnik , 2010. -# Alexander Lakhin , 2012-2016, 2017, 2019, 2020, 2021, 2023, 2024. +# SPDX-FileCopyrightText: 2012-2016, 2017, 2019, 2020, 2021, 2023, 2024, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: pg_config (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" -"PO-Revision-Date: 2024-09-04 13:45+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:49+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -72,17 +72,27 @@ msgstr "ошибка в %s(): %m" msgid "out of memory" msgstr "нехватка памяти" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: pg_config.c:73 #, c-format msgid "" diff --git a/src/bin/pg_controldata/po/de.po b/src/bin/pg_controldata/po/de.po index a69020806aa..d691086db17 100644 --- a/src/bin/pg_controldata/po/de.po +++ b/src/bin/pg_controldata/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-28 19:26+0000\n" -"PO-Revision-Date: 2026-04-13 11:25+0200\n" +"POT-Creation-Date: 2026-08-04 09:57+0000\n" +"PO-Revision-Date: 2026-08-04 12:11+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -305,248 +305,255 @@ msgstr "PrevTimeLineID des letzten Checkpoints: %u\n" msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "full_page_writes des letzten Checkpoints: %s\n" -#: pg_controldata.c:266 pg_controldata.c:309 pg_controldata.c:321 +#: pg_controldata.c:266 pg_controldata.c:268 pg_controldata.c:311 +#: pg_controldata.c:323 msgid "off" msgstr "aus" -#: pg_controldata.c:266 pg_controldata.c:309 pg_controldata.c:321 +#: pg_controldata.c:266 pg_controldata.c:268 pg_controldata.c:311 +#: pg_controldata.c:323 msgid "on" msgstr "an" #: pg_controldata.c:267 #, c-format +msgid "Latest checkpoint's logical decoding: %s\n" +msgstr "Logical Decoding des letzten Checkpoints: %s\n" + +#: pg_controldata.c:269 +#, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "NextXID des letzten Checkpoints: %u:%u\n" -#: pg_controldata.c:270 +#: pg_controldata.c:272 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "NextOID des letzten Checkpoints: %u\n" -#: pg_controldata.c:272 +#: pg_controldata.c:274 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "NextMultiXactId des letzten Checkpoints: %u\n" -#: pg_controldata.c:274 +#: pg_controldata.c:276 #, c-format msgid "Latest checkpoint's NextMultiOffset: %\n" msgstr "NextMultiOffset des letzten Checkpoints: %\n" -#: pg_controldata.c:276 +#: pg_controldata.c:278 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "oldestXID des letzten Checkpoints: %u\n" -#: pg_controldata.c:278 +#: pg_controldata.c:280 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "DB der oldestXID des letzten Checkpoints: %u\n" -#: pg_controldata.c:280 +#: pg_controldata.c:282 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "oldestActiveXID des letzten Checkpoints: %u\n" -#: pg_controldata.c:282 +#: pg_controldata.c:284 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "oldestMultiXid des letzten Checkpoints: %u\n" -#: pg_controldata.c:284 +#: pg_controldata.c:286 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "DB des oldestMulti des letzten Checkpoints: %u\n" -#: pg_controldata.c:286 +#: pg_controldata.c:288 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "oldestCommitTsXid des letzten Checkpoints: %u\n" -#: pg_controldata.c:288 +#: pg_controldata.c:290 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "newestCommitTsXid des letzten Checkpoints: %u\n" -#: pg_controldata.c:290 +#: pg_controldata.c:292 #, c-format msgid "Latest checkpoint's data_checksum_version:%u\n" msgstr "data_checksum_version des letzten Checkpoints: %u\n" -#: pg_controldata.c:292 +#: pg_controldata.c:294 #, c-format msgid "Time of latest checkpoint: %s\n" msgstr "Zeit des letzten Checkpoints: %s\n" -#: pg_controldata.c:294 +#: pg_controldata.c:296 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%08X\n" msgstr "Fake-LSN-Zähler für ungeloggte Relationen: %X/%08X\n" -#: pg_controldata.c:296 +#: pg_controldata.c:298 #, c-format msgid "Minimum recovery ending location: %X/%08X\n" msgstr "Minimaler Wiederherstellungsendpunkt: %X/%08X\n" -#: pg_controldata.c:298 +#: pg_controldata.c:300 #, c-format msgid "Min recovery ending loc's timeline: %u\n" msgstr "Zeitleiste des minimalen Wiederherstellungsendpunkts: %u\n" -#: pg_controldata.c:300 +#: pg_controldata.c:302 #, c-format msgid "Backup start location: %X/%08X\n" msgstr "Backup-Startpunkt: %X/%08X\n" -#: pg_controldata.c:302 +#: pg_controldata.c:304 #, c-format msgid "Backup end location: %X/%08X\n" msgstr "Backup-Endpunkt: %X/%08X\n" -#: pg_controldata.c:304 +#: pg_controldata.c:306 #, c-format msgid "End-of-backup record required: %s\n" msgstr "End-of-Backup-Eintrag erforderlich: %s\n" -#: pg_controldata.c:305 +#: pg_controldata.c:307 msgid "no" msgstr "nein" -#: pg_controldata.c:305 +#: pg_controldata.c:307 msgid "yes" msgstr "ja" -#: pg_controldata.c:306 +#: pg_controldata.c:308 #, c-format msgid "wal_level setting: %s\n" msgstr "wal_level-Einstellung: %s\n" -#: pg_controldata.c:308 +#: pg_controldata.c:310 #, c-format msgid "wal_log_hints setting: %s\n" msgstr "wal_log_hints-Einstellung: %s\n" -#: pg_controldata.c:310 +#: pg_controldata.c:312 #, c-format msgid "max_connections setting: %d\n" msgstr "max_connections-Einstellung: %d\n" -#: pg_controldata.c:312 +#: pg_controldata.c:314 #, c-format msgid "max_worker_processes setting: %d\n" msgstr "max_worker_processes-Einstellung: %d\n" -#: pg_controldata.c:314 +#: pg_controldata.c:316 #, c-format msgid "max_wal_senders setting: %d\n" msgstr "max_wal_senders-Einstellung: %d\n" -#: pg_controldata.c:316 +#: pg_controldata.c:318 #, c-format msgid "max_prepared_xacts setting: %d\n" msgstr "max_prepared_xacts-Einstellung: %d\n" -#: pg_controldata.c:318 +#: pg_controldata.c:320 #, c-format msgid "max_locks_per_xact setting: %d\n" msgstr "max_locks_per_xact-Einstellung: %d\n" -#: pg_controldata.c:320 +#: pg_controldata.c:322 #, c-format msgid "track_commit_timestamp setting: %s\n" msgstr "track_commit_timestamp-Einstellung: %s\n" -#: pg_controldata.c:322 +#: pg_controldata.c:324 #, c-format msgid "Maximum data alignment: %u\n" msgstr "Maximale Datenausrichtung (Alignment): %u\n" -#: pg_controldata.c:325 +#: pg_controldata.c:327 #, c-format msgid "Database block size: %u\n" msgstr "Datenbankblockgröße: %u\n" -#: pg_controldata.c:327 +#: pg_controldata.c:329 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Blöcke pro Segment: %u\n" -#: pg_controldata.c:329 +#: pg_controldata.c:331 #, c-format msgid "Pages per SLRU segment: %u\n" msgstr "Seiten pro SLRU-Segment: %u\n" -#: pg_controldata.c:331 +#: pg_controldata.c:333 #, c-format msgid "WAL block size: %u\n" msgstr "WAL-Blockgröße: %u\n" -#: pg_controldata.c:333 +#: pg_controldata.c:335 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Bytes pro WAL-Segment: %u\n" -#: pg_controldata.c:335 +#: pg_controldata.c:337 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "Maximale Bezeichnerlänge: %u\n" -#: pg_controldata.c:337 +#: pg_controldata.c:339 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "Maximale Spalten in einem Index: %u\n" -#: pg_controldata.c:339 +#: pg_controldata.c:341 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "Maximale Größe eines Stücks TOAST: %u\n" -#: pg_controldata.c:341 +#: pg_controldata.c:343 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Größe eines Large-Object-Chunks: %u\n" -#: pg_controldata.c:344 +#: pg_controldata.c:346 #, c-format msgid "Date/time type storage: %s\n" msgstr "Speicherung von Datum/Zeit-Typen: %s\n" -#: pg_controldata.c:345 +#: pg_controldata.c:347 msgid "64-bit integers" msgstr "64-Bit-Ganzzahlen" -#: pg_controldata.c:346 +#: pg_controldata.c:348 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Übergabe von Float8-Argumenten: %s\n" -#: pg_controldata.c:347 +#: pg_controldata.c:349 msgid "by reference" msgstr "Referenz" -#: pg_controldata.c:347 +#: pg_controldata.c:349 msgid "by value" msgstr "Wert" -#: pg_controldata.c:348 +#: pg_controldata.c:350 #, c-format msgid "Data page checksum version: %u\n" msgstr "Datenseitenprüfsummenversion: %u\n" -#: pg_controldata.c:350 +#: pg_controldata.c:352 #, c-format msgid "Default char data signedness: %s\n" msgstr "Standard für Vorzeichen von »char«-Daten: %s\n" -#: pg_controldata.c:351 +#: pg_controldata.c:353 msgid "signed" msgstr "mit Vorzeichen" -#: pg_controldata.c:351 +#: pg_controldata.c:353 msgid "unsigned" msgstr "ohne Vorzeichen" -#: pg_controldata.c:352 +#: pg_controldata.c:354 #, c-format msgid "Mock authentication nonce: %s\n" msgstr "Mock-Authentifizierungs-Nonce: %s\n" diff --git a/src/bin/pg_controldata/po/ka.po b/src/bin/pg_controldata/po/ka.po index 4ffbe6a9dd6..15e2477e366 100644 --- a/src/bin/pg_controldata/po/ka.po +++ b/src/bin/pg_controldata/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_controldata (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-13 06:27+0000\n" -"PO-Revision-Date: 2026-05-13 09:09+0200\n" +"POT-Creation-Date: 2026-07-25 01:57+0000\n" +"PO-Revision-Date: 2026-07-25 04:35+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -303,251 +303,257 @@ msgstr "უახლესი საკონტროლო წერტილ msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "უახლესი უკანასკნელი საკონტროლო წერტილის full_page_writes: %s\n" -#: pg_controldata.c:266 pg_controldata.c:309 pg_controldata.c:321 +#: pg_controldata.c:266 pg_controldata.c:268 pg_controldata.c:311 +#: pg_controldata.c:323 msgid "off" msgstr "გამორთული" -#: pg_controldata.c:266 pg_controldata.c:309 pg_controldata.c:321 +#: pg_controldata.c:266 pg_controldata.c:268 pg_controldata.c:311 +#: pg_controldata.c:323 msgid "on" msgstr "ჩართ" #: pg_controldata.c:267 #, c-format +msgid "Latest checkpoint's logical decoding: %s\n" +msgstr "უახლესი საკონტროლო წერტილის ლოგიკური გაშიფვრა: %s\n" + +#: pg_controldata.c:269 +#, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "უახლესი საკონტროლო წერტილის NextXID: %u:%u\n" -#: pg_controldata.c:270 +#: pg_controldata.c:272 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "უახლესი საკონტროლო წერტილის NextOID: %u\n" -#: pg_controldata.c:272 +#: pg_controldata.c:274 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "უახლესი საკონტროლო წერტილის NextMultiXactId: %u\n" -#: pg_controldata.c:274 +#: pg_controldata.c:276 #, c-format msgid "Latest checkpoint's NextMultiOffset: %\n" msgstr "" "უახლესი საკონტროლო წერტილის NextMultiOffset: %\n" "\n" -#: pg_controldata.c:276 +#: pg_controldata.c:278 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "უახლესი საკონტროლო წერტილის oldestXID: %u\n" -#: pg_controldata.c:278 +#: pg_controldata.c:280 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "უახლესი საკონტროლო წერტილის oldestXID's DB: %u\n" -#: pg_controldata.c:280 +#: pg_controldata.c:282 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "უახლესი საკონტროლო წერტილის oldestActiveXID: %u\n" -#: pg_controldata.c:282 +#: pg_controldata.c:284 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "უახლესი საკონტროლო წერტილის oldestMultiXid: %u\n" -#: pg_controldata.c:284 +#: pg_controldata.c:286 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "უახლესი საკონტროლო წერტილის oldestMulti's DB: %u\n" -#: pg_controldata.c:286 +#: pg_controldata.c:288 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "უახლესი საკონტროლო წერტილის oldestCommitTsXid:%u\n" -#: pg_controldata.c:288 +#: pg_controldata.c:290 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "უახლესი საკონტროლო წერტილის newestCommitTsXid:%u\n" -#: pg_controldata.c:290 +#: pg_controldata.c:292 #, c-format msgid "Latest checkpoint's data_checksum_version:%u\n" msgstr "უახლესი საკონტროლო წერტილის data_checksum_version:%u\n" -#: pg_controldata.c:292 +#: pg_controldata.c:294 #, c-format msgid "Time of latest checkpoint: %s\n" msgstr "უახლესი საკონტოლო წერტილის დრო: %s\n" -#: pg_controldata.c:294 +#: pg_controldata.c:296 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%08X\n" msgstr "LSN-ის ყალბი მთვლელი არაჟურნალიზებადი ურთ-თვის: %X/%08X\n" -#: pg_controldata.c:296 +#: pg_controldata.c:298 #, c-format msgid "Minimum recovery ending location: %X/%08X\n" msgstr "მინიმალური აღდგენის დასასრულის მდებარეობა %X/%08X\n" -#: pg_controldata.c:298 +#: pg_controldata.c:300 #, c-format msgid "Min recovery ending loc's timeline: %u\n" msgstr "მინ. აღდგ დასასრ მდებარ დროის ხაზი: %u\n" -#: pg_controldata.c:300 +#: pg_controldata.c:302 #, c-format msgid "Backup start location: %X/%08X\n" msgstr "მარქაფის დაწყების მდებარეობა: %X/%08X\n" -#: pg_controldata.c:302 +#: pg_controldata.c:304 #, c-format msgid "Backup end location: %X/%08X\n" msgstr "მარქაფს დასასრულის მდებარეობა: %X/%08X\n" -#: pg_controldata.c:304 +#: pg_controldata.c:306 #, c-format msgid "End-of-backup record required: %s\n" msgstr "მარქაფის-ბოლო ჩანაწერი აუცილებელია: %s\n" -#: pg_controldata.c:305 +#: pg_controldata.c:307 msgid "no" msgstr "არა" -#: pg_controldata.c:305 +#: pg_controldata.c:307 msgid "yes" msgstr "დიახ" -#: pg_controldata.c:306 +#: pg_controldata.c:308 #, c-format msgid "wal_level setting: %s\n" msgstr "wal_level პარამეტრი: %s\n" -#: pg_controldata.c:308 +#: pg_controldata.c:310 #, c-format msgid "wal_log_hints setting: %s\n" msgstr "wal_log_hints პარამეტრი: %s\n" -#: pg_controldata.c:310 +#: pg_controldata.c:312 #, c-format msgid "max_connections setting: %d\n" msgstr "max_connections პარამეტრი: %d\n" -#: pg_controldata.c:312 +#: pg_controldata.c:314 #, c-format msgid "max_worker_processes setting: %d\n" msgstr "max_worker_processes პარამეტრი: %d\n" -#: pg_controldata.c:314 +#: pg_controldata.c:316 #, c-format msgid "max_wal_senders setting: %d\n" msgstr "max_wal_senders პარამეტრი: %d\n" -#: pg_controldata.c:316 +#: pg_controldata.c:318 #, c-format msgid "max_prepared_xacts setting: %d\n" msgstr "max_prepared_xacts პარამეტრი: %d\n" -#: pg_controldata.c:318 +#: pg_controldata.c:320 #, c-format msgid "max_locks_per_xact setting: %d\n" msgstr "max_locks_per_xact პარამეტრი: %d\n" -#: pg_controldata.c:320 +#: pg_controldata.c:322 #, c-format msgid "track_commit_timestamp setting: %s\n" msgstr "track_commit_timestamp პარამეტრი: %s\n" -#: pg_controldata.c:322 +#: pg_controldata.c:324 #, c-format msgid "Maximum data alignment: %u\n" msgstr "მონაცემების სწორების მაქსიმუმი: %u\n" -#: pg_controldata.c:325 +#: pg_controldata.c:327 #, c-format msgid "Database block size: %u\n" msgstr "ბაზის ბლოკის ზომა: %u\n" -#: pg_controldata.c:327 +#: pg_controldata.c:329 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "დიდი ურთიერთობის სეგმენტები თითოეულ ბლოკში: %u\n" -#: pg_controldata.c:329 +#: pg_controldata.c:331 #, c-format msgid "Pages per SLRU segment: %u\n" msgstr "გვერდი თითოეულ SLRU სეგმენტში: %u\n" -#: pg_controldata.c:331 +#: pg_controldata.c:333 #, c-format msgid "WAL block size: %u\n" msgstr "WAL ბლოკის ზომა: %u\n" -#: pg_controldata.c:333 +#: pg_controldata.c:335 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "ბაიტები თითოეულ WAL სეგმენტში: %u\n" -#: pg_controldata.c:335 +#: pg_controldata.c:337 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "იდენტიფიკატორების მაქსიმალური სიგრძე: %u\n" -#: pg_controldata.c:337 +#: pg_controldata.c:339 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "ინდექსში სვეტების მაქსიმალური რაოდენობა: %u\n" -#: pg_controldata.c:339 +#: pg_controldata.c:341 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "TOAST ნაგლეჯის მაქსიმალური ზომა: %u\n" -#: pg_controldata.c:341 +#: pg_controldata.c:343 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "დიდი ობიექტის ნაგლეჯის ზომა: %u\n" -#: pg_controldata.c:344 +#: pg_controldata.c:346 #, c-format msgid "Date/time type storage: %s\n" msgstr "თარიღის ტიპის საცავი: %s\n" -#: pg_controldata.c:345 +#: pg_controldata.c:347 msgid "64-bit integers" msgstr "64-ბიტიანი მთელ რიცხვები" -#: pg_controldata.c:346 +#: pg_controldata.c:348 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Float8 არგუმენტის გადაცემა: %s\n" -#: pg_controldata.c:347 +#: pg_controldata.c:349 msgid "by reference" msgstr "ბმით" -#: pg_controldata.c:347 +#: pg_controldata.c:349 msgid "by value" msgstr "მნიშვნელობით" -#: pg_controldata.c:348 +#: pg_controldata.c:350 #, c-format msgid "Data page checksum version: %u\n" msgstr "მონაცემების გვერდის საკონტროლო ჯამის ვერსია: %u\n" -#: pg_controldata.c:350 +#: pg_controldata.c:352 #, c-format msgid "Default char data signedness: %s\n" msgstr "ნაგულისხმევი სტრიქონის მონაცემების ნიშნიანობა: %s\n" -#: pg_controldata.c:351 +#: pg_controldata.c:353 msgid "signed" msgstr "ნიშნიანი" -#: pg_controldata.c:351 +#: pg_controldata.c:353 msgid "unsigned" msgstr "უნიშნო" -#: pg_controldata.c:352 +#: pg_controldata.c:354 #, c-format msgid "Mock authentication nonce: %s\n" msgstr "ფსევდოავთენტიკაციის შემთხვევითი რიცხვი: %s\n" - diff --git a/src/bin/pg_controldata/po/ru.po b/src/bin/pg_controldata/po/ru.po index ce97ded1eba..1b26b844486 100644 --- a/src/bin/pg_controldata/po/ru.po +++ b/src/bin/pg_controldata/po/ru.po @@ -4,13 +4,13 @@ # Serguei A. Mokhov , 2002-2004. # Oleg Bartunov , 2004. # Andrey Sudnik , 2011. -# SPDX-FileCopyrightText: 2012-2017, 2018, 2019, 2020, 2021, 2022, 2024, 2025 Alexander Lakhin +# SPDX-FileCopyrightText: 2012-2017, 2018, 2019, 2020, 2021, 2022, 2024, 2025, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: pg_controldata (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" -"PO-Revision-Date: 2025-09-13 16:58+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:49+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -73,17 +73,27 @@ msgstr "не удалось записать файл \"%s\": %m" msgid "could not fsync file \"%s\": %m" msgstr "не удалось синхронизировать с ФС файл \"%s\": %m" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: pg_controldata.c:35 #, c-format msgid "" diff --git a/src/bin/pg_ctl/po/ru.po b/src/bin/pg_ctl/po/ru.po index 77ce8b4a9f2..20b68ca4903 100644 --- a/src/bin/pg_ctl/po/ru.po +++ b/src/bin/pg_ctl/po/ru.po @@ -6,13 +6,13 @@ # Sergey Burladyan , 2009, 2012. # Andrey Sudnik , 2010. # Dmitriy Olshevskiy , 2014. -# SPDX-FileCopyrightText: 2012-2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025 Alexander Lakhin +# SPDX-FileCopyrightText: 2012-2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: pg_ctl (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" -"PO-Revision-Date: 2025-09-13 17:07+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:49+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -70,18 +70,28 @@ msgstr "ошибка в %s(): %m" msgid "out of memory" msgstr "нехватка памяти" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 -#: ../../port/path.c:831 ../../port/path.c:868 ../../port/path.c:885 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 +#: ../../port/path.c:848 ../../port/path.c:885 ../../port/path.c:902 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/wait_error.c:55 #, c-format msgid "command not executable" @@ -112,7 +122,7 @@ msgstr "дочерний процесс завершён по сигналу %d: msgid "child process exited with unrecognized status %d" msgstr "дочерний процесс завершился с нераспознанным кодом состояния %d" -#: ../../port/path.c:853 +#: ../../port/path.c:870 #, c-format msgid "could not get current working directory: %m\n" msgstr "не удалось определить текущий рабочий каталог: %m\n" diff --git a/src/bin/pg_dump/po/de.po b/src/bin/pg_dump/po/de.po index 0a2aaf390b2..3ad2c71221d 100644 --- a/src/bin/pg_dump/po/de.po +++ b/src/bin/pg_dump/po/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-06-30 04:25+0000\n" +"POT-Creation-Date: 2026-08-07 15:55+0000\n" "PO-Revision-Date: 2026-07-04 01:15+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" @@ -37,54 +37,54 @@ msgstr "Detail: " msgid "hint: " msgstr "Tipp: " -#: ../../common/compression.c:162 ../../common/compression.c:171 -#: ../../common/compression.c:180 compress_gzip.c:453 compress_gzip.c:460 +#: ../../common/compression.c:176 ../../common/compression.c:185 +#: ../../common/compression.c:194 compress_gzip.c:453 compress_gzip.c:460 #: compress_io.c:108 compress_lz4.c:795 compress_lz4.c:802 compress_zstd.c:26 #: compress_zstd.c:32 #, c-format msgid "this build does not support compression with %s" msgstr "diese Installation unterstützt keine Komprimierung mit %s" -#: ../../common/compression.c:235 +#: ../../common/compression.c:249 msgid "found empty string where a compression option was expected" msgstr "leere Zeichenkette gefunden wo eine Komprimierungsoption erwartet wurde" -#: ../../common/compression.c:274 +#: ../../common/compression.c:288 #, c-format msgid "unrecognized compression option: \"%s\"" msgstr "unbekannte Komprimierungsoption: »%s«" -#: ../../common/compression.c:313 +#: ../../common/compression.c:327 #, c-format msgid "compression option \"%s\" requires a value" msgstr "Komprimierungsoption »%s« benötigt einen Wert" -#: ../../common/compression.c:322 +#: ../../common/compression.c:336 #, c-format msgid "value for compression option \"%s\" must be an integer" msgstr "Wert für Komprimierungsoption »%s« muss eine ganze Zahl sein" -#: ../../common/compression.c:361 +#: ../../common/compression.c:375 #, c-format msgid "value for compression option \"%s\" must be a Boolean value" msgstr "Wert für Komprimierungsoption »%s« muss ein Boole’scher Wert sein" -#: ../../common/compression.c:409 +#: ../../common/compression.c:423 #, c-format msgid "compression algorithm \"%s\" does not accept a compression level" msgstr "Komprimierungsalgorithmus »%s« akzeptiert kein Komprimierungsniveau" -#: ../../common/compression.c:416 +#: ../../common/compression.c:430 #, c-format msgid "compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)" msgstr "Komprimierungsalgorithmus »%s« erwartet ein Komprimierungsniveau zwischen %d und %d (Standard bei %d)" -#: ../../common/compression.c:427 +#: ../../common/compression.c:441 #, c-format msgid "compression algorithm \"%s\" does not accept a worker count" msgstr "Komprimierungsalgorithmus »%s« akzeptiert keine Worker-Anzahl" -#: ../../common/compression.c:438 +#: ../../common/compression.c:452 #, c-format msgid "compression algorithm \"%s\" does not support long-distance mode" msgstr "Komprimierungsalgorithmus »%s« unterstützt keinen Long-Distance-Modus" @@ -124,7 +124,7 @@ msgstr "konnte nicht von Befehl »%s« lesen: %m" msgid "no data was returned by command \"%s\"" msgstr "Befehl »%s« gab keine Daten zurück" -#: ../../common/exec.c:406 parallel.c:1611 +#: ../../common/exec.c:406 parallel.c:1613 #, c-format msgid "%s() failed: %m" msgstr "%s() fehlgeschlagen: %m" @@ -739,22 +739,27 @@ msgstr "%s() fehlgeschlagen: Fehlercode %d" msgid "could not create communication channels: %m" msgstr "konnte Kommunikationskanäle nicht erzeugen: %m" -#: parallel.c:1018 +#: parallel.c:980 +#, c-format +msgid "could not create worker thread: %m" +msgstr "konnte Arbeits-Thread nicht erzeugen: %m" + +#: parallel.c:1020 #, c-format msgid "could not create worker process: %m" msgstr "konnte Arbeitsprozess nicht erzeugen: %m" -#: parallel.c:1148 +#: parallel.c:1150 #, c-format msgid "unrecognized command received from leader: \"%s\"" msgstr "unbekannter Befehl vom Leader-Prozess empfangen: »%s«" -#: parallel.c:1191 parallel.c:1429 +#: parallel.c:1193 parallel.c:1431 #, c-format msgid "invalid message received from worker: \"%s\"" msgstr "ungültige Nachricht vom Arbeitsprozess empfangen: »%s«" -#: parallel.c:1323 +#: parallel.c:1325 #, c-format msgid "" "could not obtain lock on relation \"%s\"\n" @@ -763,47 +768,47 @@ msgstr "" "konnte Sperre für Relation »%s« nicht setzen\n" "Das bedeutet meistens, dass jemand eine ACCESS-EXCLUSIVE-Sperre auf die Tabelle gesetzt hat, nachdem der pg-dump-Elternprozess die anfängliche ACCESS-SHARE-Sperre gesetzt hatte." -#: parallel.c:1412 +#: parallel.c:1414 #, c-format msgid "a worker process died unexpectedly" msgstr "ein Arbeitsprozess endete unerwartet" -#: parallel.c:1534 parallel.c:1652 +#: parallel.c:1536 parallel.c:1654 #, c-format msgid "could not write to the communication channel: %m" msgstr "konnte nicht in den Kommunikationskanal schreiben: %m" -#: parallel.c:1736 +#: parallel.c:1738 #, c-format msgid "pgpipe: could not create socket: error code %d" msgstr "pgpipe: konnte Socket nicht erzeugen: Fehlercode %d" -#: parallel.c:1747 +#: parallel.c:1749 #, c-format msgid "pgpipe: could not bind: error code %d" msgstr "pgpipe: konnte nicht binden: Fehlercode %d" -#: parallel.c:1754 +#: parallel.c:1756 #, c-format msgid "pgpipe: could not listen: error code %d" msgstr "pgpipe: konnte nicht auf Socket hören: Fehlercode %d" -#: parallel.c:1761 +#: parallel.c:1763 #, c-format msgid "pgpipe: %s() failed: error code %d" msgstr "pgpipe: %s() fehlgeschlagen: Fehlercode %d" -#: parallel.c:1772 +#: parallel.c:1774 #, c-format msgid "pgpipe: could not create second socket: error code %d" msgstr "pgpipe: konnte zweites Socket nicht erzeugen: Fehlercode %d" -#: parallel.c:1781 +#: parallel.c:1783 #, c-format msgid "pgpipe: could not connect socket: error code %d" msgstr "pgpipe: konnte Socket nicht verbinden: Fehlercode %d" -#: parallel.c:1790 +#: parallel.c:1792 #, c-format msgid "pgpipe: could not accept connection: error code %d" msgstr "pgpipe: konnte Verbindung nicht annehmen: Fehlercode %d" @@ -1086,12 +1091,12 @@ msgstr "konnte Standardausgabe nicht zum Anhängen öffnen: %m" msgid "unrecognized file format \"%d\"" msgstr "nicht erkanntes Dateiformat »%d«" -#: pg_backup_archiver.c:2568 pg_backup_archiver.c:4845 +#: pg_backup_archiver.c:2568 pg_backup_archiver.c:4847 #, c-format msgid "finished item %d %s %s" msgstr "Element %d %s %s abgeschlossen" -#: pg_backup_archiver.c:2572 pg_backup_archiver.c:4858 +#: pg_backup_archiver.c:2572 pg_backup_archiver.c:4860 #, c-format msgid "worker process failed: exit code %d" msgstr "Arbeitsprozess fehlgeschlagen: Code %d" @@ -1158,107 +1163,107 @@ msgstr "Funktion »%s« nicht gefunden" msgid "trigger \"%s\" not found" msgstr "Trigger »%s« nicht gefunden" -#: pg_backup_archiver.c:3517 +#: pg_backup_archiver.c:3519 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "konnte Sitzungsbenutzer nicht auf »%s« setzen: %s" -#: pg_backup_archiver.c:3659 +#: pg_backup_archiver.c:3661 #, c-format msgid "could not set \"search_path\" to \"%s\": %s" msgstr "konnte »search_path« nicht auf »%s« setzen: %s" -#: pg_backup_archiver.c:3720 +#: pg_backup_archiver.c:3722 #, c-format msgid "could not set \"default_tablespace\" to %s: %s" msgstr "konnte »default_tablespace« nicht auf »%s« setzen: %s" -#: pg_backup_archiver.c:3769 +#: pg_backup_archiver.c:3771 #, c-format msgid "could not set \"default_table_access_method\": %s" msgstr "konnte »default_table_access_method« nicht setzen: %s" -#: pg_backup_archiver.c:3818 +#: pg_backup_archiver.c:3820 #, c-format msgid "could not alter table access method: %s" msgstr "konnte Tabellenzugriffsmethode nicht ändern: %s" -#: pg_backup_archiver.c:3920 +#: pg_backup_archiver.c:3922 #, c-format msgid "don't know how to set owner for object type \"%s\"" msgstr "kann Eigentümer für Objekttyp »%s« nicht setzen" -#: pg_backup_archiver.c:4055 +#: pg_backup_archiver.c:4057 #, c-format msgid "unexpected TOC entry in _printTocEntry(): %d %s %s" msgstr "unerwarteter TOC-Eintrag in _printTocEntry(): %d %s %s" -#: pg_backup_archiver.c:4203 +#: pg_backup_archiver.c:4205 #, c-format msgid "did not find magic string in file header" msgstr "magische Zeichenkette im Dateikopf nicht gefunden" -#: pg_backup_archiver.c:4217 +#: pg_backup_archiver.c:4219 #, c-format msgid "unsupported version (%d.%d) in file header" msgstr "nicht unterstützte Version (%d.%d) im Dateikopf" -#: pg_backup_archiver.c:4222 +#: pg_backup_archiver.c:4224 #, c-format msgid "sanity check on integer size (%zu) failed" msgstr "Prüfung der Integer-Größe (%zu) fehlgeschlagen" -#: pg_backup_archiver.c:4225 +#: pg_backup_archiver.c:4227 #, c-format msgid "archive was made on a machine with larger integers, some operations might fail" msgstr "Archiv wurde auf einer Maschine mit größeren Integers erstellt; einige Operationen könnten fehlschlagen" -#: pg_backup_archiver.c:4235 +#: pg_backup_archiver.c:4237 #, c-format msgid "expected format (%d) differs from format found in file (%d)" msgstr "erwartetes Format (%d) ist nicht das gleiche wie das in der Datei gefundene (%d)" -#: pg_backup_archiver.c:4257 +#: pg_backup_archiver.c:4259 #, c-format msgid "archive is compressed, but this installation does not support compression (%s) -- no data will be available" msgstr "Archiv ist komprimiert, aber diese Installation unterstützt keine Komprimierung (%s) -- keine Daten verfügbar" -#: pg_backup_archiver.c:4293 +#: pg_backup_archiver.c:4295 #, c-format msgid "invalid creation date in header" msgstr "ungültiges Erstellungsdatum im Kopf" -#: pg_backup_archiver.c:4427 +#: pg_backup_archiver.c:4429 #, c-format msgid "processing item %d %s %s" msgstr "verarbeite Element %d %s %s" -#: pg_backup_archiver.c:4512 +#: pg_backup_archiver.c:4514 #, c-format msgid "entering main parallel loop" msgstr "Eintritt in Hauptparallelschleife" -#: pg_backup_archiver.c:4523 +#: pg_backup_archiver.c:4525 #, c-format msgid "skipping item %d %s %s" msgstr "Element %d %s %s wird übersprungen" -#: pg_backup_archiver.c:4532 +#: pg_backup_archiver.c:4534 #, c-format msgid "launching item %d %s %s" msgstr "starte Element %d %s %s" -#: pg_backup_archiver.c:4586 +#: pg_backup_archiver.c:4588 #, c-format msgid "finished main parallel loop" msgstr "Hauptparallelschleife beendet" -#: pg_backup_archiver.c:4622 +#: pg_backup_archiver.c:4624 #, c-format msgid "processing missed item %d %s %s" msgstr "verarbeite verpasstes Element %d %s %s" -#: pg_backup_archiver.c:5164 +#: pg_backup_archiver.c:5166 #, c-format msgid "table \"%s\" could not be created, will not restore its data" msgstr "Tabelle »%s« konnte nicht erzeugt werden, ihre Daten werden nicht wiederhergestellt werden" @@ -2264,8 +2269,8 @@ msgstr "lese Policys für Sicherheit auf Zeilenebene" msgid "unexpected policy command type: %c" msgstr "unerwarteter Policy-Befehlstyp: %c" -#: pg_dump.c:4984 pg_dump.c:5600 pg_dump.c:8240 pg_dump.c:13795 pg_dump.c:20347 -#: pg_dump.c:20349 pg_dump.c:20990 +#: pg_dump.c:4984 pg_dump.c:5600 pg_dump.c:8271 pg_dump.c:13826 pg_dump.c:20378 +#: pg_dump.c:20380 pg_dump.c:21021 #, c-format msgid "could not parse %s array" msgstr "konnte %s-Array nicht interpretieren" @@ -2300,328 +2305,328 @@ msgstr "Schema mit OID %u existiert nicht" msgid "cannot dump statistics for relation kind \"%c\"" msgstr "für Relationstyp »%c« können keine Statistiken ausgegeben werden" -#: pg_dump.c:7774 pg_dump.c:19674 +#: pg_dump.c:7805 pg_dump.c:19705 #, c-format msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" msgstr "Sanity-Check fehlgeschlagen, Elterntabelle mit OID %u von Sequenz mit OID %u nicht gefunden" -#: pg_dump.c:7919 +#: pg_dump.c:7950 #, c-format msgid "failed sanity check, table OID %u appearing in pg_partitioned_table not found" msgstr "Sanity-Check fehlgeschlagen, Tabellen-OID %u, die in pg_partitioned_table erscheint, nicht gefunden" -#: pg_dump.c:8182 pg_dump.c:8480 pg_dump.c:8943 pg_dump.c:9611 pg_dump.c:9755 -#: pg_dump.c:9900 pg_dump.c:10000 +#: pg_dump.c:8213 pg_dump.c:8511 pg_dump.c:8974 pg_dump.c:9642 pg_dump.c:9786 +#: pg_dump.c:9931 pg_dump.c:10031 #, c-format msgid "unrecognized table OID %u" msgstr "unbekannte Tabellen-OID %u" -#: pg_dump.c:8186 +#: pg_dump.c:8217 #, c-format msgid "unexpected index data for table \"%s\"" msgstr "unerwartete Indexdaten für Tabelle »%s«" -#: pg_dump.c:8730 +#: pg_dump.c:8761 #, c-format msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" msgstr "Sanity-Check fehlgeschlagen, Elterntabelle mit OID %u von pg_rewrite-Eintrag mit OID %u nicht gefunden" -#: pg_dump.c:9618 +#: pg_dump.c:9649 #, c-format msgid "unexpected column data for table \"%s\"" msgstr "unerwartete Spaltendaten für Tabelle »%s«" -#: pg_dump.c:9652 +#: pg_dump.c:9683 #, c-format msgid "invalid column numbering in table \"%s\"" msgstr "ungültige Spaltennummerierung in Tabelle »%s«" -#: pg_dump.c:9717 +#: pg_dump.c:9748 #, c-format msgid "finding table default expressions" msgstr "finde Tabellenvorgabeausdrücke" -#: pg_dump.c:9759 +#: pg_dump.c:9790 #, c-format msgid "invalid adnum value %d for table \"%s\"" msgstr "ungültiger adnum-Wert %d für Tabelle »%s«" -#: pg_dump.c:9852 +#: pg_dump.c:9883 #, c-format msgid "finding invalid not-null constraints" msgstr "finde ungültige Not-Null-Constraints" -#: pg_dump.c:9950 +#: pg_dump.c:9981 #, c-format msgid "finding table check constraints" msgstr "finde Tabellen-Check-Constraints" -#: pg_dump.c:10004 +#: pg_dump.c:10035 #, c-format msgid "expected %d check constraint on table \"%s\" but found %d" msgid_plural "expected %d check constraints on table \"%s\" but found %d" msgstr[0] "%d Check-Constraint für Tabelle %s erwartet, aber %d gefunden" msgstr[1] "%d Check-Constraints für Tabelle %s erwartet, aber %d gefunden" -#: pg_dump.c:10008 +#: pg_dump.c:10039 #, c-format msgid "The system catalogs might be corrupted." msgstr "Die Systemkataloge sind wahrscheinlich verfälscht." -#: pg_dump.c:10823 +#: pg_dump.c:10854 #, c-format msgid "role with OID %u does not exist" msgstr "Rolle mit OID %u existiert nicht" -#: pg_dump.c:10935 pg_dump.c:10964 +#: pg_dump.c:10966 pg_dump.c:10995 #, c-format msgid "unsupported pg_init_privs entry: %u %u %d" msgstr "nicht unterstützter pg_init_privs-Eintrag: %u %u %d" -#: pg_dump.c:11286 +#: pg_dump.c:11317 #, c-format msgid "statistics dumped out of order (current: %d %s %s, expected: %d %s %s)" msgstr "Statistiken in falscher Reihenfolge ausgegeben (aktuell: %d %s %s, erwartet: %d %s %s)" -#: pg_dump.c:11441 +#: pg_dump.c:11472 #, c-format msgid "unexpected null attname" msgstr "unerwarteter atttname mit NULL-Wert" -#: pg_dump.c:11470 +#: pg_dump.c:11501 #, c-format msgid "could not find index attname \"%s\"" msgstr "konnte Index-Attname »%s« nicht finden" -#: pg_dump.c:11957 +#: pg_dump.c:11988 #, c-format msgid "missing metadata for large objects \"%s\"" msgstr "fehlende Metadaten für Large Objects »%s«" -#: pg_dump.c:12238 +#: pg_dump.c:12269 #, c-format msgid "typtype of data type \"%s\" appears to be invalid" msgstr "typtype des Datentypen »%s« scheint ungültig zu sein" -#: pg_dump.c:13866 +#: pg_dump.c:13897 #, c-format msgid "unrecognized provolatile value for function \"%s\"" msgstr "ungültiger provolatile-Wert für Funktion »%s«" -#: pg_dump.c:13916 pg_dump.c:15816 +#: pg_dump.c:13947 pg_dump.c:15847 #, c-format msgid "unrecognized proparallel value for function \"%s\"" msgstr "ungültiger proparallel-Wert für Funktion »%s«" -#: pg_dump.c:14050 pg_dump.c:14156 pg_dump.c:14163 +#: pg_dump.c:14081 pg_dump.c:14187 pg_dump.c:14194 #, c-format msgid "could not find function definition for function with OID %u" msgstr "konnte Funktionsdefinition für Funktion mit OID %u nicht finden" -#: pg_dump.c:14089 +#: pg_dump.c:14120 #, c-format msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" msgstr "unsinniger Wert in Feld pg_cast.castfunc oder pg_cast.castmethod" -#: pg_dump.c:14092 +#: pg_dump.c:14123 #, c-format msgid "bogus value in pg_cast.castmethod field" msgstr "unsinniger Wert in Feld pg_cast.castmethod" -#: pg_dump.c:14182 +#: pg_dump.c:14213 #, c-format msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" msgstr "unsinnige Transformationsdefinition, mindestens eins von trffromsql und trftosql sollte nicht null sein" -#: pg_dump.c:14199 +#: pg_dump.c:14230 #, c-format msgid "bogus value in pg_transform.trffromsql field" msgstr "unsinniger Wert in Feld pg_transform.trffromsql" -#: pg_dump.c:14220 +#: pg_dump.c:14251 #, c-format msgid "bogus value in pg_transform.trftosql field" msgstr "unsinniger Wert in Feld pg_transform.trftosql" -#: pg_dump.c:14365 +#: pg_dump.c:14396 #, c-format msgid "postfix operators are not supported anymore (operator \"%s\")" msgstr "Postfix-Operatoren werden nicht mehr unterstützt (Operator »%s«)" -#: pg_dump.c:14535 +#: pg_dump.c:14566 #, c-format msgid "could not find operator with OID %s" msgstr "konnte Operator mit OID %s nicht finden" -#: pg_dump.c:14603 +#: pg_dump.c:14634 #, c-format msgid "invalid type \"%c\" of access method \"%s\"" msgstr "ungültiger Typ »%c« für Zugriffsmethode »%s«" -#: pg_dump.c:15277 pg_dump.c:15345 +#: pg_dump.c:15308 pg_dump.c:15376 #, c-format msgid "unrecognized collation provider: %s" msgstr "unbekannter Sortierfolgen-Provider: %s" -#: pg_dump.c:15286 pg_dump.c:15293 pg_dump.c:15304 pg_dump.c:15314 -#: pg_dump.c:15329 +#: pg_dump.c:15317 pg_dump.c:15324 pg_dump.c:15335 pg_dump.c:15345 +#: pg_dump.c:15360 #, c-format msgid "invalid collation \"%s\"" msgstr "ungültige Sortierfolge »%s«" -#: pg_dump.c:15735 +#: pg_dump.c:15766 #, c-format msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" msgstr "unbekannter aggfinalmodify-Wert für Aggregat »%s«" -#: pg_dump.c:15791 +#: pg_dump.c:15822 #, c-format msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" msgstr "unbekannter aggmfinalmodify-Wert für Aggregat »%s«" -#: pg_dump.c:16514 +#: pg_dump.c:16545 #, c-format msgid "unrecognized object type in default privileges: %d" msgstr "unbekannter Objekttyp in den Vorgabeprivilegien: %d" -#: pg_dump.c:16530 +#: pg_dump.c:16561 #, c-format msgid "could not parse default ACL list (%s)" msgstr "konnte Vorgabe-ACL-Liste (%s) nicht interpretieren" -#: pg_dump.c:16614 +#: pg_dump.c:16645 #, c-format msgid "could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)" msgstr "konnte initiale ACL-Liste (%s) oder Default (%s) für Objekt »%s« (%s) nicht interpretieren" -#: pg_dump.c:16639 +#: pg_dump.c:16670 #, c-format msgid "could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)" msgstr "konnte ACL-Liste (%s) oder Default (%s) für Objekt »%s« (%s) nicht interpretieren" -#: pg_dump.c:17194 +#: pg_dump.c:17225 #, c-format msgid "query to obtain definition of view \"%s\" returned no data" msgstr "Anfrage um die Definition der Sicht »%s« zu ermitteln lieferte keine Daten" -#: pg_dump.c:17197 +#: pg_dump.c:17228 #, c-format msgid "query to obtain definition of view \"%s\" returned more than one definition" msgstr "Anfrage um die Definition der Sicht »%s« zu ermitteln lieferte mehr als eine Definition" -#: pg_dump.c:17204 +#: pg_dump.c:17235 #, c-format msgid "definition of view \"%s\" appears to be empty (length zero)" msgstr "Definition der Sicht »%s« scheint leer zu sein (Länge null)" -#: pg_dump.c:17289 +#: pg_dump.c:17320 #, c-format msgid "WITH OIDS is not supported anymore (table \"%s\")" msgstr "WITH OIDS wird nicht mehr unterstützt (Tabelle »%s«)" -#: pg_dump.c:17352 +#: pg_dump.c:17383 #, c-format msgid "query to obtain definition of property graph \"%s\" returned no data" msgstr "Anfrage um die Definition des Property Graph »%s« zu ermitteln lieferte keine Daten" -#: pg_dump.c:17355 +#: pg_dump.c:17386 #, c-format msgid "query to obtain definition of property graph \"%s\" returned more than one definition" msgstr "Anfrage um die Definition des Property Graph »%s« zu ermitteln lieferte mehr als eine Definition" -#: pg_dump.c:17362 +#: pg_dump.c:17393 #, c-format msgid "definition of property graph \"%s\" appears to be empty (length zero)" msgstr "Definition des Property Graph »%s« scheint leer zu sein (Länge null)" -#: pg_dump.c:18471 +#: pg_dump.c:18502 #, c-format msgid "invalid column number %d for table \"%s\"" msgstr "ungültige Spaltennummer %d in Tabelle »%s«" -#: pg_dump.c:18549 +#: pg_dump.c:18580 #, c-format msgid "could not parse index statistic columns" msgstr "konnte Indexstatistikspalten nicht interpretieren" -#: pg_dump.c:18551 +#: pg_dump.c:18582 #, c-format msgid "could not parse index statistic values" msgstr "konnte Indexstatistikwerte nicht interpretieren" -#: pg_dump.c:18553 +#: pg_dump.c:18584 #, c-format msgid "mismatched number of columns and values for index statistics" msgstr "Anzahl Spalten und Werte für Indexstatistiken stimmt nicht überein" -#: pg_dump.c:18965 +#: pg_dump.c:18996 #, c-format msgid "inherited cannot be NULL" msgstr "inherited kann nicht NULL sein" -#: pg_dump.c:19062 +#: pg_dump.c:19093 #, c-format msgid "missing index for constraint \"%s\"" msgstr "fehlender Index für Constraint »%s«" -#: pg_dump.c:19331 +#: pg_dump.c:19362 #, c-format msgid "unrecognized constraint type: %c" msgstr "unbekannter Constraint-Typ: %c" -#: pg_dump.c:19384 +#: pg_dump.c:19415 #, c-format msgid "unrecognized sequence type: %s" msgstr "unbekannter Sequenztyp: %s" -#: pg_dump.c:19517 pg_dump.c:19755 +#: pg_dump.c:19548 pg_dump.c:19786 #, c-format msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" msgstr[0] "Anfrage nach Daten der Sequenz %s ergab %d Zeile (erwartete 1)" msgstr[1] "Anfrage nach Daten der Sequenz %s ergab %d Zeilen (erwartete 1)" -#: pg_dump.c:19553 +#: pg_dump.c:19584 #, c-format msgid "unrecognized sequence type: %d" msgstr "unbekannter Sequenztyp: %d" -#: pg_dump.c:19778 +#: pg_dump.c:19809 #, c-format msgid "failed to get data for sequence \"%s\"; user may lack SELECT privilege on the sequence or the sequence may have been concurrently dropped" msgstr "konnte Daten für Sequenz »%s« nicht ermitteln; möglicherweise hat der Anwender nicht das SELECT-Privileg für die Sequenz oder die Sequenz würde möglicherweise gleichzeitig gelöscht" -#: pg_dump.c:20099 +#: pg_dump.c:20130 #, c-format msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" msgstr "Anfrage nach Regel »%s« der Tabelle »%s« fehlgeschlagen: falsche Anzahl Zeilen zurückgegeben" -#: pg_dump.c:20252 +#: pg_dump.c:20283 #, c-format msgid "could not find referenced extension %u" msgstr "konnte referenzierte Erweiterung %u nicht finden" -#: pg_dump.c:20351 +#: pg_dump.c:20382 #, c-format msgid "mismatched number of configurations and conditions for extension" msgstr "Anzahl Konfigurationen und Bedingungen für Erweiterung stimmt nicht überein" -#: pg_dump.c:20483 +#: pg_dump.c:20514 #, c-format msgid "reading dependency data" msgstr "lese Abhängigkeitsdaten" -#: pg_dump.c:20580 +#: pg_dump.c:20611 #, c-format msgid "no referencing object %u %u" msgstr "kein referenzierendes Objekt %u %u" -#: pg_dump.c:20591 +#: pg_dump.c:20622 #, c-format msgid "no referenced object %u %u" msgstr "kein referenziertes Objekt %u %u" -#: pg_dump.c:21024 pg_dump.c:21062 pg_dumpall.c:1858 pg_restore.c:642 +#: pg_dump.c:21055 pg_dump.c:21093 pg_dumpall.c:1858 pg_restore.c:642 #: pg_restore.c:688 #, c-format msgid "%s filter for \"%s\" is not allowed" @@ -2693,7 +2698,9 @@ msgstr "" msgid "" "%s exports a PostgreSQL database cluster as an SQL script.\n" "\n" -msgstr "%s exportiert einen PostgreSQL-Datenbankcluster als SQL-Skript.\n\n" +msgstr "" +"%s exportiert einen PostgreSQL-Datenbankcluster als SQL-Skript.\n" +"\n" #: pg_dumpall.c:706 #, c-format @@ -2885,7 +2892,9 @@ msgstr "bei Wiederherstellung ignorierte Fehler: %d" msgid "" "%s restores a PostgreSQL database from an archive created by pg_dump.\n" "\n" -msgstr "%s stellt eine PostgreSQL-Datenbank wieder her, die mit pg_dump gesichert wurde.\n\n" +msgstr "" +"%s stellt eine PostgreSQL-Datenbank wieder her, die mit pg_dump gesichert wurde.\n" +"\n" #: pg_restore.c:537 #, c-format diff --git a/src/bin/pg_dump/po/ka.po b/src/bin/pg_dump/po/ka.po index 53b2804cdf6..810160d144e 100644 --- a/src/bin/pg_dump/po/ka.po +++ b/src/bin/pg_dump/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_dump (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-06-30 04:25+0000\n" -"PO-Revision-Date: 2026-07-02 06:23+0200\n" +"POT-Creation-Date: 2026-07-25 01:55+0000\n" +"PO-Revision-Date: 2026-07-25 04:35+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -125,7 +125,7 @@ msgstr "ბრძანებიდან \"%s\" წაკითხვის შ msgid "no data was returned by command \"%s\"" msgstr "ბრძანებამ \"%s\" მონაცემები არ დააბრუნა" -#: ../../common/exec.c:406 parallel.c:1611 +#: ../../common/exec.c:406 parallel.c:1613 #, c-format msgid "%s() failed: %m" msgstr "%s()-ის შეცდომა: %m" @@ -740,22 +740,27 @@ msgstr "%s() -ის შეცდომა: შეცდომის კოდ msgid "could not create communication channels: %m" msgstr "საკომუნიკაციო არხების შექმნა ვერ მოხერხდა: %m" -#: parallel.c:1018 +#: parallel.c:980 +#, c-format +msgid "could not create worker thread: %m" +msgstr "დამხმარე ნაკადის შექმნა შეუძლებელია: %m" + +#: parallel.c:1020 #, c-format msgid "could not create worker process: %m" msgstr "დამხმარე პროცესის შექმნა შეუძლებელია: %m" -#: parallel.c:1148 +#: parallel.c:1150 #, c-format msgid "unrecognized command received from leader: \"%s\"" msgstr "თავსართიდან მიღებული ბრძანება უცნობია: %s" -#: parallel.c:1191 parallel.c:1429 +#: parallel.c:1193 parallel.c:1431 #, c-format msgid "invalid message received from worker: \"%s\"" msgstr "დამხმარე პროცესისგან მიღებულია არასწორი შეტყობინება: %s" -#: parallel.c:1323 +#: parallel.c:1325 #, c-format msgid "" "could not obtain lock on relation \"%s\"\n" @@ -764,47 +769,47 @@ msgstr "" "ურთიერთობის (\"%s\") დაბლოკვის შეცდომა\n" "ეს ჩვეულებრივ ნიშნავს, რომ ვინმემ მოითხოვა ACCESS EXCLUSIVE ბლოკი ცხრილზე მას შემდეგ, რაც pg_dump-ის მშობელმა პროცესმა საწყისი ACCESS SHARE ბლოკი ცხრილზე უკვე მიიღო." -#: parallel.c:1412 +#: parallel.c:1414 #, c-format msgid "a worker process died unexpectedly" msgstr "დამხმარე პროტოკოლის პროცესი მოულოდნელად მოკვდა" -#: parallel.c:1534 parallel.c:1652 +#: parallel.c:1536 parallel.c:1654 #, c-format msgid "could not write to the communication channel: %m" msgstr "საკომუნიკაციო არხში ჩაწერის შეცდომა: %m" -#: parallel.c:1736 +#: parallel.c:1738 #, c-format msgid "pgpipe: could not create socket: error code %d" msgstr "pgpipe: სოკეტის შექმნის შეცდომა. შეცდომის კოდი: %d" -#: parallel.c:1747 +#: parallel.c:1749 #, c-format msgid "pgpipe: could not bind: error code %d" msgstr "pgpipe: მიბმის შეცდომა: შეცდომის კოდი: %d" -#: parallel.c:1754 +#: parallel.c:1756 #, c-format msgid "pgpipe: could not listen: error code %d" msgstr "pgpipe: მოსმენის შეცდომა: შეცდომის კოდი: %d" -#: parallel.c:1761 +#: parallel.c:1763 #, c-format msgid "pgpipe: %s() failed: error code %d" msgstr "pgpipe: %s() -ის შეცდომა: შეცდომის კოდი %d" -#: parallel.c:1772 +#: parallel.c:1774 #, c-format msgid "pgpipe: could not create second socket: error code %d" msgstr "pgpipe: მეორე სოკეტის შექნა შეუძლებელია: შეცდომის კოდი: %d" -#: parallel.c:1781 +#: parallel.c:1783 #, c-format msgid "pgpipe: could not connect socket: error code %d" msgstr "pgpipe: სოკეტთან მიერთების შეცდომა: შეცდომის კოდი %d" -#: parallel.c:1790 +#: parallel.c:1792 #, c-format msgid "pgpipe: could not accept connection: error code %d" msgstr "pgpipe: შეერთების დადასტურება შეუძლებელია: შეცდომის კოდი %d" @@ -2246,8 +2251,8 @@ msgstr "მწკრივის დონის უსაფრთხოებ msgid "unexpected policy command type: %c" msgstr "წესების ბრძანების მოულოდნელი ტიპი: %c" -#: pg_dump.c:4984 pg_dump.c:5600 pg_dump.c:8240 pg_dump.c:13795 pg_dump.c:20347 -#: pg_dump.c:20349 pg_dump.c:20990 +#: pg_dump.c:4984 pg_dump.c:5600 pg_dump.c:8271 pg_dump.c:13826 pg_dump.c:20378 +#: pg_dump.c:20380 pg_dump.c:21021 #, c-format msgid "could not parse %s array" msgstr "მასივის დამუშავების შეცდომა: %s" @@ -2282,328 +2287,328 @@ msgstr "სქემა OID-ით %u არ არსებობს" msgid "cannot dump statistics for relation kind \"%c\"" msgstr "სტატისტიკის დამპი ურთიერთობის ტიპისთვის \"%c\" შეუძლებელია" -#: pg_dump.c:7774 pg_dump.c:19674 +#: pg_dump.c:7805 pg_dump.c:19705 #, c-format msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" msgstr "სისწორის შემოწმების შეცდომა. მშობელი ცხრილი OID-ით %u მიმდევრობიდან OID-ით %u არ არსებობს" -#: pg_dump.c:7919 +#: pg_dump.c:7950 #, c-format msgid "failed sanity check, table OID %u appearing in pg_partitioned_table not found" msgstr "სისწორის შემოწმების შეცდომა. pg_parttioned_table-ში მოხსენიებული ცხრილი OID-ით %u ვერ ვიპოვე" -#: pg_dump.c:8182 pg_dump.c:8480 pg_dump.c:8943 pg_dump.c:9611 pg_dump.c:9755 -#: pg_dump.c:9900 pg_dump.c:10000 +#: pg_dump.c:8213 pg_dump.c:8511 pg_dump.c:8974 pg_dump.c:9642 pg_dump.c:9786 +#: pg_dump.c:9931 pg_dump.c:10031 #, c-format msgid "unrecognized table OID %u" msgstr "ცხრილის უცნობი OID: %u" -#: pg_dump.c:8186 +#: pg_dump.c:8217 #, c-format msgid "unexpected index data for table \"%s\"" msgstr "მოულოდნელი ინდექსის მონაცემები ცხრილისთვის \"%s\"" -#: pg_dump.c:8730 +#: pg_dump.c:8761 #, c-format msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" msgstr "სისწორის შემოწმების შეცდომა. მშობელი ცხრილი OID-ით %u pg_rewrite-ის ელემენტიდან OID-ით %u ვერ ვიპოვე" -#: pg_dump.c:9618 +#: pg_dump.c:9649 #, c-format msgid "unexpected column data for table \"%s\"" msgstr "სვეტის მოულოდნელი მონაცემები ცხრილისთვის %s" -#: pg_dump.c:9652 +#: pg_dump.c:9683 #, c-format msgid "invalid column numbering in table \"%s\"" msgstr "ცხრილში \"%s\" სვეტები არასწორადაა დანომრილი" -#: pg_dump.c:9717 +#: pg_dump.c:9748 #, c-format msgid "finding table default expressions" msgstr "ვეძებ ცხრილის ნაგულისხმევ გამოსახულებებს" -#: pg_dump.c:9759 +#: pg_dump.c:9790 #, c-format msgid "invalid adnum value %d for table \"%s\"" msgstr "adnum -ის არასწორი მნიშვნელობა %d ცხრილისთვის \"%s\"" -#: pg_dump.c:9852 +#: pg_dump.c:9883 #, c-format msgid "finding invalid not-null constraints" msgstr "ვეძებ არასწორ არანულოვან შეზღუდვებს" -#: pg_dump.c:9950 +#: pg_dump.c:9981 #, c-format msgid "finding table check constraints" msgstr "ვეძებ ცხრილის შემოწმების შეზღუდვებს" -#: pg_dump.c:10004 +#: pg_dump.c:10035 #, c-format msgid "expected %d check constraint on table \"%s\" but found %d" msgid_plural "expected %d check constraints on table \"%s\" but found %d" msgstr[0] "მოველოდი %d შემოწმების შეზღუდვას ცხრილზე \"%s\", მაგრამ %d" msgstr[1] "მოველოდი %d შემოწმების შეზღუდვას ცხრილზე \"%s\", მაგრამ %d" -#: pg_dump.c:10008 +#: pg_dump.c:10039 #, c-format msgid "The system catalogs might be corrupted." msgstr "სისტემის კატალოგი შეიძლება დაზიანებულია." -#: pg_dump.c:10823 +#: pg_dump.c:10854 #, c-format msgid "role with OID %u does not exist" msgstr "როლი OID-ით %u არ არსებობს" -#: pg_dump.c:10935 pg_dump.c:10964 +#: pg_dump.c:10966 pg_dump.c:10995 #, c-format msgid "unsupported pg_init_privs entry: %u %u %d" msgstr "pg_init_privs -ის არასწორი ჩანაწერი: %u %u %d" -#: pg_dump.c:11286 +#: pg_dump.c:11317 #, c-format msgid "statistics dumped out of order (current: %d %s %s, expected: %d %s %s)" msgstr "სტატისტიკის დამპი დალაგებული არაა (მიმდინარე: %d %s %s. მოველოდი: %d %s %s)" -#: pg_dump.c:11441 +#: pg_dump.c:11472 #, c-format msgid "unexpected null attname" msgstr "მოულოდნელი null attname" -#: pg_dump.c:11470 +#: pg_dump.c:11501 #, c-format msgid "could not find index attname \"%s\"" msgstr "ინდექსის attname \"%s\" აღმოჩენილი არაა" -#: pg_dump.c:11957 +#: pg_dump.c:11988 #, c-format msgid "missing metadata for large objects \"%s\"" msgstr "აკლია მეტამონაცემები დიდი ობიექტებისთვის \"%s\"" -#: pg_dump.c:12238 +#: pg_dump.c:12269 #, c-format msgid "typtype of data type \"%s\" appears to be invalid" msgstr "მონაცემის ტიპი %s-ის typetype თურმე არასორია" -#: pg_dump.c:13866 +#: pg_dump.c:13897 #, c-format msgid "unrecognized provolatile value for function \"%s\"" msgstr "უცნობი provolatile მნიშვნელობა ფუნქციისთვის \"%s\"" -#: pg_dump.c:13916 pg_dump.c:15816 +#: pg_dump.c:13947 pg_dump.c:15847 #, c-format msgid "unrecognized proparallel value for function \"%s\"" msgstr "უცნობი proparallel მნიშვნელობა ფუნქციისთვის \"%s\"" -#: pg_dump.c:14050 pg_dump.c:14156 pg_dump.c:14163 +#: pg_dump.c:14081 pg_dump.c:14187 pg_dump.c:14194 #, c-format msgid "could not find function definition for function with OID %u" msgstr "ფუნქციის აღწერა ფუნქციისთვის OID-ით %u ვერ ვიპოვე" -#: pg_dump.c:14089 +#: pg_dump.c:14120 #, c-format msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" msgstr "pg_cast.castfunc ან pg_cast.castmethod ველების არასწორი მნიშვნელობა" -#: pg_dump.c:14092 +#: pg_dump.c:14123 #, c-format msgid "bogus value in pg_cast.castmethod field" msgstr "pg_cast.castmethod ველის არასწორი მნიშვნელობა" -#: pg_dump.c:14182 +#: pg_dump.c:14213 #, c-format msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" msgstr "არასწორი გარდაქმნის აღწერა. ერთ-ერთი, trffromsql ან trftosql ნულს არ უნდა უდრიდეს" -#: pg_dump.c:14199 +#: pg_dump.c:14230 #, c-format msgid "bogus value in pg_transform.trffromsql field" msgstr "pg_transform.trffromsql ველის არასწორი მნიშვნელობა" -#: pg_dump.c:14220 +#: pg_dump.c:14251 #, c-format msgid "bogus value in pg_transform.trftosql field" msgstr "pg_transform.trftosql ველის არასწორი მნიშვნელობა" -#: pg_dump.c:14365 +#: pg_dump.c:14396 #, c-format msgid "postfix operators are not supported anymore (operator \"%s\")" msgstr "postfix ოპერატორები მხარდაჭერილი აღარაა (ოპერატორი \"%s\")" -#: pg_dump.c:14535 +#: pg_dump.c:14566 #, c-format msgid "could not find operator with OID %s" msgstr "ოპერატორი OID-ით %s არ არსებობს" -#: pg_dump.c:14603 +#: pg_dump.c:14634 #, c-format msgid "invalid type \"%c\" of access method \"%s\"" msgstr "წვდომის მეთოდის (%2$s) არასწორი ტიპი: %1$c" -#: pg_dump.c:15277 pg_dump.c:15345 +#: pg_dump.c:15308 pg_dump.c:15376 #, c-format msgid "unrecognized collation provider: %s" msgstr "კოლაციის უცნობი მომწოდებელი: %s" -#: pg_dump.c:15286 pg_dump.c:15293 pg_dump.c:15304 pg_dump.c:15314 -#: pg_dump.c:15329 +#: pg_dump.c:15317 pg_dump.c:15324 pg_dump.c:15335 pg_dump.c:15345 +#: pg_dump.c:15360 #, c-format msgid "invalid collation \"%s\"" msgstr "არასწორი კოლაცია \"%s\"" -#: pg_dump.c:15735 +#: pg_dump.c:15766 #, c-format msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" msgstr "აგრეგატის (%s) aggfinalmodify -ის უცნობი ტიპი" -#: pg_dump.c:15791 +#: pg_dump.c:15822 #, c-format msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" msgstr "აგრეგატის (%s) aggmfinalmodify -ის უცნობი ტიპი" -#: pg_dump.c:16514 +#: pg_dump.c:16545 #, c-format msgid "unrecognized object type in default privileges: %d" msgstr "ნაგულისხმევ პრივილეგიებში არსებული ობიექტის უცნობი ტიპი: %d" -#: pg_dump.c:16530 +#: pg_dump.c:16561 #, c-format msgid "could not parse default ACL list (%s)" msgstr "ნაგულიხმები ACL სიის ანალიზი შეუძლებელია: %s" -#: pg_dump.c:16614 +#: pg_dump.c:16645 #, c-format msgid "could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)" msgstr "საწყისი ACL სიის (%s) დამუშავების შეცდომა ან ნაგულისხმევი (%s) ობიექტისთვის \"%s\" (%s)" -#: pg_dump.c:16639 +#: pg_dump.c:16670 #, c-format msgid "could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)" msgstr "შეცდომა ACL სიის (%s) დამუშავებისას ან ნაგულისხმევი (%s) ობიექტისთვის \"%s\" (%s)" -#: pg_dump.c:17194 +#: pg_dump.c:17225 #, c-format msgid "query to obtain definition of view \"%s\" returned no data" msgstr "ხედის (%s) აღწერის გამოთხოვამ მონაცემები არ დააბრუნა" -#: pg_dump.c:17197 +#: pg_dump.c:17228 #, c-format msgid "query to obtain definition of view \"%s\" returned more than one definition" msgstr "ხედის (%s) აღწერის გამოთხოვამ ერთზე მეტი აღწერა დააბრუნა" -#: pg_dump.c:17204 +#: pg_dump.c:17235 #, c-format msgid "definition of view \"%s\" appears to be empty (length zero)" msgstr "ხედის (%s) აღწერა, როგორც ჩანს, ცარიელია (ნულოვანი სიგრძე)" -#: pg_dump.c:17289 +#: pg_dump.c:17320 #, c-format msgid "WITH OIDS is not supported anymore (table \"%s\")" msgstr "WITH OIDS-ები უკვე მხარდაუჭერელია (ცხრილი \"%s\")" -#: pg_dump.c:17352 +#: pg_dump.c:17383 #, c-format msgid "query to obtain definition of property graph \"%s\" returned no data" msgstr "თვისების გრაფიკის \"%s\" აღწერის გამოთხოვამ მონაცემები არ დააბრუნა" -#: pg_dump.c:17355 +#: pg_dump.c:17386 #, c-format msgid "query to obtain definition of property graph \"%s\" returned more than one definition" msgstr "თვისების გრაფიკის \"%s\" აღწერის გამოთხოვამ ერთზე მეტი აღწერა დააბრუნა" -#: pg_dump.c:17362 +#: pg_dump.c:17393 #, c-format msgid "definition of property graph \"%s\" appears to be empty (length zero)" msgstr "თვისების გრაფიკის \"%s\" აღწერა, როგორც ჩანს, ცარიელია (ნულოვანი სიგრძე)" -#: pg_dump.c:18471 +#: pg_dump.c:18502 #, c-format msgid "invalid column number %d for table \"%s\"" msgstr "სვეტების არასწორი რიცხვი %d ცხრილისთვის %s" -#: pg_dump.c:18549 +#: pg_dump.c:18580 #, c-format msgid "could not parse index statistic columns" msgstr "ინდექსის სტატისტიკის სვეტების დამუშავების შეცდომა" -#: pg_dump.c:18551 +#: pg_dump.c:18582 #, c-format msgid "could not parse index statistic values" msgstr "ინდექსის სტატისტიკის მნიშვნელობების დამუშავების შეცდომა" -#: pg_dump.c:18553 +#: pg_dump.c:18584 #, c-format msgid "mismatched number of columns and values for index statistics" msgstr "ინდექსის სტატისტიკისთვის სვეტებისა და მნიშვნელობების რაოდენობა არ ემთხვევა" -#: pg_dump.c:18965 +#: pg_dump.c:18996 #, c-format msgid "inherited cannot be NULL" msgstr "მემკვიდრეობა არ შეიძლება, NULL იყოს" -#: pg_dump.c:19062 +#: pg_dump.c:19093 #, c-format msgid "missing index for constraint \"%s\"" msgstr "შეზღუდვას ინდექსი აკლია: \"%s\"" -#: pg_dump.c:19331 +#: pg_dump.c:19362 #, c-format msgid "unrecognized constraint type: %c" msgstr "შეზღუდვის უცნობი ტიპი: %c" -#: pg_dump.c:19384 +#: pg_dump.c:19415 #, c-format msgid "unrecognized sequence type: %s" msgstr "მიმდევრობის უცნობი ტიპი: %s" -#: pg_dump.c:19517 pg_dump.c:19755 +#: pg_dump.c:19548 pg_dump.c:19786 #, c-format msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" msgstr[0] "მოთხოვნამ, რომელსაც მონაცემები მიმდევრობიდან (%s) უნდა მიეღო, %d მწკრივი დააბრუნა. (მოველოდი: 1)" msgstr[1] "მოთხოვნამ, რომელსაც მონაცემები მიმდევრობიდან (%s) უნდა მიეღო, %d მწკრივი დააბრუნა. (მოველოდი: 1)" -#: pg_dump.c:19553 +#: pg_dump.c:19584 #, c-format msgid "unrecognized sequence type: %d" msgstr "მიმდევრობის უცნობი ტიპი: %d" -#: pg_dump.c:19778 +#: pg_dump.c:19809 #, c-format msgid "failed to get data for sequence \"%s\"; user may lack SELECT privilege on the sequence or the sequence may have been concurrently dropped" msgstr "ჩავარდა მონაცემების მიღება მიმდევრობისთვის \"%s\". მომხმარებელს, შეიძლება, SELECT პრივილეგია არ აქვს მიმდევრობაზე, ან მიმდევრობა, შეიძლება, იმავე დროს წაიშალა" -#: pg_dump.c:20099 +#: pg_dump.c:20130 #, c-format msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" msgstr "მოთხოვნის შეცდომა, რომელსაც ცხრილისთვის \"%2$s\" წესი \"%1$s\" უნდა მიეღო: დაბრუნებულია მწკრივების არასწორი რაოდენობა" -#: pg_dump.c:20252 +#: pg_dump.c:20283 #, c-format msgid "could not find referenced extension %u" msgstr "მიბმული გაფართოება (%u) ვერ ვიპოვე" -#: pg_dump.c:20351 +#: pg_dump.c:20382 #, c-format msgid "mismatched number of configurations and conditions for extension" msgstr "კონფიგურაციებისა და პირობების რაოდენობა გაფართოებისთვის არ ემთხვევა" -#: pg_dump.c:20483 +#: pg_dump.c:20514 #, c-format msgid "reading dependency data" msgstr "დამოკიდებულების მონაცემების კითხვა" -#: pg_dump.c:20580 +#: pg_dump.c:20611 #, c-format msgid "no referencing object %u %u" msgstr "მიბმადი ობიექტის გარეშე %u %u" -#: pg_dump.c:20591 +#: pg_dump.c:20622 #, c-format msgid "no referenced object %u %u" msgstr "მიბმული ობიექტის გარეშე %u %u" -#: pg_dump.c:21024 pg_dump.c:21062 pg_dumpall.c:1858 pg_restore.c:642 +#: pg_dump.c:21055 pg_dump.c:21093 pg_dumpall.c:1858 pg_restore.c:642 #: pg_restore.c:688 #, c-format msgid "%s filter for \"%s\" is not allowed" diff --git a/src/bin/pg_dump/po/ru.po b/src/bin/pg_dump/po/ru.po index 5ec16ef517d..30a932edbbe 100644 --- a/src/bin/pg_dump/po/ru.po +++ b/src/bin/pg_dump/po/ru.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_dump (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-10 08:01+0300\n" -"PO-Revision-Date: 2026-05-10 08:53+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:50+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -132,7 +132,7 @@ msgstr "не удалось прочитать вывод команды \"%s\": msgid "no data was returned by command \"%s\"" msgstr "команда \"%s\" не выдала данные" -#: ../../common/exec.c:405 parallel.c:1611 +#: ../../common/exec.c:405 parallel.c:1613 #, c-format msgid "%s() failed: %m" msgstr "ошибка в %s(): %m" @@ -141,17 +141,27 @@ msgstr "ошибка в %s(): %m" msgid "out of memory" msgstr "нехватка памяти" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/file_utils.c:69 ../../common/file_utils.c:370 #: ../../common/file_utils.c:428 ../../common/file_utils.c:502 #, c-format @@ -735,22 +745,27 @@ msgstr "ошибка в %s() (код ошибки: %d)" msgid "could not create communication channels: %m" msgstr "не удалось создать каналы межпроцессного взаимодействия: %m" -#: parallel.c:1018 +#: parallel.c:980 +#, c-format +msgid "could not create worker thread: %m" +msgstr "не удалось создать рабочий поток: %m" + +#: parallel.c:1020 #, c-format msgid "could not create worker process: %m" msgstr "не удалось создать рабочий процесс: %m" -#: parallel.c:1148 +#: parallel.c:1150 #, c-format msgid "unrecognized command received from leader: \"%s\"" msgstr "от ведущего процесса получена нераспознанная команда: \"%s\"" -#: parallel.c:1191 parallel.c:1429 +#: parallel.c:1193 parallel.c:1431 #, c-format msgid "invalid message received from worker: \"%s\"" msgstr "от рабочего процесса получено ошибочное сообщение: \"%s\"" -#: parallel.c:1323 +#: parallel.c:1325 #, c-format msgid "" "could not obtain lock on relation \"%s\"\n" @@ -763,47 +778,47 @@ msgstr "" "этой таблицы после того, как родительский процесс pg_dump получил для неё " "начальную блокировку ACCESS SHARE." -#: parallel.c:1412 +#: parallel.c:1414 #, c-format msgid "a worker process died unexpectedly" msgstr "рабочий процесс неожиданно прервался" -#: parallel.c:1534 parallel.c:1652 +#: parallel.c:1536 parallel.c:1654 #, c-format msgid "could not write to the communication channel: %m" msgstr "не удалось записать в канал взаимодействия: %m" -#: parallel.c:1736 +#: parallel.c:1738 #, c-format msgid "pgpipe: could not create socket: error code %d" msgstr "pgpipe: не удалось создать сокет (код ошибки: %d)" -#: parallel.c:1747 +#: parallel.c:1749 #, c-format msgid "pgpipe: could not bind: error code %d" msgstr "pgpipe: не удалось привязаться к сокету (код ошибки: %d)" -#: parallel.c:1754 +#: parallel.c:1756 #, c-format msgid "pgpipe: could not listen: error code %d" msgstr "pgpipe: не удалось начать приём (код ошибки: %d)" -#: parallel.c:1761 +#: parallel.c:1763 #, c-format msgid "pgpipe: %s() failed: error code %d" msgstr "pgpipe: ошибка в %s() (код ошибки: %d)" -#: parallel.c:1772 +#: parallel.c:1774 #, c-format msgid "pgpipe: could not create second socket: error code %d" msgstr "pgpipe: не удалось создать второй сокет (код ошибки: %d)" -#: parallel.c:1781 +#: parallel.c:1783 #, c-format msgid "pgpipe: could not connect socket: error code %d" msgstr "pgpipe: не удалось подключить сокет (код ошибки: %d)" -#: parallel.c:1790 +#: parallel.c:1792 #, c-format msgid "pgpipe: could not accept connection: error code %d" msgstr "pgpipe: не удалось принять соединение (код ошибки: %d)" @@ -1100,12 +1115,12 @@ msgstr "не удалось открыть stdout для добавления в msgid "unrecognized file format \"%d\"" msgstr "неопознанный формат файла: \"%d\"" -#: pg_backup_archiver.c:2567 pg_backup_archiver.c:4798 +#: pg_backup_archiver.c:2567 pg_backup_archiver.c:4837 #, c-format msgid "finished item %d %s %s" msgstr "закончен объект %d %s %s" -#: pg_backup_archiver.c:2571 pg_backup_archiver.c:4811 +#: pg_backup_archiver.c:2571 pg_backup_archiver.c:4850 #, c-format msgid "worker process failed: exit code %d" msgstr "рабочий процесс завершился с кодом возврата %d" @@ -1172,57 +1187,57 @@ msgstr "функция \"%s\" не найдена" msgid "trigger \"%s\" not found" msgstr "триггер \"%s\" не найден" -#: pg_backup_archiver.c:3470 +#: pg_backup_archiver.c:3509 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "не удалось переключить пользователя сеанса на \"%s\": %s" -#: pg_backup_archiver.c:3612 +#: pg_backup_archiver.c:3651 #, c-format msgid "could not set \"search_path\" to \"%s\": %s" msgstr "не удалось присвоить \"search_path\" значение \"%s\": %s" -#: pg_backup_archiver.c:3673 +#: pg_backup_archiver.c:3712 #, c-format msgid "could not set \"default_tablespace\" to %s: %s" msgstr "не удалось задать для \"default_tablespace\" значение %s: %s" -#: pg_backup_archiver.c:3722 +#: pg_backup_archiver.c:3761 #, c-format msgid "could not set \"default_table_access_method\": %s" msgstr "не удалось задать \"default_table_access_method\": %s" -#: pg_backup_archiver.c:3771 +#: pg_backup_archiver.c:3810 #, c-format msgid "could not alter table access method: %s" msgstr "не удалось изменить табличный метод доступа: %s" -#: pg_backup_archiver.c:3872 +#: pg_backup_archiver.c:3911 #, c-format msgid "don't know how to set owner for object type \"%s\"" msgstr "неизвестно, как назначить владельца для объекта типа \"%s\"" -#: pg_backup_archiver.c:4007 +#: pg_backup_archiver.c:4046 #, c-format msgid "unexpected TOC entry in _printTocEntry(): %d %s %s" msgstr "неожиданная запись оглавления в _printTocEntry(): %d %s %s" -#: pg_backup_archiver.c:4155 +#: pg_backup_archiver.c:4194 #, c-format msgid "did not find magic string in file header" msgstr "в заголовке файла не найдена нужная сигнатура" -#: pg_backup_archiver.c:4169 +#: pg_backup_archiver.c:4208 #, c-format msgid "unsupported version (%d.%d) in file header" msgstr "неподдерживаемая версия (%d.%d) в заголовке файла" -#: pg_backup_archiver.c:4174 +#: pg_backup_archiver.c:4213 #, c-format msgid "sanity check on integer size (%lu) failed" msgstr "несоответствие размера integer (%lu)" -#: pg_backup_archiver.c:4178 +#: pg_backup_archiver.c:4217 #, c-format msgid "" "archive was made on a machine with larger integers, some operations might " @@ -1231,12 +1246,12 @@ msgstr "" "архив был сделан на компьютере большей разрядности -- возможен сбой " "некоторых операций" -#: pg_backup_archiver.c:4188 +#: pg_backup_archiver.c:4227 #, c-format msgid "expected format (%d) differs from format found in file (%d)" msgstr "ожидаемый формат (%d) отличается от формата, указанного в файле (%d)" -#: pg_backup_archiver.c:4210 +#: pg_backup_archiver.c:4249 #, c-format msgid "" "archive is compressed, but this installation does not support compression " @@ -1245,42 +1260,42 @@ msgstr "" "архив сжат, но установленная версия не поддерживает сжатие (%s) -- данные " "будут недоступны" -#: pg_backup_archiver.c:4246 +#: pg_backup_archiver.c:4285 #, c-format msgid "invalid creation date in header" msgstr "неверная дата создания в заголовке" -#: pg_backup_archiver.c:4380 +#: pg_backup_archiver.c:4419 #, c-format msgid "processing item %d %s %s" msgstr "обработка объекта %d %s %s" -#: pg_backup_archiver.c:4465 +#: pg_backup_archiver.c:4504 #, c-format msgid "entering main parallel loop" msgstr "вход в основной параллельный цикл" -#: pg_backup_archiver.c:4476 +#: pg_backup_archiver.c:4515 #, c-format msgid "skipping item %d %s %s" msgstr "объект %d %s %s пропускается" -#: pg_backup_archiver.c:4485 +#: pg_backup_archiver.c:4524 #, c-format msgid "launching item %d %s %s" msgstr "объект %d %s %s запускается" -#: pg_backup_archiver.c:4539 +#: pg_backup_archiver.c:4578 #, c-format msgid "finished main parallel loop" msgstr "основной параллельный цикл закончен" -#: pg_backup_archiver.c:4575 +#: pg_backup_archiver.c:4614 #, c-format msgid "processing missed item %d %s %s" msgstr "обработка пропущенного объекта %d %s %s" -#: pg_backup_archiver.c:5117 +#: pg_backup_archiver.c:5156 #, c-format msgid "table \"%s\" could not be created, will not restore its data" msgstr "создать таблицу \"%s\" не удалось, её данные не будут восстановлены" @@ -2462,13 +2477,13 @@ msgstr "" "нарушение целостности: таблица с OID %u, фигурирующим в " "pg_partitioned_table, не найдена" -#: pg_dump.c:7931 pg_dump.c:8224 pg_dump.c:8687 pg_dump.c:9334 pg_dump.c:9473 +#: pg_dump.c:7929 pg_dump.c:8224 pg_dump.c:8687 pg_dump.c:9334 pg_dump.c:9473 #: pg_dump.c:9618 pg_dump.c:9718 #, c-format msgid "unrecognized table OID %u" msgstr "нераспознанный OID таблицы %u" -#: pg_dump.c:7935 +#: pg_dump.c:7933 #, c-format msgid "unexpected index data for table \"%s\"" msgstr "неожиданно получены данные индекса для таблицы \"%s\"" diff --git a/src/bin/pg_resetwal/po/de.po b/src/bin/pg_resetwal/po/de.po index 7da5ff50751..dfbe85f39b4 100644 --- a/src/bin/pg_resetwal/po/de.po +++ b/src/bin/pg_resetwal/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-28 19:24+0000\n" -"PO-Revision-Date: 2026-04-17 13:18+0200\n" +"POT-Creation-Date: 2026-08-04 09:54+0000\n" +"PO-Revision-Date: 2026-08-04 12:13+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -37,12 +37,12 @@ msgstr "Detail: " msgid "hint: " msgstr "Tipp: " -#: ../../common/controldata_utils.c:98 pg_resetwal.c:420 pg_resetwal.c:610 +#: ../../common/controldata_utils.c:98 pg_resetwal.c:424 pg_resetwal.c:614 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" -#: ../../common/controldata_utils.c:111 pg_resetwal.c:625 +#: ../../common/controldata_utils.c:111 pg_resetwal.c:629 #, c-format msgid "could not read file \"%s\": %m" msgstr "konnte Datei »%s« nicht lesen: %m" @@ -77,12 +77,12 @@ msgstr "" #: ../../common/controldata_utils.c:231 ../../common/file_utils.c:69 #: ../../common/file_utils.c:370 ../../common/file_utils.c:428 -#: ../../common/file_utils.c:502 pg_resetwal.c:1182 +#: ../../common/file_utils.c:502 pg_resetwal.c:1186 #, c-format msgid "could not open file \"%s\": %m" msgstr "konnte Datei »%s« nicht öffnen: %m" -#: ../../common/controldata_utils.c:250 pg_resetwal.c:1190 pg_resetwal.c:1202 +#: ../../common/controldata_utils.c:250 pg_resetwal.c:1194 pg_resetwal.c:1206 #, c-format msgid "could not write file \"%s\": %m" msgstr "konnte Datei »%s« nicht schreiben: %m" @@ -132,13 +132,13 @@ msgid "this build does not support sync method \"%s\"" msgstr "diese Installation unterstützt Sync-Methode »%s« nicht" #: ../../common/file_utils.c:156 ../../common/file_utils.c:304 -#: pg_resetwal.c:971 pg_resetwal.c:1024 pg_resetwal.c:1059 pg_resetwal.c:1099 +#: pg_resetwal.c:975 pg_resetwal.c:1028 pg_resetwal.c:1063 pg_resetwal.c:1103 #, c-format msgid "could not open directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" #: ../../common/file_utils.c:174 ../../common/file_utils.c:338 -#: pg_resetwal.c:997 pg_resetwal.c:1038 pg_resetwal.c:1076 pg_resetwal.c:1113 +#: pg_resetwal.c:1001 pg_resetwal.c:1042 pg_resetwal.c:1080 pg_resetwal.c:1117 #, c-format msgid "could not read directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht lesen: %m" @@ -216,15 +216,15 @@ msgstr "konnte Versionsdatei »%s« nicht parsen" #. translator: %s is a command line argument (-e, etc) #: pg_resetwal.c:192 pg_resetwal.c:204 pg_resetwal.c:218 pg_resetwal.c:232 #: pg_resetwal.c:239 pg_resetwal.c:259 pg_resetwal.c:273 pg_resetwal.c:281 -#: pg_resetwal.c:302 pg_resetwal.c:312 pg_resetwal.c:347 +#: pg_resetwal.c:302 pg_resetwal.c:316 pg_resetwal.c:351 #, c-format msgid "invalid argument for option %s" msgstr "ungültiges Argument für Option %s" #: pg_resetwal.c:193 pg_resetwal.c:205 pg_resetwal.c:219 pg_resetwal.c:233 #: pg_resetwal.c:240 pg_resetwal.c:260 pg_resetwal.c:274 pg_resetwal.c:282 -#: pg_resetwal.c:303 pg_resetwal.c:313 pg_resetwal.c:348 pg_resetwal.c:357 -#: pg_resetwal.c:370 pg_resetwal.c:377 +#: pg_resetwal.c:303 pg_resetwal.c:317 pg_resetwal.c:352 pg_resetwal.c:361 +#: pg_resetwal.c:374 pg_resetwal.c:381 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Versuchen Sie »%s --help« für weitere Informationen." @@ -259,92 +259,97 @@ msgstr "nächste Multitransaktions-ID (-m) darf nicht 0 sein" msgid "oldest multitransaction ID (-m) must not be 0" msgstr "älteste Multitransaktions-ID (-m) darf nicht 0 sein" -#: pg_resetwal.c:332 +#: pg_resetwal.c:309 +#, c-format +msgid "next multitransaction offset (-O) must not be 0" +msgstr "nächster Multitransaktions-Offset (-O) darf nicht 0 sein" + +#: pg_resetwal.c:336 #, c-format msgid "argument of %s must be a power of two between 1 and 1024" msgstr "Argument von %s muss eine Zweierpotenz zwischen 1 und 1024 sein" -#: pg_resetwal.c:368 +#: pg_resetwal.c:372 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" -#: pg_resetwal.c:376 +#: pg_resetwal.c:380 #, c-format msgid "no data directory specified" msgstr "kein Datenverzeichnis angegeben" -#: pg_resetwal.c:390 +#: pg_resetwal.c:394 #, c-format msgid "cannot be executed by \"root\"" msgstr "kann nicht von »root« ausgeführt werden" -#: pg_resetwal.c:391 +#: pg_resetwal.c:395 #, c-format msgid "You must run %s as the PostgreSQL superuser." msgstr "Sie müssen %s als PostgreSQL-Superuser ausführen." -#: pg_resetwal.c:401 +#: pg_resetwal.c:405 #, c-format msgid "could not read permissions of directory \"%s\": %m" msgstr "konnte Zugriffsrechte von Verzeichnis »%s« nicht lesen: %m" -#: pg_resetwal.c:407 +#: pg_resetwal.c:411 #, c-format msgid "could not change directory to \"%s\": %m" msgstr "konnte nicht in Verzeichnis »%s« wechseln: %m" -#: pg_resetwal.c:425 +#: pg_resetwal.c:429 #, c-format msgid "lock file \"%s\" exists" msgstr "Sperrdatei »%s« existiert" -#: pg_resetwal.c:426 +#: pg_resetwal.c:430 #, c-format msgid "Is a server running? If not, delete the lock file and try again." msgstr "Läuft der Server? Wenn nicht, dann Sperrdatei löschen und nochmal versuchen." -#: pg_resetwal.c:529 +#: pg_resetwal.c:533 #, c-format msgid "not proceeding because control file values were guessed" msgstr "es wird nicht fortgefahren, weil Kontrolldateiwerte geschätzt wurden" -#: pg_resetwal.c:530 +#: pg_resetwal.c:534 #, c-format msgid "If these values seem acceptable, use -f to force reset." msgstr "Wenn diese Werte akzeptabel scheinen, dann benutzen Sie -f, um das Zurücksetzen zu erzwingen." -#: pg_resetwal.c:539 +#: pg_resetwal.c:543 #, c-format msgid "database server was not shut down cleanly" msgstr "Datenbankserver wurde nicht sauber heruntergefahren" -#: pg_resetwal.c:540 +#: pg_resetwal.c:544 #, c-format msgid "Resetting the write-ahead log might cause data to be lost." msgstr "Beim Zurücksetzen des Write-Ahead-Logs können Daten verloren gehen." -#: pg_resetwal.c:541 +#: pg_resetwal.c:545 #, c-format msgid "If you want to proceed anyway, use -f to force reset." msgstr "Wenn Sie trotzdem weiter machen wollen, dann benutzen Sie -f, um das Zurücksetzen zu erzwingen." -#: pg_resetwal.c:554 +#: pg_resetwal.c:558 #, c-format msgid "Write-ahead log reset\n" msgstr "Write-Ahead-Log wurde zurückgesetzt\n" -#: pg_resetwal.c:579 +#: pg_resetwal.c:583 #, c-format msgid "data directory is of wrong version" msgstr "Datenverzeichnis hat falsche Version" -#: pg_resetwal.c:580 +#: pg_resetwal.c:584 #, c-format msgid "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\"." msgstr "Datei »%s« enthält »%s«, was nicht mit der Version dieses Programms »%s« kompatibel ist." -#: pg_resetwal.c:613 +#: pg_resetwal.c:617 #, c-format msgid "" "If you are sure the data directory path is correct, execute\n" @@ -355,24 +360,24 @@ msgstr "" " touch %s\n" "aus und versuchen Sie es erneut." -#: pg_resetwal.c:641 +#: pg_resetwal.c:645 #, c-format msgid "pg_control exists but has invalid CRC; proceed with caution" msgstr "pg_control existiert, aber mit ungültiger CRC; mit Vorsicht fortfahren" -#: pg_resetwal.c:650 +#: pg_resetwal.c:654 #, c-format msgid "pg_control specifies invalid WAL segment size (%d byte); proceed with caution" msgid_plural "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution" msgstr[0] "pg_control gibt ungültige WAL-Segmentgröße an (%d Byte); mit Vorsicht fortfahren" msgstr[1] "pg_control gibt ungültige WAL-Segmentgröße an (%d Bytes); mit Vorsicht fortfahren" -#: pg_resetwal.c:661 +#: pg_resetwal.c:665 #, c-format msgid "pg_control exists but is broken or wrong version; ignoring it" msgstr "pg_control existiert, aber ist kaputt oder hat falsche Version; wird ignoriert" -#: pg_resetwal.c:757 +#: pg_resetwal.c:761 #, c-format msgid "" "Guessed pg_control values:\n" @@ -381,7 +386,7 @@ msgstr "" "Geschätzte pg_control-Werte:\n" "\n" -#: pg_resetwal.c:759 +#: pg_resetwal.c:763 #, c-format msgid "" "Current pg_control values:\n" @@ -390,185 +395,185 @@ msgstr "" "Aktuelle pg_control-Werte:\n" "\n" -#: pg_resetwal.c:761 +#: pg_resetwal.c:765 #, c-format msgid "pg_control version number: %u\n" msgstr "pg_control-Versionsnummer: %u\n" -#: pg_resetwal.c:763 +#: pg_resetwal.c:767 #, c-format msgid "Catalog version number: %u\n" msgstr "Katalogversionsnummer: %u\n" -#: pg_resetwal.c:765 +#: pg_resetwal.c:769 #, c-format msgid "Database system identifier: %\n" msgstr "Datenbanksystemidentifikation: %\n" -#: pg_resetwal.c:767 +#: pg_resetwal.c:771 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "TimeLineID des letzten Checkpoints: %u\n" -#: pg_resetwal.c:769 +#: pg_resetwal.c:773 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "full_page_writes des letzten Checkpoints: %s\n" -#: pg_resetwal.c:770 +#: pg_resetwal.c:774 msgid "off" msgstr "aus" -#: pg_resetwal.c:770 +#: pg_resetwal.c:774 msgid "on" msgstr "an" -#: pg_resetwal.c:771 +#: pg_resetwal.c:775 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "NextXID des letzten Checkpoints: %u:%u\n" -#: pg_resetwal.c:774 +#: pg_resetwal.c:778 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "NextOID des letzten Checkpoints: %u\n" -#: pg_resetwal.c:776 +#: pg_resetwal.c:780 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "NextMultiXactId des letzten Checkpoints: %u\n" -#: pg_resetwal.c:778 +#: pg_resetwal.c:782 #, c-format msgid "Latest checkpoint's NextMultiOffset: %\n" msgstr "NextMultiOffset des letzten Checkpoints: %\n" -#: pg_resetwal.c:780 +#: pg_resetwal.c:784 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "oldestXID des letzten Checkpoints: %u\n" -#: pg_resetwal.c:782 +#: pg_resetwal.c:786 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "DB der oldestXID des letzten Checkpoints: %u\n" -#: pg_resetwal.c:784 +#: pg_resetwal.c:788 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "oldestActiveXID des letzten Checkpoints: %u\n" -#: pg_resetwal.c:786 +#: pg_resetwal.c:790 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "oldestMultiXid des letzten Checkpoints: %u\n" -#: pg_resetwal.c:788 +#: pg_resetwal.c:792 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "DB des oldestMulti des letzten Checkpoints: %u\n" -#: pg_resetwal.c:790 +#: pg_resetwal.c:794 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "oldestCommitTsXid des letzten Checkpoints: %u\n" -#: pg_resetwal.c:792 +#: pg_resetwal.c:796 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "newestCommitTsXid des letzten Checkpoints: %u\n" -#: pg_resetwal.c:794 +#: pg_resetwal.c:798 #, c-format msgid "Maximum data alignment: %u\n" msgstr "Maximale Datenausrichtung (Alignment): %u\n" -#: pg_resetwal.c:797 +#: pg_resetwal.c:801 #, c-format msgid "Database block size: %u\n" msgstr "Datenbankblockgröße: %u\n" -#: pg_resetwal.c:799 +#: pg_resetwal.c:803 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Blöcke pro Segment: %u\n" -#: pg_resetwal.c:801 +#: pg_resetwal.c:805 #, c-format msgid "Pages per SLRU segment: %u\n" msgstr "Seiten pro SLRU-Segment: %u\n" -#: pg_resetwal.c:803 +#: pg_resetwal.c:807 #, c-format msgid "WAL block size: %u\n" msgstr "WAL-Blockgröße: %u\n" -#: pg_resetwal.c:805 pg_resetwal.c:894 +#: pg_resetwal.c:809 pg_resetwal.c:898 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Bytes pro WAL-Segment: %u\n" -#: pg_resetwal.c:807 +#: pg_resetwal.c:811 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "Maximale Bezeichnerlänge: %u\n" -#: pg_resetwal.c:809 +#: pg_resetwal.c:813 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "Maximale Spalten in einem Index: %u\n" -#: pg_resetwal.c:811 +#: pg_resetwal.c:815 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "Maximale Größe eines Stücks TOAST: %u\n" -#: pg_resetwal.c:813 +#: pg_resetwal.c:817 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Größe eines Large-Object-Chunks: %u\n" -#: pg_resetwal.c:816 +#: pg_resetwal.c:820 #, c-format msgid "Date/time type storage: %s\n" msgstr "Speicherung von Datum/Zeit-Typen: %s\n" -#: pg_resetwal.c:817 +#: pg_resetwal.c:821 msgid "64-bit integers" msgstr "64-Bit-Ganzzahlen" -#: pg_resetwal.c:818 +#: pg_resetwal.c:822 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Übergabe von Float8-Argumenten: %s\n" -#: pg_resetwal.c:819 +#: pg_resetwal.c:823 msgid "by reference" msgstr "Referenz" -#: pg_resetwal.c:819 +#: pg_resetwal.c:823 msgid "by value" msgstr "Wert" -#: pg_resetwal.c:820 +#: pg_resetwal.c:824 #, c-format msgid "Data page checksum version: %u\n" msgstr "Datenseitenprüfsummenversion: %u\n" -#: pg_resetwal.c:822 +#: pg_resetwal.c:826 #, c-format msgid "Default char data signedness: %s\n" msgstr "Standard für Vorzeichen von »char«-Daten: %s\n" -#: pg_resetwal.c:823 +#: pg_resetwal.c:827 msgid "signed" msgstr "mit Vorzeichen" -#: pg_resetwal.c:823 +#: pg_resetwal.c:827 msgid "unsigned" msgstr "ohne Vorzeichen" -#: pg_resetwal.c:836 +#: pg_resetwal.c:840 #, c-format msgid "" "\n" @@ -581,82 +586,82 @@ msgstr "" "Zu ändernde Werte:\n" "\n" -#: pg_resetwal.c:840 +#: pg_resetwal.c:844 #, c-format msgid "First log segment after reset: %s\n" msgstr "Erstes Logdateisegment nach Zurücksetzen: %s\n" -#: pg_resetwal.c:844 +#: pg_resetwal.c:848 #, c-format msgid "NextMultiXactId: %u\n" msgstr "NextMultiXactId: %u\n" -#: pg_resetwal.c:846 +#: pg_resetwal.c:850 #, c-format msgid "OldestMultiXid: %u\n" msgstr "OldestMultiXid: %u\n" -#: pg_resetwal.c:848 +#: pg_resetwal.c:852 #, c-format msgid "OldestMulti's DB: %u\n" msgstr "OldestMulti's DB: %u\n" -#: pg_resetwal.c:854 +#: pg_resetwal.c:858 #, c-format msgid "NextMultiOffset: %\n" msgstr "NextMultiOffset: %\n" -#: pg_resetwal.c:860 +#: pg_resetwal.c:864 #, c-format msgid "NextOID: %u\n" msgstr "NextOID: %u\n" -#: pg_resetwal.c:866 +#: pg_resetwal.c:870 #, c-format msgid "NextXID: %u\n" msgstr "NextXID: %u\n" -#: pg_resetwal.c:872 +#: pg_resetwal.c:876 #, c-format msgid "OldestXID: %u\n" msgstr "OldestXID: %u\n" -#: pg_resetwal.c:874 +#: pg_resetwal.c:878 #, c-format msgid "OldestXID's DB: %u\n" msgstr "OldestXID's DB: %u\n" -#: pg_resetwal.c:880 +#: pg_resetwal.c:884 #, c-format msgid "NextXID epoch: %u\n" msgstr "NextXID-Epoche: %u\n" -#: pg_resetwal.c:886 +#: pg_resetwal.c:890 #, c-format msgid "oldestCommitTsXid: %u\n" msgstr "oldestCommitTsXid: %u\n" -#: pg_resetwal.c:888 +#: pg_resetwal.c:892 #, c-format msgid "newestCommitTsXid: %u\n" msgstr "newestCommitTsXid: %u\n" -#: pg_resetwal.c:1000 pg_resetwal.c:1041 pg_resetwal.c:1079 pg_resetwal.c:1116 +#: pg_resetwal.c:1004 pg_resetwal.c:1045 pg_resetwal.c:1083 pg_resetwal.c:1120 #, c-format msgid "could not close directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht schließen: %m" -#: pg_resetwal.c:1033 pg_resetwal.c:1071 pg_resetwal.c:1108 +#: pg_resetwal.c:1037 pg_resetwal.c:1075 pg_resetwal.c:1112 #, c-format msgid "could not delete file \"%s\": %m" msgstr "konnte Datei »%s« nicht löschen: %m" -#: pg_resetwal.c:1207 +#: pg_resetwal.c:1211 #, c-format msgid "fsync error: %m" msgstr "fsync-Fehler: %m" -#: pg_resetwal.c:1216 +#: pg_resetwal.c:1220 #, c-format msgid "" "%s resets the PostgreSQL write-ahead log.\n" @@ -665,17 +670,17 @@ msgstr "" "%s setzt den PostgreSQL-Write-Ahead-Log zurück.\n" "\n" -#: pg_resetwal.c:1217 +#: pg_resetwal.c:1221 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" -#: pg_resetwal.c:1218 +#: pg_resetwal.c:1222 #, c-format msgid " %s [OPTION]... DATADIR\n" msgstr " %s [OPTION]... DATENVERZEICHNIS\n" -#: pg_resetwal.c:1220 +#: pg_resetwal.c:1224 #, c-format msgid "" "\n" @@ -684,12 +689,12 @@ msgstr "" "\n" "Optionen:\n" -#: pg_resetwal.c:1221 +#: pg_resetwal.c:1225 #, c-format msgid " [-D, --pgdata=]DATADIR data directory\n" msgstr " [-D, --pgdata=]VERZ Datenbankverzeichnis\n" -#: pg_resetwal.c:1222 +#: pg_resetwal.c:1226 #, c-format msgid "" " -f, --force force update to be done even after unclean shutdown or\n" @@ -698,22 +703,22 @@ msgstr "" " -f, --force Änderung erzwingen, auch nach unsauberem Herunterfahren\n" " oder wenn pg_control-Werte geschätzt werden mussten\n" -#: pg_resetwal.c:1224 +#: pg_resetwal.c:1228 #, c-format msgid " -n, --dry-run no update, just show what would be done\n" msgstr " -n, --dry-run keine Änderungen; nur zeigen, was gemacht werden würde\n" -#: pg_resetwal.c:1225 +#: pg_resetwal.c:1229 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: pg_resetwal.c:1226 +#: pg_resetwal.c:1230 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_resetwal.c:1228 +#: pg_resetwal.c:1232 #, c-format msgid "" "\n" @@ -722,7 +727,7 @@ msgstr "" "\n" "Optionen um Kontrolldateiwerte setzen:\n" -#: pg_resetwal.c:1229 +#: pg_resetwal.c:1233 #, c-format msgid "" " -c, --commit-timestamp-ids=XID,XID\n" @@ -733,54 +738,54 @@ msgstr "" " älteste und neuste Transaktion mit Commit-\n" " Timestamp setzen (Null bedeutet keine Änderung)\n" -#: pg_resetwal.c:1232 +#: pg_resetwal.c:1236 #, c-format msgid " -e, --epoch=XIDEPOCH set next transaction ID epoch\n" msgstr " -e, --epoch=XIDEPOCHE nächste Transaktions-ID-Epoche setzen\n" -#: pg_resetwal.c:1233 +#: pg_resetwal.c:1237 #, c-format msgid " -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" msgstr " -l, --next-wal-file=WALDATEI minimale Startposition für neuen WAL setzen\n" -#: pg_resetwal.c:1234 +#: pg_resetwal.c:1238 #, c-format msgid " -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" msgstr " -m, --multixact-ids=MXID,MXID nächste und älteste Multitransaktions-ID setzen\n" -#: pg_resetwal.c:1235 +#: pg_resetwal.c:1239 #, c-format msgid " -o, --next-oid=OID set next OID\n" msgstr " -o, --next-oid=OID nächste OID setzen\n" -#: pg_resetwal.c:1236 +#: pg_resetwal.c:1240 #, c-format msgid " -O, --multixact-offset=OFFSET set next multitransaction offset\n" msgstr " -O, --multixact-offset=OFFSET nächsten Multitransaktions-Offset setzen\n" -#: pg_resetwal.c:1237 +#: pg_resetwal.c:1241 #, c-format msgid " -u, --oldest-transaction-id=XID set oldest transaction ID\n" msgstr " -u, --oldest-transaction-id=XID älteste Transaktions-ID setzen\n" -#: pg_resetwal.c:1238 +#: pg_resetwal.c:1242 #, c-format msgid " -x, --next-transaction-id=XID set next transaction ID\n" msgstr " -x, --next-transaction-id=XID nächste Transaktions-ID setzen\n" -#: pg_resetwal.c:1239 +#: pg_resetwal.c:1243 #, c-format msgid " --char-signedness=OPTION set char signedness to \"signed\" or \"unsigned\"\n" msgstr "" " --char-signedness=OPTION Standard für Vorzeichen von »char« auf\n" " »signed« oder »unsigned« setzen\n" -#: pg_resetwal.c:1240 +#: pg_resetwal.c:1244 #, c-format msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" msgstr " --wal-segsize=ZAHL Größe eines WAL-Segments, in Megabytes\n" -#: pg_resetwal.c:1242 +#: pg_resetwal.c:1246 #, c-format msgid "" "\n" @@ -789,7 +794,7 @@ msgstr "" "\n" "Berichten Sie Fehler an <%s>.\n" -#: pg_resetwal.c:1243 +#: pg_resetwal.c:1247 #, c-format msgid "%s home page: <%s>\n" msgstr "%s Homepage: <%s>\n" diff --git a/src/bin/pg_resetwal/po/ru.po b/src/bin/pg_resetwal/po/ru.po index b5c0ea47bb3..85aa8620713 100644 --- a/src/bin/pg_resetwal/po/ru.po +++ b/src/bin/pg_resetwal/po/ru.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_resetxlog (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-02-07 08:57+0200\n" -"PO-Revision-Date: 2026-02-07 09:15+0200\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:50+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -98,17 +98,27 @@ msgstr "не удалось записать файл \"%s\": %m" msgid "could not fsync file \"%s\": %m" msgstr "не удалось синхронизировать с ФС файл \"%s\": %m" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/file_utils.c:75 #, c-format msgid "could not synchronize file system for file \"%s\": %m" diff --git a/src/bin/pg_rewind/po/de.po b/src/bin/pg_rewind/po/de.po index 870495e71f1..e3a633ecf7e 100644 --- a/src/bin/pg_rewind/po/de.po +++ b/src/bin/pg_rewind/po/de.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: pg_rewind (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-07-04 06:27+0000\n" +"POT-Creation-Date: 2026-08-07 15:57+0000\n" "PO-Revision-Date: 2026-07-04 13:02+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" @@ -266,10 +266,9 @@ msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "Datenbankname enthält Newline oder Carriage Return: »%s«\n" #: file_ops.c:52 -#, fuzzy, c-format -#| msgid "link target has unsafe path name: \"%s\"" +#, c-format msgid "target file path is unsafe for open: \"%s\"" -msgstr "Ziel der Verknüpfung hat unsicheren Pfadnamen: »%s«" +msgstr "Zieldateipfad ist zum Öffnen nicht sicher: »%s«" #: file_ops.c:70 #, c-format @@ -297,10 +296,9 @@ msgid "invalid action (CREATE) for regular file" msgstr "ungültige Aktion (CREATE) für normale Datei" #: file_ops.c:195 -#, fuzzy, c-format -#| msgid "link target has unsafe path name: \"%s\"" +#, c-format msgid "target file path is unsafe for removal: \"%s\"" -msgstr "Ziel der Verknüpfung hat unsicheren Pfadnamen: »%s«" +msgstr "Zieldateipfad ist zum Entfernen nicht sicher: »%s«" #: file_ops.c:206 #, c-format @@ -308,10 +306,9 @@ msgid "could not remove file \"%s\": %m" msgstr "konnte Datei »%s« nicht löschen: %m" #: file_ops.c:218 -#, fuzzy, c-format -#| msgid "link target has unsafe path name: \"%s\"" +#, c-format msgid "target file path is unsafe for truncation: \"%s\"" -msgstr "Ziel der Verknüpfung hat unsicheren Pfadnamen: »%s«" +msgstr "Zieldateipfad ist für das Kürzen nicht sicher: »%s«" #: file_ops.c:227 #, c-format @@ -326,7 +323,7 @@ msgstr "konnte Datei »%s« nicht auf %u kürzen: %m" #: file_ops.c:243 #, c-format msgid "target directory path is unsafe for directory creation: \"%s\"" -msgstr "" +msgstr "Zielverzeichnispfad ist zum Erstellen des Verzeichnisses nicht sicher: »%s«" #: file_ops.c:251 #, c-format @@ -336,7 +333,7 @@ msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" #: file_ops.c:261 #, c-format msgid "target directory path is unsafe for directory removal: \"%s\"" -msgstr "" +msgstr "Zielverzeichnispfad ist zum Entfernen des Verzeichnisses nicht sicher: »%s«" #: file_ops.c:269 #, c-format @@ -344,10 +341,9 @@ msgid "could not remove directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht löschen: %m" #: file_ops.c:279 -#, fuzzy, c-format -#| msgid "link target has unsafe path name: \"%s\"" +#, c-format msgid "target symlink path is unsafe for creation: \"%s\"" -msgstr "Ziel der Verknüpfung hat unsicheren Pfadnamen: »%s«" +msgstr "Ziel-Symlink-Pfad ist zum Erstellen nicht sicher: »%s«" #: file_ops.c:286 #, c-format @@ -357,7 +353,7 @@ msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %m" #: file_ops.c:296 #, c-format msgid "target symlink path is unsafe for removal: \"%s\"" -msgstr "" +msgstr "Ziel-Symlink-Pfad ist zum Entfernen nicht sicher: »%s«" #: file_ops.c:303 #, c-format diff --git a/src/bin/pg_rewind/po/ru.po b/src/bin/pg_rewind/po/ru.po index 6f3d63dec58..55284d684a4 100644 --- a/src/bin/pg_rewind/po/ru.po +++ b/src/bin/pg_rewind/po/ru.po @@ -1,13 +1,13 @@ # Russian message translation file for pg_rewind # Copyright (C) 2015-2016 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Alexander Lakhin , 2015-2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024. +# SPDX-FileCopyrightText: 2015-2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: pg_rewind (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-02-08 07:44+0200\n" -"PO-Revision-Date: 2024-09-07 13:07+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 21:23+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -17,44 +17,44 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ../../../src/common/logging.c:276 +#: ../../../src/common/logging.c:279 #, c-format msgid "error: " msgstr "ошибка: " -#: ../../../src/common/logging.c:283 +#: ../../../src/common/logging.c:286 #, c-format msgid "warning: " msgstr "предупреждение: " -#: ../../../src/common/logging.c:294 +#: ../../../src/common/logging.c:297 #, c-format msgid "detail: " msgstr "подробности: " -#: ../../../src/common/logging.c:301 +#: ../../../src/common/logging.c:304 #, c-format msgid "hint: " msgstr "подсказка: " -#: ../../common/controldata_utils.c:97 file_ops.c:326 file_ops.c:330 +#: ../../common/controldata_utils.c:97 file_ops.c:349 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "не удалось открыть файл \"%s\" для чтения: %m" -#: ../../common/controldata_utils.c:110 file_ops.c:341 local_source.c:104 -#: local_source.c:163 parsexlog.c:371 +#: ../../common/controldata_utils.c:110 file_ops.c:364 local_source.c:102 +#: local_source.c:161 parsexlog.c:371 #, c-format msgid "could not read file \"%s\": %m" msgstr "не удалось прочитать файл \"%s\": %m" -#: ../../common/controldata_utils.c:119 file_ops.c:344 parsexlog.c:373 +#: ../../common/controldata_utils.c:119 file_ops.c:367 parsexlog.c:373 #, c-format msgid "could not read file \"%s\": read %d of %zu" msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d из %zu)" #: ../../common/controldata_utils.c:132 ../../common/controldata_utils.c:280 -#: local_source.c:121 local_source.c:172 +#: local_source.c:119 local_source.c:170 #, c-format msgid "could not close file \"%s\": %m" msgstr "не удалось закрыть файл \"%s\": %m" @@ -77,64 +77,74 @@ msgstr "" "этой программой. В этом случае результаты будут неверными и\n" "установленный PostgreSQL будет несовместим с этим каталогом данных." -#: ../../common/controldata_utils.c:230 ../../common/file_utils.c:70 -#: ../../common/file_utils.c:347 ../../common/file_utils.c:406 -#: ../../common/file_utils.c:480 ../../fe_utils/recovery_gen.c:140 +#: ../../common/controldata_utils.c:230 ../../common/file_utils.c:69 +#: ../../common/file_utils.c:370 ../../common/file_utils.c:428 +#: ../../common/file_utils.c:502 ../../fe_utils/recovery_gen.c:141 #: parsexlog.c:333 #, c-format msgid "could not open file \"%s\": %m" msgstr "не удалось открыть файл \"%s\": %m" -#: ../../common/controldata_utils.c:249 file_ops.c:117 +#: ../../common/controldata_utils.c:249 file_ops.c:120 #, c-format msgid "could not write file \"%s\": %m" msgstr "не удалось записать файл \"%s\": %m" -#: ../../common/controldata_utils.c:268 ../../common/file_utils.c:418 -#: ../../common/file_utils.c:488 +#: ../../common/controldata_utils.c:268 ../../common/file_utils.c:440 +#: ../../common/file_utils.c:510 #, c-format msgid "could not fsync file \"%s\": %m" msgstr "не удалось синхронизировать с ФС файл \"%s\": %m" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" -#: ../../common/file_utils.c:76 +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + +#: ../../common/file_utils.c:75 #, c-format msgid "could not synchronize file system for file \"%s\": %m" msgstr "не удалось синхронизировать с ФС файл \"%s\": %m" -#: ../../common/file_utils.c:120 ../../common/file_utils.c:566 -#: ../../fe_utils/archive.c:86 file_ops.c:417 +#: ../../common/file_utils.c:123 ../../common/file_utils.c:588 +#: ../../fe_utils/archive.c:86 file_ops.c:353 file_ops.c:440 #, c-format msgid "could not stat file \"%s\": %m" msgstr "не удалось получить информацию о файле \"%s\": %m" -#: ../../common/file_utils.c:130 ../../common/file_utils.c:227 +#: ../../common/file_utils.c:133 ../../common/file_utils.c:243 #: ../../fe_utils/option_utils.c:99 #, c-format msgid "this build does not support sync method \"%s\"" msgstr "эта сборка программы не поддерживает метод синхронизации \"%s\"" -#: ../../common/file_utils.c:151 ../../common/file_utils.c:281 file_ops.c:388 +#: ../../common/file_utils.c:156 ../../common/file_utils.c:304 file_ops.c:411 #, c-format msgid "could not open directory \"%s\": %m" msgstr "не удалось открыть каталог \"%s\": %m" -#: ../../common/file_utils.c:169 ../../common/file_utils.c:315 file_ops.c:462 +#: ../../common/file_utils.c:174 ../../common/file_utils.c:338 file_ops.c:485 #, c-format msgid "could not read directory \"%s\": %m" msgstr "не удалось прочитать каталог \"%s\": %m" -#: ../../common/file_utils.c:498 +#: ../../common/file_utils.c:520 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "не удалось переименовать файл \"%s\" в \"%s\": %m" @@ -219,122 +229,162 @@ msgstr "значение %s должно быть в диапазоне %d..%d" msgid "unrecognized sync method: %s" msgstr "нераспознанный метод синхронизации: %s" -#: ../../fe_utils/recovery_gen.c:39 ../../fe_utils/recovery_gen.c:50 -#: ../../fe_utils/recovery_gen.c:89 ../../fe_utils/recovery_gen.c:109 -#: ../../fe_utils/recovery_gen.c:168 +#: ../../fe_utils/recovery_gen.c:40 ../../fe_utils/recovery_gen.c:51 +#: ../../fe_utils/recovery_gen.c:90 ../../fe_utils/recovery_gen.c:110 +#: ../../fe_utils/recovery_gen.c:169 ../../fe_utils/recovery_gen.c:230 #, c-format msgid "out of memory" msgstr "нехватка памяти" -#: ../../fe_utils/recovery_gen.c:143 +#: ../../fe_utils/recovery_gen.c:144 #, c-format msgid "could not write to file \"%s\": %m" msgstr "не удалось записать в файл \"%s\": %m" -#: ../../fe_utils/recovery_gen.c:152 +#: ../../fe_utils/recovery_gen.c:153 #, c-format msgid "could not create file \"%s\": %m" msgstr "не удалось создать файл \"%s\": %m" -#: ../../fe_utils/string_utils.c:434 +#: ../../fe_utils/recovery_gen.c:215 pg_rewind.c:311 +#, c-format +msgid "%s" +msgstr "%s" + +#: ../../fe_utils/string_utils.c:587 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "" "аргумент команды оболочки содержит символ новой строки или перевода каретки: " "\"%s\"\n" -#: ../../fe_utils/string_utils.c:607 +#: ../../fe_utils/string_utils.c:760 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "" "имя базы данных содержит символ новой строки или перевода каретки: \"%s\"\n" -#: file_ops.c:67 +#: file_ops.c:52 +#, c-format +msgid "target file path is unsafe for open: \"%s\"" +msgstr "целевой путь небезопасен для открытия файла: \"%s\"" + +#: file_ops.c:70 #, c-format msgid "could not open target file \"%s\": %m" msgstr "не удалось открыть целевой файл \"%s\": %m" -#: file_ops.c:81 +#: file_ops.c:84 #, c-format msgid "could not close target file \"%s\": %m" msgstr "не удалось закрыть целевой файл \"%s\": %m" -#: file_ops.c:101 +#: file_ops.c:104 #, c-format msgid "could not seek in target file \"%s\": %m" msgstr "не удалось переместиться в целевом файле \"%s\": %m" -#: file_ops.c:150 file_ops.c:177 +#: file_ops.c:153 file_ops.c:180 #, c-format msgid "undefined file type for \"%s\"" msgstr "неопределённый тип файла \"%s\"" -#: file_ops.c:173 +#: file_ops.c:176 #, c-format msgid "invalid action (CREATE) for regular file" msgstr "неверное действие (CREATE) для обычного файла" -#: file_ops.c:200 +#: file_ops.c:195 +#, c-format +msgid "target file path is unsafe for removal: \"%s\"" +msgstr "целевой путь небезопасен для удаления файла: \"%s\"" + +#: file_ops.c:206 #, c-format msgid "could not remove file \"%s\": %m" msgstr "не удалось стереть файл \"%s\": %m" #: file_ops.c:218 #, c-format +msgid "target file path is unsafe for truncation: \"%s\"" +msgstr "целевой путь небезопасен для усечения файла: \"%s\"" + +#: file_ops.c:227 +#, c-format msgid "could not open file \"%s\" for truncation: %m" msgstr "не удалось открыть файл \"%s\" для усечения: %m" -#: file_ops.c:222 +#: file_ops.c:231 #, c-format msgid "could not truncate file \"%s\" to %u: %m" msgstr "не удалось обрезать файл \"%s\" до нужного размера (%u): %m" -#: file_ops.c:238 +#: file_ops.c:243 +#, c-format +msgid "target directory path is unsafe for directory creation: \"%s\"" +msgstr "целевой путь небезопасен для создания каталога: \"%s\"" + +#: file_ops.c:251 #, c-format msgid "could not create directory \"%s\": %m" msgstr "не удалось создать каталог \"%s\": %m" -#: file_ops.c:252 +#: file_ops.c:261 +#, c-format +msgid "target directory path is unsafe for directory removal: \"%s\"" +msgstr "целевой путь небезопасен для удаления каталога: \"%s\"" + +#: file_ops.c:269 #, c-format msgid "could not remove directory \"%s\": %m" msgstr "ошибка при удалении каталога \"%s\": %m" -#: file_ops.c:266 +#: file_ops.c:279 +#, c-format +msgid "target symlink path is unsafe for creation: \"%s\"" +msgstr "целевой путь небезопасен для создания символической ссылки: \"%s\"" + +#: file_ops.c:286 #, c-format msgid "could not create symbolic link at \"%s\": %m" msgstr "не удалось создать символическую ссылку \"%s\": %m" -#: file_ops.c:280 +#: file_ops.c:296 +#, c-format +msgid "target symlink path is unsafe for removal: \"%s\"" +msgstr "целевой путь небезопасен для удаления символической ссылки: \"%s\"" + +#: file_ops.c:303 #, c-format msgid "could not remove symbolic link \"%s\": %m" msgstr "ошибка при удалении символической ссылки \"%s\": %m" -#: file_ops.c:441 +#: file_ops.c:464 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "не удалось прочитать символическую ссылку \"%s\": %m" -#: file_ops.c:444 +#: file_ops.c:467 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "целевой путь символической ссылки \"%s\" слишком длинный" -#: file_ops.c:466 +#: file_ops.c:489 #, c-format msgid "could not close directory \"%s\": %m" msgstr "не удалось закрыть каталог \"%s\": %m" -#: filemap.c:297 +#: filemap.c:298 #, c-format msgid "data file \"%s\" in source is not a regular file" msgstr "файл данных \"%s\" в источнике не является обычным файлом" -#: filemap.c:302 filemap.c:335 +#: filemap.c:303 filemap.c:336 #, c-format msgid "duplicate source file \"%s\"" msgstr "повторный исходный файл \"%s\"" -#: filemap.c:390 +#: filemap.c:391 #, c-format msgid "unexpected page modification for non-regular file \"%s\"" msgstr "неожиданная модификация страницы для файла особого вида \"%s\"" @@ -354,78 +404,78 @@ msgstr "файл \"%s\" имеет разный тип в исходном и ц msgid "could not decide what to do with file \"%s\"" msgstr "не удалось определить, что делать с файлом \"%s\"" -#: libpq_source.c:131 +#: libpq_source.c:130 #, c-format msgid "could not clear \"search_path\": %s" msgstr "не удалось очистить \"search_path\": %s" -#: libpq_source.c:142 +#: libpq_source.c:141 #, c-format msgid "\"full_page_writes\" must be enabled in the source server" msgstr "на исходном сервере должен быть включён режим \"full_page_writes\"" -#: libpq_source.c:153 +#: libpq_source.c:152 #, c-format msgid "could not prepare statement to fetch file contents: %s" msgstr "не удалось подготовить оператор для извлечения содержимого файла: %s" -#: libpq_source.c:172 +#: libpq_source.c:171 #, c-format msgid "error running query (%s) on source server: %s" msgstr "ошибка выполнения запроса (%s) на исходном сервере: %s" -#: libpq_source.c:177 +#: libpq_source.c:176 #, c-format msgid "unexpected result set from query" msgstr "неожиданный результат запроса" -#: libpq_source.c:199 +#: libpq_source.c:198 #, c-format msgid "error running query (%s) in source server: %s" msgstr "ошибка выполнения запроса (%s) на исходном сервере: %s" -#: libpq_source.c:220 +#: libpq_source.c:219 #, c-format msgid "unrecognized result \"%s\" for current WAL insert location" msgstr "" "нераспознанный результат \"%s\" вместо текущей позиции добавления в WAL" -#: libpq_source.c:271 +#: libpq_source.c:270 #, c-format msgid "could not fetch file list: %s" msgstr "не удалось получить список файлов: %s" -#: libpq_source.c:276 +#: libpq_source.c:275 #, c-format msgid "unexpected result set while fetching file list" msgstr "неожиданный результат при получении списка файлов" -#: libpq_source.c:477 +#: libpq_source.c:476 #, c-format msgid "could not send query: %s" msgstr "не удалось отправить запрос: %s" -#: libpq_source.c:480 +#: libpq_source.c:479 #, c-format msgid "could not set libpq connection to single row mode" msgstr "не удалось перевести подключение libpq в однострочный режим" -#: libpq_source.c:510 +#: libpq_source.c:509 #, c-format msgid "unexpected result while fetching remote files: %s" msgstr "неожиданный результат при получении файлов с сервера: %s" -#: libpq_source.c:515 +#: libpq_source.c:514 #, c-format msgid "received more data chunks than requested" msgstr "получено больше сегментов данных, чем запрошено" -#: libpq_source.c:519 +#: libpq_source.c:518 #, c-format msgid "unexpected result set size while fetching remote files" msgstr "неожиданный размер набора результатов при получении файлов с сервера" -#: libpq_source.c:525 +#: libpq_source.c:524 #, c-format msgid "" "unexpected data types in result set while fetching remote files: %u %u %u" @@ -433,72 +483,73 @@ msgstr "" "неожиданные типы данных в наборе результатов при получении файлов с сервера: " "%u %u %u" -#: libpq_source.c:533 +#: libpq_source.c:532 #, c-format msgid "unexpected result format while fetching remote files" msgstr "неожиданный формат результата при получении файлов с сервера" -#: libpq_source.c:539 +#: libpq_source.c:538 #, c-format msgid "unexpected null values in result while fetching remote files" msgstr "неожиданные значения NULL в результате при получении файлов с сервера" -#: libpq_source.c:543 +#: libpq_source.c:542 #, c-format msgid "unexpected result length while fetching remote files" msgstr "неожиданная длина результата при получении файлов с сервера" -#: libpq_source.c:576 +#: libpq_source.c:575 #, c-format msgid "received data for file \"%s\", when requested for \"%s\"" msgstr "получены данные для файла \"%s\", а запрашивались данные для \"%s\"" -#: libpq_source.c:580 +#: libpq_source.c:579 #, c-format msgid "" -"received data at offset %lld of file \"%s\", when requested for offset %lld" -msgstr "" -"получены данные по смещению %lld в файле \"%s\", а запрашивались по смещению " +"received data at offset % of file \"%s\", when requested for offset " "%lld" +msgstr "" +"получены данные по смещению % в файле \"%s\", а запрашивались по " +"смещению %lld" -#: libpq_source.c:592 +#: libpq_source.c:591 #, c-format msgid "received more than requested for file \"%s\"" msgstr "получено больше данных, чем запрошено для файла \"%s\"" -#: libpq_source.c:605 +#: libpq_source.c:604 #, c-format msgid "unexpected number of data chunks received" msgstr "получено неожиданное количество сегментов данных" -#: libpq_source.c:648 +#: libpq_source.c:647 #, c-format msgid "could not fetch remote file \"%s\": %s" msgstr "не удалось получить с сервера файл \"%s\": %s" -#: libpq_source.c:653 +#: libpq_source.c:652 #, c-format msgid "unexpected result set while fetching remote file \"%s\"" msgstr "неожиданный набор результатов при получении файла \"%s\" с сервера" -#: local_source.c:90 local_source.c:142 +#: local_source.c:88 local_source.c:140 #, c-format msgid "could not open source file \"%s\": %m" msgstr "не удалось открыть исходный файл \"%s\": %m" -#: local_source.c:117 +#: local_source.c:115 #, c-format msgid "" "size of source file \"%s\" changed concurrently: %d bytes expected, %d copied" msgstr "" "размер исходного файла \"%s\" изменился, ожидалось байт: %d, скопировано: %d" -#: local_source.c:146 +#: local_source.c:144 #, c-format msgid "could not seek in source file: %m" msgstr "не удалось переместиться в исходном файле: %m" -#: local_source.c:165 +#: local_source.c:163 #, c-format msgid "unexpected EOF while reading file \"%s\"" msgstr "неожиданный конец файла при чтении \"%s\"" @@ -742,11 +793,6 @@ msgstr "Запускать %s нужно от имени суперпользо msgid "could not read permissions of directory \"%s\": %m" msgstr "не удалось прочитать права на каталог \"%s\": %m" -#: pg_rewind.c:311 -#, c-format -msgid "%s" -msgstr "%s" - #: pg_rewind.c:314 #, c-format msgid "connected to server" @@ -767,74 +813,74 @@ msgstr "серверы разошлись в позиции WAL %X/%X на ли msgid "no rewind required" msgstr "перемотка не требуется" -#: pg_rewind.c:463 +#: pg_rewind.c:464 #, c-format msgid "rewinding from last common checkpoint at %X/%X on timeline %u" msgstr "" "перемотка от последней общей контрольной точки в позиции %X/%X на линии " "времени %u" -#: pg_rewind.c:473 +#: pg_rewind.c:474 #, c-format msgid "reading source file list" msgstr "чтение списка исходных файлов" -#: pg_rewind.c:477 +#: pg_rewind.c:478 #, c-format msgid "reading target file list" msgstr "чтение списка целевых файлов" -#: pg_rewind.c:486 +#: pg_rewind.c:487 #, c-format msgid "reading WAL in target" msgstr "чтение WAL в целевом кластере" -#: pg_rewind.c:507 +#: pg_rewind.c:508 #, c-format msgid "need to copy %lu MB (total source directory size is %lu MB)" msgstr "требуется скопировать %lu МБ (общий размер исходного каталога: %lu МБ)" -#: pg_rewind.c:525 +#: pg_rewind.c:526 #, c-format msgid "syncing target data directory" msgstr "синхронизация целевого каталога данных" -#: pg_rewind.c:541 +#: pg_rewind.c:543 #, c-format msgid "Done!" msgstr "Готово!" -#: pg_rewind.c:621 +#: pg_rewind.c:623 #, c-format msgid "no action decided for file \"%s\"" msgstr "действие не определено для файла \"%s\"" -#: pg_rewind.c:653 +#: pg_rewind.c:655 #, c-format msgid "source system was modified while pg_rewind was running" msgstr "в исходной системе произошли изменения в процессе работы pg_rewind" -#: pg_rewind.c:657 +#: pg_rewind.c:659 #, c-format msgid "creating backup label and updating control file" msgstr "создание метки копии и модификация управляющего файла" -#: pg_rewind.c:707 +#: pg_rewind.c:709 #, c-format msgid "source system was in unexpected state at end of rewind" msgstr "исходная система оказалась в неожиданном состоянии после перемотки" -#: pg_rewind.c:739 +#: pg_rewind.c:741 #, c-format msgid "source and target clusters are from different systems" msgstr "исходный и целевой кластеры относятся к разным системам" -#: pg_rewind.c:747 +#: pg_rewind.c:749 #, c-format msgid "clusters are not compatible with this version of pg_rewind" msgstr "кластеры несовместимы с этой версией pg_rewind" -#: pg_rewind.c:757 +#: pg_rewind.c:759 #, c-format msgid "" "target server needs to use either data checksums or \"wal_log_hints = on\"" @@ -842,44 +888,44 @@ msgstr "" "на целевом сервере должны быть контрольные суммы данных или \"wal_log_hints " "= on\"" -#: pg_rewind.c:768 +#: pg_rewind.c:770 #, c-format msgid "target server must be shut down cleanly" msgstr "целевой сервер должен быть выключен штатно" -#: pg_rewind.c:778 +#: pg_rewind.c:780 #, c-format msgid "source data directory must be shut down cleanly" msgstr "работа с исходным каталогом данных должна быть завершена штатно" -#: pg_rewind.c:825 +#: pg_rewind.c:827 #, c-format msgid "%*s/%s kB (%d%%) copied" msgstr "%*s/%s КБ (%d%%) скопировано" -#: pg_rewind.c:951 +#: pg_rewind.c:953 #, c-format msgid "" "could not find common ancestor of the source and target cluster's timelines" msgstr "" "не удалось найти общего предка линий времени исходного и целевого кластеров" -#: pg_rewind.c:992 +#: pg_rewind.c:994 #, c-format msgid "backup label buffer too small" msgstr "буфер для метки копии слишком мал" -#: pg_rewind.c:1015 +#: pg_rewind.c:1017 #, c-format msgid "unexpected control file CRC" msgstr "неверная контрольная сумма управляющего файла" -#: pg_rewind.c:1027 +#: pg_rewind.c:1029 #, c-format msgid "unexpected control file size %d, expected %d" -msgstr "неверный размер управляющего файла (%d), ожидалось: %d" +msgstr "неверный размер управляющего файла (%d), ожидался: %d" -#: pg_rewind.c:1037 +#: pg_rewind.c:1039 #, c-format msgid "invalid WAL segment size in control file (%d byte)" msgid_plural "invalid WAL segment size in control file (%d bytes)" @@ -887,50 +933,50 @@ msgstr[0] "управляющий файл содержит неверный р msgstr[1] "управляющий файл содержит неверный размер сегмента WAL (%d Б)" msgstr[2] "управляющий файл содержит неверный размер сегмента WAL (%d Б)" -#: pg_rewind.c:1041 +#: pg_rewind.c:1043 #, c-format msgid "The WAL segment size must be a power of two between 1 MB and 1 GB." msgstr "" "Размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 ГБ." -#: pg_rewind.c:1078 pg_rewind.c:1146 +#: pg_rewind.c:1080 pg_rewind.c:1148 #, c-format msgid "" "program \"%s\" is needed by %s but was not found in the same directory as " "\"%s\"" msgstr "программа \"%s\" нужна для %s, но она не найдена в каталоге \"%s\"" -#: pg_rewind.c:1081 pg_rewind.c:1149 +#: pg_rewind.c:1083 pg_rewind.c:1151 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "" "программа \"%s\" найдена программой \"%s\", но её версия отличается от " "версии %s" -#: pg_rewind.c:1110 +#: pg_rewind.c:1112 #, c-format -msgid "could not read restore_command from target cluster" +msgid "could not read \"restore_command\" from target cluster" msgstr "не удалось прочитать параметр \"restore_command\" в целевом кластере" -#: pg_rewind.c:1115 +#: pg_rewind.c:1117 #, c-format msgid "\"restore_command\" is not set in the target cluster" msgstr "параметр \"restore_command\" в целевом кластере не определён" -#: pg_rewind.c:1153 +#: pg_rewind.c:1155 #, c-format msgid "executing \"%s\" for target server to complete crash recovery" msgstr "" "выполнение \"%s\" для восстановления согласованности на целевом сервере" -#: pg_rewind.c:1191 +#: pg_rewind.c:1193 #, c-format msgid "postgres single-user mode in target cluster failed" msgstr "" "не удалось запустить postgres в целевом кластере в однопользовательском " "режиме" -#: pg_rewind.c:1192 +#: pg_rewind.c:1194 #, c-format msgid "Command was: %s" msgstr "Выполнялась команда: %s" @@ -971,72 +1017,72 @@ msgid "Timeline IDs must be less than child timeline's ID." msgstr "" "Идентификаторы линий времени должны быть меньше идентификатора линии-потомка." -#: xlogreader.c:619 +#: xlogreader.c:620 #, c-format msgid "invalid record offset at %X/%X: expected at least %u, got %u" msgstr "" "неверное смещение записи в позиции %X/%X: ожидалось минимум %u, получено %u" -#: xlogreader.c:628 +#: xlogreader.c:629 #, c-format msgid "contrecord is requested by %X/%X" msgstr "в позиции %X/%X запрошено продолжение записи" -#: xlogreader.c:669 xlogreader.c:1134 +#: xlogreader.c:670 xlogreader.c:1145 #, c-format msgid "invalid record length at %X/%X: expected at least %u, got %u" msgstr "" "неверная длина записи в позиции %X/%X: ожидалось минимум %u, получено %u" -#: xlogreader.c:758 +#: xlogreader.c:760 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "нет флага contrecord в позиции %X/%X" -#: xlogreader.c:771 +#: xlogreader.c:773 #, c-format msgid "invalid contrecord length %u (expected %lld) at %X/%X" msgstr "неверная длина contrecord: %u (ожидалась %lld) в позиции %X/%X" -#: xlogreader.c:1142 +#: xlogreader.c:1153 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "неверный ID менеджера ресурсов %u в позиции %X/%X" -#: xlogreader.c:1155 xlogreader.c:1171 +#: xlogreader.c:1166 xlogreader.c:1182 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "запись с неверной ссылкой назад %X/%X в позиции %X/%X" -#: xlogreader.c:1209 +#: xlogreader.c:1220 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "" "некорректная контрольная сумма данных менеджера ресурсов в записи в позиции " "%X/%X" -#: xlogreader.c:1243 +#: xlogreader.c:1254 #, c-format msgid "invalid magic number %04X in WAL segment %s, LSN %X/%X, offset %u" msgstr "" "неверное магическое число %04X в сегменте WAL %s, LSN %X/%X, смещение %u" -#: xlogreader.c:1258 xlogreader.c:1300 +#: xlogreader.c:1269 xlogreader.c:1311 #, c-format msgid "invalid info bits %04X in WAL segment %s, LSN %X/%X, offset %u" msgstr "" "неверные информационные биты %04X в сегменте WAL %s, LSN %X/%X, смещение %u" -#: xlogreader.c:1274 +#: xlogreader.c:1285 #, c-format msgid "" "WAL file is from different database system: WAL file database system " -"identifier is %llu, pg_control database system identifier is %llu" +"identifier is %, pg_control database system identifier is %" msgstr "" "файл WAL принадлежит другой СУБД: в нём указан идентификатор системы БД " -"%llu, а идентификатор системы pg_control: %llu" +"%, а идентификатор системы pg_control: %" -#: xlogreader.c:1282 +#: xlogreader.c:1293 #, c-format msgid "" "WAL file is from different database system: incorrect segment size in page " @@ -1045,7 +1091,7 @@ msgstr "" "файл WAL принадлежит другой СУБД: некорректный размер сегмента в заголовке " "страницы" -#: xlogreader.c:1288 +#: xlogreader.c:1299 #, c-format msgid "" "WAL file is from different database system: incorrect XLOG_BLCKSZ in page " @@ -1054,12 +1100,12 @@ msgstr "" "файл WAL принадлежит другой СУБД: некорректный XLOG_BLCKSZ в заголовке " "страницы" -#: xlogreader.c:1320 +#: xlogreader.c:1331 #, c-format msgid "unexpected pageaddr %X/%X in WAL segment %s, LSN %X/%X, offset %u" msgstr "неожиданный pageaddr %X/%X в сегменте WAL %s, LSN %X/%X, смещение %u" -#: xlogreader.c:1346 +#: xlogreader.c:1357 #, c-format msgid "" "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%X, " @@ -1068,23 +1114,23 @@ msgstr "" "нарушение последовательности ID линии времени %u (после %u) в сегменте WAL " "%s, LSN %X/%X, смещение %u" -#: xlogreader.c:1749 +#: xlogreader.c:1771 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "идентификатор блока %u идёт не по порядку в позиции %X/%X" -#: xlogreader.c:1773 +#: xlogreader.c:1795 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA установлен, но данных в позиции %X/%X нет" -#: xlogreader.c:1780 +#: xlogreader.c:1802 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "" "BKPBLOCK_HAS_DATA не установлен, но длина данных равна %u в позиции %X/%X" -#: xlogreader.c:1816 +#: xlogreader.c:1838 #, c-format msgid "" "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at " @@ -1093,21 +1139,21 @@ msgstr "" "BKPIMAGE_HAS_HOLE установлен, но для пропуска заданы смещение %u и длина %u " "при длине образа блока %u в позиции %X/%X" -#: xlogreader.c:1832 +#: xlogreader.c:1854 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "" "BKPIMAGE_HAS_HOLE не установлен, но для пропуска заданы смещение %u и длина " "%u в позиции %X/%X" -#: xlogreader.c:1846 +#: xlogreader.c:1868 #, c-format msgid "BKPIMAGE_COMPRESSED set, but block image length %u at %X/%X" msgstr "" "BKPIMAGE_COMPRESSED установлен, но длина образа блока равна %u в позиции %X/" "%X" -#: xlogreader.c:1861 +#: xlogreader.c:1883 #, c-format msgid "" "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image " @@ -1116,41 +1162,41 @@ msgstr "" "ни BKPIMAGE_HAS_HOLE, ни BKPIMAGE_COMPRESSED не установлены, но длина образа " "блока равна %u в позиции %X/%X" -#: xlogreader.c:1877 +#: xlogreader.c:1899 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "" "BKPBLOCK_SAME_REL установлен, но предыдущее значение не задано в позиции %X/" "%X" -#: xlogreader.c:1889 +#: xlogreader.c:1911 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "неверный идентификатор блока %u в позиции %X/%X" -#: xlogreader.c:1956 +#: xlogreader.c:1978 #, c-format msgid "record with invalid length at %X/%X" msgstr "запись с неверной длиной в позиции %X/%X" -#: xlogreader.c:1982 +#: xlogreader.c:2004 #, c-format msgid "could not locate backup block with ID %d in WAL record" msgstr "не удалось найти копию блока с ID %d в записи журнала WAL" -#: xlogreader.c:2066 +#: xlogreader.c:2088 #, c-format msgid "could not restore image at %X/%X with invalid block %d specified" msgstr "" "не удалось восстановить образ в позиции %X/%X с указанным неверным блоком %d" -#: xlogreader.c:2073 +#: xlogreader.c:2095 #, c-format msgid "could not restore image at %X/%X with invalid state, block %d" msgstr "" "не удалось восстановить образ в позиции %X/%X с неверным состоянием, блок %d" -#: xlogreader.c:2100 xlogreader.c:2117 +#: xlogreader.c:2122 xlogreader.c:2139 #, c-format msgid "" "could not restore image at %X/%X compressed with %s not supported by build, " @@ -1159,7 +1205,7 @@ msgstr "" "не удалось восстановить образ в позиции %X/%X, сжатый методом %s, который не " "поддерживается этой сборкой, блок %d" -#: xlogreader.c:2126 +#: xlogreader.c:2148 #, c-format msgid "" "could not restore image at %X/%X compressed with unknown method, block %d" @@ -1167,11 +1213,15 @@ msgstr "" "не удалось восстановить образ в позиции %X/%X, сжатый неизвестным методом, " "блок %d" -#: xlogreader.c:2134 +#: xlogreader.c:2156 #, c-format msgid "could not decompress image at %X/%X, block %d" msgstr "не удалось развернуть образ в позиции %X/%X, блок %d" +#, c-format +#~ msgid "could not stat file \"%s\" for reading: %m" +#~ msgstr "не удалось получить информацию о файле \"%s\" для чтения: %m" + #, c-format #~ msgid "out of memory while trying to decode a record of length %u" #~ msgstr "не удалось выделить память для декодирования записи длины %u" diff --git a/src/bin/pg_rewind/po/sv.po b/src/bin/pg_rewind/po/sv.po index 7894e029f20..11ac30a3b8a 100644 --- a/src/bin/pg_rewind/po/sv.po +++ b/src/bin/pg_rewind/po/sv.po @@ -1,14 +1,14 @@ # Swedish message translation file for pg_rewind # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Dennis Björklund , 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024. +# Dennis Björklund , 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026. # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 17\n" +"Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2024-08-27 15:53+0000\n" -"PO-Revision-Date: 2024-08-27 18:32+0200\n" +"POT-Creation-Date: 2026-08-08 19:55+0000\n" +"PO-Revision-Date: 2026-08-09 22:38+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -17,53 +17,53 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ../../../src/common/logging.c:276 +#: ../../../src/common/logging.c:293 ../../../src/common/logging.c:295 #, c-format msgid "error: " msgstr "fel: " -#: ../../../src/common/logging.c:283 +#: ../../../src/common/logging.c:302 ../../../src/common/logging.c:304 #, c-format msgid "warning: " msgstr "varning: " -#: ../../../src/common/logging.c:294 +#: ../../../src/common/logging.c:315 ../../../src/common/logging.c:317 #, c-format msgid "detail: " msgstr "detalj: " -#: ../../../src/common/logging.c:301 +#: ../../../src/common/logging.c:324 ../../../src/common/logging.c:326 #, c-format msgid "hint: " msgstr "tips: " -#: ../../common/controldata_utils.c:97 file_ops.c:326 file_ops.c:330 +#: ../../common/controldata_utils.c:98 file_ops.c:349 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "kunde inte öppna filen \"%s\" för läsning: %m" -#: ../../common/controldata_utils.c:110 file_ops.c:341 local_source.c:104 -#: local_source.c:163 parsexlog.c:350 +#: ../../common/controldata_utils.c:111 file_ops.c:364 local_source.c:102 +#: local_source.c:161 parsexlog.c:371 #, c-format msgid "could not read file \"%s\": %m" msgstr "kunde inte läsa fil \"%s\": %m" -#: ../../common/controldata_utils.c:119 file_ops.c:344 parsexlog.c:352 +#: ../../common/controldata_utils.c:120 file_ops.c:367 parsexlog.c:373 #, c-format msgid "could not read file \"%s\": read %d of %zu" msgstr "kunde inte läsa fil \"%s\": läste %d av %zu" -#: ../../common/controldata_utils.c:132 ../../common/controldata_utils.c:280 -#: local_source.c:121 local_source.c:172 +#: ../../common/controldata_utils.c:133 ../../common/controldata_utils.c:281 +#: local_source.c:119 local_source.c:170 #, c-format msgid "could not close file \"%s\": %m" msgstr "kunde inte stänga fil \"%s\": %m" -#: ../../common/controldata_utils.c:168 +#: ../../common/controldata_utils.c:169 msgid "byte ordering mismatch" msgstr "byte-ordning stämmer inte" -#: ../../common/controldata_utils.c:170 +#: ../../common/controldata_utils.c:171 #, c-format msgid "" "possible byte ordering mismatch\n" @@ -76,64 +76,74 @@ msgstr "" "inte detta program. I så fall kan nedanstående resultat vara felaktiga\n" "och PostgreSQL-installationen vara inkompatibel med databaskatalogen." -#: ../../common/controldata_utils.c:230 ../../common/file_utils.c:70 -#: ../../common/file_utils.c:347 ../../common/file_utils.c:406 -#: ../../common/file_utils.c:480 ../../fe_utils/recovery_gen.c:140 -#: parsexlog.c:312 +#: ../../common/controldata_utils.c:231 ../../common/file_utils.c:69 +#: ../../common/file_utils.c:370 ../../common/file_utils.c:428 +#: ../../common/file_utils.c:502 ../../fe_utils/recovery_gen.c:141 +#: parsexlog.c:333 #, c-format msgid "could not open file \"%s\": %m" msgstr "kunde inte öppna fil \"%s\": %m" -#: ../../common/controldata_utils.c:249 file_ops.c:117 +#: ../../common/controldata_utils.c:250 file_ops.c:120 #, c-format msgid "could not write file \"%s\": %m" msgstr "kunde inte skriva fil \"%s\": %m" -#: ../../common/controldata_utils.c:268 ../../common/file_utils.c:418 -#: ../../common/file_utils.c:488 +#: ../../common/controldata_utils.c:269 ../../common/file_utils.c:440 +#: ../../common/file_utils.c:510 #, c-format msgid "could not fsync file \"%s\": %m" msgstr "kunde inte fsync:a fil \"%s\": %m" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "slut på minne\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "kan inte duplicera null-pekare (internt fel)\n" -#: ../../common/file_utils.c:76 +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "ogiltig storlek %zu + %zu för minnesallokering\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "ogiltig storlek %zu * %zu för minnesallokering\n" + +#: ../../common/file_utils.c:75 #, c-format msgid "could not synchronize file system for file \"%s\": %m" msgstr "kan inte synkronisera filsystemet för fil \"%s\": %m" -#: ../../common/file_utils.c:120 ../../common/file_utils.c:566 -#: ../../fe_utils/archive.c:86 file_ops.c:417 +#: ../../common/file_utils.c:123 ../../common/file_utils.c:588 +#: ../../fe_utils/archive.c:86 file_ops.c:353 file_ops.c:440 #, c-format msgid "could not stat file \"%s\": %m" msgstr "kunde inte göra stat() på fil \"%s\": %m" -#: ../../common/file_utils.c:130 ../../common/file_utils.c:227 +#: ../../common/file_utils.c:133 ../../common/file_utils.c:243 #: ../../fe_utils/option_utils.c:99 #, c-format msgid "this build does not support sync method \"%s\"" msgstr "detta bygge stöder inte synkmetod \"%s\"" -#: ../../common/file_utils.c:151 ../../common/file_utils.c:281 file_ops.c:388 +#: ../../common/file_utils.c:156 ../../common/file_utils.c:304 file_ops.c:411 #, c-format msgid "could not open directory \"%s\": %m" msgstr "kunde inte öppna katalog \"%s\": %m" -#: ../../common/file_utils.c:169 ../../common/file_utils.c:315 file_ops.c:462 +#: ../../common/file_utils.c:174 ../../common/file_utils.c:338 file_ops.c:485 #, c-format msgid "could not read directory \"%s\": %m" msgstr "kunde inte läsa katalog \"%s\": %m" -#: ../../common/file_utils.c:498 +#: ../../common/file_utils.c:520 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "kunde inte döpa om fil \"%s\" till \"%s\": %m" @@ -218,317 +228,366 @@ msgstr "%s måste vara i intervallet %d..%d" msgid "unrecognized sync method: %s" msgstr "okänd synkmetod: %s" -#: ../../fe_utils/recovery_gen.c:39 ../../fe_utils/recovery_gen.c:50 -#: ../../fe_utils/recovery_gen.c:89 ../../fe_utils/recovery_gen.c:109 -#: ../../fe_utils/recovery_gen.c:168 +#: ../../fe_utils/option_utils.c:139 +#, c-format +msgid "options %s and %s cannot be used together" +msgstr "flaggorna %s och %s kan inte användas tillsammans" + +#: ../../fe_utils/recovery_gen.c:40 ../../fe_utils/recovery_gen.c:51 +#: ../../fe_utils/recovery_gen.c:90 ../../fe_utils/recovery_gen.c:110 +#: ../../fe_utils/recovery_gen.c:169 ../../fe_utils/recovery_gen.c:230 #, c-format msgid "out of memory" msgstr "slut på minne" -#: ../../fe_utils/recovery_gen.c:143 +#: ../../fe_utils/recovery_gen.c:144 #, c-format msgid "could not write to file \"%s\": %m" msgstr "kunde inte skriva till fil \"%s\": %m" -#: ../../fe_utils/recovery_gen.c:152 +#: ../../fe_utils/recovery_gen.c:153 #, c-format msgid "could not create file \"%s\": %m" msgstr "kunde inte skapa fil \"%s\": %m" -#: ../../fe_utils/string_utils.c:434 +#: ../../fe_utils/recovery_gen.c:215 pg_rewind.c:316 +#, c-format +msgid "%s" +msgstr "%s" + +#: ../../fe_utils/string_utils.c:585 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "shell-kommandots argument innehåller nyrad eller vagnretur: \"%s\"\n" -#: ../../fe_utils/string_utils.c:607 +#: ../../fe_utils/string_utils.c:758 #, c-format msgid "database name contains a newline or carriage return: \"%s\"\n" msgstr "databasnamnet innehåller nyrad eller vagnretur: \"%s\"\n" -#: file_ops.c:67 +#: file_ops.c:52 +#, c-format +msgid "target file path is unsafe for open: \"%s\"" +msgstr "sökvägen till fil är inte säker att öppna: \"%s\"" + +#: file_ops.c:70 #, c-format msgid "could not open target file \"%s\": %m" msgstr "kunde inte öppna målfil \"%s\": %m" -#: file_ops.c:81 +#: file_ops.c:84 #, c-format msgid "could not close target file \"%s\": %m" msgstr "kunde inte stänga målfil \"%s\": %m" -#: file_ops.c:101 +#: file_ops.c:104 #, c-format msgid "could not seek in target file \"%s\": %m" msgstr "kunde inte söka i målfil \"%s\": %m" -#: file_ops.c:150 file_ops.c:177 +#: file_ops.c:153 file_ops.c:180 #, c-format msgid "undefined file type for \"%s\"" msgstr "odefinierad filtyp på \"%s\"" -#: file_ops.c:173 +#: file_ops.c:176 #, c-format msgid "invalid action (CREATE) for regular file" msgstr "ogiltig aktion (CREATE) för vanlig fil" -#: file_ops.c:200 +#: file_ops.c:195 +#, c-format +msgid "target file path is unsafe for removal: \"%s\"" +msgstr "sökvägen till fil är inte säker för borttagning: \"%s\"" + +#: file_ops.c:206 #, c-format msgid "could not remove file \"%s\": %m" msgstr "kunde inte ta bort fil \"%s\": %m" #: file_ops.c:218 #, c-format +msgid "target file path is unsafe for truncation: \"%s\"" +msgstr "sökvägen till fil är inte säker för trunkering: \"%s\"" + +#: file_ops.c:227 +#, c-format msgid "could not open file \"%s\" for truncation: %m" msgstr "kunde inte öppna fil \"%s\" för trunkering: %m" -#: file_ops.c:222 +#: file_ops.c:231 #, c-format msgid "could not truncate file \"%s\" to %u: %m" msgstr "kunde inte trunkera fil \"%s\" till %u: %m" -#: file_ops.c:238 +#: file_ops.c:243 +#, c-format +msgid "target directory path is unsafe for directory creation: \"%s\"" +msgstr "sökvägen till katalog är inte säker att skapa: \"%s\"" + +#: file_ops.c:251 #, c-format msgid "could not create directory \"%s\": %m" msgstr "kunde inte skapa katalog \"%s\": %m" -#: file_ops.c:252 +#: file_ops.c:261 +#, c-format +msgid "target directory path is unsafe for directory removal: \"%s\"" +msgstr "sökvägen till katalog är inte säker att ta bort: \"%s\"" + +#: file_ops.c:269 #, c-format msgid "could not remove directory \"%s\": %m" msgstr "kunde inte ta bort katalog \"%s\": %m" -#: file_ops.c:266 +#: file_ops.c:279 +#, c-format +msgid "target symlink path is unsafe for creation: \"%s\"" +msgstr "sökvägen till symlänk är inte säker att skapa: \"%s\"" + +#: file_ops.c:286 #, c-format msgid "could not create symbolic link at \"%s\": %m" msgstr "kunde inte skapa en symnbolisk länk vid \"%s\": %m" -#: file_ops.c:280 +#: file_ops.c:296 +#, c-format +msgid "target symlink path is unsafe for removal: \"%s\"" +msgstr "sökvägen till symlänk är inte säker att ta bort: \"%s\"" + +#: file_ops.c:303 #, c-format msgid "could not remove symbolic link \"%s\": %m" msgstr "kan inte ta bort symbolisk länk \"%s\": %m" -#: file_ops.c:441 +#: file_ops.c:464 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "kan inte läsa symbolisk länk \"%s\": %m" -#: file_ops.c:444 +#: file_ops.c:467 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "mål för symbolisk länk \"%s\" är för lång" -#: file_ops.c:466 +#: file_ops.c:489 #, c-format msgid "could not close directory \"%s\": %m" msgstr "kunde inte stänga katalog \"%s\": %m" -#: filemap.c:235 +#: filemap.c:298 #, c-format msgid "data file \"%s\" in source is not a regular file" msgstr "datafil \"%s\" i källan är inte en vanlig fil" -#: filemap.c:240 filemap.c:273 +#: filemap.c:303 filemap.c:336 #, c-format msgid "duplicate source file \"%s\"" msgstr "duplicerad källflagga \"%s\"" -#: filemap.c:328 +#: filemap.c:391 #, c-format msgid "unexpected page modification for non-regular file \"%s\"" msgstr "oväntad sidmodifiering för icke-regulär fil \"%s\"" -#: filemap.c:682 filemap.c:776 +#: filemap.c:793 filemap.c:909 #, c-format msgid "unknown file type for \"%s\"" msgstr "okänd filtyp på \"%s\"" -#: filemap.c:709 +#: filemap.c:828 #, c-format msgid "file \"%s\" is of different type in source and target" msgstr "filen \"%s\" har olika typ i källa och mål" -#: filemap.c:781 +#: filemap.c:914 #, c-format msgid "could not decide what to do with file \"%s\"" msgstr "kunde inte bestämma vad som skulle göras med filen \"%s\"" -#: libpq_source.c:131 +#: libpq_source.c:130 #, c-format msgid "could not clear \"search_path\": %s" msgstr "kunde inte nollställa \"search_path\": %s" -#: libpq_source.c:142 +#: libpq_source.c:141 #, c-format msgid "\"full_page_writes\" must be enabled in the source server" msgstr "\"full_page_writes\" måste vara påslagen i källservern" -#: libpq_source.c:153 +#: libpq_source.c:152 #, c-format msgid "could not prepare statement to fetch file contents: %s" msgstr "kunde inte förbereda satsen för att hämta filinnehåll: %s" -#: libpq_source.c:172 +#: libpq_source.c:171 #, c-format msgid "error running query (%s) on source server: %s" msgstr "fel vid körande av fråga (%s) på källserver: %s" -#: libpq_source.c:177 +#: libpq_source.c:176 #, c-format msgid "unexpected result set from query" msgstr "oväntad resultatmängd från fråga" -#: libpq_source.c:199 +#: libpq_source.c:198 #, c-format msgid "error running query (%s) in source server: %s" msgstr "fel vid körande av fråga (%s) i källserver: %s" -#: libpq_source.c:220 +#: libpq_source.c:219 #, c-format msgid "unrecognized result \"%s\" for current WAL insert location" msgstr "oväntat resultat \"%s\" för nuvarande WAL-insättningsposition" -#: libpq_source.c:271 +#: libpq_source.c:270 #, c-format msgid "could not fetch file list: %s" msgstr "kunde inte hämta fillista: %s" -#: libpq_source.c:276 +#: libpq_source.c:275 #, c-format msgid "unexpected result set while fetching file list" msgstr "oväntad resultatmängd vid hämtning av fillista" -#: libpq_source.c:477 +#: libpq_source.c:476 #, c-format msgid "could not send query: %s" msgstr "kunde inte skicka fråga: %s" -#: libpq_source.c:480 +#: libpq_source.c:479 #, c-format msgid "could not set libpq connection to single row mode" msgstr "kunde inte sätta libpq-anslutning till enradsläge" -#: libpq_source.c:510 +#: libpq_source.c:509 #, c-format msgid "unexpected result while fetching remote files: %s" msgstr "oväntat resultat vid hämtning av extern fil: %s" -#: libpq_source.c:515 +#: libpq_source.c:514 #, c-format msgid "received more data chunks than requested" msgstr "tog emot fler datastycken än efterfrågat" -#: libpq_source.c:519 +#: libpq_source.c:518 #, c-format msgid "unexpected result set size while fetching remote files" msgstr "oväntad resultatmängdstorlek vid hämtning av externa filer" -#: libpq_source.c:525 +#: libpq_source.c:524 #, c-format msgid "unexpected data types in result set while fetching remote files: %u %u %u" msgstr "oväntade datayper i resultatmängd vid hämtning av externa filer: %u %u %u" -#: libpq_source.c:533 +#: libpq_source.c:532 #, c-format msgid "unexpected result format while fetching remote files" msgstr "oväntat resultatformat vid hämtning av externa filer" -#: libpq_source.c:539 +#: libpq_source.c:538 #, c-format msgid "unexpected null values in result while fetching remote files" msgstr "oväntade null-värden i resultat vid hämtning av externa filer" -#: libpq_source.c:543 +#: libpq_source.c:542 #, c-format msgid "unexpected result length while fetching remote files" msgstr "oväntad resultatlängd vid hämtning av externa filer" -#: libpq_source.c:576 +#: libpq_source.c:575 #, c-format msgid "received data for file \"%s\", when requested for \"%s\"" msgstr "fick data för filen \"%s\", men efterfrågade för \"%s\"" -#: libpq_source.c:580 +#: libpq_source.c:579 #, c-format -msgid "received data at offset %lld of file \"%s\", when requested for offset %lld" -msgstr "fick data från offset %lld i fil \"%s\", men efterfrågade offset %lld" +msgid "received data at offset % of file \"%s\", when requested for offset %lld" +msgstr "fick data från offset % i fil \"%s\", men efterfrågade offset %lld" -#: libpq_source.c:592 +#: libpq_source.c:591 #, c-format msgid "received more than requested for file \"%s\"" msgstr "tog emot mer än efterfrågat för filen \"%s\"" -#: libpq_source.c:605 +#: libpq_source.c:604 #, c-format msgid "unexpected number of data chunks received" msgstr "oväntat antal datastycken togs emot" -#: libpq_source.c:648 +#: libpq_source.c:647 #, c-format msgid "could not fetch remote file \"%s\": %s" msgstr "kunde inte hämta extern fil \"%s\": %s" -#: libpq_source.c:653 +#: libpq_source.c:652 #, c-format msgid "unexpected result set while fetching remote file \"%s\"" msgstr "oväntat resultatmängd vid hämtning av extern fil \"%s\"" -#: local_source.c:90 local_source.c:142 +#: local_source.c:88 local_source.c:140 #, c-format msgid "could not open source file \"%s\": %m" msgstr "kunde inte öppna källfil \"%s\": %m" -#: local_source.c:117 +#: local_source.c:115 #, c-format -msgid "size of source file \"%s\" changed concurrently: %d bytes expected, %d copied" -msgstr "storleken på källfilen \"%s\" ändrades under körning: %d byte förväntades, %d kopierades" +msgid "size of source file \"%s\" changed concurrently: %zu bytes expected, %zu copied" +msgstr "storleken på källfilen \"%s\" ändrades under körning: %zu byte förväntades, %zu kopierades" -#: local_source.c:146 +#: local_source.c:144 #, c-format msgid "could not seek in source file: %m" msgstr "kunde inte söka i källfil: %m" -#: local_source.c:165 +#: local_source.c:163 #, c-format msgid "unexpected EOF while reading file \"%s\"" msgstr "oväntad EOF under läsning av fil \"%s\"" -#: parsexlog.c:80 parsexlog.c:139 parsexlog.c:199 +#: parsexlog.c:80 parsexlog.c:139 parsexlog.c:201 #, c-format msgid "out of memory while allocating a WAL reading processor" msgstr "slut på minne vid allokering av en WAL-läs-processor" #: parsexlog.c:92 parsexlog.c:146 #, c-format -msgid "could not read WAL record at %X/%X: %s" -msgstr "kunde inte läsa WAL-post vid %X/%X: %s" +msgid "could not read WAL record at %X/%08X: %s" +msgstr "kunde inte läsa WAL-post vid %X/%08X: %s" #: parsexlog.c:96 parsexlog.c:149 #, c-format -msgid "could not read WAL record at %X/%X" -msgstr "kunde inte läsa WAL-post vid %X/%X" +msgid "could not read WAL record at %X/%08X" +msgstr "kunde inte läsa WAL-post vid %X/%08X" #: parsexlog.c:108 #, c-format -msgid "end pointer %X/%X is not a valid end point; expected %X/%X" -msgstr "slutpekare %X/%X är inte en giltig slutposition; förväntade %X/%X" +msgid "end pointer %X/%08X is not a valid end point; expected %X/%08X" +msgstr "slutpekare %X/%08X är inte en giltig slutposition; förväntade %X/%08X" -#: parsexlog.c:212 +#: parsexlog.c:214 #, c-format -msgid "could not find previous WAL record at %X/%X: %s" -msgstr "kunde inte hitta föregående WAL-post vid %X/%X: %s" +msgid "could not find previous WAL record at %X/%08X: %s" +msgstr "kunde inte hitta föregående WAL-post vid %X/%08X: %s" -#: parsexlog.c:216 +#: parsexlog.c:218 #, c-format -msgid "could not find previous WAL record at %X/%X" -msgstr "kunde inte hitta förgående WAL-post vid %X/%X" +msgid "could not find previous WAL record at %X/%08X" +msgstr "kunde inte hitta förgående WAL-post vid %X/%08X" -#: parsexlog.c:341 +#: parsexlog.c:362 #, c-format msgid "could not seek in file \"%s\": %m" msgstr "kunde inte söka (seek) i fil \"%s\": %m" -#: parsexlog.c:440 +#: parsexlog.c:461 #, c-format -msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmid: %d, rmgr: %s, info: %02X" -msgstr "WAL-post modifierar en relation, men posttypen känns inte igen: lsn: %X/%X, rmid: %d, rmgr: %s, info: %02X" +msgid "" +"WAL record modifies a relation, but record type is not recognized:\n" +"lsn: %X/%08X, rmid: %d, rmgr: %s, info: %02X" +msgstr "" +"WAL-post modifierar en relation, men posttypen känns inte igen:\n" +"lsn: %X/%08X, rmid: %d, rmgr: %s, info: %02X" #: pg_rewind.c:94 #, c-format @@ -655,225 +714,230 @@ msgstr "" msgid "%s home page: <%s>\n" msgstr "hemsida för %s: <%s>\n" -#: pg_rewind.c:232 pg_rewind.c:240 pg_rewind.c:247 pg_rewind.c:254 -#: pg_rewind.c:261 pg_rewind.c:269 +#: pg_rewind.c:233 pg_rewind.c:241 pg_rewind.c:248 pg_rewind.c:255 +#: pg_rewind.c:262 pg_rewind.c:270 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Försök med \"%s --help\" för mer information." -#: pg_rewind.c:239 +#: pg_rewind.c:240 #, c-format msgid "no source specified (--source-pgdata or --source-server)" msgstr "ingen källa angavs (--source-pgdata eller --source-server)" -#: pg_rewind.c:246 +#: pg_rewind.c:247 #, c-format msgid "only one of --source-pgdata or --source-server can be specified" msgstr "bara en av --source-pgdata och --source-server får anges" -#: pg_rewind.c:253 +#: pg_rewind.c:254 #, c-format msgid "no target data directory specified (--target-pgdata)" msgstr "ingen måldatakatalog angiven (--target-pgdata)" -#: pg_rewind.c:260 +#: pg_rewind.c:261 #, c-format msgid "no source server information (--source-server) specified for --write-recovery-conf" msgstr "ingen källserverinformation (--source-server) angiven för --write-recovery-conf" -#: pg_rewind.c:267 +#: pg_rewind.c:268 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "för många kommandoradsargument (första är \"%s\")" -#: pg_rewind.c:282 +#: pg_rewind.c:283 #, c-format msgid "cannot be executed by \"root\"" msgstr "kan inte köras av \"root\"" -#: pg_rewind.c:283 +#: pg_rewind.c:284 #, c-format msgid "You must run %s as the PostgreSQL superuser." msgstr "Du måste köra %s som PostgreSQL:s superuser." -#: pg_rewind.c:293 +#: pg_rewind.c:294 #, c-format msgid "could not read permissions of directory \"%s\": %m" msgstr "kunde inte läsa rättigheter på katalog \"%s\": %m" -#: pg_rewind.c:311 +#: pg_rewind.c:306 #, c-format -msgid "%s" -msgstr "%s" +msgid "executing in dry-run mode" +msgstr "kör i övningsläge" + +#: pg_rewind.c:307 +#, c-format +msgid "The target directory will not be modified." +msgstr "Målkatalogen kommer inte ändras." -#: pg_rewind.c:314 +#: pg_rewind.c:319 #, c-format msgid "connected to server" msgstr "ansluten till server" -#: pg_rewind.c:375 +#: pg_rewind.c:380 #, c-format msgid "source and target cluster are on the same timeline" msgstr "källa och målkluster är på samma tidslinje" -#: pg_rewind.c:396 +#: pg_rewind.c:401 #, c-format -msgid "servers diverged at WAL location %X/%X on timeline %u" -msgstr "servrarna divergerade vid WAL-position %X/%X på tidslinje %u" +msgid "servers diverged at WAL location %X/%08X on timeline %u" +msgstr "servrarna divergerade vid WAL-position %X/%08X på tidslinje %u" -#: pg_rewind.c:451 +#: pg_rewind.c:462 #, c-format msgid "no rewind required" msgstr "ingen rewind krävs" -#: pg_rewind.c:460 +#: pg_rewind.c:475 #, c-format -msgid "rewinding from last common checkpoint at %X/%X on timeline %u" -msgstr "rewind från senaste gemensamma checkpoint vid %X/%X på tidslinje %u" +msgid "rewinding from last common checkpoint at %X/%08X on timeline %u" +msgstr "rewind från senaste gemensamma checkpoint vid %X/%08X på tidslinje %u" -#: pg_rewind.c:470 +#: pg_rewind.c:485 #, c-format msgid "reading source file list" msgstr "läser källfillista" -#: pg_rewind.c:474 +#: pg_rewind.c:489 #, c-format msgid "reading target file list" msgstr "läser målfillista" -#: pg_rewind.c:483 +#: pg_rewind.c:498 #, c-format msgid "reading WAL in target" msgstr "läser WAL i målet" -#: pg_rewind.c:504 +#: pg_rewind.c:519 #, c-format -msgid "need to copy %lu MB (total source directory size is %lu MB)" -msgstr "behöver kopiera %lu MB (total källkatalogstorlek är %lu MB)" +msgid "need to copy % MB (total source directory size is % MB)" +msgstr "behöver kopiera % MB (total källkatalogstorlek är % MB)" -#: pg_rewind.c:522 +#: pg_rewind.c:537 #, c-format msgid "syncing target data directory" msgstr "synkar måldatakatalog" -#: pg_rewind.c:538 +#: pg_rewind.c:554 #, c-format msgid "Done!" msgstr "Klar!" -#: pg_rewind.c:618 +#: pg_rewind.c:634 #, c-format msgid "no action decided for file \"%s\"" msgstr "ingen åtgärd beslutades för filen \"%s\"" -#: pg_rewind.c:650 +#: pg_rewind.c:666 #, c-format msgid "source system was modified while pg_rewind was running" msgstr "källsystemet ändrades samtidigt som pg_rewind kördes" -#: pg_rewind.c:654 +#: pg_rewind.c:670 #, c-format msgid "creating backup label and updating control file" msgstr "skapar backupetikett och uppdaterar kontrollfil" -#: pg_rewind.c:704 +#: pg_rewind.c:720 #, c-format msgid "source system was in unexpected state at end of rewind" msgstr "källsystemet var i ett oväntat tillstånd vid slutet av återspolningen" -#: pg_rewind.c:736 +#: pg_rewind.c:752 #, c-format msgid "source and target clusters are from different systems" msgstr "källa och målkluster är från olika system" -#: pg_rewind.c:744 +#: pg_rewind.c:760 #, c-format msgid "clusters are not compatible with this version of pg_rewind" msgstr "klustren är inte kompatibla med denna version av pg_rewind" -#: pg_rewind.c:754 +#: pg_rewind.c:770 #, c-format msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" msgstr "målservern behöver använda antingen datachecksums eller \"wal_log_hints = on\"" -#: pg_rewind.c:765 +#: pg_rewind.c:781 #, c-format msgid "target server must be shut down cleanly" msgstr "målserver måste stängas ner utan fel" -#: pg_rewind.c:775 +#: pg_rewind.c:791 #, c-format msgid "source data directory must be shut down cleanly" msgstr "måldatakatalog måste stängas ner utan fel" -#: pg_rewind.c:822 +#: pg_rewind.c:838 #, c-format msgid "%*s/%s kB (%d%%) copied" msgstr "%*s/%s kB (%d%%) kopierad" -#: pg_rewind.c:948 +#: pg_rewind.c:964 #, c-format msgid "could not find common ancestor of the source and target cluster's timelines" msgstr "kunde inte finna en gemensam anfader av källa och målklusterets tidslinjer" -#: pg_rewind.c:989 +#: pg_rewind.c:1005 #, c-format msgid "backup label buffer too small" msgstr "backupetikett-buffer för liten" -#: pg_rewind.c:1012 +#: pg_rewind.c:1028 #, c-format msgid "unexpected control file CRC" msgstr "oväntad kontrollfil-CRC" -#: pg_rewind.c:1024 +#: pg_rewind.c:1040 #, c-format -msgid "unexpected control file size %d, expected %d" -msgstr "oväntad kontrollfilstorlek %d, förväntade %d" +msgid "unexpected control file size %zu, expected %d" +msgstr "oväntad kontrollfilstorlek %zu, förväntade %d" -#: pg_rewind.c:1034 +#: pg_rewind.c:1050 #, c-format msgid "invalid WAL segment size in control file (%d byte)" msgid_plural "invalid WAL segment size in control file (%d bytes)" msgstr[0] "ogiltigt WAL-segmentstorlek i kontrollfil (%d byte)" msgstr[1] "ogiltigt WAL-segmentstorlek i kontrollfil (%d byte)" -#: pg_rewind.c:1038 +#: pg_rewind.c:1054 #, c-format msgid "The WAL segment size must be a power of two between 1 MB and 1 GB." msgstr "WAL-segmentstorleken måste vara en tvåpotens mellan 1 MB och 1 GB." -#: pg_rewind.c:1075 pg_rewind.c:1143 +#: pg_rewind.c:1091 pg_rewind.c:1159 #, c-format msgid "program \"%s\" is needed by %s but was not found in the same directory as \"%s\"" msgstr "programmet \"%s\" behövs av %s men hittades inte i samma katalog som \"%s\"" -#: pg_rewind.c:1078 pg_rewind.c:1146 +#: pg_rewind.c:1094 pg_rewind.c:1162 #, c-format msgid "program \"%s\" was found by \"%s\" but was not the same version as %s" msgstr "programmet \"%s\" hittades av \"%s\" men är inte av samma version som %s" -#: pg_rewind.c:1107 +#: pg_rewind.c:1123 #, c-format -msgid "could not read restore_command from target cluster" -msgstr "kunde inte läsa restore_command från målklustret" +msgid "could not read \"restore_command\" from target cluster" +msgstr "kunde inte läsa \"restore_command\" från målklustret" -#: pg_rewind.c:1112 +#: pg_rewind.c:1128 #, c-format msgid "\"restore_command\" is not set in the target cluster" msgstr "\"restore_command\" är inte satt i målklustret" -#: pg_rewind.c:1150 +#: pg_rewind.c:1166 #, c-format msgid "executing \"%s\" for target server to complete crash recovery" msgstr "kör \"%s\" för målservern för att slutföra krashåterställning" -#: pg_rewind.c:1188 +#: pg_rewind.c:1204 #, c-format msgid "postgres single-user mode in target cluster failed" msgstr "postgres enanvändarläge misslyckades i målklustret" -#: pg_rewind.c:1189 +#: pg_rewind.c:1205 #, c-format msgid "Command was: %s" msgstr "Kommandot var: %s" @@ -913,157 +977,157 @@ msgstr "ogiltig data i historikfil" msgid "Timeline IDs must be less than child timeline's ID." msgstr "Tidslinje-ID:er måste vara mindre än barnens tidslinje-ID:er." -#: xlogreader.c:619 +#: xlogreader.c:621 #, c-format -msgid "invalid record offset at %X/%X: expected at least %u, got %u" -msgstr "ogiltig postlängd vid %X/%X: förväntade minst %u, fick %u" +msgid "invalid record offset at %X/%08X: expected at least %u, got %u" +msgstr "ogiltig postlängd vid %X/%08X: förväntade minst %u, fick %u" -#: xlogreader.c:628 +#: xlogreader.c:630 #, c-format -msgid "contrecord is requested by %X/%X" -msgstr "contrecord är begärd vid %X/%X" +msgid "contrecord is requested by %X/%08X" +msgstr "contrecord är begärd vid %X/%08X" -#: xlogreader.c:669 xlogreader.c:1134 +#: xlogreader.c:671 xlogreader.c:1146 #, c-format -msgid "invalid record length at %X/%X: expected at least %u, got %u" -msgstr "ogiltig postlängd vid %X/%X: förväntade minst %u, fick %u" +msgid "invalid record length at %X/%08X: expected at least %u, got %u" +msgstr "ogiltig postlängd vid %X/%08X: förväntade minst %u, fick %u" -#: xlogreader.c:758 +#: xlogreader.c:761 #, c-format -msgid "there is no contrecord flag at %X/%X" -msgstr "det finns ingen contrecord-flagga vid %X/%X" +msgid "there is no contrecord flag at %X/%08X" +msgstr "det finns ingen contrecord-flagga vid %X/%08X" -#: xlogreader.c:771 +#: xlogreader.c:774 #, c-format -msgid "invalid contrecord length %u (expected %lld) at %X/%X" -msgstr "ogiltig contrecord-längd %u (förväntade %lld) vid %X/%X" +msgid "invalid contrecord length %u (expected %lld) at %X/%08X" +msgstr "ogiltig contrecord-längd %u (förväntade %lld) vid %X/%08X" -#: xlogreader.c:1142 +#: xlogreader.c:1154 #, c-format -msgid "invalid resource manager ID %u at %X/%X" -msgstr "ogiltigt resurshanterar-ID %u vid %X/%X" +msgid "invalid resource manager ID %u at %X/%08X" +msgstr "ogiltigt resurshanterar-ID %u vid %X/%08X" -#: xlogreader.c:1155 xlogreader.c:1171 +#: xlogreader.c:1167 xlogreader.c:1183 #, c-format -msgid "record with incorrect prev-link %X/%X at %X/%X" -msgstr "post med inkorrekt prev-link %X/%X vid %X/%X" +msgid "record with incorrect prev-link %X/%08X at %X/%08X" +msgstr "post med inkorrekt prev-link %X/%08X vid %X/%08X" -#: xlogreader.c:1209 +#: xlogreader.c:1221 #, c-format -msgid "incorrect resource manager data checksum in record at %X/%X" -msgstr "felaktig resurshanterardatakontrollsumma i post vid %X/%X" +msgid "incorrect resource manager data checksum in record at %X/%08X" +msgstr "felaktig resurshanterardatakontrollsumma i post vid %X/%08X" -#: xlogreader.c:1243 +#: xlogreader.c:1255 #, c-format -msgid "invalid magic number %04X in WAL segment %s, LSN %X/%X, offset %u" -msgstr "felaktigt magiskt nummer %04X i WAL-segment %s, LSN %X/%X, offset %u" +msgid "invalid magic number %04X in WAL segment %s, LSN %X/%08X, offset %u" +msgstr "felaktigt magiskt nummer %04X i WAL-segment %s, LSN %X/%08X, offset %u" -#: xlogreader.c:1258 xlogreader.c:1300 +#: xlogreader.c:1270 xlogreader.c:1312 #, c-format -msgid "invalid info bits %04X in WAL segment %s, LSN %X/%X, offset %u" -msgstr "ogiltiga infobitar %04X i WAL-segment %s, LSN %X/%X, offset %u" +msgid "invalid info bits %04X in WAL segment %s, LSN %X/%08X, offset %u" +msgstr "ogiltiga infobitar %04X i WAL-segment %s, LSN %X/%08X, offset %u" -#: xlogreader.c:1274 +#: xlogreader.c:1286 #, c-format -msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" -msgstr "WAL-fil är från ett annat databassystem: WAL-filens databassystemidentifierare är %llu, pg_control databassystemidentifierare är %llu" +msgid "WAL file is from different database system: WAL file database system identifier is %, pg_control database system identifier is %" +msgstr "WAL-fil är från ett annat databassystem: WAL-filens databassystemidentifierare är %, pg_control databassystemidentifierare är %" -#: xlogreader.c:1282 +#: xlogreader.c:1294 #, c-format msgid "WAL file is from different database system: incorrect segment size in page header" msgstr "WAL-fil är från ett annat databassystem: inkorrekt segmentstorlek i sidhuvud" -#: xlogreader.c:1288 +#: xlogreader.c:1300 #, c-format msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" msgstr "WAL-fil är från ett annat databassystem: inkorrekt XLOG_BLCKSZ i sidhuvud" -#: xlogreader.c:1320 +#: xlogreader.c:1332 #, c-format -msgid "unexpected pageaddr %X/%X in WAL segment %s, LSN %X/%X, offset %u" -msgstr "oväntad sidadress %X/%X i WAL-segment %s, LSN %X/%X, offset %u" +msgid "unexpected pageaddr %X/%08X in WAL segment %s, LSN %X/%08X, offset %u" +msgstr "oväntad sidadress %X/%08X i WAL-segment %s, LSN %X/%08X, offset %u" -#: xlogreader.c:1346 +#: xlogreader.c:1358 #, c-format -msgid "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%X, offset %u" -msgstr "ej-i-sekvens för tidslinje-ID %u (efter %u) i WAL-segment %s, LSN %X/%X, offset %u" +msgid "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%08X, offset %u" +msgstr "ej-i-sekvens för tidslinje-ID %u (efter %u) i WAL-segment %s, LSN %X/%08X, offset %u" -#: xlogreader.c:1749 +#: xlogreader.c:1790 #, c-format -msgid "out-of-order block_id %u at %X/%X" -msgstr "ej-i-sekvens block_id %u vid %X/%X" +msgid "out-of-order block_id %u at %X/%08X" +msgstr "ej-i-sekvens block_id %u vid %X/%08X" -#: xlogreader.c:1773 +#: xlogreader.c:1814 #, c-format -msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" -msgstr "BKPBLOCK_HAS_DATA är satt men ingen data inkluderad vid %X/%X" +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%08X" +msgstr "BKPBLOCK_HAS_DATA är satt men ingen data inkluderad vid %X/%08X" -#: xlogreader.c:1780 +#: xlogreader.c:1821 #, c-format -msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" -msgstr "BKPBLOCK_HAS_DATA är ej satt men datalängden är %u vid %X/%X" +msgid "BKPBLOCK_HAS_DATA not set, but data length is %d at %X/%08X" +msgstr "BKPBLOCK_HAS_DATA är ej satt men datalängden är %d vid %X/%08X" -#: xlogreader.c:1816 +#: xlogreader.c:1857 #, c-format -msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" -msgstr "BKPIMAGE_HAS_HOLE är satt men håloffset %u längd %u blockavbildlängd %u vid %X/%X" +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %d length %d block image length %d at %X/%08X" +msgstr "BKPIMAGE_HAS_HOLE är satt men håloffset %d längd %d blockavbildlängd %d vid %X/%08X" -#: xlogreader.c:1832 +#: xlogreader.c:1873 #, c-format -msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" -msgstr "BKPIMAGE_HAS_HOLE är inte satt men håloffset %u längd %u vid %X/%X" +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %d length %d at %X/%08X" +msgstr "BKPIMAGE_HAS_HOLE är inte satt men håloffset %d längd %d vid %X/%08X" -#: xlogreader.c:1846 +#: xlogreader.c:1887 #, c-format -msgid "BKPIMAGE_COMPRESSED set, but block image length %u at %X/%X" -msgstr "BKPIMAGE_COMPRESSED är satt men blockavbildlängd %u vid %X/%X" +msgid "BKPIMAGE_COMPRESSED set, but block image length %d at %X/%08X" +msgstr "BKPIMAGE_COMPRESSED är satt men blockavbildlängd %d vid %X/%08X" -#: xlogreader.c:1861 +#: xlogreader.c:1902 #, c-format -msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image length is %u at %X/%X" -msgstr "varken BKPIMAGE_HAS_HOLE eller BKPIMAGE_COMPRESSED är satt men blockavbildlängd är %u vid %X/%X" +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image length is %d at %X/%08X" +msgstr "varken BKPIMAGE_HAS_HOLE eller BKPIMAGE_COMPRESSED är satt men blockavbildlängd är %d vid %X/%08X" -#: xlogreader.c:1877 +#: xlogreader.c:1918 #, c-format -msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" -msgstr "BKPBLOCK_SAME_REL är satt men ingen tidigare rel vid %X/%X" +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%08X" +msgstr "BKPBLOCK_SAME_REL är satt men ingen tidigare rel vid %X/%08X" -#: xlogreader.c:1889 +#: xlogreader.c:1930 #, c-format -msgid "invalid block_id %u at %X/%X" -msgstr "ogiltig block_id %u vid %X/%X" +msgid "invalid block_id %u at %X/%08X" +msgstr "ogiltig block_id %u vid %X/%08X" -#: xlogreader.c:1956 +#: xlogreader.c:1997 #, c-format -msgid "record with invalid length at %X/%X" -msgstr "post med ogiltig längd vid %X/%X" +msgid "record with invalid length at %X/%08X" +msgstr "post med ogiltig längd vid %X/%08X" -#: xlogreader.c:1982 +#: xlogreader.c:2023 #, c-format msgid "could not locate backup block with ID %d in WAL record" msgstr "kunde inte hitta backup-block med ID %d i WAL-post" -#: xlogreader.c:2066 +#: xlogreader.c:2107 #, c-format -msgid "could not restore image at %X/%X with invalid block %d specified" -msgstr "kunde inte återställa avbild vid %X/%X med ogiltigt block %d angivet" +msgid "could not restore image at %X/%08X with invalid block %d specified" +msgstr "kunde inte återställa avbild vid %X/%08X med ogiltigt block %d angivet" -#: xlogreader.c:2073 +#: xlogreader.c:2114 #, c-format -msgid "could not restore image at %X/%X with invalid state, block %d" -msgstr "kunde inte återställa avbild vid %X/%X med ogiltigt state, block %d" +msgid "could not restore image at %X/%08X with invalid state, block %d" +msgstr "kunde inte återställa avbild vid %X/%08X med ogiltigt state, block %d" -#: xlogreader.c:2100 xlogreader.c:2117 +#: xlogreader.c:2141 xlogreader.c:2158 #, c-format -msgid "could not restore image at %X/%X compressed with %s not supported by build, block %d" -msgstr "kunde inte återställa avbild vid %X/%X, komprimerad med %s stöds inte av bygget, block %d" +msgid "could not restore image at %X/%08X compressed with %s not supported by build, block %d" +msgstr "kunde inte återställa avbild vid %X/%08X, komprimerad med %s stöds inte av bygget, block %d" -#: xlogreader.c:2126 +#: xlogreader.c:2167 #, c-format -msgid "could not restore image at %X/%X compressed with unknown method, block %d" -msgstr "kunde inte återställa avbild vid %X/%X, komprimerad med okänd metod, block %d" +msgid "could not restore image at %X/%08X compressed with unknown method, block %d" +msgstr "kunde inte återställa avbild vid %X/%08X, komprimerad med okänd metod, block %d" -#: xlogreader.c:2134 +#: xlogreader.c:2175 #, c-format -msgid "could not decompress image at %X/%X, block %d" -msgstr "kunde inte packa upp avbild vid %X/%X, block %d" +msgid "could not decompress image at %X/%08X, block %d" +msgstr "kunde inte packa upp avbild vid %X/%08X, block %d" diff --git a/src/bin/pg_test_fsync/po/ru.po b/src/bin/pg_test_fsync/po/ru.po index 715a63f3e9c..6fc41103694 100644 --- a/src/bin/pg_test_fsync/po/ru.po +++ b/src/bin/pg_test_fsync/po/ru.po @@ -1,13 +1,13 @@ # Russian message translation file for pg_test_fsync # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Alexander Lakhin , 2017, 2021, 2022, 2024. +# SPDX-FileCopyrightText: 2017, 2021, 2022, 2024, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: pg_test_fsync (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" -"PO-Revision-Date: 2024-09-04 18:11+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:50+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -37,17 +37,27 @@ msgstr "подробности: " msgid "hint: " msgstr "подсказка: " -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #. translator: maintain alignment with NA_FORMAT #: pg_test_fsync.c:37 #, c-format diff --git a/src/bin/pg_test_timing/po/de.po b/src/bin/pg_test_timing/po/de.po index 389ca9b1075..ea5be62c78c 100644 --- a/src/bin/pg_test_timing/po/de.po +++ b/src/bin/pg_test_timing/po/de.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: pg_test_timing (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" "POT-Creation-Date: 2026-07-04 06:24+0000\n" -"PO-Revision-Date: 2026-07-04 13:00+0200\n" +"PO-Revision-Date: 2026-08-04 14:02+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -108,7 +108,7 @@ msgstr "" #: pg_test_timing.c:230 #, c-format msgid "TSC calibration did not converge\n" -msgstr "TSC-Kalibrierung konvergierte nicht.\n" +msgstr "TSC-Kalibrierung konvergierte nicht\n" #: pg_test_timing.c:240 #, c-format diff --git a/src/bin/pg_upgrade/po/de.po b/src/bin/pg_upgrade/po/de.po index 2b11885a3f6..afefbf6ab7e 100644 --- a/src/bin/pg_upgrade/po/de.po +++ b/src/bin/pg_upgrade/po/de.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_upgrade (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-07-04 06:24+0000\n" -"PO-Revision-Date: 2026-07-04 13:01+0200\n" +"POT-Creation-Date: 2026-08-04 09:54+0000\n" +"PO-Revision-Date: 2026-08-04 12:14+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -671,7 +671,7 @@ msgstr "Prüfe auf Verwendung von gist_inet_ops/gist_cidr_ops" #: check.c:1862 #, c-format msgid "" -"Your installation contains indexes that use btree_gist extension's\n" +"Your installation contains indexes that use the btree_gist extension's\n" "gist_inet_ops or gist_cidr_ops operator classes, which cannot be\n" "binary-upgraded. Replace them with indexes that use the built-in GiST\n" "inet_ops operator class.\n" @@ -1101,8 +1101,8 @@ msgstr "alte und neue Speicherung von Datums- und Zeittypen von pg_controldata i #: controldata.c:746 #, c-format -msgid "checksums are being enabled in the old cluster" -msgstr "Prüfsummen werden gerade im alten Cluster aktiviert" +msgid "data checksums are being enabled in the old cluster" +msgstr "Datenprüfsummen werden gerade im alten Cluster aktiviert" #: controldata.c:754 #, c-format diff --git a/src/bin/pg_upgrade/po/ka.po b/src/bin/pg_upgrade/po/ka.po index ee558921a97..1a221f8554b 100644 --- a/src/bin/pg_upgrade/po/ka.po +++ b/src/bin/pg_upgrade/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_upgrade (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-06-30 04:23+0000\n" -"PO-Revision-Date: 2026-07-02 06:15+0200\n" +"POT-Creation-Date: 2026-07-25 01:54+0000\n" +"PO-Revision-Date: 2026-07-25 04:34+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -657,17 +657,17 @@ msgstr "gist_inet_ops/gist_cidr_ops-ის გამოყენების შ #: check.c:1862 #, c-format msgid "" -"Your installation contains indexes that use btree_gist extension's\n" +"Your installation contains indexes that use the btree_gist extension's\n" "gist_inet_ops or gist_cidr_ops operator classes, which cannot be\n" "binary-upgraded. Replace them with indexes that use the built-in GiST\n" "inet_ops operator class.\n" "A list of indexes with the problem is in the file:\n" " %s" msgstr "" -"თქვენი დაყენებული ვერსია შეიცავს ინდექსებს, რომლებიც იყენებენ btree_gist-ის\n" -"gist_inet_ops, ან git_cidr_ops ოპერატორის კლასებს,\n" +"თქვენი დაყენებული ვერსია შეიცავს ინდექსებს, რომლებიც იყენებენ გაფართოების btree_gist\n" +"ოპერატორის კლასებს gist_inet_ops, ან git_cidr_ops ,\n" "რომლების ბინარული განახლებაც შეუძლებელია. ჩაანაცვლეთ ისინი ინდექსებით, რომლებიც\n" -"იყენებენ ჩაშენებულ GiST inet_ops ოპკლასს.\n" +"იყენებენ ჩაშენებულ GiST inet_ops ოპერატორის კლასს.\n" "პრობლემის შემცველი ინდექსების ჩამონათვალი შეგიძლიათ იპოვოთ ფაილში:\n" " %s" @@ -1079,7 +1079,7 @@ msgstr "ძველი და ახალი pg_controldata-ის თარ #: controldata.c:746 #, c-format -msgid "checksums are being enabled in the old cluster" +msgid "data checksums are being enabled in the old cluster" msgstr "ხდება საკონტროლო ჯამების ჩართვა ძველ კლასტერში" #: controldata.c:754 diff --git a/src/bin/pg_upgrade/po/ru.po b/src/bin/pg_upgrade/po/ru.po index b4341f9cd6a..5399f8b0428 100644 --- a/src/bin/pg_upgrade/po/ru.po +++ b/src/bin/pg_upgrade/po/ru.po @@ -1,14 +1,14 @@ # Russian message translation file for pg_upgrade # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# SPDX-FileCopyrightText: 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025 Alexander Lakhin +# SPDX-FileCopyrightText: 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026 Alexander Lakhin # Maxim Yablokov , 2021. msgid "" msgstr "" "Project-Id-Version: pg_upgrade (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-10 08:01+0300\n" -"PO-Revision-Date: 2025-09-13 22:22+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:50+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -18,17 +18,27 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/restricted_token.c:168 #, c-format msgid "could not get exit code from subprocess: error code %lu" diff --git a/src/bin/pg_verifybackup/po/ru.po b/src/bin/pg_verifybackup/po/ru.po index 513e9dbb4b0..a7318be2688 100644 --- a/src/bin/pg_verifybackup/po/ru.po +++ b/src/bin/pg_verifybackup/po/ru.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_verifybackup (PostgreSQL) 13\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-05-10 08:01+0300\n" -"PO-Revision-Date: 2026-05-10 08:33+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:51+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -111,17 +111,27 @@ msgstr "буфер назначения слишком мал" msgid "OpenSSL failure" msgstr "ошибка OpenSSL" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/jsonapi.c:2484 msgid "Recursive descent parser cannot use incremental lexer." msgstr "" @@ -479,12 +489,17 @@ msgstr "входной файл не похож на архив tar" msgid "tar member has empty name" msgstr "пустое имя у компонента tar" -#: ../../fe_utils/astreamer_tar.c:328 +#: ../../fe_utils/astreamer_tar.c:309 +#, c-format +msgid "tar member has unsafe path name: \"%s\"" +msgstr "компонент tar имеет небезопасный путь: \"%s\"" + +#: ../../fe_utils/astreamer_tar.c:332 #, c-format msgid "pax extensions to tar format are not supported" msgstr "расширения PAX для формата tar не поддерживаются" -#: ../../fe_utils/astreamer_tar.c:357 +#: ../../fe_utils/astreamer_tar.c:361 #, c-format msgid "COPY stream ended before last file was finished" msgstr "поток COPY закончился до завершения последнего файла" diff --git a/src/bin/pg_waldump/po/sv.po b/src/bin/pg_waldump/po/sv.po index 24173636e1a..6ce6fa6ae99 100644 --- a/src/bin/pg_waldump/po/sv.po +++ b/src/bin/pg_waldump/po/sv.po @@ -1,14 +1,14 @@ # Swedish message translation file for pg_waldump # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Dennis Björklund , 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024. +# Dennis Björklund , 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026. # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 17\n" +"Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2024-07-12 14:19+0000\n" -"PO-Revision-Date: 2024-07-12 19:11+0200\n" +"POT-Creation-Date: 2026-08-08 19:51+0000\n" +"PO-Revision-Date: 2026-08-09 22:54+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -17,180 +17,254 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../../../src/common/logging.c:276 +#: ../../../src/common/logging.c:293 ../../../src/common/logging.c:295 #, c-format msgid "error: " msgstr "fel: " -#: ../../../src/common/logging.c:283 +#: ../../../src/common/logging.c:302 ../../../src/common/logging.c:304 #, c-format msgid "warning: " msgstr "varning: " -#: ../../../src/common/logging.c:294 +#: ../../../src/common/logging.c:315 ../../../src/common/logging.c:317 #, c-format msgid "detail: " msgstr "detalj: " -#: ../../../src/common/logging.c:301 +#: ../../../src/common/logging.c:324 ../../../src/common/logging.c:326 #, c-format msgid "hint: " msgstr "tips: " -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "slut på minne\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "kan inte duplicera null-pekare (internt fel)\n" -#: ../../common/file_utils.c:70 ../../common/file_utils.c:347 -#: ../../common/file_utils.c:406 ../../common/file_utils.c:480 pg_waldump.c:199 -#: pg_waldump.c:532 +#: ../../common/fe_memutils.c:209 +#, fuzzy, c-format +#| msgid "invalid large object write request size: %d" +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "ogiltig storlek för stort objects skrivningbegäran: %d" + +#: ../../common/fe_memutils.c:228 +#, fuzzy, c-format +#| msgid "invalid large object write request size: %d" +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "ogiltig storlek för stort objects skrivningbegäran: %d" + +#: ../../common/file_utils.c:69 ../../common/file_utils.c:370 +#: ../../common/file_utils.c:428 ../../common/file_utils.c:502 pg_waldump.c:193 +#: pg_waldump.c:648 #, c-format msgid "could not open file \"%s\": %m" msgstr "kunde inte öppna fil \"%s\": %m" -#: ../../common/file_utils.c:76 +#: ../../common/file_utils.c:75 #, c-format msgid "could not synchronize file system for file \"%s\": %m" msgstr "kan inte synkronisera filsystemet för fil \"%s\": %m" -#: ../../common/file_utils.c:120 ../../common/file_utils.c:566 +#: ../../common/file_utils.c:123 ../../common/file_utils.c:588 #, c-format msgid "could not stat file \"%s\": %m" msgstr "kunde inte göra stat() på fil \"%s\": %m" -#: ../../common/file_utils.c:130 ../../common/file_utils.c:227 +#: ../../common/file_utils.c:133 ../../common/file_utils.c:243 #, c-format msgid "this build does not support sync method \"%s\"" msgstr "detta bygge stöder inte synkmetod \"%s\"" -#: ../../common/file_utils.c:151 ../../common/file_utils.c:281 -#: pg_waldump.c:1104 pg_waldump.c:1127 +#: ../../common/file_utils.c:156 ../../common/file_utils.c:304 +#: pg_waldump.c:1252 pg_waldump.c:1286 #, c-format msgid "could not open directory \"%s\": %m" msgstr "kunde inte öppna katalog \"%s\": %m" -#: ../../common/file_utils.c:169 ../../common/file_utils.c:315 +#: ../../common/file_utils.c:174 ../../common/file_utils.c:338 #, c-format msgid "could not read directory \"%s\": %m" msgstr "kunde inte läsa katalog \"%s\": %m" -#: ../../common/file_utils.c:418 ../../common/file_utils.c:488 +#: ../../common/file_utils.c:440 ../../common/file_utils.c:510 #, c-format msgid "could not fsync file \"%s\": %m" msgstr "kunde inte fsync:a fil \"%s\": %m" -#: ../../common/file_utils.c:498 +#: ../../common/file_utils.c:520 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "kunde inte döpa om fil \"%s\" till \"%s\": %m" -#: pg_waldump.c:137 -#, c-format -msgid "could not create directory \"%s\": %m" -msgstr "kunde inte skapa katalog \"%s\": %m" - -#: pg_waldump.c:146 +#: archive_waldump.c:143 pg_waldump.c:1300 pg_waldump.c:1330 #, c-format -msgid "directory \"%s\" exists but is not empty" -msgstr "katalogen \"%s\" existerar men är inte tom" +msgid "could not open file \"%s\"" +msgstr "kunde inte öppna filen \"%s\"" -#: pg_waldump.c:150 +#: archive_waldump.c:188 #, c-format -msgid "could not access directory \"%s\": %m" -msgstr "kunde inte komma åt katalog \"%s\": %m" +msgid "could not find WAL in archive \"%s\"" +msgstr "kunde inte hitta WAL i arkivet \"%s\"" -#: pg_waldump.c:256 +#: archive_waldump.c:205 #, c-format -msgid "invalid WAL segment size in WAL file \"%s\" (%d byte)" -msgid_plural "invalid WAL segment size in WAL file \"%s\" (%d bytes)" -msgstr[0] "ogiltigt WAL-segmentstorlek i WAL-fil \"%s\" (%d byte)" -msgstr[1] "ogiltigt WAL-segmentstorlek i WAL-fil \"%s\" (%d byte)" +msgid "invalid WAL segment size in WAL file from archive \"%s\" (%u byte)" +msgid_plural "invalid WAL segment size in WAL file from archive \"%s\" (%u bytes)" +msgstr[0] "ogiltigt WAL-segmentstorlek i WAL-fil från arkivet \"%s\" (%u byte)" +msgstr[1] "ogiltigt WAL-segmentstorlek i WAL-fil från arkivet \"%s\" (%u byte)" -#: pg_waldump.c:260 +#: archive_waldump.c:209 pg_waldump.c:252 #, c-format msgid "The WAL segment size must be a power of two between 1 MB and 1 GB." msgstr "WAL-segmentstorleken måste vara en tvåpotens mellan 1 MB och 1 GB." -#: pg_waldump.c:265 +#: archive_waldump.c:291 pg_waldump.c:654 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "kunde inte stänga fil \"%s\": %m" + +#: archive_waldump.c:367 +#, c-format +msgid "WAL segment \"%s\" in archive \"%s\" is too short: read %zu of %zu bytes" +msgstr "WAL-segment \"%s\" i arkivet \"%s\" är för kort: läste %zu av %zu byte" + +#: archive_waldump.c:371 +#, c-format +msgid "unexpected end of archive \"%s\" while reading \"%s\": read %zu of %zu bytes" +msgstr "oväntat slut på arkivet \"%s\" vid läsning av \"%s\": läste bara %zu av %zu byte" + +#: archive_waldump.c:503 +#, c-format +msgid "could not close file \"%s/%s\": %m" +msgstr "kunde inte stänga fil \"%s/%s\": %m" + +#: archive_waldump.c:516 +#, c-format +msgid "could not find WAL \"%s\" in archive \"%s\"" +msgstr "kunde inte hitta WAL \"%s\" i arkivet \"%s\"" + +#: archive_waldump.c:548 pg_waldump.c:259 #, c-format msgid "could not read file \"%s\": %m" msgstr "kunde inte läsa fil \"%s\": %m" -#: pg_waldump.c:268 +#: archive_waldump.c:595 pg_waldump.c:131 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "kunde inte skapa katalog \"%s\": %m" + +#: archive_waldump.c:622 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "kunde inte skapa fil \"%s\": %m" + +#: archive_waldump.c:626 +#, c-format +msgid "could not set permissions on file \"%s\": %m" +msgstr "kunde inte sätta rättigheter på filen \"%s\": %m" + +#: archive_waldump.c:651 +#, c-format +msgid "could not write to file \"%s/%s\": %m" +msgstr "kunde inte skriva till fil \"%s/%s\": %m" + +#: archive_waldump.c:743 +#, c-format +msgid "ignoring duplicate WAL \"%s\" found in archive \"%s\"" +msgstr "hoppar över duplicerad WAL \"%s\" som hittades i arkviet \"%s\"" + +#: archive_waldump.c:779 +#, c-format +msgid "unexpected state while parsing tar file" +msgstr "oväntat tillstånd vid parsning av tar-fil" + +#: pg_waldump.c:140 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "katalogen \"%s\" existerar men är inte tom" + +#: pg_waldump.c:144 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "kunde inte komma åt katalog \"%s\": %m" + +#: pg_waldump.c:248 +#, c-format +msgid "invalid WAL segment size in WAL file \"%s\" (%u byte)" +msgid_plural "invalid WAL segment size in WAL file \"%s\" (%u bytes)" +msgstr[0] "ogiltigt WAL-segmentstorlek i WAL-fil \"%s\" (%u byte)" +msgstr[1] "ogiltigt WAL-segmentstorlek i WAL-fil \"%s\" (%u byte)" + +#: pg_waldump.c:262 #, c-format msgid "could not read file \"%s\": read %d of %d" msgstr "kunde inte läsa fil \"%s\": läste %d av %d" -#: pg_waldump.c:329 +#: pg_waldump.c:324 #, c-format msgid "could not locate WAL file \"%s\"" msgstr "kunde inte lokalisera WAL-fil \"%s\"" -#: pg_waldump.c:331 +#: pg_waldump.c:326 #, c-format msgid "could not find any WAL file" msgstr "kunde inte hitta några WAL-filer" -#: pg_waldump.c:372 +#: pg_waldump.c:393 #, c-format msgid "could not find file \"%s\": %m" msgstr "kunde inte hitta filen \"%s\": %m" -#: pg_waldump.c:421 +#: pg_waldump.c:433 #, c-format msgid "could not read from file \"%s\", offset %d: %m" msgstr "Kunde inte läsa från fil \"%s\", offset %d: %m" -#: pg_waldump.c:425 +#: pg_waldump.c:437 #, c-format msgid "could not read from file \"%s\", offset %d: read %d of %d" msgstr "kunde inte läsa från fil \"%s\", offset %d, läste %d av %d" -#: pg_waldump.c:515 +#: pg_waldump.c:631 #, c-format msgid "%s" msgstr "%s" -#: pg_waldump.c:523 +#: pg_waldump.c:639 #, c-format msgid "invalid fork number: %u" msgstr "ogiltigt fork-nummer: %u" -#: pg_waldump.c:535 +#: pg_waldump.c:651 #, c-format msgid "could not write file \"%s\": %m" msgstr "kunde inte skriva fil \"%s\": %m" -#: pg_waldump.c:538 -#, c-format -msgid "could not close file \"%s\": %m" -msgstr "kunde inte stänga fil \"%s\": %m" - -#: pg_waldump.c:758 +#: pg_waldump.c:895 #, c-format msgid "" "%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" "\n" msgstr "%s avkodar och visar PostgreSQLs write-ahead-logg för debuggning.\n" -#: pg_waldump.c:760 +#: pg_waldump.c:897 #, c-format msgid "Usage:\n" msgstr "Användning:\n" -#: pg_waldump.c:761 +#: pg_waldump.c:898 #, c-format msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" msgstr " %s [FLAGGA]... [STARTSEG [SLUTSEG]]\n" -#: pg_waldump.c:762 +#: pg_waldump.c:899 #, c-format msgid "" "\n" @@ -199,29 +273,29 @@ msgstr "" "\n" "Flaggor:\n" -#: pg_waldump.c:763 +#: pg_waldump.c:900 #, c-format msgid " -b, --bkp-details output detailed information about backup blocks\n" msgstr " -b, --bkp-details skriv detaljerad information om backupblock\n" -#: pg_waldump.c:764 +#: pg_waldump.c:901 #, c-format msgid " -B, --block=N with --relation, only show records that modify block N\n" msgstr "" " -B, --block=N tillsammans med --relation, visa bara poster som\n" " modifierar block N\n" -#: pg_waldump.c:765 +#: pg_waldump.c:902 #, c-format msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" msgstr " -e, --end=RECPTR stoppa läsning vid WAL-position RECPTR\n" -#: pg_waldump.c:766 +#: pg_waldump.c:903 #, c-format msgid " -f, --follow keep retrying after reaching end of WAL\n" msgstr " -f, --follow fortsätt försök efter att ha nått slutet av WAL\n" -#: pg_waldump.c:767 +#: pg_waldump.c:904 #, c-format msgid "" " -F, --fork=FORK only show records that modify blocks in fork FORK;\n" @@ -230,28 +304,28 @@ msgstr "" " -F, --fork=GREN visa bara poster som modifierar block i grenen GREN\n" " gilriga namn är main, fsm, vm och init\n" -#: pg_waldump.c:769 +#: pg_waldump.c:906 #, c-format msgid " -n, --limit=N number of records to display\n" msgstr " -n, --limit=N antal poster att visa\n" -#: pg_waldump.c:770 +#: pg_waldump.c:907 #, c-format msgid "" -" -p, --path=PATH directory in which to find WAL segment files or a\n" -" directory with a ./pg_wal that contains such files\n" +" -p, --path=PATH a tar archive or a directory in which to find WAL segment files or\n" +" a directory with a pg_wal subdirectory containing such files\n" " (default: current directory, ./pg_wal, $PGDATA/pg_wal)\n" msgstr "" -" -p, --path=SÖKVÄG katalog där man hittar WAL-segmentfiler eller en\n" -" katalog med en ./pg_wal som innehåller sådana filer\n" +" -p, --path=SÖKVÄG ett tar-arkiv eller katalog där man hittar WAL-segmentfiler eller\n" +" en katalog med en underkatalog pg_wal som innehåller sådana filer\n" " (standard: aktuell katalog, ./pg_wal, $PGDATA/pg_wal)\n" -#: pg_waldump.c:773 +#: pg_waldump.c:910 #, c-format msgid " -q, --quiet do not print any output, except for errors\n" msgstr " -q, --quiet skriv inte ut några meddelanden förutom fel\n" -#: pg_waldump.c:774 +#: pg_waldump.c:911 #, c-format msgid "" " -r, --rmgr=RMGR only show records generated by resource manager RMGR;\n" @@ -260,19 +334,19 @@ msgstr "" " -r, --rmgr=RMGR visa bara poster skapade av resurshanteraren RMGR;\n" " använd --rmgr=list för att lista giltiga resurshanterarnamn\n" -#: pg_waldump.c:776 +#: pg_waldump.c:913 #, c-format msgid " -R, --relation=T/D/R only show records that modify blocks in relation T/D/R\n" msgstr "" " -R, --relation=T/D/R visa bara poster som modifierar block i\n" " relationen T/D/R\n" -#: pg_waldump.c:777 +#: pg_waldump.c:914 #, c-format msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" msgstr " -s, --start=RECPTR börja läsning vid WAL-position RECPTR\n" -#: pg_waldump.c:778 +#: pg_waldump.c:915 #, c-format msgid "" " -t, --timeline=TLI timeline from which to read WAL records\n" @@ -281,22 +355,22 @@ msgstr "" " -t, --timeline=TLI tidslinje från vilken vi läser WAL-poster\n" " (standard: 1 eller värdet som används i STARTSEG)\n" -#: pg_waldump.c:780 +#: pg_waldump.c:917 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: pg_waldump.c:781 +#: pg_waldump.c:918 #, c-format msgid " -w, --fullpage only show records with a full page write\n" msgstr " -w, --fullpage visa bara poster som skrivit hela sidor\n" -#: pg_waldump.c:782 +#: pg_waldump.c:919 #, c-format msgid " -x, --xid=XID only show records with transaction ID XID\n" msgstr " -x, --xid=XID visa baras poster med transaktions-ID XID\n" -#: pg_waldump.c:783 +#: pg_waldump.c:920 #, c-format msgid "" " -z, --stats[=record] show statistics instead of records\n" @@ -305,17 +379,17 @@ msgstr "" " -z, --stats[=post] visa statistik istället för poster\n" " (alternativt, visa statistik per post)\n" -#: pg_waldump.c:785 +#: pg_waldump.c:922 #, c-format msgid " --save-fullpage=DIR save full page images to DIR\n" msgstr " --save-fullpage=KAT spara kopia av hela sidor till KAT\n" -#: pg_waldump.c:786 +#: pg_waldump.c:923 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa den här hjälpen, avsluta sedan\n" -#: pg_waldump.c:787 +#: pg_waldump.c:924 #, c-format msgid "" "\n" @@ -324,285 +398,296 @@ msgstr "" "\n" "Rapportera fel till <%s>.\n" -#: pg_waldump.c:788 +#: pg_waldump.c:925 #, c-format msgid "%s home page: <%s>\n" msgstr "hemsida för %s: <%s>\n" -#: pg_waldump.c:884 +#: pg_waldump.c:1027 #, c-format msgid "no arguments specified" msgstr "inga argument angivna" -#: pg_waldump.c:900 +#: pg_waldump.c:1043 #, c-format msgid "invalid block number: \"%s\"" msgstr "ogiltigt portnummer \"%s\"" -#: pg_waldump.c:909 pg_waldump.c:1007 +#: pg_waldump.c:1052 pg_waldump.c:1150 #, c-format msgid "invalid WAL location: \"%s\"" msgstr "ogiltig WAL-position: \"%s\"" -#: pg_waldump.c:922 +#: pg_waldump.c:1065 #, c-format msgid "invalid fork name: \"%s\"" msgstr "ogiltigt fork-namn: \"%s\"" -#: pg_waldump.c:930 pg_waldump.c:1033 +#: pg_waldump.c:1073 pg_waldump.c:1176 #, c-format msgid "invalid value \"%s\" for option %s" msgstr "ogiltigt värde \"%s\" för flaggan \"%s\"" -#: pg_waldump.c:961 +#: pg_waldump.c:1104 #, c-format msgid "custom resource manager \"%s\" does not exist" msgstr "egendefinierad resurshanterare \"%s\" finns inte" -#: pg_waldump.c:982 +#: pg_waldump.c:1125 #, c-format msgid "resource manager \"%s\" does not exist" msgstr "resurshanterare \"%s\" finns inte" -#: pg_waldump.c:997 +#: pg_waldump.c:1140 #, c-format msgid "invalid relation specification: \"%s\"" msgstr "ogiltig inställning av relation: \"%s\"" -#: pg_waldump.c:998 +#: pg_waldump.c:1141 #, c-format msgid "Expecting \"tablespace OID/database OID/relation filenode\"." msgstr "Skall vara en av \"OID för tabellutrymme/OID för databas/relations filnod\"." -#: pg_waldump.c:1040 +#: pg_waldump.c:1183 #, c-format msgid "%s must be in range %u..%u" msgstr "%s måste vara i intervallet %u..%u" -#: pg_waldump.c:1055 +#: pg_waldump.c:1198 #, c-format msgid "invalid transaction ID specification: \"%s\"" msgstr "ogiltig inställning av transaktions-ID: %s" -#: pg_waldump.c:1070 +#: pg_waldump.c:1213 #, c-format msgid "unrecognized value for option %s: %s" msgstr "okänt värde för flaggan %s: %s" -#: pg_waldump.c:1087 +#: pg_waldump.c:1230 #, c-format msgid "option %s requires option %s to be specified" msgstr "flaggan %s kräver att flaggan %s också anges" -#: pg_waldump.c:1094 +#: pg_waldump.c:1237 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "för många kommandoradsargument (första är \"%s\")" -#: pg_waldump.c:1133 pg_waldump.c:1163 -#, c-format -msgid "could not open file \"%s\"" -msgstr "kunde inte öppna filen \"%s\"" +#: pg_waldump.c:1274 +#, fuzzy, c-format +#| msgid "too many command-line arguments (first is \"%s\")" +msgid "unnecessary command-line arguments specified with tar archive (first is \"%s\")" +msgstr "för många kommandoradsargument (första är \"%s\")" -#: pg_waldump.c:1143 +#: pg_waldump.c:1310 #, c-format -msgid "start WAL location %X/%X is not inside file \"%s\"" -msgstr "start-WAL-position %X/%X är inte i filen \"%s\"" +msgid "start WAL location %X/%08X is not inside file \"%s\"" +msgstr "start-WAL-position %X/%08X är inte i filen \"%s\"" -#: pg_waldump.c:1170 +#: pg_waldump.c:1337 #, c-format msgid "ENDSEG %s is before STARTSEG %s" msgstr "SLUTSEG %s är före STARTSEG %s" -#: pg_waldump.c:1185 +#: pg_waldump.c:1351 #, c-format -msgid "end WAL location %X/%X is not inside file \"%s\"" -msgstr "slut-WAL-position %X/%X är inte i filen \"%s\"" +msgid "end WAL location %X/%08X is not inside file \"%s\"" +msgstr "slut-WAL-position %X/%08X är inte i filen \"%s\"" -#: pg_waldump.c:1197 +#: pg_waldump.c:1364 #, c-format msgid "no start WAL location given" msgstr "ingen start-WAL-position angiven" -#: pg_waldump.c:1211 +#: pg_waldump.c:1371 +#, c-format +msgid "--follow is not supported when reading from a tar archive" +msgstr "--follow stöds inte när man läser från ett tar-arkiv" + +#: pg_waldump.c:1409 #, c-format msgid "out of memory while allocating a WAL reading processor" msgstr "slut på minne vid allokering av en WAL-läs-processor" -#: pg_waldump.c:1217 +#: pg_waldump.c:1425 +#, c-format +msgid "could not find a valid record after %X/%08X: %s" +msgstr "kunde inte hitta en giltig post efter %X/%08X: %s" + +#: pg_waldump.c:1428 #, c-format -msgid "could not find a valid record after %X/%X" -msgstr "kunde inte hitta en giltig post efter %X/%X" +msgid "could not find a valid record after %X/%08X" +msgstr "kunde inte hitta en giltig post efter %X/%08X" -#: pg_waldump.c:1227 +#: pg_waldump.c:1439 #, c-format -msgid "first record is after %X/%X, at %X/%X, skipping over %u byte" -msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes" -msgstr[0] "första posten är efter %X/%X, vid %X/%X, hoppar över %u byte" -msgstr[1] "första posten är efter %X/%X, vid %X/%X, hoppar över %u byte" +msgid "first record is after %X/%08X, at %X/%08X, skipping over %u byte" +msgid_plural "first record is after %X/%08X, at %X/%08X, skipping over %u bytes" +msgstr[0] "första posten är efter %X/%08X, vid %X/%08X, hoppar över %u byte" +msgstr[1] "första posten är efter %X/%08X, vid %X/%08X, hoppar över %u byte" -#: pg_waldump.c:1312 +#: pg_waldump.c:1527 #, c-format -msgid "error in WAL record at %X/%X: %s" -msgstr "fel i WAL-post vid %X/%X: %s" +msgid "error in WAL record at %X/%08X: %s" +msgstr "fel i WAL-post vid %X/%08X: %s" -#: pg_waldump.c:1321 +#: pg_waldump.c:1545 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Försök med \"%s --help\" för mer information." -#: xlogreader.c:619 +#: xlogreader.c:621 #, c-format -msgid "invalid record offset at %X/%X: expected at least %u, got %u" -msgstr "ogiltig postoffset vid %X/%X: förväntade minst %u, fick %u" +msgid "invalid record offset at %X/%08X: expected at least %u, got %u" +msgstr "ogiltig postoffset vid %X/%08X: förväntade minst %u, fick %u" -#: xlogreader.c:628 +#: xlogreader.c:630 #, c-format -msgid "contrecord is requested by %X/%X" -msgstr "contrecord är begärd vid %X/%X" +msgid "contrecord is requested by %X/%08X" +msgstr "contrecord är begärd vid %X/%08X" -#: xlogreader.c:669 xlogreader.c:1134 +#: xlogreader.c:671 xlogreader.c:1146 #, c-format -msgid "invalid record length at %X/%X: expected at least %u, got %u" -msgstr "ogiltig postlängd vid %X/%X: förväntade minst %u, fick %u" +msgid "invalid record length at %X/%08X: expected at least %u, got %u" +msgstr "ogiltig postlängd vid %X/%08X: förväntade minst %u, fick %u" -#: xlogreader.c:758 +#: xlogreader.c:761 #, c-format -msgid "there is no contrecord flag at %X/%X" -msgstr "det finns ingen contrecord-flagga vid %X/%X" +msgid "there is no contrecord flag at %X/%08X" +msgstr "det finns ingen contrecord-flagga vid %X/%08X" -#: xlogreader.c:771 +#: xlogreader.c:774 #, c-format -msgid "invalid contrecord length %u (expected %lld) at %X/%X" -msgstr "ogiltig contrecord-längd %u (förväntade %lld) vid %X/%X" +msgid "invalid contrecord length %u (expected %lld) at %X/%08X" +msgstr "ogiltig contrecord-längd %u (förväntade %lld) vid %X/%08X" -#: xlogreader.c:1142 +#: xlogreader.c:1154 #, c-format -msgid "invalid resource manager ID %u at %X/%X" -msgstr "ogiltigt resurshanterar-ID %u vid %X/%X" +msgid "invalid resource manager ID %u at %X/%08X" +msgstr "ogiltigt resurshanterar-ID %u vid %X/%08X" -#: xlogreader.c:1155 xlogreader.c:1171 +#: xlogreader.c:1167 xlogreader.c:1183 #, c-format -msgid "record with incorrect prev-link %X/%X at %X/%X" -msgstr "post med inkorrekt prev-link %X/%X vid %X/%X" +msgid "record with incorrect prev-link %X/%08X at %X/%08X" +msgstr "post med inkorrekt prev-link %X/%08X vid %X/%08X" -#: xlogreader.c:1209 +#: xlogreader.c:1221 #, c-format -msgid "incorrect resource manager data checksum in record at %X/%X" -msgstr "felaktig resurshanterardatakontrollsumma i post vid %X/%X" +msgid "incorrect resource manager data checksum in record at %X/%08X" +msgstr "felaktig resurshanterardatakontrollsumma i post vid %X/%08X" -#: xlogreader.c:1243 +#: xlogreader.c:1255 #, c-format -msgid "invalid magic number %04X in WAL segment %s, LSN %X/%X, offset %u" -msgstr "felaktigt magiskt nummer %04X i WAL-segment %s, LSN %X/%X, offset %u" +msgid "invalid magic number %04X in WAL segment %s, LSN %X/%08X, offset %u" +msgstr "felaktigt magiskt nummer %04X i WAL-segment %s, LSN %X/%08X, offset %u" -#: xlogreader.c:1258 xlogreader.c:1300 +#: xlogreader.c:1270 xlogreader.c:1312 #, c-format -msgid "invalid info bits %04X in WAL segment %s, LSN %X/%X, offset %u" -msgstr "ogiltiga infobitar %04X i WAL-segment %s, LSN %X/%X, offset %u" +msgid "invalid info bits %04X in WAL segment %s, LSN %X/%08X, offset %u" +msgstr "ogiltiga infobitar %04X i WAL-segment %s, LSN %X/%08X, offset %u" -#: xlogreader.c:1274 +#: xlogreader.c:1286 #, c-format -msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" -msgstr "WAL-fil är från ett annat databassystem: WAL-filens databassystemidentifierare är %llu, pg_control databassystemidentifierare är %llu" +msgid "WAL file is from different database system: WAL file database system identifier is %, pg_control database system identifier is %" +msgstr "WAL-fil är från ett annat databassystem: WAL-filens databassystemidentifierare är %, pg_control databassystemidentifierare är %" -#: xlogreader.c:1282 +#: xlogreader.c:1294 #, c-format msgid "WAL file is from different database system: incorrect segment size in page header" msgstr "WAL-fil är från ett annat databassystem: inkorrekt segmentstorlek i sidhuvud" -#: xlogreader.c:1288 +#: xlogreader.c:1300 #, c-format msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" msgstr "WAL-fil är från ett annat databassystem: inkorrekt XLOG_BLCKSZ i sidhuvud" -#: xlogreader.c:1320 +#: xlogreader.c:1332 #, c-format -msgid "unexpected pageaddr %X/%X in WAL segment %s, LSN %X/%X, offset %u" -msgstr "oväntad sidadress %X/%X i WAL-segment %s, LSN %X/%X, offset %u" +msgid "unexpected pageaddr %X/%08X in WAL segment %s, LSN %X/%08X, offset %u" +msgstr "oväntad sidadress %X/%08X i WAL-segment %s, LSN %X/%08X, offset %u" # FIXME -#: xlogreader.c:1346 +#: xlogreader.c:1358 #, c-format -msgid "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%X, offset %u" -msgstr "\"ej i sekvens\"-fel på tidslinje-ID %u (efter %u) i WAL-segment %s, LSN %X/%X, offset %u" +msgid "out-of-sequence timeline ID %u (after %u) in WAL segment %s, LSN %X/%08X, offset %u" +msgstr "\"ej i sekvens\"-fel på tidslinje-ID %u (efter %u) i WAL-segment %s, LSN %X/%08X, offset %u" -#: xlogreader.c:1749 +#: xlogreader.c:1790 #, c-format -msgid "out-of-order block_id %u at %X/%X" -msgstr "\"ej i sekvens\"-block_id %u vid %X/%X" +msgid "out-of-order block_id %u at %X/%08X" +msgstr "\"ej i sekvens\"-block_id %u vid %X/%08X" -#: xlogreader.c:1773 +#: xlogreader.c:1814 #, c-format -msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" -msgstr "BKPBLOCK_HAS_DATA är satt men ingen data inkluderad vid %X/%X" +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%08X" +msgstr "BKPBLOCK_HAS_DATA är satt men ingen data inkluderad vid %X/%08X" -#: xlogreader.c:1780 +#: xlogreader.c:1821 #, c-format -msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" -msgstr "BKPBLOCK_HAS_DATA är ej satt men datalängden är %u vid %X/%X" +msgid "BKPBLOCK_HAS_DATA not set, but data length is %d at %X/%08X" +msgstr "BKPBLOCK_HAS_DATA är ej satt men datalängden är %d vid %X/%08X" -#: xlogreader.c:1816 +#: xlogreader.c:1857 #, c-format -msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" -msgstr "BKPIMAGE_HAS_HOLE är satt men håloffset %u längd %u blockavbildlängd %u vid %X/%X" +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %d length %d block image length %d at %X/%08X" +msgstr "BKPIMAGE_HAS_HOLE är satt men håloffset %d längd %d blockavbildlängd %d vid %X/%08X" -#: xlogreader.c:1832 +#: xlogreader.c:1873 #, c-format -msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" -msgstr "BKPIMAGE_HAS_HOLE är inte satt men håloffset %u längd %u vid %X/%X" +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %d length %d at %X/%08X" +msgstr "BKPIMAGE_HAS_HOLE är inte satt men håloffset %d längd %d vid %X/%08X" -#: xlogreader.c:1846 +#: xlogreader.c:1887 #, c-format -msgid "BKPIMAGE_COMPRESSED set, but block image length %u at %X/%X" -msgstr "BKPIMAGE_COMPRESSED är satt men blockavbildlängd %u vid %X/%X" +msgid "BKPIMAGE_COMPRESSED set, but block image length %d at %X/%08X" +msgstr "BKPIMAGE_COMPRESSED är satt men blockavbildlängd %d vid %X/%08X" -#: xlogreader.c:1861 +#: xlogreader.c:1902 #, c-format -msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image length is %u at %X/%X" -msgstr "varken BKPIMAGE_HAS_HOLE eller BKPIMAGE_COMPRESSED är satt men blockavbildlängd är %u vid %X/%X" +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image length is %d at %X/%08X" +msgstr "varken BKPIMAGE_HAS_HOLE eller BKPIMAGE_COMPRESSED är satt men blockavbildlängd är %d vid %X/%08X" -#: xlogreader.c:1877 +#: xlogreader.c:1918 #, c-format -msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" -msgstr "BKPBLOCK_SAME_REL är satt men ingen tidigare rel vid %X/%X" +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%08X" +msgstr "BKPBLOCK_SAME_REL är satt men ingen tidigare rel vid %X/%08X" -#: xlogreader.c:1889 +#: xlogreader.c:1930 #, c-format -msgid "invalid block_id %u at %X/%X" -msgstr "ogiltig block_id %u vid %X/%X" +msgid "invalid block_id %u at %X/%08X" +msgstr "ogiltig block_id %u vid %X/%08X" -#: xlogreader.c:1956 +#: xlogreader.c:1997 #, c-format -msgid "record with invalid length at %X/%X" -msgstr "post med ogiltig längd vid %X/%X" +msgid "record with invalid length at %X/%08X" +msgstr "post med ogiltig längd vid %X/%08X" -#: xlogreader.c:1982 +#: xlogreader.c:2023 #, c-format msgid "could not locate backup block with ID %d in WAL record" msgstr "kunde inte hitta backup-block med ID %d i WAL-post" -#: xlogreader.c:2066 +#: xlogreader.c:2107 #, c-format -msgid "could not restore image at %X/%X with invalid block %d specified" -msgstr "kunde inte återställa avbild vid %X/%X med ogiltigt block %d angivet" +msgid "could not restore image at %X/%08X with invalid block %d specified" +msgstr "kunde inte återställa avbild vid %X/%08X med ogiltigt block %d angivet" -#: xlogreader.c:2073 +#: xlogreader.c:2114 #, c-format -msgid "could not restore image at %X/%X with invalid state, block %d" -msgstr "kunde inte återställa avbild vid %X/%X med ogiltigt state, block %d" +msgid "could not restore image at %X/%08X with invalid state, block %d" +msgstr "kunde inte återställa avbild vid %X/%08X med ogiltigt state, block %d" -#: xlogreader.c:2100 xlogreader.c:2117 +#: xlogreader.c:2141 xlogreader.c:2158 #, c-format -msgid "could not restore image at %X/%X compressed with %s not supported by build, block %d" -msgstr "kunde inte återställa avbild vid %X/%X, komprimerad med %s stöds inte av bygget, block %d" +msgid "could not restore image at %X/%08X compressed with %s not supported by build, block %d" +msgstr "kunde inte återställa avbild vid %X/%08X, komprimerad med %s stöds inte av bygget, block %d" -#: xlogreader.c:2126 +#: xlogreader.c:2167 #, c-format -msgid "could not restore image at %X/%X compressed with unknown method, block %d" -msgstr "kunde inte återställa avbild vid %X/%X, komprimerad med okänd metod, block %d" +msgid "could not restore image at %X/%08X compressed with unknown method, block %d" +msgstr "kunde inte återställa avbild vid %X/%08X, komprimerad med okänd metod, block %d" -#: xlogreader.c:2134 +#: xlogreader.c:2175 #, c-format -msgid "could not decompress image at %X/%X, block %d" -msgstr "kunde inte packa upp avbild vid %X/%X, block %d" +msgid "could not decompress image at %X/%08X, block %d" +msgstr "kunde inte packa upp avbild vid %X/%08X, block %d" diff --git a/src/bin/pg_walsummary/po/ru.po b/src/bin/pg_walsummary/po/ru.po index 0fe35651185..7e6382b9057 100644 --- a/src/bin/pg_walsummary/po/ru.po +++ b/src/bin/pg_walsummary/po/ru.po @@ -1,10 +1,10 @@ -# Alexander Lakhin , 2024. +# SPDX-FileCopyrightText: 2024, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: pg_walsummary (PostgreSQL) 17\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" -"PO-Revision-Date: 2024-09-05 14:47+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:51+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -35,17 +35,27 @@ msgstr "подробности: " msgid "hint: " msgstr "подсказка: " -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/file_utils.c:69 ../../common/file_utils.c:370 #: ../../common/file_utils.c:428 ../../common/file_utils.c:502 #: pg_walsummary.c:108 diff --git a/src/bin/psql/po/de.po b/src/bin/psql/po/de.po index c808e969a68..4f127a44496 100644 --- a/src/bin/psql/po/de.po +++ b/src/bin/psql/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-07-09 08:52+0000\n" -"PO-Revision-Date: 2026-07-09 11:49+0200\n" +"POT-Creation-Date: 2026-08-04 11:52+0000\n" +"PO-Revision-Date: 2026-08-04 14:34+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -255,15 +255,15 @@ msgstr "Sie sind gegenwärtig nicht mit einer Datenbank verbunden.\n" msgid "Connection Information" msgstr "Verbindungsinformationen" -#: command.c:840 describe.c:4972 +#: command.c:840 describe.c:4976 msgid "Parameter" msgstr "Parameter" -#: command.c:841 describe.c:4973 +#: command.c:841 describe.c:4977 msgid "Value" msgstr "Wert" -#: command.c:844 describe.c:4102 +#: command.c:844 describe.c:4106 msgid "Database" msgstr "Datenbank" @@ -287,7 +287,7 @@ msgstr "Host" msgid "Server Port" msgstr "Serverport" -#: command.c:882 describe.c:250 describe.c:3839 describe.c:4184 +#: command.c:882 describe.c:250 describe.c:3843 describe.c:4188 msgid "Options" msgstr "Optionen" @@ -1034,7 +1034,7 @@ msgstr "Zeit: %.3f ms (%02d:%02d:%06.3f)\n" msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" msgstr "Zeit: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" -#: common.c:663 common.c:720 common.c:1132 describe.c:6659 +#: common.c:663 common.c:720 common.c:1132 describe.c:6663 #, c-format msgid "You are currently not connected to a database." msgstr "Sie sind gegenwärtig nicht mit einer Datenbank verbunden." @@ -1103,14 +1103,14 @@ msgstr "ANWEISUNG: %s" msgid "unexpected transaction status (%d)" msgstr "unerwarteter Transaktionsstatus (%d)" -#: common.c:1400 describe.c:2198 +#: common.c:1400 describe.c:2202 msgid "Column" msgstr "Spalte" -#: common.c:1401 describe.c:179 describe.c:368 describe.c:386 describe.c:1094 -#: describe.c:1258 describe.c:1794 describe.c:1818 describe.c:2199 -#: describe.c:4292 describe.c:4566 describe.c:4815 describe.c:4979 -#: describe.c:6283 +#: common.c:1401 describe.c:179 describe.c:368 describe.c:386 describe.c:1098 +#: describe.c:1262 describe.c:1798 describe.c:1822 describe.c:2203 +#: describe.c:4296 describe.c:4570 describe.c:4819 describe.c:4983 +#: describe.c:6287 msgid "Type" msgstr "Typ" @@ -1248,21 +1248,21 @@ msgstr "\\crosstabview: Spaltenname nicht gefunden: »%s«" msgid "Get matching aggregates" msgstr "" -#: describe.c:96 describe.c:348 describe.c:656 describe.c:834 describe.c:1085 -#: describe.c:1245 describe.c:1322 describe.c:4280 describe.c:4553 -#: describe.c:4813 describe.c:4895 describe.c:5133 describe.c:5352 -#: describe.c:5606 describe.c:5852 describe.c:5922 describe.c:5933 -#: describe.c:5990 describe.c:6399 describe.c:6481 +#: describe.c:96 describe.c:348 describe.c:656 describe.c:834 describe.c:1089 +#: describe.c:1249 describe.c:1326 describe.c:4284 describe.c:4557 +#: describe.c:4817 describe.c:4899 describe.c:5137 describe.c:5356 +#: describe.c:5610 describe.c:5856 describe.c:5926 describe.c:5937 +#: describe.c:5994 describe.c:6403 describe.c:6485 msgid "Schema" msgstr "Schema" #: describe.c:97 describe.c:176 describe.c:238 describe.c:349 describe.c:657 -#: describe.c:835 describe.c:967 describe.c:1086 describe.c:1323 -#: describe.c:4281 describe.c:4554 describe.c:4729 describe.c:4814 -#: describe.c:4896 describe.c:5061 describe.c:5134 describe.c:5353 -#: describe.c:5476 describe.c:5607 describe.c:5853 describe.c:5923 -#: describe.c:5934 describe.c:5991 describe.c:6192 describe.c:6264 -#: describe.c:6478 describe.c:6708 describe.c:7116 +#: describe.c:835 describe.c:967 describe.c:1090 describe.c:1327 +#: describe.c:4285 describe.c:4558 describe.c:4733 describe.c:4818 +#: describe.c:4900 describe.c:5065 describe.c:5138 describe.c:5357 +#: describe.c:5480 describe.c:5611 describe.c:5857 describe.c:5927 +#: describe.c:5938 describe.c:5995 describe.c:6196 describe.c:6268 +#: describe.c:6482 describe.c:6712 describe.c:7120 msgid "Name" msgstr "Name" @@ -1275,14 +1275,14 @@ msgid "Argument data types" msgstr "Argumentdatentypen" #: describe.c:107 describe.c:114 describe.c:187 describe.c:252 describe.c:438 -#: describe.c:688 describe.c:854 describe.c:1019 describe.c:1325 -#: describe.c:2219 describe.c:4001 describe.c:4340 describe.c:4607 -#: describe.c:4753 describe.c:4827 describe.c:4905 describe.c:5074 -#: describe.c:5176 describe.c:5264 describe.c:5411 describe.c:5485 -#: describe.c:5608 describe.c:5760 describe.c:5803 describe.c:5869 -#: describe.c:5926 describe.c:5935 describe.c:5992 describe.c:6210 -#: describe.c:6286 describe.c:6413 describe.c:6482 describe.c:6972 -#: describe.c:7203 describe.c:7685 +#: describe.c:688 describe.c:854 describe.c:1022 describe.c:1329 +#: describe.c:2223 describe.c:4005 describe.c:4344 describe.c:4611 +#: describe.c:4757 describe.c:4831 describe.c:4909 describe.c:5078 +#: describe.c:5180 describe.c:5268 describe.c:5415 describe.c:5489 +#: describe.c:5612 describe.c:5764 describe.c:5807 describe.c:5873 +#: describe.c:5930 describe.c:5939 describe.c:5996 describe.c:6214 +#: describe.c:6290 describe.c:6417 describe.c:6486 describe.c:6976 +#: describe.c:7207 describe.c:7689 msgid "Description" msgstr "Beschreibung" @@ -1305,11 +1305,11 @@ msgstr "entfernt eine Zugriffsmethode" msgid "Index" msgstr "Index" -#: describe.c:178 describe.c:4300 describe.c:4579 describe.c:6400 +#: describe.c:178 describe.c:4304 describe.c:4583 describe.c:6404 msgid "Table" msgstr "Tabelle" -#: describe.c:186 describe.c:6194 +#: describe.c:186 describe.c:6198 msgid "Handler" msgstr "Handler" @@ -1323,11 +1323,11 @@ msgstr "Liste der Zugriffsmethoden" msgid "Get matching tablespaces" msgstr "Liste der Tablespaces" -#: describe.c:239 describe.c:421 describe.c:681 describe.c:968 describe.c:1244 -#: describe.c:4293 describe.c:4555 describe.c:4730 describe.c:5063 -#: describe.c:5477 describe.c:6193 describe.c:6265 describe.c:6709 -#: describe.c:6959 describe.c:7117 describe.c:7315 describe.c:7401 -#: describe.c:7673 +#: describe.c:239 describe.c:421 describe.c:681 describe.c:968 describe.c:1248 +#: describe.c:4297 describe.c:4559 describe.c:4734 describe.c:5067 +#: describe.c:5481 describe.c:6197 describe.c:6269 describe.c:6713 +#: describe.c:6963 describe.c:7121 describe.c:7319 describe.c:7405 +#: describe.c:7677 msgid "Owner" msgstr "Eigentümer" @@ -1335,7 +1335,7 @@ msgstr "Eigentümer" msgid "Location" msgstr "Pfad" -#: describe.c:251 describe.c:679 describe.c:1017 describe.c:4339 +#: describe.c:251 describe.c:679 describe.c:1020 describe.c:4343 msgid "Size" msgstr "Größe" @@ -1376,7 +1376,7 @@ msgstr "Proz" msgid "func" msgstr "Funk" -#: describe.c:384 describe.c:1455 +#: describe.c:384 describe.c:1459 msgid "trigger" msgstr "Trigger" @@ -1424,19 +1424,19 @@ msgstr "invoker" msgid "Security" msgstr "Sicherheit" -#: describe.c:425 describe.c:845 describe.c:1799 describe.c:1823 -#: describe.c:2066 describe.c:4899 describe.c:5252 describe.c:5261 -#: describe.c:5400 describe.c:5405 describe.c:7303 describe.c:7504 +#: describe.c:425 describe.c:845 describe.c:1803 describe.c:1827 +#: describe.c:2070 describe.c:4903 describe.c:5256 describe.c:5265 +#: describe.c:5404 describe.c:5409 describe.c:7307 describe.c:7508 msgid "yes" msgstr "ja" -#: describe.c:426 describe.c:846 describe.c:1800 describe.c:1824 -#: describe.c:2067 describe.c:4899 describe.c:5249 describe.c:5262 -#: describe.c:5400 describe.c:7304 describe.c:7505 +#: describe.c:426 describe.c:846 describe.c:1804 describe.c:1828 +#: describe.c:2071 describe.c:4903 describe.c:5253 describe.c:5266 +#: describe.c:5404 describe.c:7308 describe.c:7509 msgid "no" msgstr "nein" -#: describe.c:427 describe.c:847 describe.c:5263 describe.c:7506 +#: describe.c:427 describe.c:847 describe.c:5267 describe.c:7510 msgid "Leakproof?" msgstr "Leakproof?" @@ -1484,8 +1484,8 @@ msgstr "Rechter Typ" msgid "Result type" msgstr "Ergebnistyp" -#: describe.c:844 describe.c:5069 describe.c:5241 describe.c:5759 -#: describe.c:7602 describe.c:7606 +#: describe.c:844 describe.c:5073 describe.c:5245 describe.c:5763 +#: describe.c:7606 describe.c:7610 msgid "Function" msgstr "Funktion" @@ -1507,1383 +1507,1379 @@ msgstr "Kodierung" msgid "Locale Provider" msgstr "Locale-Provider" -#: describe.c:985 describe.c:5372 +#: describe.c:985 describe.c:5376 msgid "Collate" msgstr "Sortierfolge" -#: describe.c:986 describe.c:5373 +#: describe.c:986 describe.c:5377 msgid "Ctype" msgstr "Zeichentyp" -#: describe.c:990 describe.c:994 describe.c:998 describe.c:5378 describe.c:5382 -#: describe.c:5386 +#: describe.c:990 describe.c:994 describe.c:998 describe.c:5382 describe.c:5386 +#: describe.c:5390 msgid "Locale" msgstr "Locale" -#: describe.c:1002 describe.c:1006 describe.c:5391 describe.c:5395 +#: describe.c:1002 describe.c:1006 describe.c:5395 describe.c:5399 msgid "ICU Rules" msgstr "ICU-Regeln" -#: describe.c:1018 +#: describe.c:1021 msgid "Tablespace" msgstr "Tablespace" -#: describe.c:1043 +#: describe.c:1047 msgid "List of databases" msgstr "Liste der Datenbanken" -#: describe.c:1071 +#: describe.c:1075 #, fuzzy #| msgid "Set the privileges of the range type instead." msgid "Get access privileges of matching relations" msgstr "Setzen Sie stattdessen die Privilegien des Range-Typs." -#: describe.c:1087 describe.c:1247 describe.c:4282 +#: describe.c:1091 describe.c:1251 describe.c:4286 msgid "table" msgstr "Tabelle" -#: describe.c:1088 describe.c:4283 +#: describe.c:1092 describe.c:4287 msgid "view" msgstr "Sicht" -#: describe.c:1089 describe.c:4284 +#: describe.c:1093 describe.c:4288 msgid "materialized view" msgstr "materialisierte Sicht" -#: describe.c:1090 describe.c:1249 describe.c:4286 +#: describe.c:1094 describe.c:1253 describe.c:4290 msgid "sequence" msgstr "Sequenz" -#: describe.c:1091 describe.c:4288 +#: describe.c:1095 describe.c:4292 msgid "foreign table" msgstr "Fremdtabelle" -#: describe.c:1092 describe.c:4291 +#: describe.c:1096 describe.c:4295 msgid "property graph" msgstr "Property-Graph" -#: describe.c:1093 describe.c:4289 describe.c:4564 +#: describe.c:1097 describe.c:4293 describe.c:4568 msgid "partitioned table" msgstr "partitionierte Tabelle" -#: describe.c:1109 +#: describe.c:1113 msgid "Column privileges" msgstr "Spaltenprivilegien" -#: describe.c:1140 describe.c:1174 +#: describe.c:1144 describe.c:1178 msgid "Policies" msgstr "Policys" -#: describe.c:1203 describe.c:4985 describe.c:7259 +#: describe.c:1207 describe.c:4989 describe.c:7263 msgid "Access privileges" msgstr "Zugriffsprivilegien" -#: describe.c:1236 +#: describe.c:1240 msgid "Get matching default ACLs" msgstr "" -#: describe.c:1251 +#: describe.c:1255 msgid "function" msgstr "Funktion" -#: describe.c:1253 +#: describe.c:1257 msgid "type" msgstr "Typ" -#: describe.c:1255 +#: describe.c:1259 msgid "schema" msgstr "Schema" -#: describe.c:1257 +#: describe.c:1261 msgid "large object" msgstr "Large Object" -#: describe.c:1279 +#: describe.c:1283 msgid "Default access privileges" msgstr "Vorgegebene Zugriffsprivilegien" -#: describe.c:1318 +#: describe.c:1322 msgid "Get matching object comments" msgstr "" -#: describe.c:1324 +#: describe.c:1328 msgid "Object" msgstr "Objekt" -#: describe.c:1338 +#: describe.c:1342 msgid "table constraint" msgstr "Tabellen-Constraint" -#: describe.c:1362 +#: describe.c:1366 msgid "domain constraint" msgstr "Domänen-Constraint" -#: describe.c:1386 +#: describe.c:1390 msgid "operator class" msgstr "Operatorklasse" -#: describe.c:1410 +#: describe.c:1414 msgid "operator family" msgstr "Operatorfamilie" -#: describe.c:1433 +#: describe.c:1437 msgid "rule" msgstr "Rule" -#: describe.c:1478 +#: describe.c:1482 msgid "Object descriptions" msgstr "Objektbeschreibungen" -#: describe.c:1512 +#: describe.c:1516 #, fuzzy #| msgid "no matching relations in tablespace \"%s\" found" msgid "Get matching relations to describe" msgstr "keine passenden Relationen in Tablespace »%s« gefunden" -#: describe.c:1545 +#: describe.c:1549 #, c-format msgid "Did not find any relation named \"%s\"." msgstr "Keine Relation namens »%s« gefunden" -#: describe.c:1548 describe.c:4446 +#: describe.c:1552 describe.c:4450 #, c-format msgid "Did not find any relations." msgstr "Keine Relationen gefunden" -#: describe.c:1650 +#: describe.c:1654 #, fuzzy #| msgid "Collects information about executing commands." msgid "Get general information about one relation" msgstr "Sammelt Informationen über ausgeführte Befehle." -#: describe.c:1746 +#: describe.c:1750 #, c-format msgid "Did not find any relation with OID %s." msgstr "Keine Relation mit OID %s gefunden" -#: describe.c:1783 +#: describe.c:1787 #, fuzzy #| msgid "sequence_option" msgid "Get sequence information" msgstr "Sequenzoption" -#: describe.c:1795 describe.c:1819 +#: describe.c:1799 describe.c:1823 msgid "Start" msgstr "Start" -#: describe.c:1796 describe.c:1820 +#: describe.c:1800 describe.c:1824 msgid "Minimum" msgstr "Minimum" -#: describe.c:1797 describe.c:1821 +#: describe.c:1801 describe.c:1825 msgid "Maximum" msgstr "Maximum" -#: describe.c:1798 describe.c:1822 +#: describe.c:1802 describe.c:1826 msgid "Increment" msgstr "Inkrement" -#: describe.c:1801 describe.c:1825 +#: describe.c:1805 describe.c:1829 msgid "Cycles?" msgstr "Zyklisch?" -#: describe.c:1802 describe.c:1826 +#: describe.c:1806 describe.c:1830 msgid "Cache" msgstr "Cache" -#: describe.c:1838 +#: describe.c:1842 msgid "Get the column that owns this sequence" msgstr "" -#: describe.c:1869 +#: describe.c:1873 #, c-format msgid "Owned by: %s" msgstr "Eigentümer: %s" -#: describe.c:1873 +#: describe.c:1877 #, c-format msgid "Sequence for identity column: %s" msgstr "Sequenz für Identitätsspalte: %s" -#: describe.c:1884 +#: describe.c:1888 msgid "Get publications containing this sequence" msgstr "" -#: describe.c:1898 describe.c:3266 describe.c:5540 -#, fuzzy -#| msgid "reading publications" +#: describe.c:1902 describe.c:3270 describe.c:5544 msgid "Included in publications:" -msgstr "lese Publikationen" +msgstr "Enthalten in Publikationen:" -#: describe.c:1916 +#: describe.c:1920 #, c-format msgid "Unlogged sequence \"%s.%s\"" msgstr "Ungeloggte Sequenz »%s.%s«" -#: describe.c:1919 +#: describe.c:1923 #, c-format msgid "Sequence \"%s.%s\"" msgstr "Sequenz »%s.%s«" -#: describe.c:1944 +#: describe.c:1948 msgid "Get property graph information" msgstr "" -#: describe.c:1960 +#: describe.c:1964 msgid "Element Alias" msgstr "Element-Alias" -#: describe.c:1961 +#: describe.c:1965 msgid "Element Table" msgstr "Elementtabelle" -#: describe.c:1962 +#: describe.c:1966 msgid "Element Kind" msgstr "Elementart" -#: describe.c:1963 +#: describe.c:1967 msgid "Source Vertex Alias" msgstr "Quellknoten-Alias" -#: describe.c:1964 +#: describe.c:1968 msgid "Destination Vertex Alias" msgstr "Zielknoten-Alias" -#: describe.c:1971 +#: describe.c:1975 #, c-format msgid "Property Graph \"%s.%s\"" msgstr "Property-Graph »%s.%s«" -#: describe.c:1979 +#: describe.c:1983 msgid "Get property graph definition" msgstr "" -#: describe.c:1989 +#: describe.c:1993 msgid "Property graph definition:" msgstr "Property-Graph-Definition:" -#: describe.c:2029 +#: describe.c:2033 msgid "Get per-column information for one relation" msgstr "" -#: describe.c:2139 +#: describe.c:2143 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "Ungeloggte Tabelle »%s.%s«" -#: describe.c:2142 +#: describe.c:2146 #, c-format msgid "Table \"%s.%s\"" msgstr "Tabelle »%s.%s«" -#: describe.c:2146 +#: describe.c:2150 #, c-format msgid "View \"%s.%s\"" msgstr "Sicht »%s.%s«" -#: describe.c:2150 +#: describe.c:2154 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "Materialisierte Sicht »%s.%s«" -#: describe.c:2155 +#: describe.c:2159 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "Ungeloggter Index »%s.%s«" -#: describe.c:2158 +#: describe.c:2162 #, c-format msgid "Index \"%s.%s\"" msgstr "Index »%s.%s«" -#: describe.c:2163 +#: describe.c:2167 #, c-format msgid "Unlogged partitioned index \"%s.%s\"" msgstr "Ungeloggter partitionierter Index »%s.%s«" -#: describe.c:2166 +#: describe.c:2170 #, c-format msgid "Partitioned index \"%s.%s\"" msgstr "Partitionierter Index »%s.%s«" -#: describe.c:2170 +#: describe.c:2174 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "TOAST-Tabelle »%s.%s«" -#: describe.c:2174 +#: describe.c:2178 #, c-format msgid "Composite type \"%s.%s\"" msgstr "Zusammengesetzter Typ »%s.%s«" -#: describe.c:2178 +#: describe.c:2182 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "Fremdtabelle »%s.%s«" -#: describe.c:2183 +#: describe.c:2187 #, c-format msgid "Unlogged partitioned table \"%s.%s\"" msgstr "Ungeloggte partitionierte Tabelle »%s.%s«" -#: describe.c:2186 +#: describe.c:2190 #, c-format msgid "Partitioned table \"%s.%s\"" msgstr "Partitionierte Tabelle »%s.%s«" -#: describe.c:2202 describe.c:4816 +#: describe.c:2206 describe.c:4820 msgid "Collation" msgstr "Sortierfolge" -#: describe.c:2203 describe.c:4817 +#: describe.c:2207 describe.c:4821 msgid "Nullable" msgstr "NULL erlaubt?" -#: describe.c:2204 describe.c:4818 +#: describe.c:2208 describe.c:4822 msgid "Default" msgstr "Vorgabewert" -#: describe.c:2207 +#: describe.c:2211 msgid "Key?" msgstr "Schlüssel?" -#: describe.c:2209 describe.c:5141 describe.c:5152 +#: describe.c:2213 describe.c:5145 describe.c:5156 msgid "Definition" msgstr "Definition" -#: describe.c:2211 describe.c:6209 describe.c:6285 describe.c:6352 -#: describe.c:6412 +#: describe.c:2215 describe.c:6213 describe.c:6289 describe.c:6356 +#: describe.c:6416 msgid "FDW options" msgstr "FDW-Optionen" -#: describe.c:2213 +#: describe.c:2217 msgid "Storage" msgstr "Speicherung" -#: describe.c:2215 +#: describe.c:2219 msgid "Compression" msgstr "Kompression" -#: describe.c:2217 +#: describe.c:2221 msgid "Stats target" msgstr "Statistikziel" -#: describe.c:2333 +#: describe.c:2337 #, fuzzy #| msgid "don't have transaction information for this type of tuple" msgid "Get partitioning information for this partition" msgstr "dieser Tupeltyp hat keine Transaktionsinformationen" -#: describe.c:2361 +#: describe.c:2365 #, c-format msgid "Partition of: %s %s%s" msgstr "Partition von: %s %s%s" -#: describe.c:2374 +#: describe.c:2378 msgid "No partition constraint" msgstr "Kein Partitions-Constraint" -#: describe.c:2376 +#: describe.c:2380 #, c-format msgid "Partition constraint: %s" msgstr "Partitions-Constraint: %s" -#: describe.c:2390 +#: describe.c:2394 #, fuzzy #| msgid "don't have transaction information for this type of tuple" msgid "Get partitioning information for this table" msgstr "dieser Tupeltyp hat keine Transaktionsinformationen" -#: describe.c:2402 +#: describe.c:2406 #, c-format msgid "Partition key: %s" msgstr "Partitionsschlüssel: %s" -#: describe.c:2414 +#: describe.c:2418 msgid "Get the table that owns this TOAST table" msgstr "" -#: describe.c:2430 +#: describe.c:2434 #, c-format msgid "Owning table: \"%s.%s\"" msgstr "Gehört zu Tabelle: »%s.%s«" -#: describe.c:2443 +#: describe.c:2447 msgid "Get index details" msgstr "" -#: describe.c:2504 +#: describe.c:2508 msgid "primary key, " msgstr "Primärschlüssel, " -#: describe.c:2508 +#: describe.c:2512 #, fuzzy #| msgid " nulls not distinct" msgid "unique nulls not distinct, " msgstr " nulls not distinct" -#: describe.c:2510 +#: describe.c:2514 #, fuzzy #| msgid "unique" msgid "unique, " msgstr "unique" #. translator: the first %s is an index AM name (eg. btree) -#: describe.c:2517 +#: describe.c:2521 #, fuzzy, c-format #| msgid "for table \"%s.%s\"" msgid "%s, for table \"%s.%s\"" msgstr "für Tabelle »%s.%s«" -#: describe.c:2521 +#: describe.c:2525 #, c-format msgid ", predicate (%s)" msgstr ", Prädikat (%s)" -#: describe.c:2524 +#: describe.c:2528 msgid ", clustered" msgstr ", geclustert" -#: describe.c:2527 +#: describe.c:2531 msgid ", invalid" msgstr ", ungültig" -#: describe.c:2530 +#: describe.c:2534 msgid ", deferrable" msgstr ", DEFERRABLE" -#: describe.c:2533 +#: describe.c:2537 msgid ", initially deferred" msgstr ", INITIALLY DEFERRED" -#: describe.c:2536 +#: describe.c:2540 msgid ", replica identity" msgstr ", Replika-Identität" -#: describe.c:2565 +#: describe.c:2569 #, fuzzy #| msgid "define a new foreign table" msgid "Get indexes for this table" msgstr "definiert eine neue Fremdtabelle" -#: describe.c:2598 +#: describe.c:2602 msgid "Indexes:" msgstr "Indexe:" -#: describe.c:2671 +#: describe.c:2675 #, fuzzy #| msgid "there are circular foreign-key constraints on this table:" #| msgid_plural "there are circular foreign-key constraints among these tables:" msgid "Get check constraints for this table" msgstr "Es gibt zirkuläre Fremdschlüssel-Constraints für diese Tabelle:" -#: describe.c:2688 +#: describe.c:2692 msgid "Check constraints:" msgstr "Check-Constraints:" -#: describe.c:2704 +#: describe.c:2708 #, fuzzy #| msgid "there are circular foreign-key constraints on this table:" #| msgid_plural "there are circular foreign-key constraints among these tables:" msgid "Get foreign key constraints for this table" msgstr "Es gibt zirkuläre Fremdschlüssel-Constraints für diese Tabelle:" -#: describe.c:2751 +#: describe.c:2755 msgid "Foreign-key constraints:" msgstr "Fremdschlüssel-Constraints:" -#: describe.c:2776 +#: describe.c:2780 msgid "Get foreign keys referencing this table" msgstr "" -#: describe.c:2812 +#: describe.c:2816 msgid "Referenced by:" msgstr "Fremdschlüsselverweise von:" -#: describe.c:2829 +#: describe.c:2833 #, fuzzy #| msgid "define a new row-level security policy for a table" msgid "Get row-level policies for this table" msgstr "definiert eine neue Policy für Sicherheit auf Zeilenebene für eine Tabelle" -#: describe.c:2863 +#: describe.c:2867 msgid "Policies:" msgstr "Policys:" -#: describe.c:2866 +#: describe.c:2870 msgid "Policies (forced row security enabled):" msgstr "Policys (Sicherheit auf Zeilenebene erzwungen):" -#: describe.c:2869 +#: describe.c:2873 msgid "Policies (row security enabled): (none)" msgstr "Policys (Sicherheit auf Zeilenebene eingeschaltet): (keine)" -#: describe.c:2872 +#: describe.c:2876 msgid "Policies (forced row security enabled): (none)" msgstr "Policys (Sicherheit auf Zeilenebene erzwungen): (keine)" -#: describe.c:2875 +#: describe.c:2879 msgid "Policies (row security disabled):" msgstr "Policys (Sicherheit auf Zeilenebene ausgeschaltet):" -#: describe.c:2913 describe.c:3013 +#: describe.c:2917 describe.c:3017 #, fuzzy #| msgid "define extended statistics" msgid "Get extended statistics for this table" msgstr "definiert erweiterte Statistiken" -#: describe.c:2937 describe.c:3044 +#: describe.c:2941 describe.c:3048 msgid "Statistics objects:" msgstr "Statistikobjekte:" -#: describe.c:3094 +#: describe.c:3098 msgid "Get rules for this relation" msgstr "" -#: describe.c:3148 describe.c:3414 +#: describe.c:3152 describe.c:3418 msgid "Rules:" msgstr "Regeln:" -#: describe.c:3151 +#: describe.c:3155 msgid "Disabled rules:" msgstr "Abgeschaltete Regeln:" -#: describe.c:3154 +#: describe.c:3158 msgid "Rules firing always:" msgstr "Regeln, die immer aktiv werden:" -#: describe.c:3157 +#: describe.c:3161 msgid "Rules firing on replica only:" msgstr "Regeln, die nur im Replikat aktiv werden:" -#: describe.c:3179 +#: describe.c:3183 #, fuzzy #| msgid "reading publication membership of tables" msgid "Get publications that publish this table" msgstr "lese Publikationsmitgliedschaft von Tabellen" -#: describe.c:3293 +#: describe.c:3297 #, fuzzy #| msgid "reading publication membership of tables" msgid "Get publications that exclude this table" msgstr "lese Publikationsmitgliedschaft von Tabellen" -#: describe.c:3309 -#, fuzzy -#| msgid "Publications:" +#: describe.c:3313 msgid "Excluded from publications:" -msgstr "Publikationen:" +msgstr "Ausgeschlossen aus Publikationen:" -#: describe.c:3327 +#: describe.c:3331 #, fuzzy #| msgid "Not-null constraints:" msgid "Get not-null constraints for this table" msgstr "Not-Null-Constraints:" -#: describe.c:3347 +#: describe.c:3351 msgid "Not-null constraints:" msgstr "Not-Null-Constraints:" -#: describe.c:3361 +#: describe.c:3365 msgid " (local, inherited)" -msgstr "(lokal, geerbt)" +msgstr " (lokal, geerbt)" -#: describe.c:3362 +#: describe.c:3366 msgid " (inherited)" -msgstr "(geerbt)" +msgstr " (geerbt)" -#: describe.c:3377 +#: describe.c:3381 #, fuzzy #| msgid "View definition:" msgid "Get view's definition" msgstr "Sichtdefinition:" -#: describe.c:3396 +#: describe.c:3400 msgid "View definition:" msgstr "Sichtdefinition:" -#: describe.c:3402 +#: describe.c:3406 msgid "Get rules for this view" msgstr "" -#: describe.c:3441 +#: describe.c:3445 #, fuzzy #| msgid "renamed trigger \"%s\" on relation \"%s\"" msgid "Get triggers for this relation" msgstr "Trigger »%s« für Tabelle »%s« wurde umbenannt" -#: describe.c:3562 +#: describe.c:3566 msgid "Triggers:" msgstr "Trigger:" -#: describe.c:3565 +#: describe.c:3569 msgid "Disabled user triggers:" msgstr "Abgeschaltete Benutzer-Trigger:" -#: describe.c:3568 +#: describe.c:3572 msgid "Disabled internal triggers:" msgstr "Abgeschaltete interne Trigger:" -#: describe.c:3571 +#: describe.c:3575 msgid "Triggers firing always:" msgstr "Trigger, die immer aktiv werden:" -#: describe.c:3574 +#: describe.c:3578 msgid "Triggers firing on replica only:" msgstr "Trigger, die nur im Replikat aktiv werden:" -#: describe.c:3626 +#: describe.c:3630 #, fuzzy #| msgid "List of foreign servers" msgid "Get foreign server for this table" msgstr "Liste der Fremdserver" -#: describe.c:3647 +#: describe.c:3651 #, c-format msgid "Server: %s" msgstr "Server: %s" -#: describe.c:3655 +#: describe.c:3659 #, c-format msgid "FDW options: (%s)" msgstr "FDW-Optionen: (%s)" -#: describe.c:3663 +#: describe.c:3667 #, fuzzy #| msgid "too many inheritance parents" msgid "Get inheritance parent tables" msgstr "zu viele Elterntabellen" -#: describe.c:3678 +#: describe.c:3682 msgid "Inherits" msgstr "Erbt von" -#: describe.c:3698 +#: describe.c:3702 #, fuzzy #| msgid "Child tables" msgid "Get child tables" msgstr "Kindtabellen" -#: describe.c:3741 +#: describe.c:3745 #, c-format msgid "Number of partitions: %d" msgstr "Anzahl Partitionen: %d" -#: describe.c:3750 +#: describe.c:3754 #, c-format msgid "Number of partitions: %d (Use \\d+ to list them.)" msgstr "Anzahl Partitionen: %d (Mit \\d+ alle anzeigen.)" -#: describe.c:3752 +#: describe.c:3756 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "Anzahl Kindtabellen: %d (Mit \\d+ alle anzeigen.)" -#: describe.c:3759 +#: describe.c:3763 msgid "Child tables" msgstr "Kindtabellen" -#: describe.c:3759 +#: describe.c:3763 msgid "Partitions" msgstr "Partitionen" -#: describe.c:3790 +#: describe.c:3794 #, c-format msgid "Typed table of type: %s" msgstr "Getypte Tabelle vom Typ: %s" -#: describe.c:3808 +#: describe.c:3812 msgid "Replica Identity" msgstr "Replika-Identität" -#: describe.c:3821 +#: describe.c:3825 msgid "Has OIDs: yes" msgstr "Hat OIDs: ja" -#: describe.c:3830 +#: describe.c:3834 #, c-format msgid "Access method: %s" msgstr "Zugriffsmethode: %s" -#: describe.c:3893 +#: describe.c:3897 #, fuzzy #| msgid "tablespace location \"%s\" is too long" msgid "Get tablespace information for this relation" msgstr "Tablespace-Pfad »%s« ist zu lang" -#: describe.c:3909 +#: describe.c:3913 #, c-format msgid "Tablespace: \"%s\"" msgstr "Tablespace: »%s«" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:3921 +#: describe.c:3925 #, c-format msgid ", tablespace \"%s\"" msgstr ", Tablespace »%s«" -#: describe.c:3955 +#: describe.c:3959 msgid "Get matching roles" msgstr "" -#: describe.c:3995 +#: describe.c:3999 msgid "List of roles" msgstr "Liste der Rollen" -#: describe.c:3997 describe.c:4167 +#: describe.c:4001 describe.c:4171 msgid "Role name" msgstr "Rollenname" -#: describe.c:3998 +#: describe.c:4002 msgid "Attributes" msgstr "Attribute" -#: describe.c:4009 +#: describe.c:4013 msgid "Superuser" msgstr "Superuser" -#: describe.c:4012 +#: describe.c:4016 msgid "No inheritance" msgstr "keine Vererbung" -#: describe.c:4015 +#: describe.c:4019 msgid "Create role" msgstr "Rolle erzeugen" -#: describe.c:4018 +#: describe.c:4022 msgid "Create DB" msgstr "DB erzeugen" -#: describe.c:4021 +#: describe.c:4025 msgid "Cannot login" msgstr "kann nicht einloggen" -#: describe.c:4024 +#: describe.c:4028 msgid "Replication" msgstr "Replikation" -#: describe.c:4028 +#: describe.c:4032 msgid "Bypass RLS" msgstr "Bypass RLS" -#: describe.c:4037 +#: describe.c:4041 msgid "No connections" msgstr "keine Verbindungen" -#: describe.c:4039 +#: describe.c:4043 #, c-format msgid "%d connection" msgid_plural "%d connections" msgstr[0] "%d Verbindung" msgstr[1] "%d Verbindungen" -#: describe.c:4049 +#: describe.c:4053 msgid "Password valid until " msgstr "Passwort gültig bis " -#: describe.c:4095 +#: describe.c:4099 #, fuzzy #| msgid "Checking database connection settings" msgid "Get per-database and per-role settings" msgstr "Prüfe Verbindungseinstellungen der Datenbank" -#: describe.c:4101 +#: describe.c:4105 msgid "Role" msgstr "Rolle" -#: describe.c:4103 +#: describe.c:4107 msgid "Settings" msgstr "Einstellung" -#: describe.c:4127 +#: describe.c:4131 #, c-format msgid "Did not find any settings for role \"%s\" and database \"%s\"." msgstr "Keine Einstellungen für Rolle »%s« und Datenbank »%s« gefunden" -#: describe.c:4130 +#: describe.c:4134 #, c-format msgid "Did not find any settings for role \"%s\"." msgstr "Keine Einstellungen für Rolle »%s« gefunden" -#: describe.c:4133 +#: describe.c:4137 #, c-format msgid "Did not find any settings." msgstr "Keine Einstellungen gefunden" -#: describe.c:4137 +#: describe.c:4141 msgid "List of settings" msgstr "Liste der Einstellungen" -#: describe.c:4163 +#: describe.c:4167 #, fuzzy #| msgid "List of role grants" msgid "Get matching role grants" msgstr "Liste der Rollen-Grants" -#: describe.c:4168 +#: describe.c:4172 msgid "Member of" msgstr "Mitglied von" -#: describe.c:4185 +#: describe.c:4189 msgid "Grantor" msgstr "Grantor" -#: describe.c:4211 +#: describe.c:4215 msgid "List of role grants" msgstr "Liste der Rollen-Grants" -#: describe.c:4263 +#: describe.c:4267 #, fuzzy #| msgid "while vacuuming relation \"%s.%s\"" msgid "Get matching relations" msgstr "beim Vacuum von Relation »%s.%s«" -#: describe.c:4285 +#: describe.c:4289 msgid "index" msgstr "Index" -#: describe.c:4287 +#: describe.c:4291 msgid "TOAST table" msgstr "TOAST-Tabelle" -#: describe.c:4290 describe.c:4565 +#: describe.c:4294 describe.c:4569 msgid "partitioned index" msgstr "partitionierter Index" -#: describe.c:4315 +#: describe.c:4319 msgid "permanent" msgstr "permanent" -#: describe.c:4316 +#: describe.c:4320 msgid "temporary" msgstr "temporär" -#: describe.c:4317 +#: describe.c:4321 msgid "unlogged" msgstr "ungeloggt" -#: describe.c:4318 +#: describe.c:4322 msgid "Persistence" msgstr "Persistenz" -#: describe.c:4334 describe.c:4588 +#: describe.c:4338 describe.c:4592 msgid "Access method" msgstr "Zugriffsmethode" -#: describe.c:4416 +#: describe.c:4420 #, c-format msgid "Did not find any relations named \"%s\"." msgstr "Keine Relationen namens »%s« gefunden" -#: describe.c:4419 +#: describe.c:4423 #, c-format msgid "Did not find any tables named \"%s\"." msgstr "Keine Tabellen namens »%s« gefunden" -#: describe.c:4422 +#: describe.c:4426 #, c-format msgid "Did not find any indexes named \"%s\"." msgstr "Keine Indexe namens »%s« gefunden" -#: describe.c:4425 +#: describe.c:4429 #, c-format msgid "Did not find any views named \"%s\"." msgstr "Keine Sichten namens »%s« gefunden" -#: describe.c:4428 +#: describe.c:4432 #, c-format msgid "Did not find any materialized views named \"%s\"." msgstr "Keine materialisierten Sichten namens »%s« gefunden" -#: describe.c:4431 +#: describe.c:4435 #, c-format msgid "Did not find any sequences named \"%s\"." msgstr "Keine Sequenzen namens »%s« gefunden" -#: describe.c:4434 +#: describe.c:4438 #, c-format msgid "Did not find any foreign tables named \"%s\"." msgstr "Keine Fremdtabellen namens »%s« gefunden" -#: describe.c:4437 +#: describe.c:4441 #, c-format msgid "Did not find any property graphs named \"%s\"." msgstr "Keine Property-Graphs namens »%s« gefunden" -#: describe.c:4448 +#: describe.c:4452 #, c-format msgid "Did not find any tables." msgstr "Keine Tabellen gefunden" -#: describe.c:4450 +#: describe.c:4454 #, c-format msgid "Did not find any indexes." msgstr "Keine Indexe gefunden" -#: describe.c:4452 +#: describe.c:4456 #, c-format msgid "Did not find any views." msgstr "Keine Sichten gefunden" -#: describe.c:4454 +#: describe.c:4458 #, c-format msgid "Did not find any materialized views." msgstr "Keine materialisierten Sichten gefunden" -#: describe.c:4456 +#: describe.c:4460 #, c-format msgid "Did not find any sequences." msgstr "Keine Sequenzen gefunden" -#: describe.c:4458 +#: describe.c:4462 #, c-format msgid "Did not find any foreign tables." msgstr "Keine Fremdtabellen gefunden" -#: describe.c:4460 +#: describe.c:4464 #, c-format msgid "Did not find any property graphs." msgstr "Keine Property-Graphs gefunden" -#: describe.c:4468 +#: describe.c:4472 msgid "List of relations" msgstr "Liste der Relationen" -#: describe.c:4469 +#: describe.c:4473 msgid "List of tables" msgstr "Liste der Tabellen" -#: describe.c:4470 +#: describe.c:4474 msgid "List of indexes" msgstr "Liste der Indexe" -#: describe.c:4471 +#: describe.c:4475 msgid "List of views" msgstr "Liste der Sichten" -#: describe.c:4472 +#: describe.c:4476 msgid "List of materialized views" msgstr "Liste der materialisierten Sichten" -#: describe.c:4473 +#: describe.c:4477 msgid "List of sequences" msgstr "Liste der Sequenzen" -#: describe.c:4474 describe.c:6445 +#: describe.c:4478 describe.c:6449 msgid "List of foreign tables" msgstr "Liste der Fremdtabellen" -#: describe.c:4475 +#: describe.c:4479 msgid "List of property graphs" msgstr "Liste der Property-Graphs" -#: describe.c:4524 +#: describe.c:4528 #, c-format msgid "The server (version %s) does not support declarative table partitioning." msgstr "Der Server (Version %s) unterstützt keine deklarative Tabellenpartitionierung." -#: describe.c:4535 +#: describe.c:4539 msgid "List of partitioned indexes" msgstr "Liste partitionierter Indexe" -#: describe.c:4537 +#: describe.c:4541 msgid "List of partitioned tables" msgstr "Liste partitionierte Tabellen" -#: describe.c:4541 +#: describe.c:4545 msgid "List of partitioned relations" msgstr "Liste partitionierter Relationen" -#: describe.c:4548 +#: describe.c:4552 #, fuzzy #| msgid "List of partitioned relations" msgid "Get matching partitioned relations" msgstr "Liste partitionierter Relationen" -#: describe.c:4574 +#: describe.c:4578 msgid "Parent name" msgstr "Elternname" -#: describe.c:4594 +#: describe.c:4598 msgid "Leaf partition size" msgstr "Größe Leaf-Partition" -#: describe.c:4597 describe.c:4603 +#: describe.c:4601 describe.c:4607 msgid "Total size" msgstr "Gesamtgröße" -#: describe.c:4724 +#: describe.c:4728 #, fuzzy #| msgid "reading procedural languages" msgid "Get matching procedural languages" msgstr "lese prozedurale Sprachen" -#: describe.c:4731 +#: describe.c:4735 msgid "Trusted" msgstr "Vertraut" -#: describe.c:4740 +#: describe.c:4744 msgid "Internal language" msgstr "Interne Sprache" -#: describe.c:4741 +#: describe.c:4745 msgid "Call handler" msgstr "Call-Handler" -#: describe.c:4742 describe.c:6195 +#: describe.c:4746 describe.c:6199 msgid "Validator" msgstr "Validator" -#: describe.c:4743 +#: describe.c:4747 msgid "Inline handler" msgstr "Inline-Handler" -#: describe.c:4777 +#: describe.c:4781 msgid "List of languages" msgstr "Liste der Sprachen" -#: describe.c:4801 +#: describe.c:4805 msgid "Get matching domains" msgstr "" -#: describe.c:4819 +#: describe.c:4823 msgid "Check" msgstr "Check" -#: describe.c:4862 +#: describe.c:4866 msgid "List of domains" msgstr "Liste der Domänen" -#: describe.c:4887 +#: describe.c:4891 #, fuzzy #| msgid "List of conversions" msgid "Get matching conversions" msgstr "Liste der Konversionen" -#: describe.c:4897 +#: describe.c:4901 msgid "Source" msgstr "Quelle" -#: describe.c:4898 +#: describe.c:4902 msgid "Destination" msgstr "Ziel" -#: describe.c:4900 describe.c:7305 +#: describe.c:4904 describe.c:7309 msgid "Default?" msgstr "Standard?" -#: describe.c:4941 +#: describe.c:4945 msgid "List of conversions" msgstr "Liste der Konversionen" -#: describe.c:4968 +#: describe.c:4972 #, fuzzy #| msgid "List of configuration parameters" msgid "Get matching configuration parameters" msgstr "Liste der Konfigurationsparameter" -#: describe.c:4980 +#: describe.c:4984 msgid "Context" msgstr "Kontext" -#: describe.c:5012 +#: describe.c:5016 msgid "List of configuration parameters" msgstr "Liste der Konfigurationsparameter" -#: describe.c:5014 +#: describe.c:5018 msgid "List of non-default configuration parameters" msgstr "Liste der veränderten Konfigurationsparameter" -#: describe.c:5041 +#: describe.c:5045 #, c-format msgid "The server (version %s) does not support event triggers." msgstr "Der Server (Version %s) unterstützt keine Ereignistrigger." -#: describe.c:5049 +#: describe.c:5053 #, fuzzy #| msgid "reading event triggers" msgid "Get matching event triggers" msgstr "lese Ereignistrigger" -#: describe.c:5062 +#: describe.c:5066 msgid "Event" msgstr "Ereignis" -#: describe.c:5064 +#: describe.c:5068 msgid "enabled" msgstr "eingeschaltet" -#: describe.c:5065 +#: describe.c:5069 msgid "replica" msgstr "Replika" -#: describe.c:5066 +#: describe.c:5070 msgid "always" msgstr "immer" -#: describe.c:5067 +#: describe.c:5071 msgid "disabled" msgstr "ausgeschaltet" -#: describe.c:5068 describe.c:7118 +#: describe.c:5072 describe.c:7122 msgid "Enabled" msgstr "Eingeschaltet" -#: describe.c:5070 +#: describe.c:5074 msgid "Tags" msgstr "Tags" -#: describe.c:5093 +#: describe.c:5097 msgid "List of event triggers" msgstr "Liste der Ereignistrigger" -#: describe.c:5120 +#: describe.c:5124 #, c-format msgid "The server (version %s) does not support extended statistics." msgstr "Der Server (Version %s) unterstützt keine erweiterten Statistiken." -#: describe.c:5128 +#: describe.c:5132 #, fuzzy #| msgid "reading extended statistics" msgid "Get matching extended statistics" msgstr "lese erweiterte Statistiken" -#: describe.c:5159 +#: describe.c:5163 msgid "Ndistinct" msgstr "Ndistinct" -#: describe.c:5160 +#: describe.c:5164 msgid "Dependencies" msgstr "Abhängigkeiten" -#: describe.c:5170 +#: describe.c:5174 msgid "MCV" msgstr "MCV" -#: describe.c:5198 +#: describe.c:5202 msgid "List of extended statistics" msgstr "Liste der erweiterten Statistiken" -#: describe.c:5222 +#: describe.c:5226 msgid "Get matching casts" msgstr "" -#: describe.c:5226 +#: describe.c:5230 msgid "Source type" msgstr "Quelltyp" -#: describe.c:5227 +#: describe.c:5231 msgid "Target type" msgstr "Zieltyp" -#: describe.c:5251 +#: describe.c:5255 msgid "in assignment" msgstr "in Zuweisung" -#: describe.c:5253 +#: describe.c:5257 msgid "Implicit?" msgstr "Implizit?" -#: describe.c:5317 +#: describe.c:5321 msgid "List of casts" msgstr "Liste der Typumwandlungen" -#: describe.c:5347 +#: describe.c:5351 #, fuzzy #| msgid "existing_collation" msgid "Get matching collations" msgstr "existierende_Sortierfolge" -#: describe.c:5363 describe.c:5367 +#: describe.c:5367 describe.c:5371 msgid "Provider" msgstr "Provider" -#: describe.c:5401 describe.c:5406 +#: describe.c:5405 describe.c:5410 msgid "Deterministic?" msgstr "Deterministisch?" -#: describe.c:5445 +#: describe.c:5449 msgid "List of collations" msgstr "Liste der Sortierfolgen" -#: describe.c:5472 +#: describe.c:5476 #, fuzzy #| msgid "reading schemas" msgid "Get matching schemas" msgstr "lese Schemas" -#: describe.c:5508 +#: describe.c:5512 msgid "List of schemas" msgstr "Liste der Schemas" -#: describe.c:5517 +#: describe.c:5521 #, fuzzy #| msgid "reading publication membership of schemas" msgid "Get publications that publish this schema" msgstr "lese Publikationsmitgliedschaft von Schemas" -#: describe.c:5598 describe.c:5648 +#: describe.c:5602 describe.c:5652 #, fuzzy #| msgid "List of text search parsers" msgid "Get matching text search parsers" msgstr "Liste der Textsucheparser" -#: describe.c:5627 +#: describe.c:5631 msgid "List of text search parsers" msgstr "Liste der Textsucheparser" -#: describe.c:5678 +#: describe.c:5682 #, c-format msgid "Did not find any text search parser named \"%s\"." msgstr "Kein Textsucheparser namens »%s« gefunden" -#: describe.c:5681 +#: describe.c:5685 #, c-format msgid "Did not find any text search parsers." msgstr "Keine Textsucheparser gefunden" -#: describe.c:5726 +#: describe.c:5730 #, fuzzy #| msgid "text search parser %s" msgid "Get text search parser details" msgstr "Textsucheparser %s" -#: describe.c:5757 +#: describe.c:5761 msgid "Start parse" msgstr "Parsen starten" -#: describe.c:5758 +#: describe.c:5762 msgid "Method" msgstr "Methode" -#: describe.c:5762 +#: describe.c:5766 msgid "Get next token" msgstr "Nächstes Token lesen" -#: describe.c:5764 +#: describe.c:5768 msgid "End parse" msgstr "Parsen beenden" -#: describe.c:5766 +#: describe.c:5770 msgid "Get headline" msgstr "Überschrift ermitteln" -#: describe.c:5768 +#: describe.c:5772 msgid "Get token types" msgstr "Tokentypen ermitteln" -#: describe.c:5778 +#: describe.c:5782 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "Textsucheparser »%s.%s«" -#: describe.c:5781 +#: describe.c:5785 #, c-format msgid "Text search parser \"%s\"" msgstr "Textsucheparser »%s«" -#: describe.c:5796 +#: describe.c:5800 #, fuzzy #| msgid "text search parser %s" msgid "Get text search parser token types" msgstr "Textsucheparser %s" -#: describe.c:5802 +#: describe.c:5806 msgid "Token name" msgstr "Tokenname" -#: describe.c:5815 +#: describe.c:5819 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "Tokentypen für Parser »%s.%s«" -#: describe.c:5818 +#: describe.c:5822 #, c-format msgid "Token types for parser \"%s\"" msgstr "Tokentypen für Parser »%s«" -#: describe.c:5847 +#: describe.c:5851 #, fuzzy #| msgid "List of text search dictionaries" msgid "Get matching text search dictionaries" msgstr "Liste der Textsuchewörterbücher" -#: describe.c:5863 +#: describe.c:5867 msgid "Template" msgstr "Vorlage" -#: describe.c:5864 +#: describe.c:5868 msgid "Init options" msgstr "Initialisierungsoptionen" -#: describe.c:5890 +#: describe.c:5894 msgid "List of text search dictionaries" msgstr "Liste der Textsuchewörterbücher" -#: describe.c:5913 +#: describe.c:5917 #, fuzzy #| msgid "List of text search templates" msgid "Get matching text search templates" msgstr "Liste der Textsuchevorlagen" -#: describe.c:5924 +#: describe.c:5928 msgid "Init" msgstr "Init" -#: describe.c:5925 +#: describe.c:5929 msgid "Lexize" msgstr "Lexize" -#: describe.c:5956 +#: describe.c:5960 msgid "List of text search templates" msgstr "Liste der Textsuchevorlagen" -#: describe.c:5982 describe.c:6029 +#: describe.c:5986 describe.c:6033 #, fuzzy #| msgid "Sets default text search configuration." msgid "Get matching text search configurations" msgstr "Setzt die vorgegebene Textsuchekonfiguration." -#: describe.c:6011 +#: describe.c:6015 msgid "List of text search configurations" msgstr "Liste der Textsuchekonfigurationen" -#: describe.c:6063 +#: describe.c:6067 #, c-format msgid "Did not find any text search configuration named \"%s\"." msgstr "Keine Textsuchekonfiguration namens »%s« gefunden" -#: describe.c:6066 +#: describe.c:6070 #, c-format msgid "Did not find any text search configurations." msgstr "Keine Textsuchekonfigurationen gefunden" -#: describe.c:6116 +#: describe.c:6120 #, fuzzy #| msgid "text search configuration %s" msgid "Get text search configuration details" msgstr "Textsuchekonfiguration %s" -#: describe.c:6133 +#: describe.c:6137 msgid "Token" msgstr "Token" -#: describe.c:6134 +#: describe.c:6138 msgid "Dictionaries" msgstr "Wörterbücher" -#: describe.c:6145 +#: describe.c:6149 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "Textsuchekonfiguration »%s.%s«" -#: describe.c:6148 +#: describe.c:6152 #, c-format msgid "Text search configuration \"%s\"" msgstr "Textsuchekonfiguration »%s«" -#: describe.c:6152 +#: describe.c:6156 #, c-format msgid "" "\n" @@ -2892,7 +2888,7 @@ msgstr "" "\n" "Parser: »%s.%s«" -#: describe.c:6155 +#: describe.c:6159 #, c-format msgid "" "\n" @@ -2901,399 +2897,395 @@ msgstr "" "\n" "Parser: »%s«" -#: describe.c:6186 +#: describe.c:6190 #, fuzzy #| msgid "List of foreign-data wrappers" msgid "Get matching foreign-data wrappers" msgstr "Liste der Fremddaten-Wrapper" -#: describe.c:6236 +#: describe.c:6240 msgid "List of foreign-data wrappers" msgstr "Liste der Fremddaten-Wrapper" -#: describe.c:6259 +#: describe.c:6263 #, fuzzy #| msgid "List of foreign servers" msgid "Get matching foreign servers" msgstr "Liste der Fremdserver" -#: describe.c:6266 +#: describe.c:6270 msgid "Foreign-data wrapper" msgstr "Fremddaten-Wrapper" -#: describe.c:6284 describe.c:6479 +#: describe.c:6288 describe.c:6483 msgid "Version" msgstr "Version" -#: describe.c:6314 +#: describe.c:6318 msgid "List of foreign servers" msgstr "Liste der Fremdserver" -#: describe.c:6337 +#: describe.c:6341 #, fuzzy #| msgid "List of user mappings" msgid "Get matching user mappings" msgstr "Liste der Benutzerabbildungen" -#: describe.c:6341 describe.c:6401 describe.c:7169 +#: describe.c:6345 describe.c:6405 describe.c:7173 msgid "Server" msgstr "Server" -#: describe.c:6342 +#: describe.c:6346 msgid "User name" msgstr "Benutzername" -#: describe.c:6371 +#: describe.c:6375 msgid "List of user mappings" msgstr "Liste der Benutzerabbildungen" -#: describe.c:6394 +#: describe.c:6398 #, fuzzy #| msgid "importing foreign table \"%s\"" msgid "Get matching foreign tables" msgstr "importiere Fremdtabelle »%s«" -#: describe.c:6468 describe.c:6524 +#: describe.c:6472 describe.c:6528 #, fuzzy #| msgid "List of installed extensions" msgid "Get matching installed extensions" msgstr "Liste der installierten Erweiterungen" -#: describe.c:6480 +#: describe.c:6484 msgid "Default version" msgstr "Standardversion" -#: describe.c:6501 +#: describe.c:6505 msgid "List of installed extensions" msgstr "Liste der installierten Erweiterungen" -#: describe.c:6551 +#: describe.c:6555 #, c-format msgid "Did not find any extension named \"%s\"." msgstr "Keine Erweiterung namens »%s« gefunden" -#: describe.c:6554 +#: describe.c:6558 #, c-format msgid "Did not find any extensions." msgstr "Keine Erweiterungen gefunden" -#: describe.c:6594 +#: describe.c:6598 #, fuzzy #| msgid "List of installed extensions" msgid "Get installed extension's contents" msgstr "Liste der installierten Erweiterungen" -#: describe.c:6600 +#: describe.c:6604 msgid "Object description" msgstr "Objektbeschreibung" -#: describe.c:6609 +#: describe.c:6613 #, c-format msgid "Objects in extension \"%s\"" msgstr "Objekte in Erweiterung »%s«" -#: describe.c:6650 +#: describe.c:6654 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "falscher qualifizierter Name (zu viele Namensteile): %s" -#: describe.c:6664 +#: describe.c:6668 #, c-format msgid "cross-database references are not implemented: %s" msgstr "Verweise auf andere Datenbanken sind nicht implementiert: %s" -#: describe.c:6695 describe.c:6842 +#: describe.c:6699 describe.c:6846 #, c-format msgid "The server (version %s) does not support publications." msgstr "Der Server (Version %s) unterstützt keine Publikationen." -#: describe.c:6703 +#: describe.c:6707 #, fuzzy #| msgid "reading publications" msgid "Get matching publications" msgstr "lese Publikationen" -#: describe.c:6710 describe.c:6960 +#: describe.c:6714 describe.c:6964 msgid "All tables" msgstr "Alle Tabellen" -#: describe.c:6715 describe.c:6962 -#, fuzzy -#| msgid "sequence" +#: describe.c:6719 describe.c:6966 msgid "All sequences" -msgstr "Sequenz" +msgstr "Alle Sequenzen" -#: describe.c:6721 describe.c:6963 +#: describe.c:6725 describe.c:6967 msgid "Inserts" msgstr "Inserts" -#: describe.c:6722 describe.c:6964 +#: describe.c:6726 describe.c:6968 msgid "Updates" msgstr "Updates" -#: describe.c:6723 describe.c:6965 +#: describe.c:6727 describe.c:6969 msgid "Deletes" msgstr "Deletes" -#: describe.c:6727 describe.c:6967 +#: describe.c:6731 describe.c:6971 msgid "Truncates" msgstr "Truncates" -#: describe.c:6736 describe.c:6886 describe.c:6969 +#: describe.c:6740 describe.c:6890 describe.c:6973 msgid "Generated columns" msgstr "Generierte Spalten" -#: describe.c:6740 describe.c:6971 +#: describe.c:6744 describe.c:6975 msgid "Via root" msgstr "Über Wurzel" -#: describe.c:6761 +#: describe.c:6765 msgid "List of publications" msgstr "Liste der Publikationen" -#: describe.c:6855 +#: describe.c:6859 #, fuzzy #| msgid "reading publications" msgid "Get details about matching publications" msgstr "lese Publikationen" -#: describe.c:6927 +#: describe.c:6931 #, c-format msgid "Did not find any publication named \"%s\"." msgstr "Keine Publikation namens »%s« gefunden" -#: describe.c:6930 +#: describe.c:6934 #, c-format msgid "Did not find any publications." msgstr "Keine Publikationen gefunden" -#: describe.c:6956 +#: describe.c:6960 #, c-format msgid "Publication %s" msgstr "Publikation %s" -#: describe.c:6993 +#: describe.c:6997 msgid "Get tables published by this publication" msgstr "" -#: describe.c:7024 +#: describe.c:7028 msgid "Tables:" msgstr "Tabellen:" -#: describe.c:7031 +#: describe.c:7035 #, fuzzy #| msgid "cannot add schema \"%s\" to publication" msgid "Get schemas published by this publication" msgstr "Schema »%s« kann nicht zu Publikation hinzugefügt werden" -#: describe.c:7038 +#: describe.c:7042 msgid "Tables from schemas:" msgstr "Tabellen aus Schemas:" -#: describe.c:7049 +#: describe.c:7053 msgid "Get tables excluded by this publication" msgstr "" -#: describe.c:7057 +#: describe.c:7061 msgid "Except tables:" -msgstr "" +msgstr "Außer Tabellen:" -#: describe.c:7102 +#: describe.c:7106 #, c-format msgid "The server (version %s) does not support subscriptions." msgstr "Der Server (Version %s) unterstützt keine Subskriptionen." -#: describe.c:7110 +#: describe.c:7114 #, fuzzy #| msgid "reading subscriptions" msgid "Get matching subscriptions" msgstr "lese Subskriptionen" -#: describe.c:7119 +#: describe.c:7123 msgid "Publication" msgstr "Publikation" -#: describe.c:7128 +#: describe.c:7132 msgid "Binary" msgstr "Binär" -#: describe.c:7137 describe.c:7141 +#: describe.c:7141 describe.c:7145 msgid "Streaming" msgstr "Streaming" -#: describe.c:7149 +#: describe.c:7153 msgid "Two-phase commit" msgstr "Two-Phase-Commit" -#: describe.c:7150 +#: describe.c:7154 msgid "Disable on error" msgstr "Bei Fehler abschalten" -#: describe.c:7157 +#: describe.c:7161 msgid "Origin" msgstr "Herkunft" -#: describe.c:7158 +#: describe.c:7162 msgid "Password required" msgstr "Passwort nötig" -#: describe.c:7159 +#: describe.c:7163 msgid "Run as owner?" msgstr "Als Eigentümer ausführen?" -#: describe.c:7164 +#: describe.c:7168 msgid "Failover" msgstr "Failover" -#: describe.c:7173 +#: describe.c:7177 msgid "Retain dead tuples" msgstr "" -#: describe.c:7177 +#: describe.c:7181 msgid "Max retention duration" msgstr "" -#: describe.c:7181 +#: describe.c:7185 msgid "Retention active" msgstr "" -#: describe.c:7187 +#: describe.c:7191 msgid "Synchronous commit" msgstr "Synchroner Commit" -#: describe.c:7188 +#: describe.c:7192 msgid "Conninfo" msgstr "Verbindungsinfo" -#: describe.c:7193 -#, fuzzy -#| msgid "TCP user timeout." +#: describe.c:7197 msgid "Receiver timeout" -msgstr "TCP-User-Timeout." +msgstr "Empfänger-Timeout" -#: describe.c:7199 +#: describe.c:7203 msgid "Skip LSN" msgstr "Skip-LSN" -#: describe.c:7229 +#: describe.c:7233 msgid "List of subscriptions" msgstr "Liste der Subskriptionen" -#: describe.c:7258 +#: describe.c:7262 msgid "(none)" msgstr "(keine)" -#: describe.c:7280 +#: describe.c:7284 #, fuzzy #| msgid "List of operator classes" msgid "Get matching operator classes" msgstr "Liste der Operatorklassen" -#: describe.c:7299 describe.c:7395 describe.c:7488 describe.c:7593 +#: describe.c:7303 describe.c:7399 describe.c:7492 describe.c:7597 msgid "AM" msgstr "AM" -#: describe.c:7300 +#: describe.c:7304 msgid "Input type" msgstr "Eingabetyp" -#: describe.c:7301 +#: describe.c:7305 msgid "Storage type" msgstr "Storage-Typ" -#: describe.c:7302 +#: describe.c:7306 msgid "Operator class" msgstr "Operatorklasse" -#: describe.c:7314 describe.c:7396 describe.c:7489 describe.c:7594 +#: describe.c:7318 describe.c:7400 describe.c:7493 describe.c:7598 msgid "Operator family" msgstr "Operatorfamilie" -#: describe.c:7349 +#: describe.c:7353 msgid "List of operator classes" msgstr "Liste der Operatorklassen" -#: describe.c:7382 +#: describe.c:7386 #, fuzzy #| msgid "List of operator families" msgid "Get matching operator families" msgstr "Liste der Operatorfamilien" -#: describe.c:7397 +#: describe.c:7401 msgid "Applicable types" msgstr "Passende Typen" -#: describe.c:7438 +#: describe.c:7442 msgid "List of operator families" msgstr "Liste der Operatorfamilien" -#: describe.c:7473 +#: describe.c:7477 #, fuzzy #| msgid "List of operators of operator families" msgid "Get operators of matching operator families" msgstr "Liste der Operatoren in Operatorfamilien" -#: describe.c:7490 +#: describe.c:7494 msgid "Operator" msgstr "Operator" -#: describe.c:7491 +#: describe.c:7495 msgid "Strategy" msgstr "Strategie" -#: describe.c:7492 +#: describe.c:7496 msgid "ordering" msgstr "Sortieren" -#: describe.c:7493 +#: describe.c:7497 msgid "search" msgstr "Suchen" -#: describe.c:7494 +#: describe.c:7498 msgid "Purpose" msgstr "Zweck" -#: describe.c:7503 +#: describe.c:7507 msgid "Sort opfamily" msgstr "Sortier-Opfamilie" -#: describe.c:7546 +#: describe.c:7550 msgid "List of operators of operator families" msgstr "Liste der Operatoren in Operatorfamilien" -#: describe.c:7581 +#: describe.c:7585 #, fuzzy #| msgid "List of support functions of operator families" msgid "Get support functions of matching operator families" msgstr "Liste der Unterstützungsfunktionen in Operatorfamilien" -#: describe.c:7595 +#: describe.c:7599 msgid "Registered left type" msgstr "Registrierter linker Typ" -#: describe.c:7596 +#: describe.c:7600 msgid "Registered right type" msgstr "Registrierter rechter Typ" -#: describe.c:7597 +#: describe.c:7601 msgid "Number" msgstr "Nummer" -#: describe.c:7640 +#: describe.c:7644 msgid "List of support functions of operator families" msgstr "Liste der Unterstützungsfunktionen in Operatorfamilien" -#: describe.c:7668 +#: describe.c:7672 #, fuzzy #| msgid "large object" msgid "Get large objects" msgstr "Large Object" -#: describe.c:7672 +#: describe.c:7676 msgid "ID" msgstr "ID" -#: describe.c:7692 +#: describe.c:7696 msgid "Large objects" msgstr "Large Objects" @@ -3955,10 +3947,8 @@ msgid " \\dx[x+] [PATTERN] list extensions\n" msgstr " \\dx[x+] [MUSTER] Erweiterungen auflisten\n" #: help.c:271 -#, fuzzy -#| msgid " \\dX[x] [PATTERN] list extended statistics\n" msgid " \\dX[x+] [PATTERN] list extended statistics\n" -msgstr " \\dX[x] [MUSTER] erweiterte Statistiken auflisten\n" +msgstr " \\dX[x+] [MUSTER] erweiterte Statistiken auflisten\n" #: help.c:272 msgid " \\dy[x+] [PATTERN] list event triggers\n" @@ -5683,19 +5673,15 @@ msgstr "Kantentabellen-Alias" #: sql_help.c:956 sql_help.c:961 sql_help.c:964 sql_help.c:969 msgid "element_table_alias" -msgstr "Elementtabellenname" +msgstr "Elementtabellenalias" #: sql_help.c:957 sql_help.c:962 sql_help.c:965 sql_help.c:970 sql_help.c:2859 -#, fuzzy -#| msgid "table_name" msgid "label_name" -msgstr "Tabellenname" +msgstr "Label-Name" #: sql_help.c:959 sql_help.c:967 sql_help.c:971 sql_help.c:2857 sql_help.c:2861 -#, fuzzy -#| msgid "improper type name" msgid "property_name" -msgstr "falscher Typname" +msgstr "Property-Name" #: sql_help.c:1018 sql_help.c:1022 sql_help.c:2894 msgid "publication_object" @@ -6396,7 +6382,7 @@ msgstr "Alias" #: sql_help.c:2843 sql_help.c:2854 msgid "element_table_label_and_properties" -msgstr "" +msgstr "Elementtabellen-Label-und-Propertys" #: sql_help.c:2844 msgid "and edge_table_definition is:" @@ -6407,20 +6393,16 @@ msgid "edge_table_name" msgstr "Kantentabellenname" #: sql_help.c:2852 -#, fuzzy -#| msgid "stable" msgid "dest_table" -msgstr "stabil" +msgstr "Zieltabelle" #: sql_help.c:2855 msgid "and element_table_label_and_properties is either:" msgstr "" #: sql_help.c:2858 -#, fuzzy -#| msgid "error: " msgid "or:" -msgstr "Fehler: " +msgstr "oder:" #: sql_help.c:2965 sql_help.c:3433 msgid "where event can be one of:" @@ -6775,10 +6757,8 @@ msgstr "Large-Object-OID" #: sql_help.c:4263 sql_help.c:4771 sql_help.c:4999 sql_help.c:5262 #: sql_help.c:5553 -#, fuzzy -#| msgid "group_name" msgid "graph_name" -msgstr "Gruppenname" +msgstr "Graphname" #: sql_help.c:4291 msgid "remote_schema" @@ -7360,10 +7340,8 @@ msgid "define a new procedure" msgstr "definiert eine neue Prozedur" #: sql_help.c:6050 -#, fuzzy -#| msgid "define an SQL-property graph" msgid "define a new SQL-property graph" -msgstr "definiert einen SQL-Property-Graph" +msgstr "definiert einen neuen SQL-Property-Graph" #: sql_help.c:6056 msgid "define a new publication" @@ -7820,7 +7798,7 @@ msgstr "überflüssiges Kommandozeilenargument »%s« ignoriert" msgid "could not find own program executable" msgstr "konnte eigene Programmdatei nicht finden" -#: tab-complete.in.c:7058 +#: tab-complete.in.c:7061 #, c-format msgid "" "tab completion query failed: %s\n" @@ -7879,9 +7857,3 @@ msgid "" msgstr "" "unbekannter Wert »%s« für »%s«\n" "Verfügbare Werte sind: %s." - -#~ msgid ", " -#~ msgstr ", " - -#~ msgid "Publications:" -#~ msgstr "Publikationen:" diff --git a/src/bin/psql/po/ru.po b/src/bin/psql/po/ru.po index be1beb51489..93666c1724a 100644 --- a/src/bin/psql/po/ru.po +++ b/src/bin/psql/po/ru.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: psql (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-02-07 08:57+0200\n" -"PO-Revision-Date: 2026-02-07 09:12+0200\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:52+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -88,17 +88,27 @@ msgstr "ошибка в %s(): %m" msgid "out of memory" msgstr "нехватка памяти" -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/username.c:43 #, c-format msgid "could not look up effective user ID %ld: %s" @@ -159,12 +169,12 @@ msgstr[0] "(%lu строка)" msgstr[1] "(%lu строки)" msgstr[2] "(%lu строк)" -#: ../../fe_utils/print.c:3154 +#: ../../fe_utils/print.c:3155 #, c-format msgid "Interrupted\n" msgstr "Прервано\n" -#: ../../fe_utils/print.c:3188 +#: ../../fe_utils/print.c:3189 #, c-format msgid "" "Cannot print table contents: number of cells % is equal to or " @@ -173,13 +183,13 @@ msgstr "" "Вывести содержимое таблицы нельзя: число ячеек % достигло максимума " "%zu.\n" -#: ../../fe_utils/print.c:3229 +#: ../../fe_utils/print.c:3230 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "" "Ошибка добавления заголовка таблицы: превышен предел числа столбцов (%d).\n" -#: ../../fe_utils/print.c:3272 +#: ../../fe_utils/print.c:3273 #, c-format msgid "" "Cannot add cell to table content: total cell count of % exceeded.\n" @@ -187,7 +197,7 @@ msgstr "" "Ошибка добавления ячейки в таблицу: превышен предел числа ячеек " "(%).\n" -#: ../../fe_utils/print.c:3530 +#: ../../fe_utils/print.c:3531 #, c-format msgid "invalid output format (internal error): %d" msgstr "неверный формат вывода (внутренняя ошибка): %d" @@ -264,15 +274,15 @@ msgstr "В данный момент вы не подключены к базе msgid "Connection Information" msgstr "Информация о подключении" -#: command.c:840 describe.c:4722 +#: command.c:840 describe.c:4726 msgid "Parameter" msgstr "Параметр" -#: command.c:841 describe.c:4723 +#: command.c:841 describe.c:4727 msgid "Value" msgstr "Значение" -#: command.c:844 describe.c:3874 +#: command.c:844 describe.c:3878 msgid "Database" msgstr "БД" @@ -296,7 +306,7 @@ msgstr "Узел" msgid "Server Port" msgstr "Порт сервера" -#: command.c:882 describe.c:246 describe.c:3615 describe.c:3955 +#: command.c:882 describe.c:246 describe.c:3619 describe.c:3959 msgid "Options" msgstr "Параметры" @@ -384,7 +394,7 @@ msgstr "" #: command.c:1656 command.c:2596 command.c:4074 command.c:4272 command.c:6511 #: common.c:233 common.c:282 common.c:455 common.c:1178 common.c:1196 -#: common.c:1264 common.c:1376 common.c:1414 common.c:1705 common.c:1785 +#: common.c:1264 common.c:1376 common.c:1414 common.c:1718 common.c:1798 #: copy.c:486 copy.c:731 large_obj.c:157 large_obj.c:192 large_obj.c:254 #: startup.c:309 #, c-format @@ -1053,7 +1063,7 @@ msgstr "Время: %.3f мс (%02d:%02d:%06.3f)\n" msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" msgstr "Время: %.3f мс (%.0f д. %02d:%02d:%06.3f)\n" -#: common.c:661 common.c:718 common.c:1130 describe.c:6371 +#: common.c:661 common.c:718 common.c:1130 describe.c:6375 #, c-format msgid "You are currently not connected to a database." msgstr "В данный момент вы не подключены к базе данных." @@ -1119,14 +1129,14 @@ msgstr "ОПЕРАТОР: %s" msgid "unexpected transaction status (%d)" msgstr "неожиданное состояние транзакции (%d)" -#: common.c:1398 describe.c:2064 +#: common.c:1398 describe.c:2068 msgid "Column" msgstr "Столбец" -#: common.c:1399 describe.c:176 describe.c:363 describe.c:381 describe.c:1082 -#: describe.c:1244 describe.c:1774 describe.c:1798 describe.c:2065 -#: describe.c:4058 describe.c:4322 describe.c:4569 describe.c:4729 -#: describe.c:6005 +#: common.c:1399 describe.c:176 describe.c:363 describe.c:381 describe.c:1086 +#: describe.c:1248 describe.c:1778 describe.c:1802 describe.c:2069 +#: describe.c:4062 describe.c:4326 describe.c:4573 describe.c:4733 +#: describe.c:6009 msgid "Type" msgstr "Тип" @@ -1135,22 +1145,22 @@ msgstr "Тип" msgid "The command has no result, or the result has no columns.\n" msgstr "Команда не выдала результат, либо в результате нет столбцов.\n" -#: common.c:1670 +#: common.c:1683 #, c-format msgid "No pending results to get" msgstr "Нет результатов, ожидающих получения" -#: common.c:1748 +#: common.c:1761 #, c-format msgid "fetching results in chunked mode failed" msgstr "получить результаты в блочном режиме не удалось" -#: common.c:1797 +#: common.c:1810 #, c-format msgid "Pipeline aborted, command did not run" msgstr "Конвейерный режим прерван, команда не была выполнена" -#: common.c:1893 +#: common.c:1906 #, c-format msgid "COPY in a pipeline is not supported, aborting connection" msgstr "COPY в конвейерном режиме не поддерживается, соединение прерывается" @@ -1271,21 +1281,21 @@ msgstr "\\crosstabview: неоднозначное имя столбца: \"%s\" msgid "\\crosstabview: column name not found: \"%s\"" msgstr "\\crosstabview: имя столбца не найдено: \"%s\"" -#: describe.c:94 describe.c:343 describe.c:650 describe.c:827 describe.c:1074 -#: describe.c:1231 describe.c:1307 describe.c:4047 describe.c:4309 -#: describe.c:4567 describe.c:4648 describe.c:4880 describe.c:5092 -#: describe.c:5341 describe.c:5582 describe.c:5651 describe.c:5662 -#: describe.c:5718 describe.c:6117 describe.c:6197 +#: describe.c:94 describe.c:343 describe.c:650 describe.c:827 describe.c:1078 +#: describe.c:1235 describe.c:1311 describe.c:4051 describe.c:4313 +#: describe.c:4571 describe.c:4652 describe.c:4884 describe.c:5096 +#: describe.c:5345 describe.c:5586 describe.c:5655 describe.c:5666 +#: describe.c:5722 describe.c:6121 describe.c:6201 msgid "Schema" msgstr "Схема" #: describe.c:95 describe.c:173 describe.c:234 describe.c:344 describe.c:651 -#: describe.c:828 describe.c:959 describe.c:1075 describe.c:1308 -#: describe.c:4048 describe.c:4310 describe.c:4484 describe.c:4568 -#: describe.c:4649 describe.c:4810 describe.c:4881 describe.c:5093 -#: describe.c:5214 describe.c:5342 describe.c:5583 describe.c:5652 -#: describe.c:5663 describe.c:5719 describe.c:5916 describe.c:5986 -#: describe.c:6194 describe.c:6422 describe.c:6768 +#: describe.c:828 describe.c:959 describe.c:1079 describe.c:1312 +#: describe.c:4052 describe.c:4314 describe.c:4488 describe.c:4572 +#: describe.c:4653 describe.c:4814 describe.c:4885 describe.c:5097 +#: describe.c:5218 describe.c:5346 describe.c:5587 describe.c:5656 +#: describe.c:5667 describe.c:5723 describe.c:5920 describe.c:5990 +#: describe.c:6198 describe.c:6426 describe.c:6772 msgid "Name" msgstr "Имя" @@ -1298,13 +1308,13 @@ msgid "Argument data types" msgstr "Типы данных аргументов" #: describe.c:105 describe.c:112 describe.c:184 describe.c:248 describe.c:433 -#: describe.c:682 describe.c:847 describe.c:1011 describe.c:1310 -#: describe.c:2085 describe.c:3774 describe.c:4106 describe.c:4363 -#: describe.c:4508 describe.c:4581 describe.c:4658 describe.c:4823 -#: describe.c:5005 describe.c:5151 describe.c:5223 describe.c:5343 -#: describe.c:5493 describe.c:5534 describe.c:5599 describe.c:5655 -#: describe.c:5664 describe.c:5720 describe.c:5934 describe.c:6008 -#: describe.c:6131 describe.c:6198 describe.c:7304 +#: describe.c:682 describe.c:847 describe.c:1014 describe.c:1314 +#: describe.c:2089 describe.c:3778 describe.c:4110 describe.c:4367 +#: describe.c:4512 describe.c:4585 describe.c:4662 describe.c:4827 +#: describe.c:5009 describe.c:5155 describe.c:5227 describe.c:5347 +#: describe.c:5497 describe.c:5538 describe.c:5603 describe.c:5659 +#: describe.c:5668 describe.c:5724 describe.c:5938 describe.c:6012 +#: describe.c:6135 describe.c:6202 describe.c:7308 msgid "Description" msgstr "Описание" @@ -1321,11 +1331,11 @@ msgstr "Сервер (версия %s) не поддерживает метод msgid "Index" msgstr "Индекс" -#: describe.c:175 describe.c:4066 describe.c:4335 describe.c:6118 +#: describe.c:175 describe.c:4070 describe.c:4339 describe.c:6122 msgid "Table" msgstr "Таблица" -#: describe.c:183 describe.c:5918 +#: describe.c:183 describe.c:5922 msgid "Handler" msgstr "Обработчик" @@ -1333,11 +1343,11 @@ msgstr "Обработчик" msgid "List of access methods" msgstr "Список методов доступа" -#: describe.c:235 describe.c:416 describe.c:675 describe.c:960 describe.c:1230 -#: describe.c:4059 describe.c:4311 describe.c:4485 describe.c:4812 -#: describe.c:5215 describe.c:5917 describe.c:5987 describe.c:6423 -#: describe.c:6644 describe.c:6769 describe.c:6939 describe.c:7024 -#: describe.c:7292 +#: describe.c:235 describe.c:416 describe.c:675 describe.c:960 describe.c:1234 +#: describe.c:4063 describe.c:4315 describe.c:4489 describe.c:4816 +#: describe.c:5219 describe.c:5921 describe.c:5991 describe.c:6427 +#: describe.c:6648 describe.c:6773 describe.c:6943 describe.c:7028 +#: describe.c:7296 msgid "Owner" msgstr "Владелец" @@ -1345,7 +1355,7 @@ msgstr "Владелец" msgid "Location" msgstr "Расположение" -#: describe.c:247 describe.c:673 describe.c:1009 describe.c:4105 +#: describe.c:247 describe.c:673 describe.c:1012 describe.c:4109 msgid "Size" msgstr "Размер" @@ -1382,7 +1392,7 @@ msgstr "проц." msgid "func" msgstr "функ." -#: describe.c:379 describe.c:1440 +#: describe.c:379 describe.c:1444 msgid "trigger" msgstr "триггерная" @@ -1430,19 +1440,19 @@ msgstr "вызывающего" msgid "Security" msgstr "Безопасность" -#: describe.c:420 describe.c:838 describe.c:1779 describe.c:1803 -#: describe.c:1932 describe.c:4652 describe.c:4993 describe.c:5002 -#: describe.c:5140 describe.c:5145 describe.c:6927 describe.c:7126 +#: describe.c:420 describe.c:838 describe.c:1783 describe.c:1807 +#: describe.c:1936 describe.c:4656 describe.c:4997 describe.c:5006 +#: describe.c:5144 describe.c:5149 describe.c:6931 describe.c:7130 msgid "yes" msgstr "да" -#: describe.c:421 describe.c:839 describe.c:1780 describe.c:1804 -#: describe.c:1933 describe.c:4652 describe.c:4990 describe.c:5003 -#: describe.c:5140 describe.c:6928 describe.c:7127 +#: describe.c:421 describe.c:839 describe.c:1784 describe.c:1808 +#: describe.c:1937 describe.c:4656 describe.c:4994 describe.c:5007 +#: describe.c:5144 describe.c:6932 describe.c:7131 msgid "no" msgstr "нет" -#: describe.c:422 describe.c:840 describe.c:5004 describe.c:7128 +#: describe.c:422 describe.c:840 describe.c:5008 describe.c:7132 msgid "Leakproof?" msgstr "Герметичная?" @@ -1478,8 +1488,8 @@ msgstr "Тип правого аргумента" msgid "Result type" msgstr "Результирующий тип" -#: describe.c:837 describe.c:4818 describe.c:4982 describe.c:5492 -#: describe.c:7222 describe.c:7226 +#: describe.c:837 describe.c:4822 describe.c:4986 describe.c:5496 +#: describe.c:7226 describe.c:7230 msgid "Function" msgstr "Функция" @@ -1495,557 +1505,557 @@ msgstr "Кодировка" msgid "Locale Provider" msgstr "Провайдер локали" -#: describe.c:977 describe.c:5112 +#: describe.c:977 describe.c:5116 msgid "Collate" msgstr "LC_COLLATE" -#: describe.c:978 describe.c:5113 +#: describe.c:978 describe.c:5117 msgid "Ctype" msgstr "LC_CTYPE" -#: describe.c:982 describe.c:986 describe.c:990 describe.c:5118 describe.c:5122 -#: describe.c:5126 +#: describe.c:982 describe.c:986 describe.c:990 describe.c:5122 describe.c:5126 +#: describe.c:5130 msgid "Locale" msgstr "Локаль" -#: describe.c:994 describe.c:998 describe.c:5131 describe.c:5135 +#: describe.c:994 describe.c:998 describe.c:5135 describe.c:5139 msgid "ICU Rules" msgstr "Правила ICU" -#: describe.c:1010 +#: describe.c:1013 msgid "Tablespace" msgstr "Табл. пространство" -#: describe.c:1035 +#: describe.c:1039 msgid "List of databases" msgstr "Список баз данных" -#: describe.c:1076 describe.c:1233 describe.c:4049 +#: describe.c:1080 describe.c:1237 describe.c:4053 msgid "table" msgstr "таблица" -#: describe.c:1077 describe.c:4050 +#: describe.c:1081 describe.c:4054 msgid "view" msgstr "представление" -#: describe.c:1078 describe.c:4051 +#: describe.c:1082 describe.c:4055 msgid "materialized view" msgstr "материализованное представление" -#: describe.c:1079 describe.c:1235 describe.c:4053 +#: describe.c:1083 describe.c:1239 describe.c:4057 msgid "sequence" msgstr "последовательность" -#: describe.c:1080 describe.c:4055 +#: describe.c:1084 describe.c:4059 msgid "foreign table" msgstr "сторонняя таблица" -#: describe.c:1081 describe.c:4056 describe.c:4320 +#: describe.c:1085 describe.c:4060 describe.c:4324 msgid "partitioned table" msgstr "секционированная таблица" -#: describe.c:1097 +#: describe.c:1101 msgid "Column privileges" msgstr "Права для столбцов" -#: describe.c:1128 describe.c:1162 +#: describe.c:1132 describe.c:1166 msgid "Policies" msgstr "Политики" -#: describe.c:1190 describe.c:4735 describe.c:6884 +#: describe.c:1194 describe.c:4739 describe.c:6888 msgid "Access privileges" msgstr "Права доступа" -#: describe.c:1237 +#: describe.c:1241 msgid "function" msgstr "функция" -#: describe.c:1239 +#: describe.c:1243 msgid "type" msgstr "тип" -#: describe.c:1241 +#: describe.c:1245 msgid "schema" msgstr "схема" -#: describe.c:1243 +#: describe.c:1247 msgid "large object" msgstr "большой объект" -#: describe.c:1265 +#: describe.c:1269 msgid "Default access privileges" msgstr "Права доступа по умолчанию" -#: describe.c:1309 +#: describe.c:1313 msgid "Object" msgstr "Объект" -#: describe.c:1323 +#: describe.c:1327 msgid "table constraint" msgstr "ограничение таблицы" -#: describe.c:1347 +#: describe.c:1351 msgid "domain constraint" msgstr "ограничение домена" -#: describe.c:1371 +#: describe.c:1375 msgid "operator class" msgstr "класс операторов" -#: describe.c:1395 +#: describe.c:1399 msgid "operator family" msgstr "семейство операторов" -#: describe.c:1418 +#: describe.c:1422 msgid "rule" msgstr "правило" -#: describe.c:1463 +#: describe.c:1467 msgid "Object descriptions" msgstr "Описание объекта" -#: describe.c:1528 +#: describe.c:1532 #, c-format msgid "Did not find any relation named \"%s\"." msgstr "Отношение \"%s\" не найдено." -#: describe.c:1531 describe.c:4207 +#: describe.c:1535 describe.c:4211 #, c-format msgid "Did not find any relations." msgstr "Отношения не найдены." -#: describe.c:1727 +#: describe.c:1731 #, c-format msgid "Did not find any relation with OID %s." msgstr "Отношение с OID %s не найдено." -#: describe.c:1775 describe.c:1799 +#: describe.c:1779 describe.c:1803 msgid "Start" msgstr "Начальное_значение" -#: describe.c:1776 describe.c:1800 +#: describe.c:1780 describe.c:1804 msgid "Minimum" msgstr "Минимум" -#: describe.c:1777 describe.c:1801 +#: describe.c:1781 describe.c:1805 msgid "Maximum" msgstr "Максимум" -#: describe.c:1778 describe.c:1802 +#: describe.c:1782 describe.c:1806 msgid "Increment" msgstr "Шаг" -#: describe.c:1781 describe.c:1805 +#: describe.c:1785 describe.c:1809 msgid "Cycles?" msgstr "Зацикливается?" -#: describe.c:1782 describe.c:1806 +#: describe.c:1786 describe.c:1810 msgid "Cache" msgstr "Кешируется" -#: describe.c:1847 +#: describe.c:1851 #, c-format msgid "Owned by: %s" msgstr "Владелец: %s" -#: describe.c:1851 +#: describe.c:1855 #, c-format msgid "Sequence for identity column: %s" msgstr "Последовательность для столбца идентификации: %s" -#: describe.c:1859 +#: describe.c:1863 #, c-format msgid "Unlogged sequence \"%s.%s\"" msgstr "Нежурналируемая последовательность \"%s.%s\"" -#: describe.c:1862 +#: describe.c:1866 #, c-format msgid "Sequence \"%s.%s\"" msgstr "Последовательность \"%s.%s\"" -#: describe.c:2005 +#: describe.c:2009 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "Нежурналируемая таблица \"%s.%s\"" -#: describe.c:2008 +#: describe.c:2012 #, c-format msgid "Table \"%s.%s\"" msgstr "Таблица \"%s.%s\"" -#: describe.c:2012 +#: describe.c:2016 #, c-format msgid "View \"%s.%s\"" msgstr "Представление \"%s.%s\"" -#: describe.c:2016 +#: describe.c:2020 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "Материализованное представление \"%s.%s\"" -#: describe.c:2021 +#: describe.c:2025 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "Нежурналируемый индекс \"%s.%s\"" -#: describe.c:2024 +#: describe.c:2028 #, c-format msgid "Index \"%s.%s\"" msgstr "Индекс \"%s.%s\"" -#: describe.c:2029 +#: describe.c:2033 #, c-format msgid "Unlogged partitioned index \"%s.%s\"" msgstr "Нежурналируемый секционированный индекс \"%s.%s\"" -#: describe.c:2032 +#: describe.c:2036 #, c-format msgid "Partitioned index \"%s.%s\"" msgstr "Секционированный индекс \"%s.%s\"" -#: describe.c:2036 +#: describe.c:2040 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "TOAST-таблица \"%s.%s\"" -#: describe.c:2040 +#: describe.c:2044 #, c-format msgid "Composite type \"%s.%s\"" msgstr "Составной тип \"%s.%s\"" -#: describe.c:2044 +#: describe.c:2048 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "Сторонняя таблица \"%s.%s\"" -#: describe.c:2049 +#: describe.c:2053 #, c-format msgid "Unlogged partitioned table \"%s.%s\"" msgstr "Нежурналируемая секционированная таблица \"%s.%s\"" -#: describe.c:2052 +#: describe.c:2056 #, c-format msgid "Partitioned table \"%s.%s\"" msgstr "Секционированная таблица \"%s.%s\"" -#: describe.c:2068 describe.c:4570 +#: describe.c:2072 describe.c:4574 msgid "Collation" msgstr "Правило сортировки" -#: describe.c:2069 describe.c:4571 +#: describe.c:2073 describe.c:4575 msgid "Nullable" msgstr "Допустимость NULL" -#: describe.c:2070 describe.c:4572 +#: describe.c:2074 describe.c:4576 msgid "Default" msgstr "По умолчанию" -#: describe.c:2073 +#: describe.c:2077 msgid "Key?" msgstr "Ключевой?" -#: describe.c:2075 describe.c:4888 describe.c:4899 +#: describe.c:2079 describe.c:4892 describe.c:4903 msgid "Definition" msgstr "Определение" # well-spelled: ОСД -#: describe.c:2077 describe.c:5933 describe.c:6007 describe.c:6072 -#: describe.c:6130 +#: describe.c:2081 describe.c:5937 describe.c:6011 describe.c:6076 +#: describe.c:6134 msgid "FDW options" msgstr "Параметры ОСД" -#: describe.c:2079 +#: describe.c:2083 msgid "Storage" msgstr "Хранилище" -#: describe.c:2081 +#: describe.c:2085 msgid "Compression" msgstr "Сжатие" -#: describe.c:2083 +#: describe.c:2087 msgid "Stats target" msgstr "Цель для статистики" -#: describe.c:2225 +#: describe.c:2229 #, c-format msgid "Partition of: %s %s%s" msgstr "Секция: %s %s%s" -#: describe.c:2238 +#: describe.c:2242 msgid "No partition constraint" msgstr "Нет ограничения секции" -#: describe.c:2240 +#: describe.c:2244 #, c-format msgid "Partition constraint: %s" msgstr "Ограничение секции: %s" -#: describe.c:2264 +#: describe.c:2268 #, c-format msgid "Partition key: %s" msgstr "Ключ разбиения: %s" -#: describe.c:2290 +#: describe.c:2294 #, c-format msgid "Owning table: \"%s.%s\"" msgstr "Принадлежит таблице: \"%s.%s\"" -#: describe.c:2363 +#: describe.c:2367 msgid "primary key, " msgstr "первичный ключ, " -#: describe.c:2366 +#: describe.c:2370 msgid "unique" msgstr "уникальный" -#: describe.c:2368 +#: describe.c:2372 msgid " nulls not distinct" msgstr " null не различаются" -#: describe.c:2369 +#: describe.c:2373 msgid ", " msgstr ", " -#: describe.c:2376 +#: describe.c:2380 #, c-format msgid "for table \"%s.%s\"" msgstr "для таблицы \"%s.%s\"" -#: describe.c:2380 +#: describe.c:2384 #, c-format msgid ", predicate (%s)" msgstr ", предикат (%s)" -#: describe.c:2383 +#: describe.c:2387 msgid ", clustered" msgstr ", кластеризованный" -#: describe.c:2386 +#: describe.c:2390 msgid ", invalid" msgstr ", нерабочий" -#: describe.c:2389 +#: describe.c:2393 msgid ", deferrable" msgstr ", откладываемый" -#: describe.c:2392 +#: describe.c:2396 msgid ", initially deferred" msgstr ", изначально отложенный" -#: describe.c:2395 +#: describe.c:2399 msgid ", replica identity" msgstr ", репликационный" -#: describe.c:2456 +#: describe.c:2460 msgid "Indexes:" msgstr "Индексы:" -#: describe.c:2544 +#: describe.c:2548 msgid "Check constraints:" msgstr "Ограничения-проверки:" # TO REWVIEW -#: describe.c:2605 +#: describe.c:2609 msgid "Foreign-key constraints:" msgstr "Ограничения внешнего ключа:" -#: describe.c:2664 +#: describe.c:2668 msgid "Referenced by:" msgstr "Ссылки извне:" -#: describe.c:2713 +#: describe.c:2717 msgid "Policies:" msgstr "Политики:" -#: describe.c:2716 +#: describe.c:2720 msgid "Policies (forced row security enabled):" msgstr "Политики (усиленная защита строк включена):" -#: describe.c:2719 +#: describe.c:2723 msgid "Policies (row security enabled): (none)" msgstr "Политики (защита строк включена): (Нет)" -#: describe.c:2722 +#: describe.c:2726 msgid "Policies (forced row security enabled): (none)" msgstr "Политики (усиленная защита строк включена): (Нет)" -#: describe.c:2725 +#: describe.c:2729 msgid "Policies (row security disabled):" msgstr "Политики (защита строк выключена):" -#: describe.c:2785 describe.c:2890 +#: describe.c:2789 describe.c:2894 msgid "Statistics objects:" msgstr "Объекты статистики:" -#: describe.c:2992 describe.c:3192 +#: describe.c:2996 describe.c:3196 msgid "Rules:" msgstr "Правила:" -#: describe.c:2995 +#: describe.c:2999 msgid "Disabled rules:" msgstr "Отключённые правила:" -#: describe.c:2998 +#: describe.c:3002 msgid "Rules firing always:" msgstr "Правила, срабатывающие всегда:" -#: describe.c:3001 +#: describe.c:3005 msgid "Rules firing on replica only:" msgstr "Правила, срабатывающие только в реплике:" -#: describe.c:3080 describe.c:5276 +#: describe.c:3084 describe.c:5280 msgid "Publications:" msgstr "Публикации:" -#: describe.c:3127 +#: describe.c:3131 msgid "Not-null constraints:" msgstr "Ограничения NOT NULL:" -#: describe.c:3141 +#: describe.c:3145 msgid " (local, inherited)" msgstr " (локальное, не наследуется)" -#: describe.c:3142 +#: describe.c:3146 msgid " (inherited)" msgstr " (наследуется)" -#: describe.c:3175 +#: describe.c:3179 msgid "View definition:" msgstr "Определение представления:" -#: describe.c:3338 +#: describe.c:3342 msgid "Triggers:" msgstr "Триггеры:" -#: describe.c:3341 +#: describe.c:3345 msgid "Disabled user triggers:" msgstr "Отключённые пользовательские триггеры:" -#: describe.c:3344 +#: describe.c:3348 msgid "Disabled internal triggers:" msgstr "Отключённые внутренние триггеры:" -#: describe.c:3347 +#: describe.c:3351 msgid "Triggers firing always:" msgstr "Триггеры, срабатывающие всегда:" -#: describe.c:3350 +#: describe.c:3354 msgid "Triggers firing on replica only:" msgstr "Триггеры, срабатывающие только в реплике:" -#: describe.c:3421 +#: describe.c:3425 #, c-format msgid "Server: %s" msgstr "Сервер: %s" # well-spelled: ОСД -#: describe.c:3429 +#: describe.c:3433 #, c-format msgid "FDW options: (%s)" msgstr "Параметр ОСД: (%s)" -#: describe.c:3450 +#: describe.c:3454 msgid "Inherits" msgstr "Наследует" -#: describe.c:3515 +#: describe.c:3519 #, c-format msgid "Number of partitions: %d" msgstr "Число секций: %d" -#: describe.c:3524 +#: describe.c:3528 #, c-format msgid "Number of partitions: %d (Use \\d+ to list them.)" msgstr "Число секций: %d (чтобы просмотреть их, введите \\d+)" -#: describe.c:3526 +#: describe.c:3530 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "Дочерних таблиц: %d (чтобы просмотреть и их, воспользуйтесь \\d+)" -#: describe.c:3533 +#: describe.c:3537 msgid "Child tables" msgstr "Дочерние таблицы" -#: describe.c:3533 +#: describe.c:3537 msgid "Partitions" msgstr "Секции" -#: describe.c:3566 +#: describe.c:3570 #, c-format msgid "Typed table of type: %s" msgstr "Типизированная таблица типа: %s" -#: describe.c:3584 +#: describe.c:3588 msgid "Replica Identity" msgstr "Идентификация реплики" -#: describe.c:3597 +#: describe.c:3601 msgid "Has OIDs: yes" msgstr "Содержит OID: да" -#: describe.c:3606 +#: describe.c:3610 #, c-format msgid "Access method: %s" msgstr "Метод доступа: %s" -#: describe.c:3683 +#: describe.c:3687 #, c-format msgid "Tablespace: \"%s\"" msgstr "Табличное пространство: \"%s\"" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:3695 +#: describe.c:3699 #, c-format msgid ", tablespace \"%s\"" msgstr ", табл. пространство \"%s\"" -#: describe.c:3768 +#: describe.c:3772 msgid "List of roles" msgstr "Список ролей" -#: describe.c:3770 describe.c:3938 +#: describe.c:3774 describe.c:3942 msgid "Role name" msgstr "Имя роли" -#: describe.c:3771 +#: describe.c:3775 msgid "Attributes" msgstr "Атрибуты" -#: describe.c:3782 +#: describe.c:3786 msgid "Superuser" msgstr "Суперпользователь" -#: describe.c:3785 +#: describe.c:3789 msgid "No inheritance" msgstr "Не наследуется" -#: describe.c:3788 +#: describe.c:3792 msgid "Create role" msgstr "Создаёт роли" -#: describe.c:3791 +#: describe.c:3795 msgid "Create DB" msgstr "Создаёт БД" -#: describe.c:3794 +#: describe.c:3798 msgid "Cannot login" msgstr "Вход запрещён" -#: describe.c:3797 +#: describe.c:3801 msgid "Replication" msgstr "Репликация" -#: describe.c:3801 +#: describe.c:3805 msgid "Bypass RLS" msgstr "Пропускать RLS" -#: describe.c:3810 +#: describe.c:3814 msgid "No connections" msgstr "Нет подключений" -#: describe.c:3812 +#: describe.c:3816 #, c-format msgid "%d connection" msgid_plural "%d connections" @@ -2053,478 +2063,478 @@ msgstr[0] "%d подключение" msgstr[1] "%d подключения" msgstr[2] "%d подключений" -#: describe.c:3822 +#: describe.c:3826 msgid "Password valid until " msgstr "Пароль действует до " -#: describe.c:3873 +#: describe.c:3877 msgid "Role" msgstr "Роль" -#: describe.c:3875 +#: describe.c:3879 msgid "Settings" msgstr "Параметры" -#: describe.c:3899 +#: describe.c:3903 #, c-format msgid "Did not find any settings for role \"%s\" and database \"%s\"." msgstr "Параметры для роли \"%s\" и базы данных \"%s\" не найдены." -#: describe.c:3902 +#: describe.c:3906 #, c-format msgid "Did not find any settings for role \"%s\"." msgstr "Параметры для роли \"%s\" не найдены." -#: describe.c:3905 +#: describe.c:3909 #, c-format msgid "Did not find any settings." msgstr "Никакие параметры не найдены." -#: describe.c:3909 +#: describe.c:3913 msgid "List of settings" msgstr "Список параметров" -#: describe.c:3939 +#: describe.c:3943 msgid "Member of" msgstr "Член ролей" -#: describe.c:3956 +#: describe.c:3960 msgid "Grantor" msgstr "Праводатель" -#: describe.c:3982 +#: describe.c:3986 msgid "List of role grants" msgstr "Список назначений ролей" -#: describe.c:4052 +#: describe.c:4056 msgid "index" msgstr "индекс" -#: describe.c:4054 +#: describe.c:4058 msgid "TOAST table" msgstr "TOAST-таблица" -#: describe.c:4057 describe.c:4321 +#: describe.c:4061 describe.c:4325 msgid "partitioned index" msgstr "секционированный индекс" -#: describe.c:4081 +#: describe.c:4085 msgid "permanent" msgstr "постоянное" -#: describe.c:4082 +#: describe.c:4086 msgid "temporary" msgstr "временное" -#: describe.c:4083 +#: describe.c:4087 msgid "unlogged" msgstr "нежурналируемое" -#: describe.c:4084 +#: describe.c:4088 msgid "Persistence" msgstr "Хранение" -#: describe.c:4100 describe.c:4344 +#: describe.c:4104 describe.c:4348 msgid "Access method" msgstr "Метод доступа" -#: describe.c:4180 +#: describe.c:4184 #, c-format msgid "Did not find any relations named \"%s\"." msgstr "Отношения с именем \"%s\" не найдены." -#: describe.c:4183 +#: describe.c:4187 #, c-format msgid "Did not find any tables named \"%s\"." msgstr "Таблицы с именем \"%s\" не найдены." -#: describe.c:4186 +#: describe.c:4190 #, c-format msgid "Did not find any indexes named \"%s\"." msgstr "Индексы с именем \"%s\" не найдены." -#: describe.c:4189 +#: describe.c:4193 #, c-format msgid "Did not find any views named \"%s\"." msgstr "Представления с именем \"%s\" не найдены." -#: describe.c:4192 +#: describe.c:4196 #, c-format msgid "Did not find any materialized views named \"%s\"." msgstr "Материализованные представления с именем \"%s\" не найдены." -#: describe.c:4195 +#: describe.c:4199 #, c-format msgid "Did not find any sequences named \"%s\"." msgstr "Последовательности с именем \"%s\" не найдены." -#: describe.c:4198 +#: describe.c:4202 #, c-format msgid "Did not find any foreign tables named \"%s\"." msgstr "Сторонние таблицы с именем \"%s\" не найдены." -#: describe.c:4209 +#: describe.c:4213 #, c-format msgid "Did not find any tables." msgstr "Никакие таблицы не найдены." -#: describe.c:4211 +#: describe.c:4215 #, c-format msgid "Did not find any indexes." msgstr "Никакие индексы не найдены." -#: describe.c:4213 +#: describe.c:4217 #, c-format msgid "Did not find any views." msgstr "Никакие представления не найдены." -#: describe.c:4215 +#: describe.c:4219 #, c-format msgid "Did not find any materialized views." msgstr "Никакие материализованные представления не найдены." -#: describe.c:4217 +#: describe.c:4221 #, c-format msgid "Did not find any sequences." msgstr "Никакие последовательности не найдены." -#: describe.c:4219 +#: describe.c:4223 #, c-format msgid "Did not find any foreign tables." msgstr "Никакие сторонние таблицы не найдены." -#: describe.c:4227 +#: describe.c:4231 msgid "List of relations" msgstr "Список отношений" -#: describe.c:4228 +#: describe.c:4232 msgid "List of tables" msgstr "Список таблиц" -#: describe.c:4229 +#: describe.c:4233 msgid "List of indexes" msgstr "Список индексов" -#: describe.c:4230 +#: describe.c:4234 msgid "List of views" msgstr "Список представлений" -#: describe.c:4231 +#: describe.c:4235 msgid "List of materialized views" msgstr "Список материализованных представлений" -#: describe.c:4232 +#: describe.c:4236 msgid "List of sequences" msgstr "Список последовательностей" -#: describe.c:4233 describe.c:6163 +#: describe.c:4237 describe.c:6167 msgid "List of foreign tables" msgstr "Список сторонних таблиц" -#: describe.c:4282 +#: describe.c:4286 #, c-format msgid "" "The server (version %s) does not support declarative table partitioning." msgstr "" "Сервер (версия %s) не поддерживает декларативное секционирование таблиц." -#: describe.c:4293 +#: describe.c:4297 msgid "List of partitioned indexes" msgstr "Список секционированных индексов" -#: describe.c:4295 +#: describe.c:4299 msgid "List of partitioned tables" msgstr "Список секционированных таблиц" -#: describe.c:4299 +#: describe.c:4303 msgid "List of partitioned relations" msgstr "Список секционированных отношений" -#: describe.c:4330 +#: describe.c:4334 msgid "Parent name" msgstr "Имя родителя" -#: describe.c:4350 +#: describe.c:4354 msgid "Leaf partition size" msgstr "Размер конечной секции" -#: describe.c:4353 describe.c:4359 +#: describe.c:4357 describe.c:4363 msgid "Total size" msgstr "Общий размер" -#: describe.c:4486 +#: describe.c:4490 msgid "Trusted" msgstr "Доверенный" -#: describe.c:4495 +#: describe.c:4499 msgid "Internal language" msgstr "Внутренний язык" -#: describe.c:4496 +#: describe.c:4500 msgid "Call handler" msgstr "Обработчик вызова" -#: describe.c:4497 describe.c:5919 +#: describe.c:4501 describe.c:5923 msgid "Validator" msgstr "Функция проверки" -#: describe.c:4498 +#: describe.c:4502 msgid "Inline handler" msgstr "Обработчик внедрённого кода" -#: describe.c:4532 +#: describe.c:4536 msgid "List of languages" msgstr "Список языков" -#: describe.c:4573 +#: describe.c:4577 msgid "Check" msgstr "Проверка" -#: describe.c:4616 +#: describe.c:4620 msgid "List of domains" msgstr "Список доменов" -#: describe.c:4650 +#: describe.c:4654 msgid "Source" msgstr "Источник" -#: describe.c:4651 +#: describe.c:4655 msgid "Destination" msgstr "Назначение" -#: describe.c:4653 describe.c:6929 +#: describe.c:4657 describe.c:6933 msgid "Default?" msgstr "По умолчанию?" -#: describe.c:4694 +#: describe.c:4698 msgid "List of conversions" msgstr "Список преобразований" -#: describe.c:4730 +#: describe.c:4734 msgid "Context" msgstr "Контекст" -#: describe.c:4762 +#: describe.c:4766 msgid "List of configuration parameters" msgstr "Список параметров конфигурации" -#: describe.c:4764 +#: describe.c:4768 msgid "List of non-default configuration parameters" msgstr "Список изменённых параметров конфигурации" -#: describe.c:4791 +#: describe.c:4795 #, c-format msgid "The server (version %s) does not support event triggers." msgstr "Сервер (версия %s) не поддерживает событийные триггеры." -#: describe.c:4811 +#: describe.c:4815 msgid "Event" msgstr "Событие" -#: describe.c:4813 +#: describe.c:4817 msgid "enabled" msgstr "включён" -#: describe.c:4814 +#: describe.c:4818 msgid "replica" msgstr "реплика" -#: describe.c:4815 +#: describe.c:4819 msgid "always" msgstr "всегда" -#: describe.c:4816 +#: describe.c:4820 msgid "disabled" msgstr "отключён" -#: describe.c:4817 describe.c:6770 +#: describe.c:4821 describe.c:6774 msgid "Enabled" msgstr "Включён" -#: describe.c:4819 +#: describe.c:4823 msgid "Tags" msgstr "Теги" -#: describe.c:4842 +#: describe.c:4846 msgid "List of event triggers" msgstr "Список событийных триггеров" -#: describe.c:4869 +#: describe.c:4873 #, c-format msgid "The server (version %s) does not support extended statistics." msgstr "Сервер (версия %s) не поддерживает расширенные статистики." -#: describe.c:4906 +#: describe.c:4910 msgid "Ndistinct" msgstr "Ndistinct" -#: describe.c:4907 +#: describe.c:4911 msgid "Dependencies" msgstr "Зависимости" -#: describe.c:4917 +#: describe.c:4921 msgid "MCV" msgstr "MCV" -#: describe.c:4940 +#: describe.c:4944 msgid "List of extended statistics" msgstr "Список расширенных статистик" -#: describe.c:4967 +#: describe.c:4971 msgid "Source type" msgstr "Исходный тип" -#: describe.c:4968 +#: describe.c:4972 msgid "Target type" msgstr "Целевой тип" -#: describe.c:4992 +#: describe.c:4996 msgid "in assignment" msgstr "в присваивании" -#: describe.c:4994 +#: describe.c:4998 msgid "Implicit?" msgstr "Неявное?" -#: describe.c:5058 +#: describe.c:5062 msgid "List of casts" msgstr "Список приведений типов" -#: describe.c:5103 describe.c:5107 +#: describe.c:5107 describe.c:5111 msgid "Provider" msgstr "Провайдер" -#: describe.c:5141 describe.c:5146 +#: describe.c:5145 describe.c:5150 msgid "Deterministic?" msgstr "Детерминированное?" -#: describe.c:5185 +#: describe.c:5189 msgid "List of collations" msgstr "Список правил сортировки" -#: describe.c:5246 +#: describe.c:5250 msgid "List of schemas" msgstr "Список схем" -#: describe.c:5362 +#: describe.c:5366 msgid "List of text search parsers" msgstr "Список анализаторов текстового поиска" -#: describe.c:5412 +#: describe.c:5416 #, c-format msgid "Did not find any text search parser named \"%s\"." msgstr "Анализатор текстового поиска \"%s\" не найден." -#: describe.c:5415 +#: describe.c:5419 #, c-format msgid "Did not find any text search parsers." msgstr "Никакие анализаторы текстового поиска не найдены." -#: describe.c:5490 +#: describe.c:5494 msgid "Start parse" msgstr "Начало разбора" -#: describe.c:5491 +#: describe.c:5495 msgid "Method" msgstr "Метод" -#: describe.c:5495 +#: describe.c:5499 msgid "Get next token" msgstr "Получение следующего фрагмента" -#: describe.c:5497 +#: describe.c:5501 msgid "End parse" msgstr "Окончание разбора" -#: describe.c:5499 +#: describe.c:5503 msgid "Get headline" msgstr "Получение выдержки" -#: describe.c:5501 +#: describe.c:5505 msgid "Get token types" msgstr "Получение типов фрагментов" -#: describe.c:5511 +#: describe.c:5515 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "Анализатор текстового поиска \"%s.%s\"" -#: describe.c:5514 +#: describe.c:5518 #, c-format msgid "Text search parser \"%s\"" msgstr "Анализатор текстового поиска \"%s\"" -#: describe.c:5533 +#: describe.c:5537 msgid "Token name" msgstr "Имя фрагмента" -#: describe.c:5546 +#: describe.c:5550 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "Типы фрагментов для анализатора \"%s.%s\"" -#: describe.c:5549 +#: describe.c:5553 #, c-format msgid "Token types for parser \"%s\"" msgstr "Типы фрагментов для анализатора \"%s\"" -#: describe.c:5593 +#: describe.c:5597 msgid "Template" msgstr "Шаблон" -#: describe.c:5594 +#: describe.c:5598 msgid "Init options" msgstr "Параметры инициализации" -#: describe.c:5620 +#: describe.c:5624 msgid "List of text search dictionaries" msgstr "Список словарей текстового поиска" -#: describe.c:5653 +#: describe.c:5657 msgid "Init" msgstr "Инициализация" -#: describe.c:5654 +#: describe.c:5658 msgid "Lexize" msgstr "Выделение лексем" -#: describe.c:5685 +#: describe.c:5689 msgid "List of text search templates" msgstr "Список шаблонов текстового поиска" -#: describe.c:5739 +#: describe.c:5743 msgid "List of text search configurations" msgstr "Список конфигураций текстового поиска" -#: describe.c:5790 +#: describe.c:5794 #, c-format msgid "Did not find any text search configuration named \"%s\"." msgstr "Конфигурация текстового поиска \"%s\" не найдена." -#: describe.c:5793 +#: describe.c:5797 #, c-format msgid "Did not find any text search configurations." msgstr "Никакие конфигурации текстового поиска не найдены." -#: describe.c:5859 +#: describe.c:5863 msgid "Token" msgstr "Фрагмент" -#: describe.c:5860 +#: describe.c:5864 msgid "Dictionaries" msgstr "Словари" -#: describe.c:5871 +#: describe.c:5875 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "Конфигурация текстового поиска \"%s.%s\"" -#: describe.c:5874 +#: describe.c:5878 #, c-format msgid "Text search configuration \"%s\"" msgstr "Конфигурация текстового поиска \"%s\"" -#: describe.c:5878 +#: describe.c:5882 #, c-format msgid "" "\n" @@ -2533,7 +2543,7 @@ msgstr "" "\n" "Анализатор: \"%s.%s\"" -#: describe.c:5881 +#: describe.c:5885 #, c-format msgid "" "\n" @@ -2542,273 +2552,273 @@ msgstr "" "\n" "Анализатор: \"%s\"" -#: describe.c:5960 +#: describe.c:5964 msgid "List of foreign-data wrappers" msgstr "Список обёрток сторонних данных" -#: describe.c:5988 +#: describe.c:5992 msgid "Foreign-data wrapper" msgstr "Обёртка сторонних данных" -#: describe.c:6006 describe.c:6195 +#: describe.c:6010 describe.c:6199 msgid "Version" msgstr "Версия" -#: describe.c:6036 +#: describe.c:6040 msgid "List of foreign servers" msgstr "Список сторонних серверов" -#: describe.c:6061 describe.c:6119 +#: describe.c:6065 describe.c:6123 msgid "Server" msgstr "Сервер" -#: describe.c:6062 +#: describe.c:6066 msgid "User name" msgstr "Имя пользователя" -#: describe.c:6091 +#: describe.c:6095 msgid "List of user mappings" msgstr "Список сопоставлений пользователей" -#: describe.c:6196 +#: describe.c:6200 msgid "Default version" msgstr "Версия по умолчанию" -#: describe.c:6217 +#: describe.c:6221 msgid "List of installed extensions" msgstr "Список установленных расширений" -#: describe.c:6265 +#: describe.c:6269 #, c-format msgid "Did not find any extension named \"%s\"." msgstr "Расширение \"%s\" не найдено." -#: describe.c:6268 +#: describe.c:6272 #, c-format msgid "Did not find any extensions." msgstr "Никакие расширения не найдены." -#: describe.c:6312 +#: describe.c:6316 msgid "Object description" msgstr "Описание объекта" -#: describe.c:6321 +#: describe.c:6325 #, c-format msgid "Objects in extension \"%s\"" msgstr "Объекты в расширении \"%s\"" -#: describe.c:6362 +#: describe.c:6366 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "неверное полное имя (слишком много компонентов): %s" -#: describe.c:6376 +#: describe.c:6380 #, c-format msgid "cross-database references are not implemented: %s" msgstr "ссылки между базами не реализованы: %s" -#: describe.c:6407 describe.c:6543 +#: describe.c:6411 describe.c:6547 #, c-format msgid "The server (version %s) does not support publications." msgstr "Сервер (версия %s) не поддерживает публикации." -#: describe.c:6424 describe.c:6645 +#: describe.c:6428 describe.c:6649 msgid "All tables" msgstr "Все таблицы" -#: describe.c:6425 describe.c:6646 +#: describe.c:6429 describe.c:6650 msgid "Inserts" msgstr "Добавления" -#: describe.c:6426 describe.c:6647 +#: describe.c:6430 describe.c:6651 msgid "Updates" msgstr "Изменения" -#: describe.c:6427 describe.c:6648 +#: describe.c:6431 describe.c:6652 msgid "Deletes" msgstr "Удаления" -#: describe.c:6431 describe.c:6650 +#: describe.c:6435 describe.c:6654 msgid "Truncates" msgstr "Опустошения" -#: describe.c:6440 describe.c:6574 describe.c:6652 +#: describe.c:6444 describe.c:6578 describe.c:6656 msgid "Generated columns" msgstr "Генерируемые столбцы" -#: describe.c:6444 describe.c:6654 +#: describe.c:6448 describe.c:6658 msgid "Via root" msgstr "Через корень" -#: describe.c:6465 +#: describe.c:6469 msgid "List of publications" msgstr "Список публикаций" -#: describe.c:6612 +#: describe.c:6616 #, c-format msgid "Did not find any publication named \"%s\"." msgstr "Публикация \"%s\" не найдена." -#: describe.c:6615 +#: describe.c:6619 #, c-format msgid "Did not find any publications." msgstr "Никакие публикации не найдены." -#: describe.c:6641 +#: describe.c:6645 #, c-format msgid "Publication %s" msgstr "Публикация %s" -#: describe.c:6698 +#: describe.c:6702 msgid "Tables:" msgstr "Таблицы:" -#: describe.c:6710 +#: describe.c:6714 msgid "Tables from schemas:" msgstr "Таблицы из схем:" -#: describe.c:6755 +#: describe.c:6759 #, c-format msgid "The server (version %s) does not support subscriptions." msgstr "Сервер (версия %s) не поддерживает подписки." -#: describe.c:6771 +#: describe.c:6775 msgid "Publication" msgstr "Публикация" -#: describe.c:6780 +#: describe.c:6784 msgid "Binary" msgstr "Бинарная" -#: describe.c:6789 describe.c:6793 +#: describe.c:6793 describe.c:6797 msgid "Streaming" msgstr "Потоковая" -#: describe.c:6801 +#: describe.c:6805 msgid "Two-phase commit" msgstr "Двухфазная фиксация" -#: describe.c:6802 +#: describe.c:6806 msgid "Disable on error" msgstr "Отключается при ошибке" -#: describe.c:6809 +#: describe.c:6813 msgid "Origin" msgstr "Источник" -#: describe.c:6810 +#: describe.c:6814 msgid "Password required" msgstr "Требуется пароль" -#: describe.c:6811 +#: describe.c:6815 msgid "Run as owner?" msgstr "Использовать владельца?" -#: describe.c:6816 +#: describe.c:6820 msgid "Failover" msgstr "Переносимая" -#: describe.c:6821 +#: describe.c:6825 msgid "Synchronous commit" msgstr "Синхронная фиксация" -#: describe.c:6822 +#: describe.c:6826 msgid "Conninfo" msgstr "Строка подключения" -#: describe.c:6828 +#: describe.c:6832 msgid "Skip LSN" msgstr "Пропустить LSN" -#: describe.c:6854 +#: describe.c:6858 msgid "List of subscriptions" msgstr "Список подписок" -#: describe.c:6883 +#: describe.c:6887 msgid "(none)" msgstr "(нет)" -#: describe.c:6923 describe.c:7018 describe.c:7110 describe.c:7213 +#: describe.c:6927 describe.c:7022 describe.c:7114 describe.c:7217 msgid "AM" msgstr "МД" -#: describe.c:6924 +#: describe.c:6928 msgid "Input type" msgstr "Входной тип" -#: describe.c:6925 +#: describe.c:6929 msgid "Storage type" msgstr "Тип хранения" -#: describe.c:6926 +#: describe.c:6930 msgid "Operator class" msgstr "Класс операторов" -#: describe.c:6938 describe.c:7019 describe.c:7111 describe.c:7214 +#: describe.c:6942 describe.c:7023 describe.c:7115 describe.c:7218 msgid "Operator family" msgstr "Семейство операторов" -#: describe.c:6973 +#: describe.c:6977 msgid "List of operator classes" msgstr "Список классов операторов" -#: describe.c:7020 +#: describe.c:7024 msgid "Applicable types" msgstr "Применимые типы" -#: describe.c:7061 +#: describe.c:7065 msgid "List of operator families" msgstr "Список семейств операторов" -#: describe.c:7112 +#: describe.c:7116 msgid "Operator" msgstr "Оператор" -#: describe.c:7113 +#: describe.c:7117 msgid "Strategy" msgstr "Стратегия" -#: describe.c:7114 +#: describe.c:7118 msgid "ordering" msgstr "сортировка" -#: describe.c:7115 +#: describe.c:7119 msgid "search" msgstr "поиск" -#: describe.c:7116 +#: describe.c:7120 msgid "Purpose" msgstr "Назначение" -#: describe.c:7125 +#: describe.c:7129 msgid "Sort opfamily" msgstr "Семейство для сортировки" -#: describe.c:7168 +#: describe.c:7172 msgid "List of operators of operator families" msgstr "Список операторов из семейств операторов" -#: describe.c:7215 +#: describe.c:7219 msgid "Registered left type" msgstr "Зарегистрированный левый тип" -#: describe.c:7216 +#: describe.c:7220 msgid "Registered right type" msgstr "Зарегистрированный правый тип" -#: describe.c:7217 +#: describe.c:7221 msgid "Number" msgstr "Номер" -#: describe.c:7260 +#: describe.c:7264 msgid "List of support functions of operator families" msgstr "Список опорных функций из семейств операторов" -#: describe.c:7291 +#: describe.c:7295 msgid "ID" msgstr "ID" -#: describe.c:7311 +#: describe.c:7315 msgid "Large objects" msgstr "Большие объекты" @@ -7258,22 +7268,22 @@ msgstr "" "значение \"%s\" не подходит для переменной \"%s\"; оно должно быть меньше " "%.2f" -#: variables.c:241 +#: variables.c:242 #, c-format msgid "value \"%s\" is out of range for variable \"%s\"" msgstr "значение \"%s\" вне диапазона для переменной \"%s\"" -#: variables.c:247 +#: variables.c:248 #, c-format msgid "invalid value \"%s\" for variable \"%s\"" msgstr "неправильное значение \"%s\" для переменной \"%s\"" -#: variables.c:294 +#: variables.c:295 #, c-format msgid "invalid variable name: \"%s\"" msgstr "неправильное имя переменной: \"%s\"" -#: variables.c:488 +#: variables.c:489 #, c-format msgid "" "unrecognized value \"%s\" for \"%s\"\n" diff --git a/src/bin/scripts/po/ru.po b/src/bin/scripts/po/ru.po index df18f6fb518..f8bf2b467b1 100644 --- a/src/bin/scripts/po/ru.po +++ b/src/bin/scripts/po/ru.po @@ -3,13 +3,13 @@ # This file is distributed under the same license as the PostgreSQL package. # Serguei A. Mokhov, , 2003-2004. # Oleg Bartunov , 2004. -# SPDX-FileCopyrightText: 2012-2017, 2019, 2020, 2021, 2022, 2023, 2024, 2025 Alexander Lakhin +# SPDX-FileCopyrightText: 2012-2017, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: pgscripts (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" -"PO-Revision-Date: 2025-09-13 17:25+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:51+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -39,17 +39,27 @@ msgstr "подробности: " msgid "hint: " msgstr "подсказка: " -#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:161 +#: ../../common/fe_memutils.c:41 ../../common/fe_memutils.c:81 +#: ../../common/fe_memutils.c:104 ../../common/fe_memutils.c:167 #, c-format msgid "out of memory\n" msgstr "нехватка памяти\n" -#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:153 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:159 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" +#: ../../common/fe_memutils.c:209 +#, c-format +msgid "invalid memory allocation request size %zu + %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu + %zu\n" + +#: ../../common/fe_memutils.c:228 +#, c-format +msgid "invalid memory allocation request size %zu * %zu\n" +msgstr "недопустимый размер в запросе на выделение памяти: %zu * %zu\n" + #: ../../common/file_utils.c:69 ../../common/file_utils.c:370 #: ../../common/file_utils.c:428 ../../common/file_utils.c:502 #, c-format @@ -171,12 +181,12 @@ msgstr[0] "(%lu строка)" msgstr[1] "(%lu строки)" msgstr[2] "(%lu строк)" -#: ../../fe_utils/print.c:3154 +#: ../../fe_utils/print.c:3155 #, c-format msgid "Interrupted\n" msgstr "Прервано\n" -#: ../../fe_utils/print.c:3188 +#: ../../fe_utils/print.c:3189 #, c-format msgid "" "Cannot print table contents: number of cells % is equal to or " @@ -185,13 +195,13 @@ msgstr "" "Вывести содержимое таблицы нельзя: число ячеек % достигло максимума " "%zu.\n" -#: ../../fe_utils/print.c:3229 +#: ../../fe_utils/print.c:3230 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "" "Ошибка добавления заголовка таблицы: превышен предел числа столбцов (%d).\n" -#: ../../fe_utils/print.c:3272 +#: ../../fe_utils/print.c:3273 #, c-format msgid "" "Cannot add cell to table content: total cell count of % exceeded.\n" @@ -199,7 +209,7 @@ msgstr "" "Ошибка добавления ячейки в таблицу: превышен предел числа ячеек " "(%).\n" -#: ../../fe_utils/print.c:3530 +#: ../../fe_utils/print.c:3531 #, c-format msgid "invalid output format (internal error): %d" msgstr "неверный формат вывода (внутренняя ошибка): %d" diff --git a/src/interfaces/ecpg/preproc/po/ru.po b/src/interfaces/ecpg/preproc/po/ru.po index e2c3683b46d..4f288f0d13b 100644 --- a/src/interfaces/ecpg/preproc/po/ru.po +++ b/src/interfaces/ecpg/preproc/po/ru.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: ecpg (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" "PO-Revision-Date: 2025-08-30 22:23+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" @@ -394,7 +394,7 @@ msgstr "имя типа \"string\" в режиме Informix зарезервир msgid "type \"%s\" is already defined" msgstr "тип \"%s\" уже определён" -#: preproc.y:539 preproc.y:9532 preproc.y:9877 variable.c:652 +#: preproc.y:539 preproc.y:9524 preproc.y:9869 variable.c:652 #, c-format msgid "multidimensional arrays for simple data types are not supported" msgstr "многомерные массивы с простыми типами данных не поддерживаются" @@ -562,23 +562,23 @@ msgstr "слишком много уровней в определении вл msgid "pointers to varchar are not implemented" msgstr "указатели на varchar не реализованы" -#: preproc.y:9497 +#: preproc.y:9489 #, c-format msgid "initializer not allowed in EXEC SQL VAR command" msgstr "команда EXEC SQL VAR не может включать инициализатор" -#: preproc.y:9820 +#: preproc.y:9812 #, c-format msgid "arrays of indicators are not allowed on input" msgstr "массивы индикаторов на входе недопустимы" -#: preproc.y:10054 +#: preproc.y:10046 #, c-format msgid "operator not allowed in variable definition" msgstr "недопустимый оператор в определении переменной" #. translator: %s is typically the translation of "syntax error" -#: preproc.y:10099 +#: preproc.y:10091 #, c-format msgid "%s at or near \"%s\"" msgstr "%s (примерное положение: \"%s\")" diff --git a/src/interfaces/libpq/po/de.po b/src/interfaces/libpq/po/de.po index cc35e8389e3..95a110dc2f7 100644 --- a/src/interfaces/libpq/po/de.po +++ b/src/interfaces/libpq/po/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-06-30 04:10+0000\n" +"POT-Creation-Date: 2026-08-07 15:40+0000\n" "PO-Revision-Date: 2026-07-04 01:02+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" @@ -17,20 +17,20 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ../libpq-oauth/oauth-curl.c:308 +#: ../libpq-oauth/oauth-curl.c:309 #, c-format msgid "WARNING: libcurl easy handle removal failed: %s\n" msgstr "WARNUNG: libcurl-Easy-Handle-Removal fehlgeschlagen: %s\n" -#: ../libpq-oauth/oauth-curl.c:328 +#: ../libpq-oauth/oauth-curl.c:329 #, c-format msgid "WARNING: libcurl multi handle cleanup failed: %s\n" msgstr "WARNUNG: libcurl-Multi-Handle-Cleanup fehlgeschlagen: %s\n" -#: ../libpq-oauth/oauth-curl.c:393 ../libpq-oauth/oauth-curl.c:1857 -#: ../libpq-oauth/oauth-curl.c:1898 ../libpq-oauth/oauth-curl.c:2216 -#: ../libpq-oauth/oauth-curl.c:2377 ../libpq-oauth/oauth-curl.c:2437 -#: ../libpq-oauth/oauth-curl.c:2525 ../libpq-oauth/oauth-curl.c:3178 +#: ../libpq-oauth/oauth-curl.c:394 ../libpq-oauth/oauth-curl.c:1858 +#: ../libpq-oauth/oauth-curl.c:1899 ../libpq-oauth/oauth-curl.c:2217 +#: ../libpq-oauth/oauth-curl.c:2378 ../libpq-oauth/oauth-curl.c:2438 +#: ../libpq-oauth/oauth-curl.c:2526 ../libpq-oauth/oauth-curl.c:3193 #: fe-auth-oauth.c:153 fe-auth-oauth.c:496 fe-auth-oauth.c:568 #: fe-auth-oauth.c:776 fe-auth-oauth.c:1065 fe-auth-oauth.c:1077 #: fe-auth-oauth.c:1163 fe-auth-oauth.c:1176 fe-auth-oauth.c:1312 @@ -50,179 +50,179 @@ msgstr "WARNUNG: libcurl-Multi-Handle-Cleanup fehlgeschlagen: %s\n" #: fe-protocol3.c:260 fe-protocol3.c:277 fe-protocol3.c:298 fe-protocol3.c:372 #: fe-protocol3.c:753 fe-protocol3.c:993 fe-protocol3.c:1608 #: fe-protocol3.c:1662 fe-protocol3.c:1708 fe-protocol3.c:1729 -#: fe-protocol3.c:1986 fe-protocol3.c:2398 fe-secure-common.c:110 -#: fe-secure-gssapi.c:508 fe-secure-gssapi.c:699 fe-secure-openssl.c:405 -#: fe-secure-openssl.c:1136 +#: fe-protocol3.c:1993 fe-protocol3.c:2405 fe-secure-common.c:110 +#: fe-secure-gssapi.c:515 fe-secure-gssapi.c:706 fe-secure-openssl.c:436 +#: fe-secure-openssl.c:1167 #, c-format msgid "out of memory" msgstr "Speicher aufgebraucht" -#: ../libpq-oauth/oauth-curl.c:438 ../libpq-oauth/oauth-curl.c:449 +#: ../libpq-oauth/oauth-curl.c:439 ../libpq-oauth/oauth-curl.c:450 #, c-format msgid "could not set libcurl option \"%s\" on OAuth connection: %s" msgstr "konnte libcurl-Option »%s« für die OAuth-Verbindung nicht setzen: %s" -#: ../libpq-oauth/oauth-curl.c:460 +#: ../libpq-oauth/oauth-curl.c:461 #, c-format msgid "could not get libcurl info \"%s\" from OAuth response: %s" msgstr "konnte libcurl-Info »%s« nicht aus der OAuth-Antwort ermitteln: %s" -#: ../libpq-oauth/oauth-curl.c:529 fe-auth-oauth.c:216 fe-auth-oauth.c:278 +#: ../libpq-oauth/oauth-curl.c:530 fe-auth-oauth.c:216 fe-auth-oauth.c:278 #: fe-auth-oauth.c:340 #, c-format msgid "field \"%s\" must be a string" msgstr "Feld »%s« muss eine Zeichenkette sein" -#: ../libpq-oauth/oauth-curl.c:533 +#: ../libpq-oauth/oauth-curl.c:534 #, c-format msgid "field \"%s\" must be a number" msgstr "Feld »%s« muss eine Zahl sein" -#: ../libpq-oauth/oauth-curl.c:537 +#: ../libpq-oauth/oauth-curl.c:538 #, c-format msgid "field \"%s\" must be an array of strings" msgstr "Feld »%s« muss ein Array von Zeichenketten sein" -#: ../libpq-oauth/oauth-curl.c:542 +#: ../libpq-oauth/oauth-curl.c:543 #, c-format msgid "field \"%s\" has unexpected type" msgstr "Feld »%s« hat unerwarteten Typ" -#: ../libpq-oauth/oauth-curl.c:566 ../libpq-oauth/oauth-curl.c:676 +#: ../libpq-oauth/oauth-curl.c:567 ../libpq-oauth/oauth-curl.c:677 #: fe-auth-oauth.c:222 fe-auth-oauth.c:284 #, c-format msgid "JSON is too deeply nested" msgstr "JSON ist zu tief geschachtelt" -#: ../libpq-oauth/oauth-curl.c:618 fe-auth-oauth.c:331 +#: ../libpq-oauth/oauth-curl.c:619 fe-auth-oauth.c:331 #, c-format msgid "field \"%s\" is duplicated" msgstr "Feld »%s« ist doppelt vorhanden" -#: ../libpq-oauth/oauth-curl.c:658 ../libpq-oauth/oauth-curl.c:718 +#: ../libpq-oauth/oauth-curl.c:659 ../libpq-oauth/oauth-curl.c:719 #: fe-auth-oauth.c:271 fe-auth-oauth.c:305 #, c-format msgid "top-level element must be an object" msgstr "Element auf oberster Ebene muss ein Objekt sein" -#: ../libpq-oauth/oauth-curl.c:821 +#: ../libpq-oauth/oauth-curl.c:822 #, c-format msgid "no content type was provided" msgstr "kein Content-Typ wurde angegeben" -#: ../libpq-oauth/oauth-curl.c:860 +#: ../libpq-oauth/oauth-curl.c:861 #, c-format msgid "unexpected content type: \"%s\"" msgstr "unerwarteter Content-Typ: »%s«" -#: ../libpq-oauth/oauth-curl.c:885 +#: ../libpq-oauth/oauth-curl.c:886 #, c-format msgid "response contains embedded null" msgstr "Antwort enthält Null-Byte" -#: ../libpq-oauth/oauth-curl.c:895 +#: ../libpq-oauth/oauth-curl.c:896 #, c-format msgid "response is not valid UTF-8" msgstr "Antwort ist kein gültiges UTF-8" -#: ../libpq-oauth/oauth-curl.c:935 +#: ../libpq-oauth/oauth-curl.c:936 #, c-format msgid "field \"%s\" is missing" msgstr "Feld »%s« fehlt" -#: ../libpq-oauth/oauth-curl.c:1141 +#: ../libpq-oauth/oauth-curl.c:1142 msgid "could not parse token error response" msgstr "konnte Token-Fehler-Antwort nicht parsen" -#: ../libpq-oauth/oauth-curl.c:1169 +#: ../libpq-oauth/oauth-curl.c:1170 #, c-format msgid "provider rejected the oauth_client_secret" msgstr "Provider hat das oauth_client_secret abgelehnt" -#: ../libpq-oauth/oauth-curl.c:1170 +#: ../libpq-oauth/oauth-curl.c:1171 #, c-format msgid "provider requires client authentication, and no oauth_client_secret is set" msgstr "Provider erfordert Client-Authentifizierung, aber kein oauth_client_secret ist gesetzt" -#: ../libpq-oauth/oauth-curl.c:1603 +#: ../libpq-oauth/oauth-curl.c:1604 #, c-format msgid "could not check timer expiration: %m" msgstr "konnte Ablauf des Timers nicht prüfen: %m" -#: ../libpq-oauth/oauth-curl.c:1765 +#: ../libpq-oauth/oauth-curl.c:1766 #, c-format msgid "could not create libcurl multi handle" msgstr "konnte libcurl-Multi-Handle nicht erzeugen" -#: ../libpq-oauth/oauth-curl.c:1785 +#: ../libpq-oauth/oauth-curl.c:1786 #, c-format msgid "could not create libcurl handle" msgstr "konnte libcurl-Handle nicht erzeugen" -#: ../libpq-oauth/oauth-curl.c:1885 +#: ../libpq-oauth/oauth-curl.c:1886 #, c-format msgid "response is too large" msgstr "Antwort ist zu groß" -#: ../libpq-oauth/oauth-curl.c:1927 +#: ../libpq-oauth/oauth-curl.c:1928 #, c-format msgid "could not queue HTTP request: %s" msgstr "Einreihen der HTTP-Anfrage fehlgeschlagen: %s" -#: ../libpq-oauth/oauth-curl.c:1944 ../libpq-oauth/oauth-curl.c:2002 +#: ../libpq-oauth/oauth-curl.c:1945 ../libpq-oauth/oauth-curl.c:2003 #, c-format msgid "asynchronous HTTP request failed: %s" msgstr "asynchrone HTTP-Anfrage fehlgeschlagen: %s" -#: ../libpq-oauth/oauth-curl.c:2043 +#: ../libpq-oauth/oauth-curl.c:2044 #, c-format msgid "libcurl easy handle removal failed: %s" msgstr "libcurl-Easy-Handle-Removal fehlgeschlagen: %s" -#: ../libpq-oauth/oauth-curl.c:2054 +#: ../libpq-oauth/oauth-curl.c:2055 #, c-format msgid "no result was retrieved for the finished handle" msgstr "für die abgeschlossene Handle wurde kein Ergebnis abgerufen" -#: ../libpq-oauth/oauth-curl.c:2187 ../libpq-oauth/oauth-curl.c:2492 -#: ../libpq-oauth/oauth-curl.c:2570 +#: ../libpq-oauth/oauth-curl.c:2188 ../libpq-oauth/oauth-curl.c:2493 +#: ../libpq-oauth/oauth-curl.c:2571 #, c-format msgid "unexpected response code %ld" msgstr "unerwarteter Antwortcode %ld" -#: ../libpq-oauth/oauth-curl.c:2194 +#: ../libpq-oauth/oauth-curl.c:2195 msgid "could not parse OpenID discovery document" msgstr "konnte OpenID-Discovery-Dokument nicht parsen" -#: ../libpq-oauth/oauth-curl.c:2259 +#: ../libpq-oauth/oauth-curl.c:2260 #, c-format msgid "issuer identifier (%s) does not match oauth_issuer (%s)" msgstr "Issuer-Identifier (%s) stimmt nicht mit oauth_issuer (%s) überein" -#: ../libpq-oauth/oauth-curl.c:2286 +#: ../libpq-oauth/oauth-curl.c:2287 #, c-format msgid "issuer \"%s\" does not provide a device authorization endpoint" msgstr "Issuer »%s« stellt keinen Device-Authorization-Endpunkt zur Verfügung" -#: ../libpq-oauth/oauth-curl.c:2312 +#: ../libpq-oauth/oauth-curl.c:2313 #, c-format msgid "device authorization endpoint \"%s\" must use HTTPS" msgstr "Device-Authorization-Endpunkt »%s« muss HTTPS verwenden" -#: ../libpq-oauth/oauth-curl.c:2321 +#: ../libpq-oauth/oauth-curl.c:2322 #, c-format msgid "token endpoint \"%s\" must use HTTPS" msgstr "Token-Endpunkt »%s« muss HTTPS verwenden" -#: ../libpq-oauth/oauth-curl.c:2461 +#: ../libpq-oauth/oauth-curl.c:2462 msgid "could not parse device authorization" msgstr "konnte Device-Authorization nicht parsen" -#: ../libpq-oauth/oauth-curl.c:2548 +#: ../libpq-oauth/oauth-curl.c:2549 msgid "could not parse access token response" msgstr "konnte Access-Token-Antwort nicht parsen" -#: ../libpq-oauth/oauth-curl.c:2628 +#: ../libpq-oauth/oauth-curl.c:2626 #, c-format msgid "slow_down interval overflow" msgstr "slow_down Intervall-Überlauf" @@ -230,25 +230,25 @@ msgstr "slow_down Intervall-Überlauf" #. translator: The first %s is a URL for the user to visit in a #. browser, and the second %s is a code to be copy-pasted there. #. -#: ../libpq-oauth/oauth-curl.c:2664 +#: ../libpq-oauth/oauth-curl.c:2662 #, c-format msgid "Visit %s and enter the code: %s\n" msgstr "Besuchen Sie %s und geben Sie den Code ein: %s\n" -#: ../libpq-oauth/oauth-curl.c:2669 +#: ../libpq-oauth/oauth-curl.c:2667 #, c-format msgid "device prompt failed" msgstr "Device-Prompt fehlgeschlagen" -#: ../libpq-oauth/oauth-curl.c:2722 +#: ../libpq-oauth/oauth-curl.c:2720 msgid "curl_global_init previously failed during OAuth setup" msgstr "curl_global_init zuvor beim OAuth-Setup fehlgeschlagen" -#: ../libpq-oauth/oauth-curl.c:2740 +#: ../libpq-oauth/oauth-curl.c:2738 msgid "curl_global_init failed during OAuth setup" msgstr "curl_global_init beim OAuth-Setup fehlgeschlagen" -#: ../libpq-oauth/oauth-curl.c:2762 +#: ../libpq-oauth/oauth-curl.c:2760 msgid "" "libcurl is no longer thread-safe\n" "\tCurl initialization was reported thread-safe when libpq\n" @@ -262,19 +262,19 @@ msgstr "" "\tberichtet, dass sie nicht thread-safe ist. Kompilieren Sie libpq neu\n" "\tmit der installierten Version von libcurl." -#: ../libpq-oauth/oauth-curl.c:2902 +#: ../libpq-oauth/oauth-curl.c:2900 msgid "could not fetch OpenID discovery document" msgstr "konnte OpenID-Discovery-Dokument nicht holen" -#: ../libpq-oauth/oauth-curl.c:2916 +#: ../libpq-oauth/oauth-curl.c:2914 msgid "cannot run OAuth device authorization" msgstr "kann OAuth-Device-Authorization nicht ausführen" -#: ../libpq-oauth/oauth-curl.c:2920 +#: ../libpq-oauth/oauth-curl.c:2918 msgid "could not obtain device authorization" msgstr "konnte Device-Authorization nicht erhalten" -#: ../libpq-oauth/oauth-curl.c:2931 ../libpq-oauth/oauth-curl.c:2982 +#: ../libpq-oauth/oauth-curl.c:2929 ../libpq-oauth/oauth-curl.c:2997 msgid "could not obtain access token" msgstr "konnte Access-Token nicht erhalten" @@ -711,7 +711,7 @@ msgstr "unbekannter Passwortverschlüsselungsalgorithmus »%s«" msgid "connection pointer is NULL" msgstr "Verbindung ist ein NULL-Zeiger" -#: fe-cancel.c:85 fe-misc.c:613 +#: fe-cancel.c:85 fe-misc.c:621 #, c-format msgid "connection not open" msgstr "Verbindung nicht offen" @@ -741,7 +741,7 @@ msgstr "fehlerhafte Angabe: %d Hostnamen und %d hostaddr-Angaben" msgid "could not match %d port numbers to %d hosts" msgstr "fehlerhafte Angabe: %d Portnummern und %d Hosts" -#: fe-connect.c:1480 fe-exec.c:532 fe-protocol3.c:2192 +#: fe-connect.c:1480 fe-exec.c:532 fe-protocol3.c:2199 #, c-format msgid "%s" msgstr "%s" @@ -1372,7 +1372,7 @@ msgstr "PQexec ist während COPY BOTH nicht erlaubt" msgid "unrecognized message type \"%c\"" msgstr "unbekannter Message-Typ »%c«" -#: fe-exec.c:2719 fe-exec.c:2773 fe-exec.c:2841 fe-protocol3.c:2123 +#: fe-exec.c:2719 fe-exec.c:2773 fe-exec.c:2841 fe-protocol3.c:2130 #, c-format msgid "no COPY in progress" msgstr "keine COPY in Ausführung" @@ -1496,18 +1496,18 @@ msgstr "konnte nicht in Datei »%s« schreiben: %s" msgid "query to initialize large object functions did not return data" msgstr "Abfrage zur Initialisierung der Large-Object-Funktionen ergab keine Daten" -#: fe-misc.c:239 +#: fe-misc.c:241 #, c-format msgid "integer of size %zu not supported by pqGetInt" msgstr "Integer der Größe %zu wird von pqGetInt nicht unterstützt" -#: fe-misc.c:272 +#: fe-misc.c:274 #, c-format msgid "integer of size %zu not supported by pqPutInt" msgstr "Integer der Größe %zu wird von pqPutInt nicht unterstützt" -#: fe-misc.c:791 fe-secure-openssl.c:181 fe-secure-openssl.c:287 -#: fe-secure.c:222 fe-secure.c:389 +#: fe-misc.c:833 fe-secure-openssl.c:182 fe-secure-openssl.c:318 +#: fe-secure.c:222 fe-secure.c:413 #, c-format msgid "" "server closed the connection unexpectedly\n" @@ -1518,26 +1518,31 @@ msgstr "" "\tDas heißt wahrscheinlich, dass der Server abnormal beendete\n" "\tbevor oder während die Anweisung bearbeitet wurde." -#: fe-misc.c:858 +#: fe-misc.c:942 +#, c-format +msgid "drained only %zd of %zd pending bytes in transport buffer" +msgstr "nur %zd von %zd ausstehenden Bytes im Transportpuffer geleert" + +#: fe-misc.c:1004 msgid "connection not open\n" msgstr "Verbindung nicht offen\n" -#: fe-misc.c:1046 +#: fe-misc.c:1192 #, c-format msgid "timeout expired" msgstr "Timeout abgelaufen" -#: fe-misc.c:1098 +#: fe-misc.c:1244 #, c-format msgid "invalid socket" msgstr "ungültiges Socket" -#: fe-misc.c:1121 +#: fe-misc.c:1265 #, c-format msgid "%s() failed: %s" msgstr "%s() fehlgeschlagen: %s" -#: fe-misc.c:1436 +#: fe-misc.c:1580 #, c-format msgid "" "\tThis indicates a bug in either the server being contacted\n" @@ -1743,22 +1748,22 @@ msgstr "ungültige BackendKeyData-Nachricht empfangen: Stornierungsschlüssel mi msgid "received invalid BackendKeyData message: cancel key with length %d is too long (maximum 256 bytes)" msgstr "ungültige BackendKeyData-Nachricht empfangen: Stornierungsschlüssel mit Länge %d ist zu lang (Maximum 256 Bytes)" -#: fe-protocol3.c:2018 +#: fe-protocol3.c:2025 #, c-format msgid "PQgetline: not doing text COPY OUT" msgstr "PQgetline: Text COPY OUT nicht ausgeführt" -#: fe-protocol3.c:2349 +#: fe-protocol3.c:2356 #, c-format msgid "server returned too much data" msgstr "Server hat zu viele Daten zurückgesendet" -#: fe-protocol3.c:2404 +#: fe-protocol3.c:2411 #, c-format msgid "protocol error: no function result" msgstr "Protokollfehler: kein Funktionsergebnis" -#: fe-protocol3.c:2416 +#: fe-protocol3.c:2423 #, c-format msgid "protocol error: id=0x%x" msgstr "Protokollfehler: id=0x%x" @@ -1809,12 +1814,12 @@ msgstr "GSSAPI-Wrap-Fehler" msgid "outgoing GSSAPI message would not use confidentiality" msgstr "ausgehende GSSAPI-Nachricht würde keine Vertraulichkeit verwenden" -#: fe-secure-gssapi.c:215 fe-secure-gssapi.c:726 +#: fe-secure-gssapi.c:215 fe-secure-gssapi.c:733 #, c-format msgid "client tried to send oversize GSSAPI packet (%zu > %zu)" msgstr "Client versuchte übergroßes GSSAPI-Paket zu senden (%zu > %zu)" -#: fe-secure-gssapi.c:354 fe-secure-gssapi.c:602 +#: fe-secure-gssapi.c:354 fe-secure-gssapi.c:609 #, c-format msgid "oversize GSSAPI packet sent by the server (%zu > %zu)" msgstr "übergroßes GSSAPI-Paket vom Server gesendet (%zu > %zu)" @@ -1828,110 +1833,120 @@ msgstr "GSSAPI-Unwrap-Fehler" msgid "incoming GSSAPI message did not use confidentiality" msgstr "eingehende GSSAPI-Nachricht verwendete keine Vertraulichkeit" -#: fe-secure-gssapi.c:665 +#: fe-secure-gssapi.c:672 msgid "could not initiate GSSAPI security context" msgstr "konnte GSSAPI-Sicherheitskontext nicht initiieren" -#: fe-secure-gssapi.c:715 +#: fe-secure-gssapi.c:722 msgid "GSSAPI size check error" msgstr "GSSAPI-Fehler bei der Größenprüfung" -#: fe-secure-openssl.c:185 fe-secure-openssl.c:291 fe-secure-openssl.c:1383 +#: fe-secure-openssl.c:186 fe-secure-openssl.c:322 fe-secure-openssl.c:1414 #, c-format msgid "SSL SYSCALL error: %s" msgstr "SSL-SYSCALL-Fehler: %s" -#: fe-secure-openssl.c:191 fe-secure-openssl.c:297 fe-secure-openssl.c:1386 +#: fe-secure-openssl.c:192 fe-secure-openssl.c:328 fe-secure-openssl.c:1417 #, c-format msgid "SSL SYSCALL error: EOF detected" msgstr "SSL-SYSCALL-Fehler: Dateiende entdeckt" -#: fe-secure-openssl.c:201 fe-secure-openssl.c:307 fe-secure-openssl.c:1394 +#: fe-secure-openssl.c:202 fe-secure-openssl.c:338 fe-secure-openssl.c:1425 #, c-format msgid "SSL error: %s" msgstr "SSL-Fehler: %s" -#: fe-secure-openssl.c:215 fe-secure-openssl.c:321 +#: fe-secure-openssl.c:216 fe-secure-openssl.c:352 #, c-format msgid "SSL connection has been closed unexpectedly" msgstr "SSL-Verbindung wurde unerwartet geschlossen" -#: fe-secure-openssl.c:220 fe-secure-openssl.c:326 fe-secure-openssl.c:1441 +#: fe-secure-openssl.c:221 fe-secure-openssl.c:357 fe-secure-openssl.c:1472 #, c-format msgid "unrecognized SSL error code: %d" msgstr "unbekannter SSL-Fehlercode: %d" -#: fe-secure-openssl.c:368 +#: fe-secure-openssl.c:251 +#, c-format +msgid "OpenSSL reports negative bytes pending" +msgstr "OpenSSL meldet eine negative Anzahl ausstehender Bytes" + +#: fe-secure-openssl.c:263 +#, c-format +msgid "OpenSSL reports INT_MAX bytes pending" +msgstr "OpenSSL meldet INT_MAX ausstehende Bytes" + +#: fe-secure-openssl.c:399 #, c-format msgid "could not determine server certificate signature algorithm" msgstr "konnte Signaturalgorithmus des Serverzertifikats nicht ermitteln" -#: fe-secure-openssl.c:388 +#: fe-secure-openssl.c:419 #, c-format msgid "could not find digest for NID %s" msgstr "konnte Digest für NID %s nicht finden" -#: fe-secure-openssl.c:397 +#: fe-secure-openssl.c:428 #, c-format msgid "could not generate peer certificate hash" msgstr "konnte Hash des Zertifikats der Gegenstelle nicht erzeugen" -#: fe-secure-openssl.c:480 +#: fe-secure-openssl.c:511 #, c-format msgid "SSL certificate's name entry is missing" msgstr "Namenseintrag fehlt im SSL-Zertifikat" -#: fe-secure-openssl.c:510 +#: fe-secure-openssl.c:541 #, c-format msgid "SSL certificate's address entry is missing" msgstr "Adresseintrag fehlt im SSL-Zertifikat" -#: fe-secure-openssl.c:716 +#: fe-secure-openssl.c:747 #, c-format msgid "WARNING: could not open SSL key logging file \"%s\": %m\n" msgstr "WARNUNG: konnte SSL-Key-Logging-Datei »%s« nicht öffnen: %m\n" -#: fe-secure-openssl.c:724 +#: fe-secure-openssl.c:755 #, c-format msgid "WARNING: could not write to SSL key logging file \"%s\": %m\n" msgstr "WARNUNG: konnte nicht in SSL-Key-Logging-Datei »%s «schreiben: %m\n" -#: fe-secure-openssl.c:777 +#: fe-secure-openssl.c:808 #, c-format msgid "could not create SSL context: %s" msgstr "konnte SSL-Kontext nicht erzeugen: %s" -#: fe-secure-openssl.c:819 +#: fe-secure-openssl.c:850 #, c-format msgid "invalid value \"%s\" for minimum SSL protocol version" msgstr "ungültiger Wert »%s« für minimale SSL-Protokollversion" -#: fe-secure-openssl.c:829 +#: fe-secure-openssl.c:860 #, c-format msgid "could not set minimum SSL protocol version: %s" msgstr "konnte minimale SSL-Protokollversion nicht setzen: %s" -#: fe-secure-openssl.c:845 +#: fe-secure-openssl.c:876 #, c-format msgid "invalid value \"%s\" for maximum SSL protocol version" msgstr "ungültiger Wert »%s« für maximale SSL-Protokollversion" -#: fe-secure-openssl.c:855 +#: fe-secure-openssl.c:886 #, c-format msgid "could not set maximum SSL protocol version: %s" msgstr "konnte maximale SSL-Protokollversion nicht setzen: %s" -#: fe-secure-openssl.c:893 +#: fe-secure-openssl.c:924 #, c-format msgid "could not load system root certificate paths: %s" msgstr "konnte System-Root-Zertifikat-Pfade nicht laden: %s" -#: fe-secure-openssl.c:910 +#: fe-secure-openssl.c:941 #, c-format msgid "could not read root certificate file \"%s\": %s" msgstr "konnte Root-Zertifikat-Datei »%s« nicht lesen: %s" -#: fe-secure-openssl.c:962 +#: fe-secure-openssl.c:993 #, c-format msgid "" "could not get home directory to locate root certificate file\n" @@ -1940,7 +1955,7 @@ msgstr "" "konnte Home-Verzeichnis nicht ermitteln, um Root-Zertifikat-Datei zu finden\n" "Legen Sie entweder die Datei an, verwenden Sie die vertrauenswürdigen Roots des Systems mit sslrootcert=system, oder ändern Sie sslmode, um die Überprüfung der Serverzertifikate abzuschalten." -#: fe-secure-openssl.c:965 +#: fe-secure-openssl.c:996 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -1949,127 +1964,127 @@ msgstr "" "Root-Zertifikat-Datei »%s« existiert nicht\n" "Legen Sie entweder die Datei an, verwenden Sie die vertrauenswürdigen Roots des Systems mit sslrootcert=system, oder ändern Sie sslmode, um die Überprüfung der Serverzertifikate abzuschalten." -#: fe-secure-openssl.c:1000 +#: fe-secure-openssl.c:1031 #, c-format msgid "could not open certificate file \"%s\": %s" msgstr "konnte Zertifikatdatei »%s« nicht öffnen: %s" -#: fe-secure-openssl.c:1018 +#: fe-secure-openssl.c:1049 #, c-format msgid "could not read certificate file \"%s\": %s" msgstr "konnte Zertifikatdatei »%s« nicht lesen: %s" -#: fe-secure-openssl.c:1042 +#: fe-secure-openssl.c:1073 #, c-format msgid "could not establish SSL connection: %s" msgstr "konnte SSL-Verbindung nicht aufbauen: %s" -#: fe-secure-openssl.c:1059 +#: fe-secure-openssl.c:1090 #, c-format msgid "WARNING: sslkeylogfile support requires OpenSSL\n" msgstr "WARNUNG: Unterstützung für sslkeylogfile benötigt OpenSSL\n" -#: fe-secure-openssl.c:1061 +#: fe-secure-openssl.c:1092 #, c-format msgid "WARNING: libpq was not built with sslkeylogfile support\n" msgstr "WARNUNG: libpq wurde ohne Unterstützung für sslkeylogfile gebaut\n" -#: fe-secure-openssl.c:1091 +#: fe-secure-openssl.c:1122 #, c-format msgid "could not set SSL Server Name Indication (SNI): %s" msgstr "konnte SSL-Server-Name-Indication (SNI) nicht setzen: %s" -#: fe-secure-openssl.c:1108 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not set SSL ALPN extension: %s" msgstr "konnte SSL-ALPN-Erweiterung nicht setzen: %s" -#: fe-secure-openssl.c:1151 +#: fe-secure-openssl.c:1182 #, c-format msgid "could not load SSL engine \"%s\": %s" msgstr "konnte SSL-Engine »%s« nicht laden: %s" -#: fe-secure-openssl.c:1162 +#: fe-secure-openssl.c:1193 #, c-format msgid "could not initialize SSL engine \"%s\": %s" msgstr "konnte SSL-Engine »%s« nicht initialisieren: %s" -#: fe-secure-openssl.c:1177 +#: fe-secure-openssl.c:1208 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s" msgstr "konnte privaten SSL-Schlüssel »%s« nicht von Engine »%s« lesen: %s" -#: fe-secure-openssl.c:1190 +#: fe-secure-openssl.c:1221 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s" msgstr "konnte privaten SSL-Schlüssel »%s« nicht von Engine »%s« laden: %s" -#: fe-secure-openssl.c:1227 +#: fe-secure-openssl.c:1258 #, c-format msgid "certificate present, but not private key file \"%s\"" msgstr "Zertifikat vorhanden, aber keine private Schlüsseldatei »%s«" -#: fe-secure-openssl.c:1230 +#: fe-secure-openssl.c:1261 #, c-format msgid "could not stat private key file \"%s\": %m" msgstr "konnte »stat« für private Schlüsseldatei »%s« nicht ausführen: %m" -#: fe-secure-openssl.c:1238 +#: fe-secure-openssl.c:1269 #, c-format msgid "private key file \"%s\" is not a regular file" msgstr "private Schlüsseldatei »%s« ist keine normale Datei" -#: fe-secure-openssl.c:1271 +#: fe-secure-openssl.c:1302 #, c-format msgid "private key file \"%s\" has group or world access; file must have permissions u=rw (0600) or less if owned by the current user, or permissions u=rw,g=r (0640) or less if owned by root" msgstr "private Schlüsseldatei »%s« erlaubt Lesezugriff für Gruppe oder Andere; Dateirechte müssen u=rw (0600) oder weniger sein, wenn der Eigentümer der aktuelle Benutzer ist, oder u=rw,g=r (0640) oder weniger, wenn der Eigentümer »root« ist" -#: fe-secure-openssl.c:1295 +#: fe-secure-openssl.c:1326 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "konnte private Schlüsseldatei »%s« nicht laden: %s" -#: fe-secure-openssl.c:1311 +#: fe-secure-openssl.c:1342 #, c-format msgid "certificate does not match private key file \"%s\": %s" msgstr "Zertifikat passt nicht zur privaten Schlüsseldatei »%s«: %s" -#: fe-secure-openssl.c:1380 +#: fe-secure-openssl.c:1411 #, c-format msgid "SSL error: certificate verify failed: %s" msgstr "SSL-Fehler: Zertifikatsüberprüfung fehlgeschlagen: %s" -#: fe-secure-openssl.c:1425 +#: fe-secure-openssl.c:1456 #, c-format msgid "This may indicate that the server does not support any SSL protocol version between %s and %s." msgstr "Das zeigt möglicherweise an, dass der Server keine SSL-Protokollversion zwischen %s und %s unterstützt." -#: fe-secure-openssl.c:1457 +#: fe-secure-openssl.c:1488 #, c-format msgid "direct SSL connection was established without ALPN protocol negotiation extension" msgstr "direkte SSL-Verbindung wurde ohne ALPN-Erweiterung zur Protokollverhandlung aufgebaut" -#: fe-secure-openssl.c:1469 +#: fe-secure-openssl.c:1500 #, c-format msgid "SSL connection was established with unexpected ALPN protocol" msgstr "SSL-Verbindung wurde mit unerwartetem ALPN-Protokoll aufgebaut" -#: fe-secure-openssl.c:1486 +#: fe-secure-openssl.c:1517 #, c-format msgid "certificate could not be obtained: %s" msgstr "Zertifikat konnte nicht ermittelt werden: %s" -#: fe-secure-openssl.c:1565 +#: fe-secure-openssl.c:1596 #, c-format msgid "no SSL error reported" msgstr "kein SSL-Fehler berichtet" -#: fe-secure-openssl.c:1608 +#: fe-secure-openssl.c:1639 #, c-format msgid "SSL error code %lu" msgstr "SSL-Fehlercode %lu" -#: fe-secure-openssl.c:1910 +#: fe-secure-openssl.c:1941 #, c-format msgid "WARNING: sslpassword truncated\n" msgstr "WARNUNG: sslpassword abgeschnitten\n" @@ -2079,7 +2094,7 @@ msgstr "WARNUNG: sslpassword abgeschnitten\n" msgid "could not receive data from server: %s" msgstr "konnte keine Daten vom Server empfangen: %s" -#: fe-secure.c:404 +#: fe-secure.c:428 #, c-format msgid "could not send data to server: %s" msgstr "konnte keine Daten an den Server senden: %s" diff --git a/src/interfaces/libpq/po/ka.po b/src/interfaces/libpq/po/ka.po index dd3ea1120e8..29499ab708d 100644 --- a/src/interfaces/libpq/po/ka.po +++ b/src/interfaces/libpq/po/ka.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: libpq (PostgreSQL) 19\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-06-11 12:10+0000\n" -"PO-Revision-Date: 2026-06-11 15:57+0200\n" +"POT-Creation-Date: 2026-07-25 01:40+0000\n" +"PO-Revision-Date: 2026-07-25 04:37+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian \n" "Language: ka\n" @@ -31,7 +31,7 @@ msgstr "გაფრთხილება: libcurl-ის დამმუშა #: ../libpq-oauth/oauth-curl.c:393 ../libpq-oauth/oauth-curl.c:1857 #: ../libpq-oauth/oauth-curl.c:1898 ../libpq-oauth/oauth-curl.c:2216 #: ../libpq-oauth/oauth-curl.c:2377 ../libpq-oauth/oauth-curl.c:2437 -#: ../libpq-oauth/oauth-curl.c:2525 ../libpq-oauth/oauth-curl.c:3161 +#: ../libpq-oauth/oauth-curl.c:2525 ../libpq-oauth/oauth-curl.c:3178 #: fe-auth-oauth.c:153 fe-auth-oauth.c:496 fe-auth-oauth.c:568 #: fe-auth-oauth.c:776 fe-auth-oauth.c:1065 fe-auth-oauth.c:1077 #: fe-auth-oauth.c:1163 fe-auth-oauth.c:1176 fe-auth-oauth.c:1312 @@ -47,13 +47,13 @@ msgstr "გაფრთხილება: libcurl-ის დამმუშა #: fe-connect.c:6860 fe-connect.c:6946 fe-connect.c:6954 fe-connect.c:7311 #: fe-connect.c:7493 fe-connect.c:8106 fe-connect.c:8147 fe-exec.c:531 #: fe-exec.c:1332 fe-exec.c:3285 fe-exec.c:4340 fe-exec.c:4533 -#: fe-gssapi-common.c:109 fe-lobj.c:870 fe-protocol3.c:213 fe-protocol3.c:236 -#: fe-protocol3.c:259 fe-protocol3.c:276 fe-protocol3.c:297 fe-protocol3.c:371 -#: fe-protocol3.c:752 fe-protocol3.c:992 fe-protocol3.c:1607 -#: fe-protocol3.c:1661 fe-protocol3.c:1707 fe-protocol3.c:1728 -#: fe-protocol3.c:1985 fe-protocol3.c:2397 fe-secure-common.c:110 -#: fe-secure-gssapi.c:508 fe-secure-gssapi.c:699 fe-secure-openssl.c:405 -#: fe-secure-openssl.c:1136 +#: fe-gssapi-common.c:109 fe-lobj.c:870 fe-protocol3.c:214 fe-protocol3.c:237 +#: fe-protocol3.c:260 fe-protocol3.c:277 fe-protocol3.c:298 fe-protocol3.c:372 +#: fe-protocol3.c:753 fe-protocol3.c:993 fe-protocol3.c:1608 +#: fe-protocol3.c:1662 fe-protocol3.c:1708 fe-protocol3.c:1729 +#: fe-protocol3.c:1986 fe-protocol3.c:2398 fe-secure-common.c:110 +#: fe-secure-gssapi.c:515 fe-secure-gssapi.c:706 fe-secure-openssl.c:436 +#: fe-secure-openssl.c:1167 #, c-format msgid "out of memory" msgstr "არასაკმარისი მეხსიერება" @@ -241,15 +241,15 @@ msgstr "გადადით %s-ზე და შეიყვანეთ კ msgid "device prompt failed" msgstr "მოწყობილობის მოთხოვნა ჩავარდა" -#: ../libpq-oauth/oauth-curl.c:2724 +#: ../libpq-oauth/oauth-curl.c:2722 msgid "curl_global_init previously failed during OAuth setup" msgstr "curl_global_init უკვე ჩავარდა OAuth-ის მორგებისას" -#: ../libpq-oauth/oauth-curl.c:2742 +#: ../libpq-oauth/oauth-curl.c:2740 msgid "curl_global_init failed during OAuth setup" msgstr "curl_global_init ჩავარდა OAuth-ის მორგებისას" -#: ../libpq-oauth/oauth-curl.c:2763 +#: ../libpq-oauth/oauth-curl.c:2762 msgid "" "libcurl is no longer thread-safe\n" "\tCurl initialization was reported thread-safe when libpq\n" @@ -263,19 +263,19 @@ msgstr "" "\tამჟამადაა დაყენებული, როგორც ჩანს, არაა. ააგეთ libpq-ი libcurl-ით, რომელიც\n" "\tახლა გაქვთ დაყენებული." -#: ../libpq-oauth/oauth-curl.c:2887 +#: ../libpq-oauth/oauth-curl.c:2902 msgid "could not fetch OpenID discovery document" msgstr "OpenID-ის აღმოჩენის დოკუმენტის გამოთხოვა შეუძლებელია" -#: ../libpq-oauth/oauth-curl.c:2901 +#: ../libpq-oauth/oauth-curl.c:2916 msgid "cannot run OAuth device authorization" msgstr "OAuth მოწყობილობის ავტორიზაციის გაშვება შეუძლებელია" -#: ../libpq-oauth/oauth-curl.c:2905 +#: ../libpq-oauth/oauth-curl.c:2920 msgid "could not obtain device authorization" msgstr "მოწყობილობის ავტორიზაციის მიღება შეუძლებელია" -#: ../libpq-oauth/oauth-curl.c:2916 ../libpq-oauth/oauth-curl.c:2967 +#: ../libpq-oauth/oauth-curl.c:2931 ../libpq-oauth/oauth-curl.c:2982 msgid "could not obtain access token" msgstr "წვდომის ტოკენის მიღება შეუძლებელია" @@ -712,7 +712,7 @@ msgstr "პაროლის დაშიფვრის უცნობი ა msgid "connection pointer is NULL" msgstr "შეერთების მაჩვენებელი ნულოვანია" -#: fe-cancel.c:85 fe-misc.c:613 +#: fe-cancel.c:85 fe-misc.c:621 #, c-format msgid "connection not open" msgstr "შეერთება ღია არაა" @@ -742,7 +742,7 @@ msgstr "%d ჰოსტის სახელები %d ჰოსტის მ msgid "could not match %d port numbers to %d hosts" msgstr "%d პორტის ნომრები %d ჰოსტს არ ემთხვევა" -#: fe-connect.c:1480 fe-exec.c:532 fe-protocol3.c:2191 +#: fe-connect.c:1480 fe-exec.c:532 fe-protocol3.c:2192 #, c-format msgid "%s" msgstr "%s" @@ -1258,7 +1258,7 @@ msgid "connection pointer is NULL\n" msgstr "შეერთების მაჩვენებელი ნულოვანია\n" #: fe-connect.c:7765 fe-exec.c:719 fe-exec.c:981 fe-exec.c:3490 -#: fe-protocol3.c:1007 fe-protocol3.c:1040 +#: fe-protocol3.c:1008 fe-protocol3.c:1041 msgid "out of memory\n" msgstr "არასაკმარისი მეხსიერება\n" @@ -1373,7 +1373,7 @@ msgstr "COPY BOTH-ის დროს PQexec დაუშვებელია" msgid "unrecognized message type \"%c\"" msgstr "შეტყობინების უცნობი ტიპი: \"%c\"" -#: fe-exec.c:2719 fe-exec.c:2773 fe-exec.c:2841 fe-protocol3.c:2122 +#: fe-exec.c:2719 fe-exec.c:2773 fe-exec.c:2841 fe-protocol3.c:2123 #, c-format msgid "no COPY in progress" msgstr "ბრძანება COPY გაშვებული არაა" @@ -1497,18 +1497,18 @@ msgstr "ფაილში (\"%s\") ჩაწერის შეცდომა: msgid "query to initialize large object functions did not return data" msgstr "დიდი ობიექტის ფუნქციების ინიციალიზაციის მოთხოვნას შედეგ არ დაუბრუნებია" -#: fe-misc.c:239 +#: fe-misc.c:241 #, c-format msgid "integer of size %zu not supported by pqGetInt" msgstr "%zu-ის მთელი რიცხვის ზომა მხარდაუჭერელია pqGetInt-is მიერ" -#: fe-misc.c:272 +#: fe-misc.c:274 #, c-format msgid "integer of size %zu not supported by pqPutInt" msgstr "%zu-ის მთელი რიცხვის ზომა მხარდაუჭერელია pqPutInt-is მიერ" -#: fe-misc.c:791 fe-secure-openssl.c:181 fe-secure-openssl.c:287 -#: fe-secure.c:222 fe-secure.c:389 +#: fe-misc.c:833 fe-secure-openssl.c:182 fe-secure-openssl.c:318 +#: fe-secure.c:222 fe-secure.c:413 #, c-format msgid "" "server closed the connection unexpectedly\n" @@ -1519,26 +1519,31 @@ msgstr "" "\tეს დიდი ალბათობით ნიშნავს, რომ სერვერის პროცესი \n" "\tმოულოდნელად, მოთხოვნამდე ან მოთხოვნის შესრულებსას დასრულდა." -#: fe-misc.c:858 +#: fe-misc.c:942 +#, c-format +msgid "drained only %zd of %zd pending bytes in transport buffer" +msgstr "ტრანსპორტის ბუფერიდან აღებულია, მხოლოდ, %zd ბაიტი %zd-დან" + +#: fe-misc.c:1004 msgid "connection not open\n" msgstr "შეერთება ღია არაა\n" -#: fe-misc.c:1046 +#: fe-misc.c:1192 #, c-format msgid "timeout expired" msgstr "მოლოდინის დრო გავიდა" -#: fe-misc.c:1098 +#: fe-misc.c:1244 #, c-format msgid "invalid socket" msgstr "არასწორი სოკეტი" -#: fe-misc.c:1121 +#: fe-misc.c:1265 #, c-format msgid "%s() failed: %s" msgstr "%s()-ის შეცდომა: %s" -#: fe-misc.c:1436 +#: fe-misc.c:1580 #, c-format msgid "" "\tThis indicates a bug in either the server being contacted\n" @@ -1555,211 +1560,211 @@ msgstr "" "\tეწვიეთ ვებგვერდს\n" "\t\t%s" -#: fe-protocol3.c:191 +#: fe-protocol3.c:192 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "შეტყობინების ტიპი 0x%02x მოვიდა სერვერიდან, როცა უქმე ვიყავი" -#: fe-protocol3.c:404 +#: fe-protocol3.c:405 #, c-format msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" msgstr "სერვერმა მონაცემები (\"D\" შეტყობინება) მწკრივების წინასწარი აღწერის (\"T\" შეტყობინება) გარეშე გამოაგზავნა" -#: fe-protocol3.c:446 +#: fe-protocol3.c:447 #, c-format msgid "unexpected response from server; first received character was \"%c\"" msgstr "სერვერის მოულოდნელი პასუხი; პირველი მიღებული სიმბოლოა \"%c\"" -#: fe-protocol3.c:470 +#: fe-protocol3.c:471 #, c-format msgid "message contents do not agree with length in message type \"%c\"" msgstr "შეტყობინების შიგთავსი შეტყობინების ამ ტიპის (%c) სიგრძეს არ ემთხვევა" -#: fe-protocol3.c:505 +#: fe-protocol3.c:506 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d" msgstr "სერვერთან სინქრონიზაციის შეცდომა: შეტყობინების ტიპი: \"%c\", სიგრძე %d" -#: fe-protocol3.c:552 fe-protocol3.c:592 +#: fe-protocol3.c:553 fe-protocol3.c:593 msgid "insufficient data in \"T\" message" msgstr "არასაკმარისი მონაცემები \"T\" შეტყობინებაში" -#: fe-protocol3.c:663 fe-protocol3.c:869 +#: fe-protocol3.c:664 fe-protocol3.c:870 msgid "out of memory for query result" msgstr "არასაკმარისი მეხსიერება მოთხოვნის შედეგისთვის" -#: fe-protocol3.c:732 +#: fe-protocol3.c:733 msgid "insufficient data in \"t\" message" msgstr "არასაკმარისი მონაცემები \"t\" შეტყობინებაში" -#: fe-protocol3.c:791 fe-protocol3.c:823 fe-protocol3.c:841 +#: fe-protocol3.c:792 fe-protocol3.c:824 fe-protocol3.c:842 msgid "insufficient data in \"D\" message" msgstr "არასაკმარისი მონაცემები \"D\" შეტყობინებაში" -#: fe-protocol3.c:797 +#: fe-protocol3.c:798 msgid "unexpected field count in \"D\" message" msgstr "ველების მოულოდნელი რაოდენობა \"D\" შეტყობინებაში" -#: fe-protocol3.c:1053 +#: fe-protocol3.c:1054 msgid "no error message available\n" msgstr "შეცდომის შეტყობინების გარეშე\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1101 fe-protocol3.c:1120 +#: fe-protocol3.c:1102 fe-protocol3.c:1121 #, c-format msgid " at character %s" msgstr " სიმბოლოსთან %s" -#: fe-protocol3.c:1133 +#: fe-protocol3.c:1134 #, c-format msgid "DETAIL: %s\n" msgstr "დეტალი: %s\n" -#: fe-protocol3.c:1136 +#: fe-protocol3.c:1137 #, c-format msgid "HINT: %s\n" msgstr "მინიშნება: %s\n" -#: fe-protocol3.c:1139 +#: fe-protocol3.c:1140 #, c-format msgid "QUERY: %s\n" msgstr "მოთხოვნა: %s\n" -#: fe-protocol3.c:1146 +#: fe-protocol3.c:1147 #, c-format msgid "CONTEXT: %s\n" msgstr "კონტექსტი: %s\n" -#: fe-protocol3.c:1155 +#: fe-protocol3.c:1156 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "სქემის სახელი: %s\n" -#: fe-protocol3.c:1159 +#: fe-protocol3.c:1160 #, c-format msgid "TABLE NAME: %s\n" msgstr "ცხრილის სახელი: %s\n" -#: fe-protocol3.c:1163 +#: fe-protocol3.c:1164 #, c-format msgid "COLUMN NAME: %s\n" msgstr "სვეტის სახელი: %s\n" -#: fe-protocol3.c:1167 +#: fe-protocol3.c:1168 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "მონ. ტიპის სახელი: %s\n" -#: fe-protocol3.c:1171 +#: fe-protocol3.c:1172 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "შეზღუდვის სახელი: %s\n" -#: fe-protocol3.c:1183 +#: fe-protocol3.c:1184 msgid "LOCATION: " msgstr "მდებარეობა: " -#: fe-protocol3.c:1185 +#: fe-protocol3.c:1186 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1187 +#: fe-protocol3.c:1188 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1395 +#: fe-protocol3.c:1396 #, c-format msgid "LINE %d: " msgstr "ხაზი %d: " -#: fe-protocol3.c:1472 +#: fe-protocol3.c:1473 #, c-format msgid "received invalid protocol negotiation message: server requested \"grease\" protocol version 3.9999" msgstr "მიღებულია არასწორი პროტოკოლის მიმოცვლის შეტყობინება: სერვერმა მოითხოვა \"ქონიანი\" პროტოკოლის ვერსია 3.9999" -#: fe-protocol3.c:1478 +#: fe-protocol3.c:1479 #, c-format msgid "received invalid protocol negotiation message: server requested downgrade to a higher-numbered version" msgstr "მიღებულია არასწორი პროტოკოლის მიმოცვლის შეტყობინება: სერვერმა მოითხოვა ვერსიის ჩამოწევა უფრო მაღალ ვერსიაზე" -#: fe-protocol3.c:1484 +#: fe-protocol3.c:1485 #, c-format msgid "received invalid protocol negotiation message: server requested downgrade to pre-3.0 protocol version" msgstr "მიღებულია არასწორი პროტოკოლის მიმოცვლის შეტყობინება: სერვერმა მოითხოვა ვერსიის ჩამოწევა 3.0-მდელ ვერსიაზე" -#: fe-protocol3.c:1491 +#: fe-protocol3.c:1492 #, c-format msgid "received invalid protocol negotiation message: server requested downgrade to non-existent 3.1 protocol version" msgstr "მიღებულია არასწორი პროტოკოლის ხელის ჩამორთმევის შეტყობინება: სერვერი ითხოვს ვერსიის ჩამოწევას არარსებულ პროტოკოლის ვერსიაზე 3.1" -#: fe-protocol3.c:1497 +#: fe-protocol3.c:1498 #, c-format msgid "received invalid protocol negotiation message: server reported negative number of unsupported parameters" msgstr "მიღებულია არასწორი პროტოკოლის მიმოცვლის შეტყობინება: სერვერმა მხარდაუჭერელი პარამეტრების უარყოფითი რაოდენობა გადმოგვცა" -#: fe-protocol3.c:1503 +#: fe-protocol3.c:1504 #, c-format msgid "received invalid protocol negotiation message: server negotiated but asks for no changes" msgstr "მიღებულია არასწორი პროტოკოლის მიმოცვლის შეტყობინება: სერვერთან კავშირი დამყარდა, მაგრამ ის ცვლილებებს არ ითხოვს" -#: fe-protocol3.c:1509 +#: fe-protocol3.c:1510 #, c-format msgid "server only supports protocol version %d.%d, but \"%s\" was set to %d.%d" msgstr "სერვერს, მხოლოდ, %d.%d ვერსიის პროტოკოლის მხარდაჭერა აქვს, მაგრამ \"%s\"-ის მნიშვნელობაა %d.%d" -#: fe-protocol3.c:1538 +#: fe-protocol3.c:1539 #, c-format msgid "received invalid protocol negotiation message: server reported unsupported parameter name without a \"%s\" prefix (\"%s\")" msgstr "მიღებულია არასწორი პროტოკოლის მოლაპარაკების შეტყობინება: სერვერმა მოიწერა მხარდაუჭერელი პარამეტრის სახელი \"%s\" პრეფიქსის გარეშე (\"%s\")" -#: fe-protocol3.c:1550 +#: fe-protocol3.c:1551 #, c-format msgid "received invalid protocol negotiation message: server reported an unsupported parameter that was not requested (\"%s\")" msgstr "მიღებულია არასწორი პროტოკოლის მიმოცვლის შეტყობინება: სერვერმა მოიწერა მხარდაუჭერელი პარამეტრი, რომელიც მას არ მოუთხოვია (\"%s\")" -#: fe-protocol3.c:1563 +#: fe-protocol3.c:1564 #, c-format msgid "server did not report the unsupported \"%s\" parameter in its protocol negotiation message" msgstr "სერვერმა არ შეგვატყობინა მხარდაუჭერელი პარამეტრის '%s' არსებობის შესახებ პროტოკოლის მოლაპარაკების შეტყობინებაში" -#: fe-protocol3.c:1571 +#: fe-protocol3.c:1572 #, c-format msgid "received invalid protocol negotiation message: message too short" msgstr "მიღებულია არასწორი პროტოკოლის მიმოცვლის შეტყობინება; შეტყობინება მეტისმეტად მოკლეა" -#: fe-protocol3.c:1639 +#: fe-protocol3.c:1640 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d not allowed in protocol version 3.0 (must be 4 bytes)" msgstr "მიღებულია არასწორი შეტყობინება BackendKeyData: გაუქმების გასაღები სიგრძით %d დაუშვებელია პროტოკოლის ვერსიაში 3.0 (უნდა იყო 4 ბაიტი)" -#: fe-protocol3.c:1646 +#: fe-protocol3.c:1647 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d is too short (minimum 4 bytes)" msgstr "მიღებულია არასწორი შეტყობინება BackendKeyData: გაუქმების გასაღები სიგრძით %d ძალიან მოკლეა (უნდა იყო 4 ბაიტი)" -#: fe-protocol3.c:1653 +#: fe-protocol3.c:1654 #, c-format msgid "received invalid BackendKeyData message: cancel key with length %d is too long (maximum 256 bytes)" msgstr "მიღებულია არასწორი შეტყობინება BackendKeyData: გაუქმების გასაღები სიგრძით %d ძალიან გრძელია (მაქს 256 ბაიტი)" -#: fe-protocol3.c:2017 +#: fe-protocol3.c:2018 #, c-format msgid "PQgetline: not doing text COPY OUT" msgstr "PQgetline: ტექსტის COPY OUT-ს არ გავაკეთებ" -#: fe-protocol3.c:2348 +#: fe-protocol3.c:2349 #, c-format msgid "server returned too much data" msgstr "სერვერმა მეტისმეტად ბევრი მონაცემები გამოაგზავნა" -#: fe-protocol3.c:2403 +#: fe-protocol3.c:2404 #, c-format msgid "protocol error: no function result" msgstr "პროტოკოლის შეცდომა: ფუნქციის შედეგის გარეშე" -#: fe-protocol3.c:2415 +#: fe-protocol3.c:2416 #, c-format msgid "protocol error: id=0x%x" msgstr "პროტოკოლის შეცდომა: id=0x%x" @@ -1810,12 +1815,12 @@ msgstr "GSSAPI -ის გადატანის შეცდომა" msgid "outgoing GSSAPI message would not use confidentiality" msgstr "გამავალი GSSAPI შეტყობინება კონფიდენციალობას ვერ იყენებს" -#: fe-secure-gssapi.c:215 fe-secure-gssapi.c:726 +#: fe-secure-gssapi.c:215 fe-secure-gssapi.c:733 #, c-format msgid "client tried to send oversize GSSAPI packet (%zu > %zu)" msgstr "კლიენტი ძალიან დიდი GSSAPI პაკეტების გაგზავნას ცდილობს (%zu > %zu)" -#: fe-secure-gssapi.c:354 fe-secure-gssapi.c:602 +#: fe-secure-gssapi.c:354 fe-secure-gssapi.c:609 #, c-format msgid "oversize GSSAPI packet sent by the server (%zu > %zu)" msgstr "სერვერის მიერ გამოგზავნილი GSSAPI-ის პაკეტი ძალიან დიდია (%zu > %zu)" @@ -1829,110 +1834,120 @@ msgstr "GSSAPI-ის გადატანის მოხსნის შე msgid "incoming GSSAPI message did not use confidentiality" msgstr "შემომავალი GSSAPI შეტყობინება კონფიდენციალობას ვერ იყენებს" -#: fe-secure-gssapi.c:665 +#: fe-secure-gssapi.c:672 msgid "could not initiate GSSAPI security context" msgstr "'GSSAPI' უსაფრთხოების კონტექსტის დაწყების შეცდომა" -#: fe-secure-gssapi.c:715 +#: fe-secure-gssapi.c:722 msgid "GSSAPI size check error" msgstr "GSSAPI-ის ზომის შემოწმების შეცდომა" -#: fe-secure-openssl.c:185 fe-secure-openssl.c:291 fe-secure-openssl.c:1383 +#: fe-secure-openssl.c:186 fe-secure-openssl.c:322 fe-secure-openssl.c:1414 #, c-format msgid "SSL SYSCALL error: %s" msgstr "SSL SYSCALL-ის შეცდომა: %s" -#: fe-secure-openssl.c:191 fe-secure-openssl.c:297 fe-secure-openssl.c:1386 +#: fe-secure-openssl.c:192 fe-secure-openssl.c:328 fe-secure-openssl.c:1417 #, c-format msgid "SSL SYSCALL error: EOF detected" msgstr "SSL SYSCALL -ის შეცდომა: ნაპოვნია EOF" -#: fe-secure-openssl.c:201 fe-secure-openssl.c:307 fe-secure-openssl.c:1394 +#: fe-secure-openssl.c:202 fe-secure-openssl.c:338 fe-secure-openssl.c:1425 #, c-format msgid "SSL error: %s" msgstr "SSL-ის შეცდომა: %s" -#: fe-secure-openssl.c:215 fe-secure-openssl.c:321 +#: fe-secure-openssl.c:216 fe-secure-openssl.c:352 #, c-format msgid "SSL connection has been closed unexpectedly" msgstr "SSL შეერთება მოულოდნელად დაიხურა" -#: fe-secure-openssl.c:220 fe-secure-openssl.c:326 fe-secure-openssl.c:1441 +#: fe-secure-openssl.c:221 fe-secure-openssl.c:357 fe-secure-openssl.c:1472 #, c-format msgid "unrecognized SSL error code: %d" msgstr "უცნობი SSL-ის შეცდომის კოდი: %d" -#: fe-secure-openssl.c:368 +#: fe-secure-openssl.c:251 +#, c-format +msgid "OpenSSL reports negative bytes pending" +msgstr "OpenSSL-მა შეგვატყობინა უარყოფითი დარჩენილი ბაიტის შესახებ" + +#: fe-secure-openssl.c:263 +#, c-format +msgid "OpenSSL reports INT_MAX bytes pending" +msgstr "OpenSSL-მა შეგვატყობინა, რომ დარჩენილია INT_MAX ბაიტი" + +#: fe-secure-openssl.c:399 #, c-format msgid "could not determine server certificate signature algorithm" msgstr "სერვერის სერტიფიკატის ხელმოწერის ალგორითმის დადგენა შეუძლებელია" -#: fe-secure-openssl.c:388 +#: fe-secure-openssl.c:419 #, c-format msgid "could not find digest for NID %s" msgstr "'NID'-ისთვის (%s) დაიჯესტის პოვნა შეუძლებელია" -#: fe-secure-openssl.c:397 +#: fe-secure-openssl.c:428 #, c-format msgid "could not generate peer certificate hash" msgstr "პარტნიორის სერტიფიკატის ჰეშის გენერირების შეცდომა" -#: fe-secure-openssl.c:480 +#: fe-secure-openssl.c:511 #, c-format msgid "SSL certificate's name entry is missing" msgstr "SSL სერტიფიკატის სახელის ჩანაწერი არ არსებობს" -#: fe-secure-openssl.c:510 +#: fe-secure-openssl.c:541 #, c-format msgid "SSL certificate's address entry is missing" msgstr "SSL სერტიფიკატის მისამართის ჩანაწერი არ არსებობს" -#: fe-secure-openssl.c:716 +#: fe-secure-openssl.c:747 #, c-format msgid "WARNING: could not open SSL key logging file \"%s\": %m\n" msgstr "გაფრთხილება: ვერ გავხსენი SSL გასაღების ჟურნალის ფაილი \"%s\": %m\n" -#: fe-secure-openssl.c:724 +#: fe-secure-openssl.c:755 #, c-format msgid "WARNING: could not write to SSL key logging file \"%s\": %m\n" msgstr "გაფრთხილება: SSL გასაღების ჟურნალის ფაილში \"%s\" ჩაწერის შეცდომა: %m\n" -#: fe-secure-openssl.c:777 +#: fe-secure-openssl.c:808 #, c-format msgid "could not create SSL context: %s" msgstr "შეცდომა SSL კონტექსტის შექმნისას: %s" -#: fe-secure-openssl.c:819 +#: fe-secure-openssl.c:850 #, c-format msgid "invalid value \"%s\" for minimum SSL protocol version" msgstr "'SSL' პროტოკოლის ვერსიის არასწორი მინიმალური მნიშვნელობა: %s" -#: fe-secure-openssl.c:829 +#: fe-secure-openssl.c:860 #, c-format msgid "could not set minimum SSL protocol version: %s" msgstr "'SSL' პროტოკოლის ვერსიის მინიმალური მნიშვნელობის დაყენების შეცდომა: %s" -#: fe-secure-openssl.c:845 +#: fe-secure-openssl.c:876 #, c-format msgid "invalid value \"%s\" for maximum SSL protocol version" msgstr "'SSL' პროტოკოლის ვერსიის არასწორი მაქსიმალური მნიშვნელობა: %s" -#: fe-secure-openssl.c:855 +#: fe-secure-openssl.c:886 #, c-format msgid "could not set maximum SSL protocol version: %s" msgstr "'SSL' პროტოკოლის ვერსიის მაქსიმალური მნიშვნელობის დაყენების შეცდომა: %s" -#: fe-secure-openssl.c:893 +#: fe-secure-openssl.c:924 #, c-format msgid "could not load system root certificate paths: %s" msgstr "სისტემური root სერტიფიკატების ბილიკების ჩატვირთვის შეცდომა: %s" -#: fe-secure-openssl.c:910 +#: fe-secure-openssl.c:941 #, c-format msgid "could not read root certificate file \"%s\": %s" msgstr "root სერტიფიკატის ფაილის (\"%s\") წაკითხვის შეცდომა: %s" -#: fe-secure-openssl.c:962 +#: fe-secure-openssl.c:993 #, c-format msgid "" "could not get home directory to locate root certificate file\n" @@ -1941,7 +1956,7 @@ msgstr "" "root სერტიფიკატის ფაილის მოსაძებნად საწყისი საქაღალდის მიღება შეუძლებელია\n" "ამ წარმოადგინეთ ფაილი, ან გამოიყენეთ სისტემის სანდო root-ები პარამეტრით sslrootcert=system, ან sslmode სერვერის სერტიფიკატის შემოწმება გამორთეთ." -#: fe-secure-openssl.c:965 +#: fe-secure-openssl.c:996 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -1950,127 +1965,127 @@ msgstr "" "root სერტიფიკატის ფაილი \"%s\" არ არსებობს\n" "წარმოადგინეთ ფაილი ან გამორთეთ sslmode სერვერის სერტიფიკატის შემოწმება." -#: fe-secure-openssl.c:1000 +#: fe-secure-openssl.c:1031 #, c-format msgid "could not open certificate file \"%s\": %s" msgstr "სერტიფიკატის ფაილის გახსნის შეცდომა \"%s\": %s" -#: fe-secure-openssl.c:1018 +#: fe-secure-openssl.c:1049 #, c-format msgid "could not read certificate file \"%s\": %s" msgstr "სერტიფიკატის ფაილის წაკითხვის შეცდომა \"%s\": %s" -#: fe-secure-openssl.c:1042 +#: fe-secure-openssl.c:1073 #, c-format msgid "could not establish SSL connection: %s" msgstr "'SSL' შეერთების დამყარების შეცდომა: %s" -#: fe-secure-openssl.c:1059 +#: fe-secure-openssl.c:1090 #, c-format msgid "WARNING: sslkeylogfile support requires OpenSSL\n" msgstr "გაფრთხილება: sslkeylogfile-ის მხარდაჭერას OpenSSL სჭირდება\n" -#: fe-secure-openssl.c:1061 +#: fe-secure-openssl.c:1092 #, c-format msgid "WARNING: libpq was not built with sslkeylogfile support\n" msgstr "გაფრთხილება: libpq არ იყო აგებული sslkeylogfile-ის მხარდაჭერით\n" -#: fe-secure-openssl.c:1091 +#: fe-secure-openssl.c:1122 #, c-format msgid "could not set SSL Server Name Indication (SNI): %s" msgstr "'SSL' სერვერის სახელის ინდიკაციის (SNI) დაყენების შეცდომა: %s" -#: fe-secure-openssl.c:1108 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not set SSL ALPN extension: %s" msgstr "\"SSL ALPN\" გაფართოების დაყენების შეცდომა: %s" -#: fe-secure-openssl.c:1151 +#: fe-secure-openssl.c:1182 #, c-format msgid "could not load SSL engine \"%s\": %s" msgstr "'SSL' ძრავის (\"%s\") ჩატვირთვის შეცდომა: %s" -#: fe-secure-openssl.c:1162 +#: fe-secure-openssl.c:1193 #, c-format msgid "could not initialize SSL engine \"%s\": %s" msgstr "'SSL' ძრავის (\"%s\") ინიციალიზაციის შეცდომა: %s" -#: fe-secure-openssl.c:1177 +#: fe-secure-openssl.c:1208 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s" msgstr "'SSL'-ის პირადი გასაღების (\"%s\") ძრავიდან (\"%s\") წაკითხვის შეცდომა: %s" -#: fe-secure-openssl.c:1190 +#: fe-secure-openssl.c:1221 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s" msgstr "'SSL'-ის პირადი გასაღების (\"%s\") ძრავიდან (\"%s\") წაკითხვის შეცდომა: %s" -#: fe-secure-openssl.c:1227 +#: fe-secure-openssl.c:1258 #, c-format msgid "certificate present, but not private key file \"%s\"" msgstr "სერტიფიკატისგან განსხვავებით, პირადი გასაღების ფაილი \"%s\" არ არსებობს" -#: fe-secure-openssl.c:1230 +#: fe-secure-openssl.c:1261 #, c-format msgid "could not stat private key file \"%s\": %m" msgstr "პირადი გასაღების ფაილი \"%s\" არ არსებობს: %m" -#: fe-secure-openssl.c:1238 +#: fe-secure-openssl.c:1269 #, c-format msgid "private key file \"%s\" is not a regular file" msgstr "პირადი გასაღების ფაილი \"%s\" ჩვეულებრივი ფაილი არაა" -#: fe-secure-openssl.c:1271 +#: fe-secure-openssl.c:1302 #, c-format msgid "private key file \"%s\" has group or world access; file must have permissions u=rw (0600) or less if owned by the current user, or permissions u=rw,g=r (0640) or less if owned by root" msgstr "პირადი გასაღების ფაილს \"%s\" აქვს ჯგუფური ან ყველა სხვაზე წვდომა; ფაილს უნდა ჰქონდეს ნებართვები u=rw (0600) ან ნაკლები, თუ ეკუთვნის ამჟამინდელ მომხმარებელს, ან ნებართვები u=rw,g=r (0640) ან ნაკლები, თუ ეკუთვნის root-ს" -#: fe-secure-openssl.c:1295 +#: fe-secure-openssl.c:1326 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "პირადი გასაღების ფაილის \"%s\" ჩატვირთვის შეცდომა: %s" -#: fe-secure-openssl.c:1311 +#: fe-secure-openssl.c:1342 #, c-format msgid "certificate does not match private key file \"%s\": %s" msgstr "სერტიფიკატი პირადი გასაღების ფაილს (\"%s\") არ ემთხვევა: %s" -#: fe-secure-openssl.c:1380 +#: fe-secure-openssl.c:1411 #, c-format msgid "SSL error: certificate verify failed: %s" msgstr "SSL-ის შეცდომა: სერტიფიკატის გადამოწმების შეცდომა: %s" -#: fe-secure-openssl.c:1425 +#: fe-secure-openssl.c:1456 #, c-format msgid "This may indicate that the server does not support any SSL protocol version between %s and %s." msgstr "ეს შეიძლება ნიშნავდეს, რომ სერვერს SSL პროტოკოლის %s-სა და %s-ს შორის ვერსიების მხარდაჭერა არ გააჩნია." -#: fe-secure-openssl.c:1457 +#: fe-secure-openssl.c:1488 #, c-format msgid "direct SSL connection was established without ALPN protocol negotiation extension" msgstr "პირდაპირი SSL მიერთება დამყარდა ALPN პროტოკოლის მიმოცვლის გაფართოების გარეშე" -#: fe-secure-openssl.c:1469 +#: fe-secure-openssl.c:1500 #, c-format msgid "SSL connection was established with unexpected ALPN protocol" msgstr "SSL შეერთება დამყარდა მოულოდნელი ALPN პროტოკოლით" -#: fe-secure-openssl.c:1486 +#: fe-secure-openssl.c:1517 #, c-format msgid "certificate could not be obtained: %s" msgstr "სერტიფიკატის მიღების შეცდომა: %s" -#: fe-secure-openssl.c:1565 +#: fe-secure-openssl.c:1596 #, c-format msgid "no SSL error reported" msgstr "'SSL'-ის შეცდომების გარეშე" -#: fe-secure-openssl.c:1608 +#: fe-secure-openssl.c:1639 #, c-format msgid "SSL error code %lu" msgstr "SSL-ის შეცდომის კოდი %lu" -#: fe-secure-openssl.c:1910 +#: fe-secure-openssl.c:1941 #, c-format msgid "WARNING: sslpassword truncated\n" msgstr "გაფრთხილება: sslpasswrord შეკვეცილია\n" @@ -2080,7 +2095,7 @@ msgstr "გაფრთხილება: sslpasswrord შეკვეცილ msgid "could not receive data from server: %s" msgstr "სერვერიდან მონაცემების მიღების შეცდომა: %s" -#: fe-secure.c:404 +#: fe-secure.c:428 #, c-format msgid "could not send data to server: %s" msgstr "სერვერისთვის მონაცემების გაგზავნის შეცდომა: %s" @@ -2089,4 +2104,3 @@ msgstr "სერვერისთვის მონაცემების #, c-format msgid "unrecognized socket error: 0x%08X/%d" msgstr "სოკეტის უცნობი შეცდომა: 0x%08X/%d" - diff --git a/src/interfaces/libpq/po/ru.po b/src/interfaces/libpq/po/ru.po index 16cb5c66728..eaaa31f70fe 100644 --- a/src/interfaces/libpq/po/ru.po +++ b/src/interfaces/libpq/po/ru.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: libpq (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2026-02-07 08:57+0200\n" -"PO-Revision-Date: 2026-02-07 10:48+0200\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:41+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -21,99 +21,99 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ../libpq-oauth/oauth-curl.c:308 ../libpq-oauth/oauth-curl.c:2011 +#: ../libpq-oauth/oauth-curl.c:309 ../libpq-oauth/oauth-curl.c:2012 #, c-format msgid "libcurl easy handle removal failed: %s" msgstr "ошибка при удалении простого указателя libcurl: %s" -#: ../libpq-oauth/oauth-curl.c:328 +#: ../libpq-oauth/oauth-curl.c:329 #, c-format msgid "libcurl multi handle cleanup failed: %s" msgstr "ошибка при очистке множественного указателя libcurl: %s" -#: ../libpq-oauth/oauth-curl.c:394 ../libpq-oauth/oauth-curl.c:405 +#: ../libpq-oauth/oauth-curl.c:395 ../libpq-oauth/oauth-curl.c:406 #, c-format msgid "failed to set %s on OAuth connection: %s" msgstr "не удалось задать %s для подключения OAuth: %s" -#: ../libpq-oauth/oauth-curl.c:416 +#: ../libpq-oauth/oauth-curl.c:417 #, c-format msgid "failed to get %s from OAuth response: %s" msgstr "не удалось получить %s из ответа OAuth: %s" -#: ../libpq-oauth/oauth-curl.c:485 fe-auth-oauth.c:209 fe-auth-oauth.c:271 +#: ../libpq-oauth/oauth-curl.c:486 fe-auth-oauth.c:209 fe-auth-oauth.c:271 #: fe-auth-oauth.c:333 #, c-format msgid "field \"%s\" must be a string" msgstr "поле \"%s\" должно быть строковым" -#: ../libpq-oauth/oauth-curl.c:489 +#: ../libpq-oauth/oauth-curl.c:490 #, c-format msgid "field \"%s\" must be a number" msgstr "поле \"%s\" должно быть числовым" -#: ../libpq-oauth/oauth-curl.c:493 +#: ../libpq-oauth/oauth-curl.c:494 #, c-format msgid "field \"%s\" must be an array of strings" msgstr "поле \"%s\" должно содержать массив строк" -#: ../libpq-oauth/oauth-curl.c:498 +#: ../libpq-oauth/oauth-curl.c:499 #, c-format msgid "field \"%s\" has unexpected type" msgstr "поле \"%s\" имеет неожиданный тип" -#: ../libpq-oauth/oauth-curl.c:522 ../libpq-oauth/oauth-curl.c:632 +#: ../libpq-oauth/oauth-curl.c:523 ../libpq-oauth/oauth-curl.c:633 #: fe-auth-oauth.c:215 fe-auth-oauth.c:277 #, c-format msgid "JSON is too deeply nested" msgstr "слишком большая вложенность в JSON" -#: ../libpq-oauth/oauth-curl.c:574 fe-auth-oauth.c:324 +#: ../libpq-oauth/oauth-curl.c:575 fe-auth-oauth.c:324 #, c-format msgid "field \"%s\" is duplicated" msgstr "поле \"%s\" дублируется" -#: ../libpq-oauth/oauth-curl.c:614 ../libpq-oauth/oauth-curl.c:674 +#: ../libpq-oauth/oauth-curl.c:615 ../libpq-oauth/oauth-curl.c:675 #: fe-auth-oauth.c:264 fe-auth-oauth.c:298 #, c-format msgid "top-level element must be an object" msgstr "элементом верхнего уровня должен быть объект" -#: ../libpq-oauth/oauth-curl.c:777 +#: ../libpq-oauth/oauth-curl.c:778 #, c-format msgid "no content type was provided" msgstr "тип содержимого не передан" -#: ../libpq-oauth/oauth-curl.c:816 +#: ../libpq-oauth/oauth-curl.c:817 #, c-format msgid "unexpected content type: \"%s\"" msgstr "неожиданный тип содержимого: \"%s\"" -#: ../libpq-oauth/oauth-curl.c:841 +#: ../libpq-oauth/oauth-curl.c:842 #, c-format msgid "response contains embedded NULLs" msgstr "ответ содержит в себе NUL" -#: ../libpq-oauth/oauth-curl.c:851 +#: ../libpq-oauth/oauth-curl.c:852 #, c-format msgid "response is not valid UTF-8" msgstr "ответ не является текстом в кодировке UTF-8" -#: ../libpq-oauth/oauth-curl.c:891 +#: ../libpq-oauth/oauth-curl.c:892 #, c-format msgid "field \"%s\" is missing" msgstr "поле \"%s\" отсутствует" -#: ../libpq-oauth/oauth-curl.c:1097 +#: ../libpq-oauth/oauth-curl.c:1098 msgid "failed to parse token error response" msgstr "не удалось разобрать ответ с ошибкой токена" -#: ../libpq-oauth/oauth-curl.c:1125 +#: ../libpq-oauth/oauth-curl.c:1126 #, c-format msgid "provider rejected the oauth_client_secret" msgstr "провайдер не принял oauth_client_secret" -#: ../libpq-oauth/oauth-curl.c:1126 +#: ../libpq-oauth/oauth-curl.c:1127 #, c-format msgid "" "provider requires client authentication, and no oauth_client_secret is set" @@ -121,25 +121,25 @@ msgstr "" "провайдер требует проверку подлинности клиента, но oauth_client_secret " "отсутствует" -#: ../libpq-oauth/oauth-curl.c:1559 +#: ../libpq-oauth/oauth-curl.c:1560 #, c-format msgid "checking timer expiration: %m" msgstr "проверка состояния таймера: %m" -#: ../libpq-oauth/oauth-curl.c:1721 +#: ../libpq-oauth/oauth-curl.c:1722 #, c-format msgid "failed to create libcurl multi handle" msgstr "не удалось создать множественный указатель libcurl" -#: ../libpq-oauth/oauth-curl.c:1741 +#: ../libpq-oauth/oauth-curl.c:1742 #, c-format msgid "failed to create libcurl handle" msgstr "не удалось создать указатель libcurl" -#: ../libpq-oauth/oauth-curl.c:1825 ../libpq-oauth/oauth-curl.c:1866 -#: ../libpq-oauth/oauth-curl.c:2184 ../libpq-oauth/oauth-curl.c:2345 -#: ../libpq-oauth/oauth-curl.c:2406 ../libpq-oauth/oauth-curl.c:2495 -#: ../libpq-oauth/oauth-curl.c:2789 ../libpq-oauth/oauth-curl.c:3006 +#: ../libpq-oauth/oauth-curl.c:1826 ../libpq-oauth/oauth-curl.c:1867 +#: ../libpq-oauth/oauth-curl.c:2185 ../libpq-oauth/oauth-curl.c:2346 +#: ../libpq-oauth/oauth-curl.c:2407 ../libpq-oauth/oauth-curl.c:2496 +#: ../libpq-oauth/oauth-curl.c:2802 ../libpq-oauth/oauth-curl.c:3036 #: fe-auth-oauth.c:146 fe-auth-oauth.c:489 fe-auth-oauth.c:561 #: fe-auth-oauth.c:723 fe-auth-oauth.c:1016 fe-auth-oauth.c:1029 #: fe-auth-oauth.c:1117 fe-auth-oauth.c:1130 fe-auth-oauth.c:1266 @@ -153,79 +153,79 @@ msgstr "не удалось создать указатель libcurl" #: fe-connect.c:6210 fe-connect.c:6308 fe-connect.c:6559 fe-connect.c:6586 #: fe-connect.c:6662 fe-connect.c:6685 fe-connect.c:6709 fe-connect.c:6744 #: fe-connect.c:6830 fe-connect.c:6838 fe-connect.c:7195 fe-connect.c:7377 -#: fe-exec.c:530 fe-exec.c:1331 fe-exec.c:3270 fe-exec.c:4341 fe-exec.c:4534 -#: fe-gssapi-common.c:109 fe-lobj.c:870 fe-protocol3.c:212 fe-protocol3.c:235 -#: fe-protocol3.c:258 fe-protocol3.c:275 fe-protocol3.c:296 fe-protocol3.c:370 -#: fe-protocol3.c:751 fe-protocol3.c:991 fe-protocol3.c:1556 -#: fe-protocol3.c:1610 fe-protocol3.c:1656 fe-protocol3.c:1677 -#: fe-protocol3.c:1934 fe-protocol3.c:2335 fe-secure-common.c:110 -#: fe-secure-gssapi.c:508 fe-secure-gssapi.c:699 fe-secure-openssl.c:405 -#: fe-secure-openssl.c:1135 +#: fe-exec.c:531 fe-exec.c:1332 fe-exec.c:3285 fe-exec.c:4335 fe-exec.c:4528 +#: fe-gssapi-common.c:109 fe-lobj.c:870 fe-protocol3.c:214 fe-protocol3.c:237 +#: fe-protocol3.c:260 fe-protocol3.c:277 fe-protocol3.c:298 fe-protocol3.c:372 +#: fe-protocol3.c:753 fe-protocol3.c:993 fe-protocol3.c:1558 +#: fe-protocol3.c:1612 fe-protocol3.c:1658 fe-protocol3.c:1679 +#: fe-protocol3.c:1943 fe-protocol3.c:2355 fe-secure-common.c:110 +#: fe-secure-gssapi.c:515 fe-secure-gssapi.c:706 fe-secure-openssl.c:436 +#: fe-secure-openssl.c:1167 #, c-format msgid "out of memory" msgstr "нехватка памяти" -#: ../libpq-oauth/oauth-curl.c:1853 +#: ../libpq-oauth/oauth-curl.c:1854 #, c-format msgid "response is too large" msgstr "ответ слишком большой" -#: ../libpq-oauth/oauth-curl.c:1895 +#: ../libpq-oauth/oauth-curl.c:1896 #, c-format msgid "failed to queue HTTP request: %s" msgstr "добавить HTTP-запрос в очередь не удалось: %s" -#: ../libpq-oauth/oauth-curl.c:1912 ../libpq-oauth/oauth-curl.c:1970 +#: ../libpq-oauth/oauth-curl.c:1913 ../libpq-oauth/oauth-curl.c:1971 #, c-format msgid "asynchronous HTTP request failed: %s" msgstr "ошибка асинхронного HTTP-запроса: %s" -#: ../libpq-oauth/oauth-curl.c:2022 +#: ../libpq-oauth/oauth-curl.c:2023 #, c-format msgid "no result was retrieved for the finished handle" msgstr "для завершённого указателя не был получен результат" -#: ../libpq-oauth/oauth-curl.c:2155 ../libpq-oauth/oauth-curl.c:2461 -#: ../libpq-oauth/oauth-curl.c:2540 +#: ../libpq-oauth/oauth-curl.c:2156 ../libpq-oauth/oauth-curl.c:2462 +#: ../libpq-oauth/oauth-curl.c:2541 #, c-format msgid "unexpected response code %ld" msgstr "неожиданный код ответа %ld" -#: ../libpq-oauth/oauth-curl.c:2162 +#: ../libpq-oauth/oauth-curl.c:2163 msgid "failed to parse OpenID discovery document" msgstr "не удалось разобрать документ обнаружения OpenID" -#: ../libpq-oauth/oauth-curl.c:2227 +#: ../libpq-oauth/oauth-curl.c:2228 #, c-format msgid "the issuer identifier (%s) does not match oauth_issuer (%s)" msgstr "идентификатор издателя (%s) не совпадает с oauth_issuer (%s)" -#: ../libpq-oauth/oauth-curl.c:2254 +#: ../libpq-oauth/oauth-curl.c:2255 #, c-format msgid "issuer \"%s\" does not provide a device authorization endpoint" msgstr "издатель \"%s\" не передал конечную точку авторизации устройств" -#: ../libpq-oauth/oauth-curl.c:2280 +#: ../libpq-oauth/oauth-curl.c:2281 #, c-format msgid "device authorization endpoint \"%s\" must use HTTPS" msgstr "конечная точка авторизации устройств \"%s\" должна использовать HTTPS" # well-spelled: токенов -#: ../libpq-oauth/oauth-curl.c:2289 +#: ../libpq-oauth/oauth-curl.c:2290 #, c-format msgid "token endpoint \"%s\" must use HTTPS" msgstr "конечная точка токенов \"%s\" должна использовать HTTPS" -#: ../libpq-oauth/oauth-curl.c:2430 +#: ../libpq-oauth/oauth-curl.c:2431 msgid "failed to parse device authorization" msgstr "не удалось разобрать сообщение авторизации устройства" # well-spelled: токеном -#: ../libpq-oauth/oauth-curl.c:2518 +#: ../libpq-oauth/oauth-curl.c:2519 msgid "failed to parse access token response" msgstr "не удалось разобрать ответ с токеном доступа" -#: ../libpq-oauth/oauth-curl.c:2598 +#: ../libpq-oauth/oauth-curl.c:2596 #, c-format msgid "slow_down interval overflow" msgstr "переполнение интервала замедления (slow_down)" @@ -233,27 +233,27 @@ msgstr "переполнение интервала замедления (slow_d #. translator: The first %s is a URL for the user to visit in a #. browser, and the second %s is a code to be copy-pasted there. #. -#: ../libpq-oauth/oauth-curl.c:2634 +#: ../libpq-oauth/oauth-curl.c:2632 #, c-format msgid "Visit %s and enter the code: %s\n" msgstr "Посетите %s и введите код: %s\n" -#: ../libpq-oauth/oauth-curl.c:2639 +#: ../libpq-oauth/oauth-curl.c:2637 #, c-format msgid "device prompt failed" msgstr "ошибка при запросе устройства" -#: ../libpq-oauth/oauth-curl.c:2695 +#: ../libpq-oauth/oauth-curl.c:2691 #, c-format msgid "curl_global_init previously failed during OAuth setup" msgstr "в curl_global_init ранее возникла ошибка при настройке OAuth" -#: ../libpq-oauth/oauth-curl.c:2714 +#: ../libpq-oauth/oauth-curl.c:2710 #, c-format msgid "curl_global_init failed during OAuth setup" msgstr "в curl_global_init возникла ошибка при настройке OAuth" -#: ../libpq-oauth/oauth-curl.c:2735 +#: ../libpq-oauth/oauth-curl.c:2732 #, c-format msgid "" "libcurl is no longer thread-safe\n" @@ -268,19 +268,19 @@ msgstr "" "\tlibcurl сообщает, что таковой не является. Перекомпилируйте\n" "\tlibpq с установленной версией libcurl." -#: ../libpq-oauth/oauth-curl.c:2897 +#: ../libpq-oauth/oauth-curl.c:2910 msgid "failed to fetch OpenID discovery document" msgstr "не удалось получить документ обнаружения OpenID" -#: ../libpq-oauth/oauth-curl.c:2911 +#: ../libpq-oauth/oauth-curl.c:2924 msgid "cannot run OAuth device authorization" msgstr "не удалось запустить авторизацию устройства OAuth" -#: ../libpq-oauth/oauth-curl.c:2915 +#: ../libpq-oauth/oauth-curl.c:2928 msgid "failed to obtain device authorization" msgstr "не удалось получить авторизацию устройства" -#: ../libpq-oauth/oauth-curl.c:2926 ../libpq-oauth/oauth-curl.c:2977 +#: ../libpq-oauth/oauth-curl.c:2939 ../libpq-oauth/oauth-curl.c:3007 msgid "failed to obtain access token" msgstr "не удалось получить токен доступа" @@ -764,7 +764,7 @@ msgstr "нераспознанный алгоритм шифрования па msgid "connection pointer is NULL" msgstr "нулевой указатель соединения" -#: fe-cancel.c:85 fe-misc.c:613 +#: fe-cancel.c:85 fe-misc.c:621 #, c-format msgid "connection not open" msgstr "соединение не открыто" @@ -1329,8 +1329,8 @@ msgstr "" msgid "connection pointer is NULL\n" msgstr "нулевой указатель соединения\n" -#: fe-connect.c:7649 fe-exec.c:718 fe-exec.c:980 fe-exec.c:3475 -#: fe-protocol3.c:1006 fe-protocol3.c:1039 +#: fe-connect.c:7649 fe-exec.c:719 fe-exec.c:981 fe-exec.c:3490 +#: fe-protocol3.c:1008 fe-protocol3.c:1041 msgid "out of memory\n" msgstr "нехватка памяти\n" @@ -1358,178 +1358,178 @@ msgstr "пароль получен из файла \"%s\"" msgid "invalid integer value \"%s\" for connection option \"%s\"" msgstr "неверное целочисленное значение \"%s\" для параметра соединения \"%s\"" -#: fe-exec.c:469 fe-exec.c:3549 +#: fe-exec.c:470 fe-exec.c:3564 #, c-format msgid "row number %d is out of range 0..%d" msgstr "номер записи %d вне диапазона 0..%d" -#: fe-exec.c:531 fe-protocol3.c:2140 +#: fe-exec.c:532 fe-protocol3.c:2149 #, c-format msgid "%s" msgstr "%s" -#: fe-exec.c:839 +#: fe-exec.c:840 #, c-format msgid "write to server failed" msgstr "ошибка при передаче данных серверу" -#: fe-exec.c:879 +#: fe-exec.c:880 #, c-format msgid "no error text available" msgstr "текст ошибки отсутствует" -#: fe-exec.c:968 +#: fe-exec.c:969 msgid "NOTICE" msgstr "ЗАМЕЧАНИЕ" -#: fe-exec.c:1026 +#: fe-exec.c:1027 msgid "PGresult cannot support more than INT_MAX tuples" msgstr "PGresult не может вместить больше чем INT_MAX кортежей" -#: fe-exec.c:1038 +#: fe-exec.c:1039 msgid "size_t overflow" msgstr "переполнение size_t" -#: fe-exec.c:1454 fe-exec.c:1523 fe-exec.c:1569 +#: fe-exec.c:1455 fe-exec.c:1524 fe-exec.c:1570 #, c-format msgid "command string is a null pointer" msgstr "указатель на командную строку нулевой" -#: fe-exec.c:1460 fe-exec.c:3019 +#: fe-exec.c:1461 fe-exec.c:3034 #, c-format msgid "%s not allowed in pipeline mode" msgstr "%s не допускается в конвейерном режиме" -#: fe-exec.c:1528 fe-exec.c:1574 fe-exec.c:1668 +#: fe-exec.c:1529 fe-exec.c:1575 fe-exec.c:1669 #, c-format msgid "number of parameters must be between 0 and %d" msgstr "число параметров должно быть от 0 до %d" -#: fe-exec.c:1564 fe-exec.c:1663 +#: fe-exec.c:1565 fe-exec.c:1664 #, c-format msgid "statement name is a null pointer" msgstr "указатель на имя оператора нулевой" -#: fe-exec.c:1705 fe-exec.c:3395 +#: fe-exec.c:1706 fe-exec.c:3410 #, c-format msgid "no connection to the server" msgstr "нет соединения с сервером" -#: fe-exec.c:1713 fe-exec.c:3403 +#: fe-exec.c:1714 fe-exec.c:3418 #, c-format msgid "another command is already in progress" msgstr "уже выполняется другая команда" -#: fe-exec.c:1743 +#: fe-exec.c:1744 #, c-format msgid "cannot queue commands during COPY" msgstr "во время COPY нельзя добавлять команды в очередь" -#: fe-exec.c:1862 +#: fe-exec.c:1863 #, c-format msgid "length must be given for binary parameter" msgstr "для двоичного параметра должна быть указана длина" -#: fe-exec.c:2221 +#: fe-exec.c:2222 #, c-format msgid "unexpected asyncStatus: %d" msgstr "неожиданный asyncStatus: %d" -#: fe-exec.c:2377 +#: fe-exec.c:2378 #, c-format msgid "" "synchronous command execution functions are not allowed in pipeline mode" msgstr "" "функции синхронного выполнения команд не допускаются в конвейерном режиме" -#: fe-exec.c:2394 +#: fe-exec.c:2395 msgid "COPY terminated by new PQexec" msgstr "операция COPY прервана вызовом PQexec" -#: fe-exec.c:2410 +#: fe-exec.c:2411 #, c-format msgid "PQexec not allowed during COPY BOTH" msgstr "вызов PQexec не допускается в процессе COPY BOTH" -#: fe-exec.c:2646 +#: fe-exec.c:2647 #, c-format msgid "unrecognized message type \"%c\"" msgstr "нераспознанный тип сообщения \"%c\"" -#: fe-exec.c:2718 fe-exec.c:2772 fe-exec.c:2840 fe-protocol3.c:2071 +#: fe-exec.c:2719 fe-exec.c:2773 fe-exec.c:2841 fe-protocol3.c:2080 #, c-format msgid "no COPY in progress" msgstr "операция COPY не выполняется" -#: fe-exec.c:3026 +#: fe-exec.c:3041 #, c-format msgid "connection in wrong state" msgstr "соединение в неправильном состоянии" -#: fe-exec.c:3069 +#: fe-exec.c:3084 #, c-format msgid "cannot enter pipeline mode, connection not idle" msgstr "перейти в конвейерный режиме нельзя, соединение не простаивает" -#: fe-exec.c:3105 fe-exec.c:3126 +#: fe-exec.c:3120 fe-exec.c:3141 #, c-format msgid "cannot exit pipeline mode with uncollected results" msgstr "выйти из конвейерного режима нельзя, не собрав все результаты" -#: fe-exec.c:3109 +#: fe-exec.c:3124 #, c-format msgid "cannot exit pipeline mode while busy" msgstr "выйти из конвейерного режима в занятом состоянии нельзя" -#: fe-exec.c:3120 +#: fe-exec.c:3135 #, c-format msgid "cannot exit pipeline mode while in COPY" msgstr "выйти из конвейерного режима во время COPY нельзя" -#: fe-exec.c:3319 +#: fe-exec.c:3334 #, c-format msgid "cannot send pipeline when not in pipeline mode" msgstr "отправить конвейер, не перейдя в конвейерный режим, нельзя" -#: fe-exec.c:3438 +#: fe-exec.c:3453 msgid "invalid ExecStatusType code" msgstr "неверный код ExecStatusType" -#: fe-exec.c:3465 +#: fe-exec.c:3480 msgid "PGresult is not an error result\n" msgstr "В PGresult не передан результат ошибки\n" -#: fe-exec.c:3533 fe-exec.c:3556 +#: fe-exec.c:3548 fe-exec.c:3571 #, c-format msgid "column number %d is out of range 0..%d" msgstr "номер столбца %d вне диапазона 0..%d" -#: fe-exec.c:3571 +#: fe-exec.c:3586 #, c-format msgid "parameter number %d is out of range 0..%d" msgstr "номер параметра %d вне диапазона 0..%d" -#: fe-exec.c:3882 +#: fe-exec.c:3897 #, c-format msgid "could not interpret result from server: %s" msgstr "не удалось интерпретировать ответ сервера: %s" -#: fe-exec.c:4157 fe-exec.c:4292 +#: fe-exec.c:4172 fe-exec.c:4286 #, c-format msgid "incomplete multibyte character" msgstr "неполный многобайтный символ" -#: fe-exec.c:4159 fe-exec.c:4311 +#: fe-exec.c:4174 fe-exec.c:4305 #, c-format msgid "invalid multibyte character" msgstr "неверный многобайтный символ" -#: fe-exec.c:4413 +#: fe-exec.c:4407 #, c-format msgid "escaped string size exceeds the maximum allowed (%zu)" msgstr "размер строки с экранированием превышает максимально допустимый (%zu)" -#: fe-exec.c:4590 +#: fe-exec.c:4584 #, c-format msgid "escaped bytea size exceeds the maximum allowed (%zu)" msgstr "" @@ -1581,18 +1581,18 @@ msgstr "не удалось записать файл \"%s\": %s" msgid "query to initialize large object functions did not return data" msgstr "запрос инициализации функций для больших объектов не вернул данные" -#: fe-misc.c:239 +#: fe-misc.c:241 #, c-format msgid "integer of size %lu not supported by pqGetInt" msgstr "функция pqGetInt не поддерживает integer размером %lu байт" -#: fe-misc.c:272 +#: fe-misc.c:274 #, c-format msgid "integer of size %lu not supported by pqPutInt" msgstr "функция pqPutInt не поддерживает integer размером %lu байт" -#: fe-misc.c:791 fe-secure-openssl.c:181 fe-secure-openssl.c:287 -#: fe-secure.c:222 fe-secure.c:389 +#: fe-misc.c:833 fe-secure-openssl.c:182 fe-secure-openssl.c:318 +#: fe-secure.c:222 fe-secure.c:413 #, c-format msgid "" "server closed the connection unexpectedly\n" @@ -1603,31 +1603,37 @@ msgstr "" "\tСкорее всего сервер прекратил работу из-за сбоя\n" "\tдо или в процессе выполнения запроса." -#: fe-misc.c:858 +#: fe-misc.c:942 +#, c-format +msgid "drained only %zd of %zd pending bytes in transport buffer" +msgstr "" +"выбрано только %zd из %zd байт, ожидающих получения в транспортном буфере" + +#: fe-misc.c:1004 msgid "connection not open\n" msgstr "соединение не открыто\n" -#: fe-misc.c:1046 +#: fe-misc.c:1192 #, c-format msgid "timeout expired" msgstr "тайм-аут" -#: fe-misc.c:1098 +#: fe-misc.c:1244 #, c-format msgid "invalid socket" msgstr "неверный сокет" -#: fe-misc.c:1121 +#: fe-misc.c:1265 #, c-format msgid "%s() failed: %s" msgstr "ошибка в %s(): %s" -#: fe-protocol3.c:190 +#: fe-protocol3.c:192 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "от сервера во время простоя получено сообщение типа 0x%02x" -#: fe-protocol3.c:403 +#: fe-protocol3.c:405 #, c-format msgid "" "server sent data (\"D\" message) without prior row description (\"T\" " @@ -1636,117 +1642,117 @@ msgstr "" "сервер отправил данные (сообщение \"D\") без предварительного описания " "строки (сообщение \"T\")" -#: fe-protocol3.c:445 +#: fe-protocol3.c:447 #, c-format msgid "unexpected response from server; first received character was \"%c\"" msgstr "неожиданный ответ сервера; первый полученный символ: \"%c\"" -#: fe-protocol3.c:469 +#: fe-protocol3.c:471 #, c-format msgid "message contents do not agree with length in message type \"%c\"" msgstr "содержимое не соответствует длине в сообщении типа \"%c\"" -#: fe-protocol3.c:504 +#: fe-protocol3.c:506 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d" msgstr "" "потеряна синхронизация с сервером: получено сообщение типа \"%c\", длина %d" -#: fe-protocol3.c:551 fe-protocol3.c:591 +#: fe-protocol3.c:553 fe-protocol3.c:593 msgid "insufficient data in \"T\" message" msgstr "недостаточно данных в сообщении \"T\"" -#: fe-protocol3.c:662 fe-protocol3.c:868 +#: fe-protocol3.c:664 fe-protocol3.c:870 msgid "out of memory for query result" msgstr "недостаточно памяти для результата запроса" -#: fe-protocol3.c:731 +#: fe-protocol3.c:733 msgid "insufficient data in \"t\" message" msgstr "недостаточно данных в сообщении \"t\"" -#: fe-protocol3.c:790 fe-protocol3.c:822 fe-protocol3.c:840 +#: fe-protocol3.c:792 fe-protocol3.c:824 fe-protocol3.c:842 msgid "insufficient data in \"D\" message" msgstr "недостаточно данных в сообщении \"D\"" -#: fe-protocol3.c:796 +#: fe-protocol3.c:798 msgid "unexpected field count in \"D\" message" msgstr "неверное число полей в сообщении \"D\"" -#: fe-protocol3.c:1052 +#: fe-protocol3.c:1054 msgid "no error message available\n" msgstr "нет сообщения об ошибке\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1100 fe-protocol3.c:1119 +#: fe-protocol3.c:1102 fe-protocol3.c:1121 #, c-format msgid " at character %s" msgstr " символ %s" -#: fe-protocol3.c:1132 +#: fe-protocol3.c:1134 #, c-format msgid "DETAIL: %s\n" msgstr "ПОДРОБНОСТИ: %s\n" -#: fe-protocol3.c:1135 +#: fe-protocol3.c:1137 #, c-format msgid "HINT: %s\n" msgstr "ПОДСКАЗКА: %s\n" -#: fe-protocol3.c:1138 +#: fe-protocol3.c:1140 #, c-format msgid "QUERY: %s\n" msgstr "ЗАПРОС: %s\n" -#: fe-protocol3.c:1145 +#: fe-protocol3.c:1147 #, c-format msgid "CONTEXT: %s\n" msgstr "КОНТЕКСТ: %s\n" -#: fe-protocol3.c:1154 +#: fe-protocol3.c:1156 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "СХЕМА: %s\n" -#: fe-protocol3.c:1158 +#: fe-protocol3.c:1160 #, c-format msgid "TABLE NAME: %s\n" msgstr "ТАБЛИЦА: %s\n" -#: fe-protocol3.c:1162 +#: fe-protocol3.c:1164 #, c-format msgid "COLUMN NAME: %s\n" msgstr "СТОЛБЕЦ: %s\n" -#: fe-protocol3.c:1166 +#: fe-protocol3.c:1168 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "ТИП ДАННЫХ: %s\n" -#: fe-protocol3.c:1170 +#: fe-protocol3.c:1172 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "ОГРАНИЧЕНИЕ: %s\n" -#: fe-protocol3.c:1182 +#: fe-protocol3.c:1184 msgid "LOCATION: " msgstr "ПОЛОЖЕНИЕ: " -#: fe-protocol3.c:1184 +#: fe-protocol3.c:1186 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1186 +#: fe-protocol3.c:1188 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1394 +#: fe-protocol3.c:1396 #, c-format msgid "LINE %d: " msgstr "СТРОКА %d: " -#: fe-protocol3.c:1456 +#: fe-protocol3.c:1458 #, c-format msgid "" "received invalid protocol negotiation message: server requested downgrade to " @@ -1755,7 +1761,7 @@ msgstr "" "получено некорректное сообщение согласования протокола: сервер запросил " "понижение версии на версию выше" -#: fe-protocol3.c:1462 +#: fe-protocol3.c:1464 #, c-format msgid "" "received invalid protocol negotiation message: server requested downgrade to " @@ -1764,7 +1770,7 @@ msgstr "" "получено некорректное сообщение согласования протокола: сервер запросил " "понижение на версию протокола, предшествующую 3.0" -#: fe-protocol3.c:1469 +#: fe-protocol3.c:1471 #, c-format msgid "" "received invalid protocol negotiation message: server requested downgrade to " @@ -1773,7 +1779,7 @@ msgstr "" "получено некорректное сообщение согласования протокола: сервер запросил " "понижение на несуществующую версию протокола 3.1" -#: fe-protocol3.c:1475 +#: fe-protocol3.c:1477 #, c-format msgid "" "received invalid protocol negotiation message: server reported negative " @@ -1782,7 +1788,7 @@ msgstr "" "получено некорректное сообщение согласования протокола: сервер передал " "отрицательное число неподдерживаемых параметров" -#: fe-protocol3.c:1481 +#: fe-protocol3.c:1483 #, c-format msgid "" "received invalid protocol negotiation message: server negotiated but asks " @@ -1791,7 +1797,7 @@ msgstr "" "получено некорректное сообщение согласования протокола: сервер согласовал " "версию и не требует никаких изменений" -#: fe-protocol3.c:1487 +#: fe-protocol3.c:1489 #, c-format msgid "" "server only supports protocol version %d.%d, but \"%s\" was set to %d.%d" @@ -1799,7 +1805,7 @@ msgstr "" "сервер поддерживает только версию протокола %d.%d, но параметр \"%s\" равен " "%d.%d" -#: fe-protocol3.c:1512 +#: fe-protocol3.c:1514 #, c-format msgid "" "received invalid protocol negotiation message: server reported unsupported " @@ -1808,7 +1814,7 @@ msgstr "" "получено некорректное сообщение согласования протокола: сервер выдал " "неподдерживаемое имя параметра без префикса \"%s\" (\"%s\")" -#: fe-protocol3.c:1515 +#: fe-protocol3.c:1517 #, c-format msgid "" "received invalid protocol negotiation message: server reported an " @@ -1817,14 +1823,14 @@ msgstr "" "получено некорректное сообщение согласования протокола: сервер выдал " "неподдерживаемый параметр, который не был запрошен (\"%s\")" -#: fe-protocol3.c:1522 +#: fe-protocol3.c:1524 #, c-format msgid "received invalid protocol negotiation message: message too short" msgstr "" "получено некорректное сообщение согласования протокола: сообщение слишком " "короткое" -#: fe-protocol3.c:1588 +#: fe-protocol3.c:1590 #, c-format msgid "" "received invalid BackendKeyData message: cancel key with length %d not " @@ -1833,7 +1839,7 @@ msgstr "" "получено некорректное сообщение согласования протокола: ключ отмены длиной " "%d в протоколе версии 3.0 не допускается (длина должна быть 4 байта)" -#: fe-protocol3.c:1595 +#: fe-protocol3.c:1597 #, c-format msgid "" "received invalid BackendKeyData message: cancel key with length %d is too " @@ -1842,7 +1848,7 @@ msgstr "" "получено некорректное сообщение согласования протокола: ключ отмены длиной " "%d слишком короткий (минимальная длина 4 байта)" -#: fe-protocol3.c:1602 +#: fe-protocol3.c:1604 #, c-format msgid "" "received invalid BackendKeyData message: cancel key with length %d is too " @@ -1851,17 +1857,22 @@ msgstr "" "получено некорректное сообщение согласования протокола: ключ отмены длиной " "%d слишком длинный (максимальная длина 256 байт)" -#: fe-protocol3.c:1966 +#: fe-protocol3.c:1975 #, c-format msgid "PQgetline: not doing text COPY OUT" msgstr "PQgetline можно вызывать только во время COPY OUT с текстом" -#: fe-protocol3.c:2341 +#: fe-protocol3.c:2306 +#, c-format +msgid "server returned too much data" +msgstr "сервер передал слишком много данных" + +#: fe-protocol3.c:2361 #, c-format msgid "protocol error: no function result" msgstr "ошибка протокола: нет результата функции" -#: fe-protocol3.c:2353 +#: fe-protocol3.c:2373 #, c-format msgid "protocol error: id=0x%x" msgstr "ошибка протокола: id=0x%x" @@ -1923,12 +1934,12 @@ msgstr "ошибка обёртывания сообщения в GSSAPI" msgid "outgoing GSSAPI message would not use confidentiality" msgstr "исходящее сообщение GSSAPI не будет защищено" -#: fe-secure-gssapi.c:215 fe-secure-gssapi.c:726 +#: fe-secure-gssapi.c:215 fe-secure-gssapi.c:733 #, c-format msgid "client tried to send oversize GSSAPI packet (%zu > %zu)" msgstr "клиент попытался передать чрезмерно большой пакет GSSAPI (%zu > %zu)" -#: fe-secure-gssapi.c:354 fe-secure-gssapi.c:602 +#: fe-secure-gssapi.c:354 fe-secure-gssapi.c:609 #, c-format msgid "oversize GSSAPI packet sent by the server (%zu > %zu)" msgstr "сервер передал чрезмерно большой пакет GSSAPI (%zu > %zu)" @@ -1942,114 +1953,124 @@ msgstr "ошибка развёртывания сообщения в GSSAPI" msgid "incoming GSSAPI message did not use confidentiality" msgstr "входящее сообщение GSSAPI не защищено" -#: fe-secure-gssapi.c:665 +#: fe-secure-gssapi.c:672 msgid "could not initiate GSSAPI security context" msgstr "не удалось инициализировать контекст безопасности GSSAPI" -#: fe-secure-gssapi.c:715 +#: fe-secure-gssapi.c:722 msgid "GSSAPI size check error" msgstr "ошибка проверки размера в GSSAPI" -#: fe-secure-openssl.c:185 fe-secure-openssl.c:291 fe-secure-openssl.c:1382 +#: fe-secure-openssl.c:186 fe-secure-openssl.c:322 fe-secure-openssl.c:1414 #, c-format msgid "SSL SYSCALL error: %s" msgstr "ошибка SSL SYSCALL: %s" -#: fe-secure-openssl.c:191 fe-secure-openssl.c:297 fe-secure-openssl.c:1385 +#: fe-secure-openssl.c:192 fe-secure-openssl.c:328 fe-secure-openssl.c:1417 #, c-format msgid "SSL SYSCALL error: EOF detected" msgstr "ошибка SSL SYSCALL: конец файла (EOF)" -#: fe-secure-openssl.c:201 fe-secure-openssl.c:307 fe-secure-openssl.c:1393 +#: fe-secure-openssl.c:202 fe-secure-openssl.c:338 fe-secure-openssl.c:1425 #, c-format msgid "SSL error: %s" msgstr "ошибка SSL: %s" -#: fe-secure-openssl.c:215 fe-secure-openssl.c:321 +#: fe-secure-openssl.c:216 fe-secure-openssl.c:352 #, c-format msgid "SSL connection has been closed unexpectedly" msgstr "SSL-соединение было неожиданно закрыто" -#: fe-secure-openssl.c:220 fe-secure-openssl.c:326 fe-secure-openssl.c:1440 +#: fe-secure-openssl.c:221 fe-secure-openssl.c:357 fe-secure-openssl.c:1472 #, c-format msgid "unrecognized SSL error code: %d" msgstr "нераспознанный код ошибки SSL: %d" -#: fe-secure-openssl.c:368 +#: fe-secure-openssl.c:251 +#, c-format +msgid "OpenSSL reports negative bytes pending" +msgstr "OpenSSL сообщил, что число ожидающих байт отрицательное" + +#: fe-secure-openssl.c:263 +#, c-format +msgid "OpenSSL reports INT_MAX bytes pending" +msgstr "OpenSSL сообщил, что число ожидающих байт равно INT_MAX" + +#: fe-secure-openssl.c:399 #, c-format msgid "could not determine server certificate signature algorithm" msgstr "не удалось определить алгоритм подписи сертификата сервера" -#: fe-secure-openssl.c:388 +#: fe-secure-openssl.c:419 #, c-format msgid "could not find digest for NID %s" msgstr "не удалось найти алгоритм хеширования по NID %s" -#: fe-secure-openssl.c:397 +#: fe-secure-openssl.c:428 #, c-format msgid "could not generate peer certificate hash" msgstr "не удалось сгенерировать хеш сертификата сервера" -#: fe-secure-openssl.c:479 +#: fe-secure-openssl.c:511 #, c-format msgid "SSL certificate's name entry is missing" msgstr "в SSL-сертификате отсутствует запись имени" -#: fe-secure-openssl.c:509 +#: fe-secure-openssl.c:541 #, c-format msgid "SSL certificate's address entry is missing" msgstr "в SSL-сертификате отсутствует запись адреса" -#: fe-secure-openssl.c:715 +#: fe-secure-openssl.c:747 #, c-format msgid "WARNING: could not open SSL key logging file \"%s\": %m\n" msgstr "" "ПРЕДУПРЕЖДЕНИЕ: не удалось открыть файл для диагностики ключа SSL \"%s\": " "%m\n" -#: fe-secure-openssl.c:723 +#: fe-secure-openssl.c:755 #, c-format msgid "WARNING: could not write to SSL key logging file \"%s\": %m\n" msgstr "" "ПРЕДУПРЕЖДЕНИЕ: не удалось записать в файл для диагностики ключа SSL \"%s\": " "%m\n" -#: fe-secure-openssl.c:776 +#: fe-secure-openssl.c:808 #, c-format msgid "could not create SSL context: %s" msgstr "не удалось создать контекст SSL: %s" -#: fe-secure-openssl.c:818 +#: fe-secure-openssl.c:850 #, c-format msgid "invalid value \"%s\" for minimum SSL protocol version" msgstr "неверное значение \"%s\" для минимальной версии протокола SSL" -#: fe-secure-openssl.c:828 +#: fe-secure-openssl.c:860 #, c-format msgid "could not set minimum SSL protocol version: %s" msgstr "не удалось задать минимальную версию протокола SSL: %s" -#: fe-secure-openssl.c:844 +#: fe-secure-openssl.c:876 #, c-format msgid "invalid value \"%s\" for maximum SSL protocol version" msgstr "неверное значение \"%s\" для максимальной версии протокола SSL" -#: fe-secure-openssl.c:854 +#: fe-secure-openssl.c:886 #, c-format msgid "could not set maximum SSL protocol version: %s" msgstr "не удалось задать максимальную версию протокола SSL: %s" -#: fe-secure-openssl.c:892 +#: fe-secure-openssl.c:924 #, c-format msgid "could not load system root certificate paths: %s" msgstr "не удалось выбрать системные пути для корневых сертификатов: %s" -#: fe-secure-openssl.c:909 +#: fe-secure-openssl.c:941 #, c-format msgid "could not read root certificate file \"%s\": %s" msgstr "не удалось прочитать файл корневых сертификатов \"%s\": %s" -#: fe-secure-openssl.c:961 +#: fe-secure-openssl.c:993 #, c-format msgid "" "could not get home directory to locate root certificate file\n" @@ -2062,7 +2083,7 @@ msgstr "" "(sslrootcert=system) или отключите проверку сертификата сервера, изменив " "sslmode." -#: fe-secure-openssl.c:964 +#: fe-secure-openssl.c:996 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -2075,78 +2096,78 @@ msgstr "" "(sslrootcert=system) или отключите проверку сертификата сервера, изменив " "sslmode." -#: fe-secure-openssl.c:999 +#: fe-secure-openssl.c:1031 #, c-format msgid "could not open certificate file \"%s\": %s" msgstr "не удалось открыть файл сертификата \"%s\": %s" -#: fe-secure-openssl.c:1017 +#: fe-secure-openssl.c:1049 #, c-format msgid "could not read certificate file \"%s\": %s" msgstr "не удалось прочитать файл сертификата \"%s\": %s" -#: fe-secure-openssl.c:1041 +#: fe-secure-openssl.c:1073 #, c-format msgid "could not establish SSL connection: %s" msgstr "не удалось установить SSL-соединение: %s" -#: fe-secure-openssl.c:1058 +#: fe-secure-openssl.c:1090 #, c-format msgid "WARNING: sslkeylogfile support requires OpenSSL\n" msgstr "ПРЕДУПРЕЖДЕНИЕ: для поддержки sslkeylogfile требуется OpenSSL\n" -#: fe-secure-openssl.c:1060 +#: fe-secure-openssl.c:1092 #, c-format msgid "WARNING: libpq was not built with sslkeylogfile support\n" msgstr "" "ПРЕДУПРЕЖДЕНИЕ: сборка libpq была произведена без поддержки sslkeylogfile\n" -#: fe-secure-openssl.c:1090 +#: fe-secure-openssl.c:1122 #, c-format msgid "could not set SSL Server Name Indication (SNI): %s" msgstr "не удалось задать SNI (Server Name Indication) для SSL-подключения: %s" -#: fe-secure-openssl.c:1107 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not set SSL ALPN extension: %s" msgstr "не удалось установить расширение SSL ALPN: %s" -#: fe-secure-openssl.c:1150 +#: fe-secure-openssl.c:1182 #, c-format msgid "could not load SSL engine \"%s\": %s" msgstr "не удалось загрузить модуль SSL ENGINE \"%s\": %s" -#: fe-secure-openssl.c:1161 +#: fe-secure-openssl.c:1193 #, c-format msgid "could not initialize SSL engine \"%s\": %s" msgstr "не удалось инициализировать модуль SSL ENGINE \"%s\": %s" -#: fe-secure-openssl.c:1176 +#: fe-secure-openssl.c:1208 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s" msgstr "не удалось прочитать закрытый ключ SSL \"%s\" из модуля \"%s\": %s" -#: fe-secure-openssl.c:1189 +#: fe-secure-openssl.c:1221 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s" msgstr "не удалось загрузить закрытый ключ SSL \"%s\" из модуля \"%s\": %s" -#: fe-secure-openssl.c:1226 +#: fe-secure-openssl.c:1258 #, c-format msgid "certificate present, but not private key file \"%s\"" msgstr "при наличии сертификата отсутствует файл закрытого ключа \"%s\"" -#: fe-secure-openssl.c:1229 +#: fe-secure-openssl.c:1261 #, c-format msgid "could not stat private key file \"%s\": %m" msgstr "не удалось получить информацию о файле закрытого ключа \"%s\": %m" -#: fe-secure-openssl.c:1237 +#: fe-secure-openssl.c:1269 #, c-format msgid "private key file \"%s\" is not a regular file" msgstr "файл закрытого ключа \"%s\" - не обычный файл" -#: fe-secure-openssl.c:1270 +#: fe-secure-openssl.c:1302 #, c-format msgid "" "private key file \"%s\" has group or world access; file must have " @@ -2158,22 +2179,22 @@ msgstr "" "текущему пользователю, либо u=rw,g=r (0640) или более строгие, если он " "принадлежит root" -#: fe-secure-openssl.c:1294 +#: fe-secure-openssl.c:1326 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "не удалось загрузить файл закрытого ключа \"%s\": %s" -#: fe-secure-openssl.c:1310 +#: fe-secure-openssl.c:1342 #, c-format msgid "certificate does not match private key file \"%s\": %s" msgstr "сертификат не соответствует файлу закрытого ключа \"%s\": %s" -#: fe-secure-openssl.c:1379 +#: fe-secure-openssl.c:1411 #, c-format msgid "SSL error: certificate verify failed: %s" msgstr "ошибка SSL: не удалось проверить сертификат: %s" -#: fe-secure-openssl.c:1424 +#: fe-secure-openssl.c:1456 #, c-format msgid "" "This may indicate that the server does not support any SSL protocol version " @@ -2182,34 +2203,34 @@ msgstr "" "Это может указывать на то, что сервер не поддерживает ни одну версию " "протокола SSL между %s и %s." -#: fe-secure-openssl.c:1456 +#: fe-secure-openssl.c:1488 #, c-format msgid "" "direct SSL connection was established without ALPN protocol negotiation " "extension" msgstr "прямое SSL-соединение было установлено без расширения ALPN" -#: fe-secure-openssl.c:1468 +#: fe-secure-openssl.c:1500 #, c-format msgid "SSL connection was established with unexpected ALPN protocol" msgstr "SSL-соединение было установлено с неподдерживаемым протоколом ALPN" -#: fe-secure-openssl.c:1485 +#: fe-secure-openssl.c:1517 #, c-format msgid "certificate could not be obtained: %s" msgstr "не удалось получить сертификат: %s" -#: fe-secure-openssl.c:1564 +#: fe-secure-openssl.c:1596 #, c-format msgid "no SSL error reported" msgstr "нет сообщения об ошибке SSL" -#: fe-secure-openssl.c:1607 +#: fe-secure-openssl.c:1639 #, c-format msgid "SSL error code %lu" msgstr "код ошибки SSL: %lu" -#: fe-secure-openssl.c:1909 +#: fe-secure-openssl.c:1941 #, c-format msgid "WARNING: sslpassword truncated\n" msgstr "ПРЕДУПРЕЖДЕНИЕ: значение sslpassword усечено\n" @@ -2219,7 +2240,7 @@ msgstr "ПРЕДУПРЕЖДЕНИЕ: значение sslpassword усечен msgid "could not receive data from server: %s" msgstr "не удалось получить данные с сервера: %s" -#: fe-secure.c:404 +#: fe-secure.c:428 #, c-format msgid "could not send data to server: %s" msgstr "не удалось передать данные серверу: %s" diff --git a/src/pl/plpython/po/ru.po b/src/pl/plpython/po/ru.po index 066976d50ab..8b576b3d634 100644 --- a/src/pl/plpython/po/ru.po +++ b/src/pl/plpython/po/ru.po @@ -1,13 +1,13 @@ # Russian message translation file for plpython # Copyright (C) 2012-2016 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Alexander Lakhin , 2012-2017, 2018, 2019. +# SPDX-FileCopyrightText: 2012-2017, 2018, 2019, 2026 Alexander Lakhin msgid "" msgstr "" "Project-Id-Version: plpython (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2025-08-30 15:59+0300\n" -"PO-Revision-Date: 2019-08-29 15:42+0300\n" +"POT-Creation-Date: 2026-08-05 06:37+0300\n" +"PO-Revision-Date: 2026-08-05 07:51+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -27,12 +27,12 @@ msgstr "plpy.cursor ожидает запрос или план" msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor принимает в качестве второго аргумента последовательность" -#: plpy_cursorobject.c:193 plpy_spi.c:200 +#: plpy_cursorobject.c:193 plpy_spi.c:205 #, c-format msgid "could not execute plan" msgstr "нельзя выполнить план" -#: plpy_cursorobject.c:196 plpy_spi.c:203 +#: plpy_cursorobject.c:196 plpy_spi.c:208 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" @@ -40,28 +40,34 @@ msgstr[0] "Ожидалась последовательность из %d ар msgstr[1] "Ожидалась последовательность из %d аргументов, получено %d: %s" msgstr[2] "Ожидалась последовательность из %d аргументов, получено %d: %s" -#: plpy_cursorobject.c:349 +#: plpy_cursorobject.c:264 plpy_spi.c:92 plpy_spi.c:259 plpy_typeio.c:1214 +#: plpy_typeio.c:1465 +#, c-format +msgid "could not get element %d from sequence" +msgstr "не удалось получить элемент %d из последовательности" + +#: plpy_cursorobject.c:354 #, c-format msgid "iterating a closed cursor" msgstr "перемещение закрытого курсора" -#: plpy_cursorobject.c:357 plpy_cursorobject.c:423 +#: plpy_cursorobject.c:362 plpy_cursorobject.c:428 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "перемещение курсора в прерванной подтранзакции" -#: plpy_cursorobject.c:415 +#: plpy_cursorobject.c:420 #, c-format msgid "fetch from a closed cursor" msgstr "выборка из закрытого курсора" -#: plpy_cursorobject.c:458 plpy_spi.c:389 +#: plpy_cursorobject.c:463 plpy_spi.c:399 #, c-format msgid "query result has too many rows to fit in a Python list" msgstr "" "результат запроса содержит слишком много строк для передачи в списке Python" -#: plpy_cursorobject.c:510 +#: plpy_cursorobject.c:515 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "закрытие курсора в прерванной подтранзакции" @@ -319,27 +325,27 @@ msgstr "команда не выдала результирующий набор msgid "second argument of plpy.prepare must be a sequence" msgstr "вторым аргументом plpy.prepare должна быть последовательность" -#: plpy_spi.c:94 +#: plpy_spi.c:99 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: имя типа с порядковым номером %d не является строкой" -#: plpy_spi.c:166 +#: plpy_spi.c:171 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute ожидает запрос или план" -#: plpy_spi.c:184 +#: plpy_spi.c:189 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute принимает в качестве второго аргумента последовательность" -#: plpy_spi.c:285 +#: plpy_spi.c:295 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "ошибка в SPI_execute_plan: %s" -#: plpy_spi.c:327 +#: plpy_spi.c:337 #, c-format msgid "SPI_execute failed: %s" msgstr "ошибка в SPI_execute: %s" @@ -413,7 +419,7 @@ msgstr "" "не удалось определить длину последовательности в возвращаемом функцией " "значении" -#: plpy_typeio.c:1225 plpy_typeio.c:1240 plpy_typeio.c:1256 +#: plpy_typeio.c:1229 plpy_typeio.c:1244 plpy_typeio.c:1260 #, c-format msgid "" "multidimensional arrays must have array expressions with matching dimensions" @@ -421,22 +427,22 @@ msgstr "" "для многомерных массивов должны задаваться выражения с соответствующими " "размерностями" -#: plpy_typeio.c:1230 +#: plpy_typeio.c:1234 #, c-format msgid "number of array dimensions exceeds the maximum allowed (%d)" msgstr "число размерностей массива превышает предел (%d)" -#: plpy_typeio.c:1332 +#: plpy_typeio.c:1336 #, c-format msgid "malformed record literal: \"%s\"" msgstr "ошибка в литерале записи: \"%s\"" -#: plpy_typeio.c:1333 +#: plpy_typeio.c:1337 #, c-format msgid "Missing left parenthesis." msgstr "Отсутствует левая скобка." -#: plpy_typeio.c:1334 plpy_typeio.c:1535 +#: plpy_typeio.c:1338 plpy_typeio.c:1542 #, c-format msgid "" "To return a composite type in an array, return the composite type as a " @@ -445,12 +451,12 @@ msgstr "" "Чтобы возвратить составной тип в массиве, нужно возвратить составное " "значение в виде кортежа Python, например: \"[('foo',)]\"." -#: plpy_typeio.c:1381 +#: plpy_typeio.c:1385 #, c-format msgid "key \"%s\" not found in mapping" msgstr "ключ \"%s\" не найден в сопоставлении" -#: plpy_typeio.c:1382 +#: plpy_typeio.c:1386 #, c-format msgid "" "To return null in a column, add the value None to the mapping with the key " @@ -459,17 +465,17 @@ msgstr "" "Чтобы присвоить столбцу NULL, добавьте в сопоставление значение None с " "ключом-именем столбца." -#: plpy_typeio.c:1435 +#: plpy_typeio.c:1439 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "длина возвращённой последовательности не равна числу столбцов в строке" -#: plpy_typeio.c:1533 +#: plpy_typeio.c:1540 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "в объекте Python не существует атрибут \"%s\"" -#: plpy_typeio.c:1536 +#: plpy_typeio.c:1543 #, c-format msgid "" "To return null in a column, let the returned object have an attribute named " From 3294ab83947270a44f680a1725383e6521315b70 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:03 -0700 Subject: [PATCH 317/481] Guard against overlength time zone abbreviations in to_char(). While typical abbreviations are only a few bytes long, a user-supplied time_zone setting could specify a much longer abbreviation, enough to overflow to_char's allocation of 12 bytes per format character. If so, throw an error in the same style as commit 9241c84cb (CVE-2015-0241). Reported-by: Hcamael Reported-by: Amjad Shahzad Reported-by: Tan Zhen of AntAISecurityLab Reported-by: Tomer Fichman Reported-by: Zheng Yu Reported-by: Amy Burnett (OpenAI Codex Security) Reported-by: Rick de Jager Reported-by: Heewon Song Reported-by: Sylvie Mayer Reported-by: Aleksander Alekseev Reported-by: Hillai Ben Sasson Author: Tom Lane Backpatch-through: 14 Security: CVE-2026-14669 --- src/backend/utils/adt/formatting.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index 641b7aa679e..effad4c37dd 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -2700,10 +2700,18 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col INVALID_FOR_INTERVAL; if (tmtcTzn(in)) { - /* We assume here that timezone names aren't localized */ + /* + * We assume here that timezone abbreviations aren't + * localized, so ASCII-only downcasing is sufficient. + */ char *p = asc_tolower_z(tmtcTzn(in)); - strcpy(s, p); + if (strlen(p) <= n->key->len * DCH_MAX_ITEM_SIZ) + strcpy(s, p); + else + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("time zone format value too long"))); pfree(p); s += strlen(s); } @@ -2712,7 +2720,14 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col INVALID_FOR_INTERVAL; if (tmtcTzn(in)) { - strcpy(s, tmtcTzn(in)); + const char *p = tmtcTzn(in); + + if (strlen(p) <= n->key->len * DCH_MAX_ITEM_SIZ) + strcpy(s, p); + else + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("time zone format value too long"))); s += strlen(s); } break; From cb947ca31f6947f3746341a635f90395a3ee52e6 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:03 -0700 Subject: [PATCH 318/481] Harden tsvector code against overflows. The core of this patch is to prevent array_to_tsvector() from generating invalid tsvectors. It did not check for overly-long lexemes (so that WordEntry.len fields could overflow), nor did it check that the total "datalen" fits within MAXSTRPOS (so that WordEntry.pos fields could overflow, and the number of entries in the tsvector could be much more than the normal limit). While the field overflows couldn't do anything much worse than produce a corrupted tsvector value, a sufficiently large number of tsvector entries could cause integer overflows in later processing, such as tsvectorout. Another important fix is to prevent tsvectorrecv() from accepting invalid tsvectors. The main problem there is that it did not reject empty-string lexemes. Hence, even though it did (mostly) enforce the MAXSTRPOS limit, it could still produce a result with an unreasonable number of tsvector entries, if they were primarily empty strings. Also, fix tsvectorout's calculation of its required output buffer size: it was multiplying the string lengths by pg_database_encoding_max_length() for no reason. That contributed to the risk of integer overflow there. With valid tsvector input, there's no risk, but there's still no reason to make the output buffer several times bigger than needed. I also tried to make a couple of related routines more robust, and spent some effort on improving the comments in ts_type.h. Also, standardize on a single spelling of the "string is too long for tsvector" message, using %zu instead of an assortment of formats. These changes aren't security per se but came out of inspecting the code for problems. Reported-by: Yuhang Wu and Zhenpeng Lin Reported-by: Zheng Yu Reported-by: Hcamael Author: Tom Lane Reviewed-by: Amit Langote Backpatch-through: 14 Security: CVE-2026-14662 --- src/backend/tsearch/to_tsany.c | 23 +++++++++++---- src/backend/tsearch/ts_parse.c | 27 ++++++++++++++---- src/backend/utils/adt/tsvector.c | 28 ++++++++++++++----- src/backend/utils/adt/tsvector_op.c | 40 +++++++++++++++++++++++---- src/include/tsearch/ts_type.h | 43 ++++++++++++++++++++--------- 5 files changed, 126 insertions(+), 35 deletions(-) diff --git a/src/backend/tsearch/to_tsany.c b/src/backend/tsearch/to_tsany.c index d98def5b63f..46a92a8105a 100644 --- a/src/backend/tsearch/to_tsany.c +++ b/src/backend/tsearch/to_tsany.c @@ -165,8 +165,8 @@ TSVector make_tsvector(ParsedText *prs) { int i, - j, - lenstr = 0, + j; + size_t lenstr = 0, totallen; TSVector in; WordEntry *ptr; @@ -177,10 +177,22 @@ make_tsvector(ParsedText *prs) if (prs->curwords > 0) prs->curwords = uniqueWORD(prs->words, prs->curwords); - /* Determine space needed */ + /* + * Determine space needed. Since what we are calculating is equivalent to + * the size of a portion of the input data structure, lenstr surely can't + * overflow size_t. + */ for (i = 0; i < prs->curwords; i++) { - lenstr += prs->words[i].len; + int toklen = prs->words[i].len; + + /* Double-check that caller passed only lexemes of valid lengths */ + if (toklen <= 0 || toklen > MAXSTRLEN) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("lexeme is too long for tsvector (%zu bytes, max %zu bytes)", + (size_t) toklen, (size_t) MAXSTRLEN))); + lenstr += toklen; if (prs->words[i].alen) { lenstr = SHORTALIGN(lenstr); @@ -191,7 +203,8 @@ make_tsvector(ParsedText *prs) if (lenstr > MAXSTRPOS) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("string is too long for tsvector (%d bytes, max %d bytes)", lenstr, MAXSTRPOS))); + errmsg("string is too long for tsvector (%zu bytes, max %zu bytes)", + lenstr, (size_t) MAXSTRPOS))); totallen = CALCDATASIZE(prs->curwords, lenstr); in = (TSVector) palloc0(totallen); diff --git a/src/backend/tsearch/ts_parse.c b/src/backend/tsearch/ts_parse.c index 64b62dcd3c0..cb69e9899c5 100644 --- a/src/backend/tsearch/ts_parse.c +++ b/src/backend/tsearch/ts_parse.c @@ -401,12 +401,30 @@ parsetext(Oid cfgId, ParsedText *prs, char *buf, int buflen) while ((norms = LexizeExec(&ldata, NULL)) != NULL) { - TSLexeme *ptr = norms; - prs->pos++; /* set pos */ - while (ptr->lexeme) + for (TSLexeme *ptr = norms; ptr->lexeme; ptr++) { + size_t lexeme_len = strlen(ptr->lexeme); + + if (lexeme_len > MAXSTRLEN) + { +#ifdef IGNORE_LONGLEXEME + ereport(NOTICE, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("word is too long to be indexed"), + errdetail("Words longer than %d characters are ignored.", + MAXSTRLEN))); + continue; +#else + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("word is too long to be indexed"), + errdetail("Words longer than %d characters are ignored.", + MAXSTRLEN))); +#endif + } + if (prs->curwords == prs->lenwords) { prs->lenwords *= 2; @@ -415,13 +433,12 @@ parsetext(Oid cfgId, ParsedText *prs, char *buf, int buflen) if (ptr->flags & TSL_ADDPOS) prs->pos++; - prs->words[prs->curwords].len = strlen(ptr->lexeme); + prs->words[prs->curwords].len = lexeme_len; prs->words[prs->curwords].word = ptr->lexeme; prs->words[prs->curwords].nvariant = ptr->nvariant; prs->words[prs->curwords].flags = ptr->flags & TSL_PREFIX; prs->words[prs->curwords].alen = 0; prs->words[prs->curwords].pos.pos = LIMITPOS(prs->pos); - ptr++; prs->curwords++; } pfree(norms); diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c index 024f5160cd4..40be82b890a 100644 --- a/src/backend/utils/adt/tsvector.c +++ b/src/backend/utils/adt/tsvector.c @@ -217,8 +217,8 @@ tsvectorin(PG_FUNCTION_ARGS) if (cur - tmpbuf > MAXSTRPOS) ereturn(escontext, (Datum) 0, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("string is too long for tsvector (%ld bytes, max %ld bytes)", - (long) (cur - tmpbuf), (long) MAXSTRPOS))); + errmsg("string is too long for tsvector (%zu bytes, max %zu bytes)", + (size_t) (cur - tmpbuf), (size_t) MAXSTRPOS))); /* * Enlarge buffers if needed @@ -271,7 +271,8 @@ tsvectorin(PG_FUNCTION_ARGS) if (buflen > MAXSTRPOS) ereturn(escontext, (Datum) 0, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("string is too long for tsvector (%d bytes, max %d bytes)", buflen, MAXSTRPOS))); + errmsg("string is too long for tsvector (%zu bytes, max %zu bytes)", + (size_t) buflen, (size_t) MAXSTRPOS))); totallen = CALCDATASIZE(len, buflen); in = (TSVector) palloc0(totallen); @@ -316,8 +317,8 @@ tsvectorout(PG_FUNCTION_ARGS) TSVector out = PG_GETARG_TSVECTOR(0); char *outbuf; int32 i, - lenbuf = 0, pp; + size_t lenbuf; WordEntry *ptr = ARRPTR(out); char *curin, *curout; @@ -326,7 +327,7 @@ tsvectorout(PG_FUNCTION_ARGS) lenbuf = out->size * 2 /* '' */ + out->size - 1 /* space */ + 2 /* \0 */ ; for (i = 0; i < out->size; i++) { - lenbuf += ptr[i].len * 2 * pg_database_encoding_max_length() /* for escape */ ; + lenbuf += ptr[i].len * 2 /* allow for escapes */ ; if (ptr[i].haspos) lenbuf += 1 /* : */ + 7 /* int2 + , + weight */ * POSDATALEN(out, &(ptr[i])); } @@ -458,12 +459,14 @@ tsvectorrecv(PG_FUNCTION_ARGS) bool needSort = false; nentries = pq_getmsgint(buf, sizeof(int32)); - if (nentries < 0 || nentries > (MaxAllocSize / sizeof(WordEntry))) + + /* We disallow empty lexemes, so more than MAXSTRPOS of them can't fit */ + if (nentries < 0 || nentries > MAXSTRPOS) elog(ERROR, "invalid size of tsvector"); hdrlen = DATAHDRSIZE + sizeof(WordEntry) * nentries; - len = hdrlen * 2; /* times two to make room for lexemes */ + len = hdrlen * 2; /* times two to make some room for lexemes */ vec = (TSVector) palloc0(len); vec->size = nentries; @@ -480,6 +483,8 @@ tsvectorrecv(PG_FUNCTION_ARGS) /* sanity checks */ lex_len = strlen(lexeme); + if (lex_len == 0) + elog(ERROR, "invalid tsvector: empty lexeme"); if (lex_len > MAXSTRLEN) elog(ERROR, "invalid tsvector: lexeme too long"); @@ -545,6 +550,15 @@ tsvectorrecv(PG_FUNCTION_ARGS) } } + /* + * Enforce that datalen is still within MAXSTRPOS, ie the last lexeme + * didn't go past that. We could allow that, since no "pos" field + * overflowed, but tsvectorrecv shouldn't accept values that other + * tsvector-constructing routines wouldn't. + */ + if (datalen > MAXSTRPOS) + elog(ERROR, "invalid tsvector: maximum total lexeme length exceeded"); + SET_VARSIZE(vec, hdrlen + datalen); if (needSort) diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c index 53a9541e89f..935a7fae538 100644 --- a/src/backend/utils/adt/tsvector_op.c +++ b/src/backend/utils/adt/tsvector_op.c @@ -175,6 +175,7 @@ tsvector_strip(PG_FUNCTION_ARGS) *arrout; char *cur; + /* Output can't be bigger than input, so no need for overflow checks */ for (i = 0; i < in->size; i++) len += arrin[i].len; @@ -492,6 +493,8 @@ tsvector_delete_by_indices(TSVector tsv, int *indices_to_delete, /* * Copy tsv to tsout, skipping lexemes listed in indices_to_delete. + * + * Output can't be bigger than input, so no need for overflow checks. */ arrout = ARRPTR(tsout); dataout = STRPTR(tsout); @@ -721,7 +724,7 @@ tsvector_to_array(PG_FUNCTION_ARGS) int i; ArrayType *array; - elements = palloc(tsin->size * sizeof(Datum)); + elements = palloc_array(Datum, tsin->size); for (i = 0; i < tsin->size; i++) { @@ -756,20 +759,29 @@ array_to_tsvector(PG_FUNCTION_ARGS) deconstruct_array_builtin(v, TEXTOID, &dlexemes, &nulls, &nitems); /* - * Reject nulls and zero length strings (maybe we should just ignore them, - * instead?) + * Reject nulls and zero-length or over-length strings (maybe we should + * just ignore them, instead?) */ for (i = 0; i < nitems; i++) { + int toklen; + if (nulls[i]) ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("lexeme array may not contain nulls"))); - if (VARSIZE(DatumGetPointer(dlexemes[i])) - VARHDRSZ == 0) + toklen = VARSIZE(DatumGetPointer(dlexemes[i])) - VARHDRSZ; + if (toklen == 0) ereport(ERROR, (errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING), errmsg("lexeme array may not contain empty strings"))); + if (toklen >= MAXSTRLEN) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("word is too long (%d bytes, max %d bytes)", + toklen, + MAXSTRLEN - 1))); } /* Sort and de-dup, because this is required for a valid tsvector. */ @@ -783,6 +795,11 @@ array_to_tsvector(PG_FUNCTION_ARGS) /* Calculate space needed for surviving lexemes. */ for (i = 0; i < nitems; i++) datalen += VARSIZE(DatumGetPointer(dlexemes[i])) - VARHDRSZ; + if (datalen > MAXSTRPOS) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("string is too long for tsvector (%zu bytes, max %zu bytes)", + (size_t) datalen, (size_t) MAXSTRPOS))); tslen = CALCDATASIZE(nitems, datalen); /* Allocate and fill tsvector. */ @@ -844,9 +861,15 @@ tsvector_filter(PG_FUNCTION_ARGS) mask |= 1 << parse_weight(char_weight); } + /* + * The output tsvector might be smaller than the input, but it can't be + * bigger, so VARSIZE(tsin) is surely enough space. Also, we don't need + * to worry about overflows below. + */ tsout = (TSVector) palloc0(VARSIZE(tsin)); tsout->size = tsin->size; arrout = ARRPTR(tsout); + /* worst-case location of output's lexemes; we may need to adjust below */ dataout = STRPTR(tsout); for (i = j = 0; i < tsin->size; i++) @@ -946,6 +969,12 @@ tsvector_concat(PG_FUNCTION_ARGS) * Conservative estimate of space needed. We might need all the data in * both inputs, and conceivably add a pad byte before position data for * each item where there was none before. + * + * Note: since the MAXSTRPOS limit constrains each input tsvector to be + * considerably less than MaxAllocSize, we don't need to worry about + * integer overflow here, nor in the data-copying steps below. We do need + * to enforce that the result meets the MAXSTRPOS limit, but we check that + * once at the end. */ output_bytes = VARSIZE(in1) + VARSIZE(in2) + i1 + i2; @@ -1097,7 +1126,8 @@ tsvector_concat(PG_FUNCTION_ARGS) if (dataoff > MAXSTRPOS) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("string is too long for tsvector (%d bytes, max %d bytes)", dataoff, MAXSTRPOS))); + errmsg("string is too long for tsvector (%zu bytes, max %zu bytes)", + (size_t) dataoff, (size_t) MAXSTRPOS))); /* * Adjust sizes (asserting that we didn't overrun the original estimates) diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h index 0226220e421..ee1e061c506 100644 --- a/src/include/tsearch/ts_type.h +++ b/src/include/tsearch/ts_type.h @@ -35,7 +35,9 @@ * * The positions for each lexeme must be sorted. * - * Note, tsvectorsend/recv believe that sizeof(WordEntry) == 4 + * Note that while the WordEntry items must be sorted per tsCompareString(), + * the per-lexeme data storage could be in some other order, ie the series + * of WordEntry->pos values need not be strictly ascending. */ typedef struct @@ -46,13 +48,15 @@ typedef struct pos:20; /* MAX 1Mb */ } WordEntry; -#define MAXSTRLEN ( (1<<11) - 1) -#define MAXSTRPOS ( (1<<20) - 1) +#define MAXSTRLEN ( (1<<11) - 1) /* maximum value of WordEntry.len */ +#define MAXSTRPOS ( (1<<20) - 1) /* maximum value of WordEntry.pos */ extern int compareWordEntryPos(const void *a, const void *b); /* - * Equivalent to + * Representation of positions (and weights) associated with a lexeme. + * + * WordEntryPos is equivalent to * typedef struct { * uint16 * weight:2, @@ -75,40 +79,53 @@ typedef struct WordEntryPos pos[1]; } WordEntryPosVector1; +#define MAXNUMPOS (256) /* semi-arbitrary limit on npos */ +/* Macros for getting/setting the fields of a WordEntryPos */ #define WEP_GETWEIGHT(x) ( (x) >> 14 ) #define WEP_GETPOS(x) ( (x) & 0x3fff ) #define WEP_SETWEIGHT(x,v) ( (x) = ( (v) << 14 ) | ( (x) & 0x3fff ) ) #define WEP_SETPOS(x,v) ( (x) = ( (x) & 0xc000 ) | ( (v) & 0x3fff ) ) -#define MAXENTRYPOS (1<<14) -#define MAXNUMPOS (256) +#define MAXENTRYPOS (1<<14) /* max value of WordEntryPos pos field, +1 */ +/* Macro for clamping a position to what will fit in WordEntryPos pos field */ #define LIMITPOS(x) ( ( (x) >= MAXENTRYPOS ) ? (MAXENTRYPOS-1) : (x) ) /* This struct represents a complete tsvector datum */ typedef struct { int32 vl_len_; /* varlena header (do not touch directly!) */ - int32 size; + int32 size; /* number of entries[] items */ WordEntry entries[FLEXIBLE_ARRAY_MEMBER]; /* lexemes follow the entries[] array */ } TSVectorData; typedef TSVectorData *TSVector; +/* + * Calculate the size of a TSVector given the number of WordEntries and + * the total space needed for lexeme text and positions. NOTE: callers + * must enforce lenstr <= MAXSTRPOS, which ensures that WordEntry.pos + * fields will not overflow, and also protects against integer overflow here. + * (Since we prohibit empty lexemes, nentries can't exceed lenstr.) + */ #define DATAHDRSIZE (offsetof(TSVectorData, entries)) #define CALCDATASIZE(nentries, lenstr) (DATAHDRSIZE + (nentries) * sizeof(WordEntry) + (lenstr) ) /* pointer to start of a tsvector's WordEntry array */ -#define ARRPTR(x) ( (x)->entries ) +#define ARRPTR(tsv) ( (tsv)->entries ) /* pointer to start of a tsvector's lexeme storage */ -#define STRPTR(x) ( (char *) &(x)->entries[(x)->size] ) - -#define _POSVECPTR(x, e) ((WordEntryPosVector *)(STRPTR(x) + SHORTALIGN((e)->pos + (e)->len))) -#define POSDATALEN(x,e) ( ( (e)->haspos ) ? (_POSVECPTR(x,e)->npos) : 0 ) -#define POSDATAPTR(x,e) (_POSVECPTR(x,e)->pos) +#define STRPTR(tsv) ( (char *) &(tsv)->entries[(tsv)->size] ) + +/* pointer to WordEntryPosVector for a WordEntry */ +#define _POSVECPTR(tsv,we) ((WordEntryPosVector *) \ + (STRPTR(tsv) + SHORTALIGN((we)->pos + (we)->len))) +/* number of positions stored for a WordEntry */ +#define POSDATALEN(tsv,we) ( (we)->haspos ? _POSVECPTR(tsv,we)->npos : 0 ) +/* pointer to start of positions stored for a WordEntry */ +#define POSDATAPTR(tsv,we) (_POSVECPTR(tsv,we)->pos) /* * fmgr interface functions From 3b2238fbe9b9cc95f026fd4129804a72d0c22151 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:03 -0700 Subject: [PATCH 319/481] Harden tsquery code against overflows. The only overflow hazards I could find in tsquery construction are in QTN2QT(), which builds a flat tsquery datum from the QTNode tree representation used by tsquery_or, tsquery_rewrite, and allied functions. There are two: 1. It seems theoretically possible for the outputs of cntsize() to overflow an int, so I widened them to size_t. There's no hazard certainly in tsquery_or and friends, but tsquery_rewrite could expand the query tree by large multiples (by replacing many identical subtrees with a large replacement tree), so in a 64-bit machine with plenty of available memory it should be possible to build a QTNode tree large enough to cause that. If these counters did overflow then we'd under-allocate the output tsquery and have a heap overwrite problem. size_t is sufficient, since it's counting the size of a subset of an in-memory data structure. We also have to fix the TSQUERY_TOO_BIG() macro to not get confused if sumlen exceeds MaxAllocSize. 2. fillQT() neglects to check that the new "distance" value for a QI_VAL item fits into the available 20-bit field. It's quite easy to reach this, for example by tsquery_or'ing two near-megabyte-sized tsquerys. However, the result is only a corrupt tsquery that does not represent the expected query, so perhaps this doesn't rise to the level of a security bug. Nonetheless it should be fixed. Note: I followed the practice used in other tsquery code of checking each distance value as it's assigned, which means that the last operand string could extend past the MAXSTRPOS boundary. This is a bit different from the pattern used for tsvectors, which insist that the total data length not exceed MAXSTRPOS and thereby avoid making per-item checks. Perhaps that should be harmonized sometime, but for now it's okay for the two types to do this differently as long as each one is self-consistent. Author: Tom Lane Reviewed-by: Amit Langote Backpatch-through: 14 Security: CVE-2026-14662 --- src/backend/utils/adt/tsquery_util.c | 13 ++++++++++--- src/include/tsearch/ts_type.h | 3 ++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/adt/tsquery_util.c b/src/backend/utils/adt/tsquery_util.c index 2eb215609f7..b666b2d632c 100644 --- a/src/backend/utils/adt/tsquery_util.c +++ b/src/backend/utils/adt/tsquery_util.c @@ -289,7 +289,7 @@ QTNBinary(QTNode *in) * Caller must initialize *sumlen and *nnode to zeroes. */ static void -cntsize(QTNode *in, int *sumlen, int *nnode) +cntsize(QTNode *in, size_t *sumlen, size_t *nnode) { /* since this function recurses, it could be driven to stack overflow. */ check_stack_depth(); @@ -327,10 +327,17 @@ fillQT(QTN2QTState *state, QTNode *in) if (in->valnode->type == QI_VAL) { + size_t distance; + memcpy(state->curitem, in->valnode, sizeof(QueryOperand)); memcpy(state->curoperand, in->word, in->valnode->qoperand.length); - state->curitem->qoperand.distance = state->curoperand - state->operand; + distance = state->curoperand - state->operand; + if (distance > MAXSTRPOS) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("tsquery is too large"))); + state->curitem->qoperand.distance = distance; state->curoperand[in->valnode->qoperand.length] = '\0'; state->curoperand += in->valnode->qoperand.length + 1; state->curitem++; @@ -364,7 +371,7 @@ QTN2QT(QTNode *in) { TSQuery out; int len; - int sumlen = 0, + size_t sumlen = 0, nnode = 0; QTN2QTState state; diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h index ee1e061c506..345a2dab930 100644 --- a/src/include/tsearch/ts_type.h +++ b/src/include/tsearch/ts_type.h @@ -251,7 +251,8 @@ typedef TSQueryData *TSQuery; */ #define COMPUTESIZE(size, lenofoperand) ( HDRSIZETQ + (size) * sizeof(QueryItem) + (lenofoperand) ) #define TSQUERY_TOO_BIG(size, lenofoperand) \ - ((size) > (MaxAllocSize - HDRSIZETQ - (lenofoperand)) / sizeof(QueryItem)) + ((size_t) (lenofoperand) > MaxAllocSize - HDRSIZETQ || \ + (size) > (MaxAllocSize - HDRSIZETQ - (lenofoperand)) / sizeof(QueryItem)) /* Returns a pointer to the first QueryItem in a TSQuery */ #define GETQUERY(x) ((QueryItem*)( (char*)(x)+HDRSIZETQ )) From 7df2aa8efeba44189dc8d763da34ce171422307e Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Mon, 10 Aug 2026 06:38:04 -0700 Subject: [PATCH 320/481] Fix potential buffer overrun in regexp match/split functions. setup_regexp_matches() sizes the buffer used to convert matched substrings back from pg_wchar form at the smaller of maxlen*eml and the original string's byte length, on the assumption that such a conversion cannot produce more bytes than the string it came from. That assumption holds only for validly encoded input. But pg_mb2wchar_with_len() silently accepts bytes that are invalid in the database encoding, turning each such byte into one pg_wchar, and converting that back can take more bytes than the input did. A string made of such bytes therefore overruns the conversion buffer by up to its own length, corrupting the following memory. regexp_match(), regexp_matches(), regexp_split_to_table() and regexp_split_to_array() are all affected. Fix by dropping the tighter bound and always allocating maxlen*eml + 1 bytes. Reported-by: Francesco Verardi Author: Masahiko Sawada Reviewed-by: Tom Lane Backpatch-through: 14 Security: CVE-2026-14664 --- src/backend/utils/adt/regexp.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/regexp.c b/src/backend/utils/adt/regexp.c index 311b9877bbb..0768b5c7389 100644 --- a/src/backend/utils/adt/regexp.c +++ b/src/backend/utils/adt/regexp.c @@ -1648,23 +1648,24 @@ setup_regexp_matches(text *orig_str, text *pattern, pg_re_flags *re_flags, if (eml > 1) { - int64 maxsiz = eml * (int64) maxlen; int conv_bufsiz; /* * Make the conversion buffer large enough for any substring of - * interest. + * interest. We can't use the original string's byte length as a + * tighter bound, because that assumes the input is validly encoded; + * but pg_mb2wchar_with_len() can accept strings that are invalid in + * the database encoding, and converting such a character back to + * multibyte form can take more bytes than it did in the input. * - * Worst case: assume we need the maximum size (maxlen*eml), but take - * advantage of the fact that the original string length in bytes is - * an upper bound on the byte length of any fetched substring (and we - * know that len+1 is safe to allocate because the varlena header is - * longer than 1 byte). + * This can't overflow, nor exceed what palloc will accept: maxlen is + * at most wide_len, which is at most orig_len, and we have already + * successfully allocated (orig_len + 1) * sizeof(pg_wchar) bytes for + * wide_str. That relies on eml being no more than sizeof(pg_wchar), + * which is true of all supported encodings. */ - if (maxsiz > orig_len) - conv_bufsiz = orig_len + 1; - else - conv_bufsiz = maxsiz + 1; /* safe since maxsiz < 2^30 */ + Assert(eml <= sizeof(pg_wchar)); + conv_bufsiz = maxlen * eml + 1; matchctx->conv_buf = palloc(conv_bufsiz); matchctx->conv_bufsiz = conv_bufsiz; From 8c48cd615195e80925fb81ad77bd08a8bd4eb0c2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:04 -0700 Subject: [PATCH 321/481] Harden PL/Perl code against "tied" Perl arrays and hashes. Tied arrays might report different sizes each time they are inspected. To avoid generating a corrupt result array, fix plperl_array_to_datum() to read av_len() of each input array only once. If the input does appear to get shorter, we'll fill nulls for the now-missing entries, which seems fine. Conversely, if it gets longer, we'll ignore the new entries. plperl_to_hstore() assumed that Perl's hv_iterinit() returns the number of entries in the given Perl hash. Usually that's true, but per the Perl docs, "the return value is currently only meaningful for hashes without tie magic". That could potentially end in a memory stomp. We don't depend on that result value anywhere else, so don't do so here either. Reported-by: Hcamael Author: Tom Lane Reviewed-by: Andrew Dunstan Backpatch-through: 14 Security: CVE-2026-14670 --- contrib/hstore_plperl/hstore_plperl.c | 11 +++++++++-- src/pl/plperl/plperl.c | 6 +++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/contrib/hstore_plperl/hstore_plperl.c b/contrib/hstore_plperl/hstore_plperl.c index 336ead65a18..d7f1b8ddb48 100644 --- a/contrib/hstore_plperl/hstore_plperl.c +++ b/contrib/hstore_plperl/hstore_plperl.c @@ -129,8 +129,9 @@ plperl_to_hstore(PG_FUNCTION_ARGS) errmsg("cannot transform non-hash Perl value to hstore"))); hv = (HV *) in; - pcount = hv_iterinit(hv); + (void) hv_iterinit(hv); + pcount = 64; /* arbitrary initial guess */ pairs = palloc_array(Pairs, pcount); i = 0; @@ -139,6 +140,12 @@ plperl_to_hstore(PG_FUNCTION_ARGS) char *key = sv2cstr(HeSVKEY_force(he)); SV *value = HeVAL(he); + if (i >= pcount) + { + pcount *= 2; + pairs = repalloc_array(pairs, Pairs, pcount); + } + pairs[i].key = pstrdup(key); pairs[i].keylen = hstoreCheckKeyLen(strlen(pairs[i].key)); pairs[i].needfree = true; @@ -159,7 +166,7 @@ plperl_to_hstore(PG_FUNCTION_ARGS) i++; } - pcount = hstoreUniquePairs(pairs, pcount, &buflen); + pcount = hstoreUniquePairs(pairs, i, &buflen); out = hstorePairs(pairs, pcount, buflen); PG_RETURN_POINTER(out); } diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 9ddb81d42b9..dbc6beeac92 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -1171,6 +1171,10 @@ get_perl_array_ref(SV *sv) * if we didn't do it like that, we'd need some other convention for knowing * whether we'd already found any scalars (and thus the number of dimensions * is frozen). + * + * Caller is required to have set dims[cur_depth - 1] to the length of the + * input array, i.e., av_len(av) + 1. We make this requirement so as to + * avoid reading av_len() twice, which is hazardous for tied arrays. */ static void array_to_datum_internal(AV *av, ArrayBuildState **astatep, @@ -1180,7 +1184,7 @@ array_to_datum_internal(AV *av, ArrayBuildState **astatep, { dTHX; int i; - int len = av_len(av) + 1; + int len = dims[cur_depth - 1]; for (i = 0; i < len; i++) { From 0d60ee71727ccd71a791b088a91c4bd8c1fb85e4 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:04 -0700 Subject: [PATCH 322/481] Be more wary about constant's datatype in scalarineqsel(). The special case here for estimating conditions involving a ctid column failed to check that the RHS constant is of type tid. While that'd always be true for the built-in operators that reference this selectivity estimator, a maliciously constructed operator could provide a user-controlled Datum value that would get interpreted as an ItemPointer pointer. That at least risks SIGSEGV, and perhaps with a bit of sweat it could be used for server memory disclosure. Reported-by: Hcamael Author: Tom Lane Reviewed-by: Noah Misch Backpatch-through: 14 Security: CVE-2026-14668 --- src/backend/utils/adt/selfuncs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index cbc70fde716..fd8a3600f1a 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -669,7 +669,8 @@ scalarineqsel(PlannerInfo *root, Oid operator, bool isgt, bool iseq, * make an estimate based on comparing the constant to the table size. */ if (vardata->var && IsA(vardata->var, Var) && - ((Var *) vardata->var)->varattno == SelfItemPointerAttributeNumber) + ((Var *) vardata->var)->varattno == SelfItemPointerAttributeNumber && + consttype == TIDOID) { ItemPointer itemptr; double block; From 92972e815d85038ccb8574a1d7e2f2df8d148fe9 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:04 -0700 Subject: [PATCH 323/481] Replace fixed-size, too-short array with a palloc'd one. MatchNamedCall's arggiven array was declared FUNC_MAX_ARGS long, but we may actually use up to pronallargs elements, and that can be more than FUNC_MAX_ARGS if the function has OUT arguments (cf. ProcedureCreate). Convert it to a palloc'd array. Reported-by: Zheng Yu Reported-by: ylwangtju Author: Tom Lane Reviewed-by: Michael Paquier Reviewed-by: Masahiko Sawada Backpatch-through: 14 Security: CVE-2026-14679 --- src/backend/catalog/namespace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 56b87d878e8..b2daf9adb32 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -1625,7 +1625,7 @@ MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, Oid *p_argtypes; char **p_argnames; char *p_argmodes; - bool arggiven[FUNC_MAX_ARGS]; + bool *arggiven; bool arg_filled_twice = false; bool isnull; int ap; /* call args position */ @@ -1650,8 +1650,8 @@ MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, Assert(include_out_arguments ? (pronargs == pronallargs) : (pronargs <= pronallargs)); /* initialize state for matching */ - *argnumbers = (int *) palloc(pronargs * sizeof(int)); - memset(arggiven, false, pronargs * sizeof(bool)); + *argnumbers = palloc_array(int, pronargs); + arggiven = palloc0_array(bool, pronallargs); /* there are numposargs positional args before the named args */ for (ap = 0; ap < numposargs; ap++) From 86cd82bf4887cd7abf2f0203d3e1a09e7022746d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:04 -0700 Subject: [PATCH 324/481] pg_dump: avoid assuming how long pg_proc.protrftypes can be. The backend doesn't impose any particular limit on the length of this array, and since there could be entries for both input and output arguments, it's feasible for the length to exceed FUNC_MAX_ARGS even without funny business. This could lead to crashes or worse. Moreover, pg_dump shouldn't rely on hard-coding FUNC_MAX_ARGS in the first place: it has no business assuming that the backend it's dumping from was compiled with the same value of FUNC_MAX_ARGS that it is. So the stanza in dumpFunc() that allocates exactly FUNC_MAX_ARGS space for the parsed OID array is fundamentally misguided. And it's broken in another way too: if there are exactly FUNC_MAX_ARGS OIDs, then parseOidArray won't zero-fill any entries, allowing the subsequent loop to run off the end of the array. A crash seems unlikely in this variant, but garbage output is certain. To fix, redesign parseOidArray's API so that it does the array-mallocing, which simplifies the callers anyway. While we're here, tighten and modernize it a bit; in particular, split it into separate functions for OIDs and integers, as was foreseen long ago. This lets us get rid of the confusing type-punning involved in having IndxInfo.indkeys be declared as "Oid *" when it's really potentially-signed ints. Also, most of the callers expect an exact number of array entries, so make it verify that not just check for "too many". I noted while testing that this dumpFunc() stanza isn't even reached during check-world. Add a function with transform to the regression tests to rectify that. Reported-by: Masahiko Sawada Author: Tom Lane Reviewed-by: Masahiko Sawada Backpatch-through: 14 Security: CVE-2026-19385 --- src/bin/pg_dump/common.c | 142 ++++++++++++++++--- src/bin/pg_dump/pg_dump.c | 30 ++-- src/bin/pg_dump/pg_dump.h | 5 +- src/test/regress/expected/object_address.out | 4 + src/test/regress/sql/object_address.sql | 4 + 5 files changed, 140 insertions(+), 45 deletions(-) diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index dc98c5c5c09..047e1c6bb35 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -1103,50 +1103,146 @@ findOwningExtension(CatalogId catalogId) /* * parseOidArray - * parse a string of numbers delimited by spaces into a character array + * parse a string of unsigned numbers separated by spaces + * into an array of OIDs * - * Note: actually this is used for both Oids and potentially-signed - * attribute numbers. This should cause no trouble, but we could split - * the function into two functions with different argument types if it does. + * The result is a malloc'd array. + * + * If arraysize >= 0, we insist that the input contain exactly that many + * OIDs, and the allocated array is of that length too. If arraysize < 0, + * we dynamically size the array to have one more entry than the input + * provides, and fill the extra entry with zero. */ - -void -parseOidArray(const char *str, Oid *array, int arraysize) +Oid * +parseOidArray(const char *str, int arraysize) { - int j, - argNum; - char temp[100]; - char s; - + Oid *array; + int allocsize, + argNum, + templen; + char temp[32]; + + if (arraysize >= 0) + allocsize = arraysize; + else + { + /* + * Make enough room for input + one extra entry (could be more than + * enough, if there are redundant spaces in the input). + */ + allocsize = 2; + for (const char *s1 = str; *s1; s1++) + { + if (*s1 == ' ') + allocsize++; + } + } + array = pg_malloc_array(Oid, allocsize); argNum = 0; - j = 0; - for (;;) + templen = 0; + for (const char *s1 = str;; s1++) { - s = *str++; + char s = *s1; + if (s == ' ' || s == '\0') { - if (j > 0) + if (templen > 0) { - if (argNum >= arraysize) + if (arraysize >= 0 && argNum >= arraysize) pg_fatal("could not parse numeric array \"%s\": too many numbers", str); - temp[j] = '\0'; + temp[templen] = '\0'; array[argNum++] = atooid(temp); - j = 0; + templen = 0; } if (s == '\0') break; } else { - if (!(isdigit((unsigned char) s) || s == '-') || - j >= sizeof(temp) - 1) + if (!isdigit((unsigned char) s) || + templen >= sizeof(temp) - 1) pg_fatal("could not parse numeric array \"%s\": invalid character in number", str); - temp[j++] = s; + temp[templen++] = s; } } - while (argNum < arraysize) + if (arraysize >= 0 && argNum != arraysize) + pg_fatal("could not parse numeric array \"%s\": too few numbers", str); + + while (argNum < allocsize) array[argNum++] = InvalidOid; + + return array; +} + + +/* + * parseIntArray + * parse a string of possibly-signed numbers separated by spaces + * into an array of ints + * + * This is exactly like parseOidArray, but for integers. + */ +int * +parseIntArray(const char *str, int arraysize) +{ + int *array; + int allocsize, + argNum, + templen; + char temp[32]; + + if (arraysize >= 0) + allocsize = arraysize; + else + { + /* + * Make enough room for input + one extra entry (could be more than + * enough, if there are redundant spaces in the input). + */ + allocsize = 2; + for (const char *s1 = str; *s1; s1++) + { + if (*s1 == ' ') + allocsize++; + } + } + array = pg_malloc_array(int, allocsize); + argNum = 0; + templen = 0; + for (const char *s1 = str;; s1++) + { + char s = *s1; + + if (s == ' ' || s == '\0') + { + if (templen > 0) + { + if (arraysize >= 0 && argNum >= arraysize) + pg_fatal("could not parse numeric array \"%s\": too many numbers", str); + temp[templen] = '\0'; + array[argNum++] = atoi(temp); + templen = 0; + } + if (s == '\0') + break; + } + else + { + if (!(isdigit((unsigned char) s) || s == '-') || + templen >= sizeof(temp) - 1) + pg_fatal("could not parse numeric array \"%s\": invalid character in number", str); + temp[templen++] = s; + } + } + + if (arraysize >= 0 && argNum != arraysize) + pg_fatal("could not parse numeric array \"%s\": too few numbers", str); + + while (argNum < allocsize) + array[argNum++] = 0; + + return array; } diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 41b9531e41a..0abc80ea5b6 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -6976,12 +6976,8 @@ getAggregates(Archive *fout) if (agginfo[i].aggfn.nargs == 0) agginfo[i].aggfn.argtypes = NULL; else - { - agginfo[i].aggfn.argtypes = pg_malloc_array(Oid, agginfo[i].aggfn.nargs); - parseOidArray(PQgetvalue(res, i, i_proargtypes), - agginfo[i].aggfn.argtypes, - agginfo[i].aggfn.nargs); - } + agginfo[i].aggfn.argtypes = parseOidArray(PQgetvalue(res, i, i_proargtypes), + agginfo[i].aggfn.nargs); agginfo[i].aggfn.postponed_def = false; /* might get set during sort */ /* Decide whether we want to dump it */ @@ -7169,11 +7165,8 @@ getFuncs(Archive *fout) if (finfo[i].nargs == 0) finfo[i].argtypes = NULL; else - { - finfo[i].argtypes = pg_malloc_array(Oid, finfo[i].nargs); - parseOidArray(PQgetvalue(res, i, i_proargtypes), - finfo[i].argtypes, finfo[i].nargs); - } + finfo[i].argtypes = parseOidArray(PQgetvalue(res, i, i_proargtypes), + finfo[i].nargs); finfo[i].postponed_def = false; /* might get set during sort */ /* Decide whether we want to dump it */ @@ -8247,9 +8240,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions)); indxinfo[j].indstatcols = pg_strdup(PQgetvalue(res, j, i_indstatcols)); indxinfo[j].indstatvals = pg_strdup(PQgetvalue(res, j, i_indstatvals)); - indxinfo[j].indkeys = pg_malloc_array(Oid, indxinfo[j].indnattrs); - parseOidArray(PQgetvalue(res, j, i_indkey), - indxinfo[j].indkeys, indxinfo[j].indnattrs); + indxinfo[j].indkeys = parseIntArray(PQgetvalue(res, j, i_indkey), + indxinfo[j].indnattrs); indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't'); indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't'); indxinfo[j].indnullsnotdistinct = (PQgetvalue(res, j, i_indnullsnotdistinct)[0] == 't'); @@ -13868,12 +13860,10 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) if (*protrftypes) { - Oid *typeids = pg_malloc_array(Oid, FUNC_MAX_ARGS); - int i; + Oid *typeids = parseOidArray(protrftypes, -1); appendPQExpBufferStr(q, " TRANSFORM "); - parseOidArray(protrftypes, typeids, FUNC_MAX_ARGS); - for (i = 0; typeids[i]; i++) + for (int i = 0; typeids[i]; i++) { if (i != 0) appendPQExpBufferStr(q, ", "); @@ -19123,7 +19113,7 @@ dumpConstraint(Archive *fout, const ConstraintInfo *coninfo) appendPQExpBufferStr(q, " ("); for (k = 0; k < indxinfo->indnkeyattrs; k++) { - int indkey = (int) indxinfo->indkeys[k]; + int indkey = indxinfo->indkeys[k]; const char *attname; if (indkey == InvalidAttrNumber) @@ -19142,7 +19132,7 @@ dumpConstraint(Archive *fout, const ConstraintInfo *coninfo) for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++) { - int indkey = (int) indxinfo->indkeys[k]; + int indkey = indxinfo->indkeys[k]; const char *attname; if (indkey == InvalidAttrNumber) diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 5a6726d8b12..e6eefa98460 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -426,7 +426,7 @@ typedef struct _indxInfo char *indstatvals; /* statistic values for columns */ int indnkeyattrs; /* number of index key attributes */ int indnattrs; /* total number of index attributes */ - Oid *indkeys; /* In spite of the name 'indkeys' this field + int *indkeys; /* In spite of the name 'indkeys' this field * contains both key and nonkey attributes */ bool indisclustered; bool indisreplident; @@ -782,7 +782,8 @@ extern SubscriptionInfo *findSubscriptionByOid(Oid oid); extern void recordExtensionMembership(CatalogId catId, ExtensionInfo *ext); extern ExtensionInfo *findOwningExtension(CatalogId catalogId); -extern void parseOidArray(const char *str, Oid *array, int arraysize); +extern Oid *parseOidArray(const char *str, int arraysize); +extern int *parseIntArray(const char *str, int arraysize); extern void sortDumpableObjects(DumpableObject **objs, int numObjs, DumpId preBoundaryId, DumpId postBoundaryId); diff --git a/src/test/regress/expected/object_address.out b/src/test/regress/expected/object_address.out index f776865ce14..cf36cb7f4f3 100644 --- a/src/test/regress/expected/object_address.out +++ b/src/test/regress/expected/object_address.out @@ -44,6 +44,10 @@ ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user REVOKE DELETE ON TABLES FROM CREATE TRANSFORM FOR int LANGUAGE SQL ( FROM SQL WITH FUNCTION prsd_lextype(internal), TO SQL WITH FUNCTION int4recv(internal)); +-- make a function that uses it too, mainly to exercise pg_dump +CREATE FUNCTION public.sql_func_with_transform(int) RETURNS int LANGUAGE sql +AS 'select $1 + 1' +TRANSFORM FOR TYPE int; -- suppress warning that depends on wal_level SET client_min_messages = 'ERROR'; CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable; diff --git a/src/test/regress/sql/object_address.sql b/src/test/regress/sql/object_address.sql index ed795a32e22..b274b42e137 100644 --- a/src/test/regress/sql/object_address.sql +++ b/src/test/regress/sql/object_address.sql @@ -47,6 +47,10 @@ ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user REVOKE DELETE ON TABLES FROM CREATE TRANSFORM FOR int LANGUAGE SQL ( FROM SQL WITH FUNCTION prsd_lextype(internal), TO SQL WITH FUNCTION int4recv(internal)); +-- make a function that uses it too, mainly to exercise pg_dump +CREATE FUNCTION public.sql_func_with_transform(int) RETURNS int LANGUAGE sql +AS 'select $1 + 1' +TRANSFORM FOR TYPE int; -- suppress warning that depends on wal_level SET client_min_messages = 'ERROR'; CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable; From 42d9749b7ab56a7cbd751d136aea7abe1c0db887 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:04 -0700 Subject: [PATCH 325/481] Protect some fixed-size arrays that have FUNC_MAX_ARGS elements. The maximum number of arguments allowed for an aggregate function is FUNC_MAX_ARGS-1 (since the underlying transfn and/or finalfn will be called with one more argument). parse_func.c failed to enforce this, allowing construction of calls that would try to pass FUNC_MAX_ARGS+1 to the underlying functions, resulting in a memory stomp in the executor. Add correct checking there. Since it's possible that a bad call has been stored in a view or SQL function, also add checks in various aggregate-related and window-function-related code that there are not more than FUNC_MAX_ARGS arguments. These will also protect us against the possibility that we're trying to run a stored view that was made by a server executable with different FUNC_MAX_ARGS. (Arguably, that scenario does not qualify as a security problem. But let's just tighten up all of this while we're here, rather than split hairs over whether an overrun is reachable.) Likewise check in compute_function_hashkey. Here the hazard is directly from a pg_proc row, but the scenario is the same. PL/Tcl has a similar issue with a fixed-size string buffer. Let's just replace that buffer with a Tcl_DString, removing the whole issue and making the code look more like what's around it. There are a lot of other FUNC_MAX_ARGS-sized arrays, but the rest have nearby guards already, some with comments explicitly pointing out the hazard of FUNC_MAX_ARGS changing. I also used palloc_array() in a few related places in funcapi.c. Those aren't live hazards AFAICS, but nearby code has been palloc_array-ified already, so it seemed inconsistent to not use it here. Reported-by: Masahiko Sawada Author: Tom Lane Reviewed-by: Masahiko Sawada Backpatch-through: 14 Security: CVE-2026-14679 --- src/backend/executor/nodeWindowAgg.c | 33 ++++++++++++++++++++++++++++ src/backend/parser/parse_agg.c | 18 ++++++++++++++- src/backend/parser/parse_func.c | 29 ++++++++++++++++++++++++ src/backend/utils/cache/funccache.c | 14 ++++++++++++ src/backend/utils/fmgr/funcapi.c | 6 ++--- src/pl/tcl/pltcl.c | 22 +++++++++++-------- 6 files changed, 109 insertions(+), 13 deletions(-) diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index 7d6ec2dfc4b..b86dcbba055 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -1085,6 +1085,20 @@ eval_windowfunction(WindowAggState *winstate, WindowStatePerFunc perfuncstate, oldContext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_tuple_memory); + /* + * Protect fixed-size fcinfo. Ordinarily this would have been checked + * while creating the WindowFunc, but it's possible that we are looking at + * a parsetree from a stored view that was made by a server executable + * with a different value of FUNC_MAX_ARGS. + */ + if (perfuncstate->numArguments > FUNC_MAX_ARGS) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("cannot pass more than %d argument to a function", + "cannot pass more than %d arguments to a function", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); + /* * We don't pass any normal arguments to a window function, but we do pass * it the number of arguments, in order to permit window function @@ -2955,6 +2969,25 @@ initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc, numArguments = list_length(wfunc->args); + /* + * Check the number of arguments, to protect fixed-size arrays here and + * later in node execution. + * + * Aggregates can have at most FUNC_MAX_ARGS-1 args (compare + * AggregateCreate, whose error message we want to match). Ordinarily + * this would have been checked while creating the WindowFunc, but it's + * possible that we are looking at a parsetree from a stored view that was + * made by a server executable with a different value of FUNC_MAX_ARGS, or + * an executable in which parse_func.c didn't enforce the correct limit. + */ + if (numArguments > FUNC_MAX_ARGS - 1) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("aggregates cannot have more than %d argument", + "aggregates cannot have more than %d arguments", + FUNC_MAX_ARGS - 1, + FUNC_MAX_ARGS - 1))); + i = 0; foreach(lc, wfunc->args) { diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index acb933392de..754a20507d0 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -2124,7 +2124,23 @@ get_aggregate_argtypes(Aggref *aggref, Oid *inputTypes) int numArguments = 0; ListCell *lc; - Assert(list_length(aggref->aggargtypes) <= FUNC_MAX_ARGS); + /* + * Check the number of arguments to protect fixed-size arrays in callers. + * + * Aggregates can have at most FUNC_MAX_ARGS-1 args (compare + * AggregateCreate, whose error message we want to match). Ordinarily + * this would have been checked while creating the Aggref, but it's + * possible that we are looking at a parsetree from a stored view that was + * made by a server executable with a different value of FUNC_MAX_ARGS, or + * an executable in which parse_func.c didn't enforce the correct limit. + */ + if (list_length(aggref->aggargtypes) > FUNC_MAX_ARGS - 1) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("aggregates cannot have more than %d argument", + "aggregates cannot have more than %d arguments", + FUNC_MAX_ARGS - 1, + FUNC_MAX_ARGS - 1))); foreach(lc, aggref->aggargtypes) { diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index a9b6be7203b..5ffb456a124 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -801,6 +801,22 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, aggref->aggtransno = -1; aggref->location = location; + /* + * The argument-count limit for aggregates is one less than for other + * kinds of functions (cf. AggregateCreate). Now that we know it's an + * aggregate, apply the stricter limit. We need an explicit check + * because hypothetical-set aggregates don't have a fixed number of + * arguments, so having matched the pg_proc entry proves nothing. + */ + if (list_length(fargs) > FUNC_MAX_ARGS - 1) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("aggregates cannot have more than %d argument", + "aggregates cannot have more than %d arguments", + FUNC_MAX_ARGS - 1, + FUNC_MAX_ARGS - 1), + parser_errposition(pstate, location))); + /* * Reject attempt to call a parameterless aggregate without (*) * syntax. This is mere pedantry but some folks insisted ... @@ -867,6 +883,19 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, errmsg("DISTINCT is not implemented for window functions"), parser_errposition(pstate, location))); + /* + * As above, enforce the correct argument-count limit if it's really + * an aggregate. + */ + if (wfunc->winagg && list_length(fargs) > FUNC_MAX_ARGS - 1) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("aggregates cannot have more than %d argument", + "aggregates cannot have more than %d arguments", + FUNC_MAX_ARGS - 1, + FUNC_MAX_ARGS - 1), + parser_errposition(pstate, location))); + /* * Reject attempt to call a parameterless aggregate without (*) * syntax. This is mere pedantry but some folks insisted ... diff --git a/src/backend/utils/cache/funccache.c b/src/backend/utils/cache/funccache.c index 701c294b88d..43f031d53a2 100644 --- a/src/backend/utils/cache/funccache.c +++ b/src/backend/utils/cache/funccache.c @@ -294,6 +294,20 @@ compute_function_hashkey(FunctionCallInfo fcinfo, */ if (procStruct->pronargs > 0) { + /* + * Protect against overrun of fixed-size hashkey->argtypes array. This + * also protects later code in places such as PL/pgSQL. Ordinarily the + * parser would have checked this long since, but it's possible that + * we are looking at a pg_proc entry that was made by a server + * executable with a different value of FUNC_MAX_ARGS. + */ + if (procStruct->pronargs > FUNC_MAX_ARGS) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("cannot pass more than %d argument to a function", + "cannot pass more than %d arguments to a function", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); hashkey->nargs = procStruct->pronargs; memcpy(hashkey->argtypes, procStruct->proargtypes.values, procStruct->pronargs * sizeof(Oid)); diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c index 6f0785067b8..5c56002ba0e 100644 --- a/src/backend/utils/fmgr/funcapi.c +++ b/src/backend/utils/fmgr/funcapi.c @@ -1413,7 +1413,7 @@ get_func_arg_info(HeapTuple procTup, ARR_ELEMTYPE(arr) != OIDOID) elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls"); Assert(numargs >= procStruct->pronargs); - *p_argtypes = (Oid *) palloc(numargs * sizeof(Oid)); + *p_argtypes = palloc_array(Oid, numargs); memcpy(*p_argtypes, ARR_DATA_PTR(arr), numargs * sizeof(Oid)); } @@ -1422,7 +1422,7 @@ get_func_arg_info(HeapTuple procTup, /* If no proallargtypes, use proargtypes */ numargs = procStruct->proargtypes.dim1; Assert(numargs == procStruct->pronargs); - *p_argtypes = (Oid *) palloc(numargs * sizeof(Oid)); + *p_argtypes = palloc_array(Oid, numargs); memcpy(*p_argtypes, procStruct->proargtypes.values, numargs * sizeof(Oid)); } @@ -1501,7 +1501,7 @@ get_func_trftypes(HeapTuple procTup, ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != OIDOID) elog(ERROR, "protrftypes is not a 1-D Oid array or it contains nulls"); - *p_trftypes = (Oid *) palloc(nelems * sizeof(Oid)); + *p_trftypes = palloc_array(Oid, nelems); memcpy(*p_trftypes, ARR_DATA_PTR(arr), nelems * sizeof(Oid)); diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 85e83bbf1e3..64fe71da8c7 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -1430,6 +1430,7 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, Tcl_DString proc_internal_def; Tcl_DString proc_internal_name; Tcl_DString proc_internal_body; + Tcl_DString proc_internal_args; /* We'll need the pg_proc tuple in any case... */ procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fn_oid)); @@ -1479,6 +1480,7 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, Tcl_DStringInit(&proc_internal_def); Tcl_DStringInit(&proc_internal_name); Tcl_DStringInit(&proc_internal_body); + Tcl_DStringInit(&proc_internal_args); PG_TRY(); { bool is_trigger = OidIsValid(tgreloid); @@ -1488,10 +1490,9 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, bool need_underscore; HeapTuple typeTup; Form_pg_type typeStruct; - char proc_internal_args[33 * FUNC_MAX_ARGS]; Datum prosrcdatum; char *proc_source; - char buf[48]; + char buf[64]; pltcl_interp_desc *interp_desc; Tcl_Interp *interp; int i; @@ -1660,7 +1661,6 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, ************************************************************/ if (!is_trigger && !is_event_trigger) { - proc_internal_args[0] = '\0'; for (i = 0; i < prodesc->nargs; i++) { Oid argtype = procStruct->proargtypes.values[i]; @@ -1693,8 +1693,8 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, } if (i > 0) - strcat(proc_internal_args, " "); - strcat(proc_internal_args, buf); + Tcl_DStringAppend(&proc_internal_args, " ", -1); + Tcl_DStringAppend(&proc_internal_args, buf, -1); ReleaseSysCache(typeTup); } @@ -1702,13 +1702,14 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, else if (is_trigger) { /* trigger procedure has fixed args */ - strcpy(proc_internal_args, - "TG_name TG_relid TG_table_name TG_table_schema TG_relatts TG_when TG_level TG_op __PLTcl_Tup_NEW __PLTcl_Tup_OLD args"); + Tcl_DStringAppend(&proc_internal_args, + "TG_name TG_relid TG_table_name TG_table_schema TG_relatts TG_when TG_level TG_op __PLTcl_Tup_NEW __PLTcl_Tup_OLD args", + -1); } else if (is_event_trigger) { /* event trigger procedure has fixed args */ - strcpy(proc_internal_args, "TG_event TG_tag"); + Tcl_DStringAppend(&proc_internal_args, "TG_event TG_tag", -1); } /************************************************************ @@ -1721,7 +1722,8 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, ************************************************************/ Tcl_DStringAppendElement(&proc_internal_def, "proc"); Tcl_DStringAppendElement(&proc_internal_def, internal_proname); - Tcl_DStringAppendElement(&proc_internal_def, proc_internal_args); + Tcl_DStringAppendElement(&proc_internal_def, + Tcl_DStringValue(&proc_internal_args)); /************************************************************ * prefix procedure body with @@ -1802,6 +1804,7 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, Tcl_DStringFree(&proc_internal_def); Tcl_DStringFree(&proc_internal_name); Tcl_DStringFree(&proc_internal_body); + Tcl_DStringFree(&proc_internal_args); PG_RE_THROW(); } PG_END_TRY(); @@ -1831,6 +1834,7 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, Tcl_DStringFree(&proc_internal_def); Tcl_DStringFree(&proc_internal_name); Tcl_DStringFree(&proc_internal_body); + Tcl_DStringFree(&proc_internal_args); ReleaseSysCache(procTup); From 21a00de43b3d887a72d79ac91407baa284070ed2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:04 -0700 Subject: [PATCH 326/481] Reject calls from SQL to functions that take or return type internal. Allowing that is a security hole, since there are many different functions with different ideas of what their "internal" argument or result is. We already had a defense against the easy case of "'foo'::internal", but that turns out to be insufficient. Lock down both function and operator syntax. Also disallow attempts to cast to or from type internal; those would mostly fail anyway, but we have created some holes with features such as CoerceViaIO. Reported-by: Amy Burnett (OpenAI Codex Security) Author: Tom Lane Reviewed-by: Robert Haas Backpatch-through: 14 Security: CVE-2026-14680 --- src/backend/parser/parse_coerce.c | 8 ++++++++ src/backend/parser/parse_func.c | 26 ++++++++++++++++++++++++++ src/backend/parser/parse_oper.c | 22 ++++++++++++++++++++++ src/pl/plpgsql/src/pl_exec.c | 12 ++++++++++-- 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index 3b92ae2a920..d3240f4b265 100644 --- a/src/backend/parser/parse_coerce.c +++ b/src/backend/parser/parse_coerce.c @@ -573,6 +573,10 @@ can_coerce_type(int nargs, const Oid *input_typeids, const Oid *target_typeids, if (inputTypeId == targetTypeId) continue; + /* reject all cases of casting something else to/from "internal" */ + if (inputTypeId == INTERNALOID || targetTypeId == INTERNALOID) + return false; + /* accept if target is ANY */ if (targetTypeId == ANYOID) continue; @@ -3173,6 +3177,10 @@ find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, if (sourceTypeId == targetTypeId) return COERCION_PATH_RELABELTYPE; + /* Reject all cases of casting something else to/from "internal" */ + if (sourceTypeId == INTERNALOID || targetTypeId == INTERNALOID) + return COERCION_PATH_NONE; + /* Look in pg_cast */ tuple = SearchSysCache2(CASTSOURCETARGET, ObjectIdGetDatum(sourceTypeId), diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 5ffb456a124..c87804f5d41 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -692,6 +692,32 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, rettype, false); + /* + * Reject any attempt to call a function that takes or returns type + * internal from SQL. (The FUNCDETAIL_COERCION case does not reach this + * check because of the early return above, but that's okay because we + * disallow coercions to or from type internal.) Note that we are + * checking the resolved argument and result types, so this will reject + * calls to polymorphic functions that pass internal-type arguments. The + * casting rules should prevent that anyway, since we won't cast internal + * to any polymorphic type, but no harm in being doubly sure. + */ + for (int i = 0; i < nargsplusdefs; i++) + { + if (declared_arg_types[i] == INTERNALOID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("functions accepting type \"%s\" cannot be called explicitly", + "internal"), + parser_errposition(pstate, location))); + } + if (rettype == INTERNALOID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("functions returning type \"%s\" cannot be called explicitly", + "internal"), + parser_errposition(pstate, location))); + /* perform the necessary typecasting of arguments */ make_fn_arguments(pstate, fargs, actual_arg_types, declared_arg_types); diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c index a7e5c686362..dc0f047ca25 100644 --- a/src/backend/parser/parse_oper.c +++ b/src/backend/parser/parse_oper.c @@ -787,6 +787,28 @@ make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, opform->oprresult, false); + /* + * Reject any attempt to call a function that takes or returns type + * internal from SQL. This is just like the check in ParseFuncOrColumn, + * but for operator syntax. (Despite that, we say "function" in the error + * messages; doesn't seem worth having two sets of translatable strings.) + */ + for (int i = 0; i < nargs; i++) + { + if (declared_arg_types[i] == INTERNALOID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("functions accepting type \"%s\" cannot be called explicitly", + "internal"), + parser_errposition(pstate, location))); + } + if (rettype == INTERNALOID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("functions returning type \"%s\" cannot be called explicitly", + "internal"), + parser_errposition(pstate, location))); + /* perform the necessary typecasting of arguments */ make_fn_arguments(pstate, args, actual_arg_types, declared_arg_types); diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 65b0fd0790f..341beb496b8 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -8145,13 +8145,21 @@ get_cast_hashentry(PLpgSQL_execstate *estate, * If there's no cast path according to the parser, fall back to using * an I/O coercion; this is semantically dubious but matches plpgsql's * historical behavior. We would need something of the sort for - * UNKNOWN literals in any case. (This is probably now only reachable - * in the case where srctype is UNKNOWN/RECORD.) + * UNKNOWN literals in any case. The only case we reject is casting + * to/from INTERNAL. (Other than that case, this is probably now only + * reachable in the case where srctype is UNKNOWN/RECORD.) */ if (cast_expr == NULL) { CoerceViaIO *iocoerce = makeNode(CoerceViaIO); + if (srctype == INTERNALOID || dsttype == INTERNALOID) + ereport(ERROR, + (errcode(ERRCODE_CANNOT_COERCE), + errmsg("cannot cast type %s to %s", + format_type_be(srctype), + format_type_be(dsttype)))); + iocoerce->arg = (Expr *) placeholder; iocoerce->resulttype = dsttype; iocoerce->resultcollid = InvalidOid; From 21d8cfb18f465be344dd83852792b88818c33634 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:04 -0700 Subject: [PATCH 327/481] Return nulls honestly in aggregate "combine" functions. numeric_combine() and several other state-combining functions for aggregates cheated for the case of both inputs being NULL: they returned a null pointer without bothering to mark it as a SQL NULL. This was harmless in the expected usage where the result would be passed to the same combine function or a related aggregate final function. But it's bad news from a security standpoint, because now that value can be passed to an internal-accepting function even if said function is strict. While a previous patch prevented such queries from being issued, it seems like good defense-in-depth to expend the few additional lines of code needed to do this properly. Comparable functions such as array_agg_combine() already do so. Reported-by: Amy Burnett (OpenAI Codex Security) Author: Tom Lane Backpatch-through: 14 Security: CVE-2026-14680 --- src/backend/utils/adt/numeric.c | 32 +++++++++++++++++++++++++++++++ src/backend/utils/adt/timestamp.c | 8 ++++++++ 2 files changed, 40 insertions(+) diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index c9717faea26..90d278e0b38 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -5015,7 +5015,15 @@ numeric_combine(PG_FUNCTION_ARGS) state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1); if (state2 == NULL) + { + /* + * NULL state2 is easy, just return state1, which we know is already + * in the agg_context + */ + if (state1 == NULL) + PG_RETURN_NULL(); PG_RETURN_POINTER(state1); + } /* manually copy all fields from state2 to state1 */ if (state1 == NULL) @@ -5107,7 +5115,15 @@ numeric_avg_combine(PG_FUNCTION_ARGS) state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1); if (state2 == NULL) + { + /* + * NULL state2 is easy, just return state1, which we know is already + * in the agg_context + */ + if (state1 == NULL) + PG_RETURN_NULL(); PG_RETURN_POINTER(state1); + } /* manually copy all fields from state2 to state1 */ if (state1 == NULL) @@ -5571,7 +5587,15 @@ numeric_poly_combine(PG_FUNCTION_ARGS) state2 = PG_ARGISNULL(1) ? NULL : (Int128AggState *) PG_GETARG_POINTER(1); if (state2 == NULL) + { + /* + * NULL state2 is easy, just return state1, which we know is already + * in the agg_context + */ + if (state1 == NULL) + PG_RETURN_NULL(); PG_RETURN_POINTER(state1); + } /* manually copy all fields from state2 to state1 */ if (state1 == NULL) @@ -5732,7 +5756,15 @@ int8_avg_combine(PG_FUNCTION_ARGS) state2 = PG_ARGISNULL(1) ? NULL : (Int128AggState *) PG_GETARG_POINTER(1); if (state2 == NULL) + { + /* + * NULL state2 is easy, just return state1, which we know is already + * in the agg_context + */ + if (state1 == NULL) + PG_RETURN_NULL(); PG_RETURN_POINTER(state1); + } /* manually copy all fields from state2 to state1 */ if (state1 == NULL) diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index a20e7ea1d11..7dfdd83f7c2 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -4091,7 +4091,15 @@ interval_avg_combine(PG_FUNCTION_ARGS) state2 = PG_ARGISNULL(1) ? NULL : (IntervalAggState *) PG_GETARG_POINTER(1); if (state2 == NULL) + { + /* + * NULL state2 is easy, just return state1, which we know is already + * in the agg_context + */ + if (state1 == NULL) + PG_RETURN_NULL(); PG_RETURN_POINTER(state1); + } if (state1 == NULL) { From 93b93f28fb1a3aef83a2fa979f54cc1b4eae5fcc Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Mon, 10 Aug 2026 06:38:04 -0700 Subject: [PATCH 328/481] Preserve the owner of extended statistics rebuilt by ALTER TABLE. When ALTER TABLE ... ALTER COLUMN TYPE (or any subcommand that rebuilds them) drops and re-creates the extended statistics objects depending on the altered column, the re-created objects were owned by the role running ALTER TABLE rather than by the original owner of the statistics. Remember each object's owner before dropping it, and restore it on re-creation. CreateStatistics()'s signature changes and CreateStatsStmt gains a field, but no known third-party code calls the former or constructs the latter. Author: Masahiko Sawada Reviewed-by: Noah Misch Backpatch-through: 14 Security: CVE-2026-6469 --- src/backend/commands/statscmds.c | 48 +++++++++++------------ src/backend/commands/tablecmds.c | 52 ++++++++++++++++++------- src/backend/tcop/utility.c | 19 ++++++++- src/include/commands/defrem.h | 2 +- src/include/nodes/parsenodes.h | 1 + src/test/regress/expected/stats_ext.out | 29 ++++++++++++++ src/test/regress/sql/stats_ext.sql | 20 ++++++++++ 7 files changed, 129 insertions(+), 42 deletions(-) diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c index b354723be44..8e377ca445d 100644 --- a/src/backend/commands/statscmds.c +++ b/src/backend/commands/statscmds.c @@ -59,9 +59,15 @@ compare_int16(const void *a, const void *b) /* * CREATE STATISTICS + * + * relids is a list of OIDs of relations specified in the FROM clause, on which + * the statistics object is defined. We identify the target by the passed-in + * OID rather than re-resolving stmt->relations by name, so that we operate + * on exactly the relation the caller looked up. Only a single relation is + * supported for now. */ ObjectAddress -CreateStatistics(CreateStatsStmt *stmt, bool check_rights) +CreateStatistics(List *relids, CreateStatsStmt *stmt, bool check_rights) { int16 attnums[STATS_MAX_DIMENSIONS]; int nattnums = 0; @@ -70,7 +76,7 @@ CreateStatistics(CreateStatsStmt *stmt, bool check_rights) NameData stxname; Oid statoid; Oid namespaceId; - Oid stxowner = GetUserId(); + Oid stxowner = OidIsValid(stmt->owner) ? stmt->owner : GetUserId(); HeapTuple htup; Datum values[Natts_pg_statistic_ext]; bool nulls[Natts_pg_statistic_ext]; @@ -79,7 +85,7 @@ CreateStatistics(CreateStatsStmt *stmt, bool check_rights) Datum exprsDatum; Relation statrel; Relation rel = NULL; - Oid relid; + Oid relid = InvalidOid; ObjectAddress parentobject, myself; Datum types[4]; /* one for each possible type of statistic */ @@ -97,24 +103,17 @@ CreateStatistics(CreateStatsStmt *stmt, bool check_rights) Assert(IsA(stmt, CreateStatsStmt)); /* - * Examine the FROM clause. Currently, we only allow it to be a single - * simple table, but later we'll probably allow multiple tables and JOIN - * syntax. The grammar is already prepared for that, so we have to check - * here that what we got is what we can support. + * Currently, we only allow the FROM clause to be a single simple table, + * but later we'll probably allow multiple tables and JOIN syntax. The + * grammar and the loop below are already prepared for that, but examining + * the FROM clause is the caller's job, so all we do here is assert that + * the caller rejected what we can't support. */ - if (list_length(stmt->relations) != 1) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("only a single relation is allowed in CREATE STATISTICS"))); + Assert(list_length(relids) == 1); - foreach(cell, stmt->relations) + foreach(cell, relids) { - Node *rln = (Node *) lfirst(cell); - - if (!IsA(rln, RangeVar)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("only a single relation is allowed in CREATE STATISTICS"))); + relid = lfirst_oid(cell); /* * CREATE STATISTICS will influence future execution plans but does @@ -123,7 +122,7 @@ CreateStatistics(CreateStatsStmt *stmt, bool check_rights) * conflicting with ANALYZE and other DDL that sets statistical * information, but not with normal queries. */ - rel = relation_openrv((RangeVar *) rln, ShareUpdateExclusiveLock); + rel = relation_open(relid, ShareUpdateExclusiveLock); /* Restrict to allowed relation types */ if (rel->rd_rel->relkind != RELKIND_RELATION && @@ -137,13 +136,11 @@ CreateStatistics(CreateStatsStmt *stmt, bool check_rights) errdetail_relkind_not_supported(rel->rd_rel->relkind))); /* - * You must own the relation to create stats on it. - * - * NB: Concurrent changes could cause this function's lookup to find a - * different relation than a previous lookup by the caller, so we must - * perform this check even when check_rights == false. + * You must own the relation to create stats on it. Skip check if + * caller doesn't want it. */ - if (!object_ownercheck(RelationRelationId, RelationGetRelid(rel), stxowner)) + if (check_rights && + !object_ownercheck(RelationRelationId, RelationGetRelid(rel), stxowner)) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind), RelationGetRelationName(rel)); @@ -156,7 +153,6 @@ CreateStatistics(CreateStatsStmt *stmt, bool check_rights) } Assert(rel); - relid = RelationGetRelid(rel); /* * If the node has a name, split it up and determine creation namespace. diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index a2003c75331..f8fedc2b249 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -211,6 +211,7 @@ typedef struct AlteredTableInfo char *clusterOnIndex; /* index to use for CLUSTER */ List *changedStatisticsOids; /* OIDs of statistics to rebuild */ List *changedStatisticsDefs; /* string definitions of same */ + List *changedStatisticsOwners; /* owners of same */ } AlteredTableInfo; /* Struct describing one new constraint to check in Phase 3 scan */ @@ -699,7 +700,7 @@ static void RememberIndexForRebuilding(Oid indoid, AlteredTableInfo *tab); static void RememberStatisticsForRebuilding(Oid stxoid, AlteredTableInfo *tab); static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode); -static void ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, +static void ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, Oid ownerId, char *cmd, List **wqueue, LOCKMODE lockmode, bool rewrite); static void RebuildConstraintComment(AlteredTableInfo *tab, AlterTablePass pass, @@ -9774,7 +9775,11 @@ ATExecAddStatistics(AlteredTableInfo *tab, Relation rel, /* The CreateStatsStmt has already been through transformStatsStmt */ Assert(stmt->transformed); - address = CreateStatistics(stmt, !is_rebuild); + /* The owner must be set to the original statistics owner */ + Assert(OidIsValid(stmt->owner)); + + address = CreateStatistics(list_make1_oid(RelationGetRelid(rel)), + stmt, !is_rebuild); return address; } @@ -16057,11 +16062,25 @@ RememberStatisticsForRebuilding(Oid stxoid, AlteredTableInfo *tab) { /* OK, capture the statistics object's existing definition string */ char *defstring = pg_get_statisticsobjdef_string(stxoid); + HeapTuple tup; + Form_pg_statistic_ext statext; + + tup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(stxoid)); + + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "cache lookup failed for statistics object %u", stxoid); + + statext = (Form_pg_statistic_ext) GETSTRUCT(tup); tab->changedStatisticsOids = lappend_oid(tab->changedStatisticsOids, stxoid); tab->changedStatisticsDefs = lappend(tab->changedStatisticsDefs, defstring); + + tab->changedStatisticsOwners = lappend_oid(tab->changedStatisticsOwners, + statext->stxowner); + + ReleaseSysCache(tup); } } @@ -16079,6 +16098,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) ObjectAddresses *objects; ListCell *def_item; ListCell *oid_item; + ListCell *owner_item; /* * Collect all the constraints and indexes to drop so we can process them @@ -16152,7 +16172,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) if (relid != tab->relid) LockRelationOid(relid, AccessExclusiveLock); - ATPostAlterTypeParse(oldId, relid, confrelid, + ATPostAlterTypeParse(oldId, relid, confrelid, InvalidOid, (char *) lfirst(def_item), wqueue, lockmode, tab->rewrite); } @@ -16171,7 +16191,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) if (relid != tab->relid) LockRelationOid(relid, AccessExclusiveLock); - ATPostAlterTypeParse(oldId, relid, InvalidOid, + ATPostAlterTypeParse(oldId, relid, InvalidOid, InvalidOid, (char *) lfirst(def_item), wqueue, lockmode, tab->rewrite); @@ -16180,8 +16200,9 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) } /* add dependencies for new statistics */ - forboth(oid_item, tab->changedStatisticsOids, - def_item, tab->changedStatisticsDefs) + forthree(oid_item, tab->changedStatisticsOids, + def_item, tab->changedStatisticsDefs, + owner_item, tab->changedStatisticsOwners) { Oid oldId = lfirst_oid(oid_item); Oid relid; @@ -16201,7 +16222,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) if (relid != tab->relid) LockRelationOid(relid, ShareUpdateExclusiveLock); - ATPostAlterTypeParse(oldId, relid, InvalidOid, + ATPostAlterTypeParse(oldId, relid, InvalidOid, lfirst_oid(owner_item), (char *) lfirst(def_item), wqueue, lockmode, tab->rewrite); @@ -16265,8 +16286,9 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) * operator that's not available for the new column type. */ static void -ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, - List **wqueue, LOCKMODE lockmode, bool rewrite) +ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, Oid ownerId, + char *cmd, List **wqueue, LOCKMODE lockmode, + bool rewrite) { List *raw_parsetree_list; List *querytree_list; @@ -16306,10 +16328,14 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, querytree_list = list_concat(querytree_list, afterStmts); } else if (IsA(stmt, CreateStatsStmt)) - querytree_list = lappend(querytree_list, - transformStatsStmt(oldRelId, - (CreateStatsStmt *) stmt, - cmd)); + { + CreateStatsStmt *csstmt; + + csstmt = transformStatsStmt(oldRelId, (CreateStatsStmt *) stmt, cmd); + csstmt->owner = ownerId; + + querytree_list = lappend(querytree_list, csstmt); + } else querytree_list = lappend(querytree_list, stmt); } diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 73a56f1df1d..5f204addcd4 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1890,7 +1890,21 @@ ProcessUtilitySlow(ParseState *pstate, { Oid relid; CreateStatsStmt *stmt = (CreateStatsStmt *) parsetree; - RangeVar *rel = (RangeVar *) linitial(stmt->relations); + RangeVar *rel; + + /* + * Examine the FROM clause. Currently, we only allow it + * to be a single simple table, but later we'll probably + * allow multiple tables and JOIN syntax. The grammar is + * already prepared for that, so we have to check here + * that what we got is what we can support. + */ + if (list_length(stmt->relations) != 1) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("only a single relation is allowed in CREATE STATISTICS"))); + + rel = (RangeVar *) linitial(stmt->relations); if (!IsA(rel, RangeVar)) ereport(ERROR, @@ -1913,7 +1927,8 @@ ProcessUtilitySlow(ParseState *pstate, /* Run parse analysis ... */ stmt = transformStatsStmt(relid, stmt, queryString); - address = CreateStatistics(stmt, true); + address = CreateStatistics(list_make1_oid(relid), stmt, + true); } break; diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index d080ad59b71..574f860bdd2 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -86,7 +86,7 @@ extern void RemoveOperatorById(Oid operOid); extern ObjectAddress AlterOperator(AlterOperatorStmt *stmt); /* commands/statscmds.c */ -extern ObjectAddress CreateStatistics(CreateStatsStmt *stmt, bool check_rights); +extern ObjectAddress CreateStatistics(List *relids, CreateStatsStmt *stmt, bool check_rights); extern ObjectAddress AlterStatistics(AlterStatsStmt *stmt); extern void RemoveStatisticsById(Oid statsOid); extern void RemoveStatisticsDataById(Oid statsOid, bool inh); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index ad31a9c059b..2fcea826003 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -3630,6 +3630,7 @@ typedef struct CreateStatsStmt char *stxcomment; /* comment to apply to stats, or NULL */ bool transformed; /* true when transformStatsStmt is finished */ bool if_not_exists; /* do nothing if stats name already exists */ + Oid owner; /* OID of owner, or InvalidOid for default */ } CreateStatsStmt; /* diff --git a/src/test/regress/expected/stats_ext.out b/src/test/regress/expected/stats_ext.out index 37070c1a896..4512670d525 100644 --- a/src/test/regress/expected/stats_ext.out +++ b/src/test/regress/expected/stats_ext.out @@ -55,6 +55,10 @@ ERROR: duplicate expression in statistics definition CREATE STATISTICS tst (unrecognized) ON x, y FROM ext_stats_test; ERROR: unrecognized statistics kind "unrecognized" -- unsupported targets +CREATE STATISTICS tst ON x, y FROM ext_stats_test, ext_stats_test; +ERROR: only a single relation is allowed in CREATE STATISTICS +CREATE STATISTICS tst ON x, y FROM ext_stats_test, (SELECT * FROM ext_stats_test) AS foo; +ERROR: only a single relation is allowed in CREATE STATISTICS CREATE STATISTICS tst ON a FROM (VALUES (x)) AS foo; ERROR: CREATE STATISTICS only supports relation names in the FROM clause CREATE STATISTICS tst ON a FROM foo NATURAL JOIN bar; @@ -3578,6 +3582,31 @@ drop cascades to view tststats.priv_test_view DROP SCHEMA sts_sch1, sts_sch2 CASCADE; NOTICE: drop cascades to table sts_sch1.tbl DROP USER regress_stats_user1; +-- CREATE STATISTICS checks for the owner +CREATE ROLE regress_relowner; +CREATE ROLE regress_stxowner; +CREATE TABLE stats_ext_tbl (a int, b int); +ALTER TABLE stats_ext_tbl OWNER TO regress_relowner; +CREATE STATISTICS tst ON a, b FROM stats_ext_tbl; +ALTER STATISTICS tst OWNER TO regress_stxowner; +SELECT stxowner::regrole FROM pg_statistic_ext WHERE stxname = 'tst'; + stxowner +------------------ + regress_stxowner +(1 row) + +-- re-creating statistics via ALTER TABLE preserve the statistics owner. +ALTER TABLE stats_ext_tbl ALTER COLUMN a TYPE bigint; +SELECT stxowner::regrole FROM pg_statistic_ext WHERE stxname = 'tst'; + stxowner +------------------ + regress_stxowner +(1 row) + +-- Tidy up +DROP TABLE stats_ext_tbl; +DROP ROLE regress_relowner; +DROP ROLE regress_stxowner; CREATE TABLE grouping_unique (x integer); INSERT INTO grouping_unique (x) SELECT gs FROM generate_series(1,1000) AS gs; ANALYZE grouping_unique; diff --git a/src/test/regress/sql/stats_ext.sql b/src/test/regress/sql/stats_ext.sql index 3cc6012b822..a9176e74f3c 100644 --- a/src/test/regress/sql/stats_ext.sql +++ b/src/test/regress/sql/stats_ext.sql @@ -41,6 +41,8 @@ CREATE STATISTICS tst ON (x || 'x'), (x || 'x'), (y + 1), (x || 'x'), (x || 'x') CREATE STATISTICS tst ON (x || 'x'), (x || 'x'), y FROM ext_stats_test; CREATE STATISTICS tst (unrecognized) ON x, y FROM ext_stats_test; -- unsupported targets +CREATE STATISTICS tst ON x, y FROM ext_stats_test, ext_stats_test; +CREATE STATISTICS tst ON x, y FROM ext_stats_test, (SELECT * FROM ext_stats_test) AS foo; CREATE STATISTICS tst ON a FROM (VALUES (x)) AS foo; CREATE STATISTICS tst ON a FROM foo NATURAL JOIN bar; CREATE STATISTICS tst ON a FROM (SELECT * FROM ext_stats_test) AS foo; @@ -1830,6 +1832,24 @@ DROP SCHEMA tststats CASCADE; DROP SCHEMA sts_sch1, sts_sch2 CASCADE; DROP USER regress_stats_user1; +-- CREATE STATISTICS checks for the owner +CREATE ROLE regress_relowner; +CREATE ROLE regress_stxowner; +CREATE TABLE stats_ext_tbl (a int, b int); +ALTER TABLE stats_ext_tbl OWNER TO regress_relowner; +CREATE STATISTICS tst ON a, b FROM stats_ext_tbl; +ALTER STATISTICS tst OWNER TO regress_stxowner; +SELECT stxowner::regrole FROM pg_statistic_ext WHERE stxname = 'tst'; + +-- re-creating statistics via ALTER TABLE preserve the statistics owner. +ALTER TABLE stats_ext_tbl ALTER COLUMN a TYPE bigint; +SELECT stxowner::regrole FROM pg_statistic_ext WHERE stxname = 'tst'; + +-- Tidy up +DROP TABLE stats_ext_tbl; +DROP ROLE regress_relowner; +DROP ROLE regress_stxowner; + CREATE TABLE grouping_unique (x integer); INSERT INTO grouping_unique (x) SELECT gs FROM generate_series(1,1000) AS gs; ANALYZE grouping_unique; From bb02eba534112594bc44a4b4c4fe9acb7ac7d656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Mon, 10 Aug 2026 06:38:04 -0700 Subject: [PATCH 329/481] pg_stat_statements: Fix buffer overflow with query normalization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 62d712ecfd94, pg_stat_statements has been underestimating the size of the result buffer possible for a normalized query, in cases where the query includes many squashable lists, causing the normalized query to write past the allocated area. The allocated buffer size forgot to account for the comment appended in a squashable list, "/*, ... */". Instead of trying to track down precisely how much space we need, fix by switch to using an expansible StringInfo. This not only fixes the bug, but it also makes the code simpler to follow. Author: Álvaro Herrera Reported-by: Sajeeb Lohani with TrendAI Zero Day Initiative Reported-by: Yuelin Wang <3020001251@tju.edu.cn> Diagnosed-by: Michaël Paquier Backpatch-through: 18 Security: CVE-2026-14676 Discussion: https://postgr.es/m/19528-7290dd7e6f7dcc22@postgresql.org --- .../pg_stat_statements/pg_stat_statements.c | 44 +++++++------------ 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 92315627916..d1d8dd34f25 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -2813,17 +2813,22 @@ static char * generate_normalized_query(const JumbleState *jstate, const char *query, int query_loc, int *query_len_p) { - char *norm_query; + StringInfoData norm_query; int query_len = *query_len_p; - int norm_query_buflen, /* Space allowed for norm_query */ - len_to_wrt, /* Length (in bytes) to write */ + int len_to_wrt, /* Length (in bytes) to write */ quer_loc = 0, /* Source query byte location */ - n_quer_loc = 0, /* Normalized query byte location */ last_off = 0, /* Offset from start for previous tok */ last_tok_len = 0; /* Length (in bytes) of that tok */ int num_constants_replaced = 0; LocationLen *locs = NULL; + /* + * Our output buffer is an expansible StringInfo, but avoid enlarging it + * in most cases by reserving extra space for each constant location. + */ + Assert(jstate->clocations_count > 0); + initStringInfoExt(&norm_query, query_len + jstate->clocations_count * 10); + /* * Determine constants' lengths (core system only gives us locations), and * return a sorted copy of jstate's LocationLen data with lengths filled @@ -2831,18 +2836,6 @@ generate_normalized_query(const JumbleState *jstate, const char *query, */ locs = ComputeConstantLengths(jstate, query, query_loc); - /* - * Allow for $n symbols to be longer than the constants they replace. - * Constants must take at least one byte in text form, while a $n symbol - * certainly isn't more than 11 bytes, even if n reaches INT_MAX. We - * could refine that limit based on the max value of n for the current - * query, but it hardly seems worth any extra effort to do so. - */ - norm_query_buflen = query_len + jstate->clocations_count * 10; - - /* Allocate result buffer */ - norm_query = palloc(norm_query_buflen + 1); - for (int i = 0; i < jstate->clocations_count; i++) { int off, /* Offset from start for cur tok */ @@ -2872,17 +2865,16 @@ generate_normalized_query(const JumbleState *jstate, const char *query, len_to_wrt = off - last_off; len_to_wrt -= last_tok_len; Assert(len_to_wrt >= 0); - memcpy(norm_query + n_quer_loc, query + quer_loc, len_to_wrt); - n_quer_loc += len_to_wrt; + appendBinaryStringInfo(&norm_query, query + quer_loc, len_to_wrt); /* * And insert a param symbol in place of the constant token; and, if * we have a squashable list, insert a placeholder comment starting * from the list's second value. */ - n_quer_loc += sprintf(norm_query + n_quer_loc, "$%d%s", - num_constants_replaced + 1 + jstate->highest_extern_param_id, - locs[i].squashed ? " /*, ... */" : ""); + appendStringInfo(&norm_query, "$%d%s", + num_constants_replaced + 1 + jstate->highest_extern_param_id, + locs[i].squashed ? " /*, ... */" : ""); num_constants_replaced++; /* move forward */ @@ -2902,12 +2894,8 @@ generate_normalized_query(const JumbleState *jstate, const char *query, len_to_wrt = query_len - quer_loc; Assert(len_to_wrt >= 0); - memcpy(norm_query + n_quer_loc, query + quer_loc, len_to_wrt); - n_quer_loc += len_to_wrt; - - Assert(n_quer_loc <= norm_query_buflen); - norm_query[n_quer_loc] = '\0'; + appendBinaryStringInfo(&norm_query, query + quer_loc, len_to_wrt); - *query_len_p = n_quer_loc; - return norm_query; + *query_len_p = norm_query.len; + return norm_query.data; } From aa7b5815ea099763b1cfe01e431b0ec8312c943f Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 10 Aug 2026 06:38:04 -0700 Subject: [PATCH 330/481] Fix pg_trgm's picksplit function with all-true datums The CACHESIGN.sign field is a BITVECP, not a TRGM, so you should not use GETSIGN() on it. You don't get a compiler warning because the GETSIGN() macro includes a cast. It resulted in a bogus read beyond end of buffer, which would cause bad split decisions or a crash if you're very unlucky. Reported-by: Mehmet D. INCE Backpatch-through: 14 Security: CVE-2026-14678 --- contrib/pg_trgm/trgm_gist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c index 11812b2984e..d2bf290ba76 100644 --- a/contrib/pg_trgm/trgm_gist.c +++ b/contrib/pg_trgm/trgm_gist.c @@ -902,7 +902,7 @@ gtrgm_picksplit(PG_FUNCTION_ARGS) else size_alpha = SIGLENBIT(siglen) - sizebitvec((cache[j].allistrue) ? GETSIGN(datum_l) : - GETSIGN(cache[j].sign), + cache[j].sign, siglen); } else @@ -915,7 +915,7 @@ gtrgm_picksplit(PG_FUNCTION_ARGS) else size_beta = SIGLENBIT(siglen) - sizebitvec((cache[j].allistrue) ? GETSIGN(datum_r) : - GETSIGN(cache[j].sign), + cache[j].sign, siglen); } else From a1c1727cb400b8ae61a13844d7e22ef38e7da79b Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 331/481] Use palloc_array() in pltcl and plperl to avoid overflow Some of these could overflow on 32-bit systems with the right input. Convert all cases where we called palloc() with multiplication to fix them. Not all of them were bugs, but it's better to be safe than sorry. Reported-by: Tulya Project, Team Dhiutsa, Bitecope Technologies Private Ltd Backpatch-through: 14 Security: CVE-2026-14677 --- src/pl/plperl/SPI.xs | 6 +++--- src/pl/plperl/plperl.c | 26 +++++++++++++------------- src/pl/tcl/pltcl.c | 16 ++++++++-------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/pl/plperl/SPI.xs b/src/pl/plperl/SPI.xs index e81432e6341..ba1e93970a8 100644 --- a/src/pl/plperl/SPI.xs +++ b/src/pl/plperl/SPI.xs @@ -75,7 +75,7 @@ spi_spi_prepare(sv, ...) char* query = sv2cstr(sv); if (items < 1) Perl_croak(aTHX_ "Usage: spi_prepare(query, ...)"); - argv = ( SV**) palloc(( items - 1) * sizeof(SV*)); + argv = palloc_array(SV*, items - 1); for ( i = 1; i < items; i++) argv[i - 1] = ST(i); RETVAL = plperl_spi_prepare(query, items - 1, argv); @@ -103,7 +103,7 @@ spi_spi_exec_prepared(sv, ...) offset++; } argc = items - offset; - argv = ( SV**) palloc( argc * sizeof(SV*)); + argv = palloc_array(SV*, argc); for ( i = 0; offset < items; offset++, i++) argv[i] = ST(offset); ret_hash = plperl_spi_exec_prepared(query, attr, argc, argv); @@ -123,7 +123,7 @@ spi_spi_query_prepared(sv, ...) if ( items < 1) Perl_croak(aTHX_ "Usage: spi_query_prepared(query, " "[\\@bind_values])"); - argv = ( SV**) palloc(( items - 1) * sizeof(SV*)); + argv = palloc_array(SV*, items - 1); for ( i = 1; i < items; i++) argv[i - 1] = ST(i); RETVAL = plperl_spi_query_prepared(query, items - 1, argv); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index dbc6beeac92..eba91f2d7d6 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -1796,9 +1796,9 @@ plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup) tupdesc = tdata->tg_relation->rd_att; natts = tupdesc->natts; - modvalues = (Datum *) palloc0(natts * sizeof(Datum)); - modnulls = (bool *) palloc0(natts * sizeof(bool)); - modrepls = (bool *) palloc0(natts * sizeof(bool)); + modvalues = palloc0_array(Datum, natts); + modnulls = palloc0_array(bool, natts); + modrepls = palloc0_array(bool, natts); hv_iterinit(hvNew); while ((he = hv_iternext(hvNew))) @@ -2815,9 +2815,9 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger) prodesc->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data); prodesc->fn_tid = procTup->t_self; prodesc->nargs = procStruct->pronargs; - prodesc->arg_out_func = (FmgrInfo *) palloc0(prodesc->nargs * sizeof(FmgrInfo)); - prodesc->arg_is_rowtype = (bool *) palloc0(prodesc->nargs * sizeof(bool)); - prodesc->arg_arraytype = (Oid *) palloc0(prodesc->nargs * sizeof(Oid)); + prodesc->arg_out_func = palloc0_array(FmgrInfo, prodesc->nargs); + prodesc->arg_is_rowtype = palloc0_array(bool, prodesc->nargs); + prodesc->arg_arraytype = palloc0_array(Oid, prodesc->nargs); MemoryContextSwitchTo(oldcontext); /* Remember if function is STABLE/IMMUTABLE */ @@ -3610,9 +3610,9 @@ plperl_spi_prepare(char *query, int argc, SV **argv) snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc); qdesc->plan_cxt = plan_cxt; qdesc->nargs = argc; - qdesc->argtypes = (Oid *) palloc(argc * sizeof(Oid)); - qdesc->arginfuncs = (FmgrInfo *) palloc(argc * sizeof(FmgrInfo)); - qdesc->argtypioparams = (Oid *) palloc(argc * sizeof(Oid)); + qdesc->argtypes = palloc_array(Oid, argc); + qdesc->arginfuncs = palloc_array(FmgrInfo, argc); + qdesc->argtypioparams = palloc_array(Oid, argc); MemoryContextSwitchTo(oldcontext); /************************************************************ @@ -3783,8 +3783,8 @@ plperl_spi_exec_prepared(char *query, HV *attr, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); - argvalues = (Datum *) palloc(argc * sizeof(Datum)); + nulls = palloc_array(char, argc); + argvalues = palloc_array(Datum, argc); } else { @@ -3896,8 +3896,8 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); - argvalues = (Datum *) palloc(argc * sizeof(Datum)); + nulls = palloc_array(char, argc); + argvalues = palloc_array(Datum, argc); } else { diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 64fe71da8c7..e2c6d99a6de 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -1598,8 +1598,8 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, prodesc->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data); prodesc->fn_tid = procTup->t_self; prodesc->nargs = procStruct->pronargs; - prodesc->arg_out_func = (FmgrInfo *) palloc0(prodesc->nargs * sizeof(FmgrInfo)); - prodesc->arg_is_rowtype = (bool *) palloc0(prodesc->nargs * sizeof(bool)); + prodesc->arg_out_func = palloc0_array(FmgrInfo, prodesc->nargs); + prodesc->arg_is_rowtype = palloc0_array(bool, prodesc->nargs); MemoryContextSwitchTo(oldcontext); /* Remember if function is STABLE/IMMUTABLE */ @@ -2118,7 +2118,7 @@ pltcl_quote(ClientData cdata, Tcl_Interp *interp, * grow to and initialize pointers ************************************************************/ cp1 = Tcl_GetStringFromObj(objv[1], &length); - tmp = palloc(length * 2 + 1); + tmp = palloc(add_size(mul_size(length, 2), 1)); cp2 = tmp; /************************************************************ @@ -2677,9 +2677,9 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, qdesc = palloc0_object(pltcl_query_desc); snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc); qdesc->nargs = nargs; - qdesc->argtypes = (Oid *) palloc(nargs * sizeof(Oid)); - qdesc->arginfuncs = (FmgrInfo *) palloc(nargs * sizeof(FmgrInfo)); - qdesc->argtypioparams = (Oid *) palloc(nargs * sizeof(Oid)); + qdesc->argtypes = palloc_array(Oid, nargs); + qdesc->arginfuncs = palloc_array(FmgrInfo, nargs); + qdesc->argtypioparams = palloc_array(Oid, nargs); MemoryContextSwitchTo(oldcontext); /************************************************************ @@ -2922,7 +2922,7 @@ pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp *interp, * Setup the value array for SPI_execute_plan() using * the type specific input functions ************************************************************/ - argvalues = (Datum *) palloc(callObjc * sizeof(Datum)); + argvalues = palloc_array(Datum, callObjc); for (j = 0; j < callObjc; j++) { @@ -3296,7 +3296,7 @@ pltcl_build_tuple_result(Tcl_Interp *interp, Tcl_Obj **kvObjv, int kvObjc, attinmeta = NULL; } - values = (char **) palloc0(tupdesc->natts * sizeof(char *)); + values = palloc0_array(char *, tupdesc->natts); if (kvObjc % 2 != 0) ereport(ERROR, From 457b8737ab29ec5e29fc06dcc019795c40e6f261 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 332/481] ecpg: Fix out-of-bound writes due to processing of invalid bytea data ECPG assumes that any bytea data it receives from a backend starts with '\x' as its first two bytes, but a check was missed to enforce that. A rogue server sending some garbage bytea data would be able to crash a client, resulting in a client-side DoS, in the most common cases. Reported-by: ylwangtju Backpatch-through: 14 Security: CVE-2026-16241 --- src/interfaces/ecpg/ecpglib/data.c | 7 +++++ src/interfaces/ecpg/ecpglib/error.c | 7 +++++ src/interfaces/ecpg/include/ecpgerrno.h | 1 + src/interfaces/ecpg/test/expected/sql-bytea.c | 27 ++++++++++++++++--- .../ecpg/test/expected/sql-bytea.stderr | 24 ++++++++++++++++- src/interfaces/ecpg/test/sql/bytea.pgc | 5 ++++ 6 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c index d5d40f7b654..719d503a1ec 100644 --- a/src/interfaces/ecpg/ecpglib/data.c +++ b/src/interfaces/ecpg/ecpglib/data.c @@ -515,6 +515,13 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, src_size, dec_size; + if (size < 2 || pval[0] != '\\' || pval[1] != 'x') + { + ecpg_raise(lineno, ECPG_BYTEA_FORMAT, + ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); + return false; + } + dst_size = ecpg_hex_enc_len(varcharsize); src_size = size - 2; /* exclude backslash + 'x' */ dec_size = src_size < dst_size ? src_size : dst_size; diff --git a/src/interfaces/ecpg/ecpglib/error.c b/src/interfaces/ecpg/ecpglib/error.c index 26fdcdb69e9..fba8b4468dd 100644 --- a/src/interfaces/ecpg/ecpglib/error.c +++ b/src/interfaces/ecpg/ecpglib/error.c @@ -130,6 +130,13 @@ ecpg_raise(int line, int code, const char *sqlstate, const char *str) ecpg_gettext("inserting an array of variables is not supported on line %d"), line); break; + case ECPG_BYTEA_FORMAT: + snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), + /*------ + translator: this string will be truncated at 149 characters expanded. */ + ecpg_gettext("invalid input syntax for type bytea: \"%s\", on line %d"), str, line); + break; + case ECPG_NO_CONN: snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), /*------ diff --git a/src/interfaces/ecpg/include/ecpgerrno.h b/src/interfaces/ecpg/include/ecpgerrno.h index 6928d44ee99..f9c1742f7bb 100644 --- a/src/interfaces/ecpg/include/ecpgerrno.h +++ b/src/interfaces/ecpg/include/ecpgerrno.h @@ -33,6 +33,7 @@ #define ECPG_NO_ARRAY -214 #define ECPG_DATA_NOT_ARRAY -215 #define ECPG_ARRAY_INSERT -216 +#define ECPG_BYTEA_FORMAT -217 #define ECPG_NO_CONN -220 #define ECPG_NOT_CONN -221 diff --git a/src/interfaces/ecpg/test/expected/sql-bytea.c b/src/interfaces/ecpg/test/expected/sql-bytea.c index 8338c6008dd..901594a6f63 100644 --- a/src/interfaces/ecpg/test/expected/sql-bytea.c +++ b/src/interfaces/ecpg/test/expected/sql-bytea.c @@ -356,17 +356,36 @@ if (sqlca.sqlcode < 0) sqlprint();} if (sqlca.sqlcode < 0) sqlprint();} #line 115 "bytea.pgc" + + /* Test for invalid bytea format */ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select '' :: text", ECPGt_EOIT, + ECPGt_bytea,&(recv_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_2), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 118 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 118 "bytea.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select '\\\\a1234' :: text", ECPGt_EOIT, + ECPGt_bytea,&(recv_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_2), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 119 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 119 "bytea.pgc" + + { ECPGtrans(__LINE__, NULL, "commit"); -#line 116 "bytea.pgc" +#line 121 "bytea.pgc" if (sqlca.sqlcode < 0) sqlprint();} -#line 116 "bytea.pgc" +#line 121 "bytea.pgc" { ECPGdisconnect(__LINE__, "CURRENT"); -#line 117 "bytea.pgc" +#line 122 "bytea.pgc" if (sqlca.sqlcode < 0) sqlprint();} -#line 117 "bytea.pgc" +#line 122 "bytea.pgc" return 0; diff --git a/src/interfaces/ecpg/test/expected/sql-bytea.stderr b/src/interfaces/ecpg/test/expected/sql-bytea.stderr index cb828a76020..58589474856 100644 --- a/src/interfaces/ecpg/test/expected/sql-bytea.stderr +++ b/src/interfaces/ecpg/test/expected/sql-bytea.stderr @@ -181,7 +181,29 @@ SQL error: invalid statement name "cursor1" on line 82 [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_process_output on line 115: OK: DROP TABLE [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ECPGtrans on line 116: action "commit"; connection "ecpg1_regression" +[NO_PID]: ecpg_execute on line 118: query: select '' :: text; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 118: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 118: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 118: RESULT: offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlcode -217 on line 118: invalid input syntax for type bytea: "", on line 118 +[NO_PID]: sqlca: code: -217, state: 42804 +SQL error: invalid input syntax for type bytea: "", on line 118 +[NO_PID]: ecpg_execute on line 119: query: select '\\a1234' :: text; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 119: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 119: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 119: RESULT: \\a1234 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlcode -217 on line 119: invalid input syntax for type bytea: "\\a1234", on line 119 +[NO_PID]: sqlca: code: -217, state: 42804 +SQL error: invalid input syntax for type bytea: "\\a1234", on line 119 +[NO_PID]: ECPGtrans on line 121: action "commit"; connection "ecpg1_regression" [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: deallocate_one on line 0: name sel_stmt [NO_PID]: sqlca: code: 0, state: 00000 diff --git a/src/interfaces/ecpg/test/sql/bytea.pgc b/src/interfaces/ecpg/test/sql/bytea.pgc index e8741231194..da9152758a2 100644 --- a/src/interfaces/ecpg/test/sql/bytea.pgc +++ b/src/interfaces/ecpg/test/sql/bytea.pgc @@ -113,6 +113,11 @@ while (0) dump_binary(recv_short_buf.arr, recv_short_buf.len, ind[1]); exec sql drop table test; + + /* Test for invalid bytea format */ + exec sql select ''::text into :recv_buf[0]; + exec sql select '\\a1234'::text into :recv_buf[0]; + exec sql commit; exec sql disconnect; From bf1bb7e29cb1eddb0fad7422c032abb2b756c281 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 333/481] Reject GSSEncRequest after direct SSL connection When a direct SSL connection was established, ProcessStartupPacket() still accepted GSSEncRequest messages. The GSSAPI negotiation would then use raw writes and reads, bypassing the TLS encryption layer. After the GSS encryption was established, the connection continued to use TLS. This could betray the HBA rules so as the backend does protocol exchanges inconsistent with the connection policies in place, with TLS taking priority over GSS in the backend. The SSL negotiation path already guarded against attempts to request SSL after a direct SSL request has been processed. The GSS path is now guarded the same way when receiving a startup packet. Reported-by: p4p3r Author: Michael Paquier Reviewed-by: Jacob Champion Backpatch-through: 17 Security: CVE-2026-14681 --- src/backend/tcop/backend_startup.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/backend/tcop/backend_startup.c b/src/backend/tcop/backend_startup.c index 25205cee0fa..912ad7dc957 100644 --- a/src/backend/tcop/backend_startup.c +++ b/src/backend/tcop/backend_startup.c @@ -659,8 +659,13 @@ ProcessStartupPacket(Port *port) char GSSok = 'N'; #ifdef ENABLE_GSS - /* No GSSAPI encryption when on Unix socket */ - if (port->laddr.addr.ss_family != AF_UNIX) + + /* + * No GSSAPI encryption when on Unix socket. + * + * Also no GSS negotiation if we already have a direct SSL connection. + */ + if (port->laddr.addr.ss_family != AF_UNIX && !port->ssl_in_use) GSSok = 'G'; #endif From b3d9262bbddcbfd1be1dbd43a48bc155234d21e1 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 334/481] Fix multirange type handling in pg_restore_attribute_stats() statatt_get_type() unconditionally converted multirange types to their underlying range type. This choice affected all the type information, like atttypid, atttyptype and operators. This made the bounds histogram work correctly (range type is required), but it was wrong for all the other stat kinds. MCV values for a multirange column should be parsed as multirange arrays, not range arrays. It also made the TYPTYPE_MULTIRANGE check for the range stats validation as dead code, since atttyptype was always TYPTYPE_RANGE after the conversion due to the centralized statatt_get_type(). pg_restore_extended_stats() handles the same case correctly: it keeps the original type and explicitly converts to the range type only at the point where range_histogram_bounds is built. The fix of this issue is simple: the multirange-to-range conversion needs to be moved from the centralized statatt_get_type() up to where attribute stats build their range_histogram_bounds, matching what is done for extended statistics restore. The regression tests for multiranges with attribute stats are extended to cover this case. Author: OpenAI Security Research Team Backpatch-through: 18 Security: CVE-2026-16238 --- src/backend/statistics/attribute_stats.c | 10 +++++++++- src/backend/statistics/stat_utils.c | 7 ------- src/test/regress/expected/stats_import.out | 20 ++++++++++++++++++++ src/test/regress/sql/stats_import.sql | 14 ++++++++++++++ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c index c133b8ad6c9..e65c8dac4a4 100644 --- a/src/backend/statistics/attribute_stats.c +++ b/src/backend/statistics/attribute_stats.c @@ -498,11 +498,19 @@ attribute_statistics_update_internal(Oid reloid, { bool converted = false; Datum stavalues; + Oid bounds_typid = atttypid; + + /* + * If it's a multirange, step down to the range type, as is done by + * multirange_typanalyze(). + */ + if (type_is_multirange(atttypid)) + bounds_typid = get_multirange_range(atttypid); stavalues = statatt_build_stavalues("range_bounds_histogram", &array_in_fn, PG_GETARG_DATUM(RANGE_BOUNDS_HISTOGRAM_ARG), - atttypid, atttypmod, + bounds_typid, atttypmod, &converted); if (converted) diff --git a/src/backend/statistics/stat_utils.c b/src/backend/statistics/stat_utils.c index 0b190e88237..ba204cd5e77 100644 --- a/src/backend/statistics/stat_utils.c +++ b/src/backend/statistics/stat_utils.c @@ -491,13 +491,6 @@ statatt_get_type(Oid reloid, AttrNumber attnum, } ReleaseSysCache(atup); - /* - * If it's a multirange, step down to the range type, as is done by - * multirange_typanalyze(). - */ - if (type_is_multirange(*atttypid)) - *atttypid = get_multirange_range(*atttypid); - /* finds the right operators even if atttypid is a domain */ typcache = lookup_type_cache(*atttypid, TYPECACHE_LT_OPR | TYPECACHE_EQ_OPR); *atttyptype = typcache->typtype; diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out index fa086195e65..c484a77f9e0 100644 --- a/src/test/regress/expected/stats_import.out +++ b/src/test/regress/expected/stats_import.out @@ -1432,12 +1432,32 @@ VALUES (1, 'red', '{[1,3),[5,9),[20,30)}'::int4multirange), (2, 'red', '{[11,13),[15,19),[20,30)}'::int4multirange), (3, 'red', '{[21,23),[25,29),[120,130)}'::int4multirange); +-- warn: reject range values as ordinary multirange statistics +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test_mr', + 'attname', 'mrange', + 'inherited', false, + 'most_common_vals', ARRAY['[1,3)']::text, + 'most_common_freqs', ARRAY[1.0]::real[] +); +WARNING: malformed multirange literal: "[1,3)" +DETAIL: Missing left brace. + pg_restore_attribute_stats +---------------------------- + f +(1 row) + -- ensure that we set attribute stats for a multirange +-- MCVs and histograms retain the multirange type. SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test_mr', 'attname', 'mrange', 'inherited', false, + 'most_common_vals', ARRAY['{[1,3),[5,9)}', '{[11,13),[15,19)}']::text, + 'most_common_freqs', ARRAY[0.6, 0.4]::real[], + 'histogram_bounds', ARRAY['{[1,3)}', '{[11,13)}', '{[21,23)}']::text, 'range_length_histogram', '{19,29,109}'::text, 'range_empty_frac', '0'::real, 'range_bounds_histogram', '{"[1,30)","[11,30)","[21,130)"}'::text diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql index 812a8335e6b..2eb50adf40b 100644 --- a/src/test/regress/sql/stats_import.sql +++ b/src/test/regress/sql/stats_import.sql @@ -1039,12 +1039,26 @@ VALUES (2, 'red', '{[11,13),[15,19),[20,30)}'::int4multirange), (3, 'red', '{[21,23),[25,29),[120,130)}'::int4multirange); +-- warn: reject range values as ordinary multirange statistics +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test_mr', + 'attname', 'mrange', + 'inherited', false, + 'most_common_vals', ARRAY['[1,3)']::text, + 'most_common_freqs', ARRAY[1.0]::real[] +); + -- ensure that we set attribute stats for a multirange +-- MCVs and histograms retain the multirange type. SELECT pg_catalog.pg_restore_attribute_stats( 'schemaname', 'stats_import', 'relname', 'test_mr', 'attname', 'mrange', 'inherited', false, + 'most_common_vals', ARRAY['{[1,3),[5,9)}', '{[11,13),[15,19)}']::text, + 'most_common_freqs', ARRAY[0.6, 0.4]::real[], + 'histogram_bounds', ARRAY['{[1,3)}', '{[11,13)}', '{[21,23)}']::text, 'range_length_histogram', '{19,29,109}'::text, 'range_empty_frac', '0'::real, 'range_bounds_histogram', '{"[1,30)","[11,30)","[21,130)"}'::text From a3832a7571013469dc81e35d0fe1c0066e86d893 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 335/481] Obstruct EXTRACT() field name deparse injection. The parser accepts any string as an EXTRACT() field name, but deparsing does not quote and escape it accordingly. To fix, quote and escape the field name during deparsing as needed. It might be a good idea to validate the field name during parsing and deparsing, too, but that is left as a future exercise. Reported-by: Ben Morris in collaboration with Claude and Anthropic Research Author: Nathan Bossart Reviewed-by: Tom Lane Reviewed-by: Etsuro Fujita Security: CVE-2026-15741 Backpatch-through: 14 --- src/backend/utils/adt/ruleutils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index b5a9c8be56e..a12b804e6dc 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -11812,7 +11812,7 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context) Assert(IsA(con, Const) && con->consttype == TEXTOID && !con->constisnull); - appendStringInfoString(buf, TextDatumGetCString(con->constvalue)); + appendStringInfoString(buf, quote_identifier(TextDatumGetCString(con->constvalue))); } appendStringInfoString(buf, " FROM "); get_rule_expr((Node *) lsecond(expr->args), context, false); @@ -11832,6 +11832,7 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context) Assert(IsA(con, Const) && con->consttype == TEXTOID && !con->constisnull); + /* NB: safe because no allowed words need quoted/escaped */ appendStringInfo(buf, " %s", TextDatumGetCString(con->constvalue)); } From 4d192fa168cf43c6431bf96941d8c709bb92bf5d Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 336/481] Use value of scram_iterations in mock_scram_secret(). Presently, mock_scram_secret() always uses SCRAM_SHA_256_DEFAULT_ITERATIONS, which poses an observable response discrepancy hazard when scram_iterations is set to something else. To fix, use the value of the configuration parameter instead, and document that unauthenticated users can discover the existence of roles with passwords created with different iteration counts. Reported-by: Radim Marek Author: Nathan Bossart Reviewed-by: Michael Paquier Reviewed-by: Heikki Linnakangas Reviewed-by: Jacob Champion Security: CVE-2026-14672 Backpatch-through: 16 --- doc/src/sgml/config.sgml | 13 +++++++++++++ src/backend/libpq/auth-scram.c | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 0a2afe88ea0..1352ae85c10 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1172,6 +1172,19 @@ include_dir 'conf.d' time of encryption. In order to make use of a changed value, a new password must be set. + + + If a role password was created with a different iteration count than + the value of scram_iterations specified in the + postgresql.conf file or on the server command + line, an unauthenticated user can discern the existence of the role by + observing discrepancies in the server's responses to connection + attempts. If you find this concerning, ensure that all role passwords + are created with scram_iterations set to the value + specified in the postgresql.conf file or on the + server command line. + + diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c index 4bac15fc5c1..e8c8352fba8 100644 --- a/src/backend/libpq/auth-scram.c +++ b/src/backend/libpq/auth-scram.c @@ -727,7 +727,7 @@ mock_scram_secret(const char *username, pg_cryptohash_type *hash_type, encoded_salt[encoded_len] = '\0'; *salt = encoded_salt; - *iterations = SCRAM_SHA_256_DEFAULT_ITERATIONS; + *iterations = scram_sha_256_iterations; /* StoredKey and ServerKey are not used in a doomed authentication */ memset(stored_key, 0, SCRAM_MAX_KEY_LEN); From 557cc7186435c7e228c8e4074254a84d1e845790 Mon Sep 17 00:00:00 2001 From: Noah Misch Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 337/481] Empty search_path in amcheck. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A grantee of amcheck function EXECUTE privilege could execute arbitrary functions as the owners of expression indexes that depend on the search path. An expression like (lower(col)) was not vulnerable, because lower() is resolved at CREATE INDEX time. However, an expression calling an sql-language or plpgsql-language function often was vulnerable, even if it used search_path only to find objects in pg_catalog. The amcheck documentation has been warning about data disclosure after such a GRANT, not about function execution. This might cause new amcheck errors when index expressions rely on a broader search_path. Such indexes have seen errors during auto-analyze since CVE-2018-1058 commit 582edc369cdbd348d68441fc50fa26a84afd0c1a, and v17 amcheck always worked this way. Hence, the risk is low. Leave a comment on the one other sandbox entrance that doesn't empty search_path. In its case, the choice was valid. Back-patch to v14 (all supported versions), but v17 was safe already. Commit 2af07e2f749a9208ca1ed84fa1d8fe0e75833288 (v17) unintentionally blocked the attack, and commit d70b17636ddf1ea2c71d1c7bc477372b36ccb66b (v18) unintentionally removed that protection. Hence, this adds to v17 just a test and a comment. While emptying search_path became more widespread in commit 2af07e2f749a9208ca1ed84fa1d8fe0e75833288 (v17), none of its other changes blocked an attack available in v16, even when considering GRANT. For example, brin_summarize_range() has had an owner check that GRANT does not override. Reported-by: 王跃林 Reported-by: Jacob Brazeal Backpatch-through: 14 Security: CVE-2026-14673 --- contrib/amcheck/expected/check_btree.out | 17 +++++++++++++++-- contrib/amcheck/sql/check_btree.sql | 18 +++++++++++++++--- contrib/amcheck/verify_common.c | 1 + src/backend/utils/init/usercontext.c | 6 ++++++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/contrib/amcheck/expected/check_btree.out b/contrib/amcheck/expected/check_btree.out index 6558f2c5a4f..4fcee5da463 100644 --- a/contrib/amcheck/expected/check_btree.out +++ b/contrib/amcheck/expected/check_btree.out @@ -186,7 +186,8 @@ SELECT bt_index_check('toasty', true); (1 row) -- --- Check that index expressions and predicates are run as the table's owner +-- Check that index expressions and predicates are run as the table's owner, +-- with empty search_path -- TRUNCATE bttest_a; INSERT INTO bttest_a SELECT * FROM generate_series(1, 1000); @@ -194,19 +195,31 @@ ALTER TABLE bttest_a OWNER TO regress_bttest_role; -- A dummy index function checking current_user CREATE FUNCTION ifun(int8) RETURNS int8 AS $$ BEGIN - ASSERT current_user = 'regress_bttest_role', + ASSERT current_setting('search_path') = 'pg_catalog, pg_temp', + format('ifun(%s) called with current_schemas %s, search_path %s', + $1, current_schemas(true), current_setting('search_path')); + ASSERT "current_user"() = 'regress_bttest_role', format('ifun(%s) called by %s', $1, current_user); RETURN $1; END; $$ LANGUAGE plpgsql IMMUTABLE; CREATE INDEX bttest_a_expr_idx ON bttest_a ((ifun(id) + ifun(0))) WHERE ifun(id + 10) > ifun(10); +BEGIN; +SET LOCAL check_function_bodies = off; +CREATE SCHEMA preempt; +GRANT USAGE ON SCHEMA preempt TO regress_bttest_role; +SET LOCAL search_path = preempt, pg_catalog, public; +CREATE FUNCTION "current_user"() RETURNS name AS $$ + broken +$$ LANGUAGE sql STABLE PARALLEL SAFE STRICT; SELECT bt_index_check('bttest_a_expr_idx', true); bt_index_check ---------------- (1 row) +ROLLBACK; -- UNIQUE constraint check SELECT bt_index_check('bttest_a_idx', heapallindexed => true, checkunique => true); bt_index_check diff --git a/contrib/amcheck/sql/check_btree.sql b/contrib/amcheck/sql/check_btree.sql index 171f7f691ec..a5585085fad 100644 --- a/contrib/amcheck/sql/check_btree.sql +++ b/contrib/amcheck/sql/check_btree.sql @@ -123,7 +123,8 @@ INSERT INTO toast_bug SELECT repeat('a', 2200); SELECT bt_index_check('toasty', true); -- --- Check that index expressions and predicates are run as the table's owner +-- Check that index expressions and predicates are run as the table's owner, +-- with empty search_path -- TRUNCATE bttest_a; INSERT INTO bttest_a SELECT * FROM generate_series(1, 1000); @@ -131,7 +132,10 @@ ALTER TABLE bttest_a OWNER TO regress_bttest_role; -- A dummy index function checking current_user CREATE FUNCTION ifun(int8) RETURNS int8 AS $$ BEGIN - ASSERT current_user = 'regress_bttest_role', + ASSERT current_setting('search_path') = 'pg_catalog, pg_temp', + format('ifun(%s) called with current_schemas %s, search_path %s', + $1, current_schemas(true), current_setting('search_path')); + ASSERT "current_user"() = 'regress_bttest_role', format('ifun(%s) called by %s', $1, current_user); RETURN $1; END; @@ -139,8 +143,16 @@ $$ LANGUAGE plpgsql IMMUTABLE; CREATE INDEX bttest_a_expr_idx ON bttest_a ((ifun(id) + ifun(0))) WHERE ifun(id + 10) > ifun(10); - +BEGIN; +SET LOCAL check_function_bodies = off; +CREATE SCHEMA preempt; +GRANT USAGE ON SCHEMA preempt TO regress_bttest_role; +SET LOCAL search_path = preempt, pg_catalog, public; +CREATE FUNCTION "current_user"() RETURNS name AS $$ + broken +$$ LANGUAGE sql STABLE PARALLEL SAFE STRICT; SELECT bt_index_check('bttest_a_expr_idx', true); +ROLLBACK; -- UNIQUE constraint check SELECT bt_index_check('bttest_a_idx', heapallindexed => true, checkunique => true); diff --git a/contrib/amcheck/verify_common.c b/contrib/amcheck/verify_common.c index 2301b843494..46e53b3f99a 100644 --- a/contrib/amcheck/verify_common.c +++ b/contrib/amcheck/verify_common.c @@ -94,6 +94,7 @@ amcheck_lock_relation_and_check(Oid indrelid, SetUserIdAndSecContext(heaprel->rd_rel->relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + RestrictSearchPath(); } else { diff --git a/src/backend/utils/init/usercontext.c b/src/backend/utils/init/usercontext.c index d3727d8be19..2aceb41da50 100644 --- a/src/backend/utils/init/usercontext.c +++ b/src/backend/utils/init/usercontext.c @@ -70,6 +70,12 @@ SwitchToUntrustedUser(Oid userid, UserContext *context) * session state. Also set up a new GUC nest level, so that we can * roll back any GUC changes that may be made by code running as the * target user, inasmuch as they could be malicious. + * + * Unlike most use of SECURITY_RESTRICTED_OPERATION, this opts not to + * use RestrictSearchPath(). Calling it would just stop the current + * user from attacking "userid", but we've already established that + * the current user could just SET ROLE to "userid". Calling it would + * be a compatibility break. */ sec_context |= SECURITY_RESTRICTED_OPERATION; SetUserIdAndSecContext(userid, sec_context); From 7082ce248a52d02507c69aa2eadafdd34552a059 Mon Sep 17 00:00:00 2001 From: Jacob Champion Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 338/481] Move SplitGUCList() to fe_utils This is needed so that all versions of pg_upgrade that migrate logical replication slots can parse the new output_plugin_libraries GUC. Backpatch-through: 17 Security: CVE-2026-6471 --- src/backend/utils/adt/varlena.c | 2 +- src/bin/pg_dump/dumputils.c | 109 --------------------------- src/bin/pg_dump/dumputils.h | 3 - src/fe_utils/string_utils.c | 110 ++++++++++++++++++++++++++++ src/include/fe_utils/string_utils.h | 2 + 5 files changed, 113 insertions(+), 113 deletions(-) diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 0c6d3ba4d22..e9548bed2ce 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -3044,7 +3044,7 @@ SplitDirectoriesString(char *rawstring, char separator, * However, it's not clear that having one function with a bunch of option * flags would be much better. * - * XXX there is a version of this function in src/bin/pg_dump/dumputils.c. + * XXX there is a version of this function in src/fe_utils/string_utils.c. * Be sure to update that if you have to change this. * * Inputs: diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index dfb1f603a43..0d9f817875d 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -744,115 +744,6 @@ variable_is_guc_list_quote(const char *name) return false; } -/* - * SplitGUCList --- parse a string containing identifiers or file names - * - * This is used to split the value of a GUC_LIST_QUOTE GUC variable, without - * presuming whether the elements will be taken as identifiers or file names. - * See comparable code in src/backend/utils/adt/varlena.c. - * - * Inputs: - * rawstring: the input string; must be overwritable! On return, it's - * been modified to contain the separated identifiers. - * separator: the separator punctuation expected between identifiers - * (typically '.' or ','). Whitespace may also appear around - * identifiers. - * Outputs: - * namelist: receives a malloc'd, null-terminated array of pointers to - * identifiers within rawstring. Caller should free this - * even on error return. - * - * Returns true if okay, false if there is a syntax error in the string. - */ -bool -SplitGUCList(char *rawstring, char separator, - char ***namelist) -{ - char *nextp = rawstring; - bool done = false; - char **nextptr; - - /* - * Since we disallow empty identifiers, this is a conservative - * overestimate of the number of pointers we could need. Allow one for - * list terminator. - */ - *namelist = nextptr = - pg_malloc_array(char *, (strlen(rawstring) / 2 + 2)); - *nextptr = NULL; - - while (isspace((unsigned char) *nextp)) - nextp++; /* skip leading whitespace */ - - if (*nextp == '\0') - return true; /* empty string represents empty list */ - - /* At the top of the loop, we are at start of a new identifier. */ - do - { - char *curname; - char *endp; - - if (*nextp == '"') - { - /* Quoted name --- collapse quote-quote pairs */ - curname = nextp + 1; - for (;;) - { - endp = strchr(nextp + 1, '"'); - if (endp == NULL) - return false; /* mismatched quotes */ - if (endp[1] != '"') - break; /* found end of quoted name */ - /* Collapse adjacent quotes into one quote, and look again */ - memmove(endp, endp + 1, strlen(endp)); - nextp = endp; - } - /* endp now points at the terminating quote */ - nextp = endp + 1; - } - else - { - /* Unquoted name --- extends to separator or whitespace */ - curname = nextp; - while (*nextp && *nextp != separator && - !isspace((unsigned char) *nextp)) - nextp++; - endp = nextp; - if (curname == nextp) - return false; /* empty unquoted name not allowed */ - } - - while (isspace((unsigned char) *nextp)) - nextp++; /* skip trailing whitespace */ - - if (*nextp == separator) - { - nextp++; - while (isspace((unsigned char) *nextp)) - nextp++; /* skip leading whitespace for next */ - /* we expect another name, so done remains false */ - } - else if (*nextp == '\0') - done = true; - else - return false; /* invalid syntax */ - - /* Now safe to overwrite separator with a null */ - *endp = '\0'; - - /* - * Finished isolating current name --- add it to output array - */ - *nextptr++ = curname; - - /* Loop back if we didn't reach end of string */ - } while (!done); - - *nextptr = NULL; - return true; -} - /* * Helper function for dumping "ALTER DATABASE/ROLE SET ..." commands. * diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h index d231ce1d654..de84bea38be 100644 --- a/src/bin/pg_dump/dumputils.h +++ b/src/bin/pg_dump/dumputils.h @@ -57,9 +57,6 @@ extern void emitShSecLabels(PGconn *conn, PGresult *res, extern bool variable_is_guc_list_quote(const char *name); -extern bool SplitGUCList(char *rawstring, char separator, - char ***namelist); - extern void makeAlterConfigCommand(PGconn *conn, const char *configitem, const char *type, const char *name, const char *type2, const char *name2, diff --git a/src/fe_utils/string_utils.c b/src/fe_utils/string_utils.c index 7a762251f32..c6d8d939836 100644 --- a/src/fe_utils/string_utils.c +++ b/src/fe_utils/string_utils.c @@ -803,6 +803,116 @@ appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname) } +/* + * SplitGUCList --- parse a string containing identifiers or file names + * + * This is used to split the value of a GUC_LIST_QUOTE GUC variable, without + * presuming whether the elements will be taken as identifiers or file names. + * See comparable code in src/backend/utils/adt/varlena.c. + * + * Inputs: + * rawstring: the input string; must be overwritable! On return, it's + * been modified to contain the separated identifiers. + * separator: the separator punctuation expected between identifiers + * (typically '.' or ','). Whitespace may also appear around + * identifiers. + * Outputs: + * namelist: receives a malloc'd, null-terminated array of pointers to + * identifiers within rawstring. Caller should free this + * even on error return. + * + * Returns true if okay, false if there is a syntax error in the string. + */ +bool +SplitGUCList(char *rawstring, char separator, + char ***namelist) +{ + char *nextp = rawstring; + bool done = false; + char **nextptr; + + /* + * Since we disallow empty identifiers, this is a conservative + * overestimate of the number of pointers we could need. Allow one for + * list terminator. + */ + *namelist = nextptr = + pg_malloc_array(char *, (strlen(rawstring) / 2 + 2)); + *nextptr = NULL; + + while (isspace((unsigned char) *nextp)) + nextp++; /* skip leading whitespace */ + + if (*nextp == '\0') + return true; /* empty string represents empty list */ + + /* At the top of the loop, we are at start of a new identifier. */ + do + { + char *curname; + char *endp; + + if (*nextp == '"') + { + /* Quoted name --- collapse quote-quote pairs */ + curname = nextp + 1; + for (;;) + { + endp = strchr(nextp + 1, '"'); + if (endp == NULL) + return false; /* mismatched quotes */ + if (endp[1] != '"') + break; /* found end of quoted name */ + /* Collapse adjacent quotes into one quote, and look again */ + memmove(endp, endp + 1, strlen(endp)); + nextp = endp; + } + /* endp now points at the terminating quote */ + nextp = endp + 1; + } + else + { + /* Unquoted name --- extends to separator or whitespace */ + curname = nextp; + while (*nextp && *nextp != separator && + !isspace((unsigned char) *nextp)) + nextp++; + endp = nextp; + if (curname == nextp) + return false; /* empty unquoted name not allowed */ + } + + while (isspace((unsigned char) *nextp)) + nextp++; /* skip trailing whitespace */ + + if (*nextp == separator) + { + nextp++; + while (isspace((unsigned char) *nextp)) + nextp++; /* skip leading whitespace for next */ + /* we expect another name, so done remains false */ + } + else if (*nextp == '\0') + done = true; + else + return false; /* invalid syntax */ + + /* Now safe to overwrite separator with a null */ + *endp = '\0'; + + /* + * Finished isolating current name --- add it to output array + */ + *nextptr++ = curname; + + /* Loop back if we didn't reach end of string */ + } while (!done); + + *nextptr = NULL; + return true; +} + + /* * Deconstruct the text representation of a 1-dimensional Postgres array * into individual items. diff --git a/src/include/fe_utils/string_utils.h b/src/include/fe_utils/string_utils.h index 0680bb3c19e..3e455c8a415 100644 --- a/src/include/fe_utils/string_utils.h +++ b/src/include/fe_utils/string_utils.h @@ -48,6 +48,8 @@ extern bool appendShellStringNoError(PQExpBuffer buf, const char *str); extern void appendConnStrVal(PQExpBuffer buf, const char *str); extern void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname); +extern bool SplitGUCList(char *rawstring, char separator, char ***namelist); + extern bool parsePGArray(const char *atext, char ***itemarray, int *nitems); extern void appendPGArray(PQExpBuffer buffer, const char *value); From 5d47df21e89967e351df5ad7aa93bc3af40db64a Mon Sep 17 00:00:00 2001 From: Jacob Champion Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 339/481] Add an output_plugin_libraries GUC to bless trusted output plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit REPLICATION users were not previously subject to restrictions on output plugin paths, so they were able to bypass LOAD-time protections during logical decoding. Unfortunately, adding the standard LOAD restrictions now would retroactively require all third-party output plugins to be installed under the $libdir/plugins directory. This would prevent the use of dynamic_library_path, introduce a wire incompatibility for clients, and require all plugin authors to check that their libraries are safe for use by any unprivileged user; we want to avoid that. Instead, introduce an output_plugin_libraries GUC so that DBAs can specify the output plugins that are trusted for use in logical decoding. For simplicity, superusers are subject to the restriction as well (though they're free to modify the GUC at will during a session, so no power is actually lost). The default setting is 'pgoutput, test_decoding'. If other third-party plugins are in use, DBAs will need to modify this parameter after they update. Some pointers have been added to the documentation to assist with this. Author: Jacob Champion Reported-by: Vladimir Tokarev Reported-by: Yu Kunpeng Reviewed-by: Álvaro Herrera Reviewed-by: Noah Misch Reviewed-by: Robert Haas Reviewed-by: Tom Lane Backpatch-through: 14 Security: CVE-2026-6471 --- .../test_decoding/expected/permissions.out | 11 +++ contrib/test_decoding/expected/repack.out | 1 - contrib/test_decoding/expected/slot.out | 3 + contrib/test_decoding/sql/permissions.sql | 8 ++ contrib/test_decoding/sql/slot.sql | 3 + doc/src/sgml/config.sgml | 57 +++++++++++ doc/src/sgml/logical-replication.sgml | 13 ++- src/backend/replication/logical/logical.c | 97 ++++++++++++++++++- src/backend/replication/pgrepack/pgrepack.c | 10 +- src/backend/utils/misc/guc_parameters.dat | 9 ++ src/backend/utils/misc/guc_tables.c | 1 + src/backend/utils/misc/postgresql.conf.sample | 1 + src/bin/pg_dump/dumputils.c | 1 + src/bin/pg_upgrade/check.c | 85 +++++++++++++++- src/bin/pg_upgrade/t/003_logical_slots.pl | 53 ++++++++-- src/include/replication/logical.h | 3 + src/test/subscription/t/100_bugs.pl | 27 +++++- 17 files changed, 359 insertions(+), 24 deletions(-) diff --git a/contrib/test_decoding/expected/permissions.out b/contrib/test_decoding/expected/permissions.out index 8d100646ce6..6e94d7106bd 100644 --- a/contrib/test_decoding/expected/permissions.out +++ b/contrib/test_decoding/expected/permissions.out @@ -29,6 +29,17 @@ SELECT pg_drop_replication_slot('regression_slot'); (1 row) RESET ROLE; +-- no users can load an untrusted plugin +SET output_plugin_libraries = pgoutput; +SET ROLE regress_lr_replication; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); +ERROR: library "test_decoding" may not be used as an output plugin +HINT: If it is safe for all REPLICATION users to use this library as an output plugin, add it to "output_plugin_libraries" and reload the server configuration. +RESET ROLE; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); +ERROR: library "test_decoding" may not be used as an output plugin +HINT: If it is safe for all REPLICATION users to use this library as an output plugin, add it to "output_plugin_libraries" and reload the server configuration. +RESET output_plugin_libraries; -- replication user can control replication SET ROLE regress_lr_replication; SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out index c4ff41be690..5ddc63238c5 100644 --- a/contrib/test_decoding/expected/repack.out +++ b/contrib/test_decoding/expected/repack.out @@ -106,7 +106,6 @@ CREATE TABLE repack_plugin (a int); SELECT * FROM pg_create_logical_replication_slot('s_repack', 'pgrepack'); ERROR: unsupported use of logical decoding plugin "pgrepack" DETAIL: This plugin can only be used by REPACK (CONCURRENTLY). -CONTEXT: slot "s_repack", output plugin "pgrepack", in the startup callback INSERT INTO repack_plugin VALUES (1); SELECT * FROM pg_logical_slot_get_binary_changes('s_repack', NULL, NULL); ERROR: replication slot "s_repack" does not exist diff --git a/contrib/test_decoding/expected/slot.out b/contrib/test_decoding/expected/slot.out index 7de03c79f6f..cf0136455b0 100644 --- a/contrib/test_decoding/expected/slot.out +++ b/contrib/test_decoding/expected/slot.out @@ -30,8 +30,11 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_t2', 'tes init (1 row) +BEGIN; +SET LOCAL output_plugin_libraries = nonexistent; SELECT pg_create_logical_replication_slot('foo', 'nonexistent'); ERROR: could not access file "nonexistent": No such file or directory +ROLLBACK; -- here we want to start a new session and wait till old one is gone select pg_backend_pid() as oldpid \gset \c - diff --git a/contrib/test_decoding/sql/permissions.sql b/contrib/test_decoding/sql/permissions.sql index 94db936aee2..b3d8b1a8e57 100644 --- a/contrib/test_decoding/sql/permissions.sql +++ b/contrib/test_decoding/sql/permissions.sql @@ -15,6 +15,14 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc SELECT pg_drop_replication_slot('regression_slot'); RESET ROLE; +-- no users can load an untrusted plugin +SET output_plugin_libraries = pgoutput; +SET ROLE regress_lr_replication; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); +RESET ROLE; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); +RESET output_plugin_libraries; + -- replication user can control replication SET ROLE regress_lr_replication; SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); diff --git a/contrib/test_decoding/sql/slot.sql b/contrib/test_decoding/sql/slot.sql index 580e3ae3bef..50a950341fc 100644 --- a/contrib/test_decoding/sql/slot.sql +++ b/contrib/test_decoding/sql/slot.sql @@ -9,7 +9,10 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_p', 'test SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_t2', 'test_decoding', true); +BEGIN; +SET LOCAL output_plugin_libraries = nonexistent; SELECT pg_create_logical_replication_slot('foo', 'nonexistent'); +ROLLBACK; -- here we want to start a new session and wait till old one is gone select pg_backend_pid() as oldpid \gset diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 1352ae85c10..88ed724b639 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -4858,6 +4858,63 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows + + output_plugin_libraries (string) + + output_plugin_libraries configuration parameter + + + + + Lists the libraries installed in + that are also trusted for use as logical output plugins by replication + clients. Any logical decoding + or replication requests for + other libraries will be refused. All users are subject to this + restriction. The default is 'pgoutput, test_decoding', + which are the two logical output plugins included in the standard + PostgreSQL distribution. + + + The format is a comma-separated list of library names, where each name + is interpreted as for the LOAD + command (but logical decoding clients must specify a plugin name that + exactly matches an entry in the list, without + variations in case or path structure). Whitespace between entries is + ignored; surround a library name with double quotes if you need to + include whitespace or commas in the name. + + + It is the responsibility of the server administrator to ensure that + libraries added to this list do not unintentionally give additional + privileges to non-superusers when they are loaded into the server. + + + + When updating the server from a version that does not have the + output_plugin_libraries parameter, the following + query can help construct the list of plugins that are required by all + persistent logical replication slots: + +SELECT DISTINCT plugin FROM pg_replication_slots WHERE plugin IS NOT NULL; + + Review the list carefully for safety before adjusting + output_plugin_libraries. + + + The above query can only display plugins which were successfully + added to replication slots at some point in the past. Newly refused + requests will appear in the logs with a message similar to + +ERROR: library "..." may not be used as an output plugin +DETAIL: The configuration parameter "output_plugin_libraries" (currently 'pgoutput, test_decoding') does not name this library as a trusted output plugin. +HINT: If it is safe for all REPLICATION users to use this library as an output plugin, add it to "output_plugin_libraries" and reload the server configuration. + + + + + + wal_keep_size (integer) diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index efbed7b3bcb..938c939e97d 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -2559,6 +2559,15 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER and it must have the LOGIN attribute. + + The name of the output plugin used by the replication connection must be + included in the server's . (For + subscriptions, the plugin name that is used is pgoutput.) + Superusers may modify the trusted list per-connection, by including + options=-coutput_plugin_libraries=... in the connection + string. + + In order to be able to copy the initial table data or synchronize sequences, the role used for the replication connection must have the @@ -2800,7 +2809,9 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER The output plugins referenced by the slots in the old cluster must be - installed in the new PostgreSQL executable directory. + installed in the new PostgreSQL executable directory. They must also be + included in the new cluster's ; + see that parameter's documentation for safety information. diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c index c30d40a8641..98e5f1dd8f9 100644 --- a/src/backend/replication/logical/logical.c +++ b/src/backend/replication/logical/logical.c @@ -31,6 +31,7 @@ #include "access/xact.h" #include "access/xlog_internal.h" #include "access/xlogutils.h" +#include "commands/repack.h" #include "fmgr.h" #include "miscadmin.h" #include "pgstat.h" @@ -42,9 +43,11 @@ #include "storage/proc.h" #include "storage/procarray.h" #include "utils/builtins.h" +#include "utils/guc.h" #include "utils/injection_point.h" #include "utils/inval.h" #include "utils/memutils.h" +#include "utils/varlena.h" /* data for errcontext callback */ typedef struct LogicalErrorCallbackState @@ -54,6 +57,9 @@ typedef struct LogicalErrorCallbackState XLogRecPtr report_location; } LogicalErrorCallbackState; +/* GUC variables */ +char *output_plugin_libraries_string; + /* wrappers around output plugin callbacks */ static void output_plugin_error_callback(void *arg); static void startup_cb_wrapper(LogicalDecodingContext *ctx, OutputPluginOptions *opt, @@ -144,6 +150,7 @@ StartupDecodingContext(List *output_plugin_options, bool need_full_snapshot, bool fast_forward, bool in_create, + bool for_repack, XLogReaderRoutine *xl_routine, LogicalOutputPluginWriterPrepareWrite prepare_write, LogicalOutputPluginWriterWrite do_write, @@ -170,7 +177,86 @@ StartupDecodingContext(List *output_plugin_options, * now. */ if (!fast_forward) - LoadOutputPlugin(&ctx->callbacks, NameStr(slot->data.plugin)); + { + /* + * Before loading this library, make sure it's been blessed for + * logical decoding. + */ + const char *plugin = NameStr(slot->data.plugin); + bool plugin_allowed = false; + + if (strcmp(plugin, "pgrepack") == 0) + { + /* + * REPACK is a special case -- print a more helpful error message + * here if we're not being called in the correct context. + */ + if (!for_repack || !AmRepackWorker()) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("unsupported use of logical decoding plugin \"%s\"", + "pgrepack"), + errdetail("This plugin can only be used by %s.", + "REPACK (CONCURRENTLY)")); + + plugin_allowed = true; + } + else if (output_plugin_libraries_string && + output_plugin_libraries_string[0]) + { + /* Check this plugin against output_plugin_libraries. */ + char *rawstring; + List *elemlist = NIL; + + /* Need a modifiable copy */ + rawstring = pstrdup(output_plugin_libraries_string); + + if (!SplitGUCList(rawstring, ',', &elemlist)) + { + /* syntax error in list */ + ereport(LOG, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid list syntax in parameter \"%s\"", + "output_plugin_libraries"))); + + list_free(elemlist); + elemlist = NIL; + } + + foreach_ptr(char, allowed, elemlist) + { + if (strcmp(allowed, plugin) == 0) + { + plugin_allowed = true; + break; + } + } + + list_free(elemlist); + pfree(rawstring); + } + + if (!plugin_allowed) + { + /* + * Use the same error message as check_restricted_library_name(), + * but provide additional context for the DBA in the logs. (The + * HINT will be sent to the client, but that's not a secret.) + */ + ereport(ERROR, + errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("library \"%s\" may not be used as an output plugin", + plugin), + /*- translator: The second %s is the value of the output_plugin_libraries GUC, which may contain whitespace, commas, and double-quotes (") */ + errdetail_log("The configuration parameter \"%s\" (currently '%s') does not name this library as a trusted output plugin.", + "output_plugin_libraries", + output_plugin_libraries_string), + errhint("If it is safe for all REPLICATION users to use this library as an output plugin, add it to \"%s\" and reload the server configuration.", + "output_plugin_libraries")); + } + + LoadOutputPlugin(&ctx->callbacks, plugin); + } /* * Now that the slot's xmin has been set, we can announce ourselves as a @@ -434,7 +520,7 @@ CreateInitDecodingContext(const char *plugin, ReplicationSlotSave(); ctx = StartupDecodingContext(NIL, restart_lsn, xmin_horizon, - need_full_snapshot, false, true, + need_full_snapshot, false, true, for_repack, xl_routine, prepare_write, do_write, update_progress); @@ -569,7 +655,8 @@ CreateDecodingContext(XLogRecPtr start_lsn, ctx = StartupDecodingContext(output_plugin_options, start_lsn, InvalidTransactionId, false, - fast_forward, false, xl_routine, prepare_write, + fast_forward, false, false, + xl_routine, prepare_write, do_write, update_progress); /* call output plugin initialization callback */ @@ -720,7 +807,9 @@ OutputPluginUpdateProgress(struct LogicalDecodingContext *ctx, /* * Load the output plugin, lookup its output plugin init function, and check - * that it provides the required callbacks. + * that it provides the required callbacks. The caller must have checked that + * the current user has the necessary privileges to load the given plugin; + * standard LOAD restrictions are not applied here. */ static void LoadOutputPlugin(OutputPluginCallbacks *callbacks, const char *plugin) diff --git a/src/backend/replication/pgrepack/pgrepack.c b/src/backend/replication/pgrepack/pgrepack.c index 5c5095bde4e..a1cbc8db68a 100644 --- a/src/backend/replication/pgrepack/pgrepack.c +++ b/src/backend/replication/pgrepack/pgrepack.c @@ -54,12 +54,10 @@ repack_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, RepackDecodingState *dstate; if (!AmRepackWorker()) - ereport(ERROR, - errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("unsupported use of logical decoding plugin \"%s\"", - "pgrepack"), - errdetail("This plugin can only be used by %s.", - "REPACK (CONCURRENTLY)")); + { + /* StartupDecodingContext() should have caught this case already */ + elog(FATAL, "unexpected pgrepack startup outside of repack worker"); + } /* Initial setup of our private state */ Assert(CurrentMemoryContext == ctx->context); diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat index 2cd115deaee..15f9261dab6 100644 --- a/src/backend/utils/misc/guc_parameters.dat +++ b/src/backend/utils/misc/guc_parameters.dat @@ -2308,6 +2308,15 @@ ifdef => 'DEBUG_BOUNDED_SORT', }, +{ name => 'output_plugin_libraries', type => 'string', context => 'PGC_SUSET', group => 'REPLICATION_SENDING', + short_desc => 'Lists libraries that may be named as logical decoding output plugins.', + long_desc => 'Users with REPLICATION privileges may only use plugins in this list when creating logical replication slots.', + # Note that src/bin/pg_upgrade/check.c assumes GUC_LIST_QUOTE here. + flags => 'GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY', + variable => 'output_plugin_libraries_string', + boot_val => '"pgoutput, test_decoding"', +}, + { name => 'parallel_leader_participation', type => 'bool', context => 'PGC_USERSET', group => 'RESOURCES_WORKER_PROCESSES', short_desc => 'Controls whether Gather and Gather Merge also run subplans.', long_desc => 'Should gather nodes also run subplans or just gather tuples?', diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 290ccbc543e..7fd83081462 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -72,6 +72,7 @@ #include "postmaster/syslogger.h" #include "postmaster/walsummarizer.h" #include "postmaster/walwriter.h" +#include "replication/logical.h" #include "replication/logicallauncher.h" #include "replication/slot.h" #include "replication/slotsync.h" diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 23dd27957be..f61bd6ad4de 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -863,6 +863,7 @@ #dynamic_library_path = '$libdir' #extension_control_path = '$system' #gin_fuzzy_search_limit = 0 +#output_plugin_libraries = 'pgoutput, test_decoding' # approved plugins for logical decoding #------------------------------------------------------------------------------ diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index 0d9f817875d..a08afaf8de5 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -734,6 +734,7 @@ variable_is_guc_list_quote(const char *name) { if (pg_strcasecmp(name, "local_preload_libraries") == 0 || pg_strcasecmp(name, "oauth_validator_libraries") == 0 || + pg_strcasecmp(name, "output_plugin_libraries") == 0 || pg_strcasecmp(name, "search_path") == 0 || pg_strcasecmp(name, "session_preload_libraries") == 0 || pg_strcasecmp(name, "shared_preload_libraries") == 0 || diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 184379c52af..e298e5658da 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -2210,6 +2210,7 @@ check_new_cluster_replication_slots(void) int nslots_on_new; int rdt_slot_on_new; int max_replication_slots; + char *output_plugin_libraries; char *wal_level; int i_nslots_on_new; int i_rdt_slot_on_new; @@ -2269,10 +2270,10 @@ check_new_cluster_replication_slots(void) PQclear(res); res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings " - "WHERE name IN ('wal_level', 'max_replication_slots') " + "WHERE name IN ('wal_level', 'output_plugin_libraries', 'max_replication_slots') " "ORDER BY name DESC;"); - if (PQntuples(res) != 2) + if (PQntuples(res) != 3) pg_fatal("could not determine parameter settings on new cluster"); wal_level = PQgetvalue(res, 0, 0); @@ -2282,7 +2283,85 @@ check_new_cluster_replication_slots(void) pg_fatal("\"wal_level\" must be \"replica\" or \"logical\" but is set to \"%s\"", wal_level); - max_replication_slots = atoi(PQgetvalue(res, 1, 0)); + output_plugin_libraries = PQgetvalue(res, 1, 0); + + /* + * Make sure the output_plugin_libraries setting covers all plugins needed + * by any migrated slots. + */ + if (nslots_on_old > 0) + { + char *guc_copy = pg_strdup(output_plugin_libraries); + char **allowed_plugins; + char output_path[MAXPGPATH]; + FILE *script = NULL; + + if (!SplitGUCList(guc_copy, ',', &allowed_plugins)) + { + /* + * Should not happen. (Frontend and backend GUC_LIST_QUOTE parsing + * have to remain compatible for pg_dump at minimum.) + */ + pg_fatal("could not parse \"output_plugin_libraries\" setting '%s'", + output_plugin_libraries); + } + + snprintf(output_path, sizeof(output_path), "%s/%s", + log_opts.basedir, + "disallowed_output_plugins.txt"); + + for (int dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++) + { + LogicalSlotInfoArr *slot_arr = &old_cluster.dbarr.dbs[dbnum].slot_arr; + + for (int slotnum = 0; slotnum < slot_arr->nslots; slotnum++) + { + LogicalSlotInfo *slot = &slot_arr->slots[slotnum]; + bool allowed = false; + + /* + * We expect the output_plugin_libraries length to be small in + * practice; O(n*m) shouldn't be a problem here. + */ + for (char **p = allowed_plugins; *p; p++) + { + if (strcmp(slot->plugin, *p) == 0) + { + allowed = true; + break; + } + } + + if (!allowed) + { + if (script == NULL && + (script = fopen_priv(output_path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", output_path); + + fprintf(script, "The slot \"%s\" uses plugin \"%s\"\n", + slot->slotname, slot->plugin); + } + } + } + + if (script) + { + fclose(script); + + pg_log(PG_REPORT, "fatal"); + pg_fatal("Your installation contains logical replication slots with plugins\n" + "that are not allowed by the new cluster's output_plugin_libraries\n" + "setting. You can add trusted plugins to output_plugin_libraries\n" + "and/or remove affected slots, and then restart the upgrade.\n" + "A list of the problematic slots is in the file:\n" + " %s", output_path); + } + + pg_free(allowed_plugins); + pg_free(guc_copy); + } + + max_replication_slots = atoi(PQgetvalue(res, 2, 0)); if (old_cluster.sub_retain_dead_tuples && nslots_on_old + 1 > max_replication_slots) diff --git a/src/bin/pg_upgrade/t/003_logical_slots.pl b/src/bin/pg_upgrade/t/003_logical_slots.pl index 05918aad935..01ab82402ae 100644 --- a/src/bin/pg_upgrade/t/003_logical_slots.pl +++ b/src/bin/pg_upgrade/t/003_logical_slots.pl @@ -62,7 +62,7 @@ $oldpub->start; $oldpub->safe_psql( 'postgres', qq[ - SELECT pg_create_logical_replication_slot('test_slot1', 'test_decoding'); + SELECT pg_create_logical_replication_slot('test_slot1', 'pgoutput'); SELECT pg_create_logical_replication_slot('test_slot2', 'test_decoding'); SELECT pg_create_logical_replication_slot('test_slot3', 'test_decoding'); ]); @@ -90,6 +90,52 @@ # old cluster. Both slots will be used for subsequent tests. $newpub->append_conf('postgresql.conf', "max_replication_slots = 3"); +# ------------------------------ +# TEST: Confirm pg_upgrade fails when slot plugins are prohibited by the new cluster + +$newpub->append_conf('postgresql.conf', + "output_plugin_libraries = 'pgoutput'"); + +command_checks_all( + [@pg_upgrade_cmd], + 1, + [ + qr/Your installation contains logical replication slots with plugins/, + qr/that are not allowed by the new cluster's output_plugin_libraries/, + ], + [qr//], + 'run of pg_upgrade where the old cluster has untrusted output plugins'); + +my $slots_filename; + +# Find a txt file that contains a list of logical replication slots that cannot +# be upgraded. We cannot predict the file's path because the output directory +# contains a milliseconds timestamp. File::Find::find must be used. +find( + sub { + if ($File::Find::name =~ m/disallowed_output_plugins\.txt/) + { + $slots_filename = $File::Find::name; + } + }, + $newpub->data_dir . "/pg_upgrade_output.d"); + +# Check the report. +my $content = slurp_file($slots_filename); +like( + $content, + qr/The slot "test_slot2" uses plugin "test_decoding"/m, + 'the previous test failed due to prohibited plugins'); +like( + $content, + qr/The slot "test_slot3" uses plugin "test_decoding"/m, + 'the previous test failed due to prohibited plugins'); +unlike($content, qr/test_slot1/m, 'allowed plugin is not reported'); + +# Fix things for the next tests. +$newpub->append_conf('postgresql.conf', + "output_plugin_libraries = 'pgoutput, test_decoding'"); + # ------------------------------ # TEST: Confirm pg_upgrade fails when the slot still has unconsumed WAL records @@ -127,11 +173,6 @@ ); # Verify the reason why the logical replication slot cannot be upgraded -my $slots_filename; - -# Find a txt file that contains a list of logical replication slots that cannot -# be upgraded. We cannot predict the file's path because the output directory -# contains a milliseconds timestamp. File::Find::find must be used. find( sub { if ($File::Find::name =~ m/invalid_logical_slots\.txt/) diff --git a/src/include/replication/logical.h b/src/include/replication/logical.h index 6e0b7628001..abc88c49ade 100644 --- a/src/include/replication/logical.h +++ b/src/include/replication/logical.h @@ -154,6 +154,9 @@ extern XLogRecPtr LogicalReplicationSlotCheckPendingWal(XLogRecPtr end_of_wal, extern XLogRecPtr LogicalSlotAdvanceAndCheckSnapState(XLogRecPtr moveto, bool *found_consistent_snapshot); +/* GUCs */ +extern PGDLLIMPORT char *output_plugin_libraries_string; + /* * This macro determines the log level for messages about starting logical diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl index 075c52f98fd..335efd86bca 100644 --- a/src/test/subscription/t/100_bugs.pl +++ b/src/test/subscription/t/100_bugs.pl @@ -477,13 +477,13 @@ is( $result, qq(2|f 3|t), 'check replicated update on subscriber'); -# Test create and immediate drop of replication slot via replication commands -# (this exposed a memory-management bug in v18) my $publisher_host = $node_publisher->host; my $publisher_port = $node_publisher->port; my $connstr_db = "host=$publisher_host port=$publisher_port replication=database dbname=postgres"; +# Test create and immediate drop of replication slot via replication commands +# (this exposed a memory-management bug in v18) is( $node_publisher->psql( 'postgres', qq[ @@ -495,6 +495,27 @@ 0, 'create and immediate drop of replication slot'); +# REPLICATION users should not be able to bypass LOAD restrictions. +$node_publisher->safe_psql( + 'postgres', qq( + CREATE USER repluser REPLICATION; +)); + +my ($ret, $stdout, $stderr) = $node_publisher->psql( + 'postgres', + qq[ + SET ROLE repluser; + CREATE_REPLICATION_SLOT fail_slot LOGICAL regress;', + ], + timeout => $PostgreSQL::Test::Utils::timeout_default, + extra_params => [ '-d', $connstr_db ]); + +is($ret, 3, 'loading unblessed output plugin fails'); +like( + $stderr, + qr/ERROR: library "regress" may not be used as an output plugin/, + 'loading unblessed output plugin fails: stderr'); + $node_publisher->stop('fast'); $node_subscriber->stop('fast'); @@ -592,7 +613,7 @@ BEGIN CREATE SUBSCRIPTION regress_sub1 CONNECTION '$publisher_connstr' PUBLICATION regress_pub WITH (connect=false); )); -my ($ret, $stdout, $stderr) = +($ret, $stdout, $stderr) = $node_publisher->psql('postgres', q{DROP SUBSCRIPTION regress_sub1}); isnt($ret, 0, "replication slot does not exist: exit code not 0"); From 64a65ead1235f50816a46d4eb66a8ffcba7d5cde Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 340/481] Cross-check the type of a portal running EXECUTE or FETCH. When an EXECUTE or FETCH statement is executed, there are two portals: an outer portal that is created for the EXECUTE or FETCH statement itself, and an inner portal for the statement being executed on its behalf. Before this commit, nothing checked that these two portals agreed on the tuple descriptor of the rows being returned. This can be leveraged to disclose server memory contents and achieve arbitrary code execution. To prevent that, we can make use of an existing safety mechanism, added by Tom Lane in commit 2f48ede080f42b97b594fb14102c82ca1001b80c, which allows a tuplestore DestReceiver to be informed of the tupleDesc required by the caller, and which will cause an ERROR to occur if that doesn't match the tupleDesc of what emerges from the executor (modulo dropped columns, which aren't an issue in the case at hand). Reported-by: Ben Morris in collaboration with Claude and Anthropic Research Reported-by: Peter Geoghegan Reviewed-by: Michael Paquier Security: CVE-2026-16239 --- src/backend/tcop/pquery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c index ee731000820..9f3ea1c9a75 100644 --- a/src/backend/tcop/pquery.c +++ b/src/backend/tcop/pquery.c @@ -1000,8 +1000,8 @@ FillPortalStore(Portal portal, bool isTopLevel) portal->holdStore, portal->holdContext, false, - NULL, - NULL); + portal->tupDesc, + gettext_noop("query result type does not match portal result type")); switch (portal->strategy) { From 62c31b490d94b38a62869593524abca5f67c4c46 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 341/481] Avoid overflow in Levenshtein distance calculations. levenshtein() and levenshtein_less_equal() let the caller specify the insertion, deletion, and substitution costs, and fuzzystrmatch's corresponding SQL functions accept any 32-bit integer for each. Since the distances are calculated with 32-bit arithmetic, large costs can cause overflows, thereby producing nonsensical results. Certain inputs to levenshtein_less_equal() can even cause out-of-bounds writes. To fix, use 64-bit arithmetic instead, and error whenever the final result won't fit in the returned 32-bit integer. We may want to teach these functions to reject negative costs, too, but that didn't seem appropriate for a security fix, and therefore it is left as a future exercise. Reported-by: Ben Morris in collaboration with Claude and Anthropic Research Author: Nathan Bossart Reviewed-by: Dean Rasheed Security: CVE-2026-15742 Backpatch-through: 14 --- .../fuzzystrmatch/expected/fuzzystrmatch.out | 14 +++ contrib/fuzzystrmatch/sql/fuzzystrmatch.sql | 3 + src/backend/utils/adt/levenshtein.c | 89 ++++++++++--------- src/backend/utils/adt/varlena.c | 14 +++ 4 files changed, 77 insertions(+), 43 deletions(-) diff --git a/contrib/fuzzystrmatch/expected/fuzzystrmatch.out b/contrib/fuzzystrmatch/expected/fuzzystrmatch.out index 3195e1ec3c8..aeab031a2ed 100644 --- a/contrib/fuzzystrmatch/expected/fuzzystrmatch.out +++ b/contrib/fuzzystrmatch/expected/fuzzystrmatch.out @@ -41,6 +41,14 @@ SELECT levenshtein('GUMBO', 'GAMBOL', 2, 1, 1); 3 (1 row) +SELECT levenshtein('GUMBO', 'GAMBOL', 1, 1, 2000000000); + levenshtein +------------- + 3 +(1 row) + +SELECT levenshtein('GUMBO', 'GAMBOL', 2000000000, 2000000000, 2000000000); +ERROR: levenshtein distance out of range SELECT levenshtein_less_equal('extensive', 'exhaustive', 2); levenshtein_less_equal ------------------------ @@ -53,6 +61,12 @@ SELECT levenshtein_less_equal('extensive', 'exhaustive', 4); 4 (1 row) +SELECT levenshtein_less_equal('aaa', 'aaaaa', 1073741824, 0, 1073741824, 10); + levenshtein_less_equal +------------------------ + 11 +(1 row) + SELECT metaphone('GUMBO', 4); metaphone ----------- diff --git a/contrib/fuzzystrmatch/sql/fuzzystrmatch.sql b/contrib/fuzzystrmatch/sql/fuzzystrmatch.sql index 0b4bb9be57e..c1d55f823d7 100644 --- a/contrib/fuzzystrmatch/sql/fuzzystrmatch.sql +++ b/contrib/fuzzystrmatch/sql/fuzzystrmatch.sql @@ -11,8 +11,11 @@ SELECT soundex(''), difference('', ''); SELECT levenshtein('GUMBO', 'GAMBOL'); SELECT levenshtein('GUMBO', 'GAMBOL', 2, 1, 1); +SELECT levenshtein('GUMBO', 'GAMBOL', 1, 1, 2000000000); +SELECT levenshtein('GUMBO', 'GAMBOL', 2000000000, 2000000000, 2000000000); SELECT levenshtein_less_equal('extensive', 'exhaustive', 2); SELECT levenshtein_less_equal('extensive', 'exhaustive', 4); +SELECT levenshtein_less_equal('aaa', 'aaaaa', 1073741824, 0, 1073741824, 10); SELECT metaphone('GUMBO', 4); diff --git a/src/backend/utils/adt/levenshtein.c b/src/backend/utils/adt/levenshtein.c index 5b3d84029f6..9b676165a70 100644 --- a/src/backend/utils/adt/levenshtein.c +++ b/src/backend/utils/adt/levenshtein.c @@ -9,7 +9,7 @@ * Levenshtein distance with custom costings, and (2) Levenshtein distance with * custom costings and a "max" value above which exact distances are not * interesting. Before the inclusion, we rely on the presence of the inline - * function rest_of_char_same(). + * functions rest_of_char_same() and levenshtein_result(). * * Written based on a description of the algorithm by Michael Gilleland found * at http://www.merriampark.com/ld.htm. Also looked at levenshtein.c in the @@ -78,13 +78,16 @@ varstr_levenshtein(const char *source, int slen, { int m, n; - int *prev; - int *curr; + int64 *prev; + int64 *curr; int *s_char_len = NULL; int j; const char *y; const char *send = source + slen; const char *tend = target + tlen; + int64 ins_c_64 = ins_c; + int64 del_c_64 = del_c; + int64 sub_c_64 = sub_c; /* * For varstr_levenshtein_less_equal, we have real variables called @@ -115,9 +118,9 @@ varstr_levenshtein(const char *source, int slen, * into an empty s with m deletions. */ if (!m) - return n * ins_c; + return levenshtein_result(n * ins_c_64); if (!n) - return m * del_c; + return levenshtein_result(m * del_c_64); /* * For security concerns, restrict excessive CPU+RAM usage. (This @@ -147,20 +150,20 @@ varstr_levenshtein(const char *source, int slen, */ if (max_d >= 0) { - int min_theo_d; /* Theoretical minimum distance. */ - int max_theo_d; /* Theoretical maximum distance. */ + int64 min_theo_d; /* Theoretical minimum distance. */ + int64 max_theo_d; /* Theoretical maximum distance. */ int net_inserts = n - m; min_theo_d = net_inserts < 0 ? - -net_inserts * del_c : net_inserts * ins_c; + -net_inserts * del_c_64 : net_inserts * ins_c_64; if (min_theo_d > max_d) - return max_d + 1; - if (ins_c + del_c < sub_c) - sub_c = ins_c + del_c; - max_theo_d = min_theo_d + sub_c * Min(m, n); + return levenshtein_result((int64) max_d + 1); + if (ins_c_64 + del_c_64 < sub_c_64) + sub_c_64 = ins_c_64 + del_c_64; + max_theo_d = min_theo_d + sub_c_64 * Min(m, n); if (max_d >= max_theo_d) max_d = -1; - else if (ins_c + del_c > 0) + else if (ins_c_64 + del_c_64 > 0) { /* * Figure out how much of the first row of the notional matrix we @@ -174,12 +177,12 @@ varstr_levenshtein(const char *source, int slen, * column n - m. If we do start further right, the best-case * total cost increases by ins_c + del_c for each move right. */ - int slack_d = max_d - min_theo_d; + int64 slack_d = max_d - min_theo_d; int best_column = net_inserts < 0 ? -net_inserts : 0; + int64 tmp; - stop_column = best_column + (slack_d / (ins_c + del_c)) + 1; - if (stop_column > m) - stop_column = m + 1; + tmp = best_column + (slack_d / (ins_c_64 + del_c_64)) + 1; + stop_column = Min(tmp, m + 1); } } #endif @@ -211,7 +214,7 @@ varstr_levenshtein(const char *source, int slen, ++n; /* Previous and current rows of notional array. */ - prev = (int *) palloc(2 * m * sizeof(int)); + prev = (int64 *) palloc(2 * m * sizeof(int64)); curr = prev + m; /* @@ -219,12 +222,12 @@ varstr_levenshtein(const char *source, int slen, * t, we must perform i deletions. */ for (int i = START_COLUMN; i < STOP_COLUMN; i++) - prev[i] = i * del_c; + prev[i] = i * del_c_64; /* Loop through rows of the notional array */ for (y = target, j = 1; j < n; j++) { - int *temp; + int64 *temp; const char *x = source; int y_char_len = n != tlen + 1 ? pg_mblen_range(y, tend) : 1; int i; @@ -239,7 +242,7 @@ varstr_levenshtein(const char *source, int slen, */ if (stop_column < m) { - prev[stop_column] = max_d + 1; + prev[stop_column] = (int64) max_d + 1; ++stop_column; } @@ -251,13 +254,13 @@ varstr_levenshtein(const char *source, int slen, */ if (start_column == 0) { - curr[0] = j * ins_c; + curr[0] = j * ins_c_64; i = 1; } else i = start_column; #else - curr[0] = j * ins_c; + curr[0] = j * ins_c_64; i = 1; #endif @@ -272,9 +275,9 @@ varstr_levenshtein(const char *source, int slen, { for (; i < STOP_COLUMN; i++) { - int ins; - int del; - int sub; + int64 ins; + int64 del; + int64 sub; int x_char_len = s_char_len[i - 1]; /* @@ -286,14 +289,14 @@ varstr_levenshtein(const char *source, int slen, * get past that test, then we compare the lengths and the * remaining bytes. */ - ins = prev[i] + ins_c; - del = curr[i - 1] + del_c; + ins = prev[i] + ins_c_64; + del = curr[i - 1] + del_c_64; if (x[x_char_len - 1] == y[y_char_len - 1] && x_char_len == y_char_len && (x_char_len == 1 || rest_of_char_same(x, y, x_char_len))) sub = prev[i - 1]; else - sub = prev[i - 1] + sub_c; + sub = prev[i - 1] + sub_c_64; /* Take the one with minimum cost. */ curr[i] = Min(ins, del); @@ -307,14 +310,14 @@ varstr_levenshtein(const char *source, int slen, { for (; i < STOP_COLUMN; i++) { - int ins; - int del; - int sub; + int64 ins; + int64 del; + int64 sub; /* Calculate costs for insertion, deletion, and substitution. */ - ins = prev[i] + ins_c; - del = curr[i - 1] + del_c; - sub = prev[i - 1] + ((*x == *y) ? 0 : sub_c); + ins = prev[i] + ins_c_64; + del = curr[i - 1] + del_c_64; + sub = prev[i - 1] + ((*x == *y) ? 0 : sub_c_64); /* Take the one with minimum cost. */ curr[i] = Min(ins, del); @@ -360,8 +363,8 @@ varstr_levenshtein(const char *source, int slen, int ii = stop_column - 1; int net_inserts = ii - zp; - if (prev[ii] + (net_inserts > 0 ? net_inserts * ins_c : - -net_inserts * del_c) <= max_d) + if (prev[ii] + (net_inserts > 0 ? net_inserts * ins_c_64 : + -net_inserts * del_c_64) <= max_d) break; stop_column--; } @@ -372,8 +375,8 @@ varstr_levenshtein(const char *source, int slen, int net_inserts = start_column - zp; if (prev[start_column] + - (net_inserts > 0 ? net_inserts * ins_c : - -net_inserts * del_c) <= max_d) + (net_inserts > 0 ? net_inserts * ins_c_64 : + -net_inserts * del_c_64) <= max_d) break; /* @@ -381,8 +384,8 @@ varstr_levenshtein(const char *source, int slen, * there's nothing here that could confuse any future * iteration of the outer loop. */ - prev[start_column] = max_d + 1; - curr[start_column] = max_d + 1; + prev[start_column] = (int64) max_d + 1; + curr[start_column] = (int64) max_d + 1; if (start_column != 0) source += (s_char_len != NULL) ? s_char_len[start_column - 1] : 1; start_column++; @@ -390,7 +393,7 @@ varstr_levenshtein(const char *source, int slen, /* If they cross, we're going to exceed the bound. */ if (start_column >= stop_column) - return max_d + 1; + return levenshtein_result((int64) max_d + 1); } #endif } @@ -399,5 +402,5 @@ varstr_levenshtein(const char *source, int slen, * Because the final value was swapped from the previous row to the * current row, that's where we'll find it. */ - return prev[m - 1]; + return levenshtein_result(prev[m - 1]); } diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index e9548bed2ce..a986ac9222e 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -5306,6 +5306,20 @@ rest_of_char_same(const char *s1, const char *s2, int len) return true; } +/* + * Helper function for checking return value of Levenshtein distance functions. + * We calculate it as an int64, but the distance functions return an int32. + */ +static inline int +levenshtein_result(int64 res) +{ + if (unlikely(res < PG_INT32_MIN || res > PG_INT32_MAX)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("levenshtein distance out of range"))); + return res; +} + /* Expand each Levenshtein distance variant */ #include "levenshtein.c" #define LEVENSHTEIN_LESS_EQUAL From efdb260728c93f605f9ef7aaef56b013f6bb87b7 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 10 Aug 2026 06:38:05 -0700 Subject: [PATCH 342/481] Check for USAGE privilege on the subtype in CREATE TYPE AS RANGE. This omission allowed roles without USAGE on a type to create range types that depend on it, which could prevent the owner from changing the type later. Reported-by: Jingzhou Fu Author: Nathan Bossart Reviewed-by: Noah Misch Reviewed-by: Robert Haas Security: CVE-2026-6470 Backpatch-through: 14 --- doc/src/sgml/ref/create_type.sgml | 5 +++++ src/backend/commands/typecmds.c | 4 ++++ src/test/regress/expected/rangetypes.out | 15 +++++++++++++++ src/test/regress/sql/rangetypes.sql | 14 ++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml index 994dfc65268..6aa01eb0daa 100644 --- a/doc/src/sgml/ref/create_type.sgml +++ b/doc/src/sgml/ref/create_type.sgml @@ -186,6 +186,11 @@ CREATE TYPE name type name. Otherwise, the multirange type name is formed by appending a _multirange suffix to the range type name. + + + To be able to create a range type, you must have USAGE + privilege on the subtype. + diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index e9c3215ccec..1d74a6e9457 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -1521,6 +1521,10 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt) errmsg("range subtype cannot be %s", format_type_be(rangeSubtype)))); + aclresult = object_aclcheck(TypeRelationId, rangeSubtype, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error_type(aclresult, rangeSubtype); + /* Identify subopclass */ rangeSubOpclass = findRangeSubOpclass(rangeSubOpclassName, rangeSubtype); diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out index e062a4e5c2c..aecd12bd232 100644 --- a/src/test/regress/expected/rangetypes.out +++ b/src/test/regress/expected/rangetypes.out @@ -1601,6 +1601,21 @@ ERROR: range lower bound must be less than or equal to range upper bound LINE 1: select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)':... ^ set timezone to default; +-- CREATE TYPE AS RANGE checks for USAGE on subtype +CREATE ROLE regress_subtype; +CREATE TYPE mytype AS (a INT, b INT); +REVOKE USAGE ON TYPE mytype FROM PUBLIC; +SET ROLE regress_subtype; +CREATE TYPE myrange AS RANGE (subtype = mytype); +ERROR: permission denied for type mytype +RESET ROLE; +GRANT USAGE ON TYPE mytype TO regress_subtype; +SET ROLE regress_subtype; +CREATE TYPE myrange AS RANGE (subtype = mytype); +RESET ROLE; +DROP TYPE mytype CASCADE; +NOTICE: drop cascades to type myrange +DROP ROLE regress_subtype; -- -- Test user-defined range of floats -- (type float8range was already made in test_setup.sql) diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql index 5c4b0337b7a..7c917c60f46 100644 --- a/src/test/regress/sql/rangetypes.sql +++ b/src/test/regress/sql/rangetypes.sql @@ -444,6 +444,20 @@ select '[2010-01-01 01:00:00 -05, 2010-01-01 02:00:00 -08)'::tstzrange; select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)'::tstzrange; set timezone to default; +-- CREATE TYPE AS RANGE checks for USAGE on subtype +CREATE ROLE regress_subtype; +CREATE TYPE mytype AS (a INT, b INT); +REVOKE USAGE ON TYPE mytype FROM PUBLIC; +SET ROLE regress_subtype; +CREATE TYPE myrange AS RANGE (subtype = mytype); +RESET ROLE; +GRANT USAGE ON TYPE mytype TO regress_subtype; +SET ROLE regress_subtype; +CREATE TYPE myrange AS RANGE (subtype = mytype); +RESET ROLE; +DROP TYPE mytype CASCADE; +DROP ROLE regress_subtype; + -- -- Test user-defined range of floats -- (type float8range was already made in test_setup.sql) From 424fb7160bc51d55c4be2023d9238f2db8807b35 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 10 Aug 2026 06:38:06 -0700 Subject: [PATCH 343/481] Check for USAGE privilege on types used by stored expressions. This omission allowed roles without USAGE on a type to create stored expressions that depend on it, which could prevent the owner from changing the type later. The checks deliberately live in the command paths rather than the dependency-recording routines. Those routines also run whenever the server re-derives an existing expression, and re-checking there would break routine maintenance for an owner who has since lost USAGE on a type its objects already reference. (Checking in the dependency-recording routines would also require additional CommandCounterIncrement() calls to avoid spurious errors.) The addition of a parameter to AlterDomainAddConstraint() breaks ABI compatibility, but we are unaware of any impacted third-party code. Reported-by: Noah Misch Author: Nathan Bossart Reviewed-by: Noah Misch Reviewed-by: Tom Lane Reviewed-by: Robert Haas Security: CVE-2026-6470 Backpatch-through: 14 --- src/backend/catalog/dependency.c | 76 ++++++++++++++++++++++++ src/backend/catalog/heap.c | 22 +++++++ src/backend/catalog/index.c | 3 + src/backend/catalog/pg_attrdef.c | 3 + src/backend/catalog/pg_constraint.c | 3 + src/backend/catalog/pg_proc.c | 6 ++ src/backend/catalog/pg_publication.c | 4 ++ src/backend/catalog/pg_type.c | 6 ++ src/backend/commands/indexcmds.c | 16 +++++ src/backend/commands/policy.c | 8 +++ src/backend/commands/propgraphcmds.c | 7 +++ src/backend/commands/statscmds.c | 5 ++ src/backend/commands/tablecmds.c | 19 +++++- src/backend/commands/trigger.c | 5 ++ src/backend/commands/typecmds.c | 33 ++++++++-- src/backend/parser/parse_utilcmd.c | 10 ++++ src/backend/rewrite/rewriteDefine.c | 2 + src/backend/tcop/utility.c | 3 +- src/include/catalog/dependency.h | 4 ++ src/include/commands/typecmds.h | 3 +- src/test/regress/expected/privileges.out | 46 ++++++++++++++ src/test/regress/sql/privileges.sql | 43 ++++++++++++++ 22 files changed, 318 insertions(+), 9 deletions(-) diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index c8dd78341eb..026b743275f 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -1792,6 +1792,82 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender, free_object_addresses(context.addrs); } +/* + * We require USAGE on a type to store a dependency on it. This helper + * function does the appropriate privilege checks. + * + * NB: Other objects have privileges of their own, but recording those + * dependencies doesn't require holding them. For example, an expression may + * reference a function for which the user lacks EXECUTE. Instead, EXECUTE is + * checked when the function is executed. + */ +static void +check_usage_on_types(ObjectAddresses *addrs, Oid roleid) +{ + for (int i = 0; i < addrs->numrefs; i++) + { + ObjectAddress *ref = &addrs->refs[i]; + AclResult aclresult; + + if (ref->classId != TypeRelationId) + continue; + + /* we don't record dependencies on pinned types */ + if (IsPinnedObject(ref->classId, ref->objectId)) + continue; + + aclresult = object_aclcheck(ref->classId, ref->objectId, + roleid, ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error_type(aclresult, ref->objectId); + } +} + +/* + * CheckUsageOnTypesInExpr - require USAGE on all types named by an expression + * + * rtable is the rangetable for interpreting Vars (or NIL if none are + * expected). roleid is the role whose USAGE is required. + */ +void +CheckUsageOnTypesInExpr(Node *expr, List *rtable, Oid roleid) +{ + ObjectAddresses *addrs = new_object_addresses(); + + collectDependenciesOfExpr(addrs, expr, rtable); + eliminate_duplicate_dependencies(addrs); + check_usage_on_types(addrs, roleid); + free_object_addresses(addrs); +} + +/* + * CheckUsageOnTypesInSingleRelExpr - as above, for a single-rel expression + * + * Like recordDependencyOnSingleRelExpr(), this handles expressions whose Vars + * all refer to one relation. roleid is the role whose USAGE is required. + */ +void +CheckUsageOnTypesInSingleRelExpr(Node *expr, Oid relId, Oid roleid) +{ + find_expr_references_context context; + RangeTblEntry rte = {0}; + + context.addrs = new_object_addresses(); + + /* We gin up a rather bogus rangetable list to handle Vars */ + rte.type = T_RangeTblEntry; + rte.rtekind = RTE_RELATION; + rte.relid = relId; + rte.relkind = RELKIND_RELATION; + rte.rellockmode = AccessShareLock; + context.rtables = list_make1(list_make1(&rte)); + + find_expr_references_walker(expr, &context); + eliminate_duplicate_dependencies(context.addrs); + check_usage_on_types(context.addrs, roleid); + free_object_addresses(context.addrs); +} + /* * Recursively search an expression tree for object references. * diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 88087654de9..0fbbf8bcf56 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -2162,6 +2162,9 @@ SetAttrMissing(Oid relid, char *attname, char *value) * in the pg_class entry for the relation. * * The OID of the new constraint is returned. + * + * NB: Caller is responsible for ensuring the user has USAGE on all types expr + * depends on. */ static Oid StoreRelCheck(Relation rel, const char *ccname, Node *expr, @@ -2477,6 +2480,13 @@ AddRelationNewConstraints(Relation rel, castNode(Const, expr)->constisnull)) continue; + /* + * The below call to StoreAttrDefault() adds the dependencies on + * types. We are responsible for checking USAGE. + */ + if (!is_internal) + CheckUsageOnTypesInSingleRelExpr(expr, RelationGetRelid(rel), GetUserId()); + defOid = StoreAttrDefault(rel, colDef->attnum, expr, is_internal); cooked = palloc_object(CookedConstraint); @@ -2517,6 +2527,14 @@ AddRelationNewConstraints(Relation rel, */ expr = cookConstraint(pstate, cdef->raw_expr, RelationGetRelationName(rel)); + + /* + * The below call to StoreRelCheck() calls + * CreateConstraintEntry(), which adds the dependencies on + * types. We are responsible for checking USAGE. + */ + if (!is_internal) + CheckUsageOnTypesInSingleRelExpr(expr, RelationGetRelid(rel), GetUserId()); } else { @@ -4020,12 +4038,16 @@ StorePartitionKey(Relation rel, * columns, i.e. they become internally dependent on the whole table. */ if (partexprs) + { + CheckUsageOnTypesInSingleRelExpr((Node *) partexprs, RelationGetRelid(rel), + GetUserId()); recordDependencyOnSingleRelExpr(&myself, (Node *) partexprs, RelationGetRelid(rel), DEPENDENCY_NORMAL, DEPENDENCY_INTERNAL, true /* reverse the self-deps */ ); + } /* * We must invalidate the relcache so that the next diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 86f22570b45..5d94dbb8334 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -728,6 +728,9 @@ UpdateIndexRelation(Oid indexoid, * constraintId: if not NULL, receives OID of created constraint * * Returns the OID of the created index. + * + * NB: Caller is responsible for ensuring the user has USAGE on all types + * indexInfo->ii_{Expressions,Predicate} depend on. */ Oid index_create(Relation heapRelation, diff --git a/src/backend/catalog/pg_attrdef.c b/src/backend/catalog/pg_attrdef.c index 24815090d3d..60bd7a40759 100644 --- a/src/backend/catalog/pg_attrdef.c +++ b/src/backend/catalog/pg_attrdef.c @@ -32,6 +32,9 @@ * Store a default expression for column attnum of relation rel. * * Returns the OID of the new pg_attrdef tuple. + * + * NB: Caller is responsible for ensuring the user has USAGE on all types expr + * depends on. */ Oid StoreAttrDefault(Relation rel, AttrNumber attnum, diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index b12765ae691..8aba9cbbc57 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -46,6 +46,9 @@ * from the constraint to the things it depends on. * * The new constraint's OID is returned. + * + * NB: Caller is responsible for ensuring the user has USAGE on all types + * conExpr depends on. */ Oid CreateConstraintEntry(const char *constraintName, diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 5df4b3f7a91..2e854eb08e9 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -662,11 +662,17 @@ ProcedureCreate(const char *procedureName, /* dependencies appearing in new-style SQL routine body */ if (languageObjectId == SQLlanguageId && prosqlbody) + { + CheckUsageOnTypesInExpr(prosqlbody, NIL, GetUserId()); collectDependenciesOfExpr(addrs, prosqlbody, NIL); + } /* dependency on parameter default expressions */ if (parameterDefaults) + { + CheckUsageOnTypesInExpr((Node *) parameterDefaults, NIL, GetUserId()); collectDependenciesOfExpr(addrs, (Node *) parameterDefaults, NIL); + } /* * Now that we have all the normal dependencies, thumb through them and diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index e6ebc1e2627..b5843dd422c 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -32,6 +32,7 @@ #include "catalog/pg_type.h" #include "commands/publicationcmds.h" #include "funcapi.h" +#include "miscadmin.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/catcache.h" @@ -609,9 +610,12 @@ publication_add_relation(Oid pubid, PublicationRelInfo *pri, /* Add dependency on the objects mentioned in the qualifications */ if (pri->whereClause) + { + CheckUsageOnTypesInSingleRelExpr(pri->whereClause, relid, GetUserId()); recordDependencyOnSingleRelExpr(&myself, pri->whereClause, relid, DEPENDENCY_NORMAL, DEPENDENCY_NORMAL, false); + } /* Add dependency on the columns, if any are listed */ i = -1; diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index fc369c35aa6..a3f5c56280c 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -189,6 +189,9 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) * Returns the ObjectAddress assigned to the new type. * If newTypeOid is zero (the normal case), a new OID is created; * otherwise we use exactly that OID. + * + * NB: Caller is responsible for ensuring the user has USAGE + * on all types defaultTypeBin depends on. * ---------------------------------------------------------------- */ ObjectAddress @@ -550,6 +553,9 @@ TypeCreate(Oid newTypeOid, * type already belongs to the current extension. That's the behavior we * want when replacing a shell type, which is the only case where both flags * are true. + * + * NB: Caller is responsible for ensuring the user has USAGE on all types + * defaultExpr depends on. */ void GenerateTypeDependencies(HeapTuple typeTuple, diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 2a73a55d1fc..c09852c9528 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -948,6 +948,22 @@ DefineIndex(ParseState *pstate, root_save_userid, root_save_sec_context, &root_save_nestlevel); + /* + * The below call to index_create() creates the dependencies on types. We + * are responsible for checking USAGE. + */ + if (check_rights) + { + if (indexInfo->ii_Expressions) + CheckUsageOnTypesInSingleRelExpr((Node *) indexInfo->ii_Expressions, + tableId, + root_save_userid); + if (indexInfo->ii_Predicate) + CheckUsageOnTypesInSingleRelExpr((Node *) indexInfo->ii_Predicate, + tableId, + root_save_userid); + } + /* * Extra checks when creating a PRIMARY KEY index. */ diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c index 21b8eebe32d..2d112b523e5 100644 --- a/src/backend/commands/policy.c +++ b/src/backend/commands/policy.c @@ -724,9 +724,12 @@ CreatePolicy(CreatePolicyStmt *stmt) recordDependencyOn(&myself, &target, DEPENDENCY_AUTO); + CheckUsageOnTypesInExpr(qual, qual_pstate->p_rtable, GetUserId()); recordDependencyOnExpr(&myself, qual, qual_pstate->p_rtable, DEPENDENCY_NORMAL); + CheckUsageOnTypesInExpr(with_check_qual, with_check_pstate->p_rtable, + GetUserId()); recordDependencyOnExpr(&myself, with_check_qual, with_check_pstate->p_rtable, DEPENDENCY_NORMAL); @@ -1055,8 +1058,13 @@ AlterPolicy(AlterPolicyStmt *stmt) recordDependencyOn(&myself, &target, DEPENDENCY_AUTO); + if (stmt->qual) + CheckUsageOnTypesInExpr(qual, qual_parse_rtable, GetUserId()); recordDependencyOnExpr(&myself, qual, qual_parse_rtable, DEPENDENCY_NORMAL); + if (stmt->with_check) + CheckUsageOnTypesInExpr(with_check_qual, with_check_parse_rtable, + GetUserId()); recordDependencyOnExpr(&myself, with_check_qual, with_check_parse_rtable, DEPENDENCY_NORMAL); diff --git a/src/backend/commands/propgraphcmds.c b/src/backend/commands/propgraphcmds.c index 9c9f4f2b299..076005226f2 100644 --- a/src/backend/commands/propgraphcmds.c +++ b/src/backend/commands/propgraphcmds.c @@ -31,12 +31,14 @@ #include "commands/defrem.h" #include "commands/propgraphcmds.h" #include "commands/tablecmds.h" +#include "miscadmin.h" #include "nodes/nodeFuncs.h" #include "parser/parse_coerce.h" #include "parser/parse_collate.h" #include "parser/parse_oper.h" #include "parser/parse_relation.h" #include "parser/parse_target.h" +#include "utils/acl.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -959,6 +961,7 @@ insert_property_record(Oid graphid, Oid ellabeloid, Oid pgerelid, const char *pr HeapTuple tup; ObjectAddress myself; ObjectAddress referenced; + AclResult aclresult; rel = table_open(PropgraphPropertyRelationId, RowExclusiveLock); @@ -979,6 +982,9 @@ insert_property_record(Oid graphid, Oid ellabeloid, Oid pgerelid, const char *pr ObjectAddressSet(referenced, RelationRelationId, graphid); recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); + aclresult = object_aclcheck(TypeRelationId, exprtypid, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error_type(aclresult, exprtypid); ObjectAddressSet(referenced, TypeRelationId, exprtypid); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); if (OidIsValid(exprcollation) && exprcollation != DEFAULT_COLLATION_OID) @@ -1063,6 +1069,7 @@ insert_property_record(Oid graphid, Oid ellabeloid, Oid pgerelid, const char *pr ObjectAddressSet(referenced, PropgraphElementLabelRelationId, ellabeloid); recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); + CheckUsageOnTypesInSingleRelExpr((Node *) expr, pgerelid, GetUserId()); recordDependencyOnSingleRelExpr(&myself, (Node *) copyObject(expr), pgerelid, DEPENDENCY_NORMAL, DEPENDENCY_NORMAL, false); table_close(rel, NoLock); diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c index 8e377ca445d..c5c1bf0bd10 100644 --- a/src/backend/commands/statscmds.c +++ b/src/backend/commands/statscmds.c @@ -613,11 +613,16 @@ CreateStatistics(List *relids, CreateStatsStmt *stmt, bool check_rights) * just like we do for index expressions. */ if (stxexprs) + { + if (check_rights) + CheckUsageOnTypesInSingleRelExpr((Node *) stxexprs, relid, GetUserId()); + recordDependencyOnSingleRelExpr(&myself, (Node *) stxexprs, relid, DEPENDENCY_NORMAL, DEPENDENCY_AUTO, false); + } /* * Also add dependencies on namespace and owner. These are required diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index f8fedc2b249..5d8963be108 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -1024,6 +1024,14 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, stmt->partbound != NULL, &old_constraints, &old_notnulls); + /* + * NB: The defaults and constraints we just inherited are already cooked, + * so they don't get the USAGE checks that AddRelationNewConstraints() + * applies to raw ones. That's intentional: the parent's own catalog + * entries already depend on those types, so copying them pins nothing + * new, and creating a child requires owning the parent, anyway. + */ + /* * Create a tuple descriptor from the relation schema. Note that this * deals with column names, types, and in-descriptor NOT NULL flags, but @@ -5556,7 +5564,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, address = AlterDomainAddConstraint(((AlterDomainStmt *) cmd->def)->typeName, ((AlterDomainStmt *) cmd->def)->def, - NULL); + NULL, true); break; case AT_ReAddComment: /* Re-add existing comment */ address = CommentObject((CommentStmt *) cmd->def); @@ -8308,7 +8316,14 @@ ATExecCookedColumnDefault(Relation rel, AttrNumber attnum, { ObjectAddress address; - /* We assume no checking is required */ + /* + * This is used for a cooked default copied by CREATE TABLE ... LIKE, + * which adds new type dependencies. Such a default doesn't go through + * AddRelationNewConstraints(), and StoreAttrDefault() leaves the + * privilege checks to its caller, so we must check for USAGE on the types + * here. + */ + CheckUsageOnTypesInSingleRelExpr(newDefault, RelationGetRelid(rel), GetUserId()); /* * Remove any old default for the column. We use RESTRICT here for diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index e980f847ec3..8444332d44f 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -1132,8 +1132,13 @@ CreateTriggerFiringOn(const CreateTrigStmt *stmt, const char *queryString, * expression (eg, functions, as well as any columns used). */ if (whenRtable != NIL) + { + if (!isInternal) + CheckUsageOnTypesInExpr(whenClause, whenRtable, GetUserId()); + recordDependencyOnExpr(&myself, whenClause, whenRtable, DEPENDENCY_NORMAL); + } /* Post creation hook for new trigger */ InvokeObjectPostCreateHookArg(TriggerRelationId, trigoid, 0, diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 1d74a6e9457..b19da409597 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -135,7 +135,8 @@ static void checkEnumOwner(HeapTuple tup); static char *domainAddCheckConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, int typMod, Constraint *constr, - const char *domainName, ObjectAddress *constrAddr); + const char *domainName, ObjectAddress *constrAddr, + bool is_readd); static Node *replace_domain_constraint_value(ParseState *pstate, ColumnRef *cref); static void domainAddNotNullConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, @@ -1050,6 +1051,13 @@ DefineDomain(ParseState *pstate, CreateDomainStmt *stmt) } } + /* + * The below call to TypeCreate() calls GenerateTypeDependencies(), which + * adds the dependencies on types. We are responsible for checking USAGE. + */ + if (defaultValueBin) + CheckUsageOnTypesInExpr(stringToNode(defaultValueBin), NIL, GetUserId()); + /* Allocate OID for array type */ domainArrayOid = AssignTypeArrayOid(); @@ -1147,7 +1155,7 @@ DefineDomain(ParseState *pstate, CreateDomainStmt *stmt) case CONSTR_CHECK: domainAddCheckConstraint(address.objectId, domainNamespace, basetypeoid, basetypeMod, - constr, domainName, NULL); + constr, domainName, NULL, false); break; case CONSTR_NOTNULL: @@ -2713,6 +2721,12 @@ AlterDomainDefault(List *names, Node *defaultRaw) } else { + /* + * The below call to GenerateTypeDependencies() creates the + * dependencies on types. We are responsible for checking USAGE. + */ + CheckUsageOnTypesInExpr(defaultExpr, NIL, GetUserId()); + /* * Expression must be stored as a nodeToString result, but we also * require a valid textual representation (mainly to make life @@ -2969,7 +2983,7 @@ AlterDomainDropConstraint(List *names, const char *constrName, */ ObjectAddress AlterDomainAddConstraint(List *names, Node *newConstraint, - ObjectAddress *constrAddr) + ObjectAddress *constrAddr, bool is_readd) { TypeName *typename; Oid domainoid; @@ -3013,7 +3027,8 @@ AlterDomainAddConstraint(List *names, Node *newConstraint, ccbin = domainAddCheckConstraint(domainoid, typTup->typnamespace, typTup->typbasetype, typTup->typtypmod, - constr, NameStr(typTup->typname), constrAddr); + constr, NameStr(typTup->typname), constrAddr, + is_readd); /* @@ -3549,7 +3564,8 @@ checkDomainOwner(HeapTuple tup) static char * domainAddCheckConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, int typMod, Constraint *constr, - const char *domainName, ObjectAddress *constrAddr) + const char *domainName, ObjectAddress *constrAddr, + bool is_readd) { Node *expr; char *ccbin; @@ -3612,6 +3628,13 @@ domainAddCheckConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, */ assign_expr_collations(pstate, expr); + /* + * The below call to CreateConstraintEntry() creates the dependencies on + * types. We are responsible for checking USAGE. + */ + if (!is_readd) + CheckUsageOnTypesInExpr(expr, NIL, GetUserId()); + /* * Domains don't allow variables (this is probably dead code now that * add_missing_from is history, but let's be sure). diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index a049cc67ed6..a17fe73cc35 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -1484,6 +1484,16 @@ expandTableLikeClause(RangeVar *heapRel, TableLikeClause *table_like_clause) ccname, RelationGetRelationName(relation)))); + /* + * Copying a CHECK constraint adds new references. Since the + * constraint arrives pre-cooked, it bypasses the checks in + * AddRelationNewConstraints(), so we must check for USAGE on + * types here. + */ + CheckUsageOnTypesInSingleRelExpr(stringToNode(ccbin), + RelationGetRelid(relation), + GetUserId()); + n = makeNode(Constraint); n->contype = CONSTR_CHECK; n->conname = pstrdup(ccname); diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 6361eeea20f..685a1fc4f58 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -161,6 +161,7 @@ InsertRule(const char *rulname, /* * Also install dependencies on objects referenced in action and qual. */ + CheckUsageOnTypesInExpr((Node *) action, NIL, GetUserId()); recordDependencyOnExpr(&myself, (Node *) action, NIL, DEPENDENCY_NORMAL); @@ -170,6 +171,7 @@ InsertRule(const char *rulname, Query *qry = linitial_node(Query, action); qry = getInsertSelectQuery(qry, NULL); + CheckUsageOnTypesInExpr(event_qual, qry->rtable, GetUserId()); recordDependencyOnExpr(&myself, event_qual, qry->rtable, DEPENDENCY_NORMAL); } diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 5f204addcd4..4d33fcb5e9d 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1370,7 +1370,8 @@ ProcessUtilitySlow(ParseState *pstate, address = AlterDomainAddConstraint(stmt->typeName, stmt->def, - &secondaryObject); + &secondaryObject, + false); break; case AD_DropConstraint: address = diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index 2f3c1eae3c7..214ef1e7e2d 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -125,6 +125,10 @@ extern void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, DependencyType self_behavior, bool reverse_self); +extern void CheckUsageOnTypesInExpr(Node *expr, List *rtable, Oid roleid); + +extern void CheckUsageOnTypesInSingleRelExpr(Node *expr, Oid relId, Oid roleid); + extern bool find_temp_object(const ObjectAddresses *addrs, bool local_temp_okay, ObjectAddress *foundobj); diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h index f0c5c111326..2112b4addd2 100644 --- a/src/include/commands/typecmds.h +++ b/src/include/commands/typecmds.h @@ -35,7 +35,8 @@ extern Oid AssignTypeMultirangeArrayOid(void); extern ObjectAddress AlterDomainDefault(List *names, Node *defaultRaw); extern ObjectAddress AlterDomainNotNull(List *names, bool notNull); extern ObjectAddress AlterDomainAddConstraint(List *names, Node *newConstraint, - ObjectAddress *constrAddr); + ObjectAddress *constrAddr, + bool is_readd); extern ObjectAddress AlterDomainValidateConstraint(List *names, const char *constrName); extern ObjectAddress AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior behavior, bool missing_ok); diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index 5e3c9510490..3e5cc81f0eb 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -1438,10 +1438,14 @@ CREATE CAST (priv_testdomain1 AS priv_testdomain3a) WITH FUNCTION castfunc(int); ERROR: permission denied for type priv_testdomain1 DROP FUNCTION castfunc(int) CASCADE; DROP DOMAIN priv_testdomain3a; +CREATE DOMAIN priv_testdomain4a AS int CHECK (VALUE > ('(0,1)'::priv_testtype1).a); +ERROR: permission denied for type priv_testtype1 CREATE FUNCTION priv_testfunc5a(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; ERROR: permission denied for type priv_testdomain1 CREATE FUNCTION priv_testfunc6a(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$; ERROR: permission denied for type priv_testdomain1 +CREATE FUNCTION priv_testfunc7a(a int DEFAULT ('(0,1)'::priv_testtype1).a) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; +ERROR: permission denied for type priv_testtype1 CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = priv_testdomain1, RIGHTARG = priv_testdomain1); ERROR: permission denied for type priv_testdomain1 CREATE TABLE test5a (a int, b priv_testdomain1); @@ -1455,6 +1459,8 @@ ALTER TABLE test9a ADD COLUMN c priv_testdomain1; ERROR: permission denied for type priv_testdomain1 ALTER TABLE test9a ALTER COLUMN b TYPE priv_testdomain1; ERROR: permission denied for type priv_testdomain1 +CREATE INDEX ON test9a ((a::priv_testdomain1)); +ERROR: permission denied for type public.priv_testdomain1 CREATE TYPE test7a AS (a int, b priv_testdomain1); ERROR: permission denied for type priv_testdomain1 CREATE TYPE test8a AS (a int, b int); @@ -1462,10 +1468,22 @@ ALTER TYPE test8a ADD ATTRIBUTE c priv_testdomain1; ERROR: permission denied for type priv_testdomain1 ALTER TYPE test8a ALTER ATTRIBUTE b TYPE priv_testdomain1; ERROR: permission denied for type priv_testdomain1 +CREATE DOMAIN priv_testdomain5a AS test8a CHECK ((VALUE).a > 0 AND ('(0,1)'::priv_testtype1).a >= 0); +ERROR: permission denied for type priv_testtype1 CREATE TABLE test11a AS (SELECT 1::priv_testdomain1 AS a); ERROR: permission denied for type priv_testdomain1 +CREATE VIEW test16a AS SELECT ('(0,1)'::priv_testtype1).a; +ERROR: permission denied for type priv_testtype1 +CREATE TABLE test17a (a int) PARTITION BY RANGE ((a + ('(0,1)'::priv_testtype1).a)); +ERROR: permission denied for type priv_testtype1 +CREATE POLICY priv_testpolicy1a ON test9a USING (('(0,1)'::priv_testtype1).a > 0); +ERROR: permission denied for type priv_testtype1 REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC; ERROR: permission denied for type priv_testtype1 +CREATE TABLE test12 (c int DEFAULT 0 CHECK (c > 0 AND '(0,1)'::priv_testtype1 IS NOT NULL)); +ERROR: permission denied for type priv_testtype1 +CREATE TABLE test13 (c int DEFAULT ('(0,1)'::priv_testtype1).a); +ERROR: permission denied for type priv_testtype1 SET SESSION AUTHORIZATION regress_priv_user2; -- commands that should succeed CREATE AGGREGATE priv_testagg1b(priv_testdomain1) (sfunc = int4_sum, stype = bigint); @@ -1474,8 +1492,10 @@ CREATE DOMAIN priv_testdomain3b AS int; CREATE FUNCTION castfunc(int) RETURNS priv_testdomain3b AS $$ SELECT $1::priv_testdomain3b $$ LANGUAGE SQL; CREATE CAST (priv_testdomain1 AS priv_testdomain3b) WITH FUNCTION castfunc(int); WARNING: cast will be ignored because the source data type is a domain +CREATE DOMAIN priv_testdomain4b AS int CHECK (VALUE > ('(0,1)'::priv_testtype1).a); CREATE FUNCTION priv_testfunc5b(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; CREATE FUNCTION priv_testfunc6b(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$; +CREATE FUNCTION priv_testfunc7b(a int DEFAULT ('(0,1)'::priv_testtype1).a) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; CREATE OPERATOR !! (PROCEDURE = priv_testfunc5b, RIGHTARG = priv_testdomain1); CREATE TABLE test5b (a int, b priv_testdomain1); CREATE TABLE test6b OF priv_testtype1; @@ -1483,19 +1503,41 @@ CREATE TABLE test10b (a int[], b priv_testtype1[]); CREATE TABLE test9b (a int, b int); ALTER TABLE test9b ADD COLUMN c priv_testdomain1; ALTER TABLE test9b ALTER COLUMN b TYPE priv_testdomain1; +CREATE INDEX ON test9b ((a::priv_testdomain1)); CREATE TYPE test7b AS (a int, b priv_testdomain1); CREATE TYPE test8b AS (a int, b int); ALTER TYPE test8b ADD ATTRIBUTE c priv_testdomain1; ALTER TYPE test8b ALTER ATTRIBUTE b TYPE priv_testdomain1; +CREATE DOMAIN priv_testdomain5b AS test8b CHECK ((VALUE).a > 0 AND ('(0,1)'::priv_testtype1).a >= 0); CREATE TABLE test11b AS (SELECT 1::priv_testdomain1 AS a); +CREATE VIEW test16b AS SELECT ('(0,1)'::priv_testtype1).a; +CREATE TABLE test17b (a int) PARTITION BY RANGE ((a + ('(0,1)'::priv_testtype1).a)); +CREATE POLICY priv_testpolicy1b ON test9b USING (('(0,1)'::priv_testtype1).a > 0); REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC; WARNING: no privileges could be revoked for "priv_testtype1" +CREATE TABLE test12 (c int DEFAULT 0 CHECK (c > 0 AND '(0,1)'::priv_testtype1 IS NOT NULL)); +CREATE TABLE test13 (c int DEFAULT ('(0,1)'::priv_testtype1).a); +-- new stored expressions require USAGE on types, rebuilds do not +\c - +REVOKE USAGE ON TYPE priv_testtype1 FROM regress_priv_user2; +SET SESSION AUTHORIZATION regress_priv_user2; +ALTER TABLE test12 ALTER COLUMN c TYPE bigint; +ALTER TYPE test8b ALTER ATTRIBUTE a TYPE bigint CASCADE; +ALTER TABLE test12 ALTER COLUMN c SET DEFAULT ('(0,1)'::priv_testtype1).a; +ERROR: permission denied for type priv_testtype1 +CREATE TABLE test14 (LIKE test12 INCLUDING CONSTRAINTS); +ERROR: permission denied for type priv_testtype1 +CREATE TABLE test15 (LIKE test13 INCLUDING DEFAULTS); +ERROR: permission denied for type priv_testtype1 \c - DROP AGGREGATE priv_testagg1b(priv_testdomain1); DROP DOMAIN priv_testdomain2b; +DROP DOMAIN priv_testdomain4b; +DROP DOMAIN priv_testdomain5b; DROP OPERATOR !! (NONE, priv_testdomain1); DROP FUNCTION priv_testfunc5b(a priv_testdomain1); DROP FUNCTION priv_testfunc6b(b int); +DROP FUNCTION priv_testfunc7b(a int); DROP TABLE test5b; DROP TABLE test6b; DROP TABLE test9b; @@ -1505,7 +1547,11 @@ DROP TYPE test8b; DROP CAST (priv_testdomain1 AS priv_testdomain3b); DROP FUNCTION castfunc(int) CASCADE; DROP DOMAIN priv_testdomain3b; +DROP VIEW test16b; DROP TABLE test11b; +DROP TABLE test17b; +DROP TABLE test12; +DROP TABLE test13; DROP TYPE priv_testtype1; -- ok DROP DOMAIN priv_testdomain1; -- ok -- truncate diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index d3e87fa617f..79322165655 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -994,8 +994,11 @@ CREATE CAST (priv_testdomain1 AS priv_testdomain3a) WITH FUNCTION castfunc(int); DROP FUNCTION castfunc(int) CASCADE; DROP DOMAIN priv_testdomain3a; +CREATE DOMAIN priv_testdomain4a AS int CHECK (VALUE > ('(0,1)'::priv_testtype1).a); + CREATE FUNCTION priv_testfunc5a(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; CREATE FUNCTION priv_testfunc6a(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$; +CREATE FUNCTION priv_testfunc7a(a int DEFAULT ('(0,1)'::priv_testtype1).a) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = priv_testdomain1, RIGHTARG = priv_testdomain1); @@ -1006,6 +1009,7 @@ CREATE TABLE test10a (a int[], b priv_testtype1[]); CREATE TABLE test9a (a int, b int); ALTER TABLE test9a ADD COLUMN c priv_testdomain1; ALTER TABLE test9a ALTER COLUMN b TYPE priv_testdomain1; +CREATE INDEX ON test9a ((a::priv_testdomain1)); CREATE TYPE test7a AS (a int, b priv_testdomain1); @@ -1013,10 +1017,19 @@ CREATE TYPE test8a AS (a int, b int); ALTER TYPE test8a ADD ATTRIBUTE c priv_testdomain1; ALTER TYPE test8a ALTER ATTRIBUTE b TYPE priv_testdomain1; +CREATE DOMAIN priv_testdomain5a AS test8a CHECK ((VALUE).a > 0 AND ('(0,1)'::priv_testtype1).a >= 0); + CREATE TABLE test11a AS (SELECT 1::priv_testdomain1 AS a); +CREATE VIEW test16a AS SELECT ('(0,1)'::priv_testtype1).a; +CREATE TABLE test17a (a int) PARTITION BY RANGE ((a + ('(0,1)'::priv_testtype1).a)); +CREATE POLICY priv_testpolicy1a ON test9a USING (('(0,1)'::priv_testtype1).a > 0); + REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC; +CREATE TABLE test12 (c int DEFAULT 0 CHECK (c > 0 AND '(0,1)'::priv_testtype1 IS NOT NULL)); +CREATE TABLE test13 (c int DEFAULT ('(0,1)'::priv_testtype1).a); + SET SESSION AUTHORIZATION regress_priv_user2; -- commands that should succeed @@ -1029,8 +1042,11 @@ CREATE DOMAIN priv_testdomain3b AS int; CREATE FUNCTION castfunc(int) RETURNS priv_testdomain3b AS $$ SELECT $1::priv_testdomain3b $$ LANGUAGE SQL; CREATE CAST (priv_testdomain1 AS priv_testdomain3b) WITH FUNCTION castfunc(int); +CREATE DOMAIN priv_testdomain4b AS int CHECK (VALUE > ('(0,1)'::priv_testtype1).a); + CREATE FUNCTION priv_testfunc5b(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; CREATE FUNCTION priv_testfunc6b(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$; +CREATE FUNCTION priv_testfunc7b(a int DEFAULT ('(0,1)'::priv_testtype1).a) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; CREATE OPERATOR !! (PROCEDURE = priv_testfunc5b, RIGHTARG = priv_testdomain1); @@ -1041,6 +1057,7 @@ CREATE TABLE test10b (a int[], b priv_testtype1[]); CREATE TABLE test9b (a int, b int); ALTER TABLE test9b ADD COLUMN c priv_testdomain1; ALTER TABLE test9b ALTER COLUMN b TYPE priv_testdomain1; +CREATE INDEX ON test9b ((a::priv_testdomain1)); CREATE TYPE test7b AS (a int, b priv_testdomain1); @@ -1048,16 +1065,38 @@ CREATE TYPE test8b AS (a int, b int); ALTER TYPE test8b ADD ATTRIBUTE c priv_testdomain1; ALTER TYPE test8b ALTER ATTRIBUTE b TYPE priv_testdomain1; +CREATE DOMAIN priv_testdomain5b AS test8b CHECK ((VALUE).a > 0 AND ('(0,1)'::priv_testtype1).a >= 0); + CREATE TABLE test11b AS (SELECT 1::priv_testdomain1 AS a); +CREATE VIEW test16b AS SELECT ('(0,1)'::priv_testtype1).a; +CREATE TABLE test17b (a int) PARTITION BY RANGE ((a + ('(0,1)'::priv_testtype1).a)); +CREATE POLICY priv_testpolicy1b ON test9b USING (('(0,1)'::priv_testtype1).a > 0); + REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC; +CREATE TABLE test12 (c int DEFAULT 0 CHECK (c > 0 AND '(0,1)'::priv_testtype1 IS NOT NULL)); +CREATE TABLE test13 (c int DEFAULT ('(0,1)'::priv_testtype1).a); + +-- new stored expressions require USAGE on types, rebuilds do not +\c - +REVOKE USAGE ON TYPE priv_testtype1 FROM regress_priv_user2; +SET SESSION AUTHORIZATION regress_priv_user2; +ALTER TABLE test12 ALTER COLUMN c TYPE bigint; +ALTER TYPE test8b ALTER ATTRIBUTE a TYPE bigint CASCADE; +ALTER TABLE test12 ALTER COLUMN c SET DEFAULT ('(0,1)'::priv_testtype1).a; +CREATE TABLE test14 (LIKE test12 INCLUDING CONSTRAINTS); +CREATE TABLE test15 (LIKE test13 INCLUDING DEFAULTS); + \c - DROP AGGREGATE priv_testagg1b(priv_testdomain1); DROP DOMAIN priv_testdomain2b; +DROP DOMAIN priv_testdomain4b; +DROP DOMAIN priv_testdomain5b; DROP OPERATOR !! (NONE, priv_testdomain1); DROP FUNCTION priv_testfunc5b(a priv_testdomain1); DROP FUNCTION priv_testfunc6b(b int); +DROP FUNCTION priv_testfunc7b(a int); DROP TABLE test5b; DROP TABLE test6b; DROP TABLE test9b; @@ -1067,7 +1106,11 @@ DROP TYPE test8b; DROP CAST (priv_testdomain1 AS priv_testdomain3b); DROP FUNCTION castfunc(int) CASCADE; DROP DOMAIN priv_testdomain3b; +DROP VIEW test16b; DROP TABLE test11b; +DROP TABLE test17b; +DROP TABLE test12; +DROP TABLE test13; DROP TYPE priv_testtype1; -- ok DROP DOMAIN priv_testdomain1; -- ok From bb1bc525dc01985efeda58a3e613e381146df6a7 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 10 Aug 2026 06:38:06 -0700 Subject: [PATCH 344/481] Check for USAGE privilege on the composite type in ALTER TABLE OF. This omission allowed roles without USAGE on a type to create tables that depend on it, which could prevent the owner from changing the type later. Reported-by: Nathan Bossart Author: Nathan Bossart Reviewed-by: Robert Haas Security: CVE-2026-6470 Backpatch-through: 14 --- src/backend/commands/tablecmds.c | 5 +++++ src/test/regress/expected/privileges.out | 6 ++++++ src/test/regress/sql/privileges.sql | 5 +++++ 3 files changed, 16 insertions(+) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 5d8963be108..c1fbe356fc9 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -18903,6 +18903,7 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) ObjectAddress tableobj, typeobj; HeapTuple classtuple; + AclResult aclresult; /* Validate the type. */ typetuple = typenameType(NULL, ofTypename, NULL); @@ -18910,6 +18911,10 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) typeform = (Form_pg_type) GETSTRUCT(typetuple); typeid = typeform->oid; + aclresult = object_aclcheck(TypeRelationId, typeid, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error_type(aclresult, typeid); + /* Fail if the table has any inheritance parents. */ inheritsRelation = table_open(InheritsRelationId, AccessShareLock); ScanKeyInit(&key, diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index 3e5cc81f0eb..ca693308e79 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -1452,6 +1452,9 @@ CREATE TABLE test5a (a int, b priv_testdomain1); ERROR: permission denied for type priv_testdomain1 CREATE TABLE test6a OF priv_testtype1; ERROR: permission denied for type priv_testtype1 +CREATE TABLE test6a2 (a int, b text); +ALTER TABLE test6a2 OF priv_testtype1; +ERROR: permission denied for type priv_testtype1 CREATE TABLE test10a (a int[], b priv_testtype1[]); ERROR: permission denied for type priv_testtype1 CREATE TABLE test9a (a int, b int); @@ -1499,6 +1502,8 @@ CREATE FUNCTION priv_testfunc7b(a int DEFAULT ('(0,1)'::priv_testtype1).a) RETUR CREATE OPERATOR !! (PROCEDURE = priv_testfunc5b, RIGHTARG = priv_testdomain1); CREATE TABLE test5b (a int, b priv_testdomain1); CREATE TABLE test6b OF priv_testtype1; +CREATE TABLE test6b2 (a int, b text); +ALTER TABLE test6b2 OF priv_testtype1; CREATE TABLE test10b (a int[], b priv_testtype1[]); CREATE TABLE test9b (a int, b int); ALTER TABLE test9b ADD COLUMN c priv_testdomain1; @@ -1540,6 +1545,7 @@ DROP FUNCTION priv_testfunc6b(b int); DROP FUNCTION priv_testfunc7b(a int); DROP TABLE test5b; DROP TABLE test6b; +DROP TABLE test6b2; DROP TABLE test9b; DROP TABLE test10b; DROP TYPE test7b; diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index 79322165655..8a5f9ff98ad 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -1004,6 +1004,8 @@ CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = priv_testdomain1, RIGHTARG = CREATE TABLE test5a (a int, b priv_testdomain1); CREATE TABLE test6a OF priv_testtype1; +CREATE TABLE test6a2 (a int, b text); +ALTER TABLE test6a2 OF priv_testtype1; CREATE TABLE test10a (a int[], b priv_testtype1[]); CREATE TABLE test9a (a int, b int); @@ -1052,6 +1054,8 @@ CREATE OPERATOR !! (PROCEDURE = priv_testfunc5b, RIGHTARG = priv_testdomain1); CREATE TABLE test5b (a int, b priv_testdomain1); CREATE TABLE test6b OF priv_testtype1; +CREATE TABLE test6b2 (a int, b text); +ALTER TABLE test6b2 OF priv_testtype1; CREATE TABLE test10b (a int[], b priv_testtype1[]); CREATE TABLE test9b (a int, b int); @@ -1099,6 +1103,7 @@ DROP FUNCTION priv_testfunc6b(b int); DROP FUNCTION priv_testfunc7b(a int); DROP TABLE test5b; DROP TABLE test6b; +DROP TABLE test6b2; DROP TABLE test9b; DROP TABLE test10b; DROP TYPE test7b; From 567286b762bcb7a70233e5bb4b401fc62f9424ee Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 10 Aug 2026 06:38:06 -0700 Subject: [PATCH 345/481] Invalidate plan cache after role changes. Role membership, role attribute, and database ownership changes may impact the expected behavior of row-level security policies, but currently the plan cache doesn't take notice. To fix, register syscache callbacks on pg_auth_members, pg_authid, and pg_database that invalidate the role-dependent plans. Changes to other databases' pg_database rows are ignored. Reported-by: Ilya Staroverov Reported-by: Shinya Kato Author: Ilya Staroverov Author: Shinya Kato Co-authored-by: Nathan Bossart Reviewed-by: Tom Lane Security: CVE-2026-14666 Backpatch-through: 14 --- src/backend/utils/adt/acl.c | 2 +- src/backend/utils/cache/plancache.c | 61 ++++++++++++++++++++++++++++- src/include/utils/acl.h | 3 ++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index e2547d719ed..e2bfa77f498 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -81,7 +81,7 @@ enum RoleRecurseType }; static Oid cached_role[] = {InvalidOid, InvalidOid, InvalidOid}; static List *cached_roles[] = {NIL, NIL, NIL}; -static uint32 cached_db_hash; +uint32 cached_db_hash; /* * If the list of roles gathered by roles_is_member_of() grows larger than the diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c index 698e7c1aa22..62b6bddba09 100644 --- a/src/backend/utils/cache/plancache.c +++ b/src/backend/utils/cache/plancache.c @@ -36,7 +36,10 @@ * certain other system catalogs, such as pg_namespace; but for them, our * response is just to invalidate all plans. We expect updates on those * catalogs to be infrequent enough that more-detailed tracking is not worth - * the effort. + * the effort. We likewise watch pg_authid, pg_auth_members, and + * pg_database, which can change which row-level security policies apply. + * Since those are shared catalogs whose inval events reach every backend + * in the cluster, we invalidate only the role-dependent plans. * * In addition to full-fledged query plans, we provide a facility for * detecting invalidations of simple scalar expressions. This is fairly @@ -67,6 +70,7 @@ #include "storage/lmgr.h" #include "tcop/pquery.h" #include "tcop/utility.h" +#include "utils/acl.h" #include "utils/inval.h" #include "utils/memutils.h" #include "utils/resowner.h" @@ -108,6 +112,8 @@ static TupleDesc PlanCacheComputeResultDesc(List *stmt_list); static void PlanCacheRelCallback(Datum arg, Oid relid); static void PlanCacheObjectCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue); +static void PlanCacheRoleCallback(Datum arg, SysCacheIdentifier cacheid, + uint32 hashvalue); static void PlanCacheSysCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue); @@ -155,6 +161,9 @@ InitPlanCache(void) CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum) 0); CacheRegisterSyscacheCallback(FOREIGNSERVEROID, PlanCacheSysCallback, (Datum) 0); CacheRegisterSyscacheCallback(FOREIGNDATAWRAPPEROID, PlanCacheSysCallback, (Datum) 0); + CacheRegisterSyscacheCallback(AUTHMEMROLEMEM, PlanCacheRoleCallback, (Datum) 0); + CacheRegisterSyscacheCallback(AUTHOID, PlanCacheRoleCallback, (Datum) 0); + CacheRegisterSyscacheCallback(DATABASEOID, PlanCacheRoleCallback, (Datum) 0); } /* @@ -2309,6 +2318,56 @@ PlanCacheObjectCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue) } } +/* + * PlanCacheRoleCallback + * Syscache inval callback function for AUTHMEMROLEMEM, AUTHOID, and + * DATABASEOID caches + * + * Role membership, role attributes, and database ownership (which confers + * membership in pg_database_owner) affect planning by way of row-level + * security, so invalidate just the role-dependent plans. For DATABASEOID, we + * can ignore changes to other databases' pg_database rows. + */ +static void +PlanCacheRoleCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue) +{ + dlist_iter iter; + + if (cacheid == DATABASEOID && + hashvalue != cached_db_hash && + hashvalue != 0) + return; /* ignore pg_database changes for other DBs */ + + dlist_foreach(iter, &saved_plan_list) + { + CachedPlanSource *plansource = dlist_container(CachedPlanSource, + node, iter.cur); + + Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); + + /* No work if it's already invalidated */ + if (!plansource->is_valid) + continue; + + /* Never invalidate if parse/plan would be a no-op anyway */ + if (!StmtPlanRequiresRevalidation(plansource)) + continue; + + if (plansource->dependsOnRLS) + { + /* Invalidate the querytree and generic plan */ + plansource->is_valid = false; + if (plansource->gplan) + plansource->gplan->is_valid = false; + } + else if (plansource->gplan && plansource->gplan->dependsOnRole) + { + /* Invalidate the generic plan only */ + plansource->gplan->is_valid = false; + } + } +} + /* * PlanCacheSysCallback * Syscache inval callback function for other caches diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index 0b9b04e78ee..a16bf2fa15a 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -228,6 +228,9 @@ extern void select_best_grantor(const RoleSpec *grantedBy, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions); +/* DATABASEOID syscache hash value for our own database, set by initialize_acl */ +extern uint32 cached_db_hash; + extern void initialize_acl(void); /* From 8cf01e213ccc33e22e87b49e2711e4a83b4f01e0 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:06 -0700 Subject: [PATCH 346/481] Save/restore more lexer state when skipping text due to \if. When we implemented \if ... \endif in psql, we arranged to save/restore the lexer's parenthesis depth counter across any chunk of input that we're ignoring. At the time, that was sufficient, because no other part of PsqlScanState could need to be restored to its prior value. However, commit e717a9a18 and follow-ons added more state fields that ought to be restored to their prior values. A problem would only be observed if someone tries to \if out a portion of a CREATE FUNCTION/PROCEDURE command that is relevant to BEGIN/END matching, which seems like a pretty unusual usage, so the lack of field reports isn't surprising. Nonetheless it's a bug. To fix, replace the simple counter field in ConditionalStack entries with a pointer to a struct defined by psqlscan_int.h. (In the back branches, keep the old field and associated functions to minimize the risk of API/ABI breakage, even though it seems unlikely that any third-party code is using this. Making the new struct private to psqlscan-related code should prevent API/ABI issues for future additions of this type.) In itself this is only a minor bug fix, but it's prerequisite infrastructure for the fix for CVE-2026-6464, which will add another such field. Author: Tom Lane Reviewed-by: Noah Misch Backpatch-through: 14 Security: CVE-2026-6464 --- src/bin/psql/command.c | 16 +++++------- src/bin/psql/psqlscanslash.h | 5 ++-- src/bin/psql/psqlscanslash.l | 40 +++++++++++++++++++++++------ src/fe_utils/conditional.c | 28 ++++++++++++-------- src/include/fe_utils/conditional.h | 16 ++++++------ src/include/fe_utils/psqlscan.h | 3 +++ src/include/fe_utils/psqlscan_int.h | 20 +++++++++++++++ src/test/regress/expected/psql.out | 16 ++++++++++++ src/test/regress/sql/psql.sql | 11 ++++++++ src/tools/pgindent/typedefs.list | 1 + 10 files changed, 119 insertions(+), 37 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 01b8f11aadd..027b8ab7ed0 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -3795,8 +3795,8 @@ is_branching_command(const char *cmd) * Prepare to possibly restore query buffer to its current state * (cf. discard_query_text). * - * We need to remember the length of the query buffer, and the lexer's - * notion of the parenthesis nesting depth. + * We need to remember the length of the query buffer, and assorted + * lexer internal state such as parenthesis nesting depth. */ static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack, @@ -3804,8 +3804,8 @@ save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack, { if (query_buf) conditional_stack_set_query_len(cstack, query_buf->len); - conditional_stack_set_paren_depth(cstack, - psql_scan_get_paren_depth(scan_state)); + conditional_stack_set_lex_state(cstack, + psql_scan_get_lex_state(scan_state)); } /* @@ -3814,9 +3814,7 @@ save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack, * We must discard data that was appended to query_buf during an inactive * \if branch. We don't have to do anything there if there's no query_buf. * - * Also, reset the lexer state to the same paren depth there was before. - * (The rest of its state doesn't need attention, since we could not be - * inside a comment or literal or partial token.) + * Also, reset the lexer's state to what it was before. */ static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack, @@ -3830,8 +3828,8 @@ discard_query_text(PsqlScanState scan_state, ConditionalStack cstack, query_buf->len = new_len; query_buf->data[new_len] = '\0'; } - psql_scan_set_paren_depth(scan_state, - conditional_stack_get_paren_depth(cstack)); + psql_scan_set_lex_state(scan_state, + conditional_stack_get_lex_state(cstack)); } /* diff --git a/src/bin/psql/psqlscanslash.h b/src/bin/psql/psqlscanslash.h index d95a6ff2d1e..2ab08d5520b 100644 --- a/src/bin/psql/psqlscanslash.h +++ b/src/bin/psql/psqlscanslash.h @@ -31,9 +31,10 @@ extern char *psql_scan_slash_option(PsqlScanState state, extern void psql_scan_slash_command_end(PsqlScanState state); -extern int psql_scan_get_paren_depth(PsqlScanState state); +extern PsqlScanStateSave *psql_scan_get_lex_state(PsqlScanState state); -extern void psql_scan_set_paren_depth(PsqlScanState state, int depth); +extern void psql_scan_set_lex_state(PsqlScanState state, + const PsqlScanStateSave *lex_state); extern void dequote_downcase_identifier(char *str, bool downcase, int encoding); diff --git a/src/bin/psql/psqlscanslash.l b/src/bin/psql/psqlscanslash.l index 2d755752374..837158ae0d3 100644 --- a/src/bin/psql/psqlscanslash.l +++ b/src/bin/psql/psqlscanslash.l @@ -705,22 +705,46 @@ psql_scan_slash_command_end(PsqlScanState state) } /* - * Fetch current paren nesting depth + * Save current lexer state + * + * Relevant parts of the state are returned in a pg_malloc'd struct. + * It is caller's responsibility to free the struct eventually. */ -int -psql_scan_get_paren_depth(PsqlScanState state) +PsqlScanStateSave * +psql_scan_get_lex_state(PsqlScanState state) { - return state->paren_depth; + PsqlScanStateSave *lex_state = pg_malloc_object(PsqlScanStateSave); + StaticAssertDecl(sizeof(lex_state->init_idents) == sizeof(state->init_idents), + "init_idents array lengths must match"); + StaticAssertDecl(sizeof(lex_state->sub_idents) == sizeof(state->sub_idents), + "sub_idents array lengths must match"); + + lex_state->paren_depth = state->paren_depth; + lex_state->begin_depth = state->begin_depth; + lex_state->init_idents_count = state->init_idents_count; + memcpy(lex_state->init_idents, state->init_idents, + sizeof(lex_state->init_idents)); + lex_state->sub_idents_count = state->sub_idents_count; + memcpy(lex_state->sub_idents, state->sub_idents, + sizeof(lex_state->sub_idents)); + return lex_state; } /* - * Set paren nesting depth + * Restore lexer state to what it was when saved */ void -psql_scan_set_paren_depth(PsqlScanState state, int depth) +psql_scan_set_lex_state(PsqlScanState state, + const PsqlScanStateSave *lex_state) { - Assert(depth >= 0); - state->paren_depth = depth; + state->paren_depth = lex_state->paren_depth; + state->begin_depth = lex_state->begin_depth; + state->init_idents_count = lex_state->init_idents_count; + memcpy(state->init_idents, lex_state->init_idents, + sizeof(state->init_idents)); + state->sub_idents_count = lex_state->sub_idents_count; + memcpy(state->sub_idents, lex_state->sub_idents, + sizeof(state->sub_idents)); } /* diff --git a/src/fe_utils/conditional.c b/src/fe_utils/conditional.c index 537c76ed3cd..2d09d21ecb1 100644 --- a/src/fe_utils/conditional.c +++ b/src/fe_utils/conditional.c @@ -56,7 +56,7 @@ conditional_stack_push(ConditionalStack cstack, ifState new_state) p->if_state = new_state; p->query_len = -1; - p->paren_depth = -1; + p->lex_state = NULL; p->next = cstack->head; cstack->head = p; } @@ -73,6 +73,8 @@ conditional_stack_pop(ConditionalStack cstack) if (!p) return false; cstack->head = cstack->head->next; + if (p->lex_state) + free(p->lex_state); free(p); return true; } @@ -167,23 +169,29 @@ conditional_stack_get_query_len(ConditionalStack cstack) } /* - * Save current parenthesis nesting depth in topmost stack entry. + * Save current lexer state in topmost stack entry. + * + * The lexer state is presumed to be a single pg_malloc'd chunk. + * It will be freed automatically when the stack entry is popped. */ void -conditional_stack_set_paren_depth(ConditionalStack cstack, int depth) +conditional_stack_set_lex_state(ConditionalStack cstack, + PsqlScanStateSave *lex_state) { Assert(!conditional_stack_empty(cstack)); - cstack->head->paren_depth = depth; + if (cstack->head->lex_state) /* free old state, if any */ + free(cstack->head->lex_state); + cstack->head->lex_state = lex_state; } /* - * Fetch last-recorded parenthesis nesting depth from topmost stack entry. - * Will return -1 if no stack or it was never saved. + * Fetch last-recorded lexer state from topmost stack entry. + * Will return NULL if no stack or it was never saved. */ -int -conditional_stack_get_paren_depth(ConditionalStack cstack) +PsqlScanStateSave * +conditional_stack_get_lex_state(ConditionalStack cstack) { if (conditional_stack_empty(cstack)) - return -1; - return cstack->head->paren_depth; + return NULL; + return cstack->head->lex_state; } diff --git a/src/include/fe_utils/conditional.h b/src/include/fe_utils/conditional.h index 2ed796b5c50..96efd81a7c8 100644 --- a/src/include/fe_utils/conditional.h +++ b/src/include/fe_utils/conditional.h @@ -49,17 +49,16 @@ typedef enum ifState * query_len is used to determine what accumulated text to throw away at the * end of an inactive branch. (We could, perhaps, teach the lexer to not add * stuff to the query buffer in the first place when inside an inactive branch; - * but that would be very invasive.) We also need to save and restore the - * lexer's parenthesis nesting depth when throwing away text. (We don't need - * to save and restore any of its other state, such as comment nesting depth, - * because a backslash command could never appear inside a comment or SQL - * literal.) + * but that would be very invasive.) We also need to save and restore some + * lexer state, such as parenthesis nesting depth, when throwing away text. */ +typedef struct PsqlScanStateSave PsqlScanStateSave; /* opaque outside lexer */ + typedef struct IfStackElem { ifState if_state; /* current state, see enum above */ int query_len; /* length of query_buf at last branch start */ - int paren_depth; /* parenthesis depth at last branch start */ + PsqlScanStateSave *lex_state; /* lexer state at last branch start */ struct IfStackElem *next; /* next surrounding \if, if any */ } IfStackElem; @@ -95,8 +94,9 @@ extern void conditional_stack_set_query_len(ConditionalStack cstack, int len); extern int conditional_stack_get_query_len(ConditionalStack cstack); -extern void conditional_stack_set_paren_depth(ConditionalStack cstack, int depth); +extern void conditional_stack_set_lex_state(ConditionalStack cstack, + PsqlScanStateSave *lex_state); -extern int conditional_stack_get_paren_depth(ConditionalStack cstack); +extern PsqlScanStateSave *conditional_stack_get_lex_state(ConditionalStack cstack); #endif /* CONDITIONAL_H */ diff --git a/src/include/fe_utils/psqlscan.h b/src/include/fe_utils/psqlscan.h index abd44fa140b..f3e972e8892 100644 --- a/src/include/fe_utils/psqlscan.h +++ b/src/include/fe_utils/psqlscan.h @@ -26,6 +26,9 @@ /* Abstract type for lexer's internal state */ typedef struct PsqlScanStateData *PsqlScanState; +/* Abstract type for state save/restore */ +typedef struct PsqlScanStateSave PsqlScanStateSave; + /* Termination states for psql_scan() */ typedef enum { diff --git a/src/include/fe_utils/psqlscan_int.h b/src/include/fe_utils/psqlscan_int.h index 8b0d153261b..ada1089f70d 100644 --- a/src/include/fe_utils/psqlscan_int.h +++ b/src/include/fe_utils/psqlscan_int.h @@ -132,6 +132,26 @@ typedef struct PsqlScanStateData void *cb_passthrough; } PsqlScanStateData; +/* + * Conditional scanning (\if ... \endif) needs to be able to reset the + * lexer's state to what it was at the beginning of a chunk of text that + * we choose to ignore. PsqlScanStateSave holds the values that need + * to be saved and restored. We assume that saving/restoring happens only + * while processing a backslash command, so we needn't save state that is + * concerned with comment or SQL literal processing: we won't be inside + * one of those. + */ +typedef struct PsqlScanStateSave +{ + int paren_depth; /* depth of nesting in parentheses */ + int begin_depth; /* depth of begin/end pairs */ + int init_idents_count; /* # identifiers since start of statement */ + char init_idents[4]; /* records the first few identifiers */ + int sub_idents_count; /* # identifiers since start of a CREATE + * SCHEMA element */ + char sub_idents[4]; /* records the first few of those identifiers */ +} PsqlScanStateSave; + /* * Functions exported by psqlscan.l, but only meant for use within diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index 42635a56a06..7e67f795f25 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -4789,6 +4789,22 @@ invalid command \lo \echo 'should print #8-1' should print #8-1 \endif +-- test that begin/end matching ignores to-be-ignored text +create function silly_function(int) returns int +begin atomic select $1; +\if false +end +\endif +; +end; +\sf silly_function(int) +CREATE OR REPLACE FUNCTION public.silly_function(integer) + RETURNS integer + LANGUAGE sql +BEGIN ATOMIC + SELECT $1; +END +drop function silly_function(int); -- :{?...} defined variable test \set i 1 \if :{?i} diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql index e51767b3e2f..42eca3b8a6b 100644 --- a/src/test/regress/sql/psql.sql +++ b/src/test/regress/sql/psql.sql @@ -1126,6 +1126,17 @@ select \if false \\ (bogus \else \\ 42 \endif \\ forty_two; \echo 'should print #8-1' \endif +-- test that begin/end matching ignores to-be-ignored text +create function silly_function(int) returns int +begin atomic select $1; +\if false +end +\endif +; +end; +\sf silly_function(int) +drop function silly_function(int); + -- :{?...} defined variable test \set i 1 \if :{?i} diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 5fcdc7a131c..032ca27daa0 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -2460,6 +2460,7 @@ PsqlScanQuoteType PsqlScanResult PsqlScanState PsqlScanStateData +PsqlScanStateSave PsqlSettings Publication PublicationActions From d6ab88d374ab6bd6fead0902f7e7ff6ebc8b9006 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 06:38:06 -0700 Subject: [PATCH 347/481] Teach psql to skip in-line COPY ... FROM STDIN data after a failure. If the COPY command fails before sending PGRES_COPY_IN, psql did not realize that it ought to consume any in-line data following the command. Failing to do so leads to trying to execute that data as SQL commands, which in the best case is wrong and in the worst case is a SQL-injection hazard. To fix: 1. Extend psqlscan.l to recognize COPY ... FROM STDIN. This can be done with a pretty simple extension to the logic that already recognizes nested BEGIN blocks within CREATE FUNCTION et al. But unlike that case, we need to consider and count multiple COPY commands within a single query string (separated by "\;"). The fallout from that is that psql_scan_reset must now always be called before starting a new query string. (The comment for it that claimed we didn't need that because "the scan state must be INITIAL" was really obsolete already, since it has long reset more state besides start_state.) 2. Teach handleCopyIn() to read and discard data when passed NULL for "conn". 3. Add logic to SendQuery() to call handleCopyIn() that way if the query string contained COPY ... FROM STDIN command(s) that remain unaccounted-for at the end. Now that we have this counting logic, we can also detect if the backend sends an unexpected PGRES_COPY_IN message. That should never happen, but perhaps a malicious server could try to extract data that way. A side-effect of doing this is that we have to adjust a number of test scripts that thought they needn't write "\." after a COPY FROM STDIN that they expect to fail. On the whole this is an improvement, since there's now a uniform rule "write \. after COPY FROM STDIN, whether you expect it to work or not". But it is an annoying amount of test churn. A loose end in this patch is that if it has to skip data, it assumes that that data is text not binary. It seems unduly difficult to detect whether the COPY command requested binary (we could handle the old-style COPY BINARY ... syntax, but not the new style with format options). In practice, copying in-line binary data is unsupported anyway, because there's no way to write an end marker: the textual terminator sequence "\n\\.\n" could appear in binary data and there's no provision for escaping it, so neither psql nor the server look for it when in binary mode. Reported-by: Alexander Lakhin Author: Tom Lane Reviewed-by: Noah Misch Backpatch-through: 14 Security: CVE-2026-6464 --- src/bin/psql/common.c | 109 ++++++++++++++++++--- src/bin/psql/common.h | 2 +- src/bin/psql/copy.c | 48 +++++---- src/bin/psql/mainloop.c | 15 +-- src/bin/psql/psqlscanslash.l | 2 + src/bin/psql/startup.c | 2 +- src/fe_utils/psqlscan.l | 88 +++++++++++++++-- src/include/fe_utils/psqlscan.h | 2 + src/include/fe_utils/psqlscan_int.h | 11 ++- src/test/regress/expected/copy.out | 4 - src/test/regress/expected/psql.out | 5 + src/test/regress/sql/alter_table.sql | 2 + src/test/regress/sql/copy.sql | 2 + src/test/regress/sql/copy2.sql | 53 ++++++++++ src/test/regress/sql/copyselect.sql | 1 + src/test/regress/sql/generated_stored.sql | 4 + src/test/regress/sql/generated_virtual.sql | 4 + src/test/regress/sql/privileges.sql | 3 + src/test/regress/sql/psql.sql | 9 ++ src/test/regress/sql/rowsecurity.sql | 4 + 20 files changed, 313 insertions(+), 57 deletions(-) diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 10078f24532..7ca890eac6f 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -27,6 +27,7 @@ #include "fe_utils/cancel.h" #include "fe_utils/mbprint.h" #include "fe_utils/string_utils.h" +#include "mainloop.h" #include "portability/instr_time.h" #include "settings.h" @@ -34,6 +35,7 @@ static bool DescribeQuery(const char *query, double *elapsed_msec); static int ExecQueryAndProcessResults(const char *query, double *elapsed_msec, bool *svpt_gone_p, + int num_copy_from_stdin, bool is_watch, int min_rows, const printQueryOpt *opt, @@ -723,7 +725,11 @@ PSQLexecWatch(const char *query, const printQueryOpt *opt, FILE *printQueryFout, SetCancelConn(pset.db); - res = ExecQueryAndProcessResults(query, &elapsed_msec, NULL, true, min_rows, opt, printQueryFout); + res = ExecQueryAndProcessResults(query, + &elapsed_msec, NULL, + -1, + true, min_rows, + opt, printQueryFout); ResetCancelConn(); @@ -895,7 +901,7 @@ ExecQueryTuples(const PGresult *result) fflush(stdout); } - if (!SendQuery(query)) + if (!SendQuery(query, -1)) { /* Error - abandon execution if ON_ERROR_STOP */ success = false; @@ -926,8 +932,7 @@ ExecQueryTuples(const PGresult *result) * once and report any error. Return whether all was ok. * * For COPY OUT, direct the output to copystream, or discard if that's NULL. - * For COPY IN, use pset.copyStream as data source if it's set, - * otherwise cur_cmd_source. + * For COPY IN, read from copystream (which mustn't be NULL). * * Update *resultp if further processing is necessary; set to NULL otherwise. * Return a result when queryFout can safely output a result status: on COPY @@ -968,8 +973,7 @@ HandleCopyResult(PGresult **resultp, FILE *copystream) else { /* COPY IN */ - /* Ignore the copystream argument passed to the function */ - copystream = pset.copyStream ? pset.copyStream : pset.cur_cmd_source; + Assert(copystream); success = handleCopyIn(pset.db, copystream, PQbinaryTuples(*resultp), @@ -1114,10 +1118,14 @@ PrintQueryResult(PGresult *result, bool last, * To send "back door" queries (generated by slash commands, etc.) in a * controlled way, use PSQLexec(). * + * In the most common case, the caller can determine whether the query + * includes any COPY FROM STDIN command(s); if so, pass the count of them. + * Otherwise pass num_copy_from_stdin == -1 and we'll compute it locally. + * * Returns true if the query executed successfully, false otherwise. */ bool -SendQuery(const char *query) +SendQuery(const char *query, int num_copy_from_stdin) { bool timing = pset.timing; PGTransactionStatusType transaction_status; @@ -1211,7 +1219,11 @@ SendQuery(const char *query) else { /* Default fetch-and-print mode */ - OK = (ExecQueryAndProcessResults(query, &elapsed_msec, &svpt_gone, false, 0, NULL, NULL) > 0); + OK = (ExecQueryAndProcessResults(query, + &elapsed_msec, &svpt_gone, + num_copy_from_stdin, + false, 0, + NULL, NULL) > 0); } if (!OK && pset.echo == PSQL_ECHO_ERRORS) @@ -1570,6 +1582,7 @@ discardAbortedPipelineResults(void) static int ExecQueryAndProcessResults(const char *query, double *elapsed_msec, bool *svpt_gone_p, + int num_copy_from_stdin, bool is_watch, int min_rows, const printQueryOpt *opt, FILE *printQueryFout) { @@ -1774,6 +1787,29 @@ ExecQueryAndProcessResults(const char *query, return 0; } + /* + * If the caller didn't count the number of COPY FROM STDIN command(s) in + * the query string, we must do so now. + */ + if (num_copy_from_stdin < 0) + { + PsqlScanState scan_state; + PQExpBuffer query_buf; + promptStatus_t prompt_tmp; + + scan_state = psql_scan_create(&psqlscan_callbacks); + psql_scan_setup(scan_state, query, strlen(query), + pset.encoding, standard_strings()); + query_buf = createPQExpBuffer(); + + (void) psql_scan(scan_state, query_buf, &prompt_tmp); + + num_copy_from_stdin = psql_scan_count_copy_from_stdin(scan_state); + + destroyPQExpBuffer(query_buf); + psql_scan_destroy(scan_state); + } + /* first result */ result = PQgetResult(pset.db); if (min_rows > 0 && PQntuples(result) < min_rows) @@ -1909,14 +1945,15 @@ ExecQueryAndProcessResults(const char *query, exit(EXIT_BADCONN); } - /* - * For COPY OUT, direct the output to the default place (probably - * a pager pipe) for \watch, or to pset.copyStream for \copy, - * otherwise to pset.gfname if that's set, otherwise to - * pset.queryFout. - */ + /* Select data source or sink. */ if (result_status == PGRES_COPY_OUT) { + /* + * For COPY OUT, direct the output to the default place + * (probably a pager pipe) for \watch, or to pset.copyStream + * for \copy, otherwise to pset.gfname if that's set, + * otherwise to pset.queryFout. + */ if (is_watch) { /* invoked by \watch */ @@ -1940,6 +1977,32 @@ ExecQueryAndProcessResults(const char *query, copy_stream = pset.queryFout; } } + else + { + if (num_copy_from_stdin <= 0) + { + /* + * We didn't send a COPY FROM STDIN command. The server + * is broken or possibly malicious. Report and quit. (We + * could instead send an empty COPY response, but it's not + * clear that that's a better behavior; it would make it + * harder to diagnose any such problem.) + */ + pg_log_info("unexpected COPY_IN result, aborting connection"); + exit(EXIT_BADCONN); + } + /* Keep track of the number of remaining copy operations */ + num_copy_from_stdin--; + + /* + * For COPY IN, read from pset.copyStream if \copy set that, + * otherwise from the current command source. + */ + if (pset.copyStream) + copy_stream = pset.copyStream; + else + copy_stream = pset.cur_cmd_source; + } /* * Even if the output stream could not be opened, we call @@ -2229,6 +2292,24 @@ ExecQueryAndProcessResults(const char *query, if (!CheckConnection()) return -1; + /* + * If we were expecting COPY ... FROM STDIN, and we didn't get + * PGRES_COPY_IN (presumably because the COPY failed server-side), and the + * data is supposed to come from the current command source, we must eat + * up the data in order to stay in sync with the command file's contents. + * Repeat for the number of unfulfilled COPY commands. + */ + while (num_copy_from_stdin > 0) + { + if (pset.copyStream == NULL || + pset.copyStream == pset.cur_cmd_source) + (void) handleCopyIn(NULL, /* no connection */ + pset.cur_cmd_source, + false, /* XXX assume not binary */ + NULL); /* no result */ + num_copy_from_stdin--; + } + if (cancel_pressed || return_early) return 0; diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index b8a5a2ab6a1..d4b99b42331 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -34,7 +34,7 @@ extern void SetShellResultVariables(int wait_result); extern PGresult *PSQLexec(const char *query); extern int PSQLexecWatch(const char *query, const printQueryOpt *opt, FILE *printQueryFout, int min_rows); -extern bool SendQuery(const char *query); +extern bool SendQuery(const char *query, int num_copy_from_stdin); extern bool is_superuser(void); extern bool standard_strings(void); diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c index 6a8a9792e7d..1b8d6c7687f 100644 --- a/src/bin/psql/copy.c +++ b/src/bin/psql/copy.c @@ -367,7 +367,7 @@ do_copy(const char *args) /* run it like a user command, but with copystream as data source/sink */ pset.copyStream = copystream; - success = SendQuery(query.data); + success = SendQuery(query.data, options->from ? 1 : 0); pset.copyStream = NULL; termPQExpBuffer(&query); @@ -495,11 +495,13 @@ handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res) * sends data to complete a COPY ... FROM STDIN command * * conn should be a database connection that you just issued COPY FROM on - * and got back a PGRES_COPY_IN result. + * and got back a PGRES_COPY_IN result. Alternatively, if conn is NULL, + * we read and discard the appropriate amount of data from copystream. * copystream is the file stream to read the data from. * isbinary can be set from PQbinaryTuples(). - * The final status for the COPY is returned into *res (but note - * we already reported the error, if it's not a success result). + * The final status for the COPY is returned into *res; but note + * we already reported the error, if it's not a success result. + * Also, if conn is NULL then *res is not touched. * * result is true if successful, false if not. */ @@ -514,6 +516,12 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res) char buf[COPYBUFSIZ]; bool showprompt; + /* We want to prompt if interactive input ... */ + showprompt = isatty(fileno(copystream)); + /* ... but if we're just discarding data, don't bother the user at all */ + if (showprompt && !conn) + return true; + /* * Establish longjmp destination for exiting from wait-for-input. (This is * only effective while sigint_interrupt_enabled is TRUE.) @@ -523,24 +531,19 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res) /* got here with longjmp */ /* Terminate data transfer */ - PQputCopyEnd(conn, - (PQprotocolVersion(conn) < 3) ? NULL : - _("canceled by user")); + if (conn) + PQputCopyEnd(conn, + (PQprotocolVersion(conn) < 3) ? NULL : + _("canceled by user")); OK = false; goto copyin_cleanup; } - /* Prompt if interactive input */ - if (isatty(fileno(copystream))) - { - showprompt = true; - if (!pset.quiet) - puts(_("Enter data to be copied followed by a newline.\n" - "End with a backslash and a period on a line by itself, or an EOF signal.")); - } - else - showprompt = false; + /* Issue initial prompt if interactive input */ + if (showprompt && !pset.quiet) + puts(_("Enter data to be copied followed by a newline.\n" + "End with a backslash and a period on a line by itself, or an EOF signal.")); OK = true; @@ -569,7 +572,7 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res) if (buflen <= 0) break; - if (PQputCopyData(conn, buf, buflen) <= 0) + if (conn && PQputCopyData(conn, buf, buflen) <= 0) { OK = false; break; @@ -667,7 +670,7 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res) */ if (buflen >= COPYBUFSIZ - 5 || (copydone && buflen > 0)) { - if (PQputCopyData(conn, buf, buflen) <= 0) + if (conn && PQputCopyData(conn, buf, buflen) <= 0) { OK = false; break; @@ -688,7 +691,8 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res) * keep the version checks just in case you're using a pre-v14 libpq.so at * runtime) */ - if (PQputCopyEnd(conn, + if (conn && + PQputCopyEnd(conn, (OK || PQprotocolVersion(conn) < 3) ? NULL : _("aborted because of read failure")) <= 0) OK = false; @@ -705,6 +709,10 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res) */ clearerr(copystream); + /* Done if we don't have a connection to clean up */ + if (!conn) + return OK; + /* * Check command status and return to normal libpq state. * diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c index e9abda07161..fa9e0904cab 100644 --- a/src/bin/psql/mainloop.c +++ b/src/bin/psql/mainloop.c @@ -436,7 +436,9 @@ MainLoop(FILE *source) /* execute query unless we're in an inactive \if branch */ if (conditional_active(cond_stack)) { - success = SendQuery(query_buf->data); + /* count_copy_from_stdin should be reliable here */ + success = SendQuery(query_buf->data, + psql_scan_count_copy_from_stdin(scan_state)); slashCmdStatus = success ? PSQL_CMD_SEND : PSQL_CMD_ERROR; pset.stmt_lineno = 1; @@ -448,9 +450,10 @@ MainLoop(FILE *source) query_buf = swap_buf; } resetPQExpBuffer(query_buf); + /* reset parsing state, too */ + psql_scan_reset(scan_state); added_nl_pos = -1; - /* we need not do psql_scan_reset() here */ } else { @@ -512,7 +515,7 @@ MainLoop(FILE *source) /* should not see this in inactive branch */ Assert(conditional_active(cond_stack)); - success = SendQuery(query_buf->data); + success = SendQuery(query_buf->data, -1); /* transfer query to previous_buf by pointer-swapping */ { @@ -522,8 +525,7 @@ MainLoop(FILE *source) query_buf = swap_buf; } resetPQExpBuffer(query_buf); - - /* flush any paren nesting info after forced send */ + /* reset parsing state, too */ psql_scan_reset(scan_state); } else if (slashCmdStatus == PSQL_CMD_NEWEDIT) @@ -610,7 +612,8 @@ MainLoop(FILE *source) /* execute query unless we're in an inactive \if branch */ if (conditional_active(cond_stack)) { - success = SendQuery(query_buf->data); + success = SendQuery(query_buf->data, + psql_scan_count_copy_from_stdin(scan_state)); } else { diff --git a/src/bin/psql/psqlscanslash.l b/src/bin/psql/psqlscanslash.l index 837158ae0d3..e3ec1775e62 100644 --- a/src/bin/psql/psqlscanslash.l +++ b/src/bin/psql/psqlscanslash.l @@ -721,6 +721,7 @@ psql_scan_get_lex_state(PsqlScanState state) lex_state->paren_depth = state->paren_depth; lex_state->begin_depth = state->begin_depth; + lex_state->copy_stdin_count = state->copy_stdin_count; lex_state->init_idents_count = state->init_idents_count; memcpy(lex_state->init_idents, state->init_idents, sizeof(lex_state->init_idents)); @@ -739,6 +740,7 @@ psql_scan_set_lex_state(PsqlScanState state, { state->paren_depth = lex_state->paren_depth; state->begin_depth = lex_state->begin_depth; + state->copy_stdin_count = lex_state->copy_stdin_count; state->init_idents_count = lex_state->init_idents_count; memcpy(state->init_idents, lex_state->init_idents, sizeof(state->init_idents)); diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index 7665f0a3124..454ce3c939e 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -390,7 +390,7 @@ main(int argc, char *argv[]) if (pset.echo == PSQL_ECHO_ALL) puts(cell->val); - successResult = SendQuery(cell->val) + successResult = SendQuery(cell->val, -1) ? EXIT_SUCCESS : EXIT_FAILURE; } else if (cell->action == ACT_SINGLE_SLASH) diff --git a/src/fe_utils/psqlscan.l b/src/fe_utils/psqlscan.l index bbfafbc5223..97055f5ad3c 100644 --- a/src/fe_utils/psqlscan.l +++ b/src/fe_utils/psqlscan.l @@ -61,6 +61,7 @@ typedef int YYSTYPE; #define ECHO psqlscan_emit(cur_state, yytext, yyleng) +static bool psqlscan_is_copy_from_stdin(PsqlScanState state); static void psqlscan_track_identifier(PsqlScanState state, const char *identifier); @@ -683,6 +684,9 @@ other . if (cur_state->paren_depth == 0 && cur_state->begin_depth == 0) { + /* Remember if this subcommand was COPY FROM STDIN */ + if (psqlscan_is_copy_from_stdin(cur_state)) + cur_state->copy_stdin_count++; /* Terminate lexing temporarily */ cur_state->start_state = YY_START; cur_state->init_idents_count = 0; @@ -698,11 +702,16 @@ other . "\\"[;:] { /* Force a semi-colon or colon into the query buffer */ psqlscan_emit(cur_state, yytext + 1, 1); - /* Reset BEGIN/END tracking if semi at outer level */ + /* Reset BEGIN/END/COPY tracking if semi at outer level */ if (yytext[1] == ';' && cur_state->paren_depth == 0 && cur_state->begin_depth == 0) + { + /* Remember if this subcommand was COPY FROM STDIN */ + if (psqlscan_is_copy_from_stdin(cur_state)) + cur_state->copy_stdin_count++; cur_state->init_idents_count = 0; + } } "\\" { @@ -975,7 +984,11 @@ psqlscan_record_initial_keyword(const char *identifier, /* * What we need to recognize is CREATE [OR REPLACE] FUNCTION/PROCEDURE * and CREATE SCHEMA. Checking for SCHEMA is useless but not harmful - * in the CREATE SCHEMA sub-statement case. + * in the CREATE SCHEMA sub-statement case. We record these keywords + * in lower case. We also need to recognize COPY ... FROM STDIN. + * (Note: the backend grammar doesn't distinguish STDIN from STDOUT, + * so we should not do so here either.) We record these keywords in + * upper case, to avoid conflicting with the first set. */ if (pg_strcasecmp(identifier, "create") == 0 || pg_strcasecmp(identifier, "function") == 0 || @@ -984,6 +997,11 @@ psqlscan_record_initial_keyword(const char *identifier, pg_strcasecmp(identifier, "replace") == 0 || pg_strcasecmp(identifier, "schema") == 0) idents[*idents_count] = pg_tolower((unsigned char) identifier[0]); + else if (pg_strcasecmp(identifier, "copy") == 0 || + pg_strcasecmp(identifier, "from") == 0 || + pg_strcasecmp(identifier, "stdin") == 0 || + pg_strcasecmp(identifier, "stdout") == 0) + idents[*idents_count] = pg_toupper((unsigned char) identifier[0]); /* For other keywords or identifiers, leave '\0' in the array entry */ (*idents_count)++; } @@ -1002,7 +1020,40 @@ psqlscan_is_create_routine(const char *idents) } /* - * Track whether we are inside a BEGIN .. END block in a function definition, + * Does the current input match COPY ... FROM STDIN? + */ +static bool +psqlscan_is_copy_from_stdin(PsqlScanState state) +{ + const char *idents = state->init_idents; + + /* + * The first word must be COPY, but after that there could be up to four + * identifiers (BINARY database.schema.table) before FROM. Since some of + * the words we track are not reserved words, don't assume the intervening + * array entries are '\0'. Life is simplified here by the fact that + * psqlscan_track_identifier ignores everything within parens: we won't + * see column lists nor the query in COPY (query). + */ + if (idents[0] != 'C') + return false; + for (int i = 1; i < lengthof(state->init_idents) - 1; i++) + { + /* Scan to find FROM; if not seen within range, it's not valid COPY */ + if (idents[i] != 'F') + continue; + /* It's COPY FROM STDIN only if the next word is STDIN */ + return (idents[i + 1] == 'S'); + } + return false; +} + +/* + * This function is called each time the lexer recognizes an unquoted + * identifier (which could also be a keyword, and indeed keywords are the + * only case we really care about here). It presently has two tasks: + * + * 1. Track whether we are inside BEGIN .. END in a function definition, * so that semicolons contained therein don't terminate the whole statement. * Short of writing a full parser here, the following heuristic should work. * @@ -1011,6 +1062,9 @@ psqlscan_is_create_routine(const char *idents) * after recognizing an embedded CREATE [OR REPLACE] {FUNCTION|PROCEDURE} * subcommand. Once one of these conditions holds, count BEGIN and END * pairs. We also have to account for CASE ... END. + * + * 2. Record enough information for psqlscan_is_copy_from_stdin() to recognize + * COPY FROM STDIN commands. */ static void psqlscan_track_identifier(PsqlScanState state, const char *identifier) @@ -1357,10 +1411,9 @@ psql_scan_finish(PsqlScanState state) /* * Reset lexer scanning state to start conditions. This is appropriate * for executing \r psql commands (or any other time that we discard the - * prior contents of query_buf). It is not, however, necessary to do this - * when we execute and clear the buffer after getting a PSCAN_SEMICOLON or - * PSCAN_EOL scan result, because the scan state must be INITIAL when those - * conditions are returned. + * prior contents of query_buf). Do not call this between psql_scan() + * calls that are scanning successive chunks of a single query string; + * do call it when preparing to process a new query string. * * Note that this is unrelated to flushing unread input; that task is * done by psql_scan_finish(). @@ -1375,6 +1428,7 @@ psql_scan_reset(PsqlScanState state) free(state->dolqstart); state->dolqstart = NULL; state->begin_depth = 0; + state->copy_stdin_count = 0; state->init_idents_count = 0; } @@ -1399,6 +1453,26 @@ psql_scan_reselect_sql_lexer(PsqlScanState state) state->start_state = INITIAL; } +/* + * Return the number of COPY ... FROM STDIN commands in the input string. + * + * This should be called only after we've finished parsing a complete + * string and are ready to send it to the backend. + */ +int +psql_scan_count_copy_from_stdin(PsqlScanState state) +{ + if (state->init_idents_count > 0) + { + /* Count any COPY FROM STDIN following the last semicolon */ + if (psqlscan_is_copy_from_stdin(state)) + state->copy_stdin_count++; + /* ... but do so only once */ + state->init_idents_count = 0; + } + return state->copy_stdin_count; +} + /* * Return true if lexer is currently in an "inside quotes" state. * diff --git a/src/include/fe_utils/psqlscan.h b/src/include/fe_utils/psqlscan.h index f3e972e8892..61f34eaa140 100644 --- a/src/include/fe_utils/psqlscan.h +++ b/src/include/fe_utils/psqlscan.h @@ -88,6 +88,8 @@ extern void psql_scan_reset(PsqlScanState state); extern void psql_scan_reselect_sql_lexer(PsqlScanState state); +extern int psql_scan_count_copy_from_stdin(PsqlScanState state); + extern bool psql_scan_in_quote(PsqlScanState state); extern void psql_scan_get_location(PsqlScanState state, diff --git a/src/include/fe_utils/psqlscan_int.h b/src/include/fe_utils/psqlscan_int.h index ada1089f70d..b1661afd4af 100644 --- a/src/include/fe_utils/psqlscan_int.h +++ b/src/include/fe_utils/psqlscan_int.h @@ -114,12 +114,14 @@ typedef struct PsqlScanStateData char *dolqstart; /* current $foo$ quote start string */ /* - * State to track boundaries of BEGIN ... END blocks in function - * definitions, so that semicolons do not send query too early. + * State used to track boundaries of BEGIN ... END blocks in function + * definitions, so that semicolons do not send query too early. We also + * use this state to detect and count COPY FROM STDIN commands. */ int begin_depth; /* depth of begin/end pairs */ + int copy_stdin_count; /* number of COPY FROM STDIN commands */ int init_idents_count; /* # identifiers since start of statement */ - char init_idents[4]; /* records the first few identifiers */ + char init_idents[8]; /* records the first few identifiers */ int sub_idents_count; /* # identifiers since start of a CREATE * SCHEMA element */ char sub_idents[4]; /* records the first few of those identifiers */ @@ -145,8 +147,9 @@ typedef struct PsqlScanStateSave { int paren_depth; /* depth of nesting in parentheses */ int begin_depth; /* depth of begin/end pairs */ + int copy_stdin_count; /* number of COPY FROM STDIN commands */ int init_idents_count; /* # identifiers since start of statement */ - char init_idents[4]; /* records the first few identifiers */ + char init_idents[8]; /* records the first few identifiers */ int sub_idents_count; /* # identifiers since start of a CREATE * SCHEMA element */ char sub_idents[4]; /* records the first few of those identifiers */ diff --git a/src/test/regress/expected/copy.out b/src/test/regress/expected/copy.out index ace38225623..0af0b646921 100644 --- a/src/test/regress/expected/copy.out +++ b/src/test/regress/expected/copy.out @@ -518,13 +518,9 @@ copy oversized_column_default from stdin; -- error if the column is excluded copy oversized_column_default (col2) from stdin; ERROR: value too long for type character varying(5) -\. -invalid command \. -- error if the DEFAULT option is given copy oversized_column_default from stdin (default ''); ERROR: value too long for type character varying(5) -\. -invalid command \. drop table oversized_column_default; -- -- Create partitioned table that does not allow bulk insertions, to test bugs diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index 7e67f795f25..e8605dd041f 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -5949,6 +5949,11 @@ SELECT line FROM reload_output ORDER BY lineno; (2 rows) DROP TABLE reload_output; +-- \copy must skip in-line data, even if the issued COPY command fails. +\copy no_such_table from stdin +ERROR: relation "no_such_table" does not exist +\echo this should get output +this should get output -- -- AUTOCOMMIT and combined queries -- diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index f5f13bbd3e7..9f6c2a4bb08 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1157,7 +1157,9 @@ copy attest from stdin; \. select * from attest; copy attest(a) from stdin; +\. copy attest("........pg.dropped.1........") from stdin; +\. copy attest(b,c) from stdin; 31 32 \. diff --git a/src/test/regress/sql/copy.sql b/src/test/regress/sql/copy.sql index 507b822946f..14da3c5ec37 100644 --- a/src/test/regress/sql/copy.sql +++ b/src/test/regress/sql/copy.sql @@ -115,6 +115,7 @@ copy copytest to stdout (format json, force_null *); copy copytest to stdout (format json, on_error ignore); copy copytest to stdout (format json, reject_limit 1); copy copytest from stdin(format json); +\. -- all of the above should yield error -- column list with json format @@ -400,6 +401,7 @@ alter table header_copytest drop column c; alter table header_copytest add column c text; copy header_copytest to stdout with (header match); copy header_copytest from stdin with (header wrong_choice); +\. -- works copy header_copytest from stdin with (header match); a b c diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql index f853499021d..696ceeeaf82 100644 --- a/src/test/regress/sql/copy2.sql +++ b/src/test/regress/sql/copy2.sql @@ -52,57 +52,94 @@ COPY x (a, b, c, d, e) from stdin; -- non-existent column in column list: should fail COPY x (xyz) from stdin; +\. -- redundant options COPY x from stdin (format CSV, FORMAT CSV); +\. COPY x from stdin (freeze off, freeze on); +\. COPY x from stdin (delimiter ',', delimiter ','); +\. COPY x from stdin (null ' ', null ' '); +\. COPY x from stdin (header off, header on); +\. COPY x from stdin (quote ':', quote ':'); +\. COPY x from stdin (escape ':', escape ':'); +\. COPY x from stdin (force_quote (a), force_quote *); +\. COPY x from stdin (force_not_null (a), force_not_null (b)); +\. COPY x from stdin (force_null (a), force_null (b)); +\. COPY x from stdin (convert_selectively (a), convert_selectively (b)); +\. COPY x from stdin (encoding 'sql_ascii', encoding 'sql_ascii'); +\. COPY x from stdin (on_error ignore, on_error ignore); +\. COPY x from stdin (on_error set_null, on_error set_null); +\. COPY x from stdin (log_verbosity default, log_verbosity verbose); +\. -- incorrect options COPY x from stdin (format BINARY, delimiter ','); +\. COPY x from stdin (format BINARY, null 'x'); +\. COPY x from stdin (format BINARY, on_error ignore); +\. COPY x from stdin (format BINARY, on_error set_null); +\. COPY x from stdin (on_error set_null, reject_limit 2); +\. COPY x from stdin (on_error unsupported); +\. COPY x from stdin (format TEXT, force_quote(a)); +\. COPY x from stdin (format TEXT, force_quote *); +\. COPY x from stdin (format CSV, force_quote(a)); +\. COPY x from stdin (format CSV, force_quote *); +\. COPY x from stdin (format TEXT, force_not_null(a)); +\. COPY x from stdin (format TEXT, force_not_null *); +\. COPY x to stdout (format CSV, force_not_null(a)); COPY x to stdout (format CSV, force_not_null *); COPY x from stdin (format TEXT, force_null(a)); +\. COPY x from stdin (format TEXT, force_null *); +\. COPY x to stdout (format CSV, force_null(a)); COPY x to stdout (format CSV, force_null *); COPY x to stdout (format BINARY, on_error unsupported); COPY x to stdout (on_error set_null); COPY x from stdin (log_verbosity unsupported); +\. COPY x from stdin with (reject_limit 1); +\. COPY x from stdin with (on_error ignore, reject_limit 0); +\. COPY x from stdin with (header -1); +\. COPY x from stdin with (header 2.5); +\. COPY x to stdout with (header 2); COPY x to stdout with (header '-1'); COPY x from stdin with (header '2.5'); +\. COPY x to stdout with (header '2'); -- too many columns in column list: should fail COPY x (a, b, c, d, e, d, c) from stdin; +\. -- missing data: should fail COPY x from stdin; @@ -159,16 +196,22 @@ COPY x from stdin WHERE a > 60003; \. COPY x from stdin WHERE f > 60003; +\. COPY x from stdin WHERE a = max(x.b); +\. COPY x from stdin WHERE a IN (SELECT 1 FROM x); +\. COPY x from stdin WHERE a IN (generate_series(1,5)); +\. COPY x from stdin WHERE a = row_number() over(b); +\. COPY x from stdin WHERE tableoid = 'x'::regclass; +\. -- check results of copy in @@ -365,10 +408,12 @@ ROLLBACK; -- should fail with "not referenced by COPY" error BEGIN; COPY forcetest (d, e) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(b)); +\. ROLLBACK; -- should fail with "not referenced by COPY" error BEGIN; COPY forcetest (d, e) FROM STDIN WITH (FORMAT csv, FORCE_NULL(b)); +\. ROLLBACK; -- should succeed with no effect ("b" remains an empty string, "c" remains NULL) BEGIN; @@ -394,10 +439,12 @@ SELECT b, c FROM forcetest WHERE a = 6; -- should fail with "conflicting or redundant options" error BEGIN; COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL *, FORCE_NOT_NULL(b)); +\. ROLLBACK; -- should fail with "conflicting or redundant options" error BEGIN; COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NULL *, FORCE_NULL(b)); +\. ROLLBACK; \pset null '' @@ -693,19 +740,25 @@ truncate copy_default; -- DEFAULT cannot be used in binary mode copy copy_default from stdin with (format binary, default '\D'); +\. -- DEFAULT cannot be new line nor carriage return copy copy_default from stdin with (default E'\n'); +\. copy copy_default from stdin with (default E'\r'); +\. -- DELIMITER cannot appear in DEFAULT spec copy copy_default from stdin with (delimiter ';', default 'test;test'); +\. -- CSV quote cannot appear in DEFAULT spec copy copy_default from stdin with (format csv, quote '"', default 'test"test'); +\. -- NULL and DEFAULT spec must be different copy copy_default from stdin with (default '\N'); +\. -- cannot use DEFAULT marker in column that has no DEFAULT value copy copy_default from stdin with (default '\D'); diff --git a/src/test/regress/sql/copyselect.sql b/src/test/regress/sql/copyselect.sql index e32a4f8e38e..273a5f90a56 100644 --- a/src/test/regress/sql/copyselect.sql +++ b/src/test/regress/sql/copyselect.sql @@ -42,6 +42,7 @@ copy (select t into temp test3 from test1 where id=3) to stdout; -- This should fail -- copy (select * from test1) from stdin; +\. -- -- This should fail -- diff --git a/src/test/regress/sql/generated_stored.sql b/src/test/regress/sql/generated_stored.sql index 9eecd13dd9e..235bc28db81 100644 --- a/src/test/regress/sql/generated_stored.sql +++ b/src/test/regress/sql/generated_stored.sql @@ -216,10 +216,13 @@ COPY gtest1 FROM stdin; \. COPY gtest1 (a, b) FROM stdin; +\. COPY gtest1 FROM stdin WHERE b <> 10; +\. COPY gtest1 FROM stdin WHERE gtest1 IS NULL; +\. SELECT * FROM gtest1 ORDER BY a; @@ -236,6 +239,7 @@ COPY gtest3 FROM stdin; \. COPY gtest3 (a, b) FROM stdin; +\. SELECT * FROM gtest3 ORDER BY a; diff --git a/src/test/regress/sql/generated_virtual.sql b/src/test/regress/sql/generated_virtual.sql index ed9d50fe784..e4ea63bb3a1 100644 --- a/src/test/regress/sql/generated_virtual.sql +++ b/src/test/regress/sql/generated_virtual.sql @@ -216,10 +216,13 @@ COPY gtest1 FROM stdin; \. COPY gtest1 (a, b) FROM stdin; +\. COPY gtest1 FROM stdin WHERE b <> 10; +\. COPY gtest1 FROM stdin WHERE gtest1 IS NULL; +\. SELECT * FROM gtest1 ORDER BY a; @@ -236,6 +239,7 @@ COPY gtest3 FROM stdin; \. COPY gtest3 (a, b) FROM stdin; +\. SELECT * FROM gtest3 ORDER BY a; diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index 8a5f9ff98ad..ac91511f451 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -253,6 +253,7 @@ BEGIN; LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail COMMIT; COPY atest2 FROM stdin; -- fail +\. GRANT ALL ON atest1 TO PUBLIC; -- fail -- checks in subquery, both ok @@ -296,6 +297,7 @@ BEGIN; LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok COMMIT; COPY atest2 FROM stdin; -- fail +\. -- checks in subquery, both fail SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) ); @@ -543,6 +545,7 @@ SELECT one, two FROM atest5 NATURAL JOIN atest6; -- ok now -- test column-level privileges for INSERT and UPDATE INSERT INTO atest5 (two) VALUES (3); -- ok COPY atest5 FROM stdin; -- fail +\. COPY atest5 (two) FROM stdin; -- ok 1 \. diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql index 42eca3b8a6b..cd685b43e0f 100644 --- a/src/test/regress/sql/psql.sql +++ b/src/test/regress/sql/psql.sql @@ -1583,6 +1583,15 @@ SELECT line FROM reload_output ORDER BY lineno; DROP TABLE reload_output; +-- \copy must skip in-line data, even if the issued COPY command fails. +\copy no_such_table from stdin +foo +\echo this should not get output +bar +\echo this should not get output +\. +\echo this should get output + -- -- AUTOCOMMIT and combined queries -- diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql index 0bd24d1028b..ed70b1b229e 100644 --- a/src/test/regress/sql/rowsecurity.sql +++ b/src/test/regress/sql/rowsecurity.sql @@ -1882,8 +1882,10 @@ COPY copy_t FROM STDIN; --ok SET SESSION AUTHORIZATION regress_rls_bob; SET row_security TO OFF; COPY copy_t FROM STDIN; --fail - would be affected by RLS. +\. SET row_security TO ON; COPY copy_t FROM STDIN; --fail - COPY FROM not supported by RLS. +\. -- Check COPY FROM as user with permissions and BYPASSRLS SET SESSION AUTHORIZATION regress_rls_exempt_user; @@ -1899,8 +1901,10 @@ COPY copy_t FROM STDIN; --ok SET SESSION AUTHORIZATION regress_rls_carol; SET row_security TO OFF; COPY copy_t FROM STDIN; --fail - permission denied. +\. SET row_security TO ON; COPY copy_t FROM STDIN; --fail - permission denied. +\. RESET SESSION AUTHORIZATION; DROP TABLE copy_t; From 80ce920a5a42a43d98ac40d174fea8ae518abf63 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 10 Aug 2026 06:38:06 -0700 Subject: [PATCH 348/481] Fix out-of-bound reads with ascii() for invalid multibyte characters This commit addresses two defects in this SQL function, the code assuming that: - The user-supplied string was long enough to contain a character of the length implied by the first byte. It is possible to provide in input data that was able to disclose a few bytes of server memory, allowing out-of-bound reads. - Specific bytes had values within the expected range, using a set of assertions to validate them. The assertions could be triggered on invalid input. These are replaced by tests and error reports. Reported-by: Hcamael Author: Michael Paquier Reviewed-by: Robert Haas Backpatch-through: 14 Security: CVE-2026-18024 --- src/backend/utils/adt/oracle_compat.c | 25 ++++++++++++++++++++----- src/test/regress/expected/encoding.out | 19 +++++++++++++++++++ src/test/regress/sql/encoding.sql | 12 ++++++++++++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c index 5b0d098bd07..17880f937ac 100644 --- a/src/backend/utils/adt/oracle_compat.c +++ b/src/backend/utils/adt/oracle_compat.c @@ -952,8 +952,10 @@ ascii(PG_FUNCTION_ARGS) text *string = PG_GETARG_TEXT_PP(0); int encoding = GetDatabaseEncoding(); unsigned char *data; + int len; - if (VARSIZE_ANY_EXHDR(string) <= 0) + len = VARSIZE_ANY_EXHDR(string); + if (len <= 0) PG_RETURN_INT32(0); data = (unsigned char *) VARDATA_ANY(string); @@ -976,18 +978,31 @@ ascii(PG_FUNCTION_ARGS) result = *data & 0x0F; tbytes = 2; } - else + else if (*data > 0xC0) { - Assert(*data > 0xC0); result = *data & 0x1f; tbytes = 1; } + else + ereport(ERROR, + (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE), + errmsg("invalid byte sequence for encoding \"%s\"", + GetDatabaseEncodingName()))); - Assert(tbytes > 0); + /* All continuation bytes are present in the input */ + if (tbytes >= len) + ereport(ERROR, + (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE), + errmsg("invalid byte sequence for encoding \"%s\"", + GetDatabaseEncodingName()))); for (i = 1; i <= tbytes; i++) { - Assert((data[i] & 0xC0) == 0x80); + if (unlikely((data[i] & 0xC0) != 0x80)) + ereport(ERROR, + (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE), + errmsg("invalid byte sequence for encoding \"%s\"", + GetDatabaseEncodingName()))); result = (result << 6) + (data[i] & 0x3f); } diff --git a/src/test/regress/expected/encoding.out b/src/test/regress/expected/encoding.out index 2ecd255f182..0bb72a1df6f 100644 --- a/src/test/regress/expected/encoding.out +++ b/src/test/regress/expected/encoding.out @@ -401,6 +401,25 @@ SELECT SUBSTRING(c FROM 3000 FOR 1) FROM toast_4b_utf8; 🚀 (1 row) +-- ascii() and multibyte characters +SELECT ascii(test_bytea_to_text('\xc3')); +ERROR: invalid byte sequence for encoding "UTF8" +SELECT ascii(test_bytea_to_text('\xe2')); +ERROR: invalid byte sequence for encoding "UTF8" +SELECT ascii(test_bytea_to_text('\xe282')); +ERROR: invalid byte sequence for encoding "UTF8" +SELECT ascii(test_bytea_to_text('\xf0')); +ERROR: invalid byte sequence for encoding "UTF8" +SELECT ascii(test_bytea_to_text('\xf09f')); +ERROR: invalid byte sequence for encoding "UTF8" +SELECT ascii(test_bytea_to_text('\xf09f98')); +ERROR: invalid byte sequence for encoding "UTF8" +-- invalid continuation byte +SELECT ascii(test_bytea_to_text('\xc3ff')); +ERROR: invalid byte sequence for encoding "UTF8" +-- invalid leading byte +SELECT ascii(test_bytea_to_text('\x80')); +ERROR: invalid byte sequence for encoding "UTF8" DROP TABLE encoding_tests; DROP TABLE toast_4b_utf8; DROP FUNCTION test_encoding; diff --git a/src/test/regress/sql/encoding.sql b/src/test/regress/sql/encoding.sql index 07d7dc8ff18..26caa93a5d5 100644 --- a/src/test/regress/sql/encoding.sql +++ b/src/test/regress/sql/encoding.sql @@ -219,6 +219,18 @@ ALTER TABLE toast_3b_utf8 RENAME TO toast_4b_utf8; UPDATE toast_4b_utf8 SET c = repeat(U&'\+01F680', 3000); SELECT SUBSTRING(c FROM 3000 FOR 1) FROM toast_4b_utf8; +-- ascii() and multibyte characters +SELECT ascii(test_bytea_to_text('\xc3')); +SELECT ascii(test_bytea_to_text('\xe2')); +SELECT ascii(test_bytea_to_text('\xe282')); +SELECT ascii(test_bytea_to_text('\xf0')); +SELECT ascii(test_bytea_to_text('\xf09f')); +SELECT ascii(test_bytea_to_text('\xf09f98')); +-- invalid continuation byte +SELECT ascii(test_bytea_to_text('\xc3ff')); +-- invalid leading byte +SELECT ascii(test_bytea_to_text('\x80')); + DROP TABLE encoding_tests; DROP TABLE toast_4b_utf8; DROP FUNCTION test_encoding; From ba207f58f38955fdd787839eb757d48fa8c15c5b Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Mon, 10 Aug 2026 06:38:06 -0700 Subject: [PATCH 349/481] Fix errorhandling for PGP encryption PGP encryption was using px_cipher_encrypt without checking if any error was returned. When OpenSSL is running in FIPS mode, or when the legacy provider hasn't been loaded, not all ciphers which are supported by the PGP code are available and fail the init step in px_cipher_encrypt. Since the PGP encryption failed to notice this it XORed the non-encrypted block with the plaintext, effectively disabling the encryption. This was found due to a report of PGP encryption not respecting the pgcrypto.builtin_crypto_enabled flag and allowing Blowfish and DES. This however turned out to be a false positive, since the PGP code only use ciphers from OpenSSL and not the built in ciphers. Bug: #19457 Reported-by: Shishir Sharma Reviewed-by: Jacob Champion Discussion: https://postgr.es/m/19457-4bab15c17aea36c7@postgresql.org Security: CVE-2026-14663 Backpatch-through: 14 --- contrib/pgcrypto/expected/pgp-decrypt_1.out | 2 +- contrib/pgcrypto/expected/pgp-encrypt_1.out | 192 ++++++++++++++++++ .../expected/pgp-pubkey-decrypt_1.out | 2 +- contrib/pgcrypto/pgp-cfb.c | 8 +- doc/src/sgml/pgcrypto.sgml | 5 + 5 files changed, 206 insertions(+), 3 deletions(-) create mode 100644 contrib/pgcrypto/expected/pgp-encrypt_1.out diff --git a/contrib/pgcrypto/expected/pgp-decrypt_1.out b/contrib/pgcrypto/expected/pgp-decrypt_1.out index ee57ad43cb7..7d3a820e0b1 100644 --- a/contrib/pgcrypto/expected/pgp-decrypt_1.out +++ b/contrib/pgcrypto/expected/pgp-decrypt_1.out @@ -11,7 +11,7 @@ yA6Ce1QTMK3KdL2MPfamsTUSAML8huCJMwYQFfE= =JcP+ -----END PGP MESSAGE----- '), 'foobar'); -ERROR: Wrong key or corrupt data +ERROR: encrypt error: Cipher cannot be initialized select pgp_sym_decrypt(dearmor(' -----BEGIN PGP MESSAGE----- Comment: dat1.aes.sha1.mdc.s2k3.z0 diff --git a/contrib/pgcrypto/expected/pgp-encrypt_1.out b/contrib/pgcrypto/expected/pgp-encrypt_1.out new file mode 100644 index 00000000000..36b1052809c --- /dev/null +++ b/contrib/pgcrypto/expected/pgp-encrypt_1.out @@ -0,0 +1,192 @@ +-- +-- PGP encrypt +-- +select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), 'key'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- check whether the defaults are ok +select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), + 'key', 'expect-cipher-algo=aes128, + expect-disable-mdc=0, + expect-sess-key=0, + expect-s2k-mode=3, + expect-s2k-digest-algo=sha1, + expect-compress-algo=0 + '); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- maybe the expect- stuff simply does not work +select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), + 'key', 'expect-cipher-algo=bf, + expect-disable-mdc=1, + expect-sess-key=1, + expect-s2k-mode=0, + expect-s2k-digest-algo=md5, + expect-compress-algo=1 + '); +NOTICE: pgp_decrypt: unexpected cipher_algo: expected 4 got 7 +NOTICE: pgp_decrypt: unexpected s2k_mode: expected 0 got 3 +NOTICE: pgp_decrypt: unexpected s2k_digest_algo: expected 1 got 2 +NOTICE: pgp_decrypt: unexpected use_sess_key: expected 1 got 0 +NOTICE: pgp_decrypt: unexpected disable_mdc: expected 1 got 0 +NOTICE: pgp_decrypt: unexpected compress_algo: expected 1 got 0 + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- bytea as text +select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz'); +ERROR: Not text data +-- text as bytea +select encode(pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz'), 'escape'); + encode +-------- + Text +(1 row) + +-- algorithm change +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=bf'), + 'key', 'expect-cipher-algo=bf'); +ERROR: encrypt error: Cipher cannot be initialized +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes'), + 'key', 'expect-cipher-algo=aes128'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes192'), + 'key', 'expect-cipher-algo=aes192'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- s2k change +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-mode=0'), + 'key', 'expect-s2k-mode=0'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-mode=1'), + 'key', 'expect-s2k-mode=1'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-mode=3'), + 'key', 'expect-s2k-mode=3'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- s2k count change +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-count=1024'), + 'key', 'expect-s2k-count=1024'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- s2k_count rounds up +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-count=65000000'), + 'key', 'expect-s2k-count=65000000'); +NOTICE: pgp_decrypt: unexpected s2k_count: expected 65000000 got 65011712 + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- s2k digest change +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=sha1'), + 'key', 'expect-s2k-digest-algo=sha1'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- sess key +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'sess-key=0'), + 'key', 'expect-sess-key=0'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'sess-key=1'), + 'key', 'expect-sess-key=1'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=bf'), + 'key', 'expect-sess-key=1, expect-cipher-algo=bf'); +ERROR: encrypt error: Cipher cannot be initialized +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes192'), + 'key', 'expect-sess-key=1, expect-cipher-algo=aes192'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes256'), + 'key', 'expect-sess-key=1, expect-cipher-algo=aes256'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- no mdc +select pgp_sym_decrypt( + pgp_sym_encrypt('Secret.', 'key', 'disable-mdc=1'), + 'key', 'expect-disable-mdc=1'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + +-- crlf +select pgp_sym_decrypt_bytea( + pgp_sym_encrypt(E'1\n2\n3\r\n', 'key', 'convert-crlf=1'), + 'key'); + pgp_sym_decrypt_bytea +------------------------ + \x310d0a320d0a330d0d0a +(1 row) + +-- conversion should be lossless +select digest(pgp_sym_decrypt( + pgp_sym_encrypt(E'\r\n0\n1\r\r\n\n2\r', 'key', 'convert-crlf=1'), + 'key', 'convert-crlf=1'), 'sha1') as result, + digest(E'\r\n0\n1\r\r\n\n2\r', 'sha1') as expect; + result | expect +--------------------------------------------+-------------------------------------------- + \x47bde5d88d6ef8770572b9cbb4278b402aa69966 | \x47bde5d88d6ef8770572b9cbb4278b402aa69966 +(1 row) + diff --git a/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out b/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out index f41c6c9893a..7e2e1f98fca 100644 --- a/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out +++ b/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out @@ -595,7 +595,7 @@ from keytbl, encdata where keytbl.id=1 and encdata.id=1; select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=2 and encdata.id=2; -ERROR: Wrong key or corrupt data +ERROR: encrypt error: Cipher cannot be initialized select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=3 and encdata.id=3; pgp_pub_decrypt diff --git a/contrib/pgcrypto/pgp-cfb.c b/contrib/pgcrypto/pgp-cfb.c index d8f1afc3aba..b4f07c1b606 100644 --- a/contrib/pgcrypto/pgp-cfb.c +++ b/contrib/pgcrypto/pgp-cfb.c @@ -221,8 +221,14 @@ cfb_process(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst, while (len > 0) { unsigned rlen; + int err; + + err = px_cipher_encrypt(ctx->ciph, 0, ctx->fr, ctx->block_size, ctx->fre, &rlen); + if (err) + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), + errmsg("encrypt error: %s", px_strerror(err)))); - px_cipher_encrypt(ctx->ciph, 0, ctx->fr, ctx->block_size, ctx->fre, &rlen); if (ctx->block_no < 5) ctx->block_no++; diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml index 6fc2069ad3e..0692d61cae7 100644 --- a/doc/src/sgml/pgcrypto.sgml +++ b/doc/src/sgml/pgcrypto.sgml @@ -1243,6 +1243,11 @@ fips_mode() returns boolean fips disables these functions if OpenSSL is detected to operate in FIPS mode. + + pgp_sym_encrypt() and + pgp_pub_encrypt() do not use built in crypto so + they are not affected. + From d97b3f58c1c49d396841f86531bf82a315d24e86 Mon Sep 17 00:00:00 2001 From: Jacob Champion Date: Mon, 10 Aug 2026 06:38:06 -0700 Subject: [PATCH 350/481] pgcrypto: Add option to revert to prior decryption behavior The previous commit raises an ERROR during PGP operations if OpenSSL does not support the cipher in use. However, any existing messages created with faulty encryption will no longer be accessible via pgp_[sym|pub]_decrypt(). To help users out of this situation, add a new ignore-cipher-failure option which reverts to the broken behavior during decryption only. A faulty encryption wrapper, created by an OpenSSL configuration that does not support the cipher, can then be stripped back off by that same OpenSSL in order to safely reencrypt it. (Note that when OpenSSL does support the cipher, corrupted messages will not be decrypted regardless of the ignore-cipher-failure setting; this is unchanged.) The new tests add a corrupted Blowfish message for both public- and symmetric-key decryption, resulting in the following test matrix: - Blowfish supported, default behavior: fails to decrypt - Blowfish supported, ignore-cipher-failure: fails to decrypt - Blowfish unsupported, default behavior: fails to load cipher - Blowfish unsupported, ignore-cipher-failure: strips faulty encryption The previous commit's change to the pubkey tests is expanded similarly: correctly encrypted messages cannot be decrypted by an OpenSSL that does not support the cipher, regardless of the option's setting, though the failure mode will change. Suggested-by: Noah Misch Reviewed-by: Daniel Gustafsson Reviewed-by: Noah Misch Security: CVE-2026-14663 Backpatch-through: 14 --- contrib/pgcrypto/expected/pgp-decrypt.out | 26 +++++++++++++++ contrib/pgcrypto/expected/pgp-decrypt_1.out | 30 +++++++++++++++++ contrib/pgcrypto/expected/pgp-info.out | 3 +- .../pgcrypto/expected/pgp-pubkey-decrypt.out | 30 +++++++++++++++++ .../expected/pgp-pubkey-decrypt_1.out | 30 +++++++++++++++++ contrib/pgcrypto/pgp-cfb.c | 21 +++++++++--- contrib/pgcrypto/pgp-decrypt.c | 9 ++++-- contrib/pgcrypto/pgp-encrypt.c | 6 ++-- contrib/pgcrypto/pgp-pgsql.c | 2 ++ contrib/pgcrypto/pgp-pubkey.c | 9 +++++- contrib/pgcrypto/pgp.c | 9 ++++++ contrib/pgcrypto/pgp.h | 7 +++- contrib/pgcrypto/sql/pgp-decrypt.sql | 26 +++++++++++++++ contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql | 27 ++++++++++++++++ doc/src/sgml/pgcrypto.sgml | 32 +++++++++++++++++++ 15 files changed, 254 insertions(+), 13 deletions(-) diff --git a/contrib/pgcrypto/expected/pgp-decrypt.out b/contrib/pgcrypto/expected/pgp-decrypt.out index 8ce6466f2e9..cd62d52242b 100644 --- a/contrib/pgcrypto/expected/pgp-decrypt.out +++ b/contrib/pgcrypto/expected/pgp-decrypt.out @@ -439,3 +439,29 @@ UCAAw2JRIISttRHMfDpDuZJpvYo= '), 'key', 'debug=1'); NOTICE: dbg: parse_compressed_data: bzip2 unsupported ERROR: Unsupported compression algorithm +-- Check ignore-cipher-failure. This message isn't actually encrypted; it was +-- created with cipher-algo=bf using an OpenSSL that didn't actually support +-- Blowfish. After the fix for CVE-2026-14663, we no longer create these broken +-- ciphertexts, but we allow users to return to the previous behavior during +-- decryption so that the bad wrapper can be stripped. +-- +-- Note that if Blowfish is supported by the linked OpenSSL, both decryptions +-- will fail. +select pgp_sym_decrypt(dearmor(' +-----BEGIN PGP MESSAGE----- + +ww0EBAMC8wIKbtvzJtxi0jABUleCwFJWGCkYKcsNdABqdtXaU2VjcmV0LtMUlnPH3A2QBmZrcucm +1GPb/s2Bkdg= +=6aqD +-----END PGP MESSAGE----- +'), 'wrong key'); +ERROR: Wrong key or corrupt data +select pgp_sym_decrypt(dearmor(' +-----BEGIN PGP MESSAGE----- + +ww0EBAMC8wIKbtvzJtxi0jABUleCwFJWGCkYKcsNdABqdtXaU2VjcmV0LtMUlnPH3A2QBmZrcucm +1GPb/s2Bkdg= +=6aqD +-----END PGP MESSAGE----- +'), 'wrong key', 'ignore-cipher-failure=1'); +ERROR: Wrong key or corrupt data diff --git a/contrib/pgcrypto/expected/pgp-decrypt_1.out b/contrib/pgcrypto/expected/pgp-decrypt_1.out index 7d3a820e0b1..df4d28872b5 100644 --- a/contrib/pgcrypto/expected/pgp-decrypt_1.out +++ b/contrib/pgcrypto/expected/pgp-decrypt_1.out @@ -435,3 +435,33 @@ UCAAw2JRIISttRHMfDpDuZJpvYo= '), 'key', 'debug=1'); NOTICE: dbg: parse_compressed_data: bzip2 unsupported ERROR: Unsupported compression algorithm +-- Check ignore-cipher-failure. This message isn't actually encrypted; it was +-- created with cipher-algo=bf using an OpenSSL that didn't actually support +-- Blowfish. After the fix for CVE-2026-14663, we no longer create these broken +-- ciphertexts, but we allow users to return to the previous behavior during +-- decryption so that the bad wrapper can be stripped. +-- +-- Note that if Blowfish is supported by the linked OpenSSL, both decryptions +-- will fail. +select pgp_sym_decrypt(dearmor(' +-----BEGIN PGP MESSAGE----- + +ww0EBAMC8wIKbtvzJtxi0jABUleCwFJWGCkYKcsNdABqdtXaU2VjcmV0LtMUlnPH3A2QBmZrcucm +1GPb/s2Bkdg= +=6aqD +-----END PGP MESSAGE----- +'), 'wrong key'); +ERROR: encrypt error: Cipher cannot be initialized +select pgp_sym_decrypt(dearmor(' +-----BEGIN PGP MESSAGE----- + +ww0EBAMC8wIKbtvzJtxi0jABUleCwFJWGCkYKcsNdABqdtXaU2VjcmV0LtMUlnPH3A2QBmZrcucm +1GPb/s2Bkdg= +=6aqD +-----END PGP MESSAGE----- +'), 'wrong key', 'ignore-cipher-failure=1'); + pgp_sym_decrypt +----------------- + Secret. +(1 row) + diff --git a/contrib/pgcrypto/expected/pgp-info.out b/contrib/pgcrypto/expected/pgp-info.out index 90648383730..909e7f7851e 100644 --- a/contrib/pgcrypto/expected/pgp-info.out +++ b/contrib/pgcrypto/expected/pgp-info.out @@ -75,5 +75,6 @@ from encdata order by id; B68504FD128E1FF9 FD0206C409B74875 FD0206C409B74875 -(5 rows) + D936CF64BB73F466 +(6 rows) diff --git a/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out b/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out index b4b6810a3c5..d3bb5f1b06d 100644 --- a/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out +++ b/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out @@ -585,6 +585,20 @@ blH2nKZC9d6fi4YzSYMepZpMOFR65M80MCMiDUGnZBB8sEADu2/iVtqDUeG8mAA= =PHJ1 -----END PGP MESSAGE----- '); +-- CVE-2026-14663. This message was created with cipher-algo=bf using an OpenSSL +-- that didn't actually support Blowfish. +insert into encdata (id, data) values (6, ' +-----BEGIN PGP MESSAGE----- + +wcBOA9k2z2S7c/RmEAP8DYbU6AeEo6riMMdnf2G62BM9gC0Z32ODydewy3Ki8AnSzpwBDAHuDMcr +P6RJDWvBOVOwgxHEwR7ZHMoFRDJEXdo6rQ9dQpDtbasMLyi6Lm1q+PbEefVd9WkU7fvFAFQx8k3t +lxrlWg/byoNplc7/hFxIFO8bN+FIlLgilAdApNcD/3Mg2/nd7pczovsYoryf9ib04kQ+SVWs3iNE +StoyEXT+oaT8u1vAxiY7fzPpQX1pnlHBUXn+v1J6LQL5Bwi5CTqOyDSyaFfgU0gQwTReFjS6L4Fs +Cv+2cFwbJBGIzr1aI4DLbzSelkmVm4hbOVeET4DJVlUVhhIyy6ZfoXiTEG6s0jMB2JdRGIl0EUQR +RMsQdABqdt5jU2VjcmV0IG1zZ9MUIIP4SPiU2pM/nF/A1hrltMhn/ZI= +=Mkdj +-----END PGP MESSAGE----- +'); -- successful decrypt select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=1 and encdata.id=1; @@ -600,6 +614,13 @@ from keytbl, encdata where keytbl.id=2 and encdata.id=2; Secret msg (1 row) +select pgp_pub_decrypt(dearmor(data), dearmor(seckey), '', 'ignore-cipher-failure=1') +from keytbl, encdata where keytbl.id=2 and encdata.id=2; + pgp_pub_decrypt +----------------- + Secret msg +(1 row) + select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=3 and encdata.id=3; pgp_pub_decrypt @@ -654,3 +675,12 @@ from keytbl, encdata where keytbl.id=5 and encdata.id=1; select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=6 and encdata.id=5; ERROR: Wrong key or corrupt data +-- Check that ignore-cipher-failure can strip faulty encryption if OpenSSL +-- doesn't support the cipher. (The decryption will correctly fail both times if +-- OpenSSL does support it.) +select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) +from keytbl, encdata where keytbl.id=1 and encdata.id=6; +ERROR: Wrong key or corrupt data +select pgp_pub_decrypt(dearmor(data), dearmor(seckey), '', 'ignore-cipher-failure=1') +from keytbl, encdata where keytbl.id=1 and encdata.id=6; +ERROR: Wrong key or corrupt data diff --git a/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out b/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out index 7e2e1f98fca..ac9307daf5e 100644 --- a/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out +++ b/contrib/pgcrypto/expected/pgp-pubkey-decrypt_1.out @@ -585,6 +585,20 @@ blH2nKZC9d6fi4YzSYMepZpMOFR65M80MCMiDUGnZBB8sEADu2/iVtqDUeG8mAA= =PHJ1 -----END PGP MESSAGE----- '); +-- CVE-2026-14663. This message was created with cipher-algo=bf using an OpenSSL +-- that didn't actually support Blowfish. +insert into encdata (id, data) values (6, ' +-----BEGIN PGP MESSAGE----- + +wcBOA9k2z2S7c/RmEAP8DYbU6AeEo6riMMdnf2G62BM9gC0Z32ODydewy3Ki8AnSzpwBDAHuDMcr +P6RJDWvBOVOwgxHEwR7ZHMoFRDJEXdo6rQ9dQpDtbasMLyi6Lm1q+PbEefVd9WkU7fvFAFQx8k3t +lxrlWg/byoNplc7/hFxIFO8bN+FIlLgilAdApNcD/3Mg2/nd7pczovsYoryf9ib04kQ+SVWs3iNE +StoyEXT+oaT8u1vAxiY7fzPpQX1pnlHBUXn+v1J6LQL5Bwi5CTqOyDSyaFfgU0gQwTReFjS6L4Fs +Cv+2cFwbJBGIzr1aI4DLbzSelkmVm4hbOVeET4DJVlUVhhIyy6ZfoXiTEG6s0jMB2JdRGIl0EUQR +RMsQdABqdt5jU2VjcmV0IG1zZ9MUIIP4SPiU2pM/nF/A1hrltMhn/ZI= +=Mkdj +-----END PGP MESSAGE----- +'); -- successful decrypt select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=1 and encdata.id=1; @@ -596,6 +610,9 @@ from keytbl, encdata where keytbl.id=1 and encdata.id=1; select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=2 and encdata.id=2; ERROR: encrypt error: Cipher cannot be initialized +select pgp_pub_decrypt(dearmor(data), dearmor(seckey), '', 'ignore-cipher-failure=1') +from keytbl, encdata where keytbl.id=2 and encdata.id=2; +ERROR: Wrong key or corrupt data select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=3 and encdata.id=3; pgp_pub_decrypt @@ -650,3 +667,16 @@ from keytbl, encdata where keytbl.id=5 and encdata.id=1; select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=6 and encdata.id=5; ERROR: Wrong key or corrupt data +-- Check that ignore-cipher-failure can strip faulty encryption if OpenSSL +-- doesn't support the cipher. (The decryption will correctly fail both times if +-- OpenSSL does support it.) +select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) +from keytbl, encdata where keytbl.id=1 and encdata.id=6; +ERROR: encrypt error: Cipher cannot be initialized +select pgp_pub_decrypt(dearmor(data), dearmor(seckey), '', 'ignore-cipher-failure=1') +from keytbl, encdata where keytbl.id=1 and encdata.id=6; + pgp_pub_decrypt +----------------- + Secret msg +(1 row) + diff --git a/contrib/pgcrypto/pgp-cfb.c b/contrib/pgcrypto/pgp-cfb.c index b4f07c1b606..db6ec271508 100644 --- a/contrib/pgcrypto/pgp-cfb.c +++ b/contrib/pgcrypto/pgp-cfb.c @@ -43,6 +43,7 @@ struct PGP_CFB int pos; int block_no; int resync; + int ignore_decrypt_cipher_failure; /* for CVE-2026-14663 recovery */ uint8 fr[PGP_MAX_BLOCK]; uint8 fre[PGP_MAX_BLOCK]; uint8 encbuf[PGP_MAX_BLOCK]; @@ -50,7 +51,7 @@ struct PGP_CFB int pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len, - int resync, uint8 *iv) + int resync, uint8 *iv, int ignore_decrypt_cipher_failure) { int res; PX_Cipher *ciph; @@ -71,6 +72,7 @@ pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len, ctx->ciph = ciph; ctx->block_size = px_cipher_block_size(ciph); ctx->resync = resync; + ctx->ignore_decrypt_cipher_failure = ignore_decrypt_cipher_failure; if (iv) memcpy(ctx->fr, iv, ctx->block_size); @@ -195,7 +197,7 @@ mix_decrypt_resync(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst) */ static int cfb_process(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst, - mix_data_t mix_data) + mix_data_t mix_data, int ignore_cipher_failure) { int n; int res; @@ -224,7 +226,14 @@ cfb_process(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst, int err; err = px_cipher_encrypt(ctx->ciph, 0, ctx->fr, ctx->block_size, ctx->fre, &rlen); - if (err) + + /* + * XXX Ignoring cipher failures is dangerous, but we allow it during + * decryption to return to the behavior prior to the fix for + * CVE-2026-14663. This lets users recover data from a badly-encrypted + * message. + */ + if (err && !ignore_cipher_failure) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("encrypt error: %s", px_strerror(err)))); @@ -259,7 +268,8 @@ pgp_cfb_encrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst) { mix_data_t mix = ctx->resync ? mix_encrypt_resync : mix_encrypt_normal; - return cfb_process(ctx, data, len, dst, mix); + return cfb_process(ctx, data, len, dst, mix, + 0 /* never ignore cipher failures for encrypt */ ); } int @@ -267,5 +277,6 @@ pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst) { mix_data_t mix = ctx->resync ? mix_decrypt_resync : mix_decrypt_normal; - return cfb_process(ctx, data, len, dst, mix); + return cfb_process(ctx, data, len, dst, mix, + ctx->ignore_decrypt_cipher_failure); } diff --git a/contrib/pgcrypto/pgp-decrypt.c b/contrib/pgcrypto/pgp-decrypt.c index 52ca7840c6d..47ae83db789 100644 --- a/contrib/pgcrypto/pgp-decrypt.c +++ b/contrib/pgcrypto/pgp-decrypt.c @@ -595,7 +595,8 @@ decrypt_key(PGP_Context *ctx, const uint8 *src, int len) PGP_CFB *cfb; res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo, - ctx->s2k.key, ctx->s2k.key_len, 0, NULL); + ctx->s2k.key, ctx->s2k.key_len, 0, NULL, + ctx->ignore_cipher_failure); if (res < 0) return res; @@ -983,7 +984,8 @@ parse_symenc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst) PullFilter *pf_prefix = NULL; res = pgp_cfb_create(&cfb, ctx->cipher_algo, - ctx->sess_key, ctx->sess_key_len, 1, NULL); + ctx->sess_key, ctx->sess_key_len, 1, NULL, + ctx->ignore_cipher_failure); if (res < 0) goto out; @@ -1026,7 +1028,8 @@ parse_symenc_mdc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst) } res = pgp_cfb_create(&cfb, ctx->cipher_algo, - ctx->sess_key, ctx->sess_key_len, 0, NULL); + ctx->sess_key, ctx->sess_key_len, 0, NULL, + ctx->ignore_cipher_failure); if (res < 0) goto out; diff --git a/contrib/pgcrypto/pgp-encrypt.c b/contrib/pgcrypto/pgp-encrypt.c index 2c059804706..c447cdeb01c 100644 --- a/contrib/pgcrypto/pgp-encrypt.c +++ b/contrib/pgcrypto/pgp-encrypt.c @@ -174,7 +174,8 @@ encrypt_init(PushFilter *next, void *init_arg, void **priv_p) return res; } res = pgp_cfb_create(&ciph, ctx->cipher_algo, - ctx->sess_key, ctx->sess_key_len, resync, NULL); + ctx->sess_key, ctx->sess_key_len, resync, NULL, + 0 /* never ignore cipher failures for encrypt */ ); if (res < 0) return res; @@ -505,7 +506,8 @@ symencrypt_sesskey(PGP_Context *ctx, uint8 *dst) uint8 algo = ctx->cipher_algo; res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo, - ctx->s2k.key, ctx->s2k.key_len, 0, NULL); + ctx->s2k.key, ctx->s2k.key_len, 0, NULL, + 0 /* never ignore cipher failures for encrypt */ ); if (res < 0) return res; diff --git a/contrib/pgcrypto/pgp-pgsql.c b/contrib/pgcrypto/pgp-pgsql.c index d3e7895b0d9..a4b1eac71bf 100644 --- a/contrib/pgcrypto/pgp-pgsql.c +++ b/contrib/pgcrypto/pgp-pgsql.c @@ -192,6 +192,8 @@ set_arg(PGP_Context *ctx, char *key, char *val, res = pgp_set_convert_crlf(ctx, atoi(val)); else if (strcmp(key, "unicode-mode") == 0) res = pgp_set_unicode_mode(ctx, atoi(val)); + else if (strcmp(key, "ignore-cipher-failure") == 0) + res = pgp_set_ignore_cipher_failure(ctx, atoi(val)); /* * The remaining options are for debugging/testing and are therefore not diff --git a/contrib/pgcrypto/pgp-pubkey.c b/contrib/pgcrypto/pgp-pubkey.c index 6f118865917..171054cddc3 100644 --- a/contrib/pgcrypto/pgp-pubkey.c +++ b/contrib/pgcrypto/pgp-pubkey.c @@ -382,8 +382,15 @@ process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p, /* * create decrypt filter + * + * ignore-cipher-failure doesn't apply here; pgcrypto didn't encrypt + * the secret key to begin with, and any stored encrypted data was + * generated using the public key, so users don't have a reason to + * want to incorrectly decrypt this. We'll ignore failures during + * decryption with the session key, instead. */ - res = pgp_cfb_create(&cfb, cipher_algo, s2k.key, s2k.key_len, 0, iv); + res = pgp_cfb_create(&cfb, cipher_algo, s2k.key, s2k.key_len, 0, iv, + 0 /* don't ignore cipher failures */ ); if (res < 0) return res; res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt); diff --git a/contrib/pgcrypto/pgp.c b/contrib/pgcrypto/pgp.c index 8a6a6c2adf1..cf3fff90fa2 100644 --- a/contrib/pgcrypto/pgp.c +++ b/contrib/pgcrypto/pgp.c @@ -49,6 +49,7 @@ static int def_use_sess_key = 0; static int def_text_mode = 0; static int def_unicode_mode = 0; static int def_convert_crlf = 0; +static int def_ignore_cipher_failure = 0; struct digest_info { @@ -204,6 +205,7 @@ pgp_init(PGP_Context **ctx_p) ctx->unicode_mode = def_unicode_mode; ctx->convert_crlf = def_convert_crlf; ctx->text_mode = def_text_mode; + ctx->ignore_cipher_failure = def_ignore_cipher_failure; *ctx_p = ctx; return 0; @@ -349,6 +351,13 @@ pgp_set_unicode_mode(PGP_Context *ctx, int mode) return 0; } +int +pgp_set_ignore_cipher_failure(PGP_Context *ctx, int ignore) +{ + ctx->ignore_cipher_failure = ignore ? 1 : 0; + return 0; +} + int pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int len) { diff --git a/contrib/pgcrypto/pgp.h b/contrib/pgcrypto/pgp.h index 0bbfd0217ba..7b130388fcc 100644 --- a/contrib/pgcrypto/pgp.h +++ b/contrib/pgcrypto/pgp.h @@ -150,6 +150,9 @@ struct PGP_Context int convert_crlf; int unicode_mode; + /* DANGEROUS recovery aid for CVE-2026-14663. Applies only to decryption. */ + int ignore_cipher_failure; + /* * internal variables */ @@ -258,6 +261,7 @@ int pgp_set_compress_level(PGP_Context *ctx, int level); int pgp_set_text_mode(PGP_Context *ctx, int mode); int pgp_set_unicode_mode(PGP_Context *ctx, int mode); int pgp_get_unicode_mode(PGP_Context *ctx); +int pgp_set_ignore_cipher_failure(PGP_Context *ctx, int ignore); int pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int len); int pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt, @@ -278,7 +282,8 @@ int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len); typedef struct PGP_CFB PGP_CFB; int pgp_cfb_create(PGP_CFB **ctx_p, int algo, - const uint8 *key, int key_len, int resync, uint8 *iv); + const uint8 *key, int key_len, int resync, uint8 *iv, + int ignore_decrypt_cipher_failure); void pgp_cfb_free(PGP_CFB *ctx); int pgp_cfb_encrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst); int pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst); diff --git a/contrib/pgcrypto/sql/pgp-decrypt.sql b/contrib/pgcrypto/sql/pgp-decrypt.sql index b499bf757b0..7e7dc189e58 100644 --- a/contrib/pgcrypto/sql/pgp-decrypt.sql +++ b/contrib/pgcrypto/sql/pgp-decrypt.sql @@ -328,3 +328,29 @@ UCAAw2JRIISttRHMfDpDuZJpvYo= =AZ9M -----END PGP MESSAGE----- '), 'key', 'debug=1'); + +-- Check ignore-cipher-failure. This message isn't actually encrypted; it was +-- created with cipher-algo=bf using an OpenSSL that didn't actually support +-- Blowfish. After the fix for CVE-2026-14663, we no longer create these broken +-- ciphertexts, but we allow users to return to the previous behavior during +-- decryption so that the bad wrapper can be stripped. +-- +-- Note that if Blowfish is supported by the linked OpenSSL, both decryptions +-- will fail. +select pgp_sym_decrypt(dearmor(' +-----BEGIN PGP MESSAGE----- + +ww0EBAMC8wIKbtvzJtxi0jABUleCwFJWGCkYKcsNdABqdtXaU2VjcmV0LtMUlnPH3A2QBmZrcucm +1GPb/s2Bkdg= +=6aqD +-----END PGP MESSAGE----- +'), 'wrong key'); + +select pgp_sym_decrypt(dearmor(' +-----BEGIN PGP MESSAGE----- + +ww0EBAMC8wIKbtvzJtxi0jABUleCwFJWGCkYKcsNdABqdtXaU2VjcmV0LtMUlnPH3A2QBmZrcucm +1GPb/s2Bkdg= +=6aqD +-----END PGP MESSAGE----- +'), 'wrong key', 'ignore-cipher-failure=1'); diff --git a/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql b/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql index 3f2bae9e40b..40a11e0b2dc 100644 --- a/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql +++ b/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql @@ -601,6 +601,21 @@ blH2nKZC9d6fi4YzSYMepZpMOFR65M80MCMiDUGnZBB8sEADu2/iVtqDUeG8mAA= -----END PGP MESSAGE----- '); +-- CVE-2026-14663. This message was created with cipher-algo=bf using an OpenSSL +-- that didn't actually support Blowfish. +insert into encdata (id, data) values (6, ' +-----BEGIN PGP MESSAGE----- + +wcBOA9k2z2S7c/RmEAP8DYbU6AeEo6riMMdnf2G62BM9gC0Z32ODydewy3Ki8AnSzpwBDAHuDMcr +P6RJDWvBOVOwgxHEwR7ZHMoFRDJEXdo6rQ9dQpDtbasMLyi6Lm1q+PbEefVd9WkU7fvFAFQx8k3t +lxrlWg/byoNplc7/hFxIFO8bN+FIlLgilAdApNcD/3Mg2/nd7pczovsYoryf9ib04kQ+SVWs3iNE +StoyEXT+oaT8u1vAxiY7fzPpQX1pnlHBUXn+v1J6LQL5Bwi5CTqOyDSyaFfgU0gQwTReFjS6L4Fs +Cv+2cFwbJBGIzr1aI4DLbzSelkmVm4hbOVeET4DJVlUVhhIyy6ZfoXiTEG6s0jMB2JdRGIl0EUQR +RMsQdABqdt5jU2VjcmV0IG1zZ9MUIIP4SPiU2pM/nF/A1hrltMhn/ZI= +=Mkdj +-----END PGP MESSAGE----- +'); + -- successful decrypt select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=1 and encdata.id=1; @@ -608,6 +623,9 @@ from keytbl, encdata where keytbl.id=1 and encdata.id=1; select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=2 and encdata.id=2; +select pgp_pub_decrypt(dearmor(data), dearmor(seckey), '', 'ignore-cipher-failure=1') +from keytbl, encdata where keytbl.id=2 and encdata.id=2; + select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=3 and encdata.id=3; @@ -645,3 +663,12 @@ from keytbl, encdata where keytbl.id=5 and encdata.id=1; -- test for a short read from prefix_init select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=6 and encdata.id=5; + +-- Check that ignore-cipher-failure can strip faulty encryption if OpenSSL +-- doesn't support the cipher. (The decryption will correctly fail both times if +-- OpenSSL does support it.) +select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) +from keytbl, encdata where keytbl.id=1 and encdata.id=6; + +select pgp_pub_decrypt(dearmor(data), dearmor(seckey), '', 'ignore-cipher-failure=1') +from keytbl, encdata where keytbl.id=1 and encdata.id=6; diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml index 0692d61cae7..8057c172a62 100644 --- a/doc/src/sgml/pgcrypto.sgml +++ b/doc/src/sgml/pgcrypto.sgml @@ -966,6 +966,38 @@ Applies to: pgp_sym_encrypt Values: 0, 1 Default: 0 Applies to: pgp_sym_encrypt, pgp_pub_encrypt + + + + + ignore-cipher-failure + + + Dangerous! Instructs pgcrypto to use an incorrect decryption algorithm + matching the historical behavior prior to the fix for CVE-2026-14663, by + completely ignoring failures from the OpenSSL cipher in use. This is + intended only for users who need to recover incorrectly-encrypted messages + created when the cipher-algo was unavailable under the + OpenSSL configuration in use. Such faulty messages do not require the + correct decryption key when ignore-cipher-failure is + enabled, so there is no guarantee that the decrypted plaintext actually + originated from a holder of the key. + + + Contrast the case of a message which was correctly encrypted, but the cipher + that produced it is unavailable under the current OpenSSL + configuration. Recovering such plaintext via pgcrypto + requires making the actual cipher available to OpenSSL by, for example, + enabling the appropriate provider. ignore-cipher-failure + is not necessary or helpful for that scenario. If decryption + of a correctly encrypted message with this option happens to pass PGP + integrity checks, that result is coincidental and does not make the + recovered plaintext trustworthy. + + +Values: 0, 1 +Default: 0 +Applies to: pgp_sym_decrypt, pgp_pub_decrypt From 0119aa30e0fc78771681cc54e4133bf7bd3a77dd Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 10 Aug 2026 06:38:06 -0700 Subject: [PATCH 351/481] psql: Don't do backquote expansion in \unrestrict. This oversight in commit 71ea0d6795 allows a malicious server to inject shell commands into plain-text dump output that are run at restore time on the machine running psql. To fix, interpret all text after \unrestrict until the end of the line as its argument. Reported-by: Lucas Velgus Reported-by: Filip Janus Reported-by: Daniel Bakker Author: Nathan Bossart Reviewed-by: Robert Haas Reviewed-by: Noah Misch Security: CVE-2026-18408 Backpatch-through: 14 --- doc/src/sgml/ref/psql-ref.sgml | 5 +++++ src/bin/psql/command.c | 10 ++++++++-- src/bin/psql/t/001_basic.pl | 7 +++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 844cd0d5d8b..6cb2f968f12 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -3859,6 +3859,11 @@ SELECT 1 \bind \sendpipeline pg_dumpall, and pg_restore, but it may be useful elsewhere. + + Unlike most other meta-commands, the entire remainder of the line is + always taken to be the argument of \unrestrict, and + neither variable interpolation nor backquote expansion are performed. + diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 027b8ab7ed0..fc5a0d4221f 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -2790,6 +2790,12 @@ exec_command_restrict(PsqlScanState scan_state, bool active_branch, Assert(!restricted); + /* + * Unlike \unrestrict, this argument may safely undergo backquote and + * variable expansion: HandleSlashCmds() rejects \restrict in + * restricted mode before its argument is scanned, so we only get here + * when the input could execute such things anyway. + */ opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true); if (opt == NULL || opt[0] == '\0') { @@ -3198,7 +3204,7 @@ exec_command_unrestrict(PsqlScanState scan_state, bool active_branch, { char *opt; - opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true); + opt = psql_scan_slash_option(scan_state, OT_WHOLE_LINE, NULL, true); if (opt == NULL || opt[0] == '\0') { pg_log_error("\\%s: missing required argument", cmd); @@ -3222,7 +3228,7 @@ exec_command_unrestrict(PsqlScanState scan_state, bool active_branch, } } else - ignore_slash_options(scan_state); + ignore_slash_whole_line(scan_state); return PSQL_CMD_SKIP_LINE; } diff --git a/src/bin/psql/t/001_basic.pl b/src/bin/psql/t/001_basic.pl index bbd330216ae..04644f2fdfc 100644 --- a/src/bin/psql/t/001_basic.pl +++ b/src/bin/psql/t/001_basic.pl @@ -540,4 +540,11 @@ sub psql_fails_like qr/backslash commands are restricted; only \\unrestrict is allowed/, 'meta-command in restrict mode fails'); +psql_fails_like( + $node, + qq{\\restrict test +\\unrestrict `echo test`}, + qr/wrong key/, + '\unrestrict does not do backquote expansion'); + done_testing(); From 3638289fb57bdabec00deda98ee9624a35f5d66a Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 10 Aug 2026 16:50:29 -0400 Subject: [PATCH 352/481] Stamp 19beta3. --- configure | 18 +++++++++--------- configure.ac | 2 +- meson.build | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/configure b/configure index 33f11dbc8fe..765c1639022 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for PostgreSQL 19beta2. +# Generated by GNU Autoconf 2.69 for PostgreSQL 19beta3. # # Report bugs to . # @@ -582,8 +582,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='PostgreSQL' PACKAGE_TARNAME='postgresql' -PACKAGE_VERSION='19beta2' -PACKAGE_STRING='PostgreSQL 19beta2' +PACKAGE_VERSION='19beta3' +PACKAGE_STRING='PostgreSQL 19beta3' PACKAGE_BUGREPORT='pgsql-bugs@lists.postgresql.org' PACKAGE_URL='https://www.postgresql.org/' @@ -1468,7 +1468,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures PostgreSQL 19beta2 to adapt to many kinds of systems. +\`configure' configures PostgreSQL 19beta3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1533,7 +1533,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of PostgreSQL 19beta2:";; + short | recursive ) echo "Configuration of PostgreSQL 19beta3:";; esac cat <<\_ACEOF @@ -1724,7 +1724,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -PostgreSQL configure 19beta2 +PostgreSQL configure 19beta3 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2477,7 +2477,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by PostgreSQL $as_me 19beta2, which was +It was created by PostgreSQL $as_me 19beta3, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -20348,7 +20348,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by PostgreSQL $as_me 19beta2, which was +This file was extended by PostgreSQL $as_me 19beta3, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20419,7 +20419,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -PostgreSQL config.status 19beta2 +PostgreSQL config.status 19beta3 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 1f3869e994f..e6428cd0b25 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Read the Autoconf manual for details. dnl m4_pattern_forbid(^PGAC_)dnl to catch undefined macros -AC_INIT([PostgreSQL], [19beta2], [pgsql-bugs@lists.postgresql.org], [], [https://www.postgresql.org/]) +AC_INIT([PostgreSQL], [19beta3], [pgsql-bugs@lists.postgresql.org], [], [https://www.postgresql.org/]) m4_if(m4_defn([m4_PACKAGE_VERSION]), [2.69], [], [m4_fatal([Autoconf version 2.69 is required. Untested combinations of 'autoconf' and PostgreSQL versions are not diff --git a/meson.build b/meson.build index d4986ef9a23..ef5ac2134fb 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project('postgresql', ['c'], - version: '19beta2', + version: '19beta3', license: 'PostgreSQL', # We want < 0.62 for python 3.6 compatibility on old platforms. From cf9453b919c75674a9349090e02dcff1c4d2a5e9 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 11 Aug 2026 18:17:48 -0400 Subject: [PATCH 353/481] Tweak allocation rule for tzload()'s "union local_storage" variable. By default, allocate this via malloc, as we've been doing since commit 62c8421e8. Commit aeb07c55f adopted upstream tzdb's default of allocating it on the stack, but that still doesn't seem like a good idea for the reasons given in 62c8421e8 (and now memorialized in a comment, in hopes that we don't make the same mistake again). However, under USE_VALGRIND, put it on the stack as upstream does. This accidentally prevents a crash when Python 3.14 is used under Valgrind. The reasons for that are obscure, and it's most likely not our bug, and even if we figured it out it'd be nice to have a fix for buildfarm member skink now rather than after persuading the guilty party to fix it. In the normal non-USE_VALGRIND case, this has no effect on the logic in released branches, and it reverts master to match them. Reported-by: Alexander Lakhin Author: Tom Lane Discussion: https://postgr.es/m/f071e691-5930-4738-9dbd-43ed2da367fe@gmail.com Backpatch-through: 14 --- src/timezone/localtime.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/timezone/localtime.c b/src/timezone/localtime.c index fb04b4cf6bf..8b62dc226cb 100644 --- a/src/timezone/localtime.c +++ b/src/timezone/localtime.c @@ -588,17 +588,31 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, int tzload(char const *name, char *canonname, struct state *sp, bool doextend) { - union local_storage *lsp = malloc(sizeof *lsp); - + /* + * PG: by default, we allocate the "union local_storage" space via malloc, + * since it's about 70kB which seems like a lot of stack space, and we're + * hardly concerned about an extra malloc/free cycle here. But under + * USE_VALGRIND, put the variable on the stack, to intentionally increase + * the amount of stack space allocated in the postmaster. This prevents a + * bad interaction between Valgrind and Python 3.14, for reasons that are + * obscure and most likely no fault of ours. + */ + int r; + union local_storage *lsp; +#ifdef USE_VALGRIND + union local_storage ls; + + lsp = &ls; +#else + lsp = malloc(sizeof *lsp); if (!lsp) return errno; - else - { - int err = tzloadbody(name, canonname, sp, doextend, lsp); - - free(lsp); - return err; - } +#endif + r = tzloadbody(name, canonname, sp, doextend, lsp); +#ifndef USE_VALGRIND + free(lsp); +#endif + return r; } static bool From 5838806ce696dd0759c5e4b87754e802612135e0 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Wed, 12 Aug 2026 01:08:21 +0200 Subject: [PATCH 354/481] Change wal_compression=on to the first of zstd, lz4, pglz Previously, wal_compression=on was an alias for pglz, with the assumption that users could make an informed choice to pick a better option. But in practice, users rarely got to that second step. Many users don't want to be choosing algorithms - they just want WAL compression, and expect that to work well. The configuration parameter is set by administrators, who do not control the workload, and so are not in a position to evaluate the options anyway. Some users may not even realize there are other options, as previously "on" was the only choice available. This change maps "on" to non-pglz options, supported by the build. Both lz4 and zstd are faster, with a comparable (or better) compression ratio. We prefer zstd over lz4 - per our testing the better compression ratio pays for the lower (de)compression speed. Like for TOAST compression, the value depends on algorithms supported by the PostgreSQL build, with lz4 and zstd being optional. But most builds will have at least one of these external libraries. If neither zstd or lz4 is supported, we fallback to pglz. This only affects what "on" means. Users can still make the informed choice and explicitly select a compression algorithm if it works better for their system. The default value for "wal_compression" remains "off." Initial proposal and patch by wenhui qiu, reviews and patch adjustments by Christoph Berg. A number of other people participated in the discussion. Benchmarks by me. Backpatch to 19. Author: wenhui qiu Reviewed-by: Christoph Berg Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/CAGjGUAL1b=Mwd1SCvLbo+fivEr9KDpFcu4jmqKCZXwT=6CiiGQ@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/config.sgml | 12 ++++++------ src/backend/utils/misc/guc_tables.c | 8 ++++---- src/backend/utils/misc/postgresql.conf.sample | 3 ++- src/include/access/xlog.h | 13 +++++++++++++ 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 88ed724b639..20cbf01164b 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -3680,12 +3680,12 @@ include_dir 'conf.d' is on, during a base backup, etc.). A compressed page image will be decompressed during WAL replay. - The supported methods are pglz, - lz4 (if PostgreSQL - was compiled with ) and - zstd (if PostgreSQL - was compiled with ). - The value on is a historical spelling of pglz. + The supported methods are off, on, + zstd (if PostgreSQL was compiled with ), + lz4 (if PostgreSQL was compiled with ), and + pglz. + The value on selects the first of zstd, + lz4, pglz that is available. The default value is off. Only superusers and users with the appropriate SET privilege can change this setting. diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 7fd83081462..031dd60771e 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -485,13 +485,13 @@ static const struct config_enum_entry wal_compression_options[] = { #ifdef USE_ZSTD {"zstd", WAL_COMPRESSION_ZSTD, false}, #endif - {"on", WAL_COMPRESSION_PGLZ, false}, + {"on", WAL_COMPRESSION_ON, false}, {"off", WAL_COMPRESSION_NONE, false}, - {"true", WAL_COMPRESSION_PGLZ, true}, + {"true", WAL_COMPRESSION_ON, true}, {"false", WAL_COMPRESSION_NONE, true}, - {"yes", WAL_COMPRESSION_PGLZ, true}, + {"yes", WAL_COMPRESSION_ON, true}, {"no", WAL_COMPRESSION_NONE, true}, - {"1", WAL_COMPRESSION_PGLZ, true}, + {"1", WAL_COMPRESSION_ON, true}, {"0", WAL_COMPRESSION_NONE, true}, {NULL, 0, false} }; diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index f61bd6ad4de..5538ad558c7 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -262,7 +262,8 @@ #wal_log_hints = off # also do full page writes of non-critical updates # (change requires restart) #wal_compression = off # enables compression of full-page writes; - # off, pglz (or "on"), lz4, or zstd + # off, on, zstd, lz4, or pglz (on means the first + # of zstd, lz4 and pglz, supported by the build) #wal_init_zero = on # zero-fill new WAL files #wal_recycle = on # recycle WAL files #wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 4dd98624204..338d68d7424 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -87,6 +87,19 @@ typedef enum WalCompression WAL_COMPRESSION_ZSTD, } WalCompression; +/* + * Choose an appropriate default WAL compression method for wal_compression=on. + * Prefer zstd when compiled in; otherwise use lz4 if available, falling back + * to pglz. + */ +#if defined(USE_ZSTD) +#define WAL_COMPRESSION_ON WAL_COMPRESSION_ZSTD +#elif defined(USE_LZ4) +#define WAL_COMPRESSION_ON WAL_COMPRESSION_LZ4 +#else +#define WAL_COMPRESSION_ON WAL_COMPRESSION_PGLZ +#endif + /* Recovery states */ typedef enum RecoveryState { From 7ff4ee83f7aeb5650e7783cced9d662381cbd94d Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 12 Aug 2026 16:23:10 +0900 Subject: [PATCH 355/481] Fix poll_query_until() timeout handling with an undefined query in Cluster.pm On timeout, poll_query_until() would fail to print its report when "$query" was undefined. Instead of the expected report, this prevented the contents of stdout and stderr from being shown. Note that some of the in-core tests use an undefined query for connection-only polls. Author: Bryan Green Reviewed-by: Jonathan Gonzalez V. Discussion: https://postgr.es/m/0f515c6d-6032-4c5f-80ac-5c78faae9522@gmail.com Backpatch-through: 14 --- src/test/perl/PostgreSQL/Test/Cluster.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm index 529f49efee1..366519e22b5 100644 --- a/src/test/perl/PostgreSQL/Test/Cluster.pm +++ b/src/test/perl/PostgreSQL/Test/Cluster.pm @@ -2796,8 +2796,10 @@ sub poll_query_until # Give up. Print the output from the last attempt, hopefully that's useful # for debugging. + my $msg_query = $query; + $msg_query = '(connection attempt only)' unless defined $query; diag qq(poll_query_until timed out executing this query: -$query +$msg_query expecting this output: $expected last actual query output: From 7cda7b50d562a03f1c2e0c1d2f2e970acbd769e8 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Wed, 12 Aug 2026 09:41:44 +0200 Subject: [PATCH 356/481] Use per-query timeout in subscription test A buildfarm failure in subscription/038_walsnd_shutdown_timeout was diagnosed to the background psql session timing out due to a backup taking a long time. The session was using a single timeout for all queries, so switch to resetting the timer for each query to make it survive slow backups due to constrained buildfarm machines. Backpatch to v19 where the test was introduced. Author: Hayato Kuroda Discussion: https://postgr.es/m/OS9PR01MB12149AA18EEA475D2AA22FD3BF5D12@OS9PR01MB12149.jpnprd01.prod.outlook.com Backpatch-through: 19 --- src/test/subscription/t/038_walsnd_shutdown_timeout.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/subscription/t/038_walsnd_shutdown_timeout.pl b/src/test/subscription/t/038_walsnd_shutdown_timeout.pl index f4ed5d97852..fe9abd38239 100644 --- a/src/test/subscription/t/038_walsnd_shutdown_timeout.pl +++ b/src/test/subscription/t/038_walsnd_shutdown_timeout.pl @@ -46,6 +46,7 @@ # Start a background session on the subscriber to run a transaction later # that will block the logical apply worker on a lock. my $sub_session = $node_subscriber->background_psql('postgres'); +$sub_session->set_query_timer_restart(); # Test that when the logical apply worker is blocked on a lock and replication # is stalled, shutting down the publisher causes the logical walsender to exit From fd56954c9fe69bdc899d7cad93ec0b22b663cb30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Wed, 12 Aug 2026 11:53:10 +0200 Subject: [PATCH 357/481] Fix stale comments/signature after commit 28d534e2ae0a Commit db89a47115f0 added an 'options' argument to table_tuple_update() and table_tuple_delete(), correctly documenting it as recognizing no values. It also (correctly) added pg_attribute_unused() to the corresponding heap_update() argument. Commit 28d534e2ae0a then added TABLE_UPDATE_NO_LOGICAL and TABLE_DELETE_NO_LOGICAL, but failed to (correctly) update the comment and heap_update()'s signature. In table_tuple_update(), move the correct explanation of 'options' to the right place, remove the bogus one. In table_tuple_delete(), add the missing TABLE_DELETE_NO_LOGICAL doc. In heap_update(), remove the pg_attribute_unused() marker. Author: Nikhil Sontakke Backpatch-through: 19 Discussion: https://postgr.es/m/CA+UBoq21SzkjThYMSwSpVU-jwzpuEsf22Hq1FPbcKcDc43C29g@mail.gmail.com --- src/backend/access/heap/heapam.c | 2 +- src/include/access/tableam.h | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 182740c8183..3514028f427 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -3265,7 +3265,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, uint32 options pg_attribute_unused(), Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index f2c36696bca..ff03a2b816f 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -1531,6 +1531,10 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, * options - bitmask of options. Supported values: * TABLE_DELETE_CHANGING_PARTITION: the tuple is being moved to another * partition table due to an update of the partition key. + * TABLE_DELETE_NO_LOGICAL: force-disables the emitting of logical + * decoding information for the tuple. This should solely be used + * during table rewrites where RelationIsLogicallyLogged(rel) is not + * yet accurate for the new relation. * crosscheck - if not InvalidSnapshot, also check tuple against this * wait - true if should wait for any conflicting update to commit/abort * @@ -1566,12 +1570,12 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, * otid - TID of old tuple to be replaced * cid - update command ID (used for visibility test, and stored into * cmax/cmin if successful) - * options - bitmask of options. No values are currently recognized. + * options - bitmask of options. Supported values: + * TABLE_UPDATE_NO_LOGICAL: force-disables the emitting of logical + * decoding information for the tuple. This should solely be used + * during table rewrites where RelationIsLogicallyLogged(rel) is not + * yet accurate for the new relation. * crosscheck - if not InvalidSnapshot, also check old tuple against this - * options - These allow the caller to specify options that may change the - * behavior of the AM. The AM will ignore options that it does not support. - * TABLE_UPDATE_NO_LOGICAL -- force-disables the emitting of logical - * decoding information for the tuple. * * Output parameters: * slot - newly constructed tuple data to store From 94f94b245c6598f3a2b1d5ee3c463719ea83c869 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 12 Aug 2026 12:48:53 -0400 Subject: [PATCH 358/481] Fix float8_regr_accum() for Inf/NaN with constant other input. Commit 649828769 improved this code to keep Sxx, Syy, and Sxy exactly zero so long as we see only a single value of the input(s). However, if any values of the other input are Inf or NaN, we'd better set Sxy to NaN instead. Otherwise we risk reporting zero variance when the result is really undefined. The old coding handled this implicitly, but in the short-circuit path we have to take care of it explicitly. Bug: #19615 Reported-by: Junwen An Author: Andrey Rachitskiy Reviewed-by: Tom Lane Discussion: https://postgr.es/m/19615-c7e390593416f6b6@postgresql.org Backpatch-through: 19 --- src/backend/utils/adt/float.c | 11 ++++++++ src/test/regress/expected/aggregates.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/aggregates.sql | 12 ++++++++ 3 files changed, 59 insertions(+) diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 4c2ccdfbf3f..fd7a6587132 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -3456,6 +3456,17 @@ float8_regr_accum(PG_FUNCTION_ARGS) Syy += tmpY * tmpY * scale; if (isnan(commonX) && isnan(commonY)) Sxy += tmpX * tmpY * scale; + else if (isnan(newvalX) || isinf(newvalX) || + isnan(newvalY) || isinf(newvalY)) + { + /* + * If one input has been constant so far, but the other one is Inf + * or NaN this time, we must force Sxy to NaN to avoid falsely + * reporting variance zero (compare the special case for the first + * inputs, below). Sxx and Syy don't have this issue. + */ + Sxy = get_float8_nan(); + } /* * Overflow check. We only report an overflow error when finite diff --git a/src/test/regress/expected/aggregates.out b/src/test/regress/expected/aggregates.out index 1824f7db557..ec3ff8651d1 100644 --- a/src/test/regress/expected/aggregates.out +++ b/src/test/regress/expected/aggregates.out @@ -538,6 +538,42 @@ SELECT corr(1.3 + g * 1e-16, 1.3 + g * 1e-16) (1 row) +-- verify that we handle Inf/NaN the same regardless of position +with data(x) as (values (1::float8),(2::float8),(3::float8)) +select covar_pop(x, 0::float8) from data; + covar_pop +----------- + 0 +(1 row) + +with data(x) as (values ('Inf'::float8),(2::float8),(3::float8)) +select covar_pop(x, 0::float8) from data; + covar_pop +----------- + NaN +(1 row) + +with data(x) as (values (1::float8),('Inf'::float8),(3::float8)) +select covar_pop(x, 0::float8) from data; + covar_pop +----------- + NaN +(1 row) + +with data(x) as (values ('NaN'::float8),(2::float8),(3::float8)) +select covar_pop(x, 0::float8) from data; + covar_pop +----------- + NaN +(1 row) + +with data(x) as (values (1::float8),('NaN'::float8),(3::float8)) +select covar_pop(x, 0::float8) from data; + covar_pop +----------- + NaN +(1 row) + -- check some cases that formerly suffered from internal overflow/underflow SELECT corr(1e-100 + g * 1e-105, 1e-100 + g * 1e-105), regr_r2(1e-100 + g * 1e-105, 1e-100 + g * 1e-105) diff --git a/src/test/regress/sql/aggregates.sql b/src/test/regress/sql/aggregates.sql index 490c52d4c03..8a592998f25 100644 --- a/src/test/regress/sql/aggregates.sql +++ b/src/test/regress/sql/aggregates.sql @@ -149,6 +149,18 @@ SELECT corr(g, 0.09), regr_r2(g, 0.09), regr_slope(g, 0.09), regr_intercept(g, 0 SELECT corr(1.3 + g * 1e-16, 1.3 + g * 1e-16) FROM generate_series(1, 3) g; +-- verify that we handle Inf/NaN the same regardless of position +with data(x) as (values (1::float8),(2::float8),(3::float8)) +select covar_pop(x, 0::float8) from data; +with data(x) as (values ('Inf'::float8),(2::float8),(3::float8)) +select covar_pop(x, 0::float8) from data; +with data(x) as (values (1::float8),('Inf'::float8),(3::float8)) +select covar_pop(x, 0::float8) from data; +with data(x) as (values ('NaN'::float8),(2::float8),(3::float8)) +select covar_pop(x, 0::float8) from data; +with data(x) as (values (1::float8),('NaN'::float8),(3::float8)) +select covar_pop(x, 0::float8) from data; + -- check some cases that formerly suffered from internal overflow/underflow SELECT corr(1e-100 + g * 1e-105, 1e-100 + g * 1e-105), regr_r2(1e-100 + g * 1e-105, 1e-100 + g * 1e-105) From 82c86ac6822033cff10a39496925c02ca7adc532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Wed, 12 Aug 2026 19:15:48 +0200 Subject: [PATCH 359/481] Reject REPLICA IDENTITY USING INDEX on column with invalid NOT NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ALTER TABLE ... REPLICA IDENTITY USING INDEX verified key columns by reading pg_attribute.attnotnull, but commit a379061a22a8 made attnotnull true also for unvalidated (NOT VALID) not-null constraints, which do not prove the column null-free. An index over such a column could thus be marked as replica identity even though the column might contain NULLs, causing apply-side divergence for UPDATE/DELETE on the nullable rows. Fix by additionally requiring convalidated for the underlying constraint, mirroring the fix d9ffc27291f applied to ATExecAddIdentity for the analogous identity-column case. Author: Ante Krešić Reviewed-by: Aleksander Alekseev Reviewed-by: solai v Backpatch-through: 18 Discussion: https://postgr.es/m/CABXQ4dJUibZzN91qvWmsfA7MUDn9YRCNyu3CcukdyokbH1=41Q@mail.gmail.com --- src/backend/commands/tablecmds.c | 22 ++++++++++++++++++ .../regress/expected/replica_identity.out | 23 +++++++++++++++++++ src/test/regress/sql/replica_identity.sql | 16 +++++++++++++ 3 files changed, 61 insertions(+) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index c1fbe356fc9..1f2411a33a8 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -19248,6 +19248,8 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode { int16 attno = indexRel->rd_index->indkey.values[key]; Form_pg_attribute attr; + HeapTuple contup; + Form_pg_constraint conForm; /* * Reject any other system columns. (Going forward, we'll disallow @@ -19267,6 +19269,26 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode errmsg("index \"%s\" cannot be used as replica identity because column \"%s\" is nullable", RelationGetRelationName(indexRel), NameStr(attr->attname)))); + + /* + * Verify that the not-null constraint for the column is valid. + */ + contup = findNotNullConstraintAttnum(RelationGetRelid(rel), attno); + if (!HeapTupleIsValid(contup)) + elog(ERROR, "cache lookup failed for not-null constraint on column \"%s\" of relation \"%s\"", + NameStr(attr->attname), RelationGetRelationName(rel)); + conForm = (Form_pg_constraint) GETSTRUCT(contup); + if (!conForm->convalidated) + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot use index \"%s\" as replica identity", + RelationGetRelationName(indexRel)), + /*- translator: third %s is a constraint characteristic such as NOT VALID */ + errdetail("The constraint \"%s\" on column \"%s\" is marked %s.", + NameStr(conForm->conname), NameStr(attr->attname), "NOT VALID"), + errhint("You might need to validate it using %s.", + "ALTER TABLE ... VALIDATE CONSTRAINT")); + heap_freetuple(contup); } /* This index is suitable for use as a replica identity. Mark it. */ diff --git a/src/test/regress/expected/replica_identity.out b/src/test/regress/expected/replica_identity.out index 336b04fa278..87feaadbb28 100644 --- a/src/test/regress/expected/replica_identity.out +++ b/src/test/regress/expected/replica_identity.out @@ -292,10 +292,33 @@ ALTER TABLE test_replica_identity5 DROP CONSTRAINT test_replica_identity5_pkey; ERROR: constraint "test_replica_identity5_pkey" of relation "test_replica_identity5" does not exist ALTER TABLE test_replica_identity5 ALTER b DROP NOT NULL; ERROR: column "b" is in index used as replica identity +-- An invalid (NOT VALID) not-null constraint sets attnotnull but does not +-- prove the column null-free, so the index must not be accepted as replica +-- identity until the constraint is validated. +CREATE TABLE test_replica_identity6 (id int); +INSERT INTO test_replica_identity6 VALUES (1), (NULL); +ALTER TABLE test_replica_identity6 ADD CONSTRAINT id_nn NOT NULL id NOT VALID; +CREATE UNIQUE INDEX test_replica_identity6_idx ON test_replica_identity6 (id); +-- should fail +ALTER TABLE test_replica_identity6 REPLICA IDENTITY USING INDEX test_replica_identity6_idx; +ERROR: cannot use index "test_replica_identity6_idx" as replica identity +DETAIL: The constraint "id_nn" on column "id" is marked NOT VALID. +HINT: You might need to validate it using ALTER TABLE ... VALIDATE CONSTRAINT. +-- after removing offending row and validating, it should succeed +DELETE FROM test_replica_identity6 WHERE id IS NULL; +ALTER TABLE test_replica_identity6 VALIDATE CONSTRAINT id_nn; +ALTER TABLE test_replica_identity6 REPLICA IDENTITY USING INDEX test_replica_identity6_idx; +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity6'::regclass; + relreplident +-------------- + i +(1 row) + DROP TABLE test_replica_identity; DROP TABLE test_replica_identity2; DROP TABLE test_replica_identity3; DROP TABLE test_replica_identity4; DROP TABLE test_replica_identity5; +DROP TABLE test_replica_identity6; DROP TABLE test_replica_identity_othertable; DROP TABLE test_replica_identity_t3; diff --git a/src/test/regress/sql/replica_identity.sql b/src/test/regress/sql/replica_identity.sql index 30daec05b71..b202b30ae2b 100644 --- a/src/test/regress/sql/replica_identity.sql +++ b/src/test/regress/sql/replica_identity.sql @@ -134,10 +134,26 @@ ALTER TABLE test_replica_identity5 ALTER b SET NOT NULL; ALTER TABLE test_replica_identity5 DROP CONSTRAINT test_replica_identity5_pkey; ALTER TABLE test_replica_identity5 ALTER b DROP NOT NULL; +-- An invalid (NOT VALID) not-null constraint sets attnotnull but does not +-- prove the column null-free, so the index must not be accepted as replica +-- identity until the constraint is validated. +CREATE TABLE test_replica_identity6 (id int); +INSERT INTO test_replica_identity6 VALUES (1), (NULL); +ALTER TABLE test_replica_identity6 ADD CONSTRAINT id_nn NOT NULL id NOT VALID; +CREATE UNIQUE INDEX test_replica_identity6_idx ON test_replica_identity6 (id); +-- should fail +ALTER TABLE test_replica_identity6 REPLICA IDENTITY USING INDEX test_replica_identity6_idx; +-- after removing offending row and validating, it should succeed +DELETE FROM test_replica_identity6 WHERE id IS NULL; +ALTER TABLE test_replica_identity6 VALIDATE CONSTRAINT id_nn; +ALTER TABLE test_replica_identity6 REPLICA IDENTITY USING INDEX test_replica_identity6_idx; +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity6'::regclass; + DROP TABLE test_replica_identity; DROP TABLE test_replica_identity2; DROP TABLE test_replica_identity3; DROP TABLE test_replica_identity4; DROP TABLE test_replica_identity5; +DROP TABLE test_replica_identity6; DROP TABLE test_replica_identity_othertable; DROP TABLE test_replica_identity_t3; From ed23f7ce7f8f633175ae785d18577fbc440139ae Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Thu, 13 Aug 2026 13:26:47 +0900 Subject: [PATCH 360/481] doc: Clarify pgbench reporting with --continue-on-error Clarify that transactions failed under --continue-on-error are reported separately and are not counted as transactions actually processed, while time spent on them can lower reported TPS. Also adjust the latency description to avoid implying that failed transactions are generally included in latency measurements. Backpatch to v19, where pgbench's --continue-on-error option was introduced. Author: Chao Li Reviewed-by: Yugo Nagata Reviewed-by: Xuneng Zhou Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/597C9755-4386-488D-A289-16D50AD81FBF@gmail.com Backpatch-through: 19 --- doc/src/sgml/ref/pgbench.sgml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml index 2e401d1ceb8..9688527c955 100644 --- a/doc/src/sgml/ref/pgbench.sgml +++ b/doc/src/sgml/ref/pgbench.sgml @@ -770,10 +770,15 @@ pgbench options d the connection to fail. See for more information. + This option is useful when your custom script may raise errors such as unique constraint violations, but you want the benchmark - to continue and measure performance including those failures. + to continue despite individual statement failures. Failed + transactions are reported separately, but are not counted as + transactions actually processed; time spent on failed transactions + remains part of the benchmark duration, so such failures can lower + the reported TPS. @@ -2933,9 +2938,17 @@ statement latencies in milliseconds, failures and retries: The latency of a successful transaction includes the entire time of - transaction execution with rollbacks and retries. The latency is measured - only for successful transactions and commands but not for failed transactions - or commands. + transaction execution with rollbacks and retries. In the main report, + when neither , , nor + is specified, the + latency average is computed from the total benchmark + duration divided by both successful and failed transactions, and therefore + includes failed transactions. Otherwise, the latency + average and latency stddev shown in the main + report are measured only for successful transactions. Detailed latency + statistics, including the per-script and per-command reports, are also + measured only for successful transactions and commands, not for failed + transactions or commands. From dc6c9c540b5a4bf5aa2aedc8959b0d015004d45c Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Thu, 13 Aug 2026 10:10:46 +0530 Subject: [PATCH 361/481] Doc: Clarify ALTER PUBLICATION's REFRESH PUBLICATION wording. The note used a confusing "tables/except tables/schemas" slash-list, omitted DROP from the operations requiring a subscriber refresh, and called out "unset ALL SEQUENCES" without its symmetric "unset ALL TABLES" case. Reword for clarity and consistency. Author: Peter Smith Reviewed-by: Amit Kapila Backpatch-through: 19 Discussion: https://postgr.es/m/CAHut+PuGKrWhVMvuFyf-wSdF-Tai_jPTz2UCSCqsYM-82ATY5w@mail.gmail.com --- doc/src/sgml/ref/alter_publication.sgml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/ref/alter_publication.sgml b/doc/src/sgml/ref/alter_publication.sgml index 52114a16a39..925b58129b1 100644 --- a/doc/src/sgml/ref/alter_publication.sgml +++ b/doc/src/sgml/ref/alter_publication.sgml @@ -97,15 +97,16 @@ ALTER PUBLICATION name RENAME TO - Note that adding tables/except tables/schemas to a publication that is - already subscribed to will require an + Note that adding, dropping, or setting tables or schemas in a publication + that is already subscribed to will require an ALTER SUBSCRIPTION ... REFRESH PUBLICATION action on the subscribing side in order to become effective. Likewise altering a - publication to set ALL TABLES or to set or unset - ALL SEQUENCES also requires the subscriber to refresh the - publication. Note also that DROP TABLES IN SCHEMA will - not drop any schema tables that were specified using + publication to set ALL TABLES, to change the + EXCEPT list, or to set ALL SEQUENCES + also requires the subscriber to refresh the publication. Note also that + DROP TABLES IN SCHEMA will not drop any schema tables + that were specified using FOR TABLE/ ADD TABLE. From 9e725e77a5d8356a2237a15025b57d75b08e87e4 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Thu, 13 Aug 2026 14:22:39 +0900 Subject: [PATCH 362/481] vacuumdb: Use ANALYZE ONLY for partitioned tables When vacuumdb --analyze-only or --analyze-in-stages enumerates tables itself, it can select both a partitioned table and its partitions as separate work items. Previously, it generated plain ANALYZE for the partitioned table, which recursively analyzed its partitions as well. This caused duplicate work when the partitions were already selected by vacuumdb. With --analyze-in-stages, the redundant work could be repeated at every stage. Fix this by generating ANALYZE ONLY for automatically selected partitioned tables when connected to servers that support it. This updates inherited statistics for the partitioned table while leaving per-partition statistics to the separately selected partition entries. For older servers that do not support ANALYZE ONLY, vacuumdb falls back to the previous plain ANALYZE command. This also applies when partitioned tables are selected by schema filters. In that case, partitions matching the filters are analyzed as separate targets, while per-partition statistics for partitions outside the filters are not updated via the partitioned parent. This commit does not change the behavior for partitioned tables specified explicitly with --table, i.e., in that case, vacuumdb continues to generate plain ANALYZE, recursively analyzing the specified partitioned table and its partitions. Suggested-by: Justin Pryzby Author: Fujii Masao Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/aKZ7lMYGnnIo35c0@pryzbyj2023 Backpatch-through: 19 --- src/bin/scripts/t/100_vacuumdb.pl | 8 +- src/bin/scripts/vacuuming.c | 120 ++++++++++++++++++++---------- src/tools/pgindent/typedefs.list | 2 + 3 files changed, 88 insertions(+), 42 deletions(-) diff --git a/src/bin/scripts/t/100_vacuumdb.pl b/src/bin/scripts/t/100_vacuumdb.pl index 58e38971b3d..7c4e35a6717 100644 --- a/src/bin/scripts/t/100_vacuumdb.pl +++ b/src/bin/scripts/t/100_vacuumdb.pl @@ -362,12 +362,16 @@ . "INSERT INTO parent_table VALUES (1);\n"); $node->issues_sql_like( [ 'vacuumdb', '--analyze-only', 'postgres' ], - qr/statement: ANALYZE public.parent_table/s, + qr/statement: ANALYZE ONLY public.parent_table/s, '--analyze-only updates statistics for partitioned tables'); $node->issues_sql_like( [ 'vacuumdb', '--analyze-in-stages', 'postgres' ], - qr/statement: ANALYZE public.parent_table/s, + qr/statement: ANALYZE ONLY public.parent_table/s, '--analyze-in-stages updates statistics for partitioned tables'); +$node->issues_sql_like( + [ 'vacuumdb', '--analyze-only', '-t', 'parent_table', 'postgres' ], + qr/statement: ANALYZE public.parent_table/s, + '--analyze-only with --table keeps normal ANALYZE recursion'); $node->issues_sql_unlike( [ 'vacuumdb', '--analyze-only', 'postgres' ], qr/statement:\ VACUUM/sx, diff --git a/src/bin/scripts/vacuuming.c b/src/bin/scripts/vacuuming.c index 67a7665c5d7..d8c36b7d88d 100644 --- a/src/bin/scripts/vacuuming.c +++ b/src/bin/scripts/vacuuming.c @@ -23,12 +23,23 @@ #include "fe_utils/string_utils.h" #include "vacuuming.h" +typedef struct RetrievedObject +{ + char *target; + bool use_only; +} RetrievedObject; + +typedef struct RetrievedObjects +{ + int num_objects; + RetrievedObject objects[FLEXIBLE_ARRAY_MEMBER]; +} RetrievedObjects; static int vacuum_one_database(ConnParams *cparams, vacuumingOptions *vacopts, int stage, SimpleStringList *objects, - SimpleStringList **found_objs, + RetrievedObjects **found_objs, int concurrentCons, const char *progname); static int vacuum_all_databases(ConnParams *cparams, @@ -36,12 +47,13 @@ static int vacuum_all_databases(ConnParams *cparams, SimpleStringList *objects, int concurrentCons, const char *progname); -static SimpleStringList *retrieve_objects(PGconn *conn, +static RetrievedObjects *retrieve_objects(PGconn *conn, vacuumingOptions *vacopts, SimpleStringList *objects); -static void free_retrieved_objects(SimpleStringList *list); +static void free_retrieved_objects(RetrievedObjects *objs); static void prepare_vacuum_command(PGconn *conn, PQExpBuffer sql, - vacuumingOptions *vacopts, const char *table); + vacuumingOptions *vacopts, const char *table, + bool use_only); static void run_vacuum_command(ParallelSlot *free_slot, vacuumingOptions *vacopts, const char *sql, const char *table); @@ -89,7 +101,7 @@ vacuuming_main(ConnParams *cparams, const char *dbname, if (vacopts->mode == MODE_ANALYZE_IN_STAGES) { - SimpleStringList *found_objs = NULL; + RetrievedObjects *found_objs = NULL; for (int stage = 0; stage < ANALYZE_NUM_STAGES; stage++) { @@ -127,9 +139,9 @@ vacuuming_main(ConnParams *cparams, const char *dbname, * * There are two ways to specify the list of objects to process: * - * 1) The "found_objs" parameter is a double pointer to a fully qualified list - * of objects to process, as returned by a previous call to - * vacuum_one_database(). + * 1) The "found_objs" parameter is a double pointer to a list of fully + * qualified objects and their command generation metadata, as returned by + * a previous call to vacuum_one_database(). * * a) If both "found_objs" (the double pointer) and "*found_objs" (the * once-dereferenced double pointer) are not NULL, this list takes @@ -165,17 +177,16 @@ vacuum_one_database(ConnParams *cparams, vacuumingOptions *vacopts, int stage, SimpleStringList *objects, - SimpleStringList **found_objs, + RetrievedObjects **found_objs, int concurrentCons, const char *progname) { PQExpBufferData sql; PGconn *conn; - SimpleStringListCell *cell; ParallelSlotArray *sa; int ntups = 0; const char *initcmd; - SimpleStringList *retobjs = NULL; + RetrievedObjects *retobjs = NULL; bool free_retobjs = false; int ret = EXIT_SUCCESS; const char *stage_commands[] = { @@ -295,7 +306,7 @@ vacuum_one_database(ConnParams *cparams, /* * If the caller provided the results of a previous catalog query, just * use that. Otherwise, run the catalog query ourselves and set the - * return variable if provided. (If it is, then freeing the string list + * return variable if provided. (If it is, then freeing the results * becomes the caller's responsibility.) */ if (found_objs && *found_objs) @@ -309,12 +320,7 @@ vacuum_one_database(ConnParams *cparams, free_retobjs = true; } - /* - * Count the number of objects in the catalog query result. If there are - * none, we are done. - */ - for (cell = retobjs->head; cell; cell = cell->next) - ntups++; + ntups = retobjs->num_objects; if (ntups == 0) { @@ -361,10 +367,10 @@ vacuum_one_database(ConnParams *cparams, initPQExpBuffer(&sql); - cell = retobjs->head; - do + for (int i = 0; i < ntups; i++) { - const char *tabname = cell->val; + RetrievedObject *object = &retobjs->objects[i]; + const char *tabname = object->target; ParallelSlot *free_slot; if (CancelRequested) @@ -381,7 +387,7 @@ vacuum_one_database(ConnParams *cparams, } prepare_vacuum_command(free_slot->connection, &sql, - vacopts, tabname); + vacopts, tabname, object->use_only); /* * Execute the vacuum. All errors are handled in processQueryResult @@ -390,8 +396,7 @@ vacuum_one_database(ConnParams *cparams, ParallelSlotSetHandler(free_slot, TableCommandResultHandler, NULL); run_vacuum_command(free_slot, vacopts, sql.data, tabname); - cell = cell->next; - } while (cell != NULL); + } if (!ParallelSlotsWaitCompletion(sa)) { @@ -456,10 +461,10 @@ vacuum_all_databases(ConnParams *cparams, if (vacopts->mode == MODE_ANALYZE_IN_STAGES) { - SimpleStringList **found_objs = NULL; + RetrievedObjects **found_objs = NULL; if (vacopts->missing_stats_only) - found_objs = palloc0(numdbs * sizeof(SimpleStringList *)); + found_objs = palloc0(numdbs * sizeof(RetrievedObjects *)); /* * When analyzing all databases in stages, we analyze them all in the @@ -526,7 +531,7 @@ vacuum_all_databases(ConnParams *cparams, * generated qualified identifiers and to filter for the tables provided via * --table. If a listed table does not exist, the catalog query will fail. */ -static SimpleStringList * +static RetrievedObjects * retrieve_objects(PGconn *conn, vacuumingOptions *vacopts, SimpleStringList *objects) { @@ -534,8 +539,9 @@ retrieve_objects(PGconn *conn, vacuumingOptions *vacopts, PQExpBufferData catalog_query; PGresult *res; SimpleStringListCell *cell; - SimpleStringList *found_objs = palloc0_object(SimpleStringList); + RetrievedObjects *found_objs; bool objects_listed = false; + int ntups; initPQExpBuffer(&catalog_query); for (cell = objects ? objects->head : NULL; cell; cell = cell->next) @@ -588,7 +594,7 @@ retrieve_objects(PGconn *conn, vacuumingOptions *vacopts, if (objects_listed) appendPQExpBufferStr(&catalog_query, "\n)\n"); - appendPQExpBufferStr(&catalog_query, "SELECT c.relname, ns.nspname"); + appendPQExpBufferStr(&catalog_query, "SELECT c.relname, ns.nspname, c.relkind"); if (objects_listed) appendPQExpBufferStr(&catalog_query, ", listed_objects.column_list"); @@ -791,18 +797,39 @@ retrieve_objects(PGconn *conn, vacuumingOptions *vacopts, * Build qualified identifiers for each table, including the column list * if given. */ + ntups = PQntuples(res); + found_objs = palloc0(add_size(offsetof(RetrievedObjects, objects), + mul_size(sizeof(RetrievedObject), ntups))); + found_objs->num_objects = ntups; + initPQExpBuffer(&buf); - for (int i = 0; i < PQntuples(res); i++) + for (int i = 0; i < found_objs->num_objects; i++) { + RetrievedObject *object; + bool use_only; + + /* + * For automatically enumerated partitioned tables, use ONLY to + * collect inherited statistics without recursively updating + * per-partition statistics. Partitions selected by the current + * filters are processed as separate targets. + */ + use_only = ((vacopts->mode == MODE_ANALYZE || + vacopts->mode == MODE_ANALYZE_IN_STAGES) && + (vacopts->objfilter & OBJFILTER_TABLE) == 0 && + PQgetvalue(res, i, 2)[0] == RELKIND_PARTITIONED_TABLE); + appendPQExpBufferStr(&buf, fmtQualifiedIdEnc(PQgetvalue(res, i, 1), PQgetvalue(res, i, 0), PQclientEncoding(conn))); - if (objects_listed && !PQgetisnull(res, i, 2)) - appendPQExpBufferStr(&buf, PQgetvalue(res, i, 2)); + if (objects_listed && !PQgetisnull(res, i, 3)) + appendPQExpBufferStr(&buf, PQgetvalue(res, i, 3)); - simple_string_list_append(found_objs, buf.data); + object = &found_objs->objects[i]; + object->target = pg_strdup(buf.data); + object->use_only = use_only; resetPQExpBuffer(&buf); } termPQExpBuffer(&buf); @@ -818,12 +845,14 @@ retrieve_objects(PGconn *conn, vacuumingOptions *vacopts, * although retrieve_objects() will never return that. */ static void -free_retrieved_objects(SimpleStringList *list) +free_retrieved_objects(RetrievedObjects *objs) { - if (list) + if (objs) { - simple_string_list_destroy(list); - pg_free(list); + for (int i = 0; i < objs->num_objects; i++) + pg_free(objs->objects[i].target); + + pg_free(objs); } } @@ -831,18 +860,25 @@ free_retrieved_objects(SimpleStringList *list) * Construct a vacuum/analyze command to run based on the given * options, in the given string buffer, which may contain previous garbage. * - * The table name used must be already properly quoted. The command generated - * depends on the server version involved and it is semicolon-terminated. + * The table reference used must be already properly quoted. It is usually a + * table name, but may also include a column list. The command generated + * depends on the server version involved and it is semicolon-terminated. If + * use_only is set, the command targets the table with ANALYZE ONLY. */ static void prepare_vacuum_command(PGconn *conn, PQExpBuffer sql, - vacuumingOptions *vacopts, const char *table) + vacuumingOptions *vacopts, const char *table, + bool use_only) { int serverVersion = PQserverVersion(conn); const char *paren = " ("; const char *comma = ", "; const char *sep = paren; + Assert(!use_only || + vacopts->mode == MODE_ANALYZE || + vacopts->mode == MODE_ANALYZE_IN_STAGES); + resetPQExpBuffer(sql); if (vacopts->mode == MODE_ANALYZE || @@ -880,6 +916,10 @@ prepare_vacuum_command(PGconn *conn, PQExpBuffer sql, if (vacopts->verbose) appendPQExpBufferStr(sql, " VERBOSE"); } + + /* ANALYZE ONLY is supported since v18 */ + if (use_only && serverVersion >= 180000) + appendPQExpBufferStr(sql, " ONLY"); } else { diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 032ca27daa0..f416ec0f475 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -2697,6 +2697,8 @@ ResultState ResultType RetainDeadTuplesData RetainDeadTuplesPhase +RetrievedObject +RetrievedObjects ReturnSetInfo ReturnStmt ReturningClause From 5185e64ae0b220fac434f10a490bf108f01cb66a Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 13 Aug 2026 11:20:27 -0400 Subject: [PATCH 363/481] Consistently enforce tsvector/tsquery maximum lengths. Some places rejected individual tokens longer than MAXSTRLEN, while others rejected ones longer than MAXSTRLEN-1. The data structure is perfectly capable of handling MAXSTRLEN, so there's nothing wrong with using the looser bound. Moreover, as things stand there is a dump/reload hazard: some code paths permit construction of a tsvector or tsquery that would later be rejected by tsvectorin or tsqueryin. So standardize on using MAXSTRLEN. Identical remarks apply to MAXSTRPOS (the total data length), so fix that too. Back-patch, in hopes of avoiding cases where a value acceptable to one supported release is not acceptable to another. Author: Tom Lane Reviewed-by: Zsolt Parragi Discussion: https://postgr.es/m/CAN4CZFNYQo4zfbRR435uD0vSfuy5y7dnFOXDfKr9zYoL1JnAxA@mail.gmail.com Backpatch-through: 14 --- src/backend/tsearch/ts_parse.c | 4 ++-- src/backend/utils/adt/tsquery.c | 6 +++--- src/backend/utils/adt/tsvector.c | 4 ++-- src/backend/utils/adt/tsvector_op.c | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/backend/tsearch/ts_parse.c b/src/backend/tsearch/ts_parse.c index cb69e9899c5..93d46f1d642 100644 --- a/src/backend/tsearch/ts_parse.c +++ b/src/backend/tsearch/ts_parse.c @@ -379,7 +379,7 @@ parsetext(Oid cfgId, ParsedText *prs, char *buf, int buflen) PointerGetDatum(&lemm), PointerGetDatum(&lenlemm))); - if (type > 0 && lenlemm >= MAXSTRLEN) + if (type > 0 && lenlemm > MAXSTRLEN) { #ifdef IGNORE_LONGLEXEME ereport(NOTICE, @@ -582,7 +582,7 @@ hlparsetext(Oid cfgId, HeadlineParsedText *prs, TSQuery query, char *buf, int bu PointerGetDatum(&lemm), PointerGetDatum(&lenlemm))); - if (type > 0 && lenlemm >= MAXSTRLEN) + if (type > 0 && lenlemm > MAXSTRLEN) { #ifdef IGNORE_LONGLEXEME ereport(NOTICE, diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c index 7e54f36c2a7..c49b06f72bb 100644 --- a/src/backend/utils/adt/tsquery.c +++ b/src/backend/utils/adt/tsquery.c @@ -548,12 +548,12 @@ pushValue_internal(TSQueryParserState state, pg_crc32 valcrc, int distance, int { QueryOperand *tmp; - if (distance >= MAXSTRPOS) + if (distance > MAXSTRPOS) ereturn(state->escontext,, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("value is too big in tsquery: \"%s\"", state->buffer))); - if (lenval >= MAXSTRLEN) + if (lenval > MAXSTRLEN) ereturn(state->escontext,, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("operand is too long in tsquery: \"%s\"", @@ -581,7 +581,7 @@ pushValue(TSQueryParserState state, char *strval, int lenval, int16 weight, bool { pg_crc32 valcrc; - if (lenval >= MAXSTRLEN) + if (lenval > MAXSTRLEN) ereturn(state->escontext,, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("word is too long in tsquery: \"%s\"", diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c index 40be82b890a..b99878d0ca2 100644 --- a/src/backend/utils/adt/tsvector.c +++ b/src/backend/utils/adt/tsvector.c @@ -207,12 +207,12 @@ tsvectorin(PG_FUNCTION_ARGS) while (gettoken_tsvector(state, &token, &toklen, &pos, &poslen, NULL)) { - if (toklen >= MAXSTRLEN) + if (toklen > MAXSTRLEN) ereturn(escontext, (Datum) 0, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("word is too long (%d bytes, max %d bytes)", toklen, - MAXSTRLEN - 1))); + MAXSTRLEN))); if (cur - tmpbuf > MAXSTRPOS) ereturn(escontext, (Datum) 0, diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c index 935a7fae538..0ecc1fbcb2b 100644 --- a/src/backend/utils/adt/tsvector_op.c +++ b/src/backend/utils/adt/tsvector_op.c @@ -776,12 +776,12 @@ array_to_tsvector(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING), errmsg("lexeme array may not contain empty strings"))); - if (toklen >= MAXSTRLEN) + if (toklen > MAXSTRLEN) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("word is too long (%d bytes, max %d bytes)", toklen, - MAXSTRLEN - 1))); + MAXSTRLEN))); } /* Sort and de-dup, because this is required for a valid tsvector. */ From d7db169fa13a7e4db9013816c7a2c498bd304fba Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 13 Aug 2026 15:28:34 -0500 Subject: [PATCH 364/481] Reject CLUSTER (ANALYZE). The introduction of the REPACK command also added support for CLUSTER (ANALYZE). Presumably this was unintentional, as the CLUSTER docs make no mention of it. CLUSTER (ANALYZE) on an ordinary table succeeds and does indeed analyze the table, but a database-wide CLUSTER (ANALYZE) or one on a partitioned table fails with an error like: ERROR: cannot execute REPACK (ANALYZE) on multiple tables Rather than improving support for CLUSTER (ANALYZE) and thereby encouraging folks to use CLUSTER instead of REPACK, let's just reject it. This commit does so by teaching ExecRepack() to ERROR for the ANALYZE option in anything except REPACK commands. Note that VACUUM (FULL, ANALYZE) does not go through ExecRepack() and therefore is unaffected by this change. Oversight in commit ac58465e06. Reported-by: Zsolt Parragi Author: Zsolt Parragi Discussion: https://postgr.es/m/CAN4CZFMVcgv1b2G-i%2Bkhs2MDnzWSr7O_53j_x%2BuhAxUV5rwWqw%40mail.gmail.com Backpatch-through: 19 --- src/backend/commands/repack.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index dde56fb1e8d..edff54e734e 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -265,7 +265,14 @@ ExecRepack(ParseState *pstate, RepackStmt *stmt, bool isTopLevel) verbose = defGetBoolean(opt); else if (strcmp(opt->defname, "analyze") == 0 || strcmp(opt->defname, "analyse") == 0) + { + if (stmt->command != REPACK_COMMAND_REPACK) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("ANALYZE option not supported for %s", + RepackCommandAsString(stmt->command))); analyze = defGetBoolean(opt); + } else if (strcmp(opt->defname, "concurrently") == 0) { if (stmt->command != REPACK_COMMAND_REPACK) From 9db2383e0041324f01c066fa9b000750c385bfff Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 13 Aug 2026 16:35:07 -0500 Subject: [PATCH 365/481] Fix authorization check for role membership changes. Presently, check_role_membership_authorization() decides whether the current user may grant or revoke membership in a role by calling is_admin_of_role(), which recurses through all grants, while it chooses the grantor to record for the resulting entry by calling select_best_admin(), which recurses only through inherited grants. When the two disagree, the permission check passes and the grantor lookup then comes up empty, so the user sees an internal "no possible grantors" error. ALTER GROUP ... ADD USER reaches the same error through the separate check in AlterRole(). To fix, teach both checks to search the same way select_best_admin() does via a new has_admin_privs_of_role(). The new check passes exactly when the grantor lookup was going to succeed, so nothing that works today starts failing; the internal error simply becomes a proper permission error. Note that this leaves the other callers of is_admin_of_role() alone, so a role reachable only through a non-inherited grant can still be dropped, renamed, or altered. Whether that ought to change as well is left as a future exercise. Oversight in commit ce6b672e44. Reported-by: ChangAo Chen Author: ChangAo Chen Reviewed-by: Chao Li Reviewed-by: Pretham Reviewed-by: Robert Haas Reviewed-by: Jacob Champion Discussion: https://postgr.es/m/tencent_ADCE2B34B230A9B631854806104FEF40C105%40qq.com Discussion: https://postgr.es/m/CAJUn_kN%2BMhbb8fYP5xxQCq1KEziOinM6HgYx4ts_pPDnQ2y1nQ%40mail.gmail.com Backpatch-through: 16 --- src/backend/commands/user.c | 4 ++-- src/backend/utils/adt/acl.c | 27 ++++++++++++++++++++++++ src/include/utils/acl.h | 1 + src/test/regress/expected/privileges.out | 9 ++++++++ src/test/regress/sql/privileges.sql | 5 +++++ 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index be11c49f919..04b270c08a8 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -825,7 +825,7 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt) } /* To add or drop members, you need ADMIN OPTION. */ - if (drolemembers && !is_admin_of_role(currentUserId, roleid)) + if (drolemembers && !has_admin_privs_of_role(currentUserId, roleid)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied to alter role"), @@ -2165,7 +2165,7 @@ check_role_membership_authorization(Oid currentUserId, Oid roleid, /* * Otherwise, must have admin option on the role to be changed. */ - if (!is_admin_of_role(currentUserId, roleid)) + if (!has_admin_privs_of_role(currentUserId, roleid)) { if (is_grant) ereport(ERROR, diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index e2bfa77f498..090a69be071 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -5442,6 +5442,8 @@ is_member_of_role_nosuper(Oid member, Oid role) * Is member an admin of role? That is, is member the role itself (subject to * restrictions below), a member (directly or indirectly) WITH ADMIN OPTION, * or a superuser? + * + * See also has_admin_privs_of_role() below. */ bool is_admin_of_role(Oid member, Oid role) @@ -5459,6 +5461,31 @@ is_admin_of_role(Oid member, Oid role) return OidIsValid(admin_role); } +/* + * Does member hold ADMIN OPTION on role, either directly or through a role + * whose privileges member inherits? + * + * Unlike is_admin_of_role(), this does not recurse through grants that are not + * inherited. Callers that must go on to record a grantor for the operation + * should use this rather than is_admin_of_role(), since select_best_admin() + * searches the same way. + */ +bool +has_admin_privs_of_role(Oid member, Oid role) +{ + Oid admin_role; + + if (superuser_arg(member)) + return true; + + /* By policy, a role cannot have WITH ADMIN OPTION on itself. */ + if (member == role) + return false; + + (void) roles_is_member_of(member, ROLERECURSE_PRIVS, role, &admin_role); + return OidIsValid(admin_role); +} + /* * Find a role whose privileges "member" inherits which has ADMIN OPTION * on "role", ignoring super-userness. diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index a16bf2fa15a..0278d1e6a52 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -216,6 +216,7 @@ extern void check_can_set_role(Oid member, Oid role); extern bool is_member_of_role(Oid member, Oid role); extern bool is_member_of_role_nosuper(Oid member, Oid role); extern bool is_admin_of_role(Oid member, Oid role); +extern bool has_admin_privs_of_role(Oid member, Oid role); extern Oid select_best_admin(Oid member, Oid role); extern Oid get_role_oid(const char *rolname, bool missing_ok); extern Oid get_role_oid_or_public(const char *rolname); diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index ca693308e79..ce76a4d2f4d 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -78,6 +78,15 @@ SELECT grantor::regrole FROM pg_auth_members WHERE roleid = 'regress_priv_user1' regress_priv_user2 (1 row) +RESET ROLE; +REVOKE INHERIT OPTION FOR regress_priv_user2 FROM regress_priv_user3; +SET ROLE regress_priv_user3; +GRANT regress_priv_user1 TO regress_priv_user5; -- fail +ERROR: permission denied to grant role "regress_priv_user1" +DETAIL: Only roles with the ADMIN option on role "regress_priv_user1" may grant this role. +ALTER GROUP regress_priv_user1 ADD USER regress_priv_user5; -- fail +ERROR: permission denied to alter role +DETAIL: Only roles with the ADMIN option on role "regress_priv_user1" may add or drop members. RESET ROLE; REVOKE regress_priv_user2 FROM regress_priv_user3; REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE; diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index ac91511f451..9f7767fb2b9 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -60,6 +60,11 @@ SET ROLE regress_priv_user3; GRANT regress_priv_user1 TO regress_priv_user4; SELECT grantor::regrole FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole and member = 'regress_priv_user4'::regrole; RESET ROLE; +REVOKE INHERIT OPTION FOR regress_priv_user2 FROM regress_priv_user3; +SET ROLE regress_priv_user3; +GRANT regress_priv_user1 TO regress_priv_user5; -- fail +ALTER GROUP regress_priv_user1 ADD USER regress_priv_user5; -- fail +RESET ROLE; REVOKE regress_priv_user2 FROM regress_priv_user3; REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE; From 48965e14655a007c1250dbd4a1aba65e478ce929 Mon Sep 17 00:00:00 2001 From: Etsuro Fujita Date: Fri, 14 Aug 2026 17:40:01 +0900 Subject: [PATCH 366/481] postgres_fdw: Rename option "restore_stats" to "import_stats". The option added by commit 28972b6fc was named "restore_stats", because it was calling pg_restore_relation_stats()/pg_restore_attribute_stats() in place of fetching a remote rowsample. However, those code paths have been replaced with calls to import_relation_statistics()/import_attribute_statistics() (cf. commit 54cd6fc83), so the option is now slightly misnamed. Switch the option to "import_stats", which more closely reflects both the functions being called internally, and the user's perception of what the operation is doing. Back-patch to v19 where commit 28972b6fc went in. Suggested-by: Etsuro Fujita Author: Corey Huinker Discussion: https://postgr.es/m/CADkLM%3DezuspTk3VD-2EM6XtFP-Dfz7cJKtnbn0cB6gocsAgu1g%40mail.gmail.com Backpatch-through: 19 --- contrib/postgres_fdw/expected/postgres_fdw.out | 6 +++--- contrib/postgres_fdw/option.c | 8 ++++---- contrib/postgres_fdw/postgres_fdw.c | 16 ++++++++-------- contrib/postgres_fdw/sql/postgres_fdw.sql | 6 +++--- doc/src/sgml/postgres-fdw.sgml | 6 +++--- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 5a77671d35f..d5390ef62d0 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -13110,7 +13110,7 @@ CREATE TABLE simport_table (c1 int, c2 text); CREATE FOREIGN TABLE simport_ftable (c1 int, c2 text, cx int) SERVER loopback OPTIONS (table_name 'simport_table'); ALTER FOREIGN TABLE simport_ftable ALTER COLUMN cx OPTIONS (ADD column_name 'c1'); -ALTER FOREIGN TABLE simport_ftable OPTIONS (ADD restore_stats 'true'); +ALTER FOREIGN TABLE simport_ftable OPTIONS (ADD import_stats 'true'); ANALYZE simport_ftable; -- should fail WARNING: could not import statistics for foreign table "public.simport_ftable" --- remote table "public.simport_table" has no relation statistics to import ANALYZE simport_table; @@ -13195,14 +13195,14 @@ ERROR: column "c1" of relation "simport_ftable" appears more than once CREATE VIEW simport_view AS SELECT * FROM simport_table; CREATE FOREIGN TABLE simport_fview (c1 int, c2 text) SERVER loopback OPTIONS (table_name 'simport_view'); -ALTER FOREIGN TABLE simport_fview OPTIONS (ADD restore_stats 'true'); +ALTER FOREIGN TABLE simport_fview OPTIONS (ADD import_stats 'true'); ANALYZE simport_fview; -- should fail WARNING: could not import statistics for foreign table "public.simport_fview" --- remote table "public.simport_view" is of relkind "v" which cannot have statistics -- This tests build_remattrmap()'s deparsing of column names that include -- single quotes or backslashes CREATE TABLE dtest_table ("col'quote" int, "col\backslash" int); CREATE FOREIGN TABLE dtest_ftable ("col'quote" int, "col\backslash" int) - SERVER loopback OPTIONS (table_name 'dtest_table', restore_stats 'true'); + SERVER loopback OPTIONS (table_name 'dtest_table', import_stats 'true'); INSERT INTO dtest_table SELECT g, g FROM generate_series(1, 10) g; ANALYZE dtest_table; ANALYZE VERBOSE dtest_ftable; -- should work diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c index 79b16c3f318..5b539c4eeef 100644 --- a/contrib/postgres_fdw/option.c +++ b/contrib/postgres_fdw/option.c @@ -121,7 +121,7 @@ postgres_fdw_validator(PG_FUNCTION_ARGS) strcmp(def->defname, "parallel_commit") == 0 || strcmp(def->defname, "parallel_abort") == 0 || strcmp(def->defname, "keep_connections") == 0 || - strcmp(def->defname, "restore_stats") == 0 || + strcmp(def->defname, "import_stats") == 0 || strcmp(def->defname, "use_scram_passthrough") == 0) { /* these accept only boolean values */ @@ -276,9 +276,9 @@ InitPgFdwOptions(void) /* sampling is available on both server and table */ {"analyze_sampling", ForeignServerRelationId, false}, {"analyze_sampling", ForeignTableRelationId, false}, - /* restore_stats is available on both server and table */ - {"restore_stats", ForeignServerRelationId, false}, - {"restore_stats", ForeignTableRelationId, false}, + /* import_stats is available on both server and table */ + {"import_stats", ForeignServerRelationId, false}, + {"import_stats", ForeignTableRelationId, false}, {"use_scram_passthrough", ForeignServerRelationId, false}, {"use_scram_passthrough", UserMappingRelationId, false}, diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index b9739610131..0469a761a9d 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -5458,7 +5458,7 @@ analyze_row_processor(PGresult *res, int row, PgFdwAnalyzeState *astate) /* * postgresImportForeignStatistics - * Attempt to fetch/restore remote statistics instead of sampling. + * Attempt to import remote statistics instead of sampling. */ static bool postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel) @@ -5471,7 +5471,7 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel) RemoteAttributeMapping *remattrmap = NULL; int attrcnt = 0; TimestampTz starttime = 0; - bool restore_stats = false; + bool import_stats = false; bool ok = false; ListCell *lc; @@ -5481,7 +5481,7 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel) server = GetForeignServer(table->serverid); /* - * Check whether the restore_stats option is enabled on the foreign table. + * Check whether the import_stats option is enabled on the foreign table. * If not, silently ignore the foreign table. * * Server-level options can be overridden by table-level options, so check @@ -5491,9 +5491,9 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel) { DefElem *def = (DefElem *) lfirst(lc); - if (strcmp(def->defname, "restore_stats") == 0) + if (strcmp(def->defname, "import_stats") == 0) { - restore_stats = defGetBoolean(def); + import_stats = defGetBoolean(def); break; } } @@ -5501,13 +5501,13 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel) { DefElem *def = (DefElem *) lfirst(lc); - if (strcmp(def->defname, "restore_stats") == 0) + if (strcmp(def->defname, "import_stats") == 0) { - restore_stats = defGetBoolean(def); + import_stats = defGetBoolean(def); break; } } - if (!restore_stats) + if (!import_stats) return false; /* diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index 54d09040d0d..1d771391c07 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -4626,7 +4626,7 @@ CREATE TABLE simport_table (c1 int, c2 text); CREATE FOREIGN TABLE simport_ftable (c1 int, c2 text, cx int) SERVER loopback OPTIONS (table_name 'simport_table'); ALTER FOREIGN TABLE simport_ftable ALTER COLUMN cx OPTIONS (ADD column_name 'c1'); -ALTER FOREIGN TABLE simport_ftable OPTIONS (ADD restore_stats 'true'); +ALTER FOREIGN TABLE simport_ftable OPTIONS (ADD import_stats 'true'); ANALYZE simport_ftable; -- should fail @@ -4682,7 +4682,7 @@ ANALYZE simport_ftable (c1, c1); -- should fail CREATE VIEW simport_view AS SELECT * FROM simport_table; CREATE FOREIGN TABLE simport_fview (c1 int, c2 text) SERVER loopback OPTIONS (table_name 'simport_view'); -ALTER FOREIGN TABLE simport_fview OPTIONS (ADD restore_stats 'true'); +ALTER FOREIGN TABLE simport_fview OPTIONS (ADD import_stats 'true'); ANALYZE simport_fview; -- should fail @@ -4690,7 +4690,7 @@ ANALYZE simport_fview; -- should fail -- single quotes or backslashes CREATE TABLE dtest_table ("col'quote" int, "col\backslash" int); CREATE FOREIGN TABLE dtest_ftable ("col'quote" int, "col\backslash" int) - SERVER loopback OPTIONS (table_name 'dtest_table', restore_stats 'true'); + SERVER loopback OPTIONS (table_name 'dtest_table', import_stats 'true'); INSERT INTO dtest_table SELECT g, g FROM generate_series(1, 10) g; ANALYZE dtest_table; diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml index 8b0669f672d..171a009b610 100644 --- a/doc/src/sgml/postgres-fdw.sgml +++ b/doc/src/sgml/postgres-fdw.sgml @@ -365,13 +365,13 @@ OPTIONS (ADD password_required 'false'); - restore_stats (boolean) + import_stats (boolean) This option, which can be specified for a foreign table or a foreign server, determines if ANALYZE on a foreign table will instead attempt to fetch the existing statistics for the foreign - table on the remote server, and restore those statistics directly to + table on the remote server, and import those statistics directly to the local server. If the attempt failed, statistics are collected by row sampling on the foreign table. This option is only useful if the remote table is one that can have @@ -386,7 +386,7 @@ OPTIONS (ADD password_required 'false'); If the foreign table is a partition of a partitioned table, analyzing the partitioned table will still result in row sampling on the foreign table regardless of this setting, though direct analysis of the foreign - table would have attempted to fetch and restore remote statistics first. + table would have attempted to fetch and import remote statistics first. From f3a116a26ff0c0be83b990d3d9b3fd9e425bb197 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 14 Aug 2026 11:43:19 +0200 Subject: [PATCH 367/481] Enforce WITH CHECK OPTION on DELETE FOR PORTION OF leftovers DELETE FOR PORTION OF inserts temporal leftovers through ExecInsert(), but the rewriter only attached view WCOs for INSERT/UPDATE. Leftover rows could therefore silently escape a WITH CHECK OPTION view, while the equivalent UPDATE correctly raised an error. This commit fixes it by attaching the WCOs for FOR PORTION OF deletes too. Author: Zsolt Parragi Co-authored-by: Paul A Jungwirth Reviewed-by: solai v Reviewed-by: Dean Rasheed Discussion: https://www.postgresql.org/message-id/flat/CAN4CZFOuTyhGspG0Nyits8PiK2keoNXkLj-u3APzc66aRcWY9A%40mail.gmail.com --- doc/src/sgml/ref/create_view.sgml | 20 ++++--- src/backend/rewrite/rewriteHandler.c | 8 ++- src/test/regress/expected/updatable_views.out | 56 +++++++++++++++++++ src/test/regress/sql/updatable_views.sql | 29 ++++++++++ 4 files changed, 104 insertions(+), 9 deletions(-) diff --git a/doc/src/sgml/ref/create_view.sgml b/doc/src/sgml/ref/create_view.sgml index 60215eba3b8..2c08f7e3cff 100644 --- a/doc/src/sgml/ref/create_view.sgml +++ b/doc/src/sgml/ref/create_view.sgml @@ -197,11 +197,12 @@ CREATE VIEW [ schema . ] view_nameCHECK OPTION is not specified, - INSERT, UPDATE, and - MERGE commands on the view are - allowed to create rows that are not visible through the view. The - following check options are supported: + rejected. The temporal + leftovers inserted by an UPDATE or + DELETE with a FOR PORTION OF clause + are checked in the same way. If the CHECK OPTION is + not specified, these commands are allowed to create rows that are not + visible through the view. The following check options are supported: @@ -431,10 +432,13 @@ CREATE VIEW vista AS SELECT text 'Hello World' AS hello; potentially insert base-relation rows that do not satisfy the WHERE condition and thus are not visible through the view (ON CONFLICT DO SELECT/UPDATE may - similarly affect an existing row not visible through the view). + similarly affect an existing row not visible through the view). An + UPDATE or DELETE with a + FOR PORTION OF clause can do so as well, since the + temporal leftovers it inserts may fall outside the + WHERE condition. The CHECK OPTION may be used to prevent - INSERT, UPDATE, and - MERGE commands from creating such rows that are not + these commands from creating such rows that are not visible through the view. diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 38f54b57eec..3e43418e996 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -3953,8 +3953,14 @@ rewriteTargetView(Query *parsetree, Relation view) * the WITH CHECK OPTION, or any parent view specified WITH CASCADED CHECK * OPTION, add the quals from the view to the query's withCheckOptions * list. + * + * DELETE FOR PORTION OF needs this too: it inserts temporal leftovers to + * preserve the untouched parts of the deleted row, and those must not + * escape the view either. For UPDATE, any WCO we add below will apply to + * inserted leftovers as well. */ - if (insert_or_update) + if (insert_or_update || + (parsetree->commandType == CMD_DELETE && parsetree->forPortionOf != NULL)) { bool has_wco = RelationHasCheckOption(view); bool cascaded = RelationHasCascadedCheckOption(view); diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out index 9c6bb2219f9..b4b4e93a7dd 100644 --- a/src/test/regress/expected/updatable_views.out +++ b/src/test/regress/expected/updatable_views.out @@ -3768,6 +3768,62 @@ delete from uv_fpo_view_nonupd for portion of valid_at from 1 to 10; ERROR: cannot delete from view "uv_fpo_view_nonupd" using FOR PORTION OF "valid_at" DETAIL: View columns that are not columns of their base relation are not updatable. drop view uv_fpo_view_nonupd; +-- WITH CHECK OPTION must be enforced on temporal leftovers, i.e. the rows +-- FOR PORTION OF inserts to preserve the untouched parts of the target row. +-- This applies to DELETE as well as UPDATE. +create table uv_fpo_wco_tab (id int4range, valid_at daterange, b int); +insert into uv_fpo_wco_tab values ('[1,1]', '[2020-01-01,2030-01-01)', 0); +create view uv_fpo_wco_view as + select * from uv_fpo_wco_tab + where valid_at && daterange('2024-01-01', '2025-01-01') + with check option; +-- The leftovers fall outside the view, so both commands fail: +update uv_fpo_wco_view for portion of valid_at from '2024-01-01' to '2025-01-01' set b = 1; +ERROR: new row violates check option for view "uv_fpo_wco_view" +DETAIL: Failing row contains ([1,2), [01-01-2020,01-01-2024), 0). +delete from uv_fpo_wco_view for portion of valid_at from '2024-01-01' to '2025-01-01'; +ERROR: new row violates check option for view "uv_fpo_wco_view" +DETAIL: Failing row contains ([1,2), [01-01-2020,01-01-2024), 0). +-- The base table is unchanged: +select * from uv_fpo_wco_tab order by valid_at; + id | valid_at | b +-------+-------------------------+--- + [1,2) | [01-01-2020,01-01-2030) | 0 +(1 row) + +-- Leftovers that still satisfy the view are allowed: +delete from uv_fpo_wco_view for portion of valid_at from '2024-03-01' to '2024-06-01'; +update uv_fpo_wco_view for portion of valid_at from '2024-07-01' to '2024-08-01' set b = 1; +select * from uv_fpo_wco_tab order by valid_at; + id | valid_at | b +-------+-------------------------+--- + [1,2) | [01-01-2020,03-01-2024) | 0 + [1,2) | [06-01-2024,07-01-2024) | 0 + [1,2) | [07-01-2024,08-01-2024) | 1 + [1,2) | [08-01-2024,01-01-2030) | 0 +(4 rows) + +-- Without WITH CHECK OPTION the leftovers may leave the view: +create view uv_fpo_nowco_view as + select * from uv_fpo_wco_tab + where valid_at && daterange('2024-01-01', '2025-01-01'); +delete from uv_fpo_nowco_view for portion of valid_at from '2024-01-01' to '2024-02-01'; +update uv_fpo_nowco_view for portion of valid_at from '2024-09-01' to '2026-01-01' set b = 2; +select * from uv_fpo_wco_tab order by valid_at; + id | valid_at | b +-------+-------------------------+--- + [1,2) | [01-01-2020,01-01-2024) | 0 + [1,2) | [02-01-2024,03-01-2024) | 0 + [1,2) | [06-01-2024,07-01-2024) | 0 + [1,2) | [07-01-2024,08-01-2024) | 1 + [1,2) | [08-01-2024,09-01-2024) | 0 + [1,2) | [09-01-2024,01-01-2026) | 2 + [1,2) | [01-01-2026,01-01-2030) | 0 +(7 rows) + +drop view uv_fpo_wco_view; +drop view uv_fpo_nowco_view; +drop table uv_fpo_wco_tab; -- Test whole-row references to the view create table uv_iocu_tab (a int unique, b text); create view uv_iocu_view as diff --git a/src/test/regress/sql/updatable_views.sql b/src/test/regress/sql/updatable_views.sql index 2ef9aa32f36..3ddb7b43cc8 100644 --- a/src/test/regress/sql/updatable_views.sql +++ b/src/test/regress/sql/updatable_views.sql @@ -1914,6 +1914,35 @@ update uv_fpo_view_nonupd for portion of valid_at from 1 to 10 set b = 2; delete from uv_fpo_view_nonupd for portion of valid_at from 1 to 10; drop view uv_fpo_view_nonupd; +-- WITH CHECK OPTION must be enforced on temporal leftovers, i.e. the rows +-- FOR PORTION OF inserts to preserve the untouched parts of the target row. +-- This applies to DELETE as well as UPDATE. +create table uv_fpo_wco_tab (id int4range, valid_at daterange, b int); +insert into uv_fpo_wco_tab values ('[1,1]', '[2020-01-01,2030-01-01)', 0); +create view uv_fpo_wco_view as + select * from uv_fpo_wco_tab + where valid_at && daterange('2024-01-01', '2025-01-01') + with check option; +-- The leftovers fall outside the view, so both commands fail: +update uv_fpo_wco_view for portion of valid_at from '2024-01-01' to '2025-01-01' set b = 1; +delete from uv_fpo_wco_view for portion of valid_at from '2024-01-01' to '2025-01-01'; +-- The base table is unchanged: +select * from uv_fpo_wco_tab order by valid_at; +-- Leftovers that still satisfy the view are allowed: +delete from uv_fpo_wco_view for portion of valid_at from '2024-03-01' to '2024-06-01'; +update uv_fpo_wco_view for portion of valid_at from '2024-07-01' to '2024-08-01' set b = 1; +select * from uv_fpo_wco_tab order by valid_at; +-- Without WITH CHECK OPTION the leftovers may leave the view: +create view uv_fpo_nowco_view as + select * from uv_fpo_wco_tab + where valid_at && daterange('2024-01-01', '2025-01-01'); +delete from uv_fpo_nowco_view for portion of valid_at from '2024-01-01' to '2024-02-01'; +update uv_fpo_nowco_view for portion of valid_at from '2024-09-01' to '2026-01-01' set b = 2; +select * from uv_fpo_wco_tab order by valid_at; +drop view uv_fpo_wco_view; +drop view uv_fpo_nowco_view; +drop table uv_fpo_wco_tab; + -- Test whole-row references to the view create table uv_iocu_tab (a int unique, b text); create view uv_iocu_view as From 41a300ae3df5015d0779728ee0b4adb866953d31 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 14 Aug 2026 14:53:50 +0200 Subject: [PATCH 368/481] Make generate_queries_for_path_pattern_recurse() interruptible In case of a very long path pattern with each element pattern being resolved to many graph elements generate_queries_for_path_pattern_recurse() may take very long time to generate all the possible graph paths. Make generate_queries_for_path_pattern_recurse() interruptible so that a user may be able to cancel such a query if required and the interrupts are processed in timely manner. Author: Satyanarayana Narlapuram Reviewed-by: Ashutosh Bapat Discussion: https://www.postgresql.org/message-id/flat/CAHg%2BQDfDwcM4%3DDSiAV6Ly89YQ5EcMhzO1-9x%3DmGG1WJzODcAig%40mail.gmail.com --- src/backend/rewrite/rewriteGraphTable.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backend/rewrite/rewriteGraphTable.c b/src/backend/rewrite/rewriteGraphTable.c index cdb1f4c0dca..0eaf28b3de5 100644 --- a/src/backend/rewrite/rewriteGraphTable.c +++ b/src/backend/rewrite/rewriteGraphTable.c @@ -367,6 +367,8 @@ generate_queries_for_path_pattern_recurse(RangeTblEntry *rte, List *pathqueries, foreach_ptr(struct path_element, pe, path_elems) { + CHECK_FOR_INTERRUPTS(); + /* Update current path being built with current element. */ cur_path = lappend(cur_path, pe); From 7f8de6d877c2440480eb4fcd2fd6a503a373065f Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 14 Aug 2026 12:14:24 -0400 Subject: [PATCH 369/481] psql: count every COPY FROM STDIN when scanning a query string. When SendQuery() is not told how many COPY FROM STDIN commands the query string contains (as for -c, \gexec, and \watch), it scans the string to count them itself. But it called psql_scan() only once, which stops at the first semicolon, so any COPY FROM STDIN past the first sub-command was not counted, causing failure of cases that used to work. Oversight in commit 3045a25ba. Author: Zsolt Parragi Reviewed-by: Tom Lane Discussion: https://postgr.es/m/CAN4CZFPqa6c+u4uX5jJ8LANHTQ4dxM3m4_8G9WmX_A4-2wuv2A@mail.gmail.com Backpatch-through: 14 --- src/bin/psql/common.c | 25 +++++++++++++++++++++++-- src/bin/psql/t/001_basic.pl | 30 ++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 7ca890eac6f..305c423e196 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -1796,15 +1796,36 @@ ExecQueryAndProcessResults(const char *query, PsqlScanState scan_state; PQExpBuffer query_buf; promptStatus_t prompt_tmp; + PsqlScanResult scan_result; scan_state = psql_scan_create(&psqlscan_callbacks); psql_scan_setup(scan_state, query, strlen(query), pset.encoding, standard_strings()); query_buf = createPQExpBuffer(); - (void) psql_scan(scan_state, query_buf, &prompt_tmp); + /* + * A semicolon ends only one sub-command; keep scanning so that COPY + * FROM STDIN commands past the first semicolon are counted too. The + * count accumulates in scan_state across the psql_scan() calls. + */ + do + { + scan_result = psql_scan(scan_state, query_buf, &prompt_tmp); + } while (scan_result == PSCAN_SEMICOLON); - num_copy_from_stdin = psql_scan_count_copy_from_stdin(scan_state); + /* + * We expect the result now to be PSCAN_EOL. If it is PSCAN_BACKSLASH + * or PSCAN_INCOMPLETE, the server will get a parse error and refuse + * to execute any part of the command string, so don't expect any + * PGRES_COPY_IN results. (This will mean that we don't attempt to + * discard any following data, but this seems consistent with the + * general contract of psql_scan_count_copy_from_stdin, which is that + * it only promises to count syntactically-valid COPY commands.) + */ + if (scan_result == PSCAN_EOL) + num_copy_from_stdin = psql_scan_count_copy_from_stdin(scan_state); + else + num_copy_from_stdin = 0; destroyPQExpBuffer(query_buf); psql_scan_destroy(scan_state); diff --git a/src/bin/psql/t/001_basic.pl b/src/bin/psql/t/001_basic.pl index 04644f2fdfc..028df33ce8a 100644 --- a/src/bin/psql/t/001_basic.pl +++ b/src/bin/psql/t/001_basic.pl @@ -533,6 +533,36 @@ sub psql_fails_like qr/COPY in a pipeline is not supported, aborting connection/, '\copy to in pipeline: fails'); +# Test execution of COPY FROM STDIN in -c. This case is a bit weird +# because it will read from psql's stdin not from the command source. +# To make it even weirder, try two such commands, to stress psql's logic +# that counts them. Also test both \. and EOF termination. +{ + $node->safe_psql('postgres', 'CREATE TABLE copy_stdin_count (a int)'); + my ($stdin, $stdout, $stderr) = ("50\n\\.\n60\n", '', ''); + my $ret = IPC::Run::run( + [ + 'psql', '--no-psqlrc', + '--set' => 'ON_ERROR_STOP=1', + '--dbname' => $node->connstr('postgres'), + '--command' => + 'COPY copy_stdin_count FROM STDIN; COPY copy_stdin_count FROM STDIN', + ], + '<' => \$stdin, + '>' => \$stdout, + '2>' => \$stderr); + + ok($ret, '-c COPY FROM STDIN: psql exits 0'); + unlike( + $stderr, + qr/unexpected COPY_IN result/, + '-c COPY FROM STDIN: unexpected COPY_IN result'); + + my $data = $node->safe_psql('postgres', 'SELECT * FROM copy_stdin_count'); + is($data, "50\n60", '-c COPY FROM STDIN: correct data loaded'); +} + +# Test \restrict and \unrestrict. psql_fails_like( $node, qq{\\restrict test From e19cd26f06c9ed4a6994accbbdcbef9ab05b2ad1 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Fri, 14 Aug 2026 13:41:32 -0500 Subject: [PATCH 370/481] Add missing PGDLLIMPORT marker. Oversight in commit ffca23839c. Reported-by: Anton Voloshin Author: Anton Voloshin Backpatch-through: 14 --- src/include/utils/acl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index 0278d1e6a52..4f2a3c59904 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -230,7 +230,7 @@ extern void select_best_grantor(const RoleSpec *grantedBy, AclMode privileges, Oid *grantorId, AclMode *grantOptions); /* DATABASEOID syscache hash value for our own database, set by initialize_acl */ -extern uint32 cached_db_hash; +extern PGDLLIMPORT uint32 cached_db_hash; extern void initialize_acl(void); From de73e691e7f53a4fe08f09928a9f72331476a439 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Fri, 14 Aug 2026 21:52:06 +0200 Subject: [PATCH 371/481] Use int64 for number of entries in pg_stat_statements Commit 13b935cd changed hash_get_num_entries to return int64 instead of long. This fixes a few more users of hash_get_num_entries which were missed in the original commit. PGSS_FILE_HEADER is left unchanged since this only affects as of yet unreleased versions of PostgreSQL. Backpatch to v19 where the int64 change was performed. Author: Karina Litskevich Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CACiT8iYTkc33YWaA2D3t51Y5s=GqBO7T1zX7bkpSmet2njcLLw@mail.gmail.com Backpatch-through: 19 --- contrib/pg_stat_statements/pg_stat_statements.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index d1d8dd34f25..f9938336192 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -506,7 +506,7 @@ static void pgss_shmem_request(void *arg) { ShmemRequestHash(.name = "pg_stat_statements hash", - .nelems = pgss_max, + .nelems = (int64) pgss_max, .hash_info.keysize = sizeof(pgssHashKey), .hash_info.entrysize = sizeof(pgssEntry), .hash_flags = HASH_ELEM | HASH_BLOBS, @@ -533,9 +533,8 @@ pgss_shmem_init(void *arg) FILE *file = NULL; FILE *qfile = NULL; uint32 header; - int32 num; + int64 num; int32 pgver; - int32 i; int buffer_size; char *buffer = NULL; @@ -612,14 +611,14 @@ pgss_shmem_init(void *arg) if (fread(&header, sizeof(uint32), 1, file) != 1 || fread(&pgver, sizeof(uint32), 1, file) != 1 || - fread(&num, sizeof(int32), 1, file) != 1) + fread(&num, sizeof(int64), 1, file) != 1) goto read_error; if (header != PGSS_FILE_HEADER || pgver != PGSS_PG_MAJOR_VERSION) goto data_error; - for (i = 0; i < num; i++) + for (int64 i = 0; i < num; i++) { pgssEntry temp; pgssEntry *entry; @@ -737,7 +736,7 @@ pgss_shmem_shutdown(int code, Datum arg) char *qbuffer = NULL; Size qbuffer_size = 0; HASH_SEQ_STATUS hash_seq; - int32 num_entries; + int64 num_entries; pgssEntry *entry; /* Don't try to dump during a crash. */ @@ -761,7 +760,7 @@ pgss_shmem_shutdown(int code, Datum arg) if (fwrite(&PGSS_PG_MAJOR_VERSION, sizeof(uint32), 1, file) != 1) goto error; num_entries = hash_get_num_entries(pgss_hash); - if (fwrite(&num_entries, sizeof(int32), 1, file) != 1) + if (fwrite(&num_entries, sizeof(int64), 1, file) != 1) goto error; qbuffer = qtext_load_file(&qbuffer_size); @@ -2086,7 +2085,7 @@ entry_alloc(pgssHashKey *key, Size query_offset, int query_len, int encoding, bool found; /* Make space if needed */ - while (hash_get_num_entries(pgss_hash) >= pgss_max) + while (hash_get_num_entries(pgss_hash) >= (int64) pgss_max) entry_dealloc(); /* Find or create an entry with desired hash code */ From 16742849a3dea3d8e6331471cb5134ca4aec14b2 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Fri, 14 Aug 2026 15:27:16 -0500 Subject: [PATCH 372/481] doc: Clarify the logging collector's guarantees. Presently, the documentation for logging_collector says that the collector "is designed to never lose messages," which reads as a stronger promise than we actually make. The collector does not fsync the log file or retry failed writes, so log messages can go missing after an operating system crash, power loss, or a write error. Reword that sentence and add a note about what is not guaranteed. Author: Daniel Bauman Reviewed-by: Fujii Masao Reviewed-by: Zhenwei Shang Reviewed-by: Robert Treat Discussion: https://postgr.es/m/CAMtj0_a86DdDKkW-ReVpQpqjndVS6GMrwXVpQY4G3-SGY7saMQ%40mail.gmail.com Backpatch-through: 14 --- doc/src/sgml/config.sgml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 20cbf01164b..97aeadfc35f 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -7138,7 +7138,7 @@ local0.* /var/log/postgresql - The logging collector is designed to never lose messages. This means + The logging collector is designed to avoid dropping messages. This means that in case of extremely high load, server processes could be blocked while trying to send additional log messages when the collector has fallen behind. In contrast, syslog @@ -7146,6 +7146,11 @@ local0.* /var/log/postgresql may fail to log some messages in such cases but it will not block the rest of the system. + + The logging collector does not guarantee that log messages have + reached durable storage. It can still lose messages due to a system + crash, power loss, or an error while writing the log file. + From 3ab3f33281f62bdcef1dd987a89fcfe7f082b6d8 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Sat, 15 Aug 2026 18:12:14 +0900 Subject: [PATCH 373/481] Rename EXISTS-to-ANY converted subplan to exists_to_any Simple EXISTS subplans can be converted to hashed ANY subplans as an alternative implementation. Previously, both the original EXISTS subplan and the converted ANY subplan used names with the exists_ prefix, making EXPLAIN output harder to read and pg_plan_advice targets less clear. Use the exists_to_any_ prefix for converted ANY subplans so that their names distinguish them from the original EXISTS alternative. This only changes the names shown by EXPLAIN and used by plan advice; it does not affect planner behavior. Author: Yugo Nagata Reviewed-by: Tom Lane Reviewed-by: solai v Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/20260605165641.3950f99ace0aad8f807abe96@sraoss.co.jp Backpatch-through: 19 --- .../pg_plan_advice/expected/alternatives.out | 30 +++++++++---------- contrib/pg_plan_advice/sql/alternatives.sql | 2 +- src/backend/optimizer/plan/subselect.c | 8 +++-- src/test/regress/expected/partition_prune.out | 10 +++---- src/test/regress/expected/subselect.out | 16 +++++----- 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/contrib/pg_plan_advice/expected/alternatives.out b/contrib/pg_plan_advice/expected/alternatives.out index a6fb296d4b4..94bfcf3d0a2 100644 --- a/contrib/pg_plan_advice/expected/alternatives.out +++ b/contrib/pg_plan_advice/expected/alternatives.out @@ -12,15 +12,15 @@ VACUUM ANALYZE alt_t2; EXPLAIN (COSTS OFF, PLAN_ADVICE) SELECT * FROM alt_t1 WHERE EXISTS (SELECT 1 FROM alt_t2 WHERE alt_t2.a = alt_t1.a) OR alt_t1.a < 0; - QUERY PLAN -------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Seq Scan on alt_t1 - Filter: ((ANY (a = (hashed SubPlan exists_2).col1)) OR (a < 0)) - SubPlan exists_2 + Filter: ((ANY (a = (hashed SubPlan exists_to_any_1).col1)) OR (a < 0)) + SubPlan exists_to_any_1 -> Seq Scan on alt_t2 Generated Plan Advice: - SEQ_SCAN(alt_t1 alt_t2@exists_2) - NO_GATHER(alt_t1 alt_t2@exists_2) + SEQ_SCAN(alt_t1 alt_t2@exists_to_any_1) + NO_GATHER(alt_t1 alt_t2@exists_to_any_1) DO_NOT_SCAN(alt_t2@exists_1) (8 rows) @@ -31,21 +31,21 @@ SET LOCAL pg_plan_advice.advice = 'DO_NOT_SCAN(alt_t2@exists_1)'; EXPLAIN (COSTS OFF, PLAN_ADVICE) SELECT * FROM alt_t1 WHERE EXISTS (SELECT 1 FROM alt_t2 WHERE alt_t2.a = alt_t1.a) OR alt_t1.a < 0; - QUERY PLAN -------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Seq Scan on alt_t1 - Filter: ((ANY (a = (hashed SubPlan exists_2).col1)) OR (a < 0)) - SubPlan exists_2 + Filter: ((ANY (a = (hashed SubPlan exists_to_any_1).col1)) OR (a < 0)) + SubPlan exists_to_any_1 -> Seq Scan on alt_t2 Supplied Plan Advice: DO_NOT_SCAN(alt_t2@exists_1) /* matched */ Generated Plan Advice: - SEQ_SCAN(alt_t1 alt_t2@exists_2) - NO_GATHER(alt_t1 alt_t2@exists_2) + SEQ_SCAN(alt_t1 alt_t2@exists_to_any_1) + NO_GATHER(alt_t1 alt_t2@exists_to_any_1) DO_NOT_SCAN(alt_t2@exists_1) (10 rows) -SET LOCAL pg_plan_advice.advice = 'DO_NOT_SCAN(alt_t2@exists_2)'; +SET LOCAL pg_plan_advice.advice = 'DO_NOT_SCAN(alt_t2@exists_to_any_1)'; EXPLAIN (COSTS OFF, PLAN_ADVICE) SELECT * FROM alt_t1 WHERE EXISTS (SELECT 1 FROM alt_t2 WHERE alt_t2.a = alt_t1.a) OR alt_t1.a < 0; @@ -57,12 +57,12 @@ WHERE EXISTS (SELECT 1 FROM alt_t2 WHERE alt_t2.a = alt_t1.a) OR alt_t1.a < 0; -> Index Only Scan using alt_t2_a_idx on alt_t2 Index Cond: (a = alt_t1.a) Supplied Plan Advice: - DO_NOT_SCAN(alt_t2@exists_2) /* matched */ + DO_NOT_SCAN(alt_t2@exists_to_any_1) /* matched */ Generated Plan Advice: SEQ_SCAN(alt_t1) INDEX_ONLY_SCAN(alt_t2@exists_1 public.alt_t2_a_idx) NO_GATHER(alt_t1 alt_t2@exists_1) - DO_NOT_SCAN(alt_t2@exists_2) + DO_NOT_SCAN(alt_t2@exists_to_any_1) (12 rows) COMMIT; diff --git a/contrib/pg_plan_advice/sql/alternatives.sql b/contrib/pg_plan_advice/sql/alternatives.sql index 16299edd196..f45f7083882 100644 --- a/contrib/pg_plan_advice/sql/alternatives.sql +++ b/contrib/pg_plan_advice/sql/alternatives.sql @@ -22,7 +22,7 @@ SET LOCAL pg_plan_advice.advice = 'DO_NOT_SCAN(alt_t2@exists_1)'; EXPLAIN (COSTS OFF, PLAN_ADVICE) SELECT * FROM alt_t1 WHERE EXISTS (SELECT 1 FROM alt_t2 WHERE alt_t2.a = alt_t1.a) OR alt_t1.a < 0; -SET LOCAL pg_plan_advice.advice = 'DO_NOT_SCAN(alt_t2@exists_2)'; +SET LOCAL pg_plan_advice.advice = 'DO_NOT_SCAN(alt_t2@exists_to_any_1)'; EXPLAIN (COSTS OFF, PLAN_ADVICE) SELECT * FROM alt_t1 WHERE EXISTS (SELECT 1 FROM alt_t2 WHERE alt_t2.a = alt_t1.a) OR alt_t1.a < 0; diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 6aa8971c95d..26384fd5fdb 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -271,8 +271,12 @@ make_subplan(PlannerInfo *root, Query *orig_subquery, { char *plan_name; - /* Generate Paths for the ANY subquery; we'll need all rows */ - plan_name = choose_plan_name(root->glob, sublinkstr, true); + /* + * Generate Paths for the ANY subquery; we'll need all rows. + * Use a distinct prefix for this user-visible name, since this is + * an ANY implementation of the original EXISTS subplan. + */ + plan_name = choose_plan_name(root->glob, "exists_to_any", true); subroot = subquery_planner(root->glob, subquery, plan_name, root, subroot, false, 0.0, NULL); diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out index 0d21a2d027c..aa821646011 100644 --- a/src/test/regress/expected/partition_prune.out +++ b/src/test/regress/expected/partition_prune.out @@ -1967,15 +1967,15 @@ where asptab.id > ss.b::int; -> Seq Scan on int4_tbl touter -> Append -> Index Only Scan using asptab0_pkey on asptab0 asptab_1 - Index Cond: (id > (EXISTS(SubPlan exists_3))::integer) - SubPlan exists_4 + Index Cond: (id > (EXISTS(SubPlan exists_2))::integer) + SubPlan exists_to_any_2 -> Seq Scan on int4_tbl tinner_2 -> Index Only Scan using asptab1_pkey on asptab1 asptab_2 - Index Cond: (id > (EXISTS(SubPlan exists_3))::integer) - SubPlan exists_3 + Index Cond: (id > (EXISTS(SubPlan exists_2))::integer) + SubPlan exists_2 -> Seq Scan on int4_tbl tinner_1 Filter: (f1 = touter.f1) - SubPlan exists_2 + SubPlan exists_to_any_1 -> Seq Scan on int4_tbl tinner (14 rows) diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index 427b3765ae3..6a54f2bbb88 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -1253,12 +1253,12 @@ rollback; -- to get rid of the bogus operator explain (costs off) select count(*) from tenk1 t where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0); - QUERY PLAN ---------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------- Aggregate -> Seq Scan on tenk1 t - Filter: ((ANY (unique2 = (hashed SubPlan exists_2).col1)) OR (ten < 0)) - SubPlan exists_2 + Filter: ((ANY (unique2 = (hashed SubPlan exists_to_any_1).col1)) OR (ten < 0)) + SubPlan exists_to_any_1 -> Index Only Scan using tenk1_unique1 on tenk1 k (5 rows) @@ -1303,8 +1303,8 @@ analyze exists_tbl; explain (costs off) select * from exists_tbl t1 where (exists(select 1 from exists_tbl t2 where t1.c1 = t2.c2) or c3 < 0); - QUERY PLAN ---------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Append -> Seq Scan on exists_tbl_null t1_1 Filter: (EXISTS(SubPlan exists_1) OR (c3 < 0)) @@ -1315,8 +1315,8 @@ select * from exists_tbl t1 -> Seq Scan on exists_tbl_def t2_2 Filter: (t1_1.c1 = c2) -> Seq Scan on exists_tbl_def t1_2 - Filter: ((ANY (c1 = (hashed SubPlan exists_2).col1)) OR (c3 < 0)) - SubPlan exists_2 + Filter: ((ANY (c1 = (hashed SubPlan exists_to_any_1).col1)) OR (c3 < 0)) + SubPlan exists_to_any_1 -> Append -> Seq Scan on exists_tbl_null t2_4 -> Seq Scan on exists_tbl_def t2_5 From 3d2f2eb1664e5c823b66a063d2de9a9787970d42 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Sat, 15 Aug 2026 23:15:31 +0900 Subject: [PATCH 374/481] pgindent fix for commit 7b7c4a8dcc9 Per buildfarm member koel. --- src/backend/optimizer/plan/subselect.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 26384fd5fdb..2cf5c15a309 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -272,9 +272,9 @@ make_subplan(PlannerInfo *root, Query *orig_subquery, char *plan_name; /* - * Generate Paths for the ANY subquery; we'll need all rows. - * Use a distinct prefix for this user-visible name, since this is - * an ANY implementation of the original EXISTS subplan. + * Generate Paths for the ANY subquery; we'll need all rows. Use a + * distinct prefix for this user-visible name, since this is an + * ANY implementation of the original EXISTS subplan. */ plan_name = choose_plan_name(root->glob, "exists_to_any", true); subroot = subquery_planner(root->glob, subquery, plan_name, From c9bd90242db70e9a7bec9897a124faf2a6f80168 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Sat, 15 Aug 2026 23:26:57 +0900 Subject: [PATCH 375/481] Add previous commit to .git-blame-ignore-revs --- .git-blame-ignore-revs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index ef919ccb7bd..a602b47f7c9 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -14,6 +14,9 @@ # # $ git log --pretty=format:"%H # %cd%n# %s" $PGINDENTGITHASH -1 --date=iso +3d2f2eb1664e5c823b66a063d2de9a9787970d42 # 2026-08-15 23:16:15 +0900 +# pgindent fix for commit 7b7c4a8dcc9 + 52d87b42d9bef6a2ca66572fc39e5c1b0f61f5dd # 2026-08-07 17:38:13 +0900 # Fix indentation issue introduced by commit 291a4bd2ca From 7b846015a40df872db572d92476d1e7c4e0c0066 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Sat, 15 Aug 2026 09:42:23 -0700 Subject: [PATCH 376/481] Clarify logic in CreateSubscription(). No bug found in previous code, but it unnecessarily relied on grammar rules. Per complaint from Coverity. Reported-by: Tom Lane Discussion: https://postgr.es/m/1787286.1786328153@sss.pgh.pa.us Backpatch-through: 19 --- src/backend/commands/subscriptioncmds.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index fd28c978c6e..bbbe5ddc921 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -846,11 +846,17 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt, values[Anum_pg_subscription_subretentionactive - 1] = BoolGetDatum(opts.retaindeadtuples); values[Anum_pg_subscription_subserver - 1] = ObjectIdGetDatum(serverid); - if (!OidIsValid(serverid)) + if (stmt->conninfo) + { + Assert(stmt->conninfo == conninfo && !OidIsValid(serverid)); values[Anum_pg_subscription_subconninfo - 1] = - CStringGetTextDatum(conninfo); + CStringGetTextDatum(stmt->conninfo); + } else + { + Assert(OidIsValid(serverid)); nulls[Anum_pg_subscription_subconninfo - 1] = true; + } if (opts.slot_name) values[Anum_pg_subscription_subslotname - 1] = DirectFunctionCall1(namein, CStringGetDatum(opts.slot_name)); From 13967fe0e2b64cfcaab53ca05f4e11b34147423e Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 17 Aug 2026 08:53:24 +0900 Subject: [PATCH 377/481] Fix ASAN failure after flex errors in GUC file parsing As detected by ASAN, the scanner value used when parsing GUC files can be indeterminate when the flex error handler sigjumps to the old cleanup path, before yylex_init() is called. The flex scanner state is now made volatile in ParseConfigFp(), since its value is assigned after sigsetjmp() and cna be accessed after siglongjmp(). yylex_init() cannot use a volatile pointer; a temporary variable is used before assigning the result of yylex_init() to it. While on it, yy_create_buffer() is changed to detect the case where it returns a NULL value. Based on my read of the flex code, this cannot be reached currently. Future upstream changes or changes in the error logic of the GUC file parsing could make that reachable, and it is four extra lines of code. Oversight in d663f150b5ed. Reported-by: Ilia Kashintsev Reviewed-by: Tom Lane Reviewed-by: Andrey Rachitskiy Discussion: https://postgr.es/m/19612-24ccb4fc6da7786f@postgresql.org Backpatch-through: 18 --- src/backend/utils/misc/guc-file.l | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l index 58669a67e05..8c38a23a84d 100644 --- a/src/backend/utils/misc/guc-file.l +++ b/src/backend/utils/misc/guc-file.l @@ -354,7 +354,8 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel, unsigned int save_ConfigFileLineno = ConfigFileLineno; sigjmp_buf *save_GUC_flex_fatal_jmp = GUC_flex_fatal_jmp; sigjmp_buf flex_fatal_jmp; - yyscan_t scanner; + volatile yyscan_t scanner = NULL; + yyscan_t scanner_init = NULL; /* non-volatile for yylex_init() */ struct yyguts_t *yyg; /* needed for yytext macro */ volatile YY_BUFFER_STATE lex_buffer = NULL; int errorcount; @@ -384,11 +385,20 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel, ConfigFileLineno = 1; errorcount = 0; - if (yylex_init(&scanner) != 0) + if (yylex_init(&scanner_init) != 0) + { elog(elevel, "yylex_init() failed: %m"); + goto cleanup; + } + scanner = scanner_init; yyg = (struct yyguts_t *) scanner; lex_buffer = yy_create_buffer(fp, YY_BUF_SIZE, scanner); + if (lex_buffer == NULL) + { + elog(elevel, "yy_create_buffer() failed"); + goto cleanup; + } yy_switch_to_buffer(lex_buffer, scanner); /* This loop iterates once per logical line */ @@ -559,8 +569,11 @@ parse_error: } cleanup: - yy_delete_buffer(lex_buffer, scanner); - yylex_destroy(scanner); + if (scanner) + { + yy_delete_buffer(lex_buffer, scanner); + yylex_destroy(scanner); + } /* Each recursion level must save and restore these static variables. */ ConfigFileLineno = save_ConfigFileLineno; GUC_flex_fatal_jmp = save_GUC_flex_fatal_jmp; From 67342a148632801d44c2fb9a7bf4231b6827c5d2 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 17 Aug 2026 09:21:06 +0900 Subject: [PATCH 378/481] psql: Fix \d+ display of REPLICA IDENTITY NOTHING Commit 18954ce7f69 has replaced hardcoded relreplident values in describe.c with CppAsString2 macros, but used a DEFAULT instead of a NOTHING at one location. This caused \d+ on a table with REPLICA IDENTITY NOTHING to show incorrect data. Author: Shinya Kato Discussion: https://postgr.es/m/CAOzEurRHWt+9XLBrbXQOSVkE45NksJ4F28twuqgZ7veW0RzpUQ@mail.gmail.com Backpatch-through: 18 --- src/bin/psql/describe.c | 2 +- .../regress/expected/replica_identity.out | 24 +++++++++++++++++++ src/test/regress/sql/replica_identity.sql | 1 + 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index f258a33a808..af12a319cd4 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -3814,7 +3814,7 @@ describeOneTableDetails(const char *schemaname, printfPQExpBuffer(&buf, "%s: %s", s, tableinfo.relreplident == REPLICA_IDENTITY_FULL ? "FULL" : - tableinfo.relreplident == REPLICA_IDENTITY_DEFAULT ? "NOTHING" : + tableinfo.relreplident == REPLICA_IDENTITY_NOTHING ? "NOTHING" : "???"); printTableAddFooter(&cont, buf.data); diff --git a/src/test/regress/expected/replica_identity.out b/src/test/regress/expected/replica_identity.out index 87feaadbb28..1560cd04125 100644 --- a/src/test/regress/expected/replica_identity.out +++ b/src/test/regress/expected/replica_identity.out @@ -187,6 +187,30 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; n (1 row) +\d+ test_replica_identity + Table "public.test_replica_identity" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------------------------------------------------+----------+--------------+------------- + id | integer | | not null | nextval('test_replica_identity_id_seq'::regclass) | plain | | + keya | text | | not null | | extended | | + keyb | text | | not null | | extended | | + nonkey | text | | | | extended | | +Indexes: + "test_replica_identity_pkey" PRIMARY KEY, btree (id) + "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3)) + "test_replica_identity_hash" hash (nonkey) + "test_replica_identity_keyab" btree (keya, keyb) + "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb) + "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey) + "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text + "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE + "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, keyb) +Not-null constraints: + "test_replica_identity_id_not_null" NOT NULL "id" + "test_replica_identity_keya_not_null" NOT NULL "keya" + "test_replica_identity_keyb_not_null" NOT NULL "keyb" +Replica Identity: NOTHING + --- -- Test that ALTER TABLE rewrite preserves nondefault replica identity --- diff --git a/src/test/regress/sql/replica_identity.sql b/src/test/regress/sql/replica_identity.sql index b202b30ae2b..4ebb097f282 100644 --- a/src/test/regress/sql/replica_identity.sql +++ b/src/test/regress/sql/replica_identity.sql @@ -77,6 +77,7 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; \d+ test_replica_identity ALTER TABLE test_replica_identity REPLICA IDENTITY NOTHING; SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; +\d+ test_replica_identity --- -- Test that ALTER TABLE rewrite preserves nondefault replica identity From b6b4f5a6460a6c2634924dd44e0b07f990b8aae0 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 17 Aug 2026 15:06:02 -0400 Subject: [PATCH 379/481] Make plperl's handling of Perl arrays safer and more consistent. plperl_func_handler()'s stanza for handling an arrayref result in a SETOF function could loop forever (or at least till OOM) when given a tied array, since av_fetch won't necessarily ever return a null pointer in that case. Be consistent with the other places where we traverse a perl array: call av_len() once and use len+1 as the loop limit, silently ignoring any null pointers we get back from that range of subscripts. But actually, Perl's preferred locution for this seems to be to use av_count() not av_len()+1. av_count() seems better since there's less risk of forgetting to add 1. Also, both of those functions return Size_t (or SSize_t) not int, creating at least a theoretical overflow hazard. While we're modernizing this, let's use the correct variable type where we can, and include an overflow check where we can't. Reported-by: Claude Code (via Noah Misch) Author: Tom Lane Reviewed-by: Andrey Rachitskiy Discussion: https://postgr.es/m/569769.1786901901@sss.pgh.pa.us Backpatch-through: 14 --- contrib/jsonb_plperl/jsonb_plperl.c | 5 ++-- src/pl/plperl/plperl.c | 41 ++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/contrib/jsonb_plperl/jsonb_plperl.c b/contrib/jsonb_plperl/jsonb_plperl.c index 97d147cc65a..00a99d303c6 100644 --- a/contrib/jsonb_plperl/jsonb_plperl.c +++ b/contrib/jsonb_plperl/jsonb_plperl.c @@ -135,12 +135,11 @@ static void AV_to_JsonbValue(AV *in, JsonbInState *jsonb_state) { dTHX; - SSize_t pcount = av_len(in) + 1; - SSize_t i; + Size_t pcount = av_count(in); pushJsonbValue(jsonb_state, WJB_BEGIN_ARRAY, NULL); - for (i = 0; i < pcount; i++) + for (Size_t i = 0; i < pcount; i++) { SV **value = av_fetch(in, i, FALSE); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index eba91f2d7d6..8175407849e 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -279,6 +279,7 @@ static void array_to_datum_internal(AV *av, ArrayBuildState **astatep, int *ndims, int *dims, int cur_depth, Oid elemtypid, int32 typmod, FmgrInfo *finfo, Oid typioparam); +static int av_count_limit(AV *av); static Datum plperl_hash_to_datum(SV *src, TupleDesc td); static void plperl_init_shared_libs(pTHX); @@ -1173,8 +1174,8 @@ get_perl_array_ref(SV *sv) * is frozen). * * Caller is required to have set dims[cur_depth - 1] to the length of the - * input array, i.e., av_len(av) + 1. We make this requirement so as to - * avoid reading av_len() twice, which is hazardous for tied arrays. + * input array, i.e., av_count_limit(av). We make this requirement so as to + * avoid reading av_count() twice, which is hazardous for tied arrays. */ static void array_to_datum_internal(AV *av, ArrayBuildState **astatep, @@ -1214,11 +1215,11 @@ array_to_datum_internal(AV *av, ArrayBuildState **astatep, errmsg("number of array dimensions exceeds the maximum allowed (%d)", MAXDIM))); /* OK, add a dimension */ - dims[*ndims] = av_len(nav) + 1; + dims[*ndims] = av_count_limit(nav); (*ndims)++; } else if (cur_depth >= *ndims || - av_len(nav) + 1 != dims[cur_depth]) + av_count_limit(nav) != dims[cur_depth]) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("multidimensional arrays must have array expressions with matching dimensions"))); @@ -1260,6 +1261,25 @@ array_to_datum_internal(AV *av, ArrayBuildState **astatep, } } +/* + * av_count returns Size_t, so at least in theory it could overrun INT_MAX. + * As long as we have to check, let's throw error for anything above + * MaxArraySize, which will surely fail later. + */ +static int +av_count_limit(AV *av) +{ + dTHX; + Size_t cnt = av_count(av); + + if (cnt > MaxArraySize) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("array size exceeds the maximum allowed (%zu)", + MaxArraySize))); + return (int) cnt; +} + /* * convert perl array ref to a datum */ @@ -1287,7 +1307,7 @@ plperl_array_to_datum(SV *src, Oid typid, int32 typmod) _sv_to_datum_finfo(elemtypid, &finfo, &typioparam); memset(dims, 0, sizeof(dims)); - dims[0] = av_len(nav) + 1; + dims[0] = av_count_limit(nav); array_to_datum_internal(nav, &astate, &ndims, dims, 1, @@ -2478,14 +2498,15 @@ plperl_func_handler(PG_FUNCTION_ARGS) if (sav) { dTHX; - int i = 0; - SV **svp = 0; AV *rav = (AV *) SvRV(sav); + Size_t alen = av_count(rav); - while ((svp = av_fetch(rav, i, FALSE)) != NULL) + for (Size_t i = 0; i < alen; i++) { - plperl_return_next_internal(*svp); - i++; + SV **svp = av_fetch(rav, i, FALSE); + + if (svp) + plperl_return_next_internal(*svp); } } else if (SvOK(perlret)) From 81aa0a2fa7c4d35511e68daf1ba47bdfa3ec5474 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 17 Aug 2026 16:36:40 +0200 Subject: [PATCH 380/481] Replace printf format %i by %d as is PostgreSQL standard --- src/backend/postmaster/datachecksum_state.c | 4 ++-- src/test/modules/plsample/plsample.c | 2 +- src/test/regress/pg_regress.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/postmaster/datachecksum_state.c b/src/backend/postmaster/datachecksum_state.c index 368df23e967..28d2a4379d4 100644 --- a/src/backend/postmaster/datachecksum_state.c +++ b/src/backend/postmaster/datachecksum_state.c @@ -492,7 +492,7 @@ AbsorbDataChecksumsBarrier(ProcSignalBarrierType barrier) target_state = PG_DATA_CHECKSUM_OFF; break; default: - elog(ERROR, "incorrect barrier \"%i\" received", barrier); + elog(ERROR, "incorrect barrier \"%d\" received", barrier); } /* @@ -530,7 +530,7 @@ AbsorbDataChecksumsBarrier(ProcSignalBarrierType barrier) if (!found) ereport(ERROR, errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("incorrect data checksum state %i for target state %i", + errmsg("incorrect data checksum state %d for target state %d", current, target_state)); SetLocalDataChecksumState(target_state); diff --git a/src/test/modules/plsample/plsample.c b/src/test/modules/plsample/plsample.c index f294f5ca4ad..31ef4c96f22 100644 --- a/src/test/modules/plsample/plsample.c +++ b/src/test/modules/plsample/plsample.c @@ -337,7 +337,7 @@ plsample_trigger_handler(PG_FUNCTION_ARGS) */ for (int i = 0; i < trigdata->tg_trigger->tgnargs; i++) ereport(NOTICE, - (errmsg("trigger arg[%i]: %s", i, + (errmsg("trigger arg[%d]: %s", i, trigdata->tg_trigger->tgargs[i]))); } PG_CATCH(); diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index b53821dd10c..83073da0bcf 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -161,7 +161,7 @@ static void psql_end_command(StringInfo buf, const char *database); * Convenience macros for printing TAP output with a more shorthand syntax * aimed at making the code more readable. */ -#define plan(x) emit_tap_output(PLAN, "1..%i", (x)) +#define plan(x) emit_tap_output(PLAN, "1..%d", (x)) #define note(...) emit_tap_output(NOTE, __VA_ARGS__) #define note_detail(...) emit_tap_output(NOTE_DETAIL, __VA_ARGS__) #define diag(...) emit_tap_output(DIAG, __VA_ARGS__) From 3a18526e8d6bcdd25db847128dd83bb4c1ba6ec2 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Mon, 17 Aug 2026 22:40:22 +0200 Subject: [PATCH 381/481] Make data checksums launcher cancel its worker at SIGINT Make sure the launcher cancels the currently running worker by calling TerminateBackgroundWorker when it receives SIGINT. In order to handle cases where SIGINT arrives while tje launcher is waiting for a worker to start or exit, implement a version of WaitForBackgroundWorkerStartup and WaitForBackgroundWorkerShutdown which checks the abort_requested signalling. A new test which kills processing with SIGINT is added. Backpatch to v19 where online checksums were introduced. Author: Fujii Masao Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CAHGQGwEQ1-+iPQnUpTXYiHmzSz9ufFVkOK4kL_uyTdYt7jgg0Q@mail.gmail.com Backpatch-through: 19 --- src/backend/postmaster/datachecksum_state.c | 112 ++++++++++++++++-- .../modules/test_checksums/t/002_restarts.pl | 42 +++++++ 2 files changed, 143 insertions(+), 11 deletions(-) diff --git a/src/backend/postmaster/datachecksum_state.c b/src/backend/postmaster/datachecksum_state.c index 28d2a4379d4..47dcc82fb81 100644 --- a/src/backend/postmaster/datachecksum_state.c +++ b/src/backend/postmaster/datachecksum_state.c @@ -393,6 +393,10 @@ static DataChecksumsWorkerResult ProcessDatabase(DataChecksumsWorkerDatabase *db static bool ProcessAllDatabases(void); static bool ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferAccessStrategy strategy); static void ResetDataChecksumsProgressCounters(void); +static BgwHandleStatus WaitForDataChecksumsWorkerState(BackgroundWorkerHandle *handle, + bool wait_for_startup, + pid_t *pidp, + uint32 wait_event); static void launcher_cancel_handler(SIGNAL_ARGS); static void WaitForAllTransactionsToFinish(void); @@ -861,6 +865,73 @@ ProcessSingleRelationByOid(Oid relationId, BufferAccessStrategy strategy) return !aborted; } +/* + * WaitForDataChecksumsWorkerState + * Wait for a data checksums worker to start or stop. + * + * This is like WaitForBackgroundWorkerStartup() and + * WaitForBackgroundWorkerShutdown(), except that it also reacts to SIGINT + * received by the launcher. The launcher owns the overall checksum + * operation, so canceling it should stop the worker it has registered or is + * currently running. + * + * If wait_for_startup is true, wait until the worker is no longer in + * BGWH_NOT_YET_STARTED state, like WaitForBackgroundWorkerStartup(). If it + * is false, wait until the worker reaches BGWH_STOPPED state, like + * WaitForBackgroundWorkerShutdown(). + * + * pidp is set to the worker's PID when startup succeeds, if it is not NULL. + */ +static BgwHandleStatus +WaitForDataChecksumsWorkerState(BackgroundWorkerHandle *handle, + bool wait_for_startup, + pid_t *pidp, + uint32 wait_event) +{ + BgwHandleStatus status; + bool termination_requested = false; + + for (;;) + { + int rc; + pid_t pid; + + CHECK_FOR_INTERRUPTS(); + + status = GetBackgroundWorkerPid(handle, &pid); + if (status == BGWH_STARTED && pidp) + *pidp = pid; + + if (abort_requested && !termination_requested) + { + TerminateBackgroundWorker(handle); + termination_requested = true; + } + + /* + * Startup waits for the worker to leave BGWH_NOT_YET_STARTED, while + * shutdown waits for it to reach BGWH_STOPPED. + */ + if (status == BGWH_STOPPED || + (wait_for_startup && status == BGWH_STARTED)) + break; + + rc = WaitLatch(MyLatch, + WL_LATCH_SET | WL_POSTMASTER_DEATH, 0, + wait_event); + + if (rc & WL_POSTMASTER_DEATH) + { + status = BGWH_POSTMASTER_DIED; + break; + } + + ResetLatch(MyLatch); + } + + return status; +} + /* * ProcessDatabase * Enable data checksums in a single database. @@ -921,9 +992,20 @@ ProcessDatabase(DataChecksumsWorkerDatabase *db) return DATACHECKSUMSWORKER_FAILED; } - status = WaitForBackgroundWorkerStartup(bgw_handle, &pid); + /* + * While this expects to wait for BGWORKER_STARTUP it may return _STOPPED + * if the worker was terminated in the meantime so we must check status. + */ + status = WaitForDataChecksumsWorkerState(bgw_handle, true, &pid, + WAIT_EVENT_BGWORKER_STARTUP); if (status == BGWH_STOPPED) { + if (abort_requested) + { + result = DATACHECKSUMSWORKER_ABORTED; + goto done; + } + /* * If the worker managed to start, and stop, before we got to waiting * for it we can see a STOPPED status here without it being a failure. @@ -981,7 +1063,8 @@ ProcessDatabase(DataChecksumsWorkerDatabase *db) "Waiting for worker in database %s (pid %ld)", db->dbname, (long) pid); pgstat_report_activity(STATE_RUNNING, activity); - status = WaitForBackgroundWorkerShutdown(bgw_handle); + status = WaitForDataChecksumsWorkerState(bgw_handle, false, NULL, + WAIT_EVENT_BGWORKER_SHUTDOWN); if (status == BGWH_POSTMASTER_DIED) ereport(FATAL, errcode(ERRCODE_ADMIN_SHUTDOWN), @@ -1004,6 +1087,11 @@ ProcessDatabase(DataChecksumsWorkerDatabase *db) if (result == DATACHECKSUMSWORKER_FAILED && !DatabaseExists(db->dboid)) result = DATACHECKSUMSWORKER_DROPDB; + CHECK_FOR_LAUNCHER_ABORT_REQUEST(); + if (abort_requested) + result = DATACHECKSUMSWORKER_ABORTED; + +done: if (result == DATACHECKSUMSWORKER_ABORTED) ereport(LOG, errmsg("data checksums processing was aborted in database \"%s\"", @@ -1056,9 +1144,9 @@ launcher_exit(int code, Datum arg) /* * launcher_cancel_handler * - * Internal routine for reacting to SIGINT and flagging the worker to abort. - * The worker won't be interrupted immediately but will check for abort flag - * between each block in a relation. + * Internal routine for reacting to SIGINT and flagging the launcher to abort. + * If a worker is registered or running, the launcher will request worker + * termination from its normal control flow. */ static void launcher_cancel_handler(SIGNAL_ARGS) @@ -1068,10 +1156,8 @@ launcher_cancel_handler(SIGNAL_ARGS) abort_requested = true; /* - * There is no sleeping in the main loop, the flag will be checked - * periodically in ProcessSingleRelationFork. The worker does however - * sleep when waiting for concurrent transactions to end so we still need - * to set the latch. + * Wake the launcher if it is waiting for transactions to finish or for a + * worker to start up or shut down. */ SetLatch(MyLatch); @@ -1226,8 +1312,9 @@ DataChecksumsWorkerLauncherMain(Datum arg) if (!ProcessAllDatabases()) { /* - * If the target state changed during processing then it's not a - * failure, so restart processing instead. + * If processing was canceled, or the target state changed during + * processing, then it's not a failure. In the latter case, the + * launcher will restart processing with the new target state. */ CHECK_FOR_LAUNCHER_ABORT_REQUEST(); if (abort_requested) @@ -1314,6 +1401,8 @@ ProcessAllDatabases(void) /* Get a list of all databases to process */ WaitForAllTransactionsToFinish(); + if (abort_requested) + return false; DatabaseList = BuildDatabaseList(); /* @@ -1370,6 +1459,7 @@ ProcessAllDatabases(void) else if (result == DATACHECKSUMSWORKER_ABORTED || abort_requested) { /* Abort flag set, so exit the whole process */ + FreeDatabaseList(DatabaseList); return false; } else if (result == DATACHECKSUMSWORKER_DROPDB) diff --git a/src/test/modules/test_checksums/t/002_restarts.pl b/src/test/modules/test_checksums/t/002_restarts.pl index 1aa2c0c65e5..d98c8024f29 100644 --- a/src/test/modules/test_checksums/t/002_restarts.pl +++ b/src/test/modules/test_checksums/t/002_restarts.pl @@ -93,6 +93,48 @@ test_checksum_state($node, 'off'); } +# Test interrupting the processing with SIGINT to make sure the launcher and +# worker are cancelled. Create a barrier for checksum enablement to block on +# using the same technique as earlier with a temporary table. +my $block_session = $node->background_psql('postgres'); +$block_session->query_safe('CREATE TEMPORARY TABLE tt (a integer);'); + +# In another session, make sure we can see the blocking temp table but +# start processing anyways and check that we are blocked with a proper +# wait event. +$result = $node->safe_psql('postgres', + "SELECT relpersistence FROM pg_catalog.pg_class WHERE relname = 'tt';"); +is($result, 't', 'ensure we can see the temporary table'); + +# Ensure that we reach inprogress-on and the worker is launched and waiting for +# the temporary table to disappear before we try to interrupt the processing. +enable_data_checksums($node, wait => 'inprogress-on'); +$result = $node->poll_query_until( + 'postgres', + "SELECT wait_event FROM pg_catalog.pg_stat_activity " + . "WHERE backend_type = 'datachecksums worker';", + 'ChecksumEnableTemptableWait'); +is($result, '1', 'ensure the correct wait condition is set'); + +# Terminate launcher and worker with SIGINT +my $pid = $node->safe_psql('postgres', + "SELECT pid FROM pg_catalog.pg_stat_activity WHERE backend_type = 'datachecksums launcher';" +); +is(PostgreSQL::Test::Utils::system_log('pg_ctl', 'kill', 'INT', $pid), + 0, "datachecksums launcher process signalled with INT"); + +# Wait for all processes to exit and make sure that the data_checksum state +# was reverted back to off since we didn't finish +$result = $node->poll_query_until( + 'postgres', + "SELECT count(*) FROM pg_catalog.pg_stat_activity WHERE backend_type LIKE 'datachecksums%';", + '0'); +is($result, 1, 'await datachecksums worker/launcher termination'); +wait_for_checksum_state($node, "off"); +$block_session->quit; + +# Finish test suite by enabling checksums and make sure all data can be read +# back and no processes are left over enable_data_checksums($node, wait => 'on'); $result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1"); From abac86c7a27a4604c07a3a85ca02dae4b12ae8c8 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Mon, 17 Aug 2026 22:40:26 +0200 Subject: [PATCH 382/481] Reorder function prototypes to match definition order While purely aesthetic, it makes reading the code easier to rearrange before the feature has shipped since doing it after risk backpatching conflicts. Also add missing prototypes. Backpatch to v19 where online checksums were introduced. Author: Fujii Masao Discussion: https://postgr.es/m/CAHGQGwEQ1-+iPQnUpTXYiHmzSz9ufFVkOK4kL_uyTdYt7jgg0Q@mail.gmail.com Backpatch-through: 19 --- src/backend/postmaster/datachecksum_state.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/backend/postmaster/datachecksum_state.c b/src/backend/postmaster/datachecksum_state.c index 47dcc82fb81..443cb799915 100644 --- a/src/backend/postmaster/datachecksum_state.c +++ b/src/backend/postmaster/datachecksum_state.c @@ -383,22 +383,24 @@ static DataChecksumsWorkerOperation operation; static void StartDataChecksumsWorkerLauncher(DataChecksumsWorkerOperation op, int cost_delay, int cost_limit); -static void DataChecksumsShmemRequest(void *arg); -static bool DatabaseExists(Oid dboid); static void ErrorOnInvalidDatabases(void); -static List *BuildDatabaseList(void); -static List *BuildRelationList(bool temp_relations, bool include_shared); -static void FreeDatabaseList(List *dblist); -static DataChecksumsWorkerResult ProcessDatabase(DataChecksumsWorkerDatabase *db); -static bool ProcessAllDatabases(void); static bool ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferAccessStrategy strategy); static void ResetDataChecksumsProgressCounters(void); +static bool ProcessSingleRelationByOid(Oid relationId, BufferAccessStrategy strategy); static BgwHandleStatus WaitForDataChecksumsWorkerState(BackgroundWorkerHandle *handle, bool wait_for_startup, pid_t *pidp, uint32 wait_event); +static DataChecksumsWorkerResult ProcessDatabase(DataChecksumsWorkerDatabase *db); +static void launcher_exit(int code, Datum arg); static void launcher_cancel_handler(SIGNAL_ARGS); static void WaitForAllTransactionsToFinish(void); +static bool ProcessAllDatabases(void); +static void DataChecksumsShmemRequest(void *arg); +static bool DatabaseExists(Oid dboid); +static List *BuildDatabaseList(void); +static void FreeDatabaseList(List *dblist); +static List *BuildRelationList(bool temp_relations, bool include_shared); const ShmemCallbacks DataChecksumsShmemCallbacks = { .request_fn = DataChecksumsShmemRequest, From 9c1e3b58bf541fca073892ddc4f81eef85067b50 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Mon, 17 Aug 2026 17:31:11 -0400 Subject: [PATCH 383/481] GiST: Deprecate F_TUPLES_DELETED opaque area flag. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This flag hasn't been useful since the removal of old-style VACUUM FULL, so remove it now (this includes removing vestigial code that unnecessarily set the flag). Also add test coverage of gistprunepage(). Had that test case been available before now, the issue fixed by this commit would have been detected by wal_consistency_checking buildfarm animals. Author: Peter Geoghegan Reviewed-by: Michael Paquiër Discussion: https://postgr.es/m/CAH2-WznbTsQCrjmd=eSawfPqcxCjSFUkk6Qzd3z+gpNte5i03Q@mail.gmail.com Backpatch-through: 14 --- src/backend/access/gist/gistvacuum.c | 1 - src/backend/access/gist/gistxlog.c | 3 --- src/include/access/gist.h | 8 ++------ src/test/regress/expected/gist.out | 26 ++++++++++++++++++++++++++ src/test/regress/sql/gist.sql | 21 +++++++++++++++++++++ 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index 686a0418054..b87e98207cc 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -401,7 +401,6 @@ gistvacuumpage(GistVacState *vstate, Buffer buffer) MarkBufferDirty(buffer); PageIndexMultiDelete(page, todelete, ntodelete); - GistMarkTuplesDeleted(page); if (RelationNeedsWAL(rel)) { diff --git a/src/backend/access/gist/gistxlog.c b/src/backend/access/gist/gistxlog.c index ae538dc81ca..1f8100f2a8a 100644 --- a/src/backend/access/gist/gistxlog.c +++ b/src/backend/access/gist/gistxlog.c @@ -114,8 +114,6 @@ gistRedoPageUpdateRecord(XLogReaderState *record) data += sizeof(OffsetNumber) * xldata->ntodelete; PageIndexMultiDelete(page, todelete, xldata->ntodelete); - if (GistPageIsLeaf(page)) - GistMarkTuplesDeleted(page); } /* Add new tuples if any */ @@ -204,7 +202,6 @@ gistRedoDeleteRecord(XLogReaderState *record) PageIndexMultiDelete(page, toDelete, xldata->ntodelete); GistClearPageHasGarbage(page); - GistMarkTuplesDeleted(page); PageSetLSN(page, lsn); MarkBufferDirty(buffer); diff --git a/src/include/access/gist.h b/src/include/access/gist.h index 9b385b13a88..69a7945c53d 100644 --- a/src/include/access/gist.h +++ b/src/include/access/gist.h @@ -48,8 +48,8 @@ */ #define F_LEAF (1 << 0) /* leaf page */ #define F_DELETED (1 << 1) /* the page has been deleted */ -#define F_TUPLES_DELETED (1 << 2) /* some tuples on the page were - * deleted */ +#define F_TUPLES_DELETED (1 << 2) /* old-style VACUUM FULL flag + * (deprecated) */ #define F_FOLLOW_RIGHT (1 << 3) /* page to the right has no downlink */ #define F_HAS_GARBAGE (1 << 4) /* some tuples on the page are dead, * but not deleted yet */ @@ -174,10 +174,6 @@ typedef struct GISTENTRY #define GistPageIsDeleted(page) ( GistPageGetOpaque(page)->flags & F_DELETED) -#define GistTuplesDeleted(page) ( GistPageGetOpaque(page)->flags & F_TUPLES_DELETED) -#define GistMarkTuplesDeleted(page) ( GistPageGetOpaque(page)->flags |= F_TUPLES_DELETED) -#define GistClearTuplesDeleted(page) ( GistPageGetOpaque(page)->flags &= ~F_TUPLES_DELETED) - #define GistPageHasGarbage(page) ( GistPageGetOpaque(page)->flags & F_HAS_GARBAGE) #define GistMarkPageHasGarbage(page) ( GistPageGetOpaque(page)->flags |= F_HAS_GARBAGE) #define GistClearPageHasGarbage(page) ( GistPageGetOpaque(page)->flags &= ~F_HAS_GARBAGE) diff --git a/src/test/regress/expected/gist.out b/src/test/regress/expected/gist.out index ae5b522b3c6..ac79f94aa80 100644 --- a/src/test/regress/expected/gist.out +++ b/src/test/regress/expected/gist.out @@ -423,6 +423,32 @@ select lower(r) = repeat('7', 200)::numeric as lower_ok, (1 row) drop table gist_ios_tupdesc; +-- test deletion of LP_DEAD-marked index tuples +create table gist_prune_tbl (k int, p point); +create index gist_prune_tbl_p_index on gist_prune_tbl using gist (p); +begin; +insert into gist_prune_tbl select i, point(1, i) from generate_series(1, 600) i; +rollback; +set enable_bitmapscan = off; +set enable_indexonlyscan = off; +set enable_seqscan = off; +select count(*) from gist_prune_tbl where p <@ box(point(0,0), point(2,1000)); + count +------- + 0 +(1 row) + +insert into gist_prune_tbl select i, point(1, i) from generate_series(1, 600) i; +select count(*) from gist_prune_tbl where p <@ box(point(0,0), point(2,1000)); + count +------- + 600 +(1 row) + +reset enable_bitmapscan; +reset enable_indexonlyscan; +reset enable_seqscan; +drop table gist_prune_tbl; -- Force an index build using buffering. create index gist_tbl_box_index_forcing_buffering on gist_tbl using gist (p) with (buffering=on, fillfactor=50); diff --git a/src/test/regress/sql/gist.sql b/src/test/regress/sql/gist.sql index 1ebb1d9ee43..57dcc082450 100644 --- a/src/test/regress/sql/gist.sql +++ b/src/test/regress/sql/gist.sql @@ -198,6 +198,27 @@ select lower(r) = repeat('7', 200)::numeric as lower_ok, drop table gist_ios_tupdesc; +-- test deletion of LP_DEAD-marked index tuples +create table gist_prune_tbl (k int, p point); +create index gist_prune_tbl_p_index on gist_prune_tbl using gist (p); + +begin; +insert into gist_prune_tbl select i, point(1, i) from generate_series(1, 600) i; +rollback; + +set enable_bitmapscan = off; +set enable_indexonlyscan = off; +set enable_seqscan = off; + +select count(*) from gist_prune_tbl where p <@ box(point(0,0), point(2,1000)); +insert into gist_prune_tbl select i, point(1, i) from generate_series(1, 600) i; +select count(*) from gist_prune_tbl where p <@ box(point(0,0), point(2,1000)); + +reset enable_bitmapscan; +reset enable_indexonlyscan; +reset enable_seqscan; +drop table gist_prune_tbl; + -- Force an index build using buffering. create index gist_tbl_box_index_forcing_buffering on gist_tbl using gist (p) with (buffering=on, fillfactor=50); From 1c732c8518d88c2663f96236bf8bb104f3d0a5d4 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 17 Aug 2026 18:09:07 -0400 Subject: [PATCH 384/481] Tighten up tsqueryrecv(). tsqueryrecv() accepted zero-length lexemes, which tsqueryin() doesn't. It also accepted phrase distance values larger than MAXENTRYPOS, which tsqueryin() doesn't. While neither of these omissions are very harmful in themselves, they do allow accepting tsquery values that will fail in a subsequent textual dump/reload. Commit 23d9ad771 performed similar tightening of tsvectorrecv(), but I left off these changes at the time because they didn't seem to have security implications. Reported-by: Claude Code (via Noah Misch) Author: Tom Lane Reviewed-by: Chao Li Discussion: https://postgr.es/m/455079.1786897319@sss.pgh.pa.us Backpatch-through: 14 --- src/backend/utils/adt/tsquery.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c index c49b06f72bb..a63b8f75eb8 100644 --- a/src/backend/utils/adt/tsquery.c +++ b/src/backend/utils/adt/tsquery.c @@ -1273,6 +1273,9 @@ tsqueryrecv(PG_FUNCTION_ARGS) if (weight > 0xF) elog(ERROR, "invalid tsquery: invalid weight bitmap"); + if (val_len == 0) + elog(ERROR, "invalid tsquery: empty operand"); + if (val_len > MAXSTRLEN) elog(ERROR, "invalid tsquery: operand too long"); @@ -1312,7 +1315,14 @@ tsqueryrecv(PG_FUNCTION_ARGS) item->qoperator.oper = oper; if (oper == OP_PHRASE) - item->qoperator.distance = (int16) pq_getmsgint(buf, sizeof(int16)); + { + unsigned int dist = pq_getmsgint(buf, sizeof(int16)); + + if (dist > MAXENTRYPOS) + elog(ERROR, "invalid tsquery: invalid phrase distance %u", + dist); + item->qoperator.distance = (int16) dist; + } } else elog(ERROR, "unrecognized tsquery node type: %d", item->type); From 2d893fd926eb17b6d85d1eb7f1f6d615b2e68ba9 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 17 Aug 2026 18:17:51 -0400 Subject: [PATCH 385/481] Doc: clean up documentation about text search datatype limits. textsearch.sgml neglected to mention that the MAXSTRPOS total-length limit applies to tsquery as well as tsvector. It also claims that there is a 32K limit on the total number of nodes in a tsquery, which is wrong. (I suspect that QueryOperator.left may once have been int16, which would give rise to such a limit. But it's uint32 now, so you'd hit the 1GB varlena limit well before overflowing that.) While at it, re-order the bullet points into an order that makes more sense, to me anyway. Reported-by: Claude Code (via Noah Misch) Author: Tom Lane Reviewed-by: Chao Li Discussion: https://postgr.es/m/455079.1786897319@sss.pgh.pa.us Backpatch-through: 14 --- doc/src/sgml/textsearch.sgml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/src/sgml/textsearch.sgml b/doc/src/sgml/textsearch.sgml index d6d2ddeaacc..2f3a76bef1e 100644 --- a/doc/src/sgml/textsearch.sgml +++ b/doc/src/sgml/textsearch.sgml @@ -4046,24 +4046,24 @@ Parser: "pg_catalog.default" The length of each lexeme must be less than 2 kilobytes - The length of a tsvector (lexemes + positions) must be - less than 1 megabyte + No more than 256 positions per lexeme Position values in tsvector must be greater than 0 and no more than 16,383 - The match distance in a <N> - (FOLLOWED BY) tsquery operator cannot be more than - 16,384 + The length of a tsvector's data (lexemes + positions) + must be less than 1 megabyte - No more than 256 positions per lexeme + The length of a tsquery's data (lexemes only) + must be less than 1 megabyte - The number of nodes (lexemes + operators) in a tsquery - must be less than 32,768 + The match distance in a <N> + (FOLLOWED BY) tsquery operator cannot be more than + 16,384 From 3b70fa6f3d32ac832ed9ddd566c11b05e575f2c7 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Tue, 18 Aug 2026 12:16:02 +0900 Subject: [PATCH 386/481] Fix cross-type foreign keys in the batched fast-path FK check ri_FastPathFlushArray() rechecked a concurrently updated PK tuple with a scan key it built itself, putting found_val, the key of the tuple it had just locked, into sk_argument, and passing that same slot to recheck_matched_pk_tuple(). Both operands therefore came from the locked tuple, and since sk_argument is the operator's right-hand input, the PK value was read as an FK value. For a foreign key using a cross-type equality operator, such as a "date" primary key referenced by a "timestamp" column, that compares days against microseconds, so the recheck always failed and a batch that had to follow an update chain reported a violation even though the version it locked still had the key. Remove the recheck. For a same-type key it compared the tuple against itself and so never rejected anything, which was harmless only because the loop a few lines below does the real work: it already compares found_val, read after the chain has been followed, against every buffered FK value, with the arguments in the order the operator expects. That makes the recheck redundant as well as wrong. Detection is not weakened by dropping it, since the buffered value that led the scan to a tuple can be matched by no other row visible to our snapshot. ri_FastPathProbeOne() passes its original scan key, with the FK value still in sk_argument, and was never affected; nor were single-row statements or multi-column foreign keys, which go through it. Add an isolation test covering the cross-type case, a permutation where the key really does move away, and a same-type permutation that should behave identically. Reported-by: Peter Geoghegan Co-authored-by: Peter Geoghegan Discussion: https://postgr.es/m/CAH2-WznQjX3GByh_Ju7unuzMcik_5PJ5D7i_=qhwk=gPEkhfVQ@mail.gmail.com Backpatch-through: 19 --- src/backend/utils/adt/ri_triggers.c | 43 +++++++-------- .../expected/fk-crosstype-recheck.out | 37 +++++++++++++ src/test/isolation/isolation_schedule | 1 + .../isolation/specs/fk-crosstype-recheck.spec | 54 +++++++++++++++++++ 4 files changed, 111 insertions(+), 24 deletions(-) create mode 100644 src/test/isolation/expected/fk-crosstype-recheck.out create mode 100644 src/test/isolation/specs/fk-crosstype-recheck.spec diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index e5ee1541077..f285bf0e808 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -3193,10 +3193,18 @@ ri_FastPathFlushArray(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, { Datum found_val; bool found_null; - bool concurrently_updated; - ScanKeyData recheck_skey[1]; - if (!ri_LockPKTuple(pk_rel, pk_slot, snapshot, &concurrently_updated)) + /* + * No key recheck is needed here, so we have no use for + * concurrently_updated. Unlike ri_FastPathProbeOne(), which takes + * the index scan's word for it that the tuple matches, this path + * compares the key against every buffered FK value below, and it does + * so using found_val, which is read out of the version we actually + * locked. A concurrent key update is therefore caught by that + * comparison: the batch item that led us to this tuple is left + * unmatched and reported as a violation. + */ + if (!ri_LockPKTuple(pk_rel, pk_slot, snapshot, NULL)) continue; /* @@ -3213,22 +3221,6 @@ ri_FastPathFlushArray(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, if (found_null) continue; - if (concurrently_updated) - { - /* - * Build a single-key scankey for recheck. We need the actual PK - * value that was found, not the FK search value. - */ - ScanKeyEntryInitialize(&recheck_skey[0], 0, 1, - fpmeta->strats[0], - fpmeta->subtypes[0], - idx_rel->rd_indcollation[0], - fpmeta->regops[0], - found_val); - if (!recheck_matched_pk_tuple(idx_rel, recheck_skey, 1, pk_slot)) - continue; - } - /* * Linear scan to mark all batch items matching this PK value. * O(batch_size) per match, O(batch_size^2) worst case -- fine for the @@ -3296,9 +3288,11 @@ ri_FastPathProbeOne(Relation pk_rel, Relation idx_rel, * Calls table_tuple_lock() directly with handling specific to RI checks. * Returns true if the tuple was successfully locked. * - * Sets *concurrently_updated to true if the locked tuple was reached - * by following an update chain (tmfd.traversed), indicating the caller - * should recheck the key. + * If concurrently_updated is not NULL, sets *concurrently_updated to true + * if the locked tuple was reached by following an update chain + * (tmfd.traversed), indicating the caller should recheck the key. Callers + * that compare the locked tuple's key against the value they were looking + * for anyway can pass NULL. */ static bool ri_LockPKTuple(Relation pk_rel, TupleTableSlot *slot, Snapshot snap, @@ -3308,7 +3302,8 @@ ri_LockPKTuple(Relation pk_rel, TupleTableSlot *slot, Snapshot snap, TM_Result result; int lockflags = TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS; - *concurrently_updated = false; + if (concurrently_updated) + *concurrently_updated = false; if (!IsolationUsesXactSnapshot()) lockflags |= TUPLE_LOCK_FLAG_FIND_LAST_VERSION; @@ -3321,7 +3316,7 @@ ri_LockPKTuple(Relation pk_rel, TupleTableSlot *slot, Snapshot snap, switch (result) { case TM_Ok: - if (tmfd.traversed) + if (tmfd.traversed && concurrently_updated) *concurrently_updated = true; return true; diff --git a/src/test/isolation/expected/fk-crosstype-recheck.out b/src/test/isolation/expected/fk-crosstype-recheck.out new file mode 100644 index 00000000000..875dc856bce --- /dev/null +++ b/src/test/isolation/expected/fk-crosstype-recheck.out @@ -0,0 +1,37 @@ +Parsed test spec with 2 sessions + +starting permutation: s1b s1away s1back s2ins s1c s2sel +step s1b: BEGIN; +step s1away: UPDATE fkct_pk SET k = '2020-06-01' WHERE payload = 'p1'; +step s1back: UPDATE fkct_pk SET k = '2020-01-01' WHERE payload = 'p1'; +step s2ins: INSERT INTO fkct_fk SELECT g, '2020-01-01'::timestamp FROM generate_series(1,2) g; +step s1c: COMMIT; +step s2ins: <... completed> +step s2sel: SELECT k FROM fkct_pk; + k +---------- +01-01-2020 +(1 row) + + +starting permutation: s1b s1away s2ins s1c s2sel +step s1b: BEGIN; +step s1away: UPDATE fkct_pk SET k = '2020-06-01' WHERE payload = 'p1'; +step s2ins: INSERT INTO fkct_fk SELECT g, '2020-01-01'::timestamp FROM generate_series(1,2) g; +step s1c: COMMIT; +step s2ins: <... completed> +ERROR: insert or update on table "fkct_fk" violates foreign key constraint "fkct_fk_t_fkey" +step s2sel: SELECT k FROM fkct_pk; + k +---------- +06-01-2020 +(1 row) + + +starting permutation: s1b s1aways s1backs s2inss s1c +step s1b: BEGIN; +step s1aways: UPDATE fkct_pk_same SET k = '2020-06-01' WHERE payload = 'p1'; +step s1backs: UPDATE fkct_pk_same SET k = '2020-01-01' WHERE payload = 'p1'; +step s2inss: INSERT INTO fkct_fk_same SELECT g, '2020-01-01'::timestamp FROM generate_series(1,2) g; +step s1c: COMMIT; +step s2inss: <... completed> diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index a27480a86a2..6469aafa2e1 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -30,6 +30,7 @@ test: detach-partition-concurrently-2 test: detach-partition-concurrently-3 test: detach-partition-concurrently-4 test: fk-contention +test: fk-crosstype-recheck test: fk-deadlock test: fk-deadlock2 test: fk-partitioned-1 diff --git a/src/test/isolation/specs/fk-crosstype-recheck.spec b/src/test/isolation/specs/fk-crosstype-recheck.spec new file mode 100644 index 00000000000..5d479b8d46c --- /dev/null +++ b/src/test/isolation/specs/fk-crosstype-recheck.spec @@ -0,0 +1,54 @@ +# A foreign key may use a cross-type equality operator: a "date" primary key +# and a "timestamp" referencing column give "=(date,timestamp without time +# zone)", whose left input is the PK type and whose right input is the FK type. +# +# When the referenced row is updated while a check is locking it, the check +# has to re-check against the new version of the row. That re-check must +# still pass each value to the side of the operator that expects it. A date +# counts days and a timestamp counts microseconds, so reading one as the other +# compares two unrelated numbers. Both types are pass-by-value, so nothing +# here turns on how a value is stored, only on which side it is read from. +# +# Below the referenced key is present the whole time -- s1 moves it away and +# puts it back inside one transaction -- so the INSERT must succeed, exactly as +# it does for the same-type case in the second permutation. + +setup +{ + CREATE TABLE fkct_pk (k date PRIMARY KEY, payload text); + CREATE TABLE fkct_fk (id int, t timestamp REFERENCES fkct_pk(k)); + INSERT INTO fkct_pk VALUES ('2020-01-01', 'p1'); + + CREATE TABLE fkct_pk_same (k timestamp PRIMARY KEY, payload text); + CREATE TABLE fkct_fk_same (id int, t timestamp REFERENCES fkct_pk_same(k)); + INSERT INTO fkct_pk_same VALUES ('2020-01-01', 'p1'); +} + +teardown +{ + DROP TABLE fkct_fk, fkct_pk, fkct_fk_same, fkct_pk_same; +} + +session s1 +step s1b { BEGIN; } +step s1away { UPDATE fkct_pk SET k = '2020-06-01' WHERE payload = 'p1'; } +step s1back { UPDATE fkct_pk SET k = '2020-01-01' WHERE payload = 'p1'; } +step s1aways { UPDATE fkct_pk_same SET k = '2020-06-01' WHERE payload = 'p1'; } +step s1backs { UPDATE fkct_pk_same SET k = '2020-01-01' WHERE payload = 'p1'; } +step s1c { COMMIT; } + +# Two rows in one statement, so the checks are batched -- that is what reaches +# the re-check path under test. +session s2 +step s2ins { INSERT INTO fkct_fk SELECT g, '2020-01-01'::timestamp FROM generate_series(1,2) g; } +step s2inss { INSERT INTO fkct_fk_same SELECT g, '2020-01-01'::timestamp FROM generate_series(1,2) g; } +step s2sel { SELECT k FROM fkct_pk; } + +permutation s1b s1away s1back s2ins s1c s2sel + +# The mirror image: s1 leaves the key where it moved it, so the INSERT must +# fail. Making the re-check accept every concurrently updated tuple would +# satisfy the permutation above while breaking this one. +permutation s1b s1away s2ins s1c s2sel + +permutation s1b s1aways s1backs s2inss s1c From ec51b80b348fe34da15cfb991191ef0bdc4838c6 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Tue, 18 Aug 2026 17:07:02 +0900 Subject: [PATCH 387/481] Fix RI fast-path race with REINDEX CONCURRENTLY The RI fast path reads pg_constraint.conindid before taking RowShareLock on the referenced table. REINDEX CONCURRENTLY can repoint the constraint and mark the old index dead, or drop it, between those operations. A backend in that window does not yet hold a relation lock, so it is not covered by REINDEX CONCURRENTLY's waits for lockers. Opening an index that has already been dropped produces "could not open relation with OID". Opening one that has only been marked dead can produce wrong answers: the index is no longer maintained or vacuumed, so a scan can miss a referenced row or follow a stale entry to a reused heap line pointer. After locking the referenced table, reload the constraint and use its current conindid. LockRelationOid() processes invalidation messages after acquiring the lock, so the reload sees a committed index swap. If the lock was already held, REINDEX CONCURRENTLY cannot mark the old index dead or drop it until the transaction releases that lock, so continuing to use the old conindid is safe. Do this at both RI fast-path call sites. Add injection-point coverage for old indexes that have either been dropped or marked dead. Author: Mihail Nikalayeu Discussion: https://postgr.es/m/CADzfLwUJiVuv69uwuF5z4TrMhNkVwQUXW03q+uVNwmYFLtjEhw@mail.gmail.com Backpatch-through: 19 --- src/backend/commands/indexcmds.c | 1 + src/backend/utils/adt/ri_triggers.c | 20 ++ src/test/modules/injection_points/Makefile | 1 + .../expected/ri_fastpath_reindex.out | 171 ++++++++++++++++++ src/test/modules/injection_points/meson.build | 1 + .../specs/ri_fastpath_reindex.spec | 108 +++++++++++ 6 files changed, 302 insertions(+) create mode 100644 src/test/modules/injection_points/expected/ri_fastpath_reindex.out create mode 100644 src/test/modules/injection_points/specs/ri_fastpath_reindex.spec diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index c09852c9528..af03cc7cb08 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -4401,6 +4401,7 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein * Drop the old indexes. */ + INJECTION_POINT("reindex-relation-concurrently-before-drop", NULL); pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, PROGRESS_CREATEIDX_PHASE_WAIT_5); WaitForLockersMultiple(lockTags, AccessExclusiveLock, true); diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index f285bf0e808..d51e9dd3b23 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -49,6 +49,7 @@ #include "utils/fmgroids.h" #include "utils/guc.h" #include "utils/hsearch.h" +#include "utils/injection_point.h" #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -2824,7 +2825,13 @@ ri_FastPathCheck(RI_ConstraintInfo *riinfo, CommandCounterIncrement(); snapshot = RegisterSnapshot(GetTransactionSnapshot()); + INJECTION_POINT("ri-before-pk-lock", NULL); + pk_rel = table_open(riinfo->pk_relid, RowShareLock); + + /* Re-read the constraint under that lock; see ri_FastPathGetEntry(). */ + riinfo = ri_LoadConstraintInfo(riinfo->constraint_id); + idx_rel = index_open(riinfo->conindid, AccessShareLock); slot = table_slot_create(pk_rel, NULL); @@ -4421,7 +4428,20 @@ ri_FastPathGetEntry(const RI_ConstraintInfo *riinfo, Relation fk_rel) * We don't release these locks until end of transaction, matching SPI * behavior. */ + + INJECTION_POINT("ri-before-pk-lock", NULL); + entry->pk_rel = table_open(riinfo->pk_relid, RowShareLock); + + /* + * conindid may have been read before we took that lock, and REINDEX + * CONCURRENTLY moves a constraint to a new index. Re-read it now: + * LockRelationOid() processes invalidation messages after acquiring + * the lock, so we either see the new index, or an old one that cannot + * be marked dead or dropped until this transaction ends. + */ + riinfo = ri_LoadConstraintInfo(riinfo->constraint_id); + entry->idx_rel = index_open(riinfo->conindid, AccessShareLock); entry->pk_slot = table_slot_create(entry->pk_rel, NULL); diff --git a/src/test/modules/injection_points/Makefile b/src/test/modules/injection_points/Makefile index 25a3ddd890d..3b136adf126 100644 --- a/src/test/modules/injection_points/Makefile +++ b/src/test/modules/injection_points/Makefile @@ -19,6 +19,7 @@ ISOLATION = basic \ repack_temporal \ repack_temporal_multirange \ repack_toast \ + ri_fastpath_reindex \ syscache-update-pruned \ wait_cleanup \ heap_lock_update diff --git a/src/test/modules/injection_points/expected/ri_fastpath_reindex.out b/src/test/modules/injection_points/expected/ri_fastpath_reindex.out new file mode 100644 index 00000000000..275b9a6d085 --- /dev/null +++ b/src/test/modules/injection_points/expected/ri_fastpath_reindex.out @@ -0,0 +1,171 @@ +Parsed test spec with 3 sessions + +starting permutation: reindex upd wake_reindex reindexed swapped wake_check checked rows orphan +injection_points_attach +----------------------- + +(1 row) + +injection_points_attach +----------------------- + +(1 row) + +step reindex: REINDEX INDEX CONCURRENTLY ri_pk_pkey; +step upd: UPDATE ri_fk SET pid = 42 WHERE id = 1; +step wake_reindex: + SELECT injection_points_detach('reindex-relation-concurrently-before-swap'); + SELECT injection_points_wakeup('reindex-relation-concurrently-before-swap'); + +injection_points_detach +----------------------- + +(1 row) + +injection_points_wakeup +----------------------- + +(1 row) + +step reindex: <... completed> +step reindexed: +step swapped: + SELECT count(*) = 0 AS old_index_dropped + FROM pg_class WHERE oid = (SELECT conindid FROM ri_old_index); + SELECT conindid <> (SELECT conindid FROM ri_old_index) AS constraint_moved + FROM pg_constraint WHERE conname = 'ri_fk_pid_fkey'; + +old_index_dropped +----------------- +t +(1 row) + +constraint_moved +---------------- +t +(1 row) + +step wake_check: + SELECT injection_points_detach('ri-before-pk-lock'); + SELECT injection_points_wakeup('ri-before-pk-lock'); + +injection_points_detach +----------------------- + +(1 row) + +injection_points_wakeup +----------------------- + +(1 row) + +step upd: <... completed> +step checked: +step rows: SELECT id, pid FROM ri_fk WHERE id IN (1, 2) ORDER BY id; +id|pid +--+--- + 1| 42 + 2| 2 +(2 rows) + +step orphan: INSERT INTO ri_fk VALUES (999, 12345); +ERROR: insert or update on table "ri_fk" violates foreign key constraint "ri_fk_pid_fkey" + +starting permutation: park_drop reindex upd_new wake_reindex await_drop dead wake_check checked wake_drop reindexed rows orphan +injection_points_attach +----------------------- + +(1 row) + +injection_points_attach +----------------------- + +(1 row) + +step park_drop: + SELECT injection_points_attach('reindex-relation-concurrently-before-drop', 'wait'); + +injection_points_attach +----------------------- + +(1 row) + +step reindex: REINDEX INDEX CONCURRENTLY ri_pk_pkey; +step upd_new: UPDATE ri_fk SET pid = 500 WHERE id = 1; +step wake_reindex: + SELECT injection_points_detach('reindex-relation-concurrently-before-swap'); + SELECT injection_points_wakeup('reindex-relation-concurrently-before-swap'); + +injection_points_detach +----------------------- + +(1 row) + +injection_points_wakeup +----------------------- + +(1 row) + +step await_drop: + DO $$ + BEGIN + LOOP + PERFORM 1 FROM pg_stat_activity + WHERE wait_event = 'reindex-relation-concurrently-before-drop'; + EXIT WHEN FOUND; + PERFORM pg_sleep(.1); + END LOOP; + END + $$; + +step dead: + SELECT indisvalid, indisready, indislive + FROM pg_index WHERE indexrelid = (SELECT conindid FROM ri_old_index); + INSERT INTO ri_pk VALUES (500); + +indisvalid|indisready|indislive +----------+----------+--------- +f |f |f +(1 row) + +step wake_check: + SELECT injection_points_detach('ri-before-pk-lock'); + SELECT injection_points_wakeup('ri-before-pk-lock'); + +injection_points_detach +----------------------- + +(1 row) + +injection_points_wakeup +----------------------- + +(1 row) + +step upd_new: <... completed> +step checked: +step wake_drop: + SELECT injection_points_detach('reindex-relation-concurrently-before-drop'); + SELECT injection_points_wakeup('reindex-relation-concurrently-before-drop'); + +injection_points_detach +----------------------- + +(1 row) + +injection_points_wakeup +----------------------- + +(1 row) + +step reindex: <... completed> +step reindexed: +step rows: SELECT id, pid FROM ri_fk WHERE id IN (1, 2) ORDER BY id; +id|pid +--+--- + 1|500 + 2| 2 +(2 rows) + +step orphan: INSERT INTO ri_fk VALUES (999, 12345); +ERROR: insert or update on table "ri_fk" violates foreign key constraint "ri_fk_pid_fkey" diff --git a/src/test/modules/injection_points/meson.build b/src/test/modules/injection_points/meson.build index aaf0536ba7e..aff516b901a 100644 --- a/src/test/modules/injection_points/meson.build +++ b/src/test/modules/injection_points/meson.build @@ -50,6 +50,7 @@ tests += { 'repack_temporal', 'repack_temporal_multirange', 'repack_toast', + 'ri_fastpath_reindex', 'syscache-update-pruned', 'wait_cleanup', 'heap_lock_update', diff --git a/src/test/modules/injection_points/specs/ri_fastpath_reindex.spec b/src/test/modules/injection_points/specs/ri_fastpath_reindex.spec new file mode 100644 index 00000000000..3c2b8dc1ccb --- /dev/null +++ b/src/test/modules/injection_points/specs/ri_fastpath_reindex.spec @@ -0,0 +1,108 @@ +# A foreign key check racing a rebuild of the index it resolves through. +# +# The RI fast path reads conindid before it locks the referenced table, so a +# concurrent REINDEX CONCURRENTLY can repoint the constraint and drop that +# index in between. Cover both outcomes: an index that is already gone, and +# one that is only marked dead and so no longer receives new rows. + +setup +{ + CREATE EXTENSION injection_points; + CREATE TABLE ri_pk (id int PRIMARY KEY); + INSERT INTO ri_pk SELECT g FROM generate_series(1, 100) g; + CREATE TABLE ri_fk (id int PRIMARY KEY, pid int REFERENCES ri_pk(id)); + INSERT INTO ri_fk SELECT g, g FROM generate_series(1, 100) g; + CREATE TABLE ri_old_index AS + SELECT conindid FROM pg_constraint WHERE conname = 'ri_fk_pid_fkey'; +} + +teardown +{ + DROP TABLE ri_fk, ri_pk, ri_old_index; + DROP EXTENSION injection_points; +} + +# The rebuild, stopped just before it repoints the constraint. +session s1 +setup +{ + SELECT injection_points_set_local(); + SELECT injection_points_attach('reindex-relation-concurrently-before-swap', 'wait'); +} +# Stops it again, after the old index is dead and before it is dropped. +step park_drop +{ + SELECT injection_points_attach('reindex-relation-concurrently-before-drop', 'wait'); +} +step reindex { REINDEX INDEX CONCURRENTLY ri_pk_pkey; } +# Forces the rebuild to have finished before anything else runs. +step reindexed { } + +# The writer, stopped after it read conindid and before it locks ri_pk. +session s2 +setup +{ + SELECT injection_points_set_local(); + SELECT injection_points_attach('ri-before-pk-lock', 'wait'); +} +step upd { UPDATE ri_fk SET pid = 42 WHERE id = 1; } +# 500 is added while the check is parked, so only a maintained index has it. +step upd_new { UPDATE ri_fk SET pid = 500 WHERE id = 1; } +# Forces the check to have finished before anything else runs. +step checked { } + +session s3 +step wake_reindex +{ + SELECT injection_points_detach('reindex-relation-concurrently-before-swap'); + SELECT injection_points_wakeup('reindex-relation-concurrently-before-swap'); +} +step swapped +{ + SELECT count(*) = 0 AS old_index_dropped + FROM pg_class WHERE oid = (SELECT conindid FROM ri_old_index); + SELECT conindid <> (SELECT conindid FROM ri_old_index) AS constraint_moved + FROM pg_constraint WHERE conname = 'ri_fk_pid_fkey'; +} +step wake_check +{ + SELECT injection_points_detach('ri-before-pk-lock'); + SELECT injection_points_wakeup('ri-before-pk-lock'); +} +# Waking a session does not mean it has moved on: it can still be reported as +# waiting on the point it was woken from. Wait for the name of the next point +# instead, which only appears once the old index is dead. The empty step trick +# used above does not work here, since the rebuild parks again rather than +# finishing. +step await_drop +{ + DO $$ + BEGIN + LOOP + PERFORM 1 FROM pg_stat_activity + WHERE wait_event = 'reindex-relation-concurrently-before-drop'; + EXIT WHEN FOUND; + PERFORM pg_sleep(.1); + END LOOP; + END + $$; +} +step dead +{ + SELECT indisvalid, indisready, indislive + FROM pg_index WHERE indexrelid = (SELECT conindid FROM ri_old_index); + INSERT INTO ri_pk VALUES (500); +} +step wake_drop +{ + SELECT injection_points_detach('reindex-relation-concurrently-before-drop'); + SELECT injection_points_wakeup('reindex-relation-concurrently-before-drop'); +} +step rows { SELECT id, pid FROM ri_fk WHERE id IN (1, 2) ORDER BY id; } +# The constraint must still be enforced, not merely not crashing. +step orphan { INSERT INTO ri_fk VALUES (999, 12345); } + +# Batched call site. +permutation reindex upd wake_reindex reindexed swapped wake_check checked rows orphan +# Dead index rather than dropped one. +permutation park_drop reindex upd_new wake_reindex await_drop dead wake_check checked wake_drop reindexed rows orphan From 7864a14c4370b11cac74bcdf4cae5bb6a6ae867b Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Tue, 18 Aug 2026 14:24:21 +0300 Subject: [PATCH 388/481] Add wait-for-lsn process-exit cleanup callback WaitLSNCleanup() was called from ProcKill(), but not from AuxiliaryProcKill(), even though xlogwait.c sizes its shared memory to include NUM_AUXILIARY_PROCS and thus accepts calls from auxiliary processes. Such a process exiting while waiting would leave its entry in the heap. Register an on_shmem_exit callback lazily before a process enters a wait-for-lsn heap instead, as suggested by Noah: that keeps the cleanup local to xlogwait.c and makes it harder to miss a caller that needs it, rather than having to remember every process-kill path. Reported-by: Noah Misch Author: Xuneng Zhou Reviewed-by: Alexander Korotkov Discussion: https://postgr.es/m/20260706012642.f9.noahmisch%40microsoft.com Discussion: https://postgr.es/m/CABPTF7UtW_cAa%3DQh4RDfKiUqu3pJJE22ai9tbWJVERbeRyssLw%40mail.gmail.com Backpatch-through: 19 --- src/backend/access/transam/xlogwait.c | 38 +++++++++++++++++++++++++++ src/backend/storage/lmgr/proc.c | 6 ----- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/backend/access/transam/xlogwait.c b/src/backend/access/transam/xlogwait.c index 582dde3b061..85de3f5cdae 100644 --- a/src/backend/access/transam/xlogwait.c +++ b/src/backend/access/transam/xlogwait.c @@ -54,6 +54,7 @@ #include "miscadmin.h" #include "pgstat.h" #include "replication/walreceiver.h" +#include "storage/ipc.h" #include "storage/latch.h" #include "storage/proc.h" #include "storage/shmem.h" @@ -69,8 +70,12 @@ static int waitlsn_cmp(const pairingheap_node *a, const pairingheap_node *b, struct WaitLSNState *waitLSNState = NULL; +static bool waitLSNShmemExitRegistered = false; + static void WaitLSNShmemRequest(void *arg); static void WaitLSNShmemInit(void *arg); +static void WaitLSNShmemExit(int code, Datum arg); +static void RegisterWaitLSNShmemExit(void); const ShmemCallbacks WaitLSNShmemCallbacks = { .request_fn = WaitLSNShmemRequest, @@ -378,6 +383,31 @@ WaitLSNCleanup(void) } } +/* + * Exit callback to clean up any LSN wait state left behind if this process + * exits while waiting. Transaction abort paths call WaitLSNCleanup() + * directly. + */ +static void +WaitLSNShmemExit(int code, Datum arg) +{ + WaitLSNCleanup(); +} + +/* + * Register shared-memory exit cleanup once per process. A backend may + * execute WAIT FOR LSN more than once. + */ +static void +RegisterWaitLSNShmemExit(void) +{ + if (!waitLSNShmemExitRegistered) + { + on_shmem_exit(WaitLSNShmemExit, 0); + waitLSNShmemExitRegistered = true; + } +} + /* * Check if the given LSN type requires recovery to be in progress. * Standby wait types (replay, write, flush) require recovery; @@ -412,6 +442,14 @@ WaitForLSN(WaitLSNType lsnType, XLogRecPtr targetLSN, int64 timeout) /* Should have a valid proc number */ Assert(MyProcNumber >= 0 && MyProcNumber < MaxBackends + NUM_AUXILIARY_PROCS); + /* + * Ensure cleanup is registered before publishing our waiter entry. + * on_shmem_exit callbacks run in reverse registration order, so this + * callback runs before the earlier-registered ProcKill() and removes the + * entry before our PGPROC slot can be reused. + */ + RegisterWaitLSNShmemExit(); + if (timeout > 0) { endtime = TimestampTzPlusMilliseconds(GetCurrentTimestamp(), timeout); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7d01c981a1f..cfa60154278 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -37,7 +37,6 @@ #include "access/transam.h" #include "access/twophase.h" #include "access/xlogutils.h" -#include "access/xlogwait.h" #include "miscadmin.h" #include "pgstat.h" #include "postmaster/autovacuum.h" @@ -955,11 +954,6 @@ ProcKill(int code, Datum arg) */ LWLockReleaseAll(); - /* - * Cleanup waiting for LSN if any. - */ - WaitLSNCleanup(); - /* Cancel any pending condition variable sleep, too */ ConditionVariableCancelSleep(); From d2eb714c7ae70afc1837da5db4393b0f50dcc77f Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Tue, 18 Aug 2026 14:25:03 +0300 Subject: [PATCH 389/481] Fix WAIT FOR LSN documentation examples Pad example LSNs to match pg_lsn_out() output, and use "standby_replay LSN" in the timeout error to match the server message. Author: Xuneng Zhou Reviewed-by: Alexander Korotkov Discussion: https://postgr.es/m/CABPTF7UtW_cAa%3DQh4RDfKiUqu3pJJE22ai9tbWJVERbeRyssLw%40mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/ref/wait_for.sgml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/src/sgml/ref/wait_for.sgml b/doc/src/sgml/ref/wait_for.sgml index cd5dd031991..01dc2a84a1a 100644 --- a/doc/src/sgml/ref/wait_for.sgml +++ b/doc/src/sgml/ref/wait_for.sgml @@ -301,7 +301,7 @@ UPDATE 100 postgres=# SELECT pg_current_wal_insert_lsn(); pg_current_wal_insert_lsn --------------------------- - 0/306EE20 + 0/0306EE20 (1 row) @@ -310,7 +310,7 @@ postgres=# SELECT pg_current_wal_insert_lsn(); changes made on primary should be guaranteed to be visible on replica. -postgres=# WAIT FOR LSN '0/306EE20'; +postgres=# WAIT FOR LSN '0/0306EE20'; status --------- success @@ -326,7 +326,7 @@ postgres=# SELECT * FROM movie WHERE genre = 'Drama'; Wait for flush (data durable on replica): -postgres=# WAIT FOR LSN '0/306EE20' WITH (MODE 'standby_flush'); +postgres=# WAIT FOR LSN '0/0306EE20' WITH (MODE 'standby_flush'); status --------- success @@ -338,7 +338,7 @@ postgres=# WAIT FOR LSN '0/306EE20' WITH (MODE 'standby_flush'); Wait for write with timeout: -postgres=# WAIT FOR LSN '0/306EE20' WITH (MODE 'standby_write', TIMEOUT '100ms', NO_THROW); +postgres=# WAIT FOR LSN '0/0306EE20' WITH (MODE 'standby_write', TIMEOUT '100ms', NO_THROW); status --------- success @@ -350,7 +350,7 @@ postgres=# WAIT FOR LSN '0/306EE20' WITH (MODE 'standby_write', TIMEOUT '100ms', Wait for flush on primary: -postgres=# WAIT FOR LSN '0/306EE20' WITH (MODE 'primary_flush'); +postgres=# WAIT FOR LSN '0/0306EE20' WITH (MODE 'primary_flush'); status --------- success @@ -362,8 +362,8 @@ postgres=# WAIT FOR LSN '0/306EE20' WITH (MODE 'primary_flush'); If the target LSN is not reached before the timeout, an error is thrown: -postgres=# WAIT FOR LSN '0/306EE20' WITH (TIMEOUT '0.1s'); -ERROR: timed out while waiting for target LSN 0/306EE20 to be replayed; current replay LSN 0/306EA60 +postgres=# WAIT FOR LSN '0/0306EE20' WITH (TIMEOUT '0.1s'); +ERROR: timed out while waiting for target LSN 0/0306EE20 to be replayed; current standby_replay LSN 0/0306EA60 @@ -372,7 +372,7 @@ ERROR: timed out while waiting for target LSN 0/306EE20 to be replayed; current NO_THROW option: -postgres=# WAIT FOR LSN '0/306EE20' WITH (TIMEOUT '100ms', NO_THROW); +postgres=# WAIT FOR LSN '0/0306EE20' WITH (TIMEOUT '100ms', NO_THROW); status --------- timeout From 58c48b4ec42583c69b3a7e9c6cf7649b38fc8151 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Tue, 18 Aug 2026 14:25:53 +0300 Subject: [PATCH 390/481] Avoid locking when an LSN waiter is already removed WaitLSNWakeup() removes each selected waiter from its heap and clears its inHeap flag before setting its latch. When such a waiter later calls deleteLSNWaiter(), it acquires WaitLSNLock exclusively only to discover that there is nothing left to remove. Waking many waiters can therefore make them serialize on the lock for no useful work. Check inHeap before acquiring WaitLSNLock. A lockless false value is conclusive because only the owning backend can change inHeap from false to true. A concurrent waker can only clear it. A stale true value falls through to the existing recheck under the lock. WaitLSNCleanup() performed the same lockless check before calling deleteLSNWaiter(). Drop it there, as it is now redundant. Author: Xuneng Zhou Reviewed-by: Alexander Korotkov Discussion: https://postgr.es/m/CABPTF7UtW_cAa%3DQh4RDfKiUqu3pJJE22ai9tbWJVERbeRyssLw%40mail.gmail.com Backpatch-through: 19 --- src/backend/access/transam/xlogwait.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/backend/access/transam/xlogwait.c b/src/backend/access/transam/xlogwait.c index 85de3f5cdae..5ff1d4fcd70 100644 --- a/src/backend/access/transam/xlogwait.c +++ b/src/backend/access/transam/xlogwait.c @@ -252,6 +252,15 @@ deleteLSNWaiter(WaitLSNType lsnType) Assert(i >= 0 && i < WAIT_LSN_TYPE_COUNT); + /* + * Avoid taking WaitLSNLock if a waker has already removed us. Only this + * backend can set inHeap; other processes can only clear it. Therefore + * false is conclusive, while a stale true is harmless because it is + * rechecked under WaitLSNLock below. + */ + if (!procInfo->inHeap) + return; + LWLockAcquire(WaitLSNLock, LW_EXCLUSIVE); Assert(procInfo->lsnType == lsnType); @@ -370,17 +379,15 @@ WaitLSNWakeup(WaitLSNType lsnType, XLogRecPtr currentLSN) void WaitLSNCleanup(void) { + /* + * deleteLSNWaiter() starts with the same lockless inHeap check, so + * calling it unconditionally costs nothing when this process isn't + * waiting. Its lsnType is then unused, and reading it is harmless in any + * case: an entry that was never used is zeroed, which is a valid + * WaitLSNType. + */ if (waitLSNState) - { - /* - * We do a fast-path check of the inHeap flag without the lock. This - * flag is set to true only by the process itself. So, it's only - * possible to get a false positive. But that will be eliminated by a - * recheck inside deleteLSNWaiter(). - */ - if (waitLSNState->procInfos[MyProcNumber].inHeap) - deleteLSNWaiter(waitLSNState->procInfos[MyProcNumber].lsnType); - } + deleteLSNWaiter(waitLSNState->procInfos[MyProcNumber].lsnType); } /* From f2d6392e199256dd4a37bebbc92a2d28fac45b5f Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Tue, 18 Aug 2026 14:26:38 +0300 Subject: [PATCH 391/481] Clarify LSN waiter cleanup after wakeup WaitLSNWakeup() can be called by several processes, not only the startup process. Update the cleanup comment to explain that another process may remove the waiter before waking it and that inHeap prevents double deletion. Author: Xuneng Zhou Reviewed-by: Alexander Korotkov Discussion: https://postgr.es/m/CABPTF7UtW_cAa%3DQh4RDfKiUqu3pJJE22ai9tbWJVERbeRyssLw%40mail.gmail.com Backpatch-through: 19 --- src/backend/access/transam/xlogwait.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/backend/access/transam/xlogwait.c b/src/backend/access/transam/xlogwait.c index 5ff1d4fcd70..b82f64df65a 100644 --- a/src/backend/access/transam/xlogwait.c +++ b/src/backend/access/transam/xlogwait.c @@ -524,9 +524,10 @@ WaitForLSN(WaitLSNType lsnType, XLogRecPtr targetLSN, int64 timeout) } /* - * Delete our process from the shared memory heap. We might already be - * deleted by the startup process. The 'inHeap' flags prevents us from - * the double deletion. + * A progress waker, such as the startup process during WAL replay, may + * already have removed this waiter through WaitLSNWakeup() before setting + * its latch. The inHeap flag makes this cleanup safe whether or not the + * entry remains in the heap. */ deleteLSNWaiter(lsnType); From 0ec36f4ba325062882eb7a36b8f815e85ff8c123 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Tue, 18 Aug 2026 14:27:23 +0300 Subject: [PATCH 392/481] Re-register LSN waiters after stale wakeups WaitLSNWakeup() removes a waiter from the heap before setting its latch. If the position that caused the wakeup moves backwards before the waiter rechecks it, as can happen when WAL streaming restarts, the waiter may sleep again while no longer registered. Subsequent WAL progress then cannot wake it. When an unmet waiter finds that it is no longer in the heap, add it back and restart the loop. Rereading the position after registration also prevents missing an advance between the previous read and the re-add. Process interrupts before re-registering rather than after, so that a wakeup which goes stale again cannot postpone cancellation, however often it repeats. As a side effect, a pending cancel now wins over an expired timeout, which previously reported a timeout instead. Add deterministic TAP coverage that simulates a stale standby_write wakeup without advancing the actual write or replay positions. Author: Xuneng Zhou Reviewed-by: Alexander Korotkov Discussion: https://postgr.es/m/CABPTF7UtW_cAa%3DQh4RDfKiUqu3pJJE22ai9tbWJVERbeRyssLw%40mail.gmail.com Backpatch-through: 19 --- src/backend/access/transam/xlogwait.c | 37 ++++++- src/test/modules/Makefile | 1 + src/test/modules/meson.build | 1 + src/test/modules/test_wait_lsn/Makefile | 21 ++++ src/test/modules/test_wait_lsn/meson.build | 22 +++++ .../test_wait_lsn/test_wait_lsn--1.0.sql | 14 +++ .../modules/test_wait_lsn/test_wait_lsn.c | 99 +++++++++++++++++++ .../test_wait_lsn/test_wait_lsn.control | 4 + src/test/recovery/Makefile | 3 +- src/test/recovery/t/049_wait_for_lsn.pl | 85 ++++++++++++++++ 10 files changed, 284 insertions(+), 3 deletions(-) create mode 100644 src/test/modules/test_wait_lsn/Makefile create mode 100644 src/test/modules/test_wait_lsn/meson.build create mode 100644 src/test/modules/test_wait_lsn/test_wait_lsn--1.0.sql create mode 100644 src/test/modules/test_wait_lsn/test_wait_lsn.c create mode 100644 src/test/modules/test_wait_lsn/test_wait_lsn.control diff --git a/src/backend/access/transam/xlogwait.c b/src/backend/access/transam/xlogwait.c index b82f64df65a..eee90e7f626 100644 --- a/src/backend/access/transam/xlogwait.c +++ b/src/backend/access/transam/xlogwait.c @@ -440,6 +440,7 @@ WaitLSNResult WaitForLSN(WaitLSNType lsnType, XLogRecPtr targetLSN, int64 timeout) { XLogRecPtr currentLSN; + WaitLSNProcInfo *procInfo; TimestampTz endtime = 0; int wake_events = WL_LATCH_SET | WL_POSTMASTER_DEATH; @@ -449,6 +450,8 @@ WaitForLSN(WaitLSNType lsnType, XLogRecPtr targetLSN, int64 timeout) /* Should have a valid proc number */ Assert(MyProcNumber >= 0 && MyProcNumber < MaxBackends + NUM_AUXILIARY_PROCS); + procInfo = &waitLSNState->procInfos[MyProcNumber]; + /* * Ensure cleanup is registered before publishing our waiter entry. * on_shmem_exit callbacks run in reverse registration order, so this @@ -498,6 +501,38 @@ WaitForLSN(WaitLSNType lsnType, XLogRecPtr targetLSN, int64 timeout) break; } + CHECK_FOR_INTERRUPTS(); + + /* + * The target is not reached. Normally we remain in the waiters heap + * and can sleep again. A wakeup can become stale, however, if the + * position moves backwards after the waker removed us. That happens + * with the walreceiver-tracked positions: when streaming starts on a + * new timeline, or after receiveStart was reset, + * RequestXLogStreaming() re-seeds writtenUpto and flushedUpto with + * the requested start position, which can be below what was published + * before. Re-register in that case and reread the position, since an + * advance between the previous read and the re-add could not have + * woken us. + * + * A wakeup that goes stale again sends us around the loop once more, + * so interrupts are processed before we re-register: however often + * that repeats, the wait stays cancellable. Repeating requires a + * fresh wakeup, hence the position reaching the target and falling + * back below it, so it follows streaming restarts rather than burning + * CPU. The deadline is checked on every iteration that goes on to + * sleep, which is the only place it matters. + * + * It is safe to read inHeap without the lock because only this + * process sets it true. If a waker clears it concurrently, it also + * sets our latch, so we will recheck and re-register if necessary. + */ + if (!procInfo->inHeap) + { + addLSNWaiter(targetLSN, lsnType); + continue; + } + if (timeout > 0) { delay_ms = TimestampDifferenceMilliseconds(GetCurrentTimestamp(), endtime); @@ -505,8 +540,6 @@ WaitForLSN(WaitLSNType lsnType, XLogRecPtr targetLSN, int64 timeout) break; } - CHECK_FOR_INTERRUPTS(); - rc = WaitLatch(MyLatch, wake_events, delay_ms, WaitLSNWaitEvents[lsnType]); diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 098bb8142ae..bb88b3058ed 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -53,6 +53,7 @@ SUBDIRS = \ test_shm_mq \ test_slru \ test_tidstore \ + test_wait_lsn \ unsafe_tests \ worker_spi \ xid_wraparound diff --git a/src/test/modules/meson.build b/src/test/modules/meson.build index 4bca42bb370..ce09e00531d 100644 --- a/src/test/modules/meson.build +++ b/src/test/modules/meson.build @@ -54,6 +54,7 @@ subdir('test_shmem') subdir('test_shm_mq') subdir('test_slru') subdir('test_tidstore') +subdir('test_wait_lsn') subdir('typcache') subdir('unsafe_tests') subdir('worker_spi') diff --git a/src/test/modules/test_wait_lsn/Makefile b/src/test/modules/test_wait_lsn/Makefile new file mode 100644 index 00000000000..e9ce2fd3ad0 --- /dev/null +++ b/src/test/modules/test_wait_lsn/Makefile @@ -0,0 +1,21 @@ +# src/test/modules/test_wait_lsn/Makefile + +MODULE_big = test_wait_lsn +OBJS = \ + $(WIN32RES) \ + test_wait_lsn.o +PGFILEDESC = "test_wait_lsn - test code for WAIT FOR LSN" + +EXTENSION = test_wait_lsn +DATA = test_wait_lsn--1.0.sql + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/test_wait_lsn +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/test_wait_lsn/meson.build b/src/test/modules/test_wait_lsn/meson.build new file mode 100644 index 00000000000..66e074298d7 --- /dev/null +++ b/src/test/modules/test_wait_lsn/meson.build @@ -0,0 +1,22 @@ +# Copyright (c) 2026, PostgreSQL Global Development Group + +test_wait_lsn_sources = files( + 'test_wait_lsn.c', +) + +if host_system == 'windows' + test_wait_lsn_sources += rc_lib_gen.process(win32ver_rc, extra_args: [ + '--NAME', 'test_wait_lsn', + '--FILEDESC', 'test_wait_lsn - test code for WAIT FOR LSN',]) +endif + +test_wait_lsn = shared_module('test_wait_lsn', + test_wait_lsn_sources, + kwargs: pg_test_mod_args, +) +test_install_libs += test_wait_lsn + +test_install_data += files( + 'test_wait_lsn.control', + 'test_wait_lsn--1.0.sql', +) diff --git a/src/test/modules/test_wait_lsn/test_wait_lsn--1.0.sql b/src/test/modules/test_wait_lsn/test_wait_lsn--1.0.sql new file mode 100644 index 00000000000..4111223726f --- /dev/null +++ b/src/test/modules/test_wait_lsn/test_wait_lsn--1.0.sql @@ -0,0 +1,14 @@ +/* src/test/modules/test_wait_lsn/test_wait_lsn--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION test_wait_lsn" to load this file. \quit + +CREATE FUNCTION test_wait_lsn_wakeup( + pg_catalog.text, pg_catalog.pg_lsn) +RETURNS pg_catalog.void STRICT +AS 'MODULE_PATHNAME' LANGUAGE C; + +CREATE FUNCTION test_wait_lsn_waiter_is_registered( + pg_catalog.int4, pg_catalog.text, pg_catalog.pg_lsn) +RETURNS pg_catalog.bool STRICT +AS 'MODULE_PATHNAME' LANGUAGE C; diff --git a/src/test/modules/test_wait_lsn/test_wait_lsn.c b/src/test/modules/test_wait_lsn/test_wait_lsn.c new file mode 100644 index 00000000000..1eebcf61c5f --- /dev/null +++ b/src/test/modules/test_wait_lsn/test_wait_lsn.c @@ -0,0 +1,99 @@ +/*-------------------------------------------------------------------------- + * + * test_wait_lsn.c + * Test support for WAIT FOR LSN. + * + * Copyright (c) 2026, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/test/modules/test_wait_lsn/test_wait_lsn.c + * + * ------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/xlogwait.h" +#include "fmgr.h" +#include "storage/lwlock.h" +#include "storage/proc.h" +#include "storage/procarray.h" +#include "utils/builtins.h" +#include "utils/pg_lsn.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(test_wait_lsn_wakeup); +PG_FUNCTION_INFO_V1(test_wait_lsn_waiter_is_registered); + +static WaitLSNType +parse_wait_lsn_type(text *mode_text) +{ + char *mode = text_to_cstring(mode_text); + WaitLSNType lsn_type; + + if (pg_strcasecmp(mode, "standby_replay") == 0) + lsn_type = WAIT_LSN_TYPE_STANDBY_REPLAY; + else if (pg_strcasecmp(mode, "standby_write") == 0) + lsn_type = WAIT_LSN_TYPE_STANDBY_WRITE; + else if (pg_strcasecmp(mode, "standby_flush") == 0) + lsn_type = WAIT_LSN_TYPE_STANDBY_FLUSH; + else if (pg_strcasecmp(mode, "primary_flush") == 0) + lsn_type = WAIT_LSN_TYPE_PRIMARY_FLUSH; + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("unrecognized WAIT FOR LSN mode \"%s\"", mode))); + + pfree(mode); + return lsn_type; +} + +/* + * Wake all waiters of the supplied type through the supplied LSN without + * advancing the underlying WAL position. + */ +Datum +test_wait_lsn_wakeup(PG_FUNCTION_ARGS) +{ + WaitLSNType lsn_type = parse_wait_lsn_type(PG_GETARG_TEXT_PP(0)); + XLogRecPtr upto_lsn = PG_GETARG_LSN(1); + + WaitLSNWakeup(lsn_type, upto_lsn); + + PG_RETURN_VOID(); +} + +/* + * Check whether the backend with the supplied PID is registered for the + * supplied mode and target. ProcArrayLock stabilizes the PID mapping, while + * WaitLSNLock protects the registration state. + */ +Datum +test_wait_lsn_waiter_is_registered(PG_FUNCTION_ARGS) +{ + int pid = PG_GETARG_INT32(0); + WaitLSNType lsn_type = parse_wait_lsn_type(PG_GETARG_TEXT_PP(1)); + XLogRecPtr target_lsn = PG_GETARG_LSN(2); + bool registered = false; + PGPROC *proc; + + LWLockAcquire(ProcArrayLock, LW_SHARED); + proc = BackendPidGetProcWithLock(pid); + + if (proc != NULL) + { + ProcNumber procno = GetNumberFromPGProc(proc); + WaitLSNProcInfo *proc_info = &waitLSNState->procInfos[procno]; + + LWLockAcquire(WaitLSNLock, LW_SHARED); + registered = proc_info->inHeap && + proc_info->procno == procno && + proc_info->lsnType == lsn_type && + proc_info->waitLSN == target_lsn; + LWLockRelease(WaitLSNLock); + } + + LWLockRelease(ProcArrayLock); + + PG_RETURN_BOOL(registered); +} diff --git a/src/test/modules/test_wait_lsn/test_wait_lsn.control b/src/test/modules/test_wait_lsn/test_wait_lsn.control new file mode 100644 index 00000000000..7b84150e179 --- /dev/null +++ b/src/test/modules/test_wait_lsn/test_wait_lsn.control @@ -0,0 +1,4 @@ +comment = 'Test code for WAIT FOR LSN' +default_version = '1.0' +module_pathname = '$libdir/test_wait_lsn' +relocatable = true diff --git a/src/test/recovery/Makefile b/src/test/recovery/Makefile index d41aaaf8ae1..9c4102b6b2c 100644 --- a/src/test/recovery/Makefile +++ b/src/test/recovery/Makefile @@ -12,7 +12,8 @@ EXTRA_INSTALL=contrib/pg_prewarm \ contrib/pg_stat_statements \ contrib/test_decoding \ - src/test/modules/injection_points + src/test/modules/injection_points \ + src/test/modules/test_wait_lsn subdir = src/test/recovery top_builddir = ../../.. diff --git a/src/test/recovery/t/049_wait_for_lsn.pl b/src/test/recovery/t/049_wait_for_lsn.pl index bc216064714..cb7d4d461de 100644 --- a/src/test/recovery/t/049_wait_for_lsn.pl +++ b/src/test/recovery/t/049_wait_for_lsn.pl @@ -1055,6 +1055,91 @@ sub check_wait_for_lsn_fencepost 'success', "standby_replay: waiter at current + 1 wakes when replay advances"); +# 11d. A standby_write waiter removed from the waiters heap by a stale wakeup +# must re-register if its target has not actually been reached. +SKIP: +{ + skip 'Required test extension is not installed', 2 + unless $rcv_primary->check_extension('test_wait_lsn'); + + $rcv_primary->safe_psql('postgres', 'CREATE EXTENSION test_wait_lsn'); + $rcv_primary->wait_for_catchup($rcv_standby); + + # Stop streaming before generating the target. This keeps both the + # walreceiver write position and the replay position below the target. + stop_walreceiver($rcv_standby); + $rcv_primary->safe_psql('postgres', 'INSERT INTO rcv_test VALUES (300)'); + my $stale_target = $rcv_primary->safe_psql('postgres', + 'SELECT pg_current_wal_insert_lsn()'); + + # Keep WAIT FOR untimed. After streaming resumes below, its own timeout + # could wake the backend and make the completion check pass even if the + # WAL-progress wakeup were lost. + my $stale_waiter_name = 'wait_for_lsn_stale_wakeup'; + my $stale_session = $rcv_standby->background_psql('postgres', + connstr => $rcv_standby->connstr('postgres') + . " application_name=$stale_waiter_name"); + + $stale_session->set_query_timer_restart(); + + my $stale_waiter_pid = $rcv_standby->safe_psql( + 'postgres', + "SELECT pid FROM pg_stat_activity + WHERE application_name = '$stale_waiter_name'"); + die "could not determine stale waiter PID: '$stale_waiter_pid'" + unless $stale_waiter_pid =~ /^[0-9]+$/; + + $stale_session->query_until( + qr/started/, qq[ + \\echo started + WAIT FOR LSN '$stale_target' WITH (MODE 'standby_write'); + \\echo completed + ]); + + $rcv_standby->poll_query_until( + 'postgres', qq[ + SELECT test_wait_lsn_waiter_is_registered( + $stale_waiter_pid, 'standby_write', '$stale_target') + ] + ) or die "standby_write waiter did not register"; + + # The write position is below the target because the receiver was stopped + # before the target was generated. Verify that replay is below it too. + $rcv_standby->safe_psql( + 'postgres', qq[ + SELECT pg_wal_lsn_diff( + '$stale_target'::pg_lsn, pg_last_wal_replay_lsn()) > 0 + ]) eq 't' + or die "standby replay reached the target before the stale wakeup"; + + # Simulate the state left by a wakeup that became stale before the waiter + # could recheck its target. The helper removes the waiter from the heap + # and wakes it without changing the actual write or replay positions. To + # the waiter, this is indistinguishable from the position reaching the + # target and then decreasing before the recheck. + $rcv_standby->safe_psql('postgres', + "SELECT test_wait_lsn_wakeup('standby_write', '$stale_target')"); + + # The position is still below the target, so the waiter must restore its + # heap registration before sleeping again. + ok( $rcv_standby->poll_query_until( + 'postgres', qq[ + SELECT test_wait_lsn_waiter_is_registered( + $stale_waiter_pid, 'standby_write', '$stale_target') + ]), + "standby_write waiter re-registers after a stale wakeup" + ) or die "standby_write waiter did not re-register"; + + # Reach the target for real; WAL progress should wake the re-registered waiter. + resume_walreceiver($rcv_standby); + + like( + $stale_session->query_until(qr/completed/, ''), + qr/^success\r?\ncompleted/m, + "standby_write waiter completes once the target is reached"); + $stale_session->quit; +} + $rcv_standby->stop; $rcv_primary->stop; From f8408134dd47f9a99c6452b91da7271084a9e6a4 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 18 Aug 2026 14:08:14 +0200 Subject: [PATCH 393/481] Message style fixes --- src/backend/access/transam/slru.c | 4 ++-- src/backend/libpq/be-secure-openssl.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c index 47dd52d6749..885fd068535 100644 --- a/src/backend/access/transam/slru.c +++ b/src/backend/access/transam/slru.c @@ -1135,12 +1135,12 @@ SlruReportIOError(SlruDesc *ctl, int64 pageno, const void *opaque_data) if (errno) ereport(ERROR, (errcode_for_file_access(), - errmsg("Could not write to file \"%s\" at offset %d: %m", + errmsg("could not write to file \"%s\" at offset %d: %m", path, offset), opaque_data ? ctl->options.errdetail_for_io_error(opaque_data) : 0)); else ereport(ERROR, - (errmsg("Could not write to file \"%s\" at offset %d: wrote too few bytes.", + (errmsg("could not write to file \"%s\" at offset %d: wrote too few bytes", path, offset), opaque_data ? ctl->options.errdetail_for_io_error(opaque_data) : 0)); break; diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 2fb61db00d0..79af222b4a2 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -364,7 +364,7 @@ be_tls_init(bool isServerStart) errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("no SSL configurations loaded"), /*- translator: The two %s contain filenames */ - errhint("If ssl_sni is enabled then add configuration to \"%s\", else \"%s\"", + errhint("If ssl_sni is enabled then add configuration to \"%s\", else \"%s\".", HostsFileName, "postgresql.conf")); goto error; } From 96c34b1a8bb5b083c5f4cf5eee91e5edd63e8edd Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Tue, 18 Aug 2026 09:06:05 -0400 Subject: [PATCH 394/481] test_json_parser: Fix broken file ref and inverted result check A comma following a file ref in a perl print statement makes the statement just print the file's GLOB rather than redirecting the following arguments to the file. This meant the test was not testing any contents and the logs were instead bulked up with what the test was supposed to be testing. Also, run_log() returns 1 for success, not 0, so the tests for the return values were wrong. (We were getting 0 because of the comma error above.) Backpatch-thru: 17 --- src/test/modules/test_json_parser/t/004_test_parser_perf.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/modules/test_json_parser/t/004_test_parser_perf.pl b/src/test/modules/test_json_parser/t/004_test_parser_perf.pl index 1152e8292b8..d5a7afe606b 100644 --- a/src/test/modules/test_json_parser/t/004_test_parser_perf.pl +++ b/src/test/modules/test_json_parser/t/004_test_parser_perf.pl @@ -26,7 +26,7 @@ # repeat the input json file 50 times in an array -print $fh, '[', $contents, ",$contents" x 49, ']'; +print $fh '[', $contents, ",$contents" x 49, ']'; close($fh); @@ -34,10 +34,10 @@ my ($result) = run_log([ $exe, "1", $fname ]); -ok($result == 0, "perf test runs with recursive descent parser"); +ok($result, "perf test runs with recursive descent parser"); $result = run_log([ $exe, "-i", "1", $fname ]); -ok($result == 0, "perf test runs with table driven parser"); +ok($result, "perf test runs with table driven parser"); done_testing(); From ffb7e3af79b307cf93a5a26e0ddc4e96f420befc Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Tue, 18 Aug 2026 10:43:33 -0400 Subject: [PATCH 395/481] doc PG 19: update to current Backpatch-through: 19 only --- doc/src/sgml/release-19.sgml | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/release-19.sgml b/doc/src/sgml/release-19.sgml index cb5a220f7c3..a8046ab41f0 100644 --- a/doc/src/sgml/release-19.sgml +++ b/doc/src/sgml/release-19.sgml @@ -6,7 +6,7 @@ Release date: - 2026-??-??, AS OF 2026-07-18 + 2026-??-??, AS OF 2026-08-18 @@ -832,6 +832,22 @@ Previously most backends were woken by NOTIF + + + + +Change wal_compression equals on to use the best WAL compression method available (wenhui qiu) +§ + + + +Previously this always used pglz. + + + Allow the retrieval of statistics from foreign data wrapper servers (Corey Huinker, Etsuro Fujita) § +§ -This is enabled for by using the option restore_stats. The default is for ANALYZE to retrieve rows from the remote server to locally generate statistics. +This is enabled for by using the option import_stats. The default is for ANALYZE to retrieve rows from the remote server to locally generate statistics. From e4f16fda6e1479b4fdfa6dc31dd41f48c86426fe Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Tue, 18 Aug 2026 11:56:52 -0700 Subject: [PATCH 396/481] Fix stream abort for a transaction that was never streamed. Commit 072ee847ad4 taught logical decoding to discard the changes of a transaction that is already known to be aborted when it is picked for eviction. That path reuses ReorderBufferTruncateTXN(), which marks every subtransaction that still has in-memory changes as streamed. Since nothing is streamed in that path, and the top-level transaction is never marked, a subtransaction ends up flagged as streamed even though the output plugin has never seen it. Decoding the subsequent abort record then makes ReorderBufferAbort() invoke the stream_abort callback for that subtransaction. For pgoutput this sends a Stream Abort ('A') message to a subscriber that requested streaming = off, and it does so regardless of the negotiated protocol version, so even a client speaking a version that predates transaction streaming receives a message it cannot parse. test_decoding dereferences a NULL pointer and crashes, since it allocates its per-transaction state in the begin or stream start callback, neither of which runs for a transaction discarded as aborted. This commit fixes this by marking a subtransaction as streamed only when it has changes and its top-level transaction is already marked as streamed. All streaming call sites mark the top-level transaction before truncating it, so their behavior is unchanged, while the abort-discard path never marks the top-level transaction and therefore now leaves its subtransactions unmarked. Backpatch to v18, where commit 072ee847ad4 was introduced. Bug: #19616 Reported-by: Tyler Smart Author: Andrey Rachitskiy Reviewed-by: Hayato Kuroda Reviewed-by: Fujii Masao Reviewed-by: Masahiko Sawada Discussion: https://postgr.es/m/19616-f6153af509910853@postgresql.org Backpatch-through: 18 --- contrib/test_decoding/expected/stream.out | 23 +++++++++++ contrib/test_decoding/sql/stream.sql | 17 +++++++++ .../replication/logical/reorderbuffer.c | 38 ++++++++++++------- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/contrib/test_decoding/expected/stream.out b/contrib/test_decoding/expected/stream.out index 9879e02ca84..0ec5c933610 100644 --- a/contrib/test_decoding/expected/stream.out +++ b/contrib/test_decoding/expected/stream.out @@ -134,6 +134,29 @@ SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, (1 row) RESET debug_logical_replication_streaming; +-- bug #19616 +-- +-- An aborted top-level transaction that is discarded at eviction must not +-- leave its subtransactions marked as streamed. Otherwise, decoding its +-- abort record invokes the stream abort callback for a subtransaction the +-- output plugin has never seen, even though streaming was never requested. +-- The trailing committed transaction is required to flush the ROLLBACK +-- record; without it decoding would stop before reaching the abort. +BEGIN; +SAVEPOINT s; +INSERT INTO stream_test VALUES ('subxact-change'); +RELEASE SAVEPOINT s; +INSERT INTO stream_test SELECT 'toplevel-change' || g.i FROM generate_series(1, 5000) g(i); +ROLLBACK; +INSERT INTO stream_test VALUES ('after-abort'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +---------------------------------------------------------------------------- + BEGIN + table public.stream_test: INSERT: data[text]:'after-abort' i[integer]:null + COMMIT +(3 rows) + DROP TABLE stream_test; SELECT pg_drop_replication_slot('regression_slot'); pg_drop_replication_slot diff --git a/contrib/test_decoding/sql/stream.sql b/contrib/test_decoding/sql/stream.sql index f1269403e0a..5e45a8e9b64 100644 --- a/contrib/test_decoding/sql/stream.sql +++ b/contrib/test_decoding/sql/stream.sql @@ -65,5 +65,22 @@ COMMIT; SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); RESET debug_logical_replication_streaming; +-- bug #19616 +-- +-- An aborted top-level transaction that is discarded at eviction must not +-- leave its subtransactions marked as streamed. Otherwise, decoding its +-- abort record invokes the stream abort callback for a subtransaction the +-- output plugin has never seen, even though streaming was never requested. +-- The trailing committed transaction is required to flush the ROLLBACK +-- record; without it decoding would stop before reaching the abort. +BEGIN; +SAVEPOINT s; +INSERT INTO stream_test VALUES ('subxact-change'); +RELEASE SAVEPOINT s; +INSERT INTO stream_test SELECT 'toplevel-change' || g.i FROM generate_series(1, 5000) g(i); +ROLLBACK; +INSERT INTO stream_test VALUES ('after-abort'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + DROP TABLE stream_test; SELECT pg_drop_replication_slot('regression_slot'); diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 08be0dacc4a..077b80afd6f 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -2132,26 +2132,36 @@ ReorderBufferSaveTXNSnapshot(ReorderBuffer *rb, ReorderBufferTXN *txn, } /* - * Mark the given transaction as streamed if it's a top-level transaction - * or has changes. + * Mark the given transaction as streamed, if appropriate. + * + * A top-level transaction is always marked. A subtransaction is marked + * only when it has changes and its top-level transaction is already + * marked as streamed. */ static void ReorderBufferMaybeMarkTXNStreamed(ReorderBuffer *rb, ReorderBufferTXN *txn) { /* - * The top-level transaction, is marked as streamed always, even if it - * does not contain any changes (that is, when all the changes are in - * subtransactions). - * - * For subtransactions, we only mark them as streamed when there are - * changes in them. - * - * We do it this way because of aborts - we don't want to send aborts for - * XIDs the downstream is not aware of. And of course, it always knows - * about the top-level xact (we send the XID in all messages), but we - * never stream XIDs of empty subxacts. + * The top-level transaction is marked as streamed always, even if it does + * not contain any changes (that is, when all the changes are in + * subtransactions). The downstream always knows about it, since we send + * its XID in every message. + */ + if (rbtxn_is_toptxn(txn)) + { + /* We only reach here when streaming is supported. */ + Assert(ReorderBufferCanStream(rb)); + txn->txn_flags |= RBTXN_IS_STREAMED; + return; + } + + /* + * A subtransaction is marked only when it has changes, and only when its + * top-level transaction has already been marked as streamed. We never + * stream XIDs of empty subxacts, and we must not send an abort for an XID + * the downstream has never heard of. */ - if (rbtxn_is_toptxn(txn) || (txn->nentries_mem != 0)) + if (txn->nentries_mem != 0 && rbtxn_is_streamed(rbtxn_get_toptxn(txn))) txn->txn_flags |= RBTXN_IS_STREAMED; } From fe91799d3bc6511247a58643b095b5f9a1ccd660 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Tue, 18 Aug 2026 13:16:28 -0700 Subject: [PATCH 397/481] pg_locale.c: comment improvements. Add missing comments and fix outdated/incorrect comments in pg_locale.c and related files. Suggested-by: Andres Freund Discussion: https://postgr.es/m/v3nniwcrxejmcfvz56xbd22hphprqleuornd6hqkmw2bl7kgmz@cnytz2ee5ltk Backpatch-through: 18 --- src/backend/utils/adt/pg_locale.c | 106 ++++++++++++++++++---- src/backend/utils/adt/pg_locale_builtin.c | 4 +- src/backend/utils/adt/pg_locale_icu.c | 19 ++-- src/include/utils/pg_locale.h | 13 ++- 4 files changed, 106 insertions(+), 36 deletions(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 11d48a3916e..cf77db77682 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1317,6 +1317,20 @@ strupper_c(char *dst, size_t dstsize, const char *src, size_t srclen) return srclen; } +/* + * pg_strlower() + * + * Convert src to lowercase, and return the result length (not including + * terminating NUL). + * + * src must be in the database encoding with no embedded NULs. If dstsize is + * zero, dst may be NULL, which is useful for calculating the required buffer + * size before allocating. + * + * If the result length is less than dstsize, the NUL-terminated result is + * stored in dst. Otherwise, the contents of dst are undefined, and the + * caller should use the return value to resize the buffer and retry. + */ size_t pg_strlower(char *dst, size_t dstsize, const char *src, size_t srclen, pg_locale_t locale) @@ -1327,6 +1341,20 @@ pg_strlower(char *dst, size_t dstsize, const char *src, size_t srclen, return locale->ctype->strlower(dst, dstsize, src, srclen, locale); } +/* + * pg_strtitle() + * + * Convert src to titlecase, and return the result length (not including + * terminating NUL). + * + * src must be in the database encoding with no embedded NULs. If dstsize is + * zero, dst may be NULL, which is useful for calculating the required buffer + * size before allocating. + * + * If the result length is less than dstsize, the NUL-terminated result is + * stored in dst. Otherwise, the contents of dst are undefined, and the + * caller should use the return value to resize the buffer and retry. + */ size_t pg_strtitle(char *dst, size_t dstsize, const char *src, size_t srclen, pg_locale_t locale) @@ -1337,6 +1365,20 @@ pg_strtitle(char *dst, size_t dstsize, const char *src, size_t srclen, return locale->ctype->strtitle(dst, dstsize, src, srclen, locale); } +/* + * pg_strupper() + * + * Convert src to uppercase, and return the result length (not including + * terminating NUL). + * + * src must be in the database encoding with no embedded NULs. If dstsize is + * zero, dst may be NULL, which is useful for calculating the required buffer + * size before allocating. + * + * If the result length is less than dstsize, the NUL-terminated result is + * stored in dst. Otherwise, the contents of dst are undefined, and the + * caller should use the return value to resize the buffer and retry. + */ size_t pg_strupper(char *dst, size_t dstsize, const char *src, size_t srclen, pg_locale_t locale) @@ -1347,6 +1389,19 @@ pg_strupper(char *dst, size_t dstsize, const char *src, size_t srclen, return locale->ctype->strupper(dst, dstsize, src, srclen, locale); } +/* + * pg_strfold() + * + * Casefold src, and return the result length (not including terminating NUL). + * + * src must be in the database encoding with no embedded NULs. If dstsize is + * zero, dst may be NULL, which is useful for calculating the required buffer + * size before allocating. + * + * If the result length is less than dstsize, the NUL-terminated result is + * stored in dst. Otherwise, the contents of dst are undefined, and the + * caller should use the return value to resize the buffer and retry. + */ size_t pg_strfold(char *dst, size_t dstsize, const char *src, size_t srclen, pg_locale_t locale) @@ -1359,11 +1414,15 @@ pg_strfold(char *dst, size_t dstsize, const char *src, size_t srclen, } /* - * Lowercase an identifier using the database default locale. + * pg_downcase_ident() + * + * Lowercase an identifier using historical identifier-folding semantics, and + * return the result length (not including terminating NUL). If the result + * length is less than dstsize, the NUL-terminated result is stored in dst; + * otherwise the contents of dst are undefined. * - * For historical reasons, does not use ordinary locale behavior. Should only - * be used for identifiers. XXX: can we make this equivalent to - * pg_strfold(..., default_locale)? + * XXX: callers currently depend on the result length being equal to srclen, + * but that may change in the future if we change to proper case folding. */ size_t pg_downcase_ident(char *dst, size_t dstsize, const char *src, size_t srclen) @@ -1392,11 +1451,9 @@ pg_strcoll(const char *arg1, const char *arg2, pg_locale_t locale) /* * pg_strncoll * - * Call ucol_strcollUTF8(), ucol_strcoll(), strcoll_l() or wcscoll_l() as - * appropriate for the given locale, platform, and database encoding. If the - * locale is not specified, use the database collation. + * Compare strings according to the given locale. * - * The input strings must be encoded in the database encoding. + * Strings must be encoded in the database encoding with no embedded NULs. * * The caller is responsible for breaking ties if the collation is * deterministic; this maintains consistency with pg_strnxfrm(), which cannot @@ -1410,11 +1467,8 @@ pg_strncoll(const char *arg1, size_t len1, const char *arg2, size_t len2, } /* - * Return true if the collation provider supports pg_strxfrm() and - * pg_strnxfrm(); otherwise false. - * - * - * No similar problem is known for the ICU provider. + * Return true if the locale supports pg_strxfrm() and pg_strnxfrm(); + * otherwise false. */ bool pg_strxfrm_enabled(pg_locale_t locale) @@ -1445,8 +1499,8 @@ pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale) * ordinary strcmp() on transformed strings is equivalent to pg_strcoll() on * untransformed strings. * - * The input string must be encoded in the database encoding. If 'destsize' is - * zero, 'dest' may be NULL. + * String must be encoded in the database encoding with no embedded NULs. If + * 'destsize' is zero, 'dest' may be NULL. * * Not all providers support pg_strnxfrm() safely. The caller should check * pg_strxfrm_enabled() first, otherwise this function may return wrong @@ -1464,7 +1518,7 @@ pg_strnxfrm(char *dest, size_t destsize, const char *src, size_t srclen, } /* - * Return true if the collation provider supports pg_strxfrm_prefix() and + * Return true if the locale supports pg_strxfrm_prefix() and * pg_strnxfrm_prefix(); otherwise false. */ bool @@ -1492,11 +1546,11 @@ pg_strxfrm_prefix(char *dest, const char *src, size_t destsize, * memcmp() on the byte sequence is equivalent to pg_strncoll() on * untransformed strings. The result is not nul-terminated. * - * The input string must be encoded in the database encoding. + * String must be encoded in the database encoding with no embedded NULs. If + * destsize is zero, dest may be NULL. * - * Not all providers support pg_strnxfrm_prefix() safely. The caller should - * check pg_strxfrm_prefix_enabled() first, otherwise this function may return - * wrong results or an error. + * Not all providers support pg_strnxfrm_prefix() safely. The caller must + * check pg_strxfrm_prefix_enabled() first. * * If destsize is not large enough to hold the resulting byte sequence, stores * only the first destsize bytes in 'dest'. Returns the number of bytes @@ -1509,6 +1563,18 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src, return locale->collate->strnxfrm_prefix(dest, destsize, src, srclen, locale); } +/* + * pg_iswdigit(), pg_iswalpha(), etc. + * + * Character semantics for pattern-matching. Uses pg_wchar, which is an + * encoding-dependent value, which may or may not be equivalent to a code + * point. + * + * For case-mapping an entire string, use pg_strlower(), etc., instead. + * String based functions can handle one-to-many and context-sensitive + * mappings. + */ + bool pg_iswdigit(pg_wchar wc, pg_locale_t locale) { diff --git a/src/backend/utils/adt/pg_locale_builtin.c b/src/backend/utils/adt/pg_locale_builtin.c index 7c36fd5091b..8fa0b637b06 100644 --- a/src/backend/utils/adt/pg_locale_builtin.c +++ b/src/backend/utils/adt/pg_locale_builtin.c @@ -288,8 +288,8 @@ char * get_collation_actual_version_builtin(const char *collcollate) { /* - * The only two supported locales (C and C.UTF-8) are both based on memcmp - * and are not expected to change, but track the version anyway. + * The supported locales (C, C.UTF-8, and PG_UNICODE_FAST) are all based + * on memcmp and are not expected to change, but track the version anyway. * * Note that the character semantics may change for some locales, but the * collation version only tracks changes to sort order. diff --git a/src/backend/utils/adt/pg_locale_icu.c b/src/backend/utils/adt/pg_locale_icu.c index cb92ac6ee59..5ba37a54f9c 100644 --- a/src/backend/utils/adt/pg_locale_icu.c +++ b/src/backend/utils/adt/pg_locale_icu.c @@ -705,8 +705,8 @@ strfold_icu_utf8(char *dest, size_t destsize, const char *src, size_t srclen, /* * For historical compatibility, behavior is not multibyte-aware. * - * NB: uses libc tolower() for single-byte encodings (also for historical - * compatibility), and therefore relies on the global LC_CTYPE setting. + * NB: uses libc tolower_l() for single-byte encodings (also for historical + * compatibility), and therefore relies on the LC_CTYPE setting. */ static size_t downcase_ident_icu(char *dst, size_t dstsize, const char *src, @@ -736,10 +736,9 @@ downcase_ident_icu(char *dst, size_t dstsize, const char *src, } /* - * strncoll_icu_utf8 + * strncoll_icu_utf8() * - * Call ucol_strcollUTF8() or ucol_strcoll() as appropriate for the given - * database encoding. + * Wrapper for ucol_strcollUTF8(). */ #ifdef HAVE_UCOL_STRCOLLUTF8 int @@ -927,13 +926,11 @@ icu_to_uchar(UChar **buff_uchar, const char *buff, size_t nbytes) /* * Convert a string of UChars into the database encoding. * - * The source string at buff_uchar is of length len_uchar - * (it needn't be nul-terminated) - * - * *result receives a pointer to the palloc'd result string, and the - * function's result is the number of bytes generated (not counting nul). + * The source string at buff_uchar is of length len_uchar (it needn't be + * nul-terminated) * - * The result string is nul-terminated. + * If the result length is less than destsize, the NUL-terminated result is + * stored in dest. Otherwise the contents of dest are undefined. */ static size_t icu_from_uchar(char *dest, size_t destsize, const UChar *buff_uchar, int32_t len_uchar) diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h index b74821fdfa9..fcd508f5dd6 100644 --- a/src/include/utils/pg_locale.h +++ b/src/include/utils/pg_locale.h @@ -59,7 +59,9 @@ extern void cache_locale_time(void); struct pg_locale_struct; typedef struct pg_locale_struct *pg_locale_t; -/* methods that define collation behavior */ +/* + * Collation behavior: string ordering. + */ struct collate_methods { /* required */ @@ -88,16 +90,19 @@ struct collate_methods /* * If the strnxfrm method is not trusted to return the correct results, - * set strxfrm_is_safe to false. It set to false, the method will not be + * set strxfrm_is_safe to false. If set to false, the method will not be * used in most cases, but the planner still expects it to be there for * estimation purposes (where incorrect results are acceptable). */ bool strxfrm_is_safe; }; +/* + * Character behavior: casing semantics and pattern matching. + */ struct ctype_methods { - /* case mapping: LOWER()/INITCAP()/UPPER() */ + /* required */ size_t (*strlower) (char *dest, size_t destsize, const char *src, size_t srclen, pg_locale_t locale); @@ -110,6 +115,8 @@ struct ctype_methods size_t (*strfold) (char *dest, size_t destsize, const char *src, size_t srclen, pg_locale_t locale); + + /* optional */ size_t (*downcase_ident) (char *dest, size_t destsize, const char *src, size_t srclen, pg_locale_t locale); From aaf8b9989f7aaeb6594122caee1eea6c87e10655 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Tue, 18 Aug 2026 22:25:42 +0200 Subject: [PATCH 398/481] Record initial state of data checksums in controlfile The controlfile records the current state of data checksums, which also used to be the initial state from initdb when checksums could not be altered after initialization. pg_control_init is documented to return information about cluster initialization state, which it no longer will if data checksums have been changed either using the offline tool or with online processing. Fix by adding a new field in the control file which tracks the init value of data checksums, and is left read only after initialization. While this is a regression dating back to when changing checksum state was made possible offline with pg_checksums, it is a control file change so it cannot be backpatched. Backpatch to v19 where online checksums were introduced. Author: Daniel Gustafsson Reviewed-by: Bertrand Drouvot Discussion: https://postgr.es/m/B87ABFBE-A304-4839-8706-C80D73E6BF5C@yesql.se Backpatch-through: 19 --- src/backend/access/transam/xlog.c | 1 + src/backend/utils/misc/pg_controldata.c | 2 +- src/include/catalog/pg_control.h | 10 ++++++-- .../modules/test_checksums/t/001_basic.pl | 23 +++++++++++++------ .../modules/test_checksums/t/002_restarts.pl | 12 +++++++++- .../modules/test_checksums/t/004_offline.pl | 14 +++++++++-- 6 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 254bb158565..0161d045fba 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -4284,6 +4284,7 @@ InitControlFile(uint64 sysidentifier, uint32 data_checksum_version) ControlFile->wal_log_hints = wal_log_hints; ControlFile->track_commit_timestamp = track_commit_timestamp; ControlFile->data_checksum_version = data_checksum_version; + ControlFile->data_checksum_version_init = data_checksum_version; /* * Set the data_checksum_version value into XLogCtl, which is where all diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c index d229ae35209..d4feec95b26 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -254,7 +254,7 @@ pg_control_init(PG_FUNCTION_ARGS) values[9] = BoolGetDatum(ControlFile->float8ByVal); nulls[9] = false; - values[10] = Int32GetDatum(ControlFile->data_checksum_version); + values[10] = Int32GetDatum(ControlFile->data_checksum_version_init); nulls[10] = false; values[11] = BoolGetDatum(ControlFile->default_char_signedness); diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 80b3a730e03..7b5404460ec 100644 --- a/src/include/catalog/pg_control.h +++ b/src/include/catalog/pg_control.h @@ -22,7 +22,7 @@ /* Version identifier for this pg_control format */ -#define PG_CONTROL_VERSION 1902 +#define PG_CONTROL_VERSION 1903 /* Nonce key length, see below */ #define MOCK_AUTH_NONCE_LEN 32 @@ -228,7 +228,13 @@ typedef struct ControlFileData bool float8ByVal; /* float8, int8, etc pass-by-value? */ - /* Are data pages protected by checksums? Zero if no checksum version */ + /* + * Data checksum state at cluster initialization. Since the state can be + * changed during runtime, we need to store the initial value for system + * functions which report initdb settings. + */ + uint32 data_checksum_version_init; + /* Current data checksums state */ uint32 data_checksum_version; /* diff --git a/src/test/modules/test_checksums/t/001_basic.pl b/src/test/modules/test_checksums/t/001_basic.pl index 72e0d0df46f..7477f00947d 100644 --- a/src/test/modules/test_checksums/t/001_basic.pl +++ b/src/test/modules/test_checksums/t/001_basic.pl @@ -14,24 +14,33 @@ use DataChecksums::Utils; -# Initialize node with checksums disabled. +# Initialize node with checksums enabled to test pg_control_init returning +# 1 for this cluster, the remaining tests will initialize to off to test the +# return value for a cluster initialized without checksums my $node = PostgreSQL::Test::Cluster->new('basic_node'); -$node->init(no_data_checksums => 1); +$node->init; $node->start; -# Create some content to have un-checksummed data in the cluster +# Create some content to have data in the cluster $node->safe_psql('postgres', "CREATE TABLE t AS SELECT generate_series(1,10000) AS a;"); -# Ensure that checksums are turned off -test_checksum_state($node, 'off'); +# Ensure that checksums are turned on +test_checksum_state($node, 'on'); + +# Disable data checksums and wait for the state transition to 'off' +disable_data_checksums($node, wait => 'off'); + +# Make sure pg_control_init reports the initial enabled state +my $result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_init();'); +is($result, '1', 'ensure pg_control_init reports enabled state'); # Enable data checksums and wait for the state transition to 'on' enable_data_checksums($node, wait => 'on'); # Run a dummy query just to make sure we can read back data -my $result = - $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1 "); +$result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1 "); is($result, '9999', 'ensure checksummed pages can be read back'); # Enable data checksums again which should be a no-op so we explicitly don't diff --git a/src/test/modules/test_checksums/t/002_restarts.pl b/src/test/modules/test_checksums/t/002_restarts.pl index d98c8024f29..bef0bb90993 100644 --- a/src/test/modules/test_checksums/t/002_restarts.pl +++ b/src/test/modules/test_checksums/t/002_restarts.pl @@ -30,6 +30,11 @@ # Ensure that checksums are disabled test_checksum_state($node, 'off'); +# Make sure pg_control_init reports the initial disabled state +$result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_init();'); +is($result, '0', 'ensure pg_control_init reports disabled state'); + SKIP: { skip 'Data checksum delay tests not enabled in PG_TEST_EXTRA', 6 @@ -134,9 +139,14 @@ $block_session->quit; # Finish test suite by enabling checksums and make sure all data can be read -# back and no processes are left over +# back, no processes are left over and the initial state is still correctly +# reported enable_data_checksums($node, wait => 'on'); +$result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_init();'); +is($result, '0', 'ensure pg_control_init still reports disabled state'); + $result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1"); is($result, '9999', 'ensure checksummed pages can be read back'); diff --git a/src/test/modules/test_checksums/t/004_offline.pl b/src/test/modules/test_checksums/t/004_offline.pl index 73c279e75e0..48254111410 100644 --- a/src/test/modules/test_checksums/t/004_offline.pl +++ b/src/test/modules/test_checksums/t/004_offline.pl @@ -20,6 +20,11 @@ $node->init(no_data_checksums => 1); $node->start; +# Make sure pg_control_init reports the initial state as disabled +my $result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_init();'); +is($result, '0', 'ensure pg_control_init reports disabled state'); + # Create some content to have un-checksummed data in the cluster $node->safe_psql('postgres', "CREATE TABLE t AS SELECT generate_series(1,10000) AS a;"); @@ -35,9 +40,14 @@ # Ensure that checksums are enabled test_checksum_state($node, 'on'); +# Make sure pg_control_init still reports the initial state as disabled even +# though the current state has changed. +$result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_init();'); +is($result, '0', 'ensure pg_control_init still reports disabled state'); + # Run a dummy query just to make sure we can read back some data -my $result = - $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1"); +$result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1"); is($result, '9999', 'ensure checksummed pages can be read back'); # Disable checksums offline again using pg_checksums From 397f0fd06edc3a5b114449164c5d39c59a468b61 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Tue, 18 Aug 2026 22:25:49 +0200 Subject: [PATCH 399/481] Add data_page_checksum_version to pg_control_checkpoint Commit f19c0eccae added the data_checksum_version to the pg_controldata output, but omitted a corresponding change to the pg_control_checkpoint SQL function, which reports the same checkpoint information. The field is named to match what pg_control_init already reports for consistency. The integer version reported is an implementation detail which bleeds through, but it is quite widely used and a more holistic approach to improving this is left as an excercise for the next major version. The mapping between states and versions is added to the documentation to make it easier for users. Backpatch to v19 where online checksums were introduced. Author: Ian Barwick Co-authored-by: Daniel Gustafsson Reviewed-by: Fujii Masao Reviewed-by: Chao Li Reviewed-by: Bertrand Drouvot Discussion: https://postgr.es/m/CAB8KJ=hb765sE8bKC-6sh=Yp3sCjN8xs474yuBrkwyoTM2pgZA@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/func/func-info.sgml | 5 +++ doc/src/sgml/wal.sgml | 45 ++++++++++++++++++- src/backend/utils/misc/pg_controldata.c | 9 ++-- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 6 +-- .../modules/test_checksums/t/001_basic.pl | 18 ++++++++ .../modules/test_checksums/t/004_offline.pl | 12 +++++ 7 files changed, 89 insertions(+), 8 deletions(-) diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml index 122fc740f1a..e3c05e8b933 100644 --- a/doc/src/sgml/func/func-info.sgml +++ b/doc/src/sgml/func/func-info.sgml @@ -3496,6 +3496,11 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} xid + + data_page_checksum_version + integer + + checkpoint_time timestamp with time zone diff --git a/doc/src/sgml/wal.sgml b/doc/src/sgml/wal.sgml index 646076f7e39..ec62d17fbcc 100644 --- a/doc/src/sgml/wal.sgml +++ b/doc/src/sgml/wal.sgml @@ -256,9 +256,52 @@ The current state of checksums in the cluster can be verified by viewing the value of the read-only configuration variable by issuing the command SHOW - data_checksums. + data_checksums. + pg_control_init and + + pg_control_checkpoint can also be used for + inspecting the data checksum state at cluster initialization and current + checkpoint. Data checksum states are often referred to as data checksum + versions using an integer representation due to how they were originally + implemented. contains a mapping + between state names and versions, which are defined in + src/include/storage/checksum.h. +
    + Data Checksums States and Version Mapping + + + + State + Version + + + + + + off + 0 + + + + on + 1 + + + + inprogress-off + 2 + + + + inprogress-on + 3 + + + +
    + When attempting to recover from page corruptions, it may be necessary to bypass the checksum protection. To do this, temporarily set the diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c index d4feec95b26..ab74d169c96 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -69,8 +69,8 @@ pg_control_system(PG_FUNCTION_ARGS) Datum pg_control_checkpoint(PG_FUNCTION_ARGS) { - Datum values[19]; - bool nulls[19]; + Datum values[20]; + bool nulls[20]; TupleDesc tupdesc; HeapTuple htup; ControlFileData *ControlFile; @@ -154,9 +154,12 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) values[17] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid); nulls[17] = false; - values[18] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time)); + values[18] = Int32GetDatum(ControlFile->checkPointCopy.dataChecksumState); nulls[18] = false; + values[19] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time)); + nulls[19] = false; + htup = heap_form_tuple(tupdesc, values, nulls); PG_RETURN_DATUM(HeapTupleGetDatum(htup)); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 80c2070f358..8b5dd160cdf 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202607272 +#define CATALOG_VERSION_NO 202608182 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index aa5ac43aff0..f5867349d14 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -12346,9 +12346,9 @@ descr => 'pg_controldata checkpoint state information as a function', proname => 'pg_control_checkpoint', provolatile => 'v', prorettype => 'record', proargtypes => '', - proallargtypes => '{pg_lsn,pg_lsn,text,int4,int4,bool,bool,text,oid,xid,xid,xid,oid,xid,xid,oid,xid,xid,timestamptz}', - proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', - proargnames => '{checkpoint_lsn,redo_lsn,redo_wal_file,timeline_id,prev_timeline_id,full_page_writes,logical_decoding,next_xid,next_oid,next_multixact_id,next_multi_offset,oldest_xid,oldest_xid_dbid,oldest_active_xid,oldest_multi_xid,oldest_multi_dbid,oldest_commit_ts_xid,newest_commit_ts_xid,checkpoint_time}', + proallargtypes => '{pg_lsn,pg_lsn,text,int4,int4,bool,bool,text,oid,xid,xid,xid,oid,xid,xid,oid,xid,xid,int4,timestamptz}', + proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', + proargnames => '{checkpoint_lsn,redo_lsn,redo_wal_file,timeline_id,prev_timeline_id,full_page_writes,logical_decoding,next_xid,next_oid,next_multixact_id,next_multi_offset,oldest_xid,oldest_xid_dbid,oldest_active_xid,oldest_multi_xid,oldest_multi_dbid,oldest_commit_ts_xid,newest_commit_ts_xid,data_page_checksum_version,checkpoint_time}', prosrc => 'pg_control_checkpoint' }, { oid => '3443', diff --git a/src/test/modules/test_checksums/t/001_basic.pl b/src/test/modules/test_checksums/t/001_basic.pl index 7477f00947d..5a16b6fb9e4 100644 --- a/src/test/modules/test_checksums/t/001_basic.pl +++ b/src/test/modules/test_checksums/t/001_basic.pl @@ -43,6 +43,18 @@ $result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1 "); is($result, '9999', 'ensure checksummed pages can be read back'); +# Ensure the new state is registered properly in pg_control_checkpoint() +$result = + $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_checkpoint();'); +is($result, '1', 'ensure pg_control_checkpoint reports enabled state'); +# Regardless of the new state, pg_control_init() should still report checksums +# as on. +$result = + $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_init();'); +is($result, '1', 'ensure pg_control_init reports enabled state'); + # Enable data checksums again which should be a no-op so we explicitly don't # wait for any state transition as none should happen here. enable_data_checksums($node); @@ -59,6 +71,12 @@ $result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1"); is($result, '10000', 'ensure previously checksummed pages can be read back'); +# And ensure the disabled state is shown in pg_control_checkpoint() +$result = + $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_checkpoint();'); +is($result, '0', 'ensure pg_control_checkpoint reports disabled state'); + # Re-enable checksums and make sure that the underlying data has changed to # ensure that checksums will be different. $node->safe_psql('postgres', "UPDATE t SET a = a + 1;"); diff --git a/src/test/modules/test_checksums/t/004_offline.pl b/src/test/modules/test_checksums/t/004_offline.pl index 48254111410..d0eee3afe46 100644 --- a/src/test/modules/test_checksums/t/004_offline.pl +++ b/src/test/modules/test_checksums/t/004_offline.pl @@ -40,6 +40,18 @@ # Ensure that checksums are enabled test_checksum_state($node, 'on'); +# Since offline checksums don't issue a checkpoint like online checksums, the +# first call to pg_control_checkpoint will show the state as off even though +# checksums are enabled. After a CHECKPOINT, pg_control_checkpoint shall +# return 1. +$result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_checkpoint();'); +is($result, '0', 'latest checkpoint will still see off state'); +$node->safe_psql('postgres', 'CHECKPOINT;'); +$result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_checkpoint();'); +is($result, '1', 'latest checkpoint will now see on state'); + # Make sure pg_control_init still reports the initial state as disabled even # though the current state has changed. $result = $node->safe_psql('postgres', From 0907112d3882192f3c14d5ce0735790341e073ed Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Tue, 18 Aug 2026 22:25:52 +0200 Subject: [PATCH 400/481] basebackup: do not verify checksums on pages from before enabling Enabling data checksums in a running cluster changes the state to "on" before the checkpoint which flushes the pages the worker rewrote. A base backup which started before that transition absorbs the barrier mid-run and starts verifying pages whose on-disk copies legitimately lack checksums, and whose LSNs predate the backup start, so the LSN check does not skip them either. The backup fails with bogus corruption warnings. The same applies to checksums being disabled and re-enabled while the backup runs: hint bits set while checksums were off reach disk without a checksum update and without moving the page LSN, tripping verification once the re-enabling completes. To fix, verify checksums only while they have been continuously enabled since the checkpoint the backup started from: track the location of the last XLOG2_CHECKSUMS record inserted or replayed, and verify only when the state is "on" and the last change predates the backup start. The starting checkpoint then guarantees that every page flushed before it has a checksum written, and any later change disables verification for the rest of the backup. A standby loses the tracked location when restarting, while pg_control already carries the new state, so it could reach consistency below the record and serve base backups with the location unknown. To prevent this, replaying XLOG2_CHECKSUMS advances minRecoveryPoint to the record, like XLOG_PARAMETER_CHANGE does. The tests hold the enabling between the state change and its final checkpoint with injection points, straddling it with backups on the primary and across a standby crash-restart. Author: Zsolt Parragi Reviewed-by: Bertrand Drouvot Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CAN4CZFP=-cVVVPue+e8qqPtDfuLuQn=ZB4Mw_C9-Ncru2wqAsQ@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/ref/pg_basebackup.sgml | 6 + src/backend/access/transam/xlog.c | 58 ++++ src/backend/backup/basebackup.c | 73 ++++- src/include/access/xlog.h | 1 + src/test/modules/test_checksums/meson.build | 2 + .../test_checksums/t/010_backup_straddle.pl | 260 ++++++++++++++++++ .../test_checksums/t/011_standby_straddle.pl | 249 +++++++++++++++++ 7 files changed, 640 insertions(+), 9 deletions(-) create mode 100644 src/test/modules/test_checksums/t/010_backup_straddle.pl create mode 100644 src/test/modules/test_checksums/t/011_standby_straddle.pl diff --git a/doc/src/sgml/ref/pg_basebackup.sgml b/doc/src/sgml/ref/pg_basebackup.sgml index fecee08b0a5..3117968d125 100644 --- a/doc/src/sgml/ref/pg_basebackup.sgml +++ b/doc/src/sgml/ref/pg_basebackup.sgml @@ -788,6 +788,12 @@ PostgreSQL documentation in the pg_stat_database view. + + Checksums must be enabled on the server for the duration of the base + backup in order to be verified. If checksums are in the process of + being enabled when the base backup starts then checksum verification is + disabled for the base backup. +
    diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 0161d045fba..7f5d3b1417a 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -560,6 +560,14 @@ typedef struct XLogCtlData uint32 data_checksum_version; slock_t info_lck; /* locks shared variables shown above */ + + /* + * lastChecksumChangeRecPtr points to the end of the last XLOG2_CHECKSUMS + * record inserted or replayed, i.e. the last change of + * data_checksum_version. InvalidXLogRecPtr if the state hasn't changed + * since the server started. + */ + pg_atomic_uint64 lastChecksumChangeRecPtr; } XLogCtlData; /* @@ -4736,6 +4744,23 @@ DataChecksumsNeedVerify(void) return (LocalDataChecksumState == PG_DATA_CHECKSUM_VERSION); } +/* + * GetLastChecksumChangeRecPtr + * Returns the location of the last data checksum state change + * + * Offline state changes by pg_checksums leave no trace here; callers must + * also inspect the current state. + * + * No barrier semantics are needed: pages reach disk under a new checksum + * state only after their writer absorbed the procsignal barrier for the + * change, which is emitted after the new location became visible. + */ +XLogRecPtr +GetLastChecksumChangeRecPtr(void) +{ + return pg_atomic_read_u64(&XLogCtl->lastChecksumChangeRecPtr); +} + /* * SetDataChecksumsOnInProgress * Sets the data checksum state to "inprogress-on" to enable checksums @@ -4846,6 +4871,8 @@ SetDataChecksumsOn(void) MyProc->delayChkptFlags &= ~DELAY_CHKPT_START; END_CRIT_SECTION(); + INJECTION_POINT("datachecksums-on-before-checkpoint", NULL); + RequestCheckpoint(CHECKPOINT_FORCE | CHECKPOINT_WAIT | CHECKPOINT_FAST); WaitForProcSignalBarrier(barrier); } @@ -5436,6 +5463,7 @@ XLOGShmemInit(void *arg) pg_atomic_init_u64(&XLogCtl->logWriteResult, InvalidXLogRecPtr); pg_atomic_init_u64(&XLogCtl->logFlushResult, InvalidXLogRecPtr); pg_atomic_init_u64(&XLogCtl->unloggedLSN, InvalidXLogRecPtr); + pg_atomic_init_u64(&XLogCtl->lastChecksumChangeRecPtr, InvalidXLogRecPtr); } /* @@ -8743,6 +8771,7 @@ XLogChecksums(uint32 new_type) XLogRegisterData((char *) &xlrec, sizeof(xl_checksum_state)); recptr = XLogInsert(RM_XLOG2_ID, XLOG2_CHECKSUMS); + pg_atomic_write_u64(&XLogCtl->lastChecksumChangeRecPtr, recptr); XLogFlush(recptr); } @@ -9244,15 +9273,44 @@ xlog2_redo(XLogReaderState *record) if (info == XLOG2_CHECKSUMS) { xl_checksum_state state; + XLogRecPtr lsn = record->EndRecPtr; memcpy(&state, XLogRecGetData(record), sizeof(xl_checksum_state)); + /* advertise the location before the new state becomes visible */ + pg_atomic_write_u64(&XLogCtl->lastChecksumChangeRecPtr, lsn); + SpinLockAcquire(&XLogCtl->info_lck); XLogCtl->data_checksum_version = state.new_checksum_state; SpinLockRelease(&XLogCtl->info_lck); LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); ControlFile->data_checksum_version = state.new_checksum_state; + + /* + * Update minRecoveryPoint to ensure that if recovery is aborted, we + * recover back up to this point before allowing hot standby again. + * The new state is durable in pg_control while its location is only + * tracked in shared memory; a standby becoming consistent below this + * record would let base backups resume checksum verification with the + * location unknown. The local copies cannot be updated as long as + * crash recovery is happening and we expect all the WAL to be + * replayed. + */ + if (InArchiveRecovery) + { + LocalMinRecoveryPoint = ControlFile->minRecoveryPoint; + LocalMinRecoveryPointTLI = ControlFile->minRecoveryPointTLI; + } + if (XLogRecPtrIsValid(LocalMinRecoveryPoint) && LocalMinRecoveryPoint < lsn) + { + TimeLineID replayTLI; + + (void) GetCurrentReplayRecPtr(&replayTLI); + ControlFile->minRecoveryPoint = lsn; + ControlFile->minRecoveryPointTLI = replayTLI; + } + UpdateControlFile(); LWLockRelease(ControlFileLock); diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c index 5214e7b99c7..fe89b812bed 100644 --- a/src/backend/backup/basebackup.c +++ b/src/backend/backup/basebackup.c @@ -45,6 +45,7 @@ #include "storage/reinit.h" #include "utils/builtins.h" #include "utils/guc.h" +#include "utils/injection_point.h" #include "utils/ps_status.h" #include "utils/relcache.h" #include "utils/resowner.h" @@ -107,6 +108,7 @@ static off_t read_file_data_into_buffer(bbsink *sink, int *checksum_failures); static void push_to_sink(bbsink *sink, pg_checksum_context *checksum_ctx, size_t *bytes_done, void *data, size_t length); +static bool backup_checksums_verifiable(XLogRecPtr start_lsn); static bool verify_page_checksum(Page page, XLogRecPtr start_lsn, BlockNumber blkno, uint16 *expected_checksum); @@ -325,6 +327,12 @@ perform_base_backup(basebackup_options *opt, bbsink *sink, /* notify basebackup sink about start of backup */ bbsink_begin_backup(sink, &state, SINK_BUFFER_LENGTH); + /* + * Allow tests to hold the backup after the starting checkpoint but + * before any file data is sent. + */ + INJECTION_POINT("basebackup-before-send-files", NULL); + /* Send off our tablespaces one by one */ foreach(lc, state.tablespaces) { @@ -1609,13 +1617,14 @@ sendFile(bbsink *sink, const char *readfilename, const char *tarfilename, Assert((sink->bbs_buffer_length % BLCKSZ) == 0); /* - * If we weren't told not to verify checksums, and if checksums are - * enabled for this cluster, and if this is a relation file, then verify - * the checksum. We cannot at this point check if checksums are enabled - * or disabled as that might change, thus we check at each point where we + * Verify checksums unless the client requested otherwise, but only for + * relation files, and only while checksums have been continuously enabled + * since the checkpoint this backup started from. Checksums can still be + * disabled while the backup runs, thus we check at each point where we * could be validating a checksum. */ - if (!noverify_checksums && RelFileNumberIsValid(relfilenumber)) + if (!noverify_checksums && RelFileNumberIsValid(relfilenumber) && + backup_checksums_verifiable(sink->bbs_state->startptr)) verify_checksum = true; /* @@ -1748,7 +1757,9 @@ sendFile(bbsink *sink, const char *readfilename, const char *tarfilename, * If the amount of data we were able to read was not a multiple of * BLCKSZ, we cannot verify checksums, which are block-level. */ - if (verify_checksum && DataChecksumsNeedVerify() && (cnt % BLCKSZ != 0)) + if (verify_checksum && + backup_checksums_verifiable(sink->bbs_state->startptr) && + (cnt % BLCKSZ != 0)) { ereport(WARNING, (errmsg("could not verify checksum in file \"%s\", block " @@ -1876,7 +1887,7 @@ read_file_data_into_buffer(bbsink *sink, const char *readfilename, int fd, * The data checksum state can change at any point, so we need to * re-check before each page. */ - if (!DataChecksumsNeedVerify()) + if (!backup_checksums_verifiable(sink->bbs_state->startptr)) return cnt; page = sink->bbs_buffer + BLCKSZ * i; @@ -1905,7 +1916,7 @@ read_file_data_into_buffer(bbsink *sink, const char *readfilename, int fd, * The data checksum state may also have changed concurrently so check * again. */ - if (!DataChecksumsNeedVerify()) + if (!backup_checksums_verifiable(sink->bbs_state->startptr)) return cnt; reread_cnt = basebackup_read_file(fd, sink->bbs_buffer + BLCKSZ * i, @@ -1996,6 +2007,27 @@ push_to_sink(bbsink *sink, pg_checksum_context *checksum_ctx, } } +/* + * Check whether data checksums can be verified for a backup started at + * start_lsn. + * + * Checksums are verified only while they have been continuously enabled + * since the checkpoint the backup started from: the state must be "on" and + * the last state change must predate the backup start. Such a checkpoint + * guarantees that every page flushed before it has a checksum written. Any + * later state change ends verification for the rest of the backup: pages + * written while checksums were off can lack checksums yet keep LSNs older + * than the backup start, and re-enabling completes before the rewritten + * pages are flushed, so observing the "on" state again is not enough to + * resume. + */ +static bool +backup_checksums_verifiable(XLogRecPtr start_lsn) +{ + return DataChecksumsNeedVerify() && + GetLastChecksumChangeRecPtr() <= start_lsn; +} + /* * Try to verify the checksum for the provided page, if it seems appropriate * to do so. @@ -2021,12 +2053,35 @@ verify_page_checksum(Page page, XLogRecPtr start_lsn, BlockNumber blkno, if (PageIsNew(page) || PageGetLSN(page) >= start_lsn) return true; - if (!DataChecksumsNeedVerify()) + if (!backup_checksums_verifiable(start_lsn)) return true; /* Perform the actual checksum calculation. */ checksum = pg_checksum_page(page, blkno); +#ifdef USE_INJECTION_POINTS + { + /* + * Make it possible to test checksum verification failure without + * having to destroy data on disk. There is cap on how many times we + * want to cause verification failure to make tests more interesting + * and less log intensive. This makes it easy to test pg_basebackup + * with the command_checks_all test function. + */ + static int hit = 0; + + if (IS_INJECTION_POINT_ATTACHED("basebackup-fail-checksum-verification")) + { + if (hit++ < 5) + { + checksum = 0; + INJECTION_POINT_CACHED("basebackup-fail-checksum-verification", + NULL); + } + } + } +#endif + /* See whether it matches the value from the page. */ phdr = (PageHeader) page; if (phdr->pd_checksum == checksum) diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 338d68d7424..130ba929109 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -262,6 +262,7 @@ extern uint64 GetSystemIdentifier(void); extern char *GetMockAuthenticationNonce(void); extern bool DataChecksumsNeedWrite(void); extern bool DataChecksumsNeedVerify(void); +extern XLogRecPtr GetLastChecksumChangeRecPtr(void); extern bool DataChecksumsOn(void); extern bool DataChecksumsOff(void); extern bool DataChecksumsInProgressOn(void); diff --git a/src/test/modules/test_checksums/meson.build b/src/test/modules/test_checksums/meson.build index 9b1421a9b91..fb7129d796f 100644 --- a/src/test/modules/test_checksums/meson.build +++ b/src/test/modules/test_checksums/meson.build @@ -33,6 +33,8 @@ tests += { 't/007_pgbench_standby.pl', 't/008_pitr.pl', 't/009_fpi.pl', + 't/010_backup_straddle.pl', + 't/011_standby_straddle.pl', ], }, } diff --git a/src/test/modules/test_checksums/t/010_backup_straddle.pl b/src/test/modules/test_checksums/t/010_backup_straddle.pl new file mode 100644 index 00000000000..aeeb3c8ccb0 --- /dev/null +++ b/src/test/modules/test_checksums/t/010_backup_straddle.pl @@ -0,0 +1,260 @@ + +# Copyright (c) 2026, PostgreSQL Global Development Group + +# Test base backups running while the data checksum state changes. The +# transition to "on" happens before the checkpoint which flushes the rewritten +# pages, so a backup straddling it reads on-disk pages which legitimately lack +# checksums and carry LSNs older than the backup start. The same applies to +# checksums being disabled and re-enabled while a backup runs: hint bit +# updates made while checksums were off reach disk without a checksum update +# and without moving the page LSN, so once the re-enabling completes the +# backup would resume verification and misjudge those pages until the +# rewritten versions are flushed. +# +# Both scenarios hold the two sides with injection points: the backup after +# its starting checkpoint but before it sends any file data, and the enabling +# after the state changed to "on" but before the checkpoint which flushes the +# rewritten pages. The backup is thus guaranteed to read the stale on-disk +# pages after the state change, without any timing assumptions. + +use strict; +use warnings FATAL => 'all'; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use File::Path qw(rmtree); +use Test::More; +use IPC::Run; + +use FindBin; +use lib $FindBin::RealBin; + +use DataChecksums::Utils; + +# This test suite is potentially expensive due to it requiring an increased +# shared_buffers setting. It requires the "checksum" PG_TEST_EXTRA setting to +# not cause false positives on slow or constrained systems. +if ($ENV{PG_TEST_EXTRA}) +{ + plan skip_all => 'Expensive data checksums test disabled' + unless ($ENV{PG_TEST_EXTRA} =~ /\bchecksum(_extended)?\b/); +} +else +{ + plan skip_all => 'Expensive data checksums test disabled'; +} + +if ($ENV{enable_injection_points} ne 'yes') +{ + plan skip_all => 'Injection points not supported by this build'; +} + +my $node = PostgreSQL::Test::Cluster->new('backup_node'); +$node->init(no_data_checksums => 1, allows_streaming => 1); +# The pages rewritten while enabling must stay dirty in shared buffers until +# the final checkpoint, otherwise they reach disk with checksums on their own +# and nothing is left to misjudge. The background writer must not flush them +# behind our back, and shared_buffers must exceed four times the table size +# so that the scan below does not go through a ring buffer. Autovacuum is +# disabled so that nothing sets hint bits behind our back, and wal_log_hints +# (implied by allows_streaming) must be off so that setting them does not +# move the page LSNs past the backup start. +$node->append_conf('postgresql.conf', 'shared_buffers = 32MB'); +$node->append_conf('postgresql.conf', 'bgwriter_lru_maxpages = 0'); +$node->append_conf('postgresql.conf', 'autovacuum = off'); +$node->append_conf('postgresql.conf', 'wal_log_hints = off'); +$node->start; + +$node->safe_psql('postgres', 'CREATE EXTENSION injection_points;'); + +# A body of relation pages for the backup to misjudge. The scan pulls the +# table into shared buffers so that enabling doesn't read it through a ring +# buffer, which would write the pages back out. +$node->safe_psql('postgres', + "CREATE TABLE t AS SELECT generate_series(1,100000) AS a;"); +$node->safe_psql('postgres', "SELECT count(*) FROM t;"); +test_checksum_state($node, 'off'); + +$node->safe_psql('postgres', + "SELECT injection_points_attach('basebackup-before-send-files','wait');"); +$node->safe_psql('postgres', + "SELECT injection_points_attach('datachecksums-on-before-checkpoint','wait');" +); + +my $backupdir = $node->backup_dir . '/straddle'; +my ($out, $err) = ('', ''); +my $backup = IPC::Run::start( + [ + 'pg_basebackup', '-D', + $backupdir, '--wal-method=none', + '--no-sync', '--checkpoint=fast', + '-d', $node->connstr('postgres') + ], + '>', + \$out, + '2>', + \$err, + IPC::Run::timeout(180)); + +$node->wait_for_event('walsender', 'basebackup-before-send-files'); + +# Enable checksums while the backup is held, then release the backup once the +# enabling has reached the "on" state and is held before its checkpoint. +enable_data_checksums($node); +$node->wait_for_event('datachecksums launcher', + 'datachecksums-on-before-checkpoint'); + +$node->safe_psql('postgres', + "SELECT injection_points_wakeup('basebackup-before-send-files');"); +$node->safe_psql('postgres', + "SELECT injection_points_detach('basebackup-before-send-files');"); + +ok($backup->finish, 'backup straddling enable completion succeeds') + or diag("stderr: $err"); + +# The backup must not even mention checksums: it must skip verification +# entirely, including the warning-only path for short reads. +unlike($err, qr/checksum/, 'straddling backup does not verify checksums'); + +$node->safe_psql('postgres', + "SELECT injection_points_wakeup('datachecksums-on-before-checkpoint');"); +$node->safe_psql('postgres', + "SELECT injection_points_detach('datachecksums-on-before-checkpoint');"); + +wait_for_checksum_state($node, 'on'); +$node->poll_query_until('postgres', + "SELECT count(*) = 0 FROM pg_catalog.pg_stat_activity " + . "WHERE backend_type = 'datachecksums launcher';"); + +# A backup started once enabling has completed must verify, and pass +$node->command_ok( + [ + 'pg_basebackup', '-D', + $node->backup_dir . '/after_enable', '--wal-method=none', + '--no-sync', '--checkpoint=fast' + ], + 'backup after enable completion succeeds'); +rmtree($node->backup_dir . '/after_enable'); + +# Now test a backup which straddles checksums being disabled and re-enabled. +# Recreate the table since the earlier scan set its hint bits and the rewrite +# gave the pages checksums; the new contents are not read here, leaving the +# hint bits unset until checksums are off. +$node->safe_psql('postgres', "DROP TABLE t;"); +$node->safe_psql('postgres', + "CREATE TABLE t AS SELECT generate_series(1,100000) AS a;"); + +$node->safe_psql('postgres', + "SELECT injection_points_attach('basebackup-before-send-files','wait');"); + +$backupdir = $node->backup_dir . '/onoffon'; +($out, $err) = ('', ''); +$backup = IPC::Run::start( + [ + 'pg_basebackup', '-D', + $backupdir, '--wal-method=none', + '--no-sync', '--checkpoint=fast', + '-d', $node->connstr('postgres') + ], + '>', + \$out, + '2>', + \$err, + IPC::Run::timeout(180)); + +$node->wait_for_event('walsender', 'basebackup-before-send-files'); + +disable_data_checksums($node, wait => 1); + +# With checksums off, the scan sets hint bits without WAL logging them, and +# the checkpoint flushes the modified pages without updating their checksums. +# The on-disk pages now carry stale checksums and LSNs older than the backup +# start. +$node->safe_psql('postgres', "SELECT count(*) FROM t;"); +$node->safe_psql('postgres', "CHECKPOINT;"); + +$node->safe_psql('postgres', + "SELECT injection_points_attach('datachecksums-on-before-checkpoint','wait');" +); + +enable_data_checksums($node); +$node->wait_for_event('datachecksums launcher', + 'datachecksums-on-before-checkpoint'); + +$node->safe_psql('postgres', + "SELECT injection_points_wakeup('basebackup-before-send-files');"); +$node->safe_psql('postgres', + "SELECT injection_points_detach('basebackup-before-send-files');"); + +ok($backup->finish, 'backup straddling disable and re-enable succeeds') + or diag("stderr: $err"); +unlike($err, qr/checksum/, + 'backup straddling disable and re-enable does not verify checksums'); + +$node->safe_psql('postgres', + "SELECT injection_points_wakeup('datachecksums-on-before-checkpoint');"); +$node->safe_psql('postgres', + "SELECT injection_points_detach('datachecksums-on-before-checkpoint');"); + +wait_for_checksum_state($node, 'on'); +$node->poll_query_until('postgres', + "SELECT count(*) = 0 FROM pg_catalog.pg_stat_activity " + . "WHERE backend_type = 'datachecksums launcher';"); +rmtree($backupdir); + +# A backup started once re-enabling has completed must verify, and pass +$node->command_ok( + [ + 'pg_basebackup', '-D', + $node->backup_dir . '/after_onoffon', '--wal-method=none', + '--no-sync', '--checkpoint=fast' + ], + 'backup after re-enable completion succeeds'); +rmtree($node->backup_dir . '/after_onoffon'); + +# Test another backup, but this time inject synthetic checksum verification +# failures into it. The regex matching the WARNING is different from the next +# test on purpose as it will have NOTICE output from the injection point as +# well. +$node->safe_psql('postgres', + "SELECT injection_points_attach('basebackup-fail-checksum-verification', 'notice');" +); +$node->command_checks_all( + [ + 'pg_basebackup', '-D', + $node->backup_dir . '/corrupt', '--wal-method=none', + '--no-sync', '--checkpoint=fast' + ], + 1, + [qr{^$}], + [qr/WARNING.*checksum verification failed/s], + 'pg_basebackup reports checksum mismatch'); +rmtree($node->backup_dir . '/corrupt'); +$node->safe_psql('postgres', + "SELECT injection_points_detach('basebackup-fail-checksum-verification');" +); + +# Now corrupt data on disk and take another backup to make sure the corruption +# is reported. +my $corrupt_table = $node->safe_psql('postgres', + q{CREATE TABLE corrupt_table AS SELECT a FROM generate_series(1,10000) AS a; ALTER TABLE corrupt_table SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt_table')} +); + +$node->stop; +$node->corrupt_page_checksum($corrupt_table, 0); +$node->start; + +$node->command_checks_all( + [ + 'pg_basebackup', '-D', + $node->backup_dir . '/corrupt', '--wal-method=none', + '--no-sync', '--checkpoint=fast' + ], + 1, + [qr{^$}], + [qr/^WARNING.*checksum verification failed/s], + 'pg_basebackup reports checksum mismatch'); +rmtree($node->backup_dir . '/corrupt'); + +$node->stop; +done_testing(); diff --git a/src/test/modules/test_checksums/t/011_standby_straddle.pl b/src/test/modules/test_checksums/t/011_standby_straddle.pl new file mode 100644 index 00000000000..e50fb65fcaf --- /dev/null +++ b/src/test/modules/test_checksums/t/011_standby_straddle.pl @@ -0,0 +1,249 @@ + +# Copyright (c) 2026, PostgreSQL Global Development Group + +# Test that a standby does not become available for base backups before it +# has re-replayed the latest data checksum state change after a restart. +# +# When a standby replays XLOG2_CHECKSUMS it writes the new state to +# pg_control, but the location of the change is only tracked in shared +# memory. If the standby restarts before a restartpoint covers the record, +# and reaches consistency below it, base backups would resume checksum +# verification with the change location unknown, while the pages rewritten +# before the change may not have reached disk. The redo routine must +# therefore advance minRecoveryPoint to the record, so that consistency (and +# with it hot standby and base backups) is withheld until the change location +# is known again. +# +# The test holds the enabling on the primary between the state change and its +# final checkpoint, waits for the standby to replay the state change, and +# crashes the standby so that the rewritten pages never reach its disk. WAL +# from the enabling onwards is removed from the standby's pg_wal and +# streaming is disabled, so that replay after the restart stalls below the +# state change record. Restarted this way, the standby must refuse +# connections; once streaming is re-enabled and the record replayed again, +# base backups must succeed without spurious checksum failures. + +use strict; +use warnings FATAL => 'all'; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use File::Path qw(rmtree); +use Test::More; + +use FindBin; +use lib $FindBin::RealBin; + +use DataChecksums::Utils; + +# This test suite is potentially expensive due to it requiring an increased +# shared_buffers setting and use custom timeouts. It requires the +# "checksum_extended" PG_TEST_EXTRA setting to not cause false positives on +# slow or constrained systems. +if ($ENV{PG_TEST_EXTRA}) +{ + plan skip_all => 'Expensive data checksums test disabled' + unless ($ENV{PG_TEST_EXTRA} =~ /\bchecksum_extended\b/); +} +else +{ + plan skip_all => 'Expensive data checksums test disabled'; +} + +if ($ENV{enable_injection_points} ne 'yes') +{ + plan skip_all => 'Injection points not supported by this build'; +} + +my $node_primary = PostgreSQL::Test::Cluster->new('straddle_primary'); +$node_primary->init(no_data_checksums => 1, allows_streaming => 1); +# The pages rewritten while enabling must stay dirty in shared buffers until +# the final checkpoint, and their standby copies must stay dirty as well, so +# that the on-disk pages legitimately lack checksums. wal_log_hints (implied +# by allows_streaming) is turned off to keep the page LSNs put during setup. +$node_primary->append_conf('postgresql.conf', 'shared_buffers = 128MB'); +$node_primary->append_conf('postgresql.conf', 'autovacuum = off'); +$node_primary->append_conf('postgresql.conf', 'wal_log_hints = off'); +$node_primary->start; + +$node_primary->safe_psql('postgres', 'CREATE EXTENSION injection_points;'); + +my $slotname = 'physical_slot'; +$node_primary->safe_psql('postgres', + "SELECT pg_create_physical_replication_slot('$slotname');"); + +# A body of relation pages whose standby copies will lack checksums +$node_primary->safe_psql('postgres', + "CREATE TABLE t AS SELECT generate_series(1,100000) AS a;"); + +my $backup_name = 'straddle_backup'; +$node_primary->backup($backup_name); + +my $node_standby = PostgreSQL::Test::Cluster->new('straddle_standby'); +$node_standby->init_from_backup($node_primary, $backup_name, + has_streaming => 1); +# The background writer must not flush the replayed page rewrites behind our +# back, or nothing is left to protect and minRecoveryPoint could move on its +# own. +$node_standby->append_conf( + 'postgresql.conf', qq[ +primary_slot_name = '$slotname' +bgwriter_lru_maxpages = 0 +]); +$node_standby->start; + +$node_primary->wait_for_catchup($node_standby, 'replay', + $node_primary->lsn('insert')); +test_checksum_state($node_primary, 'off'); +test_checksum_state($node_standby, 'off'); + +# Pin the restartpoint the later base backups will start from: replay a +# primary checkpoint and force a restartpoint on it. No further checkpoint +# record reaches the standby until the enabling is released, so this remains +# the standby's backup starting checkpoint throughout. +$node_primary->safe_psql('postgres', 'CHECKPOINT;'); +$node_primary->wait_for_catchup($node_standby, 'replay', + $node_primary->lsn('insert')); +$node_standby->safe_psql('postgres', 'CHECKPOINT;'); + +# Put everything the enabling writes into fresh WAL segments, so that the +# standby's copies of them can be removed later, and remember where the +# enabling era begins. +$node_primary->safe_psql('postgres', 'SELECT pg_switch_wal();'); + +# Enable checksums, holding the launcher after the state change but before +# the final checkpoint, so the rewritten pages stay dirty everywhere. +$node_primary->safe_psql('postgres', + "SELECT injection_points_attach('datachecksums-enable-checksums-delay', 'wait');" +); +$node_primary->safe_psql('postgres', + "SELECT injection_points_attach('datachecksums-on-before-checkpoint','wait');" +); +enable_data_checksums($node_primary); + +$node_primary->wait_for_event('datachecksums launcher', + 'datachecksums-enable-checksums-delay'); +my $enable_start_lsn = + $node_primary->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn();'); +my $enable_start_seg = $node_primary->safe_psql('postgres', + "SELECT pg_walfile_name('$enable_start_lsn');"); +$node_primary->safe_psql('postgres', + "SELECT injection_points_wakeup('datachecksums-enable-checksums-delay');" +); + +# Immediately start to wait for the next event and hold off on detaching the +# previous injection point till later to avoid delays and risk missing the +# wait event +$node_primary->wait_for_event('datachecksums launcher', + 'datachecksums-on-before-checkpoint'); +# Detach the injection point now that we have some more time +$node_primary->safe_psql('postgres', + "SELECT injection_points_detach('datachecksums-enable-checksums-delay');" +); + +# The standby has now replayed the state change: its pg_control says "on" +# while the rewritten pages are only dirty in its shared buffers. +$node_primary->wait_for_catchup($node_standby, 'replay', + $node_primary->lsn('insert')); +wait_for_checksum_state($node_standby, 'on'); + +# Crash the standby, losing the dirty rewritten pages. +$node_standby->stop('immediate'); + +# The state change record must have dragged minRecoveryPoint along with it, +# otherwise the standby can become consistent below the record after the +# restart. +my ($stdout, $stderr) = + run_command([ 'pg_controldata', $node_standby->data_dir ]); +my ($min_recovery) = + $stdout =~ /Minimum recovery ending location:\s*([0-9A-F]+\/[0-9A-F]+)/; +die "could not parse pg_controldata output" unless defined $min_recovery; + +my $result = $node_primary->safe_psql('postgres', + "SELECT '$min_recovery'::pg_lsn > '$enable_start_lsn'::pg_lsn;"); +is($result, 't', 'minRecoveryPoint advanced past the checksum state change'); + +# Remove the enabling-era WAL from the standby and cut it off from the +# primary, so that replay after the restart stalls below the state change. +# The replication slot retains the removed segments on the primary. +my $wal_dir = $node_standby->data_dir . '/pg_wal'; +opendir(my $dh, $wal_dir) or die "could not open $wal_dir: $!"; +foreach my $segment (readdir($dh)) +{ + next unless $segment =~ /^[0-9A-F]{24}$/; + next unless $segment ge $enable_start_seg; + unlink("$wal_dir/$segment") + or die "could not unlink $wal_dir/$segment: $!"; +} +closedir($dh); +$node_standby->append_conf('postgresql.conf', "primary_conninfo = ''"); + +# The standby must not reach consistency until it has re-replayed the state +# change, so startup must not complete within the timeout. Reaching hot +# standby below the record would make pg_ctl return success here. +my $started; +{ + local $ENV{PGCTLTIMEOUT} = 10; + $started = $node_standby->start(fail_ok => 1); +} +is($started, 0, + 'standby withholds consistency until the state change is replayed again'); + +my ($ret, $out, $err) = $node_standby->psql('postgres', 'SELECT 1;'); +isnt($ret, 0, 'standby refuses connections while below the state change'); + +# Reconnect the standby; streaming provides the removed WAL again, replay +# passes the state change and the standby becomes consistent. +$node_standby->enable_streaming($node_primary); +$node_standby->reload; +$node_standby->poll_query_until('postgres', 'SELECT true;'); +$node_primary->wait_for_catchup($node_standby, 'replay', + $node_primary->lsn('insert')); + +# The rewritten pages are again only dirty in shared buffers, so the on-disk +# pages still lack checksums. A base backup must skip verification entirely +# and pass without mentioning checksums on stderr. Standby backups always +# print a NOTICE about WAL archiving, so stderr is not empty. +$node_standby->command_checks_all( + [ + 'pg_basebackup', '-D', + $node_standby->backup_dir . '/underway', '--wal-method=none', + '--no-sync', '--checkpoint=fast' + ], + 0, + [qr{^$}], + [qr{^(?!.*checksum)}s], + 'backup from standby while enabling is underway succeeds'); +rmtree($node_standby->backup_dir . '/underway'); + +# Release the enabling; its final checkpoint flushes the rewritten pages. +$node_primary->safe_psql('postgres', + "SELECT injection_points_wakeup('datachecksums-on-before-checkpoint');"); +$node_primary->safe_psql('postgres', + "SELECT injection_points_detach('datachecksums-on-before-checkpoint');"); +wait_for_checksum_state($node_primary, 'on'); +$node_primary->poll_query_until('postgres', + "SELECT count(*) = 0 FROM pg_catalog.pg_stat_activity " + . "WHERE backend_type = 'datachecksums launcher';"); + +# A restartpoint on the final checkpoint lets verification resume, and a +# backup started from it must again pass. +$node_primary->wait_for_catchup($node_standby, 'replay', + $node_primary->lsn('insert')); +$node_standby->safe_psql('postgres', 'CHECKPOINT;'); + +$node_standby->command_checks_all( + [ + 'pg_basebackup', '-D', + $node_standby->backup_dir . '/after_enable', '--wal-method=none', + '--no-sync', '--checkpoint=fast' + ], + 0, + [qr{^$}], + [qr{^(?!.*checksum)}s], + 'backup from standby after enable completion succeeds'); +rmtree($node_standby->backup_dir . '/after_enable'); + +$node_standby->stop; +$node_primary->stop; +done_testing(); From c61c3ec40cb8e08fe54573de7cf1a27fa4d10f9f Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Tue, 18 Aug 2026 22:25:55 +0200 Subject: [PATCH 401/481] Minor test suite cleanup A few catalog queries were missing proper schema qualification in the test_checksums module test suites, and one suite contained a disable call right before tearing down the test which can be removed. Backpatch to v19 where the test suite was added. Author: Daniel Gustafsson Discussion: https://postgr.es/m/8CF9B235-AEE9-4E68-93DD-DF4F29E2FCE5@yesql.se Backpatch-through: 19 --- src/test/modules/test_checksums/t/001_basic.pl | 4 ++-- src/test/modules/test_checksums/t/002_restarts.pl | 4 +--- src/test/modules/test_checksums/t/003_standby_restarts.pl | 7 ++++--- src/test/modules/test_checksums/t/005_injection.pl | 5 +++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/test/modules/test_checksums/t/001_basic.pl b/src/test/modules/test_checksums/t/001_basic.pl index 5a16b6fb9e4..4cfa35b6885 100644 --- a/src/test/modules/test_checksums/t/001_basic.pl +++ b/src/test/modules/test_checksums/t/001_basic.pl @@ -136,7 +136,7 @@ $node->poll_query_until( 'postgres', qq[ - SELECT count(*) > 0 FROM pg_stat_activity + SELECT count(*) > 0 FROM pg_catalog.pg_stat_activity WHERE backend_type = 'datachecksums worker' AND datname = 'postgres' AND query LIKE 'Waiting for % temp tables to be removed'] ) or die "timed out waiting for worker to wait for temporary tables"; @@ -180,7 +180,7 @@ $node->poll_query_until( 'postgres', qq[ - SELECT count(*) > 0 FROM pg_stat_activity + SELECT count(*) > 0 FROM pg_catalog.pg_stat_activity WHERE backend_type = 'datachecksums worker' AND datname = 'dropmeforce' AND query LIKE 'Waiting for % temp tables to be removed'] ) or die "timed out waiting for worker to wait for temporary tables"; diff --git a/src/test/modules/test_checksums/t/002_restarts.pl b/src/test/modules/test_checksums/t/002_restarts.pl index bef0bb90993..4799afed628 100644 --- a/src/test/modules/test_checksums/t/002_restarts.pl +++ b/src/test/modules/test_checksums/t/002_restarts.pl @@ -152,11 +152,9 @@ $result = $node->poll_query_until( 'postgres', - "SELECT count(*) FROM pg_stat_activity WHERE backend_type LIKE 'datachecksums%';", + "SELECT count(*) FROM pg_catalog.pg_stat_activity WHERE backend_type LIKE 'datachecksums%';", '0'); is($result, 1, 'await datachecksums worker/launcher termination'); -disable_data_checksums($node, wait => 1); - $node->stop; done_testing(); diff --git a/src/test/modules/test_checksums/t/003_standby_restarts.pl b/src/test/modules/test_checksums/t/003_standby_restarts.pl index bb35ed0b325..b05ffd8643a 100644 --- a/src/test/modules/test_checksums/t/003_standby_restarts.pl +++ b/src/test/modules/test_checksums/t/003_standby_restarts.pl @@ -95,7 +95,7 @@ $result = $node_primary->poll_query_until( 'postgres', - "SELECT count(*) FROM pg_stat_activity WHERE backend_type LIKE 'datachecksums%';", + "SELECT count(*) FROM pg_catalog.pg_stat_activity WHERE backend_type LIKE 'datachecksums%';", '0'); is($result, 1, 'await datachecksums worker/launcher termination'); @@ -145,9 +145,10 @@ # Get the relfilenode and database OID so we can inspect the filesystem my $unlogged_rfn = $node_primary->safe_psql('postgres', - "SELECT relfilenode FROM pg_class WHERE relname = 'unlogged_tbl';"); + "SELECT relfilenode FROM pg_catalog.pg_class WHERE relname = 'unlogged_tbl';" +); my $db_oid = $node_primary->safe_psql('postgres', - "SELECT oid FROM pg_database WHERE datname = 'postgres';"); + "SELECT oid FROM pg_catalog.pg_database WHERE datname = 'postgres';"); # Verify the standby only has the init fork (no main fork) my $standby_datadir = $node_standby->data_dir; diff --git a/src/test/modules/test_checksums/t/005_injection.pl b/src/test/modules/test_checksums/t/005_injection.pl index 60bb716d922..92a4948f040 100644 --- a/src/test/modules/test_checksums/t/005_injection.pl +++ b/src/test/modules/test_checksums/t/005_injection.pl @@ -98,7 +98,7 @@ enable_data_checksums($node); $node->poll_query_until( 'postgres', qq[ - SELECT count(*) > 0 FROM pg_stat_activity + SELECT count(*) > 0 FROM pg_catalog.pg_stat_activity WHERE backend_type = 'datachecksums worker' AND datname = 'postgres' AND query LIKE 'Waiting for % temp tables to be removed'] ) or die "timed out waiting for worker to wait for temporary tables"; @@ -125,7 +125,8 @@ "SELECT injection_points_detach('dropdb-after-invalid-marker');"); my $invalid_state = $node->safe_psql('postgres', - "SELECT datconnlimit FROM pg_database WHERE datname = 'invalid_dropdb';"); + "SELECT datconnlimit FROM pg_catalog.pg_database WHERE datname = 'invalid_dropdb';" +); is($invalid_state, '-2', 'interrupted DROP left an invalid database row'); # Let checksum processing continue. The invalid database must be treated as From 1d28812160d4e7ec06ebb2223d2c67b0dec74720 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Tue, 18 Aug 2026 22:25:58 +0200 Subject: [PATCH 402/481] Stabilize the FORCE drop test for online data checksums Commit 51f55b13a4d added a test where DROP DATABASE ... WITH (FORCE) terminates a session holding a temporary table in the target database. While exiting, the terminated session drops its temporary table and commits, and the commit waits for a WAL flush behind the backlog generated by the checksum workers. On machines with slow storage this can exceed the five seconds DROP DATABASE waits for terminated backends to exit, making the test fail with "database "dropmeforce" is being accessed by other users", as observed on buildfarm member turaco. To fix, use asynchronous commit in the terminated session, so that its exit does not wait for a WAL flush, and checkpoint before the drop so that the exit-time WAL records do not queue up behind the backlog. Author: Zsolt Parragi Reported-by: Alexander Lakhin Discussion: https://postgr.es/m/361531e2-52b5-499c-a126-815f277bbef2@gmail.com Backpatch-through: 19 --- src/test/modules/test_checksums/t/001_basic.pl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/test/modules/test_checksums/t/001_basic.pl b/src/test/modules/test_checksums/t/001_basic.pl index 4cfa35b6885..4cfd532500d 100644 --- a/src/test/modules/test_checksums/t/001_basic.pl +++ b/src/test/modules/test_checksums/t/001_basic.pl @@ -172,8 +172,13 @@ "CREATE TABLE dropme_t AS SELECT generate_series(1,10000) AS a;"); # Hold the worker inside "dropmeforce" by keeping a temporary table around -# there. +# there. The session is later terminated by DROP DATABASE ... WITH (FORCE) +# and drops the temp table while exiting; commit that drop asynchronously, +# otherwise the exit has to flush WAL behind the traffic generated by the +# checksum workers, which on slow machines can exceed the time DROP DATABASE +# waits for the session to exit. $bg = $node->background_psql('dropmeforce'); +$bg->query_safe('SET synchronous_commit = off;'); $bg->query_safe('CREATE TEMP TABLE holdme (a int);'); enable_data_checksums($node); @@ -185,6 +190,11 @@ AND query LIKE 'Waiting for % temp tables to be removed'] ) or die "timed out waiting for worker to wait for temporary tables"; +# Write out the WAL backlog from the checksum processing so far, so that the +# sessions terminated below do not get stuck behind it when writing their +# final WAL records on slow machines. +$node->safe_psql('postgres', "CHECKPOINT;"); + # Terminates both the session holding the temp table and the checksums # worker connected to the database. $node->safe_psql('postgres', "DROP DATABASE dropmeforce WITH (FORCE);"); From fe06b9b5bd61dc04ab788091c56a0cb9ef44b3d2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 18 Aug 2026 17:33:44 -0400 Subject: [PATCH 403/481] Defend against null "SV *" pointers in plperl modules. Tied hashes, and probably tied arrays, are capable of returning Perl value pointers that are actually NULL, not the usual pointer to an undef SV. We were not defending against that everywhere, leading to possible SIGSEGV. Fix the code to consistently treat a null pointer returned from hv_iternext or av_fetch like a !SvOK one. (Note that the large diff in SV_to_JsonbValue is actually quite trivial, but it required reindenting a chunk of existing code.) Claude Code found the instance in hstore_plperl, and I found the others by code auditing. Perhaps the other instances aren't actually reachable, but I see little reason to assume that. The known test cases for these errors require perl's Tie modules, which may not be present, so it doesn't seem worth the trouble to create regression test cases that would cover them. Reported-by: Claude Code (via Noah Misch) Author: Tom Lane Discussion: https://postgr.es/m/569769.1786901901@sss.pgh.pa.us Backpatch-through: 14 --- contrib/hstore_plperl/hstore_plperl.c | 2 +- contrib/jsonb_plperl/jsonb_plperl.c | 161 ++++++++++++++------------ src/pl/plperl/plperl.c | 2 +- 3 files changed, 86 insertions(+), 79 deletions(-) diff --git a/contrib/hstore_plperl/hstore_plperl.c b/contrib/hstore_plperl/hstore_plperl.c index d7f1b8ddb48..197d84141e5 100644 --- a/contrib/hstore_plperl/hstore_plperl.c +++ b/contrib/hstore_plperl/hstore_plperl.c @@ -150,7 +150,7 @@ plperl_to_hstore(PG_FUNCTION_ARGS) pairs[i].keylen = hstoreCheckKeyLen(strlen(pairs[i].key)); pairs[i].needfree = true; - if (!SvOK(value)) + if (!value || !SvOK(value)) { pairs[i].val = NULL; pairs[i].vallen = 0; diff --git a/contrib/jsonb_plperl/jsonb_plperl.c b/contrib/jsonb_plperl/jsonb_plperl.c index 00a99d303c6..676b7393c1d 100644 --- a/contrib/jsonb_plperl/jsonb_plperl.c +++ b/contrib/jsonb_plperl/jsonb_plperl.c @@ -186,7 +186,7 @@ SV_to_JsonbValue(SV *in, JsonbInState *jsonb_state, bool is_elem) check_stack_depth(); /* Dereference references recursively. */ - while (SvROK(in)) + while (in && SvROK(in)) { /* * It's possible for circular references to make this an infinite @@ -197,85 +197,92 @@ SV_to_JsonbValue(SV *in, JsonbInState *jsonb_state, bool is_elem) in = SvRV(in); } - switch (SvTYPE(in)) + if (!in) { - case SVt_PVAV: - AV_to_JsonbValue((AV *) in, jsonb_state); - return; - - case SVt_PVHV: - HV_to_JsonbValue((HV *) in, jsonb_state); - return; - - default: - if (!SvOK(in)) - { - out.type = jbvNull; - } - else if (SvUOK(in)) - { - /* - * If UV is >=64 bits, we have no better way to make this - * happen than converting to text and back. Given the low - * usage of UV in Perl code, it's not clear it's worth working - * hard to provide alternate code paths. - */ - const char *strval = SvPV_nolen(in); - - out.type = jbvNumeric; - out.val.numeric = - DatumGetNumeric(DirectFunctionCall3(numeric_in, - CStringGetDatum(strval), - ObjectIdGetDatum(InvalidOid), - Int32GetDatum(-1))); - } - else if (SvIOK(in)) - { - IV ival = SvIV(in); + out.type = jbvNull; + } + else + { + switch (SvTYPE(in)) + { + case SVt_PVAV: + AV_to_JsonbValue((AV *) in, jsonb_state); + return; + + case SVt_PVHV: + HV_to_JsonbValue((HV *) in, jsonb_state); + return; + + default: + if (!SvOK(in)) + { + out.type = jbvNull; + } + else if (SvUOK(in)) + { + /* + * If UV is >=64 bits, we have no better way to make this + * happen than converting to text and back. Given the low + * usage of UV in Perl code, it's not clear it's worth + * working hard to provide alternate code paths. + */ + const char *strval = SvPV_nolen(in); + + out.type = jbvNumeric; + out.val.numeric = + DatumGetNumeric(DirectFunctionCall3(numeric_in, + CStringGetDatum(strval), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1))); + } + else if (SvIOK(in)) + { + IV ival = SvIV(in); - out.type = jbvNumeric; - out.val.numeric = int64_to_numeric(ival); - } - else if (SvNOK(in)) - { - double nval = SvNV(in); - - /* - * jsonb doesn't allow infinity or NaN (per JSON - * specification), but the numeric type that is used for the - * storage accepts those, so we have to reject them here - * explicitly. - */ - if (isinf(nval)) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("cannot convert infinity to jsonb"))); - if (isnan(nval)) + out.type = jbvNumeric; + out.val.numeric = int64_to_numeric(ival); + } + else if (SvNOK(in)) + { + double nval = SvNV(in); + + /* + * jsonb doesn't allow infinity or NaN (per JSON + * specification), but the numeric type that is used for + * the storage accepts those, so we have to reject them + * here explicitly. + */ + if (isinf(nval)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("cannot convert infinity to jsonb"))); + if (isnan(nval)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("cannot convert NaN to jsonb"))); + + out.type = jbvNumeric; + out.val.numeric = + DatumGetNumeric(DirectFunctionCall1(float8_numeric, + Float8GetDatum(nval))); + } + else if (SvPOK(in)) + { + out.type = jbvString; + out.val.string.val = sv2cstr(in); + out.val.string.len = strlen(out.val.string.val); + } + else + { + /* + * XXX It might be nice if we could include the Perl type + * in the error message. + */ ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("cannot convert NaN to jsonb"))); - - out.type = jbvNumeric; - out.val.numeric = - DatumGetNumeric(DirectFunctionCall1(float8_numeric, - Float8GetDatum(nval))); - } - else if (SvPOK(in)) - { - out.type = jbvString; - out.val.string.val = sv2cstr(in); - out.val.string.len = strlen(out.val.string.val); - } - else - { - /* - * XXX It might be nice if we could include the Perl type in - * the error message. - */ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot transform this Perl type to jsonb"))); - } + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot transform this Perl type to jsonb"))); + } + } } if (jsonb_state->parseState) diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 8175407849e..dcade2b4969 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -1146,7 +1146,7 @@ get_perl_array_ref(SV *sv) { dTHX; - if (SvOK(sv) && SvROK(sv)) + if (sv && SvOK(sv) && SvROK(sv)) { if (SvTYPE(SvRV(sv)) == SVt_PVAV) return sv; From db0f6dd80a0323bd39a5566f72699b6cbfe204bc Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 19 Aug 2026 09:51:52 +0900 Subject: [PATCH 404/481] Report single-page checksum failures in pg_stat_database Base backups reported checksum failures to pg_stat_database only for files with more than one failing page. Commit 6b9e875f728 placed the report inside the block emitting the per-file summary WARNING, which was skipped for a single failure. As a result, a backup failing on files with one corrupted page each left checksum_failures untouched. To fix, emit the per-file summary and the pgstat report for any non-zero failure count. The end-of-backup total WARNING had the same off-by-one and is now also emitted for a single failure. Author: Zsolt Parragi Reviewed-by: Nazir Bilal Yavuz Discussion: https://postgr.es/m/CAN4CZFN+Bi6XmaH8zOdMWjoycYFx9nKtOr+dzQf0o-UQ+Rdqmw@mail.gmail.com Backpatch-through: 14 --- src/backend/backup/basebackup.c | 13 ++++++------- src/bin/pg_basebackup/t/010_pg_basebackup.pl | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c index fe89b812bed..4dcb06942d1 100644 --- a/src/backend/backup/basebackup.c +++ b/src/backend/backup/basebackup.c @@ -663,12 +663,11 @@ perform_base_backup(basebackup_options *opt, bbsink *sink, if (total_checksum_failures) { - if (total_checksum_failures > 1) - ereport(WARNING, - (errmsg_plural("%lld total checksum verification failure", - "%lld total checksum verification failures", - total_checksum_failures, - total_checksum_failures))); + ereport(WARNING, + (errmsg_plural("%lld total checksum verification failure", + "%lld total checksum verification failures", + total_checksum_failures, + total_checksum_failures))); ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), @@ -1821,7 +1820,7 @@ sendFile(bbsink *sink, const char *readfilename, const char *tarfilename, CloseTransientFile(fd); - if (checksum_failures > 1) + if (checksum_failures > 0) { ereport(WARNING, (errmsg_plural("file \"%s\" has a total of %d checksum verification failure", diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl index cfcfdb8b580..2442131e179 100644 --- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl +++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl @@ -913,6 +913,13 @@ 'pg_basebackup reports checksum mismatch'); rmtree("$tempdir/backup_corrupt"); +# Single failure counted in pg_stat_database. +ok( $node->poll_query_until( + 'postgres', + 'SELECT checksum_failures = 1 FROM pg_stat_database ' + . "WHERE datname = 'postgres';"), + 'checksum failure reported in pg_stat_database'); + # induce further corruption in 5 more blocks $node->stop; for my $i (1 .. 5) @@ -942,6 +949,13 @@ 'pg_basebackup correctly report the total number of checksum mismatches'); rmtree("$tempdir/backup_corrupt3"); +# Failures across all the backups. +ok( $node->poll_query_until( + 'postgres', + 'SELECT checksum_failures = 14 FROM pg_stat_database ' + . "WHERE datname = 'postgres';"), + 'checksum failures accumulated in pg_stat_database'); + # do not verify checksums, should return ok $node->command_ok( [ From 4a710d68871cd9bbdcc57b244dbbeeca08de7735 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 19 Aug 2026 11:32:47 +0900 Subject: [PATCH 405/481] Fix relcache reference leak when decoding TRUNCATE ReorderBufferProcessTXN() opens every relation referenced by a TRUNCATE change. When RelationIsLogicallyLogged() returns false, it skips the relation without releasing the reference acquired by RelationIdGetRelation(). Looking at the in-core code paths building XLOG_HEAP_TRUNCATE records, no relation OIDs would be included if they do not satisfy RelationIsLogicallyLogged(). One pattern that could go through is if a table is switched to SET UNLOGGED, but that would not be reachable in practice as the decoding happens after a historical snapshot is taken, so the relation should still be valid. This is a defense-in-depth measure in practice, and we tend to be careful about how Relations are handled when sending changes to output plugins, so backpatch all the way down. Author: Chao Li Reviewed-by: Xuneng Zhou Discussion: https://postgr.es/m/7DD65D03-3B5A-43B2-99AD-8E6AF5372BAB@gmail.com Backpatch-through: 14 --- src/backend/replication/logical/reorderbuffer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 077b80afd6f..05225433322 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -2502,7 +2502,10 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, elog(ERROR, "could not open relation with OID %u", relid); if (!RelationIsLogicallyLogged(rel)) + { + RelationClose(rel); continue; + } relations[nrelations++] = rel; } From 9d4505b7f826b649501253c094aea5c28a66f266 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 19 Aug 2026 12:31:00 +0900 Subject: [PATCH 406/481] psql: Avoid returning oom_buffer from psql slash command scanner psql_scan_slash_command() builds the command name in a local PQExpBufferData and returns the buffer's data pointer to its caller. If either the initial allocation or a later enlargement failed, that data pointer could be the static PQExpBuffer OOM buffer rather than malloc-owned storage. HandleSlashCmds() could then eventually pass it to free(), causing undefined behavior. Detect a broken command-name buffer before returning it, report OOM, and return NULL instead. Teach HandleSlashCmds() to treat a NULL command name as a command error before trying to compare or dispatch it. Backpatch to all supported versions. Reported-by: Junwang Zhao Author: Fujii Masao Reviewed-by: Chao Li Reviewed-by: Junwang Zhao Discussion: https://postgr.es/m/CAHGQGwEh3R3=1tx_a5=fTDJ+ycuwxWMEn6bG_Yt4B5P+hE7AVw@mail.gmail.com Backpatch-through: 14 --- src/bin/psql/command.c | 4 +++- src/bin/psql/psqlscanslash.l | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index fc5a0d4221f..0c9d430def2 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -249,7 +249,9 @@ HandleSlashCmds(PsqlScanState scan_state, * If we are in "restricted" mode, the only allowable backslash command is * \unrestrict (to exit restricted mode). */ - if (restricted && strcmp(cmd, "unrestrict") != 0) + if (cmd == NULL) + status = PSQL_CMD_ERROR; + else if (restricted && strcmp(cmd, "unrestrict") != 0) { pg_log_error("backslash commands are restricted; only \\unrestrict is allowed"); status = PSQL_CMD_ERROR; diff --git a/src/bin/psql/psqlscanslash.l b/src/bin/psql/psqlscanslash.l index e3ec1775e62..9640d6e6a6e 100644 --- a/src/bin/psql/psqlscanslash.l +++ b/src/bin/psql/psqlscanslash.l @@ -474,7 +474,7 @@ other . * has been consumed through the leading backslash. * * The return value is a malloc'd copy of the command name, as parsed off - * from the input. + * from the input, or NULL on out-of-memory. */ char * psql_scan_slash_command(PsqlScanState state) @@ -505,7 +505,7 @@ psql_scan_slash_command(PsqlScanState state) /* And lex. */ yylex(NULL, state->scanner); - /* There are no possible errors in this lex state... */ + /* There are no possible syntax errors in this lex state... */ /* * In case the caller returns to using the regular SQL lexer, reselect the @@ -513,6 +513,17 @@ psql_scan_slash_command(PsqlScanState state) */ psql_scan_reselect_sql_lexer(state); + /* + * yylex() appends command-name text to mybuf, so a buffer enlargement + * failure during lexing can leave mybuf broken even if initialization + * succeeded. + */ + if (PQExpBufferDataBroken(mybuf)) + { + pg_log_error("out of memory"); + return NULL; + } + return mybuf.data; } From e793e51abab3987dd55d4598316e60966c9e159e Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 19 Aug 2026 12:34:28 +0900 Subject: [PATCH 407/481] psql: Avoid returning oom_buffer from psql slash option scanner psql_scan_slash_option() builds option text in a local PQExpBufferData and returns the buffer's data pointer to its caller. If either the initial allocation or a later enlargement failed, that data pointer could be the static PQExpBuffer OOM buffer rather than malloc-owned storage. The callers could then eventually pass it to free(), causing undefined behavior. Detect a broken option buffer before returning it, report OOM, and return NULL instead. Also avoid evaluating a backtick substitution when the option buffer is already broken, since doing so could otherwise touch the static OOM buffer. This keeps the existing NULL-return convention for slash options. Callers are not generally changed to distinguish OOM from no option. Backpatch to all supported versions. Reported-by: Junwang Zhao Author: Fujii Masao Reviewed-by: Chao Li Reviewed-by: Junwang Zhao Discussion: https://postgr.es/m/CAHGQGwEh3R3=1tx_a5=fTDJ+ycuwxWMEn6bG_Yt4B5P+hE7AVw@mail.gmail.com Backpatch-through: 14 --- src/bin/psql/command.c | 2 +- src/bin/psql/psqlscanslash.l | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 0c9d430def2..e4fbbdefc1b 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -2385,7 +2385,7 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd) if (strcmp(cmd + 3, "export") == 0) { - if (!opt2) + if (!opt1 || !opt2) { pg_log_error("\\%s: missing required argument", cmd); success = false; diff --git a/src/bin/psql/psqlscanslash.l b/src/bin/psql/psqlscanslash.l index 9640d6e6a6e..298473afda8 100644 --- a/src/bin/psql/psqlscanslash.l +++ b/src/bin/psql/psqlscanslash.l @@ -529,7 +529,8 @@ psql_scan_slash_command(PsqlScanState state) /* * Parse off the next argument for a backslash command, and return it as a - * malloc'd string. If there are no more arguments, returns NULL. + * malloc'd string. If there are no more arguments or on out-of-memory, + * returns NULL. * * type tells what processing, if any, to perform on the option string; * for example, if it's a SQL identifier, we want to downcase any unquoted @@ -606,6 +607,16 @@ psql_scan_slash_option(PsqlScanState state, */ Assert(lexresult == LEXRES_EOL || lexresult == LEXRES_OK); + /* + * yylex() appends option text to mybuf, so a buffer enlargement failure + * during lexing can leave mybuf broken even if initialization succeeded. + */ + if (PQExpBufferDataBroken(mybuf)) + { + pg_log_error("out of memory"); + return NULL; + } + switch (final_state) { case xslashargstart: @@ -816,7 +827,7 @@ static void evaluate_backtick(PsqlScanState state) { PQExpBuffer output_buf = state->output_buf; - char *cmd = output_buf->data + backtick_start_offset; + char *cmd; PQExpBufferData cmd_output; FILE *fd; bool error = false; @@ -824,6 +835,15 @@ evaluate_backtick(PsqlScanState state) char buf[512]; size_t result; + /* + * The option buffer is already broken; avoid touching the static + * oom_buffer and let psql_scan_slash_option() return NULL. + */ + if (PQExpBufferBroken(output_buf)) + return; + + cmd = output_buf->data + backtick_start_offset; + initPQExpBuffer(&cmd_output); fflush(NULL); From e3ad751e1f43a97a3ed5da358a938f8f87b6a4a1 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 19 Aug 2026 12:37:09 +0900 Subject: [PATCH 408/481] psql: Fix psql slash option leaks psql_scan_slash_option() returns a malloc'd string, but \getresults, \gset in pipeline mode, \restrict, and \unrestrict did not free it after consuming or copying the value. Free these option strings after use. Backpatch to all supported versions. In v17 and older, only \restrict and \unrestrict are affected, so those branches need only that part of the fix. Author: Fujii Masao Reviewed-by: Chao Li Discussion: https://postgr.es/m/CAHGQGwEh3R3=1tx_a5=fTDJ+ycuwxWMEn6bG_Yt4B5P+hE7AVw@mail.gmail.com Backpatch-through: 14 --- src/bin/psql/command.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index e4fbbdefc1b..4c9f97c2714 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1946,6 +1946,7 @@ exec_command_getresults(PsqlScanState scan_state, bool active_branch) if (opt != NULL) { num_results = atoi(opt); + free(opt); if (num_results < 0) { pg_log_error("\\getresults: invalid number of requested results"); @@ -2001,6 +2002,7 @@ exec_command_gset(PsqlScanState scan_state, bool active_branch) { pg_log_error("\\%s not allowed in pipeline mode", "gset"); clean_extended_state(); + free(prefix); return PSQL_CMD_ERROR; } @@ -2802,10 +2804,12 @@ exec_command_restrict(PsqlScanState scan_state, bool active_branch, if (opt == NULL || opt[0] == '\0') { pg_log_error("\\%s: missing required argument", cmd); + free(opt); return PSQL_CMD_ERROR; } restrict_key = pstrdup(opt); + free(opt); restricted = true; } else @@ -3210,22 +3214,26 @@ exec_command_unrestrict(PsqlScanState scan_state, bool active_branch, if (opt == NULL || opt[0] == '\0') { pg_log_error("\\%s: missing required argument", cmd); + free(opt); return PSQL_CMD_ERROR; } if (!restricted) { pg_log_error("\\%s: not currently in restricted mode", cmd); + free(opt); return PSQL_CMD_ERROR; } else if (strcmp(opt, restrict_key) == 0) { pfree(restrict_key); restricted = false; + free(opt); } else { pg_log_error("\\%s: wrong key", cmd); + free(opt); return PSQL_CMD_ERROR; } } From b6b1f89847f7bece7fab2ef392d3c84a7ee6f88d Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 19 Aug 2026 08:46:54 +0200 Subject: [PATCH 409/481] Message style fixes --- src/backend/commands/analyze.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..597f1f16dc6 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -242,7 +242,7 @@ analyze_rel(Oid relid, RangeVar *relation, if (!ok) { ereport(WARNING, - errmsg("skipping \"%s\" -- cannot analyze this foreign table.", + errmsg("skipping \"%s\" --- cannot analyze this foreign table", RelationGetRelationName(onerel))); relation_close(onerel, ShareUpdateExclusiveLock); goto out; From ca86b45adddc5385c50e974a0905b7938eb10487 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 19 Aug 2026 08:56:56 +0200 Subject: [PATCH 410/481] Message wording fix --- src/backend/parser/parse_utilcmd.c | 2 +- src/test/regress/expected/partition_split.out | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index a17fe73cc35..5d90c6692c5 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -4111,7 +4111,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, if (list_length(partcmd->partlist) < 2) ereport(ERROR, errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("list of new partitions should contain at least two partitions")); + errmsg("list of new partitions must contain at least two partitions")); transformPartitionCmdForSplit(&cxt, partcmd); newcmds = lappend(newcmds, cmd); diff --git a/src/test/regress/expected/partition_split.out b/src/test/regress/expected/partition_split.out index 8e245563801..089f89ed6ac 100644 --- a/src/test/regress/expected/partition_split.out +++ b/src/test/regress/expected/partition_split.out @@ -47,7 +47,7 @@ DETAIL: Specified lower bound ('03-01-2022') is greater than or equal to upper -- ERROR ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-10-01')); -ERROR: list of new partitions should contain at least two partitions +ERROR: list of new partitions must contain at least two partitions -- ERROR ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO (PARTITION sales_feb2022 FOR VALUES FROM ('2022-01-01') TO ('2022-03-01'), @@ -1528,7 +1528,7 @@ ERROR: partition of hash-partitioned table cannot be split -- ERROR ALTER TABLE t SPLIT PARTITION tp1 INTO (PARTITION tp1_1 FOR VALUES WITH (MODULUS 4, REMAINDER 0)); -ERROR: list of new partitions should contain at least two partitions +ERROR: list of new partitions must contain at least two partitions DROP TABLE t; -- Test for split partition properties: -- * STATISTICS is empty From 18a15b9673809c6b4848575aa14aaa8e0e5c7a33 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Wed, 19 Aug 2026 16:06:05 +0900 Subject: [PATCH 411/481] Don't free fast-path FK metadata from the inval callback Commit e484b0eea6 made InvalidateConstraintCacheCallBack() pfree an entry's FastPathMeta to plug a leak, but that breaks the rule stated atop the callback: entries may have active references at invalidation time, so we mark them invalid rather than removing them. The metadata is subject to the same rule. ri_FastPathCheck() and ri_FastPathBatchFlush() copy riinfo->fpmeta into a local, and ri_FastPathFlushArray() additionally takes FmgrInfo pointers into it before its "walk all matches" loop. That loop runs index_getnext_slot(), ri_LockPKTuple(), and user-supplied cast and equality functions, any of which can accept invalidation messages, and a user function that performs DDL triggers one deliberately, no concurrency required. The callback then freed the object still in use, so the loop read freed memory and called through FmgrInfos in it. Fix by unlinking the metadata from the entry, so the next check rebuilds it as before, but deferring the actual free to AtEOXact_RI(), which runs from CommitTransaction() / PrepareTransaction() / AbortTransaction() with no RI check on the stack. Detached objects are chained through a new next_dead field and released there. The queue holds a few kB per detached object until the transaction ends, which only affects transactions that interleave DDL with FK-checking DML. That seems clearly preferable to a use-after-free. Unlinking alone is not enough for the multi-column path. ri_FastPathFlushLoop() calls build_index_scankeys() once per buffered row, and that function re-read riinfo->fpmeta each time. A cast invoked for one row can accept an invalidation that clears the field, so the next row found NULL there. Pass the metadata down from ri_FastPathBatchFlush() instead, as the array path already did, so one reference covers the whole batch. That is only safe because of the deferred release above; latching without it would turn the NULL dereference into a use-after-free. Reported-by: Jacob Brazeal (offlist) Reported-by: Brian Carpenter | Deep Fork Cyber Reported-by: Anh Khoa (offlist) Reported-by: Ayush Tiwari Reviewed-by: Ayush Tiwari Discussion: https://postgr.es/m/CA+HiwqFFB6vzx8v3t2=rbNYyxMistLf5kkJfqzJ81nadFyLrxA@mail.gmail.com Discussion: https://postgr.es/m/CAJTYsWUFBZNs_UN5MAAK7vG4_DEmv0FiT8552CWuOcggDUki2g@mail.gmail.com Backpatch-through: 19 --- src/backend/utils/adt/ri_triggers.c | 89 +++++++++++++++++++---- src/test/regress/expected/foreign_key.out | 64 ++++++++++++++++ src/test/regress/sql/foreign_key.sql | 56 ++++++++++++++ 3 files changed, 195 insertions(+), 14 deletions(-) diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index d51e9dd3b23..bf0c8c1542f 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -160,6 +160,9 @@ typedef struct FastPathMeta Oid subtypes[RI_MAX_NUMKEYS]; int strats[RI_MAX_NUMKEYS]; AttrNumber index_attnos[RI_MAX_NUMKEYS]; /* index column positions */ + + /* Link in ri_fpmeta_dead_list while awaiting deferred release */ + struct FastPathMeta *next_dead; } FastPathMeta; /* @@ -272,6 +275,14 @@ static HTAB *ri_fastpath_cache = NULL; static bool ri_fastpath_callback_registered = false; static bool ri_fastpath_flushing = false; +/* + * FastPathMeta objects detached from their cache entry by invalidation, but + * possibly still referenced by an RI check further up the stack. Released + * by AtEOXact_RI(), where no such reference can exist. See + * InvalidateConstraintCacheCallBack(). + */ +static FastPathMeta *ri_fpmeta_dead_list = NULL; + /* * Local function prototypes */ @@ -326,10 +337,12 @@ static void ri_FastPathBatchAdd(RI_ConstraintInfo *riinfo, static void ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel, RI_ConstraintInfo *riinfo); static int ri_FastPathFlushArray(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, - const RI_ConstraintInfo *riinfo, Relation fk_rel, + const RI_ConstraintInfo *riinfo, + FastPathMeta *fpmeta, Relation fk_rel, Snapshot snapshot, IndexScanDesc scandesc); static int ri_FastPathFlushLoop(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, - const RI_ConstraintInfo *riinfo, Relation fk_rel, + const RI_ConstraintInfo *riinfo, + FastPathMeta *fpmeta, Relation fk_rel, Snapshot snapshot, IndexScanDesc scandesc); static bool ri_FastPathProbeOne(Relation pk_rel, Relation idx_rel, IndexScanDesc scandesc, TupleTableSlot *slot, @@ -342,6 +355,7 @@ static void ri_CheckPermissions(Relation query_rel); static bool recheck_matched_pk_tuple(Relation idxrel, ScanKeyData *skeys, int nkeys, TupleTableSlot *new_slot); static void build_index_scankeys(const RI_ConstraintInfo *riinfo, + FastPathMeta *fpmeta, Relation idx_rel, Datum *pk_vals, char *pk_nulls, ScanKey skeys); static void ri_populate_fastpath_metadata(RI_ConstraintInfo *riinfo, @@ -2561,6 +2575,10 @@ get_ri_constraint_root(Oid constrOid) * from the cache, but only mark them invalid, which is harmless to active * uses. (Any query using an entry should hold a lock sufficient to keep that * data from changing under it --- but we may get cache flushes anyway.) + * + * The fast-path metadata hanging off an entry is subject to the same rule. + * We unlink it so that the next check rebuilds it, but the object itself is + * only queued here and is actually released by AtEOXact_RI(). */ static void InvalidateConstraintCacheCallBack(Datum arg, SysCacheIdentifier cacheid, @@ -2594,11 +2612,25 @@ InvalidateConstraintCacheCallBack(Datum arg, SysCacheIdentifier cacheid, riinfo->rootHashValue == hashvalue) { riinfo->valid = false; + + /* + * Detach any fast-path metadata so that the next check + * repopulates it, but do not free it here. ri_FastPathCheck() + * and the flush routines copy riinfo->fpmeta into a local (and + * take FmgrInfo pointers into it) and then run index scans, tuple + * locking, and user-supplied cast and equality functions, all of + * which can accept invalidation messages and reach this callback. + * Freeing now would leave those callers reading freed memory. + * Queue it instead; AtEOXact_RI() releases it once no RI check + * can be running. + */ if (riinfo->fpmeta) { - pfree(riinfo->fpmeta); + riinfo->fpmeta->next_dead = ri_fpmeta_dead_list; + ri_fpmeta_dead_list = riinfo->fpmeta; riinfo->fpmeta = NULL; } + /* Remove invalidated entries from the list, too */ dclist_delete_from(&ri_constraint_cache_valid_list, iter.cur); } @@ -2862,7 +2894,8 @@ ri_FastPathCheck(RI_ConstraintInfo *riinfo, } Assert(riinfo->fpmeta); ri_ExtractValues(fk_rel, newslot, riinfo, false, pk_vals, pk_nulls); - build_index_scankeys(riinfo, idx_rel, pk_vals, pk_nulls, skey); + build_index_scankeys(riinfo, riinfo->fpmeta, idx_rel, pk_vals, pk_nulls, + skey); found = ri_FastPathProbeOne(pk_rel, idx_rel, scandesc, slot, snapshot, riinfo, skey, riinfo->nkeys); SetUserIdAndSecContext(saved_userid, saved_sec_context); @@ -2954,6 +2987,7 @@ ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel, Oid saved_userid; int saved_sec_context; MemoryContext oldcxt; + FastPathMeta *fpmeta; int violation_index; if (fpentry->batch_count == 0) @@ -3011,6 +3045,15 @@ ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel, } Assert(riinfo->fpmeta); + /* + * Take our own reference to the metadata for the duration of the flush. + * The probe below runs user-defined cast and equality functions, which + * can accept invalidation messages; InvalidateConstraintCacheCallBack() + * then clears riinfo->fpmeta, so re-reading it partway through the batch + * would find NULL. The object itself stays valid until AtEOXact_RI(). + */ + fpmeta = riinfo->fpmeta; + /* * The probe runs user-defined cast and equality functions. Set the * flushing flag around it so a re-entrant ri_FastPathBatchAdd on this @@ -3024,10 +3067,12 @@ ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel, /* Skip array overhead for single-row batches. */ if (riinfo->nkeys == 1 && fpentry->batch_count > 1) violation_index = ri_FastPathFlushArray(fpentry, fk_slot, riinfo, - fk_rel, snapshot, scandesc); + fpmeta, fk_rel, snapshot, + scandesc); else violation_index = ri_FastPathFlushLoop(fpentry, fk_slot, riinfo, - fk_rel, snapshot, scandesc); + fpmeta, fk_rel, snapshot, + scandesc); } PG_FINALLY(); { @@ -3065,8 +3110,9 @@ ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel, */ static int ri_FastPathFlushLoop(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, - const RI_ConstraintInfo *riinfo, Relation fk_rel, - Snapshot snapshot, IndexScanDesc scandesc) + const RI_ConstraintInfo *riinfo, FastPathMeta *fpmeta, + Relation fk_rel, Snapshot snapshot, + IndexScanDesc scandesc) { Relation pk_rel = fpentry->pk_rel; Relation idx_rel = fpentry->idx_rel; @@ -3080,7 +3126,7 @@ ri_FastPathFlushLoop(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, { ExecStoreHeapTuple(fpentry->batch[i], fk_slot, false); ri_ExtractValues(fk_rel, fk_slot, riinfo, false, pk_vals, pk_nulls); - build_index_scankeys(riinfo, idx_rel, pk_vals, pk_nulls, skey); + build_index_scankeys(riinfo, fpmeta, idx_rel, pk_vals, pk_nulls, skey); found = ri_FastPathProbeOne(pk_rel, idx_rel, scandesc, pk_slot, snapshot, riinfo, skey, riinfo->nkeys); @@ -3109,10 +3155,10 @@ ri_FastPathFlushLoop(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, */ static int ri_FastPathFlushArray(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, - const RI_ConstraintInfo *riinfo, Relation fk_rel, - Snapshot snapshot, IndexScanDesc scandesc) + const RI_ConstraintInfo *riinfo, FastPathMeta *fpmeta, + Relation fk_rel, Snapshot snapshot, + IndexScanDesc scandesc) { - FastPathMeta *fpmeta = riinfo->fpmeta; Relation pk_rel = fpentry->pk_rel; Relation idx_rel = fpentry->idx_rel; TupleTableSlot *pk_slot = fpentry->pk_slot; @@ -3496,11 +3542,10 @@ recheck_matched_pk_tuple(Relation idxrel, ScanKeyData *skeys, int nkeys, */ static void build_index_scankeys(const RI_ConstraintInfo *riinfo, + FastPathMeta *fpmeta, Relation idx_rel, Datum *pk_vals, char *pk_nulls, ScanKey skeys) { - FastPathMeta *fpmeta = riinfo->fpmeta; - Assert(fpmeta); /* @@ -3553,8 +3598,10 @@ ri_populate_fastpath_metadata(RI_ConstraintInfo *riinfo, MemoryContext oldcxt = MemoryContextSwitchTo(TopMemoryContext); Assert(riinfo != NULL && riinfo->valid); + Assert(riinfo->fpmeta == NULL); fpmeta = palloc_object(FastPathMeta); + fpmeta->next_dead = NULL; for (int i = 0; i < riinfo->nkeys; i++) { Oid eq_opr = riinfo->pf_eq_oprs[i]; @@ -4368,6 +4415,20 @@ AtEOXact_RI(bool isCommit) * set. */ ri_fastpath_flushing = false; + + /* + * Release fast-path metadata detached during this transaction by + * InvalidateConstraintCacheCallBack(). We are past every RI check that + * could still hold a pointer into one of these, so freeing here is safe + * on both the commit and the abort path. + */ + while (ri_fpmeta_dead_list != NULL) + { + FastPathMeta *dead = ri_fpmeta_dead_list; + + ri_fpmeta_dead_list = dead->next_dead; + pfree(dead); + } } /* diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out index 120d3319451..b699164260a 100644 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@ -3846,3 +3846,67 @@ DETAIL: Key (a)=(999) is not present in table "fp_subxact_pk". DROP TRIGGER fp_subxact_trg ON fp_subxact_fk; DROP FUNCTION fp_abort_subxact(); DROP TABLE fp_subxact_fk, fp_subxact_pk; +-- +-- Cache invalidation arriving in the middle of a fast-path batch flush. +-- +-- A cross-type foreign key runs the user's cast function once per key per +-- buffered row, inside ri_FastPathFlushLoop(). A cast that performs DDL +-- raises an invalidation there, which detaches the constraint's fast-path +-- metadata while the flush is still using it. +-- +CREATE TYPE fkint; +CREATE FUNCTION fkint_in(cstring) RETURNS fkint + AS 'int4in' LANGUAGE internal IMMUTABLE STRICT; +NOTICE: return type fkint is only a shell +CREATE FUNCTION fkint_out(fkint) RETURNS cstring + AS 'int4out' LANGUAGE internal IMMUTABLE STRICT; +NOTICE: argument type fkint is only a shell +LINE 1: CREATE FUNCTION fkint_out(fkint) RETURNS cstring + ^ +CREATE TYPE fkint (INPUT = fkint_in, OUTPUT = fkint_out, LIKE = int4); +-- Renames the constraint the first time it is called, and so raises an +-- invalidation partway through the flush. Guarded on the catalog so the +-- second and later calls are no-ops. +CREATE FUNCTION fkint_to_int4(fkint) RETURNS int4 AS $$ +BEGIN + IF EXISTS (SELECT 1 FROM pg_constraint + WHERE conrelid = 'fktable_inval'::regclass + AND conname = 'fktable_inval_fk') THEN + EXECUTE 'ALTER TABLE fktable_inval' + ' RENAME CONSTRAINT fktable_inval_fk TO fktable_inval_fk2'; + END IF; + RETURN format('%s', $1)::int4; +END $$ LANGUAGE plpgsql; +CREATE CAST (fkint AS int4) WITH FUNCTION fkint_to_int4(fkint) AS IMPLICIT; +CREATE TABLE pktable_inval (a int4, b int4, PRIMARY KEY (a, b)); +INSERT INTO pktable_inval VALUES (1, 1), (2, 2); +-- Multi-column FK, so the flush takes the per-row loop rather than the +-- array path; cross-type on column a, so the cast above is invoked. +CREATE TABLE fktable_inval (a fkint, b int4, + CONSTRAINT fktable_inval_fk FOREIGN KEY (a, b) + REFERENCES pktable_inval (a, b)); +-- More than one row, so the flush is still running after the invalidation. +INSERT INTO fktable_inval VALUES ('1', 1), ('2', 2); +-- Confirms the cast actually ran and raised the invalidation. Without this +-- the insert above could pass merely by not exercising the path at all. +SELECT conname FROM pg_constraint + WHERE conrelid = 'fktable_inval'::regclass AND contype = 'f'; + conname +------------------- + fktable_inval_fk2 +(1 row) + +SELECT count(*) FROM fktable_inval; + count +------- + 2 +(1 row) + +DROP TABLE fktable_inval; +DROP TABLE pktable_inval; +DROP CAST (fkint AS int4); +DROP FUNCTION fkint_to_int4(fkint); +DROP TYPE fkint CASCADE; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to function fkint_in(cstring) +drop cascades to function fkint_out(fkint) diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql index b9b88064ea5..31736251d78 100644 --- a/src/test/regress/sql/foreign_key.sql +++ b/src/test/regress/sql/foreign_key.sql @@ -2801,3 +2801,59 @@ INSERT INTO fp_subxact_fk VALUES (999, 'bad'), (0, 'boom'), (1, 'ok'); DROP TRIGGER fp_subxact_trg ON fp_subxact_fk; DROP FUNCTION fp_abort_subxact(); DROP TABLE fp_subxact_fk, fp_subxact_pk; + +-- +-- Cache invalidation arriving in the middle of a fast-path batch flush. +-- +-- A cross-type foreign key runs the user's cast function once per key per +-- buffered row, inside ri_FastPathFlushLoop(). A cast that performs DDL +-- raises an invalidation there, which detaches the constraint's fast-path +-- metadata while the flush is still using it. +-- +CREATE TYPE fkint; +CREATE FUNCTION fkint_in(cstring) RETURNS fkint + AS 'int4in' LANGUAGE internal IMMUTABLE STRICT; +CREATE FUNCTION fkint_out(fkint) RETURNS cstring + AS 'int4out' LANGUAGE internal IMMUTABLE STRICT; +CREATE TYPE fkint (INPUT = fkint_in, OUTPUT = fkint_out, LIKE = int4); + +-- Renames the constraint the first time it is called, and so raises an +-- invalidation partway through the flush. Guarded on the catalog so the +-- second and later calls are no-ops. +CREATE FUNCTION fkint_to_int4(fkint) RETURNS int4 AS $$ +BEGIN + IF EXISTS (SELECT 1 FROM pg_constraint + WHERE conrelid = 'fktable_inval'::regclass + AND conname = 'fktable_inval_fk') THEN + EXECUTE 'ALTER TABLE fktable_inval' + ' RENAME CONSTRAINT fktable_inval_fk TO fktable_inval_fk2'; + END IF; + RETURN format('%s', $1)::int4; +END $$ LANGUAGE plpgsql; + +CREATE CAST (fkint AS int4) WITH FUNCTION fkint_to_int4(fkint) AS IMPLICIT; + +CREATE TABLE pktable_inval (a int4, b int4, PRIMARY KEY (a, b)); +INSERT INTO pktable_inval VALUES (1, 1), (2, 2); + +-- Multi-column FK, so the flush takes the per-row loop rather than the +-- array path; cross-type on column a, so the cast above is invoked. +CREATE TABLE fktable_inval (a fkint, b int4, + CONSTRAINT fktable_inval_fk FOREIGN KEY (a, b) + REFERENCES pktable_inval (a, b)); + +-- More than one row, so the flush is still running after the invalidation. +INSERT INTO fktable_inval VALUES ('1', 1), ('2', 2); + +-- Confirms the cast actually ran and raised the invalidation. Without this +-- the insert above could pass merely by not exercising the path at all. +SELECT conname FROM pg_constraint + WHERE conrelid = 'fktable_inval'::regclass AND contype = 'f'; + +SELECT count(*) FROM fktable_inval; + +DROP TABLE fktable_inval; +DROP TABLE pktable_inval; +DROP CAST (fkint AS int4); +DROP FUNCTION fkint_to_int4(fkint); +DROP TYPE fkint CASCADE; From abca12838fefabbf146307447c23176ec7eb67ed Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Wed, 19 Aug 2026 16:10:18 +0900 Subject: [PATCH 412/481] Give RI fast-path cached FmgrInfos their own memory context ri_populate_fastpath_metadata() copies the cast and equality FmgrInfos into the cached FastPathMeta with fn_mcxt set to TopMemoryContext, the context active at the copy. fn_mcxt is scratch space for the called function: record_eq(), and the record I/O functions generally, allocate their per-call cache there and keep a pointer to it in fn_extra. Because that scratch is in TopMemoryContext, it outlives the metadata. When the metadata is discarded on invalidation, whatever the cast and equality functions cached is left behind, with nothing pointing at it. Each subsequent repopulation allocates afresh, so a session that repeatedly invalidates a foreign key constraint grows TopMemoryContext without bound. Give the metadata its own context for the FmgrInfos' fn_mcxt and delete it along with the metadata, so the cached scratch is freed with the FmgrInfos that point at it. Since the preceding commit defers release of the metadata to AtEOXact_RI(), the context is deleted there rather than in InvalidateConstraintCacheCallBack(). The context deliberately is not reset while the metadata is in use. fn_extra points into fn_mcxt, so resetting it would leave those pointers dangling; the next call would find fn_extra non-NULL and read freed memory. fmgr_info_copy() zeroing fn_extra in the copy is the same invariant seen from the other side. Nothing accumulates in the context during use in any case: record_eq() and friends allocate only when fn_extra is NULL and reuse the cache afterwards. Reported-by: Noah Misch Reviewed-by: Ayush Tiwari Discussion: https://postgr.es/m/20260705210533.ee.noahmisch@microsoft.com Discussion: https://postgr.es/m/CA+HiwqFFB6vzx8v3t2=rbNYyxMistLf5kkJfqzJ81nadFyLrxA@mail.gmail.com Backpatch-through: 19 --- src/backend/utils/adt/ri_triggers.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index bf0c8c1542f..f76eb37731e 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -161,6 +161,18 @@ typedef struct FastPathMeta int strats[RI_MAX_NUMKEYS]; AttrNumber index_attnos[RI_MAX_NUMKEYS]; /* index column positions */ + /* + * fn_mcxt for the cached FmgrInfos above. Cast and equality functions + * (e.g. record_eq()) use fn_mcxt as scratch space, caching state there + * and keeping a pointer to it in FmgrInfo.fn_extra. Give them a context + * of their own, created with this struct and destroyed with it in + * AtEOXact_RI(). + * + * Note this context must not be reset while the FmgrInfos remain in use, + * since that would free the state fn_extra still points at. + */ + MemoryContext scratch_cxt; + /* Link in ri_fpmeta_dead_list while awaiting deferred release */ struct FastPathMeta *next_dead; } FastPathMeta; @@ -3602,6 +3614,11 @@ ri_populate_fastpath_metadata(RI_ConstraintInfo *riinfo, fpmeta = palloc_object(FastPathMeta); fpmeta->next_dead = NULL; + + /* Scratch context for the cached FmgrInfos' fn_mcxt; see FastPathMeta. */ + fpmeta->scratch_cxt = AllocSetContextCreate(TopMemoryContext, + "RI fast-path finfo scratch", + ALLOCSET_SMALL_SIZES); for (int i = 0; i < riinfo->nkeys; i++) { Oid eq_opr = riinfo->pf_eq_oprs[i]; @@ -3627,9 +3644,9 @@ ri_populate_fastpath_metadata(RI_ConstraintInfo *riinfo, fpmeta->index_attnos[i] = idx_col + 1; fmgr_info_copy(&fpmeta->cast_func_finfo[i], &entry->cast_func_finfo, - CurrentMemoryContext); + fpmeta->scratch_cxt); fmgr_info_copy(&fpmeta->eq_opr_finfo[i], &entry->eq_opr_finfo, - CurrentMemoryContext); + fpmeta->scratch_cxt); fpmeta->regops[i] = get_opcode(eq_opr); get_op_opfamily_properties(eq_opr, @@ -4427,6 +4444,7 @@ AtEOXact_RI(bool isCommit) FastPathMeta *dead = ri_fpmeta_dead_list; ri_fpmeta_dead_list = dead->next_dead; + MemoryContextDelete(dead->scratch_cxt); pfree(dead); } } From 9bb8e16bd53e2c8a822bf13832c4dcb3905a34e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Wed, 19 Aug 2026 12:25:06 +0200 Subject: [PATCH 413/481] Tighten ACL check in repack_is_permitted_for_relation() repack_is_permitted_for_relation() uses pg_class_aclcheck_ext() to silently skip a concurrently-dropped relation. That's wrong for a caller that may already hold a lock on the relation whose ACL is checked, where missing a relation is not fine, and it makes the single-relation REPACK and CLUSTER cases more brittle. So only detect a missing relation where that's expected, following the fix for vacuum_is_permitted_for_relation() in commit 824d5f6241ea. The new already_locked behavior is limited to get_tables_to_repack() and get_tables_to_repack_partitioned(). All other callers of repack_is_permitted_for_relation() hold a lock on the relation that prevents it from being concurrently dropped, so this commit also adds an assertion to that effect. While at it, update the comment in RangeVarCallbackMaintainsTable to also mention REPACK. Author: Bharath Rupireddy Backpatch-through: 19 Discussion: https://www.postgresql.org/message-id/CALj2ACX3pyuRS8%2B%2B6L20cJUMRTf_qbbVp69J1btJ3y6%3D77e5gw%40mail.gmail.com --- src/backend/commands/repack.c | 35 ++++++++++++++++++++++---------- src/backend/commands/tablecmds.c | 2 +- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index edff54e734e..477c86b2ba6 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -173,7 +173,8 @@ static List *get_tables_to_repack_partitioned(RepackStmt *stmt, Relation rel, MemoryContext permcxt); static bool repack_is_permitted_for_relation(RepackCommand cmd, - Oid relid, Oid userid); + Oid relid, Oid userid, + bool already_locked); static void apply_concurrent_changes(BufFile *file, ChangeContext *chgcxt); static void apply_concurrent_insert(Relation rel, TupleTableSlot *slot, @@ -681,7 +682,7 @@ cluster_rel_recheck(RepackCommand cmd, Relation OldHeap, Oid indexOid, Assert(CheckRelationLockedByMe(OldHeap, lmode, false)); /* Check that the user still has privileges for the relation */ - if (!repack_is_permitted_for_relation(cmd, tableOid, userid)) + if (!repack_is_permitted_for_relation(cmd, tableOid, userid, true)) { relation_close(OldHeap, lmode); return false; @@ -2155,7 +2156,7 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt) /* noisily skip rels which the user can't process */ if (!repack_is_permitted_for_relation(cmd, index->indrelid, - GetUserId())) + GetUserId(), false)) continue; /* Use a permanent memory context for the result list */ @@ -2192,7 +2193,7 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt) /* noisily skip rels which the user can't process */ if (!repack_is_permitted_for_relation(cmd, class->oid, - GetUserId())) + GetUserId(), false)) continue; /* Use a permanent memory context for the result list */ @@ -2321,7 +2322,7 @@ get_tables_to_repack_partitioned(RepackStmt *stmt, Relation rel, * if so. */ if (!repack_is_permitted_for_relation(stmt->command, table_oid, - GetUserId())) + GetUserId(), false)) continue; /* Use a permanent memory context for the result list */ @@ -2341,26 +2342,38 @@ get_tables_to_repack_partitioned(RepackStmt *stmt, Relation rel, /* - * Return whether userid has privileges to execute REPACK on relid. + * Return whether userid has privileges to execute REPACK/CLUSTER on relid. * - * Caller may not have a lock on the relation, so it could have been - * dropped concurrently. In that case, silently return false. + * The relation may already be locked by caller, in which case it cannot + * possibly go missing; otherwise it may have been removed recently. If + * it's been removed, silently return false. If the relation exists but + * the user doesn't have the required privs, emit a WARNING and return false. * - * If the relation does exist but the user doesn't have the required - * privs, emit a WARNING and return false. Otherwise, return true. + * Otherwise the relation exists and user has required perms, so return true. */ static bool -repack_is_permitted_for_relation(RepackCommand cmd, Oid relid, Oid userid) +repack_is_permitted_for_relation(RepackCommand cmd, Oid relid, Oid userid, + bool already_locked) { bool is_missing = false; AclResult result; char *relname; Assert(cmd == REPACK_COMMAND_CLUSTER || cmd == REPACK_COMMAND_REPACK); + Assert(!already_locked || + CheckRelationOidLockedByMe(relid, AccessShareLock, true)); result = pg_class_aclcheck_ext(relid, userid, ACL_MAINTAIN, &is_missing); + + /* + * If the relation was concurrently dropped, nothing to do. This is only + * reachable when the caller doesn't already have a lock on the relation. + */ if (is_missing) + { + Assert(!already_locked); return false; + } if (result == ACLCHECK_OK) return true; diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 1f2411a33a8..c7fde625279 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -20187,7 +20187,7 @@ AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, * the relation to be locked only if (1) it's a plain or partitioned table, * materialized view, or TOAST table and (2) the current user is the owner (or * the superuser) or has been granted MAINTAIN. This meets the - * permission-checking needs of CLUSTER, REINDEX TABLE, and REFRESH + * permission-checking needs of CLUSTER, REPACK, REINDEX TABLE, and REFRESH * MATERIALIZED VIEW; we expose it here so that it can be used by all. */ void From 6ee9a8b398c0e5024568bc9333b0f5458287a0c1 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Wed, 19 Aug 2026 12:31:07 -0400 Subject: [PATCH 414/481] Fix GIN VACUUM posting tree root split bug. ginVacuumPostingTreeLeaves swaps a shared buffer lock for an exclusive one when it encounters a leaf page. It neglected to re-verify whether a page that was initially a leaf root page became an internal page due to a concurrent root page split (during the window when no lock was held). It was therefore possible for GIN VACUUM to spuriously treat an internal page as a leaf page, leading to data corruption. VACUUM could miss dead TIDs that it was required to remove, leaving behind dangling references in the index. To fix, re-verify that a leaf page is still a leaf page after an exclusive lock is acquired. If it isn't, drop our exclusive lock and acquire a shared lock so that the non-leaf root page gets processed in the usual way. Oversight in commit fd83c83d, which fixed a deadlock bug in GIN posting tree vacuuming. Author: Peter Geoghegan Reviewed-by: Andrey Borodin Discussion: https://postgr.es/m/CAH2-Wz=RBpJTQgvOxr6C=J04dExmFSt1E3F-r+cRTQ56hEotkg@mail.gmail.com Backpatch-through: 14 --- src/backend/access/gin/ginvacuum.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index 040f21a92e3..292b26cbfd5 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -399,6 +399,16 @@ ginVacuumPostingTreeLeaves(GinVacuumState *gvs, BlockNumber blkno) { LockBuffer(buffer, GIN_UNLOCK); LockBuffer(buffer, GIN_EXCLUSIVE); + + if (!GinPageIsLeaf(page)) + { + /* + * The root page was a leaf page, but became an internal page + * while no lock was held. Unlock and reacquire a share lock. + */ + UnlockReleaseBuffer(buffer); + continue; + } break; } From adf440cbe69920b0475ffca118041de4a8e369ca Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Wed, 19 Aug 2026 13:46:44 -0400 Subject: [PATCH 415/481] Fix GIN multiple-VACUUM-scans pending list bug. ginbulkdelete performs pending list cleanup before it searches the entry tree (and any posting trees) for dead TIDs. This is necessary to avoid leaving behind dangling TID references that index vacuuming is required to remove; nothing prevents recently inserted pending list tuples from containing TIDs that VACUUM already considers dead. However, ginbulkdelete neglected to perform pending list cleanup on VACUUM's second or subsequent call. It was therefore possible for a VACUUM that requires multiple rounds of index vacuuming to leave behind dangling references. To fix, teach ginbulkdelete to perform pending list cleanup during every call. In passing, tweak some related comments in the pending list cleanup path to make it clear why it's safe for VACUUM to not _fully_ empty an index's pending list. This was arguably an oversight in commit e2c79e14, which fixed a similar issue where pending list cleanup by VACUUM could end early, but missed this closely related problem. Author: Peter Geoghegan Reviewed-by: Andrey Borodin Discussion: https://postgr.es/m/CAH2-Wzmsa-RPA2Ko8A5LaGOnmbpimJ--71xkiBqwgjk3Fq8YEg@mail.gmail.com Backpatch-through: 14 --- src/backend/access/gin/ginfast.c | 15 +++++++++------ src/backend/access/gin/ginvacuum.c | 18 ++++++++++++------ src/include/access/gin_private.h | 2 +- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c index f50848eb65a..46fc60115a8 100644 --- a/src/backend/access/gin/ginfast.c +++ b/src/backend/access/gin/ginfast.c @@ -777,7 +777,7 @@ processPendingPage(BuildAccumulator *accum, KeyArray *ka, * If stats isn't null, we count deleted pending pages into the counts. */ void -ginInsertCleanup(GinState *ginstate, bool full_clean, +ginInsertCleanup(GinState *ginstate, bool must_empty_list, bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats) { @@ -808,7 +808,9 @@ ginInsertCleanup(GinState *ginstate, bool full_clean, { /* * We are called from [auto]vacuum/analyze or gin_clean_pending_list() - * and we would like to wait concurrent cleanup to finish. + * and we must wait for concurrent cleanup to finish. In particular, + * VACUUM must have the opportunity to remove any dead TIDs that are + * now in the pending list. */ LockPage(index, GIN_METAPAGE_BLKNO, ExclusiveLock); workMemory = @@ -880,11 +882,12 @@ ginInsertCleanup(GinState *ginstate, bool full_clean, /* * Are we walk through the page which as we remember was a tail when - * we start our cleanup? But if caller asks us to clean up whole - * pending list then ignore old tail, we will work until list becomes - * empty. + * we start our cleanup? But if caller asks us to fully empty the + * pending list (not just move all items that were in the list when + * blknoFinish was established) then ignore old tail and work until + * the list is fully empty. */ - if (blkno == blknoFinish && full_clean == false) + if (blkno == blknoFinish && !must_empty_list) cleanupFinish = true; /* diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index 292b26cbfd5..d69d59748b5 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -640,14 +640,20 @@ ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, { /* Yes, so initialize stats to zeroes */ stats = palloc0_object(IndexBulkDeleteResult); - - /* - * and cleanup any pending inserts - */ - ginInsertCleanup(&gvs.ginstate, !AmAutoVacuumWorkerProcess(), - false, true, stats); } + /* + * The pending list might have already-dead TIDs that VACUUM now requires + * us to remove from the index. We must force cleanup of the pending list + * now, before vacuuming proper begins, to make sure nothing is missed. + * + * When running in an autovacuum worker, we won't necessarily _fully_ + * empty the pending list. This is still safe; concurrent inserters + * cannot insert new tuples whose TIDs VACUUM needs us to remove. + */ + ginInsertCleanup(&gvs.ginstate, !AmAutoVacuumWorkerProcess(), + false, true, stats); + /* we'll re-count the tuples each time */ stats->num_index_tuples = 0; gvs.result = stats; diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index 6725ee2839f..3c5fd6ba817 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -468,7 +468,7 @@ extern void ginHeapTupleFastCollect(GinState *ginstate, GinTupleCollector *collector, OffsetNumber attnum, Datum value, bool isNull, ItemPointer ht_ctid); -extern void ginInsertCleanup(GinState *ginstate, bool full_clean, +extern void ginInsertCleanup(GinState *ginstate, bool must_empty_list, bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats); /* ginpostinglist.c */ From c684d98c3da783d37321649dd75df3f67ec98b99 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 19 Aug 2026 10:36:44 -0700 Subject: [PATCH 416/481] pg_locale.c, unicode_case.c: use size_t for iteration. Already done by e615da8cb21b in master. Backpatch these particular cases to make other backpatches in this area safer, and to be safe for callers in extensions that we don't know about. This applies to REL_19_STABLE and REL_18_STABLE only. Suggested-by: Andres Freund Reviewed-by: Andres Freund Discussion: https://postgr.es/m/v36ssaygf7grb3qzfsjhtdzi7kqd45ds56nyuf7gi5qjml4qbb@ezmfqzmhlrs2 --- src/backend/utils/adt/pg_locale.c | 6 +++--- src/backend/utils/adt/pg_locale_icu.c | 2 +- src/backend/utils/adt/pg_locale_libc.c | 2 +- src/common/unicode_case.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index cf77db77682..60e46a4fe02 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1270,7 +1270,7 @@ get_collation_actual_version(char collprovider, const char *collcollate) static size_t strlower_c(char *dst, size_t dstsize, const char *src, size_t srclen) { - int i; + size_t i; for (i = 0; i < srclen && i < dstsize; i++) dst[i] = pg_ascii_tolower(src[i]); @@ -1284,7 +1284,7 @@ static size_t strtitle_c(char *dst, size_t dstsize, const char *src, size_t srclen) { bool wasalnum = false; - int i; + size_t i; for (i = 0; i < srclen && i < dstsize; i++) { @@ -1308,7 +1308,7 @@ strtitle_c(char *dst, size_t dstsize, const char *src, size_t srclen) static size_t strupper_c(char *dst, size_t dstsize, const char *src, size_t srclen) { - int i; + size_t i; for (i = 0; i < srclen && i < dstsize; i++) dst[i] = pg_ascii_toupper(src[i]); diff --git a/src/backend/utils/adt/pg_locale_icu.c b/src/backend/utils/adt/pg_locale_icu.c index 5ba37a54f9c..0c8ddde630a 100644 --- a/src/backend/utils/adt/pg_locale_icu.c +++ b/src/backend/utils/adt/pg_locale_icu.c @@ -712,7 +712,7 @@ static size_t downcase_ident_icu(char *dst, size_t dstsize, const char *src, size_t srclen, pg_locale_t locale) { - int i; + size_t i; bool libc_lower; locale_t lt = locale->icu.lt; diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c index b50b3f24efd..d1f55e145f5 100644 --- a/src/backend/utils/adt/pg_locale_libc.c +++ b/src/backend/utils/adt/pg_locale_libc.c @@ -372,7 +372,7 @@ downcase_ident_libc_sb(char *dst, size_t dstsize, const char *src, size_t srclen, pg_locale_t locale) { locale_t loc = locale->lt; - int i; + size_t i; for (i = 0; i < srclen && i < dstsize; i++) { diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c index dd5b3ba86d0..744b9116b12 100644 --- a/src/common/unicode_case.c +++ b/src/common/unicode_case.c @@ -336,7 +336,7 @@ check_final_sigma(const unsigned char *str, size_t len, size_t offset) int ulen; /* iterate backwards looking for preceding character */ - for (int i = offset; i > 0;) + for (size_t i = offset; i > 0;) { /* skip backwards through continuation bytes */ i--; @@ -364,7 +364,7 @@ check_final_sigma(const unsigned char *str, size_t len, size_t offset) ulen = utf8_mblen((const unsigned char *) str + offset); /* iterate forward looking for following character */ - for (int i = offset + ulen; i < len;) + for (size_t i = offset + ulen; i < len;) { ulen = utf8_mblen((const unsigned char *) str + i); From 29f7881a5fdb6f0282a32bdb4fe7ef3c03e88a7f Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Wed, 19 Aug 2026 15:45:54 -0400 Subject: [PATCH 417/481] GiST: Invalidate killed items consistently. GiST neglected to invalidate its killedItems[] array on a rescan. As a result, it was just about possible for the wrong tuples from the wrong index page to be LP_DEAD-marked on a rescan. The scan mistakenly believed that the previous rescan's killedItems[] were for this rescan's curBlkno, causing index corruption. To fix, bring GiST in line with nbtree and hash: call gistkillitems from both gistrescan and gistendscan (the existing gistgettuple caller still handles the common case where we need to LP_DEAD-mark before moving on to the next page). That way the scan's pending killedItems[] are passed to gistkillitems while they still describe items from curBlkno. When gistkillitems runs, it'll invalidate the array in passing (and won't needlessly miss out on an opportunity to LP_DEAD-mark eligible index tuples). Back branches just get minimal hardening: we invalidate killedItems[] at the places where the master branch gets new calls to gistkillitems (and we invalidate curBlkno and curPageLSN on a rescan). The test that proved corruption on master didn't result in corruption on any stable branch, though only because, without commit 9c9ddf109, we'd clobber curPageLSN without also updating curBlkno -- which accidentally prevented it. Relying on gistkillitems to not LP_DEAD-mark by passing it a curBlkno whose curPageLSN was taken from an entirely different page seems like a very bad idea, which is why this issue is being treated as a bug affecting all stable branches. Author: Peter Geoghegan Reviewed-By: Andrey Borodin Discussion: https://postgr.es/m/CAH2-WzmwEThnQf17Ju+t0N9_KJLsEQSXzYrFnaS2=s4KnGGrqw@mail.gmail.com Backpatch-through: 14 --- src/backend/access/gist/gistget.c | 4 ++++ src/backend/access/gist/gistscan.c | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index 4d7c100d737..917fb31de37 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -432,7 +432,10 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, * killed tuple as not passing the qual. */ if (scan->ignore_killed_tuples && ItemIdIsDead(iid)) + { + Assert(GistPageIsLeaf(page)); continue; + } it = (IndexTuple) PageGetItem(page, iid); @@ -731,6 +734,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir) CHECK_FOR_INTERRUPTS(); /* save current item BlockNumber for next gistkillitems() call */ + Assert(so->numKilled == 0); so->curBlkno = item->blkno; /* diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index c65f93abdae..826d5ae299d 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -133,7 +133,12 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, int i; MemoryContext oldCxt; + /* invalidate any killed items still pending */ + so->numKilled = 0; + /* rescan an existing indexscan --- reset state */ + so->curBlkno = InvalidBlockNumber; + so->curPageLSN = InvalidXLogRecPtr; /* * The first time through, we create the search queue in the scanCxt. @@ -349,6 +354,9 @@ gistendscan(IndexScanDesc scan) { GISTScanOpaque so = (GISTScanOpaque) scan->opaque; + /* invalidate any killed items still pending */ + so->numKilled = 0; + /* * freeGISTstate is enough to clean up everything made by gistbeginscan, * as well as the queueCxt if there is a separate context for it. From 2a2076da14077518cd01b19fff7ac6251871e9dd Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Thu, 20 Aug 2026 09:38:27 +0900 Subject: [PATCH 418/481] Reject too many arguments in CREATE TRIGGER The number of trigger arguments is stored as a smallint, but there was no check that the number of arguments fits with the catalog data type. This could result in an invalid negative value being stored once one defined more than INT16_MAX arguments, with an overflowed value stored in the catalogs. Looking at other catalogs that store a number of arguments, we have similar protections already in place (aggregates, functions, etc.). Reported-by: Xingwang Xiang Author: Kyotaro Horiguchi Discussion: https://postgr.es/m/19627-5b72a57e332e2b3f@postgresql.org Backpatch-through: 14 --- src/backend/commands/trigger.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 8444332d44f..d1542035fd7 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -885,9 +885,16 @@ CreateTriggerFiringOn(const CreateTrigStmt *stmt, const char *queryString, { ListCell *le; char *args; - int16 nargs = list_length(stmt->args); + int nargs = list_length(stmt->args); int len = 0; + Assert(nargs >= 0); + if (nargs > PG_INT16_MAX) + ereport(ERROR, + errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg("triggers cannot have more than %d arguments", + PG_INT16_MAX)); + foreach(le, stmt->args) { char *ar = strVal(lfirst(le)); From f3a52a229adeb9c54e5b656b45af609b967874d6 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Thu, 20 Aug 2026 14:02:57 +0900 Subject: [PATCH 419/481] Restore after-trigger firing context at subtransaction end AfterTriggerEndQuery(), AfterTriggerFireDeferred(), and AfterTriggerSetState() bracket their firing loops with firing_depth++/--. The decrement runs after the loop and is not protected by PG_FINALLY, so an error caught by a subtransaction (e.g. a PL/pgSQL EXCEPTION block) leaves firing_depth too high. Separately, AfterTriggerEndSubXact() unconditionally cleared firing_batch_callbacks, even if the subtransaction began while an outer batch-callback loop was active. firing_depth feeds AfterTriggerIsActive(), which the RI fast path uses to decide whether an FK check is running inside trigger firing and may batch. A stranded firing_depth makes AfterTriggerIsActive() wrongly report firing as active afterwards. This is reachable and results in silent data corruption: after a caught FK-check error, an ALTER TABLE ... ADD FOREIGN KEY whose validation runs per-row (RI_Initial_Check() having bailed, e.g. because RLS is enabled on the referenced table) calls RI_FKey_check() with AfterTriggerIsActive() wrongly true. The check is routed into the batched fast path, but a utility command has no AfterTriggerEndQuery() to fire the flush callback. The violating row is not reported, the constraint is marked validated, and the cached PK relation and index leak. Save firing_depth and firing_batch_callbacks at subtransaction start and restore them in AfterTriggerEndSubXact(), next to the existing query_depth handling. Restoring, rather than zeroing or clearing, is required because a subtransaction can begin and end while an outer query is firing, where firing_depth is legitimately positive and firing_batch_callbacks may be legitimately set. Reported-by: Noah Misch Discussion: https://postgr.es/m/20260705222115.be.noahmisch@microsoft.com Backpatch-through: 19 --- src/backend/commands/trigger.c | 29 ++++++++++++++-- src/test/regress/expected/foreign_key.out | 41 +++++++++++++++++++++++ src/test/regress/sql/foreign_key.sql | 40 ++++++++++++++++++++++ 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index d1542035fd7..f1914aac4c6 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -3933,6 +3933,8 @@ struct AfterTriggersTransData SetConstraintState state; /* saved S C state, or NULL if not yet saved */ AfterTriggerEventList events; /* saved list pointer */ int query_depth; /* saved query_depth */ + int firing_depth; /* saved firing_depth */ + bool firing_batch_callbacks; /* saved firing_batch_callbacks */ CommandId firing_counter; /* saved firing_counter */ }; @@ -5504,6 +5506,9 @@ AfterTriggerBeginSubXact(void) afterTriggers.trans_stack[my_level].state = NULL; afterTriggers.trans_stack[my_level].events = afterTriggers.events; afterTriggers.trans_stack[my_level].query_depth = afterTriggers.query_depth; + afterTriggers.trans_stack[my_level].firing_depth = afterTriggers.firing_depth; + afterTriggers.trans_stack[my_level].firing_batch_callbacks = + afterTriggers.firing_batch_callbacks; afterTriggers.trans_stack[my_level].firing_counter = afterTriggers.firing_counter; } @@ -5604,8 +5609,28 @@ AfterTriggerEndSubXact(bool isCommit) } } - /* Reset in case a callback threw an error while firing. */ - afterTriggers.firing_batch_callbacks = false; + /* + * Restore firing_depth and firing_batch_callbacks to their values at + * subtransaction start. The matching decrement of firing_depth in + * AfterTriggerEndQuery()/AfterTriggerFireDeferred(), and the clearing of + * firing_batch_callbacks in FireAfterTriggerBatchCallbacks(), run after + * their loops and are not protected by PG_FINALLY. A trigger or batch + * callback error caught by this subtransaction can therefore leave either + * one set; restoring the saved values unwinds only this subtransaction's + * firing. + * + * Restoring (rather than zeroing/clearing) matters because a + * subtransaction can begin and end while an outer query's triggers are + * firing -- for instance a batch callback whose user-supplied cast or + * equality function runs DML in a BEGIN ... EXCEPTION block. There + * firing_depth is positive and firing_batch_callbacks is true; forcing + * them to 0/false would corrupt the outer firing + * (FireAfterTriggerBatchCallbacks() asserts firing_depth > 0, and + * clearing the guard would defeat its re-entrancy check). + */ + afterTriggers.firing_depth = afterTriggers.trans_stack[my_level].firing_depth; + afterTriggers.firing_batch_callbacks = + afterTriggers.trans_stack[my_level].firing_batch_callbacks; } /* diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out index b699164260a..01343c58e11 100644 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@ -3910,3 +3910,44 @@ DROP TYPE fkint CASCADE; NOTICE: drop cascades to 2 other objects DETAIL: drop cascades to function fkint_in(cstring) drop cascades to function fkint_out(fkint) +-- Stranded firing state must not misroute ALTER TABLE ... ADD FOREIGN KEY +-- validation into the batched fast path. A caught FK-check error inside a +-- subtransaction leaves firing_depth set (its decrement is skipped); a +-- following ALTER whose validation runs per-row (forced here by RLS on the +-- referenced table, so RI_Initial_Check() bails) would then be wrongly treated +-- as running inside trigger firing, batched, and never flushed (a utility +-- command has no AfterTriggerEndQuery), silently validating a violating row. +CREATE ROLE regress_fpav_role; +CREATE TABLE fpav_pk (id int PRIMARY KEY); +INSERT INTO fpav_pk VALUES (1); +ALTER TABLE fpav_pk ENABLE ROW LEVEL SECURITY; +CREATE POLICY fpav_pk_all ON fpav_pk FOR ALL USING (true) WITH CHECK (true); +GRANT REFERENCES, SELECT ON fpav_pk TO regress_fpav_role; +CREATE TABLE fpav_fk (a int); +INSERT INTO fpav_fk VALUES (1), (99); +ALTER TABLE fpav_fk OWNER TO regress_fpav_role; +CREATE TABLE fpav_cv_pk (id int PRIMARY KEY); +INSERT INTO fpav_cv_pk VALUES (1); +CREATE TABLE fpav_cv_fk (a int REFERENCES fpav_cv_pk(id)); +GRANT INSERT ON fpav_cv_fk TO regress_fpav_role; +GRANT SELECT, INSERT ON fpav_cv_pk TO regress_fpav_role; +SET ROLE regress_fpav_role; +BEGIN; +-- Caught FK violation: leaves firing_depth set if it is not restored. +DO $$ +BEGIN + BEGIN + INSERT INTO fpav_cv_fk VALUES (999); + EXCEPTION WHEN foreign_key_violation THEN + NULL; + END; +END$$; +-- Must ERROR on the violating row (99), not silently validate it. +ALTER TABLE fpav_fk ADD CONSTRAINT fpav_fk_fkey + FOREIGN KEY (a) REFERENCES fpav_pk (id); +ERROR: insert or update on table "fpav_fk" violates foreign key constraint "fpav_fk_fkey" +DETAIL: Key (a)=(99) is not present in table "fpav_pk". +ROLLBACK; +RESET ROLE; +DROP TABLE fpav_fk, fpav_pk, fpav_cv_fk, fpav_cv_pk; +DROP ROLE regress_fpav_role; diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql index 31736251d78..987cea61ba2 100644 --- a/src/test/regress/sql/foreign_key.sql +++ b/src/test/regress/sql/foreign_key.sql @@ -2857,3 +2857,43 @@ DROP TABLE pktable_inval; DROP CAST (fkint AS int4); DROP FUNCTION fkint_to_int4(fkint); DROP TYPE fkint CASCADE; + +-- Stranded firing state must not misroute ALTER TABLE ... ADD FOREIGN KEY +-- validation into the batched fast path. A caught FK-check error inside a +-- subtransaction leaves firing_depth set (its decrement is skipped); a +-- following ALTER whose validation runs per-row (forced here by RLS on the +-- referenced table, so RI_Initial_Check() bails) would then be wrongly treated +-- as running inside trigger firing, batched, and never flushed (a utility +-- command has no AfterTriggerEndQuery), silently validating a violating row. +CREATE ROLE regress_fpav_role; +CREATE TABLE fpav_pk (id int PRIMARY KEY); +INSERT INTO fpav_pk VALUES (1); +ALTER TABLE fpav_pk ENABLE ROW LEVEL SECURITY; +CREATE POLICY fpav_pk_all ON fpav_pk FOR ALL USING (true) WITH CHECK (true); +GRANT REFERENCES, SELECT ON fpav_pk TO regress_fpav_role; +CREATE TABLE fpav_fk (a int); +INSERT INTO fpav_fk VALUES (1), (99); +ALTER TABLE fpav_fk OWNER TO regress_fpav_role; +CREATE TABLE fpav_cv_pk (id int PRIMARY KEY); +INSERT INTO fpav_cv_pk VALUES (1); +CREATE TABLE fpav_cv_fk (a int REFERENCES fpav_cv_pk(id)); +GRANT INSERT ON fpav_cv_fk TO regress_fpav_role; +GRANT SELECT, INSERT ON fpav_cv_pk TO regress_fpav_role; +SET ROLE regress_fpav_role; +BEGIN; +-- Caught FK violation: leaves firing_depth set if it is not restored. +DO $$ +BEGIN + BEGIN + INSERT INTO fpav_cv_fk VALUES (999); + EXCEPTION WHEN foreign_key_violation THEN + NULL; + END; +END$$; +-- Must ERROR on the violating row (99), not silently validate it. +ALTER TABLE fpav_fk ADD CONSTRAINT fpav_fk_fkey + FOREIGN KEY (a) REFERENCES fpav_pk (id); +ROLLBACK; +RESET ROLE; +DROP TABLE fpav_fk, fpav_pk, fpav_cv_fk, fpav_cv_pk; +DROP ROLE regress_fpav_role; From 3861984342d85898a674fa0c7c93019317bfcff7 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Thu, 20 Aug 2026 15:17:29 +0900 Subject: [PATCH 420/481] Fix postmaster failing to exit when startup crashes during crash restart Commit 9b43e6793b0f removed the PM_STARTUP shortcut that exited the postmaster directly when the startup process died, routing the case through HandleChildCrash() so that children processes running during PM_STARTUP are cleaned up rather than orphaned. However, HandleChildCrash() does nothing if FatalError is already set, and that is exactly the case while reinitializing after a crash: a relaunched startup process that dies before WAL redo starts would leave the state machine stuck at PM_STARTUP, preventing the postmaster to shut down. This issue is fixed by restoring the pre-9b43e6793b0f shortcut behavior: if FatalError is set when the startup process crashes, signal the remaining children and move to PM_NO_CHILDREN, so as the postmaster can properly exit with nothing orphaned. This is only reachable in v18 and newer versions, the early return of HandleChildCrash() on FatalError being introduced in f0b7ab725139. This issue has been reported on Windows, for a postmaster with its console gone. A trick to make InitPostmasterChild() fail aggressively was equally able to stuck a postmaster. Reported-by: Kuan-Ting Kuo Author: Zexin Li Discussion: https://postgr.es/m/19623-f9bd331940be1273@postgresql.org Backpatch-through: 18 --- src/backend/postmaster/postmaster.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 90c7c4528e8..c5b141ed3e3 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -432,6 +432,7 @@ static void process_pm_shutdown_request(void); static void dummy_handler(SIGNAL_ARGS); static void CleanupBackend(PMChild *bp, int exitstatus); static void HandleChildCrash(int pid, int exitstatus, const char *procname); +static void HandleFatalError(QuitSignalReason reason, bool consider_sigabrt); static void LogChildExit(int lev, const char *procname, int pid, int exitstatus); static void PostmasterStateMachine(void); @@ -2333,8 +2334,25 @@ process_pm_child_exit(void) } else StartupStatus = STARTUP_CRASHED; - HandleChildCrash(pid, exitstatus, - _("startup process")); + + /* + * If FatalError is already set, we are reinitializing after a + * previous crash, and HandleChildCrash() would do nothing, + * leaving the state machine stuck at PM_STARTUP. Give up, + * signal the remaining children and head for PM_NO_CHILDREN, + * where STARTUP_CRASHED makes us exit. + */ + if (StartupStatus == STARTUP_CRASHED && + FatalError && Shutdown != ImmediateShutdown) + { + LogChildExit(LOG, _("startup process"), pid, exitstatus); + ereport(LOG, + (errmsg("aborting startup due to startup process failure"))); + HandleFatalError(PMQUIT_FOR_CRASH, true); + } + else + HandleChildCrash(pid, exitstatus, + _("startup process")); continue; } @@ -2725,15 +2743,13 @@ CleanupBackend(PMChild *bp, * happened. Commonly the caller will have logged the reason for entering * FatalError state. * - * This should only be called when not already in FatalError or - * ImmediateShutdown state. + * This should only be called when not already in ImmediateShutdown state. */ static void HandleFatalError(QuitSignalReason reason, bool consider_sigabrt) { int sigtosend; - Assert(!FatalError); Assert(Shutdown != ImmediateShutdown); SetQuitSignalReason(reason); From 28f9c5b5777bcb27de2e63a5feb41ec82d225992 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 20 Aug 2026 08:53:57 +0200 Subject: [PATCH 421/481] Unify error messages and some small style improvements --- src/backend/commands/explain_state.c | 6 +++--- src/backend/commands/subscriptioncmds.c | 5 +++-- src/backend/commands/wait.c | 6 +++--- src/test/regress/expected/subscription.out | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/backend/commands/explain_state.c b/src/backend/commands/explain_state.c index a0ee0a664be..816f2797d7a 100644 --- a/src/backend/commands/explain_state.c +++ b/src/backend/commands/explain_state.c @@ -424,7 +424,7 @@ GUCCheckExplainExtensionOption(const char *option_name, } /* Unrecognized option name. */ - GUC_check_errmsg("unrecognized EXPLAIN option \"%s\"", option_name); + GUC_check_errmsg("unrecognized %s option \"%s\"", "EXPLAIN", option_name); return false; } @@ -489,8 +489,8 @@ GUCCheckBooleanExplainOption(const char *option_name, if (!valid) { - GUC_check_errmsg("EXPLAIN option \"%s\" requires a Boolean value", - option_name); + GUC_check_errmsg("%s option \"%s\" requires a Boolean value", + "EXPLAIN", option_name); return false; } diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index bbbe5ddc921..cff86dd57ab 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -360,7 +360,7 @@ parse_subscription_options(ParseState *pstate, List *stmt_options, if (opts->maxretention < 0) ereport(ERROR, errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("max_retention_duration cannot be negative")); + errmsg("option \"%s\" cannot be negative", "max_retention_duration")); } else if (IsSet(supported_opts, SUBOPT_ORIGIN) && strcmp(defel->defname, "origin") == 0) @@ -1895,7 +1895,8 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, if (logicalrep_workers_find(subid, true, true)) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("cannot alter retain_dead_tuples when logical replication worker is still running"), + errmsg("cannot alter option \"%s\" when logical replication worker is still running", + "retain_dead_tuples"), errhint("Try again after some time."))); /* diff --git a/src/backend/commands/wait.c b/src/backend/commands/wait.c index 40a6ffde16b..9ba4c75021e 100644 --- a/src/backend/commands/wait.c +++ b/src/backend/commands/wait.c @@ -302,21 +302,21 @@ ExecWaitStmt(ParseState *pstate, WaitStmt *stmt, bool isTopLevel, ereport(ERROR, errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("recovery is not in progress"), - errhint("Waiting for the standby_replay LSN can only be executed during recovery.")); + errhint("Waiting for the %s LSN can only be executed during recovery.", "standby_replay")); break; case WAIT_LSN_TYPE_STANDBY_WRITE: ereport(ERROR, errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("recovery is not in progress"), - errhint("Waiting for the standby_write LSN can only be executed during recovery.")); + errhint("Waiting for the %s LSN can only be executed during recovery.", "standby_write")); break; case WAIT_LSN_TYPE_STANDBY_FLUSH: ereport(ERROR, errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("recovery is not in progress"), - errhint("Waiting for the standby_flush LSN can only be executed during recovery.")); + errhint("Waiting for the %s LSN can only be executed during recovery.", "standby_flush")); break; default: diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index 7163b756787..9cf1aac7272 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -560,7 +560,7 @@ CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUB ERROR: max_retention_duration requires an integer value -- fail - max_retention_duration must be non-negative CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, max_retention_duration = -1); -ERROR: max_retention_duration cannot be negative +ERROR: option "max_retention_duration" cannot be negative -- ok CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, max_retention_duration = 1000); NOTICE: max_retention_duration is ineffective when retain_dead_tuples is disabled @@ -575,7 +575,7 @@ HINT: To initiate replication, you must manually create the replication slot, e -- fail - max_retention_duration must be non-negative ALTER SUBSCRIPTION regress_testsub SET (max_retention_duration = -1); -ERROR: max_retention_duration cannot be negative +ERROR: option "max_retention_duration" cannot be negative -- ok ALTER SUBSCRIPTION regress_testsub SET (max_retention_duration = 0); \dRs+ From d2a710c7e9e08e101694fe6c1f6789f18f9d3dcf Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Thu, 20 Aug 2026 17:12:53 +0900 Subject: [PATCH 422/481] Track RI fast-path FK-check batches per firing cycle Commit 34a30786293 fixed an RI fast-path crash under nested C-level SPI by keeping batch-callback lists per after-trigger query depth. That fix was incomplete: the RI fast path still tracked callback registration with one global flag. Once an outer firing cycle had registered its callback, the flag suppressed registration for a nested cycle, leaving the nested batch to be handled by the outer callback, too late and with the wrong snapshot, potentially after the ResourceOwner holding its relations had gone away. Nor is per-depth callback registration sufficient while the cache is keyed only by constraint OID. If nested firing checks the same constraint, it reuses the outer entry, combining rows that must be checked in separate firing cycles. Key the cache by both constraint OID and query depth. Register a callback for each depth that creates an entry, and make ri_FastPathEndBatch() flush and release only entries belonging to the ending depth. Add AfterTriggerCurrentQueryDepth() so ri_triggers.c can obtain the current depth; depth -1 represents deferred firing. Add regression coverage for nested firing through a cursor portal, whose resources must not outlive the nested cycle, nested firing of the same constraint at different query depths, and deferred firing at query depth -1. Reported-by: Noah Misch Reported-by: Peter Geoghegan Discussion: https://postgr.es/m/20260705222115.be.noahmisch@microsoft.com Discussion: https://postgr.es/m/CAH2-Wz=D533JbF_ak_Pc8kP0FKse-ju8DnMxtjvY==yHsP4xgw@mail.gmail.com Backpatch-through: 19 --- src/backend/commands/trigger.c | 14 +++ src/backend/utils/adt/ri_triggers.c | 106 +++++++++++++++++----- src/include/commands/trigger.h | 1 + src/test/regress/expected/foreign_key.out | 92 +++++++++++++++++++ src/test/regress/sql/foreign_key.sql | 78 ++++++++++++++++ src/tools/pgindent/typedefs.list | 1 + 6 files changed, 269 insertions(+), 23 deletions(-) diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index f1914aac4c6..911045b9b9d 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -6951,3 +6951,17 @@ AfterTriggerIsActive(void) { return afterTriggers.firing_depth > 0; } + +/* + * AfterTriggerCurrentQueryDepth + * Return the current after-trigger query nesting depth. + * + * Lets a batch-callback registrant (e.g. the RI fast path) associate cached + * state with the firing cycle that created it, so a nested cycle's callback + * acts only on its own entries. Returns -1 outside any query level. + */ +int +AfterTriggerCurrentQueryDepth(void) +{ + return afterTriggers.query_depth; +} diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index f76eb37731e..5a209673b61 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -231,13 +231,27 @@ typedef struct RI_CompareHashEntry */ #define RI_FASTPATH_BATCH_SIZE 64 +/* + * RI_FastPathKey + * Hash key for an RI_FastPathEntry. + * + * A constraint can be checked in nested trigger-firing cycles. Each cycle + * must have a separate entry so that its rows are checked with that cycle's + * snapshot and its resources are released by that cycle's callback. + */ +typedef struct RI_FastPathKey +{ + Oid conoid; /* pg_constraint OID */ + int query_depth; /* after-trigger query depth */ +} RI_FastPathKey; + /* * RI_FastPathEntry - * Per-constraint cache of resources needed by ri_FastPathBatchFlush(). + * Per-constraint, per-firing-cycle cache of resources needed by + * ri_FastPathBatchFlush(). * - * One entry per constraint, keyed by pg_constraint OID. Created lazily - * by ri_FastPathGetEntry() on first use within a trigger-firing batch - * and torn down by ri_FastPathTeardown() at batch end. + * Created lazily by ri_FastPathGetEntry() on first use within a + * trigger-firing batch and torn down by ri_FastPathTeardown() at batch end. * * FK tuples are buffered in batch[] across trigger invocations and * flushed when the buffer fills or the batch ends. @@ -251,7 +265,7 @@ typedef struct RI_CompareHashEntry */ typedef struct RI_FastPathEntry { - Oid conoid; /* hash key: pg_constraint OID */ + RI_FastPathKey key; /* hash key */ Oid fk_relid; /* for ri_FastPathEndBatch() */ Relation pk_rel; Relation idx_rel; @@ -284,7 +298,6 @@ static HTAB *ri_compare_cache = NULL; static dclist_head ri_constraint_cache_valid_list; static HTAB *ri_fastpath_cache = NULL; -static bool ri_fastpath_callback_registered = false; static bool ri_fastpath_flushing = false; /* @@ -382,7 +395,7 @@ pg_noreturn static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, static RI_FastPathEntry *ri_FastPathGetEntry(const RI_ConstraintInfo *riinfo, Relation fk_rel); static void ri_FastPathEndBatch(void *arg); -static void ri_FastPathTeardown(void); +static void ri_FastPathTeardown(int depth); /* @@ -4302,6 +4315,7 @@ ri_FastPathEndBatch(void *arg) { HASH_SEQ_STATUS status; RI_FastPathEntry *entry; + int my_depth = (int) (intptr_t) arg; if (ri_fastpath_cache == NULL) return; @@ -4326,10 +4340,13 @@ ri_FastPathEndBatch(void *arg) hash_seq_init(&status, ri_fastpath_cache); while ((entry = hash_seq_search(&status)) != NULL) { - if (entry->batch_count > 0) + /* Flush only entries created in the cycle now ending. */ + if (entry->key.query_depth == my_depth && entry->batch_count > 0) { Relation fk_rel = table_open(entry->fk_relid, AccessShareLock); - RI_ConstraintInfo *riinfo = ri_LoadConstraintInfo(entry->conoid); + RI_ConstraintInfo *riinfo; + + riinfo = ri_LoadConstraintInfo(entry->key.conoid); ri_FastPathBatchFlush(entry, fk_rel, riinfo); table_close(fk_rel, NoLock); @@ -4342,17 +4359,26 @@ ri_FastPathEndBatch(void *arg) } PG_END_TRY(); - ri_FastPathTeardown(); + /* + * Release this cycle's entries and remove them from the cache; leave + * outer cycles' entries for their own callbacks. Destroy the cache once + * empty. + */ + ri_FastPathTeardown(my_depth); } /* * ri_FastPathTeardown - * Tear down all cached fast-path state. + * Release and remove the cached entries of one firing cycle, and drop + * the cache once it holds no more entries. * - * Called from ri_FastPathEndBatch() after flushing any remaining rows. + * Called from ri_FastPathEndBatch() with the depth of the cycle that is + * ending: it releases only that cycle's entries, leaving an outer cycle's + * still-live entries for their own callbacks. The cache (and its static + * pointer) go away once the last entry is removed. */ static void -ri_FastPathTeardown(void) +ri_FastPathTeardown(int depth) { HASH_SEQ_STATUS status; RI_FastPathEntry *entry; @@ -4363,6 +4389,8 @@ ri_FastPathTeardown(void) hash_seq_init(&status, ri_fastpath_cache); while ((entry = hash_seq_search(&status)) != NULL) { + if (entry->key.query_depth != depth) + continue; if (entry->idx_rel) index_close(entry->idx_rel, NoLock); if (entry->pk_rel) @@ -4373,11 +4401,15 @@ ri_FastPathTeardown(void) ExecDropSingleTupleTableSlot(entry->fk_slot); if (entry->flush_cxt) MemoryContextDelete(entry->flush_cxt); + hash_search(ri_fastpath_cache, &entry->key, HASH_REMOVE, NULL); } - hash_destroy(ri_fastpath_cache); - ri_fastpath_cache = NULL; - ri_fastpath_callback_registered = false; + if (hash_get_num_entries(ri_fastpath_cache) == 0) + { + hash_destroy(ri_fastpath_cache); + ri_fastpath_cache = NULL; + ri_fastpath_flushing = false; + } } /* @@ -4423,7 +4455,6 @@ AtEOXact_RI(bool isCommit) * memory-context reset; here we only drop the references to it. */ ri_fastpath_cache = NULL; - ri_fastpath_callback_registered = false; /* * Also clear the in-flush flag. ri_FastPathEndBatch() already clears it @@ -4462,15 +4493,20 @@ AtEOXact_RI(bool isCommit) static RI_FastPathEntry * ri_FastPathGetEntry(const RI_ConstraintInfo *riinfo, Relation fk_rel) { + RI_FastPathKey key; RI_FastPathEntry *entry; bool found; + int cur_depth = AfterTriggerCurrentQueryDepth(); + + key.conoid = riinfo->constraint_id; + key.query_depth = cur_depth; /* Create hash table on first use in this batch */ if (ri_fastpath_cache == NULL) { HASHCTL ctl; - ctl.keysize = sizeof(Oid); + ctl.keysize = sizeof(RI_FastPathKey); ctl.entrysize = sizeof(RI_FastPathEntry); ctl.hcxt = TopTransactionContext; ri_fastpath_cache = hash_create("RI fast-path cache", @@ -4479,7 +4515,7 @@ ri_FastPathGetEntry(const RI_ConstraintInfo *riinfo, Relation fk_rel) HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); } - entry = hash_search(ri_fastpath_cache, &riinfo->constraint_id, + entry = hash_search(ri_fastpath_cache, &key, HASH_ENTER, &found); if (!found) @@ -4536,11 +4572,35 @@ ri_FastPathGetEntry(const RI_ConstraintInfo *riinfo, Relation fk_rel) ALLOCSET_SMALL_SIZES); MemoryContextSwitchTo(oldcxt); - /* Ensure cleanup at end of this trigger-firing batch */ - if (!ri_fastpath_callback_registered) + /* + * Register an end-of-batch callback once per firing cycle, passing + * the query depth so the callback flushes only entries belonging to + * that cycle. + */ { - RegisterAfterTriggerBatchCallback(ri_FastPathEndBatch, NULL); - ri_fastpath_callback_registered = true; + bool depth_registered = false; + HASH_SEQ_STATUS reg_status; + RI_FastPathEntry *other; + + /* + * An existing entry at this depth means its callback is already + * registered. Ignore the just-created entry, which is already in + * the hash. + */ + hash_seq_init(®_status, ri_fastpath_cache); + while ((other = hash_seq_search(®_status)) != NULL) + { + if (other != entry && other->key.query_depth == cur_depth) + { + depth_registered = true; + hash_seq_term(®_status); + break; + } + } + + if (!depth_registered) + RegisterAfterTriggerBatchCallback(ri_FastPathEndBatch, + (void *) (intptr_t) cur_depth); } entry->flushing = false; diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h index 0c3d485abf4..1f268f87957 100644 --- a/src/include/commands/trigger.h +++ b/src/include/commands/trigger.h @@ -309,6 +309,7 @@ typedef void (*AfterTriggerBatchCallback) (void *arg); extern void RegisterAfterTriggerBatchCallback(AfterTriggerBatchCallback callback, void *arg); extern bool AfterTriggerIsActive(void); +extern int AfterTriggerCurrentQueryDepth(void); extern void AtEOXact_RI(bool isCommit); diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out index 01343c58e11..126c251bbda 100644 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@ -3951,3 +3951,95 @@ ROLLBACK; RESET ROLE; DROP TABLE fpav_fk, fpav_pk, fpav_cv_fk, fpav_cv_pk; DROP ROLE regress_fpav_role; +-- An AFTER trigger runs a query of its own, and that query inserts into a +-- second table with a fast-path foreign key. The entry the nested INSERT +-- creates belongs to the cursor's portal, which is gone by the time the +-- entry is torn down at the end of the outer statement. Every key stored +-- below is present in its referenced table, so the INSERT must just succeed. +CREATE TABLE fp_customer (id int PRIMARY KEY); +INSERT INTO fp_customer VALUES (1); +CREATE TABLE fp_product (id int PRIMARY KEY); +INSERT INTO fp_product SELECT generate_series(1, 4); +CREATE TABLE fp_kit_component (kit_product_id int, component_product_id int); +INSERT INTO fp_kit_component VALUES (1, 2), (1, 3), (1, 4); +CREATE TABLE fp_order (id int, customer_id int REFERENCES fp_customer, + product_id int); +CREATE TABLE fp_order_item (order_id int, product_id int + REFERENCES fp_product); +CREATE FUNCTION fp_add_order_item(order_id int, product_id int) RETURNS int + LANGUAGE plpgsql AS $$ +BEGIN + INSERT INTO fp_order_item VALUES (order_id, product_id); + RETURN product_id; +END$$; +CREATE FUNCTION fp_expand_kit() RETURNS trigger LANGUAGE plpgsql AS $$ +DECLARE + component_id int; + ncomponents int := 0; +BEGIN + FOR component_id IN + SELECT fp_add_order_item(NEW.id, component_product_id) + FROM fp_kit_component WHERE kit_product_id = NEW.product_id + LOOP + ncomponents := ncomponents + 1; + END LOOP; + RAISE NOTICE 'order % expanded into % order items', NEW.id, ncomponents; + RETURN NULL; +END$$; +CREATE TRIGGER fp_expand_kit_trg AFTER INSERT ON fp_order + FOR EACH ROW EXECUTE FUNCTION fp_expand_kit(); +INSERT INTO fp_order VALUES (1, 1, 1); +NOTICE: order 1 expanded into 3 order items +SELECT count(*) FROM fp_order_item; + count +------- + 3 +(1 row) + +DROP TABLE fp_order, fp_order_item, fp_kit_component, fp_product, fp_customer; +DROP FUNCTION fp_expand_kit(), fp_add_order_item(int, int); +-- Nested firing of the same constraint must use an entry for its own query +-- depth. The RAISE is reached if the nested violation remains buffered for +-- the outer cycle's callback. +CREATE TABLE fp_depth_pk (id int PRIMARY KEY); +INSERT INTO fp_depth_pk VALUES (1); +CREATE TABLE fp_depth_fk (a int REFERENCES fp_depth_pk); +CREATE FUNCTION fp_depth_reentry() RETURNS trigger LANGUAGE plpgsql AS $$ +BEGIN + IF NEW.a = 1 THEN + INSERT INTO fp_depth_fk VALUES (999); + RAISE EXCEPTION 'nested FK check was not flushed'; + END IF; + RETURN NEW; +END$$; +-- Sort after the RI trigger, so the outer row has already been batched. +CREATE TRIGGER zz_fp_depth_reentry AFTER INSERT ON fp_depth_fk + FOR EACH ROW EXECUTE FUNCTION fp_depth_reentry(); +INSERT INTO fp_depth_fk VALUES (1); +ERROR: insert or update on table "fp_depth_fk" violates foreign key constraint "fp_depth_fk_a_fkey" +DETAIL: Key (a)=(999) is not present in table "fp_depth_pk". +CONTEXT: SQL statement "INSERT INTO fp_depth_fk VALUES (999)" +PL/pgSQL function fp_depth_reentry() line 4 at SQL statement +SELECT * FROM fp_depth_fk; + a +--- +(0 rows) + +DROP TABLE fp_depth_fk, fp_depth_pk; +DROP FUNCTION fp_depth_reentry(); +-- Deferred FK check fires at commit (query depth -1); its batch must still get +-- a callback registered and flushed. +CREATE TABLE fp_deferred_pk (id int PRIMARY KEY); +CREATE TABLE fp_deferred_fk (a int REFERENCES fp_deferred_pk (id) + DEFERRABLE INITIALLY DEFERRED); +BEGIN; +INSERT INTO fp_deferred_fk VALUES (1); +INSERT INTO fp_deferred_pk VALUES (1); +COMMIT; +SELECT count(*) AS deferred_rows FROM fp_deferred_fk; -- 1, check passed at commit + deferred_rows +--------------- + 1 +(1 row) + +DROP TABLE fp_deferred_fk, fp_deferred_pk; diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql index 987cea61ba2..7319de6a280 100644 --- a/src/test/regress/sql/foreign_key.sql +++ b/src/test/regress/sql/foreign_key.sql @@ -2897,3 +2897,81 @@ ROLLBACK; RESET ROLE; DROP TABLE fpav_fk, fpav_pk, fpav_cv_fk, fpav_cv_pk; DROP ROLE regress_fpav_role; + +-- An AFTER trigger runs a query of its own, and that query inserts into a +-- second table with a fast-path foreign key. The entry the nested INSERT +-- creates belongs to the cursor's portal, which is gone by the time the +-- entry is torn down at the end of the outer statement. Every key stored +-- below is present in its referenced table, so the INSERT must just succeed. +CREATE TABLE fp_customer (id int PRIMARY KEY); +INSERT INTO fp_customer VALUES (1); +CREATE TABLE fp_product (id int PRIMARY KEY); +INSERT INTO fp_product SELECT generate_series(1, 4); +CREATE TABLE fp_kit_component (kit_product_id int, component_product_id int); +INSERT INTO fp_kit_component VALUES (1, 2), (1, 3), (1, 4); +CREATE TABLE fp_order (id int, customer_id int REFERENCES fp_customer, + product_id int); +CREATE TABLE fp_order_item (order_id int, product_id int + REFERENCES fp_product); +CREATE FUNCTION fp_add_order_item(order_id int, product_id int) RETURNS int + LANGUAGE plpgsql AS $$ +BEGIN + INSERT INTO fp_order_item VALUES (order_id, product_id); + RETURN product_id; +END$$; +CREATE FUNCTION fp_expand_kit() RETURNS trigger LANGUAGE plpgsql AS $$ +DECLARE + component_id int; + ncomponents int := 0; +BEGIN + FOR component_id IN + SELECT fp_add_order_item(NEW.id, component_product_id) + FROM fp_kit_component WHERE kit_product_id = NEW.product_id + LOOP + ncomponents := ncomponents + 1; + END LOOP; + RAISE NOTICE 'order % expanded into % order items', NEW.id, ncomponents; + RETURN NULL; +END$$; +CREATE TRIGGER fp_expand_kit_trg AFTER INSERT ON fp_order + FOR EACH ROW EXECUTE FUNCTION fp_expand_kit(); +INSERT INTO fp_order VALUES (1, 1, 1); +SELECT count(*) FROM fp_order_item; +DROP TABLE fp_order, fp_order_item, fp_kit_component, fp_product, fp_customer; +DROP FUNCTION fp_expand_kit(), fp_add_order_item(int, int); + +-- Nested firing of the same constraint must use an entry for its own query +-- depth. The RAISE is reached if the nested violation remains buffered for +-- the outer cycle's callback. +CREATE TABLE fp_depth_pk (id int PRIMARY KEY); +INSERT INTO fp_depth_pk VALUES (1); +CREATE TABLE fp_depth_fk (a int REFERENCES fp_depth_pk); +CREATE FUNCTION fp_depth_reentry() RETURNS trigger LANGUAGE plpgsql AS $$ +BEGIN + IF NEW.a = 1 THEN + INSERT INTO fp_depth_fk VALUES (999); + RAISE EXCEPTION 'nested FK check was not flushed'; + END IF; + RETURN NEW; +END$$; +-- Sort after the RI trigger, so the outer row has already been batched. +CREATE TRIGGER zz_fp_depth_reentry AFTER INSERT ON fp_depth_fk + FOR EACH ROW EXECUTE FUNCTION fp_depth_reentry(); + +INSERT INTO fp_depth_fk VALUES (1); +SELECT * FROM fp_depth_fk; + +DROP TABLE fp_depth_fk, fp_depth_pk; +DROP FUNCTION fp_depth_reentry(); + +-- Deferred FK check fires at commit (query depth -1); its batch must still get +-- a callback registered and flushed. +CREATE TABLE fp_deferred_pk (id int PRIMARY KEY); +CREATE TABLE fp_deferred_fk (a int REFERENCES fp_deferred_pk (id) + DEFERRABLE INITIALLY DEFERRED); +BEGIN; +INSERT INTO fp_deferred_fk VALUES (1); +INSERT INTO fp_deferred_pk VALUES (1); +COMMIT; +SELECT count(*) AS deferred_rows FROM fp_deferred_fk; -- 1, check passed at commit +DROP TABLE fp_deferred_fk, fp_deferred_pk; diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index f416ec0f475..23d4e6c0651 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -2521,6 +2521,7 @@ RI_CompareHashEntry RI_CompareKey RI_ConstraintInfo RI_FastPathEntry +RI_FastPathKey RI_QueryHashEntry RI_QueryKey RTEKind From d85a2590075fe652739a18be6f4bf0047a433218 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 20 Aug 2026 11:45:51 +0300 Subject: [PATCH 423/481] Skip bogus find_composite_type_dependencies() call on sequences A sequence has no rowtype. We called find_composite_type_dependencies() with InvalidOid, which is harmless but pointless. Skip it. This started to happen with commit 344d62fb9a97 in v15, which added the ALTER SEQUENCE ... SET LOGGED/UNLOGGED subcommand. Before that, sequences were never rewritten. While this is harmless, backpatch to keep the code the same on all branches, to make backpatching future patches a little easier. Backpatch-through: 15 --- src/backend/commands/tablecmds.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index c7fde625279..cad394b3540 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -5963,7 +5963,7 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode, * constraints, so it's not necessary/appropriate to enforce them just * during ALTER.) */ - if (tab->newvals != NIL || tab->rewrite > 0) + if (tab->newvals != NIL || (tab->rewrite > 0 && tab->relkind != RELKIND_SEQUENCE)) { Relation rel; @@ -7048,6 +7048,8 @@ find_composite_type_dependencies(Oid typeOid, Relation origRelation, SysScanDesc depScan; HeapTuple depTup; + Assert(OidIsValid(typeOid)); + /* since this function recurses, it could be driven to stack overflow */ check_stack_depth(); From 5e9d23f98cc1c5a7b4add5b843a564fe9c35c6b3 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Thu, 20 Aug 2026 09:24:50 -0700 Subject: [PATCH 424/481] Ensure all pg_locale.h APIs work with collate_is_c. Safer for callers, so that checking collate_is_c is only needed if the caller wants to optimize for that case. Backpatch to avoid creating a hazard for other backpatches in this area. Suggested-by: Andres Freund Suggested-by: Heikki Linnakangas Discussion: https://postgr.es/m/v36ssaygf7grb3qzfsjhtdzi7kqd45ds56nyuf7gi5qjml4qbb@ezmfqzmhlrs2 Backpatch-through: 18 --- src/backend/utils/adt/pg_locale.c | 55 +++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 60e46a4fe02..b6e6ee8928b 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1445,7 +1445,10 @@ pg_downcase_ident(char *dst, size_t dstsize, const char *src, size_t srclen) int pg_strcoll(const char *arg1, const char *arg2, pg_locale_t locale) { - return locale->collate->strcoll(arg1, arg2, locale); + if (locale->collate == NULL) + return strcmp(arg1, arg2); + else + return locale->collate->strcoll(arg1, arg2, locale); } /* @@ -1463,7 +1466,16 @@ int pg_strncoll(const char *arg1, size_t len1, const char *arg2, size_t len2, pg_locale_t locale) { - return locale->collate->strncoll(arg1, len1, arg2, len2, locale); + if (locale->collate == NULL) + { + int result = memcmp(arg1, arg2, Min(len1, len2)); + + if ((result == 0) && (len1 != len2)) + result = (len1 < len2) ? -1 : 1; + return result; + } + else + return locale->collate->strncoll(arg1, len1, arg2, len2, locale); } /* @@ -1473,6 +1485,9 @@ pg_strncoll(const char *arg1, size_t len1, const char *arg2, size_t len2, bool pg_strxfrm_enabled(pg_locale_t locale) { + if (locale->collate == NULL) + return true; + /* * locale->collate->strnxfrm is still a required method, even if it may * have the wrong behavior, because the planner uses it for estimates in @@ -1489,7 +1504,10 @@ pg_strxfrm_enabled(pg_locale_t locale) size_t pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale) { - return locale->collate->strxfrm(dest, destsize, src, locale); + if (locale->collate == NULL) + return pg_strnxfrm(dest, destsize, src, strlen(src), locale); + else + return locale->collate->strxfrm(dest, destsize, src, locale); } /* @@ -1514,6 +1532,16 @@ size_t pg_strnxfrm(char *dest, size_t destsize, const char *src, size_t srclen, pg_locale_t locale) { + if (locale->collate == NULL) + { + if (destsize > srclen) + { + memcpy(dest, src, srclen); + dest[srclen] = '\0'; + } + + return srclen; + } return locale->collate->strnxfrm(dest, destsize, src, srclen, locale); } @@ -1524,7 +1552,10 @@ pg_strnxfrm(char *dest, size_t destsize, const char *src, size_t srclen, bool pg_strxfrm_prefix_enabled(pg_locale_t locale) { - return (locale->collate->strnxfrm_prefix != NULL); + if (locale->collate == NULL) + return true; + else + return (locale->collate->strnxfrm_prefix != NULL); } /* @@ -1536,7 +1567,10 @@ size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize, pg_locale_t locale) { - return locale->collate->strxfrm_prefix(dest, destsize, src, locale); + if (locale->collate == NULL) + return pg_strnxfrm_prefix(dest, destsize, src, strlen(src), locale); + else + return locale->collate->strxfrm_prefix(dest, destsize, src, locale); } /* @@ -1560,7 +1594,16 @@ size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src, size_t srclen, pg_locale_t locale) { - return locale->collate->strnxfrm_prefix(dest, destsize, src, srclen, locale); + if (locale->collate == NULL) + { + size_t len = Min(srclen, destsize); + + if (destsize > 0) + memcpy(dest, src, len); + return len; + } + else + return locale->collate->strnxfrm_prefix(dest, destsize, src, srclen, locale); } /* From 3849ce5b3094f6d679a4c474f0654eba5187b14d Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Thu, 20 Aug 2026 13:54:45 -0700 Subject: [PATCH 425/481] hashtext: fix fragile code. Previously, in the path for non-deterministic collations, the code assumed that bsize==rsize. That assumption seems to be true for ICU, and all non-deterministic collations are ICU, so it's not known to be an actual bug. The only known place where bsize may not equal rsize is in the libc provider, where strxfrm() can return an upper bound of the size needed to store the result. That means the initial call to determine the buffer size (with dest==NULL, n==0) could return a larger number than the actual call with an adequate dest buffer. That's OK, because libc locales are always deterministic. Commit 679c5084cf2 partially fixed the assumption, but missed this part. Fix it, and add a more prominent documentation note. Reviewed-by: Haibo Yan Discussion: https://postgr.es/m/CABXr29Hb31nkj1g2Jmk+1BhAm=3ecGs_pWy4tU++j8CQBnbMxQ@mail.gmail.com Backpatch-through: 16 --- src/backend/access/hash/hashfunc.c | 4 ++-- src/backend/utils/adt/pg_locale.c | 8 +++++--- src/backend/utils/adt/pg_locale_libc.c | 10 ++++++++++ src/backend/utils/adt/varchar.c | 4 ++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c index 575342a21b6..97c2c5a6a4c 100644 --- a/src/backend/access/hash/hashfunc.c +++ b/src/backend/access/hash/hashfunc.c @@ -310,7 +310,7 @@ hashtext(PG_FUNCTION_ARGS) * character in the hash, but it was done before and the behavior must * be preserved. */ - result = hash_any((uint8_t *) buf, bsize + 1); + result = hash_any((uint8_t *) buf, rsize + 1); pfree(buf); } @@ -365,7 +365,7 @@ hashtextextended(PG_FUNCTION_ARGS) * character in the hash, but it was done before and the behavior must * be preserved. */ - result = hash_any_extended((uint8_t *) buf, bsize + 1, + result = hash_any_extended((uint8_t *) buf, rsize + 1, PG_GETARG_INT64(1)); pfree(buf); diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index b6e6ee8928b..4f0d0ca5057 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1524,9 +1524,11 @@ pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale) * pg_strxfrm_enabled() first, otherwise this function may return wrong * results or an error. * - * Returns the number of bytes needed (or more) to store the transformed - * string, excluding the terminating nul byte. If the value returned is - * 'destsize' or greater, the resulting contents of 'dest' are undefined. + * Returns the number of bytes needed (NB: or more; see comments above + * strnxfrm_libc()) to store the transformed string, excluding the terminating + * nul byte. If the value returned is 'destsize' or greater, the resulting + * contents of 'dest' are undefined, and the caller should use the return + * value to resize the buffer. */ size_t pg_strnxfrm(char *dest, size_t destsize, const char *src, size_t srclen, diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c index d1f55e145f5..d9a33db8de5 100644 --- a/src/backend/utils/adt/pg_locale_libc.c +++ b/src/backend/utils/adt/pg_locale_libc.c @@ -971,6 +971,11 @@ strcoll_libc(const char *arg1, const char *arg2, pg_locale_t locale) * strnxfrm_libc * * NUL-terminate src and pass to strxfrm_l(). + * + * NB: it's possible for this function to return a different size needed for + * two calls with the same input string. If destsize is too small to hold the + * result, strxfrm() may return the upper bound of the size needed rather than + * the exact size needed. */ static size_t strnxfrm_libc(char *dest, size_t destsize, const char *src, size_t srclen, @@ -1001,6 +1006,11 @@ strnxfrm_libc(char *dest, size_t destsize, const char *src, size_t srclen, /* * strxfrm_libc + * + * NB: it's possible for this function to return a different size needed for + * two calls with the same input string. If destsize is too small to hold the + * result, strxfrm() may return the upper bound of the size needed rather than + * the exact size needed. */ static size_t strxfrm_libc(char *dest, size_t destsize, const char *src, pg_locale_t locale) diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c index 45b7ef185a1..be598cfaf23 100644 --- a/src/backend/utils/adt/varchar.c +++ b/src/backend/utils/adt/varchar.c @@ -1032,7 +1032,7 @@ hashbpchar(PG_FUNCTION_ARGS) * character in the hash, but it was done before and the behavior must * be preserved. */ - result = hash_any((uint8_t *) buf, bsize + 1); + result = hash_any((uint8_t *) buf, rsize + 1); pfree(buf); } @@ -1089,7 +1089,7 @@ hashbpcharextended(PG_FUNCTION_ARGS) * character in the hash, but it was done before and the behavior must * be preserved. */ - result = hash_any_extended((uint8_t *) buf, bsize + 1, + result = hash_any_extended((uint8_t *) buf, rsize + 1, PG_GETARG_INT64(1)); pfree(buf); From 86ed13547589d8401b3b1e1ec2873903b287cb80 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 21 Aug 2026 07:05:11 +0900 Subject: [PATCH 426/481] test_aio: Fix broken error recovery assertions in 001_aio The three error recovery checks in `test_handle()` used "qr/^|ok$/" to look for the marker "ok" in psql's output. '^' matches every string, so the assertions passed no matter what psql printed. Spelling the regex correctly as "qr/^ok\|$/" exposed that the explicit xact case was actually failing, reporting an incorrect "current transaction is aborted" instead of showing that an AIO handle can be acquired again after an error. This is rewritten with a ROLLBACK, similarly to the subxact counterpart. While on it, the subxact case had no marker column in its query, so add one there for consistency, and reformat to use same pattern. Author: Jelte Fennema-Nio Discussion: https://postgr.es/m/DKSU6GI1YLG5.3VF6M4IRKQ7XE@jeltef.nl Backpatch-through: 18 --- src/test/modules/test_aio/t/001_aio.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/modules/test_aio/t/001_aio.pl b/src/test/modules/test_aio/t/001_aio.pl index 63cadd64c15..bb74c325376 100644 --- a/src/test/modules/test_aio/t/001_aio.pl +++ b/src/test/modules/test_aio/t/001_aio.pl @@ -239,7 +239,7 @@ sub test_handle $psql, "handle error recovery in implicit xact", qq(SELECT handle_get_and_error(); SELECT 'ok', handle_get_release()), - qr/^|ok$/, + qr/^ok\|$/, qr/ERROR.*as you command/); # recover after error in implicit xact @@ -247,8 +247,8 @@ sub test_handle $io_method, $psql, "handle error recovery in explicit xact", - qq(BEGIN; SELECT handle_get_and_error(); SELECT handle_get_release(), 'ok'; COMMIT;), - qr/^|ok$/, + qq(BEGIN; SELECT handle_get_and_error(); ROLLBACK; SELECT 'ok', handle_get_release();), + qr/^ok\|$/, qr/ERROR.*as you command/); # recover after error in subtrans @@ -256,8 +256,8 @@ sub test_handle $io_method, $psql, "handle error recovery in explicit subxact", - qq(BEGIN; SAVEPOINT foo; SELECT handle_get_and_error(); ROLLBACK TO SAVEPOINT foo; SELECT handle_get_release(); ROLLBACK;), - qr/^|ok$/, + qq(BEGIN; SAVEPOINT foo; SELECT handle_get_and_error(); ROLLBACK TO SAVEPOINT foo; SELECT 'ok', handle_get_release(); ROLLBACK;), + qr/^ok\|$/, qr/ERROR.*as you command/); $psql->quit(); From ca99016f939dc1e1b260c3ea16721948a1558ef7 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Thu, 20 Aug 2026 19:47:31 -0400 Subject: [PATCH 427/481] Fix snapshot import xmin ProcArrayLock bug. ProcArrayInstallImportedXmin verifies that the source transaction (the transaction whose snapshot we're importing) is still running, and then installs the caller's imported xmin. These steps have to be atomic. But it was just about possible for VACUUM to fail to observe the imported xmin in either the source proc or the importing one. This could result in VACUUM pruning away deleted tuples that were still visible to the imported snapshot. To fix, take ProcArrayLock in exclusive mode while importing an exported snapshot's xmin within ProcArrayInstallImportedXmin. That guarantees that a concurrent VACUUM's OldestXmin cannot advance past the xmin (one proc or the other always advertises an xmin that holds it back). Author: Chee Wooson Reviewed-by: Peter Geoghegan Discussion: https://postgr.es/m/20260730042128.714201-1-chee.wooson@gmail.com Backpatch-through: 14 --- src/backend/storage/ipc/procarray.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 60336b31803..dd221018322 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -2487,8 +2487,13 @@ ProcArrayInstallImportedXmin(TransactionId xmin, if (!sourcevxid) return false; - /* Get lock so source xact can't end while we're doing this */ - LWLockAcquire(ProcArrayLock, LW_SHARED); + /* + * Take the lock in exclusive mode to ensure that installing xmin is + * atomic with our check that the source transaction is still running. + * (Using shared mode risks a concurrent VACUUM whose ComputeXidHorizons() + * call fails to observe the xmin in either the source proc or our own.) + */ + LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); /* * Find the PGPROC entry of the source transaction. (This could use From c06bf14e87c0fe9cda937a5de3ec2a698b249554 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Fri, 21 Aug 2026 12:26:34 +1200 Subject: [PATCH 428/481] Attempt to stabilize plan of self-join test in tidscan.sql The test that checks the expected plan for this self-join test has been known to have failed in the past due to badly timed VACUUMs causing small variations in row estimates on one of the tables, resulting in a swapped join order. Currently, failures have only been seen in v14, and seemingly due to 74388a1ac and 4496020e6 the failures have not been seen in more recent versions. Here we shrink down the number of matching rows on one side of the join to make the alternative join order's costs more expensive relative to the cheapest join order. Previously the alternative order had the same cost. We do this in all supported versions to reduce the chances of future changes reintroducing stability issues with these queries. Reported-by: Alexander Lakhin Author: David Rowley Discussion: https://postgr.es/m/f5d1f4c2-6224-4797-be17-c86e77f96c9c@gmail.com Backpatch-through: 14 --- src/test/regress/expected/tidscan.out | 22 ++++++++++++++-------- src/test/regress/sql/tidscan.sql | 16 ++++++++++++---- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/test/regress/expected/tidscan.out b/src/test/regress/expected/tidscan.out index e823bc91c57..52250e09c95 100644 --- a/src/test/regress/expected/tidscan.out +++ b/src/test/regress/expected/tidscan.out @@ -237,7 +237,8 @@ ROLLBACK; -- (these plans don't use TID scans, but this still seems like an -- appropriate place for these tests) EXPLAIN (COSTS OFF) -SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +WHERE t2.ten = 0; QUERY PLAN ---------------------------------------- Aggregate @@ -246,17 +247,20 @@ SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; -> Seq Scan on tenk1 t1 -> Hash -> Seq Scan on tenk1 t2 -(6 rows) + Filter: (ten = 0) +(7 rows) -SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +WHERE t2.ten = 0; count ------- - 10000 + 1000 (1 row) SET enable_hashjoin TO off; EXPLAIN (COSTS OFF) -SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +WHERE t2.ten = 0; QUERY PLAN ----------------------------------------- Aggregate @@ -268,12 +272,14 @@ SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; -> Sort Sort Key: t2.ctid -> Seq Scan on tenk1 t2 -(9 rows) + Filter: (ten = 0) +(10 rows) -SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +WHERE t2.ten = 0; count ------- - 10000 + 1000 (1 row) RESET enable_hashjoin; diff --git a/src/test/regress/sql/tidscan.sql b/src/test/regress/sql/tidscan.sql index 1b82d5f1a53..fcea11c027a 100644 --- a/src/test/regress/sql/tidscan.sql +++ b/src/test/regress/sql/tidscan.sql @@ -86,12 +86,20 @@ ROLLBACK; -- (these plans don't use TID scans, but this still seems like an -- appropriate place for these tests) EXPLAIN (COSTS OFF) -SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; -SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +WHERE t2.ten = 0; + +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +WHERE t2.ten = 0; + SET enable_hashjoin TO off; + EXPLAIN (COSTS OFF) -SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; -SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +WHERE t2.ten = 0; + +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid +WHERE t2.ten = 0; RESET enable_hashjoin; -- check predicate lock on CTID From 2b0d50e39c58e14b69de76aae2a1c73877de52a6 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 21 Aug 2026 12:36:01 +0900 Subject: [PATCH 429/481] psql: Do not let invalid \getresults affect the next query In pipeline mode, an invalid \getresults argument could previously affect the next SQL command in the same pipeline. For example, after reporting an error for \getresults -1, psql could treat the following SQL command as a request to read pending pipeline results instead of sending it to the server, making the command appear to be skipped or causing missing results. This happened because psql marked \getresults as a request to read pipeline results before validating its optional argument. When validation failed, psql reported the error without running the normal cleanup path that clears the request. Fix this by validating the \getresults argument before marking the command as a request to read pipeline results. After an invalid argument, psql now reports the error and sends the following SQL command normally. Backpatch to v18, where psql pipeline meta-commands were introduced. Author: Fujii Masao Reviewed-by: Anthonin Bonnefoy Discussion: https://postgr.es/m/CAHGQGwGkgM2HKZeig5hobEgUCjn7MMJux4UCcN=OfOzOEvRT0A@mail.gmail.com Backpatch-through: 18 --- src/bin/psql/command.c | 9 +++++---- src/test/regress/expected/psql_pipeline.out | 21 +++++++++++++++++++++ src/test/regress/sql/psql_pipeline.sql | 11 +++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 4c9f97c2714..aaa118a2687 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1936,10 +1936,8 @@ exec_command_getresults(PsqlScanState scan_state, bool active_branch) if (active_branch) { char *opt; - int num_results; + int num_results = 0; - pset.send_mode = PSQL_SEND_GET_RESULTS; - status = PSQL_CMD_SEND; opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false); pset.requested_results = 0; @@ -1952,8 +1950,11 @@ exec_command_getresults(PsqlScanState scan_state, bool active_branch) pg_log_error("\\getresults: invalid number of requested results"); return PSQL_CMD_ERROR; } - pset.requested_results = num_results; } + + pset.requested_results = num_results; + pset.send_mode = PSQL_SEND_GET_RESULTS; + status = PSQL_CMD_SEND; } else ignore_slash_options(scan_state); diff --git a/src/test/regress/expected/psql_pipeline.out b/src/test/regress/expected/psql_pipeline.out index a931d63cafe..6fc5aea49d9 100644 --- a/src/test/regress/expected/psql_pipeline.out +++ b/src/test/regress/expected/psql_pipeline.out @@ -627,6 +627,27 @@ Pipeline aborted, command did not run \startpipeline \getresults -1 \getresults: invalid number of requested results +\endpipeline +-- After an invalid \getresults argument, the next SQL command in the +-- pipeline should still be sent and returned normally. +\startpipeline +SELECT 1; +\flushrequest +\getresults -1 +\getresults: invalid number of requested results +SELECT 99; +\flushrequest +\getresults + ?column? +---------- + 1 +(1 row) + + ?column? +---------- + 99 +(1 row) + \endpipeline -- \getresults when there is no result should not impact the next -- query executed. diff --git a/src/test/regress/sql/psql_pipeline.sql b/src/test/regress/sql/psql_pipeline.sql index 468ef1d090b..b6bd917c90b 100644 --- a/src/test/regress/sql/psql_pipeline.sql +++ b/src/test/regress/sql/psql_pipeline.sql @@ -354,6 +354,17 @@ SELECT $1 \bind \sendpipeline \getresults -1 \endpipeline +-- After an invalid \getresults argument, the next SQL command in the +-- pipeline should still be sent and returned normally. +\startpipeline +SELECT 1; +\flushrequest +\getresults -1 +SELECT 99; +\flushrequest +\getresults +\endpipeline + -- \getresults when there is no result should not impact the next -- query executed. \getresults 1 From c63b210ed34d9153e82c86abba3160a569b86f72 Mon Sep 17 00:00:00 2001 From: Etsuro Fujita Date: Fri, 21 Aug 2026 17:50:01 +0900 Subject: [PATCH 430/481] Fix typos in comments. Author: Etsuro Fujita Reviewed-by: Bharath Rupireddy Discussion: https://postgr.es/m/CAPmGK14otpa7XZyBO5GxDABUK9OPWFLsAwoQP3ugNdXq%3DK4J1g%40mail.gmail.com Backpatch-through: 19 --- contrib/postgres_fdw/postgres_fdw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 0469a761a9d..209ff7b8fef 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -5637,10 +5637,10 @@ fetch_remote_statistics(Relation relation, } /* - * If the reltuples value > 0, then then we can expect to find attribute - * stats for the remote table. + * If the reltuples value > 0, then we can expect to find attribute stats + * for the remote table. * - * In v14 or latter, if a reltuples value is -1, it means the table has + * In v14 or later, if a reltuples value is -1, it means the table has * never been analyzed, so we wouldn't expect to find the stats for the * table; fallback to sampling in that case. If the value is 0, it means * it was empty; in which case skip the stats and import relation stats @@ -5793,7 +5793,7 @@ fetch_attstats(PGconn *conn, int server_version_num, } /* - * Build the mapping of local columns to remote columns and create a column + * Build the mappings of local columns to remote columns and create a column * list used for constructing the fetch_attstats query. */ static RemoteAttributeMapping * @@ -5849,7 +5849,7 @@ build_remattrmap(Relation relation, List *va_cols, } appendStringInfoChar(column_list, ']'); - /* Sort mapping by remote attribute name if needed. */ + /* Sort mappings by remote attribute name if needed. */ if (attrcnt > 1) qsort(remattrmap, attrcnt, sizeof(RemoteAttributeMapping), remattrmap_cmp); From c7e34c31e844b2234fa57fef12ae37f30c8f5a9b Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 21 Aug 2026 13:55:58 +0200 Subject: [PATCH 431/481] Fix error code for null FOR PORTION OF target When the target expression of FOR PORTION OF (...) evaluated to NULL, ExecInitModifyTable raised an error without an errcode, so clients got the internal error code XX000 for a user-reachable condition. Oversight in commit 8e72d914c52. To fix, report ERRCODE_NULL_VALUE_NOT_ALLOWED, and reword the message to "FOR PORTION OF target must not be null", matching similar executor messages such as "frame starting offset must not be null". Bug: #19630 Reported-by: Zheng Wang Reported-by: Yanjie Zhao Reported-by: Yiyang Liu Author: Zsolt Parragi Discussion: https://www.postgresql.org/message-id/flat/19630-9f10ca28426295fa%40postgresql.org --- src/backend/executor/nodeModifyTable.c | 5 +++-- src/test/regress/expected/for_portion_of.out | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 9a1c0992bfe..5681505d31c 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -5645,8 +5645,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) */ if (isNull) ereport(ERROR, - (errmsg("FOR PORTION OF target was null")), - executor_errposition(estate, forPortionOf->targetLocation)); + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("FOR PORTION OF target must not be null"), + executor_errposition(estate, forPortionOf->targetLocation))); /* Create state for FOR PORTION OF operation */ diff --git a/src/test/regress/expected/for_portion_of.out b/src/test/regress/expected/for_portion_of.out index a6cb1ba8380..1a53e549de0 100644 --- a/src/test/regress/expected/for_portion_of.out +++ b/src/test/regress/expected/for_portion_of.out @@ -407,7 +407,7 @@ UPDATE for_portion_of_test FOR PORTION OF valid_at (NULL) SET name = 'one^3' WHERE id = '[1,2)'; -ERROR: FOR PORTION OF target was null +ERROR: FOR PORTION OF target must not be null LINE 2: FOR PORTION OF valid_at (NULL) ^ -- Updating with a direct target of empty does nothing @@ -884,7 +884,7 @@ LINE 2: FOR PORTION OF valid_at (4) DELETE FROM for_portion_of_test FOR PORTION OF valid_at (NULL) WHERE id = '[1,2)'; -ERROR: FOR PORTION OF target was null +ERROR: FOR PORTION OF target must not be null LINE 2: FOR PORTION OF valid_at (NULL) ^ -- Deleting with a direct target of empty does nothing @@ -1971,7 +1971,7 @@ UPDATE for_portion_of_test2 FOR PORTION OF valid_at (NULL) SET name = 'one^3' WHERE id = '[1,2)'; -ERROR: FOR PORTION OF target was null +ERROR: FOR PORTION OF target must not be null LINE 2: FOR PORTION OF valid_at (NULL) ^ -- Updating with empty does nothing @@ -2035,7 +2035,7 @@ LINE 2: FOR PORTION OF valid_at (4) DELETE FROM for_portion_of_test2 FOR PORTION OF valid_at (NULL) WHERE id = '[2,3)'; -ERROR: FOR PORTION OF target was null +ERROR: FOR PORTION OF target must not be null LINE 2: FOR PORTION OF valid_at (NULL) ^ -- Deleting with empty does nothing From 051be721d02a7b1dedc10521db43a94bcf8a739a Mon Sep 17 00:00:00 2001 From: David Rowley Date: Sat, 22 Aug 2026 12:49:17 +1200 Subject: [PATCH 432/481] Doc: fix typo Author: Jochen Bandhauer Discussion: https://postgr.es/m/69ecfa04-9177-42fd-8d5d-9f375669fc5b@jbitc.de Backpatch-through: 14 --- doc/src/sgml/maintenance.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index e351e5e9ca1..88350ebbc73 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -724,7 +724,7 @@ HINT: Execute a database-wide VACUUM in that database. Execute VACUUM in the target database. A database-wide - VACUUM is simplest; to reduce the time required, it as also possible + VACUUM is simplest; to reduce the time required, it is also possible to issue manual VACUUM commands on the tables where relminxid is oldest. Do not use VACUUM FULL in this scenario, because it requires an XID and will therefore fail, except in super-user From 268958a2e5feac370844e164a4e7e2535f6d2bc7 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Sat, 22 Aug 2026 16:23:28 +0900 Subject: [PATCH 433/481] Track RI fast-path FK-check batches per subtransaction Commit 4113873 confined RI fast-path batching to the top transaction level to avoid mishandling the batch cache on subtransaction abort. That disabled batching for a foreign-key load wrapped in a savepoint, such as: BEGIN; SAVEPOINT s; COPY fk_table FROM ... This was a surprising performance cliff and departed from the usual per-subtransaction resource handling. Track cache entries per subtransaction instead. Add AtEOSubXact_RI(), called from CommitSubTransaction() and AbortSubTransaction() after ResourceOwnerRelease(). On abort, it removes only entries opened by the ending subtransaction, whose resources have just been released, while leaving entries opened by an outer level intact. Thus, an inner subtransaction abort during outer-level trigger firing does not discard the outer statement's batch. On commit, no matching entry is expected because its batch should already have been flushed at statement end. Each entry records the subtransaction that opened its resources. After an abort, the remaining slot storage and per-entry flush contexts are reclaimed when TopTransactionContext is reset at top-level transaction end. A fast-path batch is filled and flushed within a single trigger-firing cycle, so every row added to an entry must come from the subtransaction that created it. AtEOSubXact_RI() relies on this invariant to identify an aborting subtransaction's entries by the subid stamped at entry creation. Assert the invariant in ri_FastPathBatchAdd(). Add regression coverage for batching during nested firing inside a subtransaction, both with different constraints and with the same constraint at the inner and outer firing levels. Reported-by: Noah Misch Reported-by: Nikolay Samokhvalov Discussion: https://postgr.es/m/20260705222115.be.noahmisch@microsoft.com Backpatch-through: 19 --- src/backend/access/transam/xact.c | 2 + src/backend/utils/adt/ri_triggers.c | 94 +++++++++++++++++++++-- src/include/commands/trigger.h | 2 + src/test/regress/expected/foreign_key.out | 70 +++++++++++++++++ src/test/regress/sql/foreign_key.sql | 57 ++++++++++++++ 5 files changed, 217 insertions(+), 8 deletions(-) diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 3a89149016f..9e2d507c8a9 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -5245,6 +5245,7 @@ CommitSubTransaction(void) s->parent->subTransactionId); AtEOSubXact_HashTables(true, s->nestingLevel); AtEOSubXact_PgStat(true, s->nestingLevel); + AtEOSubXact_RI(true, s->subTransactionId, s->parent->subTransactionId); AtSubCommit_Snapshot(s->nestingLevel); /* @@ -5419,6 +5420,7 @@ AbortSubTransaction(void) s->parent->subTransactionId); AtEOSubXact_HashTables(false, s->nestingLevel); AtEOSubXact_PgStat(false, s->nestingLevel); + AtEOSubXact_RI(false, s->subTransactionId, s->parent->subTransactionId); AtSubAbort_Snapshot(s->nestingLevel); } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 5a209673b61..439376a6cc2 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -287,6 +287,14 @@ typedef struct RI_FastPathEntry * re-entrant ri_FastPathBatchAdd from user code run during the flush. */ bool flushing; + + /* + * Subtransaction whose resource owner opened this entry's relations. + * AtEOSubXact_RI() drops only entries matching an aborting subxact, so a + * subxact abort during outer-level trigger firing leaves the outer batch + * intact. + */ + SubTransactionId subid; } RI_FastPathEntry; /* @@ -512,9 +520,7 @@ RI_FKey_check(TriggerData *trigdata) */ if (ri_fastpath_is_applicable(riinfo)) { - if (AfterTriggerIsActive() && - GetCurrentTransactionNestLevel() == 1 && - !ri_fastpath_flushing) + if (AfterTriggerIsActive() && !ri_fastpath_flushing) { /* Batched path: buffer and probe in groups */ ri_FastPathBatchAdd(riinfo, fk_rel, newslot); @@ -522,15 +528,11 @@ RI_FKey_check(TriggerData *trigdata) else { /* - * Per-row path, used when batching is not safe or not applicable: + * Per-row path, used when batching is not applicable: * * - ALTER TABLE validation, where no after-trigger firing is * active; * - * - any FK check inside a subtransaction, since the batch cache - * is confined to the top transaction level (it cannot be cleanly - * unwound on subxact abort); - * * - a re-entrant check from user cast/operator code running * during a batch flush, since adding a cache entry while * ri_FastPathEndBatch is iterating the cache could leave it @@ -2969,6 +2971,14 @@ ri_FastPathBatchAdd(RI_ConstraintInfo *riinfo, return; } + /* + * A batch is filled and flushed within a single trigger-firing cycle, so + * every row added to an entry comes from the subtransaction that created + * it. AtEOSubXact_RI() relies on this to identify an aborting + * subtransaction's entries by the subid stamped at entry creation. + */ + Assert(fpentry->subid == GetCurrentSubTransactionId()); + /* * Buffer the row. A full batch is flushed below and re-entry is handled * above, so there is always room here; the bounds check just guards the @@ -4480,6 +4490,73 @@ AtEOXact_RI(bool isCommit) } } +/* + * AtEOSubXact_RI + * Reset fast-path batching state at subtransaction end. + * + * Called from CommitSubTransaction() with isCommit true and from + * AbortSubTransaction() with isCommit false, in both cases after the + * subtransaction's ResourceOwnerRelease(). + * + * Fast-path cache entries are normally flushed and removed at the end of + * their trigger-firing cycle, and the cache is destroyed when its last entry + * is removed. Thus, at a normal subtransaction boundary this is a no-op. + * + * The exception is a batch flush that errors out partway and is caught by this + * subtransaction (e.g. a PL/pgSQL EXCEPTION block): ri_FastPathEndBatch()'s + * teardown was skipped, so the cache still contains entries whose relations + * were opened under this subtransaction's resource owner. That owner has + * just released those relations, making the entries stale. Remove those + * entries so a later firing cycle cannot reuse them. Entries belonging to + * outer subtransactions remain valid and are preserved. + * + * The remaining slot storage and per-entry flush contexts are reclaimed when + * TopTransactionContext is reset at top-level transaction end. + */ +void +AtEOSubXact_RI(bool isCommit, SubTransactionId mySubid, + SubTransactionId parentSubid) +{ + HASH_SEQ_STATUS status; + RI_FastPathEntry *entry; + long remaining; + + if (ri_fastpath_cache == NULL) + return; + + /* Process only entries belonging to the ending subtransaction. */ + hash_seq_init(&status, ri_fastpath_cache); + while ((entry = hash_seq_search(&status)) != NULL) + { + if (entry->subid != mySubid) + continue; + + if (isCommit) + { + /* + * A committing subxact's entry should already have been flushed + * and torn down at its statement's end (ri_FastPathEndBatch()), + * so we don't expect to find one here. If we do, reassign it to + * the parent so it's still cleaned up rather than left under a + * subxact id that no longer exists. + */ + Assert(false); + entry->subid = parentSubid; + } + else + hash_search(ri_fastpath_cache, &entry->key, HASH_REMOVE, NULL); + } + + /* If that emptied the cache, drop it so the next batch starts clean. */ + remaining = hash_get_num_entries(ri_fastpath_cache); + if (remaining == 0) + { + hash_destroy(ri_fastpath_cache); + ri_fastpath_cache = NULL; + ri_fastpath_flushing = false; + } +} + /* * ri_FastPathGetEntry * Look up or create a per-batch cache entry for the given constraint. @@ -4605,6 +4682,7 @@ ri_FastPathGetEntry(const RI_ConstraintInfo *riinfo, Relation fk_rel) entry->flushing = false; entry->batch_count = 0; + entry->subid = GetCurrentSubTransactionId(); } return entry; diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h index 1f268f87957..fecdb785f35 100644 --- a/src/include/commands/trigger.h +++ b/src/include/commands/trigger.h @@ -312,5 +312,7 @@ extern bool AfterTriggerIsActive(void); extern int AfterTriggerCurrentQueryDepth(void); extern void AtEOXact_RI(bool isCommit); +extern void AtEOSubXact_RI(bool isCommit, SubTransactionId mySubid, + SubTransactionId parentSubid); #endif /* TRIGGER_H */ diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out index 126c251bbda..ac044eb40fa 100644 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@ -3951,6 +3951,76 @@ ROLLBACK; RESET ROLE; DROP TABLE fpav_fk, fpav_pk, fpav_cv_fk, fpav_cv_pk; DROP ROLE regress_fpav_role; +-- Re-entrant fast-path check inside a committing subtransaction. An AFTER +-- trigger on one FK table runs FK DML on a second FK table inside a PL/pgSQL +-- BEGIN ... EXCEPTION block, so the inner check batches in its own +-- trigger-firing cycle nested in the outer check's. The inner cycle must +-- register its own end-of-batch callback and flush -- otherwise its FK check +-- is skipped (an orphan commits) and its relations leak. +CREATE TABLE fp_inner_pk (id int PRIMARY KEY); +INSERT INTO fp_inner_pk VALUES (1); +CREATE TABLE fp_inner_fk (a int REFERENCES fp_inner_pk (id)); +CREATE TABLE fp_outer_pk (id int PRIMARY KEY); +INSERT INTO fp_outer_pk SELECT g FROM generate_series(1, 64) g; +CREATE FUNCTION fp_reentry_subxact() RETURNS trigger LANGUAGE plpgsql AS $$ +BEGIN + IF NEW.a = 32 THEN + BEGIN + INSERT INTO fp_inner_fk VALUES (999); -- violates; must be caught + EXCEPTION WHEN foreign_key_violation THEN + NULL; + END; + END IF; + RETURN NEW; +END$$; +CREATE TABLE fp_outer_fk (a int REFERENCES fp_outer_pk (id)); +CREATE TRIGGER fp_reentry_subxact_trg AFTER INSERT ON fp_outer_fk + FOR EACH ROW EXECUTE FUNCTION fp_reentry_subxact(); +INSERT INTO fp_outer_fk SELECT g FROM generate_series(1, 64) g; +SELECT count(*) AS outer_rows FROM fp_outer_fk; -- 64, outer batch intact + outer_rows +------------ + 64 +(1 row) + +SELECT count(*) AS inner_rows FROM fp_inner_fk; -- 0, inner check caught + inner_rows +------------ + 0 +(1 row) + +DROP TRIGGER fp_reentry_subxact_trg ON fp_outer_fk; +DROP FUNCTION fp_reentry_subxact(); +DROP TABLE fp_outer_fk, fp_outer_pk, fp_inner_fk, fp_inner_pk; +-- A nested trigger-firing cycle that checks the same constraint must use a +-- separate cache entry. The inner violation is caught by its subtransaction, +-- while the valid outer row remains buffered and is checked normally. +CREATE TABLE fp_same_pk (id int PRIMARY KEY); +INSERT INTO fp_same_pk VALUES (1); +CREATE TABLE fp_same_fk (a int REFERENCES fp_same_pk (id)); +CREATE FUNCTION fp_reentry_same_constraint() RETURNS trigger LANGUAGE plpgsql AS $$ +BEGIN + IF NEW.a = 1 THEN + BEGIN + INSERT INTO fp_same_fk VALUES (999); + EXCEPTION WHEN foreign_key_violation THEN + NULL; + END; + END IF; + RETURN NEW; +END$$; +CREATE TRIGGER fp_reentry_same_constraint_trg AFTER INSERT ON fp_same_fk + FOR EACH ROW EXECUTE FUNCTION fp_reentry_same_constraint(); +INSERT INTO fp_same_fk VALUES (1); +SELECT * FROM fp_same_fk; + a +--- + 1 +(1 row) + +DROP TRIGGER fp_reentry_same_constraint_trg ON fp_same_fk; +DROP FUNCTION fp_reentry_same_constraint(); +DROP TABLE fp_same_fk, fp_same_pk; -- An AFTER trigger runs a query of its own, and that query inserts into a -- second table with a fast-path foreign key. The entry the nested INSERT -- creates belongs to the cursor's portal, which is gone by the time the diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql index 7319de6a280..a93e81b42bc 100644 --- a/src/test/regress/sql/foreign_key.sql +++ b/src/test/regress/sql/foreign_key.sql @@ -2898,6 +2898,63 @@ RESET ROLE; DROP TABLE fpav_fk, fpav_pk, fpav_cv_fk, fpav_cv_pk; DROP ROLE regress_fpav_role; +-- Re-entrant fast-path check inside a committing subtransaction. An AFTER +-- trigger on one FK table runs FK DML on a second FK table inside a PL/pgSQL +-- BEGIN ... EXCEPTION block, so the inner check batches in its own +-- trigger-firing cycle nested in the outer check's. The inner cycle must +-- register its own end-of-batch callback and flush -- otherwise its FK check +-- is skipped (an orphan commits) and its relations leak. +CREATE TABLE fp_inner_pk (id int PRIMARY KEY); +INSERT INTO fp_inner_pk VALUES (1); +CREATE TABLE fp_inner_fk (a int REFERENCES fp_inner_pk (id)); +CREATE TABLE fp_outer_pk (id int PRIMARY KEY); +INSERT INTO fp_outer_pk SELECT g FROM generate_series(1, 64) g; +CREATE FUNCTION fp_reentry_subxact() RETURNS trigger LANGUAGE plpgsql AS $$ +BEGIN + IF NEW.a = 32 THEN + BEGIN + INSERT INTO fp_inner_fk VALUES (999); -- violates; must be caught + EXCEPTION WHEN foreign_key_violation THEN + NULL; + END; + END IF; + RETURN NEW; +END$$; +CREATE TABLE fp_outer_fk (a int REFERENCES fp_outer_pk (id)); +CREATE TRIGGER fp_reentry_subxact_trg AFTER INSERT ON fp_outer_fk + FOR EACH ROW EXECUTE FUNCTION fp_reentry_subxact(); +INSERT INTO fp_outer_fk SELECT g FROM generate_series(1, 64) g; +SELECT count(*) AS outer_rows FROM fp_outer_fk; -- 64, outer batch intact +SELECT count(*) AS inner_rows FROM fp_inner_fk; -- 0, inner check caught +DROP TRIGGER fp_reentry_subxact_trg ON fp_outer_fk; +DROP FUNCTION fp_reentry_subxact(); +DROP TABLE fp_outer_fk, fp_outer_pk, fp_inner_fk, fp_inner_pk; + +-- A nested trigger-firing cycle that checks the same constraint must use a +-- separate cache entry. The inner violation is caught by its subtransaction, +-- while the valid outer row remains buffered and is checked normally. +CREATE TABLE fp_same_pk (id int PRIMARY KEY); +INSERT INTO fp_same_pk VALUES (1); +CREATE TABLE fp_same_fk (a int REFERENCES fp_same_pk (id)); +CREATE FUNCTION fp_reentry_same_constraint() RETURNS trigger LANGUAGE plpgsql AS $$ +BEGIN + IF NEW.a = 1 THEN + BEGIN + INSERT INTO fp_same_fk VALUES (999); + EXCEPTION WHEN foreign_key_violation THEN + NULL; + END; + END IF; + RETURN NEW; +END$$; +CREATE TRIGGER fp_reentry_same_constraint_trg AFTER INSERT ON fp_same_fk + FOR EACH ROW EXECUTE FUNCTION fp_reentry_same_constraint(); +INSERT INTO fp_same_fk VALUES (1); +SELECT * FROM fp_same_fk; +DROP TRIGGER fp_reentry_same_constraint_trg ON fp_same_fk; +DROP FUNCTION fp_reentry_same_constraint(); +DROP TABLE fp_same_fk, fp_same_pk; + -- An AFTER trigger runs a query of its own, and that query inserts into a -- second table with a fast-path foreign key. The entry the nested INSERT -- creates belongs to the cursor's portal, which is gone by the time the From b13fd289988067dd09ccc08243fcab803804595b Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Sat, 22 Aug 2026 14:50:39 -0400 Subject: [PATCH 434/481] Fix GIN posting tree page deletion with incomplete splits. GIN posting tree page deletion failed to consider whether the target page's left sibling page, or the deletion target itself, was marked as incompletely split. Page deletion finds the target page's left sibling by walking the parent's downlinks, but an incompletely split page's new right half is part of the sibling chain despite having no downlink. Deletion could therefore overwrite the rightlink of the wrong page, disconnecting the split's still-live right half from the sibling chain. Scans would then silently miss tuples from that page. To fix, teach the relevant page deletion path to avoid deleting a posting tree page whose left sibling is marked incompletely split (and to avoid doing so when the target page itself is so marked). This is essentially the same approach used by nbtree page deletion. Claude Code found this problem. The committed test case is a simplified version of the one that it wrote to demonstrate this bug. Author: Peter Geoghegan Reviewed-by: Andrey Borodin Discussion: https://postgr.es/m/CAH2-Wz=sKJcn+OtfVN9rdg+Ps9e4cuQWNP-9t12UE2d8nEG90Q@mail.gmail.com Backpatch-through: 14 --- src/backend/access/gin/ginvacuum.c | 18 ++- src/test/modules/gin/Makefile | 2 +- .../gin/expected/gin_incomplete_splits.out | 109 +++++++++++++++++- .../modules/gin/sql/gin_incomplete_splits.sql | 83 ++++++++++++- 4 files changed, 206 insertions(+), 6 deletions(-) diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index d69d59748b5..2cd4e50aa61 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -167,6 +167,8 @@ ginDeletePostingPage(GinVacuumState *gvs, Buffer dBuffer, Buffer lBuffer, page = BufferGetPage(dBuffer); rightlink = GinPageGetOpaque(page)->rightlink; + Assert(GinPageGetOpaque(BufferGetPage(lBuffer))->rightlink == deleteBlkno); + /* * Any insert which would have gone on the leaf block will now go to its * right sibling. @@ -334,10 +336,20 @@ ginScanPostingTreeToDelete(GinVacuumState *gvs, DataPageDeleteStack *myStackItem if (isempty) { /* - * Proceed to the ginDeletePostingPage() if that's not the leftmost or - * the rightmost page. + * Proceed to the ginDeletePostingPage() if target page is not the + * leftmost or the rightmost page. + * + * leftBuffer is the target's left sibling according to the parent + * level, which is not necessarily its left sibling in the sibling + * link chain (the rightlinks stored on pages): the new right half of + * an incompletely split page is in the sibling chain, but has no + * downlink yet. ginDeletePostingPage isn't prepared to deal with + * that, so we must refuse to delete when either the target or its + * left sibling page is marked incompletely split. */ - if (BufferIsValid(myStackItem->leftBuffer) && !GinPageRightMost(page)) + if (BufferIsValid(myStackItem->leftBuffer) && !GinPageRightMost(page) && + !GinPageIsIncompleteSplit(page) && + !GinPageIsIncompleteSplit(BufferGetPage(myStackItem->leftBuffer))) { Assert(!myStackItem->isRoot); ginDeletePostingPage(gvs, buffer, myStackItem->leftBuffer, diff --git a/src/test/modules/gin/Makefile b/src/test/modules/gin/Makefile index e007e38ac27..468e46d35e9 100644 --- a/src/test/modules/gin/Makefile +++ b/src/test/modules/gin/Makefile @@ -1,6 +1,6 @@ # src/test/modules/gin/Makefile -EXTRA_INSTALL = src/test/modules/injection_points +EXTRA_INSTALL = src/test/modules/injection_points contrib/pageinspect REGRESS = gin_incomplete_splits diff --git a/src/test/modules/gin/expected/gin_incomplete_splits.out b/src/test/modules/gin/expected/gin_incomplete_splits.out index 0f3ac9a0466..c4bc09ac6ab 100644 --- a/src/test/modules/gin/expected/gin_incomplete_splits.out +++ b/src/test/modules/gin/expected/gin_incomplete_splits.out @@ -19,7 +19,6 @@ SELECT injection_points_set_local(); (1 row) --- Use the index for all the queries set enable_seqscan=off; -- Print a NOTICE whenever an incomplete split gets fixed SELECT injection_points_attach('gin-finish-incomplete-split', 'notice'); @@ -192,4 +191,112 @@ SELECT injection_points_detach('gin-finish-incomplete-split'); (1 row) +-- +-- Test that VACUUM does not delete the right sibling of an incompletely +-- split posting tree leaf page +-- +create extension pageinspect; +-- Create a GIN index with a posting tree that has several leaf pages +create temp table gin_posting_tree(id int4, i int4[]); +insert into gin_posting_tree select g, '{1}' from generate_series(1, 55000) g; +create index gin_posting_tree_idx on gin_posting_tree using gin (i) with (fastupdate = off); +-- Free space in the middle of the index key space/heap. The later inserts +-- will get TIDs in the middle of the posting tree's key space, splitting a +-- leaf page that is neither the leftmost nor rightmost of the posting tree. +delete from gin_posting_tree where id between 10001 and 27500; +vacuum (index_cleanup on) gin_posting_tree; +-- Insert rows until a leaf page split fails, leaving the split incomplete +SELECT injection_points_attach('gin-leave-leaf-split-incomplete', 'error'); + injection_points_attach +------------------------- + +(1 row) + +do $$ +begin + for n in 1..200000 loop + begin + insert into gin_posting_tree values (n, '{1}'); + exception when others then + return; + end; + end loop; + raise 'no leaf split after 200000 inserts'; +end; +$$; +SELECT injection_points_detach('gin-leave-leaf-split-incomplete'); + injection_points_detach +------------------------- + +(1 row) + +-- Locate the incompletely split page's new right half (reachable only +-- through its left sibling's rightlink), and the leaf to the right of +-- that (the page that VACUUM will delete). Errors out unless there is +-- exactly one incomplete split. +select o.rightlink::int as righthalf, + (gin_page_opaque_info(get_raw_page('gin_posting_tree_idx', + o.rightlink::int))).rightlink::int + as nextleaf + from generate_series(0, pg_relation_size('gin_posting_tree_idx') / + current_setting('block_size')::int - 1) blkno, + lateral gin_page_opaque_info(get_raw_page('gin_posting_tree_idx', + blkno::int)) o + where o.flags @> '{incomplete_split}' +\gset +-- Sanity check: scan will miss nothing if the right half held no live rows, +-- and VACUUM never deletes the rightmost page +select exists (select from gin_posting_tree + where ctid in (select unnest(tids) from gin_leafpage_items( + get_raw_page('gin_posting_tree_idx', :righthalf)))) + as righthalf_has_live_rows, + (gin_page_opaque_info(get_raw_page('gin_posting_tree_idx', + :nextleaf))).rightlink <> 4294967295 + as nextleaf_is_not_rightmost; + righthalf_has_live_rows | nextleaf_is_not_rightmost +-------------------------+--------------------------- + t | t +(1 row) + +-- Empty the page to the right of the right half, and have VACUUM consider +-- deleting it +delete from gin_posting_tree + where ctid in (select unnest(tids) from gin_leafpage_items( + get_raw_page('gin_posting_tree_idx', :nextleaf))); +vacuum (index_cleanup on) gin_posting_tree; +-- Count the remaining rows through a bitmap scan +explain (costs off) +select count(*) as bitmapscan_count from gin_posting_tree where i @> '{1}'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on gin_posting_tree + Recheck Cond: (i @> '{1}'::integer[]) + -> Bitmap Index Scan on gin_posting_tree_idx + Index Cond: (i @> '{1}'::integer[]) +(5 rows) + +select count(*) as bitmapscan_count from gin_posting_tree where i @> '{1}' +\gset +-- Verify that a sequential scan finds the same rows +set enable_seqscan=on; +set enable_bitmapscan=off; +explain (costs off) +select count(*) from gin_posting_tree where i @> '{1}'; + QUERY PLAN +----------------------------------------- + Aggregate + -> Seq Scan on gin_posting_tree + Filter: (i @> '{1}'::integer[]) +(3 rows) + +select count(*) = :bitmapscan_count as seqscan_agrees + from gin_posting_tree where i @> '{1}'; + seqscan_agrees +---------------- + t +(1 row) + +drop table gin_posting_tree; +drop extension pageinspect; drop extension injection_points; diff --git a/src/test/modules/gin/sql/gin_incomplete_splits.sql b/src/test/modules/gin/sql/gin_incomplete_splits.sql index d451257c275..1a0c0055fe9 100644 --- a/src/test/modules/gin/sql/gin_incomplete_splits.sql +++ b/src/test/modules/gin/sql/gin_incomplete_splits.sql @@ -17,7 +17,6 @@ create extension injection_points; -- Make all injection points local to this process, for concurrency. SELECT injection_points_set_local(); --- Use the index for all the queries set enable_seqscan=off; -- Print a NOTICE whenever an incomplete split gets fixed @@ -149,4 +148,86 @@ select verify(:next_i); SELECT injection_points_detach('gin-finish-incomplete-split'); +-- +-- Test that VACUUM does not delete the right sibling of an incompletely +-- split posting tree leaf page +-- +create extension pageinspect; + +-- Create a GIN index with a posting tree that has several leaf pages +create temp table gin_posting_tree(id int4, i int4[]); +insert into gin_posting_tree select g, '{1}' from generate_series(1, 55000) g; +create index gin_posting_tree_idx on gin_posting_tree using gin (i) with (fastupdate = off); + +-- Free space in the middle of the index key space/heap. The later inserts +-- will get TIDs in the middle of the posting tree's key space, splitting a +-- leaf page that is neither the leftmost nor rightmost of the posting tree. +delete from gin_posting_tree where id between 10001 and 27500; +vacuum (index_cleanup on) gin_posting_tree; + +-- Insert rows until a leaf page split fails, leaving the split incomplete +SELECT injection_points_attach('gin-leave-leaf-split-incomplete', 'error'); +do $$ +begin + for n in 1..200000 loop + begin + insert into gin_posting_tree values (n, '{1}'); + exception when others then + return; + end; + end loop; + raise 'no leaf split after 200000 inserts'; +end; +$$; +SELECT injection_points_detach('gin-leave-leaf-split-incomplete'); + +-- Locate the incompletely split page's new right half (reachable only +-- through its left sibling's rightlink), and the leaf to the right of +-- that (the page that VACUUM will delete). Errors out unless there is +-- exactly one incomplete split. +select o.rightlink::int as righthalf, + (gin_page_opaque_info(get_raw_page('gin_posting_tree_idx', + o.rightlink::int))).rightlink::int + as nextleaf + from generate_series(0, pg_relation_size('gin_posting_tree_idx') / + current_setting('block_size')::int - 1) blkno, + lateral gin_page_opaque_info(get_raw_page('gin_posting_tree_idx', + blkno::int)) o + where o.flags @> '{incomplete_split}' +\gset + +-- Sanity check: scan will miss nothing if the right half held no live rows, +-- and VACUUM never deletes the rightmost page +select exists (select from gin_posting_tree + where ctid in (select unnest(tids) from gin_leafpage_items( + get_raw_page('gin_posting_tree_idx', :righthalf)))) + as righthalf_has_live_rows, + (gin_page_opaque_info(get_raw_page('gin_posting_tree_idx', + :nextleaf))).rightlink <> 4294967295 + as nextleaf_is_not_rightmost; + +-- Empty the page to the right of the right half, and have VACUUM consider +-- deleting it +delete from gin_posting_tree + where ctid in (select unnest(tids) from gin_leafpage_items( + get_raw_page('gin_posting_tree_idx', :nextleaf))); +vacuum (index_cleanup on) gin_posting_tree; + +-- Count the remaining rows through a bitmap scan +explain (costs off) +select count(*) as bitmapscan_count from gin_posting_tree where i @> '{1}'; +select count(*) as bitmapscan_count from gin_posting_tree where i @> '{1}' +\gset + +-- Verify that a sequential scan finds the same rows +set enable_seqscan=on; +set enable_bitmapscan=off; +explain (costs off) +select count(*) from gin_posting_tree where i @> '{1}'; +select count(*) = :bitmapscan_count as seqscan_agrees + from gin_posting_tree where i @> '{1}'; + +drop table gin_posting_tree; + +drop extension pageinspect; drop extension injection_points; From 165aa5040a02e13011f07e3c6669ac0edf4f8258 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 23 Aug 2026 12:42:55 -0400 Subject: [PATCH 435/481] Allow an aggregate's planner support function to be set via CREATE AGGREGATE. Commit 42473b3b3 implemented SupportRequestSimplifyAggref, but failed to think about what infrastructure would be required for an extension to use that: there is no SQL-level mechanism for attaching a planner support function to an aggregate. That seems pretty critical for a feature that's primarily intended to be used by extensions. To fix, add a SUPPORT clause to CREATE AGGREGATE, and teach pg_dump (and thereby pg_upgrade) about dumping this aggregate property. We don't need to touch ALTER AGGREGATE, because it's already the case that you're supposed to use CREATE OR REPLACE AGGREGATE if you want to alter any aggregate-specific properties set by CREATE AGGREGATE. (Maybe at some point we'll think that that policy ought to change, but I don't think this one feature moves the needle enough.) Per report from Andrei Lepikhov, who also provided some of the new documentation text. Reported-by: Andrei Lepikhov Author: Tom Lane Reviewed-by: Andrei Lepikhov Discussion: https://postgr.es/m/8f58c96d-d3c7-4c0f-9898-116f00eeaff6@gmail.com Backpatch-through: 19 --- doc/src/sgml/ref/alter_aggregate.sgml | 7 ++++ doc/src/sgml/ref/create_aggregate.sgml | 15 +++++++++ doc/src/sgml/xfunc.sgml | 18 +++++++++- src/backend/catalog/pg_aggregate.c | 33 ++++++++++++++++++- src/backend/commands/aggregatecmds.c | 4 +++ src/bin/pg_dump/pg_dump.c | 18 ++++++++-- src/include/catalog/pg_aggregate.h | 1 + .../regress/expected/create_aggregate.out | 15 +++++++++ src/test/regress/sql/create_aggregate.sql | 8 +++++ 9 files changed, 115 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/ref/alter_aggregate.sgml b/doc/src/sgml/ref/alter_aggregate.sgml index d0a39ba7b5e..cc11e077561 100644 --- a/doc/src/sgml/ref/alter_aggregate.sgml +++ b/doc/src/sgml/ref/alter_aggregate.sgml @@ -149,6 +149,13 @@ ALTER AGGREGATE name ( aggregate_signatu if VARIADIC "any" was used in both the direct and aggregated argument lists, write VARIADIC "any" only once. + + + ALTER AGGREGATE deals only with generic properties of + an aggregate, such as its name. To change the aggregate-specific + properties of an aggregate such as its support functions, replace its + definition entirely with CREATE OR REPLACE AGGREGATE. + diff --git a/doc/src/sgml/ref/create_aggregate.sgml b/doc/src/sgml/ref/create_aggregate.sgml index 0472ac2e874..9d12c8f59ac 100644 --- a/doc/src/sgml/ref/create_aggregate.sgml +++ b/doc/src/sgml/ref/create_aggregate.sgml @@ -41,6 +41,7 @@ CREATE [ OR REPLACE ] AGGREGATE nameminitial_condition ] [ , SORTOP = sort_operator ] + [ , SUPPORT = psfunc ] [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ] ) @@ -53,6 +54,7 @@ CREATE [ OR REPLACE ] AGGREGATE nameinitial_condition ] + [ , SUPPORT = psfunc ] [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ] [ , HYPOTHETICAL ] ) @@ -80,6 +82,7 @@ CREATE [ OR REPLACE ] AGGREGATE nameminitial_condition ] [ , SORTOP = sort_operator ] + [ , SUPPORT = psfunc ] ) @@ -628,6 +631,18 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1; + + psfunc + + + The name (optionally schema-qualified) of a planner support + function to use for this aggregate. See + for details. + You must be superuser to use this option. + + + + PARALLEL = { SAFE | RESTRICTED | UNSAFE } diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 2b8a11e7ad0..35916a1c25c 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -4167,7 +4167,7 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, It is also possible to attach a planner support - function to an SQL-callable function (called + function to an SQL-callable function or aggregate (called its target function), and thereby provide knowledge about the target function that is too complex to be represented declaratively. Planner support functions have to be @@ -4241,6 +4241,22 @@ supportfn(internal) returns internal normal execution of the target function. + + Aggregate function calls can also be simplified during planning. For + example, COUNT(x) can be + replaced by COUNT(*) + when x is known to not be null. This can be + done by a support function that implements + the SupportRequestSimplifyAggref request type. The + support function will be called for each instance of its target aggregate + found in a query parse tree. If it finds that the particular call can be + replaced, it can build and return a new node, usually another aggregate + call, leaving the node it was given unmodified. As with + SupportRequestSimplify, it is the support function's + responsibility that the replacement be equivalent to normal execution of + the target aggregate. + + For target functions that return boolean, it is often useful to estimate the fraction of rows that will be selected by a WHERE clause using that diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c index 243b952b9cc..4d98a7584ae 100644 --- a/src/backend/catalog/pg_aggregate.c +++ b/src/backend/catalog/pg_aggregate.c @@ -68,6 +68,7 @@ AggregateCreate(const char *aggName, char finalfnModify, char mfinalfnModify, List *aggsortopName, + List *aggsupportfuncName, Oid aggTransType, int32 aggTransSpace, Oid aggmTransType, @@ -92,6 +93,7 @@ AggregateCreate(const char *aggName, Oid minvtransfn = InvalidOid; /* can be omitted */ Oid mfinalfn = InvalidOid; /* can be omitted */ Oid sortop = InvalidOid; /* can be omitted */ + Oid supportfn = InvalidOid; /* can be omitted */ Oid *aggArgTypes = parameterTypes->values; bool mtransIsStrict = false; Oid rettype; @@ -581,6 +583,35 @@ AggregateCreate(const char *aggName, false, -1); } + /* + * Validate the planner support function, if present. + */ + if (aggsupportfuncName) + { + /* signature is always support(internal) returns internal */ + fnArgs[0] = INTERNALOID; + + supportfn = lookup_agg_function(aggsupportfuncName, 1, + fnArgs, InvalidOid, + &rettype); + + if (rettype != INTERNALOID) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("return type of support function %s is not %s", + NameListToString(aggsupportfuncName), + format_type_be(INTERNALOID)))); + + /* + * Specifying a support function requires superuser, same as in CREATE + * FUNCTION. + */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to specify a support function"))); + } + /* * permission checks on used types */ @@ -639,7 +670,7 @@ AggregateCreate(const char *aggName, PointerGetDatum(NULL), /* trftypes */ NIL, /* trfoids */ PointerGetDatum(NULL), /* proconfig */ - InvalidOid, /* no prosupport */ + supportfn, /* prosupport */ 1, /* procost */ 0); /* prorows */ procOid = myself.objectId; diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index 41b45dc6402..d26cfd8081d 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -74,6 +74,7 @@ DefineAggregate(ParseState *pstate, char finalfuncModify = 0; char mfinalfuncModify = 0; List *sortoperatorName = NIL; + List *supportfuncName = NIL; TypeName *baseType = NULL; TypeName *transType = NULL; TypeName *mtransType = NULL; @@ -155,6 +156,8 @@ DefineAggregate(ParseState *pstate, mfinalfuncModify = extractModify(defel); else if (strcmp(defel->defname, "sortop") == 0) sortoperatorName = defGetQualifiedName(defel); + else if (strcmp(defel->defname, "support") == 0) + supportfuncName = defGetQualifiedName(defel); else if (strcmp(defel->defname, "basetype") == 0) baseType = defGetTypeName(defel); else if (strcmp(defel->defname, "hypothetical") == 0) @@ -462,6 +465,7 @@ DefineAggregate(ParseState *pstate, finalfuncModify, mfinalfuncModify, sortoperatorName, /* sort operator name */ + supportfuncName, /* planner support func name */ transTypeId, /* transition data type */ transSpace, /* transition space */ mtransTypeId, /* transition data type */ diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 0abc80ea5b6..358ac1d390e 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -15582,6 +15582,7 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) const char *agginitval; const char *aggminitval; const char *proparallel; + const char *prosupport; char defaultfinalmodify; /* Do nothing if not dumping schema */ @@ -15650,11 +15651,18 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, "aggfinalmodify,\n" - "aggmfinalmodify\n"); + "aggmfinalmodify,\n"); else appendPQExpBufferStr(query, "'0' AS aggfinalmodify,\n" - "'0' AS aggmfinalmodify\n"); + "'0' AS aggmfinalmodify,\n"); + + if (fout->remoteVersion >= 120000) + appendPQExpBufferStr(query, + "prosupport\n"); + else + appendPQExpBufferStr(query, + "'-' AS prosupport\n"); appendPQExpBufferStr(query, "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p " @@ -15696,6 +15704,7 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) agginitval = PQgetvalue(res, 0, i_agginitval); aggminitval = PQgetvalue(res, 0, i_aggminitval); proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel")); + prosupport = PQgetvalue(res, 0, PQfnumber(res, "prosupport")); { char *funcargs; @@ -15824,6 +15833,11 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) free(aggsortconvop); } + if (strcmp(prosupport, "-") != 0) + { + appendPQExpBuffer(details, ",\n SUPPORT = %s", prosupport); + } + if (aggkind == AGGKIND_HYPOTHETICAL) appendPQExpBufferStr(details, ",\n HYPOTHETICAL"); diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h index 2b4f5dae5f2..2668b035859 100644 --- a/src/include/catalog/pg_aggregate.h +++ b/src/include/catalog/pg_aggregate.h @@ -175,6 +175,7 @@ extern ObjectAddress AggregateCreate(const char *aggName, char finalfnModify, char mfinalfnModify, List *aggsortopName, + List *aggsupportfuncName, Oid aggTransType, int32 aggTransSpace, Oid aggmTransType, diff --git a/src/test/regress/expected/create_aggregate.out b/src/test/regress/expected/create_aggregate.out index dcf69094237..68062620efa 100644 --- a/src/test/regress/expected/create_aggregate.out +++ b/src/test/regress/expected/create_aggregate.out @@ -30,12 +30,27 @@ CREATE AGGREGATE oldcnt ( -- aggregate that only cares about null/nonnull input CREATE AGGREGATE newcnt ("any") ( sfunc = int8inc_any, stype = int8, + support = int8inc_support, initcond = '0' ); COMMENT ON AGGREGATE nosuchagg (*) IS 'should fail'; ERROR: aggregate nosuchagg(*) does not exist COMMENT ON AGGREGATE newcnt (*) IS 'an agg(*) comment'; COMMENT ON AGGREGATE newcnt ("any") IS 'an agg(any) comment'; +-- verify that newcnt's support function enables run-condition optimization +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT newcnt(ten) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) c + FROM tenk1) t +WHERE c = 1; + QUERY PLAN +------------------------------------------------------------- + WindowAgg + Window: w1 AS (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) + Run Condition: (newcnt(tenk1.ten) OVER w1 = 1) + -> Seq Scan on tenk1 +(4 rows) + -- multi-argument aggregate create function sum3(int8,int8,int8) returns int8 as 'select $1 + $2 + $3' language sql strict immutable; diff --git a/src/test/regress/sql/create_aggregate.sql b/src/test/regress/sql/create_aggregate.sql index d4b4036fd7d..6b88b9735af 100644 --- a/src/test/regress/sql/create_aggregate.sql +++ b/src/test/regress/sql/create_aggregate.sql @@ -35,6 +35,7 @@ CREATE AGGREGATE oldcnt ( -- aggregate that only cares about null/nonnull input CREATE AGGREGATE newcnt ("any") ( sfunc = int8inc_any, stype = int8, + support = int8inc_support, initcond = '0' ); @@ -42,6 +43,13 @@ COMMENT ON AGGREGATE nosuchagg (*) IS 'should fail'; COMMENT ON AGGREGATE newcnt (*) IS 'an agg(*) comment'; COMMENT ON AGGREGATE newcnt ("any") IS 'an agg(any) comment'; +-- verify that newcnt's support function enables run-condition optimization +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT newcnt(ten) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) c + FROM tenk1) t +WHERE c = 1; + -- multi-argument aggregate create function sum3(int8,int8,int8) returns int8 as 'select $1 + $2 + $3' language sql strict immutable; From 250942b0d8212f8bdb10b9d63a911aeea5dd4de0 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 24 Aug 2026 14:20:47 +0200 Subject: [PATCH 436/481] Fix untranslatable message that was pasted together at run time --- src/backend/storage/page/bufpage.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c index 1fdfda59edd..8df74618fcd 100644 --- a/src/backend/storage/page/bufpage.c +++ b/src/backend/storage/page/bufpage.c @@ -160,9 +160,11 @@ PageIsVerified(PageData *page, BlockNumber blkno, int flags, bool *checksum_fail if ((flags & (PIV_LOG_WARNING | PIV_LOG_LOG)) != 0) ereport(flags & PIV_LOG_WARNING ? WARNING : LOG, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("page verification failed, calculated checksum %u but expected %u%s", - checksum, p->pd_checksum, - (flags & PIV_ZERO_BUFFERS_ON_ERROR ? ", buffer will be zeroed" : "")))); + (flags & PIV_ZERO_BUFFERS_ON_ERROR) ? + errmsg("page verification failed, calculated checksum %u but expected %u, buffer will be zeroed", + checksum, p->pd_checksum) : + errmsg("page verification failed, calculated checksum %u but expected %u", + checksum, p->pd_checksum))); if (header_sane && (flags & PIV_IGNORE_CHECKSUM_FAILURE)) return true; From 3b984ab52a4eb667b49271fbde5dfbff7b5ef801 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 24 Aug 2026 11:51:15 -0700 Subject: [PATCH 437/481] Add C test function for pg_locale.h APIs. Test the API independently to account for fallback paths that aren't adequately tested from SQL. The backport to 18 also tests the previously-supported behavior where a size of -1 meant that the string was NUL-terminated. That behavior was later removed in 19. Reviewed-by: Andres Freund Discussion: https://postgr.es/m/v36ssaygf7grb3qzfsjhtdzi7kqd45ds56nyuf7gi5qjml4qbb@ezmfqzmhlrs2 Backpatch-through: 18 --- src/test/regress/expected/misc_functions.out | 40 ++++++ src/test/regress/regress.c | 134 +++++++++++++++++++ src/test/regress/sql/misc_functions.sql | 25 ++++ 3 files changed, 199 insertions(+) diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index c3261bff209..2990e0c4f28 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -861,3 +861,43 @@ SELECT test_instr_time(); t (1 row) +-- +-- C tests for pg_locale.h APIs. No interesting output; tests will +-- ERROR upon failure. +-- +-- The test function is STRICT, so tests will be skipped if the +-- collation is unavailable in the current database encoding +-- (to_regcollation() will return NULL). +-- +CREATE FUNCTION test_pg_locale_apis(oid) + RETURNS void + AS :'regresslib' + LANGUAGE C STRICT; +-- Libc C. Available in every database. +SELECT test_pg_locale_apis(to_regcollation('"C"')); + test_pg_locale_apis +--------------------- + +(1 row) + +-- Builtin C (collate and ctype). Usable only in UTF8 databases. +SELECT test_pg_locale_apis(to_regcollation('ucs_basic')); + test_pg_locale_apis +--------------------- + +(1 row) + +-- Builtin C.UTF-8 (C collate, Unicode ctype). Same encoding restriction. +SELECT test_pg_locale_apis(to_regcollation('pg_c_utf8')); + test_pg_locale_apis +--------------------- + +(1 row) + +-- en-x-icu is present when ICU collations were imported at initdb. +SELECT test_pg_locale_apis(to_regcollation('en-x-icu')); + test_pg_locale_apis +--------------------- + +(1 row) + diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 90bb2a7e881..1a9108d7fb6 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -48,6 +48,7 @@ #include "utils/builtins.h" #include "utils/geo_decls.h" #include "utils/memutils.h" +#include "utils/pg_locale.h" #include "utils/rel.h" #include "utils/typcache.h" @@ -1498,3 +1499,136 @@ test_pglz_decompress(PG_FUNCTION_ARGS) SET_VARSIZE(result, dlen + VARHDRSZ); PG_RETURN_BYTEA_P(result); } + +static void +test_case_mapping(pg_locale_t locale) +{ + char buf[32]; + size_t n; + + n = pg_strlower(NULL, 0, "AbC", 3, locale); + if (n != 3) + elog(ERROR, "pg_strlower() size probe returned %zu, expected 3", n); + n = pg_strlower(buf, 4, "AbC", 3, locale); + if (n != 3 || strcmp(buf, "abc") != 0) + elog(ERROR, "pg_strlower() produced \"%s\"", buf); + + n = pg_strupper(NULL, 0, "AbC", 3, locale); + if (n != 3) + elog(ERROR, "pg_strupper() size probe returned %zu, expected 3", n); + n = pg_strupper(buf, 4, "AbC", 3, locale); + if (n != 3 || strcmp(buf, "ABC") != 0) + elog(ERROR, "pg_strupper() produced \"%s\"", buf); + + n = pg_strfold(buf, 4, "AbC", 3, locale); + if (n != 3 || strcmp(buf, "abc") != 0) + elog(ERROR, "pg_strfold() produced \"%s\"", buf); + + buf[0] = '\0'; + n = pg_strtitle(buf, sizeof(buf), "hello-world", 11, locale); + if (n != 11) + elog(ERROR, "pg_strtitle() returned %zu, expected 11", n); + if (locale->ctype_is_c && strcmp(buf, "Hello-World") != 0) + elog(ERROR, "pg_strtitle() produced \"%s\"", buf); +} + +static void +test_collate(pg_locale_t locale) +{ + char buf[32]; + char pfx[8]; + char x1[8]; + char x2[8]; + size_t n; + + if (pg_strcoll("abc", "abc", locale) != 0 || + pg_strncoll("abc", 3, "abc", 3, locale) != 0 || + pg_strcoll("", "", locale) != 0) + elog(ERROR, "equal strings did not compare equal"); + + if (locale->collate_is_c) + { + if (locale->collate != NULL) + elog(ERROR, "collate_is_c but collate methods are set"); + if (pg_strcoll("abc", "abd", locale) >= 0 || + pg_strcoll("abd", "abc", locale) <= 0 || + pg_strncoll("ab", 2, "abc", 3, locale) >= 0 || + pg_strncoll("abc", 3, "ab", 2, locale) <= 0 || + pg_strncoll("xyz", 3, "abc", 2, locale) <= 0) + elog(ERROR, "C-locale comparison result is wrong"); + + if (!pg_strxfrm_enabled(locale)) + elog(ERROR, "pg_strxfrm_enabled() is false for C locale"); + n = pg_strnxfrm(NULL, 0, "abc", 3, locale); + if (n != 3) + elog(ERROR, "pg_strnxfrm() size probe returned %zu, expected 3", n); + n = pg_strnxfrm(buf, 4, "abc", 3, locale); + if (n != 3 || strcmp(buf, "abc") != 0) + elog(ERROR, "pg_strnxfrm() produced \"%s\"", buf); + n = pg_strxfrm(buf, "abc", 4, locale); + if (n != 3 || strcmp(buf, "abc") != 0) + elog(ERROR, "pg_strxfrm() produced \"%s\"", buf); + n = pg_strnxfrm(buf, 3, "abc", 3, locale); + if (n != 3) + elog(ERROR, "pg_strnxfrm() destsize==srclen returned %zu", n); + n = pg_strnxfrm(buf, 2, "abc", 3, locale); + if (n != 3) + elog(ERROR, "pg_strnxfrm() short dest returned %zu", n); + + if (!pg_strxfrm_prefix_enabled(locale)) + elog(ERROR, "pg_strxfrm_prefix_enabled() is false for C locale"); + n = pg_strnxfrm_prefix(NULL, 0, "abcdef", 6, locale); + if (n != 0) + elog(ERROR, "pg_strnxfrm_prefix() destsize 0 returned %zu", n); + n = pg_strnxfrm_prefix(pfx, 2, "abcdef", 6, locale); + if (n != 2 || memcmp(pfx, "ab", 2) != 0) + elog(ERROR, "pg_strnxfrm_prefix() produced a wrong prefix"); + n = pg_strnxfrm_prefix(pfx, sizeof(pfx), "abc", 3, locale); + if (n != 3 || memcmp(pfx, "abc", 3) != 0) + elog(ERROR, "pg_strnxfrm_prefix() destsize>=srclen produced a wrong result"); + n = pg_strxfrm_prefix(pfx, "abcdef", 2, locale); + if (n != 2 || memcmp(pfx, "ab", 2) != 0) + elog(ERROR, "pg_strxfrm_prefix() produced a wrong prefix"); + + if (pg_strxfrm(x1, "abc", sizeof(x1), locale) >= sizeof(x1) || + pg_strxfrm(x2, "abd", sizeof(x2), locale) >= sizeof(x2) || + (strcmp(x1, x2) < 0) != (pg_strcoll("abc", "abd", locale) < 0)) + elog(ERROR, "pg_strxfrm() disagrees with pg_strcoll()"); + } + else + { + char *tmp; + + if (locale->collate == NULL) + elog(ERROR, "collate methods missing for non-C locale"); + + n = pg_strnxfrm(NULL, 0, "abc", 3, locale); + tmp = palloc(n + 1); + if (pg_strnxfrm(tmp, n + 1, "abc", 3, locale) > n) + elog(ERROR, "pg_strnxfrm() grew on the second call"); + pfree(tmp); + + if (pg_strxfrm_prefix_enabled(locale) && + pg_strnxfrm_prefix(pfx, sizeof(pfx), "abc", 3, locale) > sizeof(pfx)) + elog(ERROR, "pg_strnxfrm_prefix() exceeded destsize"); + } +} + +/* + * Test pg_locale.h APIs directly, to cover cases not easily reachable by SQL. + */ +PG_FUNCTION_INFO_V1(test_pg_locale_apis); +Datum +test_pg_locale_apis(PG_FUNCTION_ARGS) +{ + pg_locale_t locale; + + locale = pg_newlocale_from_collation(PG_GETARG_OID(0)); + if (locale == NULL) + elog(ERROR, "pg_newlocale_from_collation() returned NULL"); + + test_collate(locale); + test_case_mapping(locale); + + PG_RETURN_VOID(); +} diff --git a/src/test/regress/sql/misc_functions.sql b/src/test/regress/sql/misc_functions.sql index 946ee5726cd..950d9ab1a4a 100644 --- a/src/test/regress/sql/misc_functions.sql +++ b/src/test/regress/sql/misc_functions.sql @@ -356,3 +356,28 @@ CREATE FUNCTION test_instr_time() AS :'regresslib' LANGUAGE C; SELECT test_instr_time(); + +-- +-- C tests for pg_locale.h APIs. No interesting output; tests will +-- ERROR upon failure. +-- +-- The test function is STRICT, so tests will be skipped if the +-- collation is unavailable in the current database encoding +-- (to_regcollation() will return NULL). +-- +CREATE FUNCTION test_pg_locale_apis(oid) + RETURNS void + AS :'regresslib' + LANGUAGE C STRICT; + +-- Libc C. Available in every database. +SELECT test_pg_locale_apis(to_regcollation('"C"')); + +-- Builtin C (collate and ctype). Usable only in UTF8 databases. +SELECT test_pg_locale_apis(to_regcollation('ucs_basic')); + +-- Builtin C.UTF-8 (C collate, Unicode ctype). Same encoding restriction. +SELECT test_pg_locale_apis(to_regcollation('pg_c_utf8')); + +-- en-x-icu is present when ICU collations were imported at initdb. +SELECT test_pg_locale_apis(to_regcollation('en-x-icu')); From c96cd80d6055cc2fec3335efe08ca897c6a5c012 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 24 Aug 2026 11:51:35 -0700 Subject: [PATCH 438/481] pg_locale.c: add explanatory comments. Explain the purpose of case mapping functions, rather than just the API. Suggested-by: Andres Freund Discussion: https://postgr.es/m/v36ssaygf7grb3qzfsjhtdzi7kqd45ds56nyuf7gi5qjml4qbb@ezmfqzmhlrs2 Backpatch-through: 18 --- src/backend/utils/adt/pg_locale.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 4f0d0ca5057..7f73cd75956 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1323,6 +1323,9 @@ strupper_c(char *dst, size_t dstsize, const char *src, size_t srclen) * Convert src to lowercase, and return the result length (not including * terminating NUL). * + * Lowercasing is intended for human-readable display. If the goal is to + * convert to a canonical caseless form, see pg_strfold(). + * * src must be in the database encoding with no embedded NULs. If dstsize is * zero, dst may be NULL, which is useful for calculating the required buffer * size before allocating. @@ -1347,6 +1350,11 @@ pg_strlower(char *dst, size_t dstsize, const char *src, size_t srclen, * Convert src to titlecase, and return the result length (not including * terminating NUL). * + * Titlecasing is intended for human-readable display. A titlecase string has + * the initial letter of each word uppercased (or changed to a special + * titlecase form, if available), and all other characters lowercased. Used + * to implement the SQL INITCAP() function. + * * src must be in the database encoding with no embedded NULs. If dstsize is * zero, dst may be NULL, which is useful for calculating the required buffer * size before allocating. @@ -1371,6 +1379,9 @@ pg_strtitle(char *dst, size_t dstsize, const char *src, size_t srclen, * Convert src to uppercase, and return the result length (not including * terminating NUL). * + * Uppercasing is intended for human-readable display. If the goal is to + * convert to a canonical caseless form, see pg_strfold(). + * * src must be in the database encoding with no embedded NULs. If dstsize is * zero, dst may be NULL, which is useful for calculating the required buffer * size before allocating. @@ -1392,7 +1403,17 @@ pg_strupper(char *dst, size_t dstsize, const char *src, size_t srclen, /* * pg_strfold() * - * Casefold src, and return the result length (not including terminating NUL). + * Casefold src, and return the result length (not including terminating + * NUL). + * + * Casefolding produces a canonical string such that, iff the casefolded + * strings are equal, the original strings are a case-insensitive match (the + * strength of this guarantee depends on normalization, provider and locale). + * In practice the result is similar to lowercasing, but the purpose is + * different: lowercasing is for human-readable display; whereas casefolding + * is meant to canonicalize complex mappings reliably without regard for + * display. Unicode guarantees that casefolding is stable across versions if + * the original string consists only of assigned code points. * * src must be in the database encoding with no embedded NULs. If dstsize is * zero, dst may be NULL, which is useful for calculating the required buffer From 5ce1cf485c2382fdd40ce54a0a39bece8f67b451 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 24 Aug 2026 13:33:31 -0700 Subject: [PATCH 439/481] ltree/crc32.c: fix fragile code. Explicitly make space for the NUL when casefolding. No known bug in the previous code, because the previous buffer (size 12) was more than large enough for folding any codepoint with enough room left for a NUL. The builtin provider's limit is 7; ICU's limit seems to be 7 also; and libc always does 1:1 mappings so the real limit is MAX_MULTIBYTE_CHAR_LEN + 1 (size 5). Reviewed-by: Heikki Linnakangas Reviewed-by: Rithvika Devisetti Discussion: https://postgr.es/m/2cfbc37ae8deccd3825e36b7f31c391cbf8ff9b8.camel@j-davis.com Backpatch-through: 18 --- contrib/ltree/crc32.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/contrib/ltree/crc32.c b/contrib/ltree/crc32.c index d21bed31fdd..1269e707ee5 100644 --- a/contrib/ltree/crc32.c +++ b/contrib/ltree/crc32.c @@ -32,13 +32,14 @@ ltree_crc32_sz(const char *buf, int size) INIT_TRADITIONAL_CRC32(crc); while (size > 0) { - char foldstr[UNICODE_CASEMAP_BUFSZ]; + /* max space required to map single codepoint, including NUL */ + char foldstr[UNICODE_CASEMAP_BUFSZ + 1]; int srclen = pg_mblen_range(p, end); size_t foldlen; /* fold one codepoint at a time */ - foldlen = pg_strfold(foldstr, UNICODE_CASEMAP_BUFSZ, p, srclen, - locale); + foldlen = pg_strfold(foldstr, sizeof(foldstr), p, srclen, locale); + Assert(foldlen < sizeof(foldstr)); COMP_TRADITIONAL_CRC32(crc, foldstr, foldlen); From d6e4e22e9143749a9b629f2149e78edf2b6e0ec0 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Tue, 25 Aug 2026 10:43:08 +1200 Subject: [PATCH 440/481] Align random test function parameters in test_bitmapset 53a981ed5 adjusted test_random_offset_operations() so that the minimum value parameter came before the maximum value parameter. Here we adjust test_random_operations() so that it accepts absolute numbers for the minimum and maximum values. Previously the maximum value to put in the random Bitmapset was the minimum value plus the range. Also align the parameter order with test_random_offset_operations() to make these functions consistent with each other. Backpatch to v19 as test_random_operations() is new there. Author: David Rowley Reviewed-by: Greg Burd Discussion: https://postgr.es/m/66d041b4-32f4-4097-bb2c-0e7147337a5e@app.fastmail.com Backpatch-through: 19 --- .../expected/test_bitmapset.out | 2 +- .../test_bitmapset/sql/test_bitmapset.sql | 2 +- .../modules/test_bitmapset/test_bitmapset.c | 38 +++++++++++-------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/test/modules/test_bitmapset/expected/test_bitmapset.out b/src/test/modules/test_bitmapset/expected/test_bitmapset.out index 0b72b91cd1f..f126790a774 100644 --- a/src/test/modules/test_bitmapset/expected/test_bitmapset.out +++ b/src/test/modules/test_bitmapset/expected/test_bitmapset.out @@ -1569,7 +1569,7 @@ SELECT test_bms_nonempty_difference('(b 1 2)', '(b 50 100)') AS result; (1 row) -- random operations -SELECT test_random_operations(NULL, 10000, 81920, 0) > 0 AS result; +SELECT test_random_operations(NULL, 10000, 0, 81920) > 0 AS result; result -------- t diff --git a/src/test/modules/test_bitmapset/sql/test_bitmapset.sql b/src/test/modules/test_bitmapset/sql/test_bitmapset.sql index c53232e0ada..333591f6360 100644 --- a/src/test/modules/test_bitmapset/sql/test_bitmapset.sql +++ b/src/test/modules/test_bitmapset/sql/test_bitmapset.sql @@ -401,6 +401,6 @@ SELECT test_bms_nonempty_difference('(b 100)', '(b 5)') AS result; SELECT test_bms_nonempty_difference('(b 1 2)', '(b 50 100)') AS result; -- random operations -SELECT test_random_operations(NULL, 10000, 81920, 0) > 0 AS result; +SELECT test_random_operations(NULL, 10000, 0, 81920) > 0 AS result; DROP EXTENSION test_bitmapset; diff --git a/src/test/modules/test_bitmapset/test_bitmapset.c b/src/test/modules/test_bitmapset/test_bitmapset.c index 66b6badb82f..5dc0151a898 100644 --- a/src/test/modules/test_bitmapset/test_bitmapset.c +++ b/src/test/modules/test_bitmapset/test_bitmapset.c @@ -585,10 +585,11 @@ test_bitmap_match(PG_FUNCTION_ARGS) * equivalent C functions, this stresses Bitmapsets in a random fashion for * various operations. * - * "min_value" is the minimal value used for the members, that will stand - * up to a range of "max_range". "num_ops" defines the number of time each - * operation is done. "seed" is a random seed used to calculate the member - * values. When "seed" is NULL, a random seed will be chosen automatically. + * Arguments: + * arg1: optional random seed. NULL autoselects the seed. + * arg2: defines the number of times each operation is done. + * arg3: the minimum bitmapset member number to use in the random set. + * arg4: the maximum bitmapset member number to use in the random set. * * The return value is the number of times all operations have been executed. */ @@ -602,9 +603,10 @@ test_random_operations(PG_FUNCTION_ARGS) pg_prng_state state; uint64 seed = GetCurrentTimestamp(); int num_ops; - int max_range; int min_value; + int max_value; int member; + uint32 range; int *members; int num_members = 0; int total_ops = 0; @@ -612,18 +614,22 @@ test_random_operations(PG_FUNCTION_ARGS) if (!PG_ARGISNULL(0)) seed = PG_GETARG_INT64(0); - num_ops = PG_GETARG_INT32(1); - max_range = PG_GETARG_INT32(2); - min_value = PG_GETARG_INT32(3); - - if (PG_ARGISNULL(1) || num_ops <= 0) + if (PG_ARGISNULL(1) || PG_GETARG_INT32(1) <= 0) elog(ERROR, "invalid number of operations"); - if (PG_ARGISNULL(2) || max_range <= 0) - elog(ERROR, "invalid maximum range"); - if (PG_ARGISNULL(3) || min_value < 0) + if (PG_ARGISNULL(2) || PG_GETARG_INT32(2) < 0) elog(ERROR, "invalid minimum value"); + if (PG_ARGISNULL(3) || PG_GETARG_INT32(3) < 0) + elog(ERROR, "invalid maximum value"); + + num_ops = PG_GETARG_INT32(1); + min_value = PG_GETARG_INT32(2); + max_value = PG_GETARG_INT32(3); + + if (max_value < min_value) + elog(ERROR, "maximum value must be greater than or equal to minimum value"); pg_prng_seed(&state, seed); + range = (uint32) max_value - (uint32) min_value + 1; /* * There can be up to "num_ops" members added. This is very unlikely, @@ -637,7 +643,7 @@ test_random_operations(PG_FUNCTION_ARGS) { CHECK_FOR_INTERRUPTS(); - member = pg_prng_uint32(&state) % max_range + min_value; + member = min_value + (pg_prng_uint32(&state) % range); if (!bms_is_member(member, bms1)) members[num_members++] = member; @@ -649,7 +655,7 @@ test_random_operations(PG_FUNCTION_ARGS) { CHECK_FOR_INTERRUPTS(); - member = pg_prng_uint32(&state) % max_range + min_value; + member = min_value + (pg_prng_uint32(&state) % range); if (!bms_is_member(member, bms2)) members[num_members++] = member; @@ -724,7 +730,7 @@ test_random_operations(PG_FUNCTION_ARGS) switch (pg_prng_uint32(&state) % 3) { case 0: /* add */ - member = pg_prng_uint32(&state) % max_range + min_value; + member = min_value + (pg_prng_uint32(&state) % range); if (!bms_is_member(member, bms)) members[num_members++] = member; bms = bms_add_member(bms, member); From d446ca2c459c5541c257fbff05ec5a0bdbeb6a0c Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Tue, 25 Aug 2026 10:16:58 +0900 Subject: [PATCH 441/481] Don't assume DISTINCT ON implies uniqueness when the tlist has SRFs query_is_distinct_for() treated a subquery's DISTINCT ON clause as proof that its output is unique over the DISTINCT ON columns, even if the targetlist contains set-returning functions. That's not true: when the query has an ORDER BY, the planner postpones evaluation of SRFs that are not DISTINCT ON or ORDER BY columns until after the Unique step, so the subquery can produce duplicates of the DISTINCT ON columns. Relying on this bogus uniqueness proof allowed join removal and unique-inner joins to produce wrong results. Plain DISTINCT is not affected, since all tlist columns are DISTINCT columns there, and so any SRFs get expanded before the Unique step. To fix, make query_supports_distinctness() and query_is_distinct_for() refuse to prove distinctness via DISTINCT ON if the targetlist contains any SRFs. This is more conservative than necessary, since the SRFs are only postponed when there is an ORDER BY and none of them appear in a sort/group column, but it doesn't seem worth the trouble to check that precisely. Author: Richard Guo Reviewed-by: Tom Lane Discussion: https://postgr.es/m/CAMbWs4-hfd1Pyy_zBejsVUSy-3dx16rz2hgUakkKnAg3qg2q=Q@mail.gmail.com Backpatch-through: 14 --- src/backend/optimizer/plan/analyzejoins.c | 16 +++++++---- src/test/regress/expected/join.out | 33 +++++++++++++++++++++++ src/test/regress/sql/join.sql | 12 +++++++++ 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c index 881950e5264..9b694104aa3 100644 --- a/src/backend/optimizer/plan/analyzejoins.c +++ b/src/backend/optimizer/plan/analyzejoins.c @@ -1280,8 +1280,9 @@ rel_is_distinct_for(PlannerInfo *root, RelOptInfo *rel, List *clause_list, bool query_supports_distinctness(Query *query) { - /* SRFs break distinctness except with DISTINCT, see below */ - if (query->hasTargetSRFs && query->distinctClause == NIL) + /* SRFs break distinctness except with plain DISTINCT, see below */ + if (query->hasTargetSRFs && + (query->distinctClause == NIL || query->hasDistinctOn)) return false; /* check for features we can prove distinctness with */ @@ -1333,10 +1334,15 @@ query_is_distinct_for(Query *query, List *distinct_cols) /* * DISTINCT (including DISTINCT ON) guarantees uniqueness if all the * columns in the DISTINCT clause appear in colnos and operator semantics - * match. This is true even if there are SRFs in the DISTINCT columns or - * elsewhere in the tlist. + * match. With plain DISTINCT this is true even if there are SRFs in the + * tlist, since they are all DISTINCT columns and hence get expanded + * before the Unique step. But with DISTINCT ON, the planner may postpone + * SRFs that are not DISTINCT ON or ORDER BY columns until after the + * Unique step, which can produce duplicates of the DISTINCT ON columns; + * so we can't rely on DISTINCT ON if there are any tlist SRFs. */ - if (query->distinctClause) + if (query->distinctClause && + !(query->hasTargetSRFs && query->hasDistinctOn)) { foreach(l, query->distinctClause) { diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index 05f359d3aa7..deca5617ac8 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -6497,6 +6497,39 @@ select d.* from d left join (select distinct * from b) s -> Seq Scan on d (9 rows) +-- join removal is not possible when the subquery has DISTINCT ON and a +-- set-returning function that is not a DISTINCT ON column +explain (costs off) +select d.* from d left join + (select distinct on (id) id, generate_series(1, 2) as g from b order by id) s + on d.a = s.id + order by 1, 2; + QUERY PLAN +----------------------------------------------------------------------- + Sort + Sort Key: d.a, d.b + -> Hash Left Join + Hash Cond: (d.a = s.id) + -> Seq Scan on d + -> Hash + -> Subquery Scan on s + -> ProjectSet + -> Unique + -> Index Only Scan using b_pkey on b +(10 rows) + +select d.* from d left join + (select distinct on (id) id, generate_series(1, 2) as g from b order by id) s + on d.a = s.id + order by 1, 2; + a | b +---+--- + 1 | 3 + 1 | 3 + 2 | 2 + 3 | 1 +(4 rows) + -- join removal is not possible here explain (costs off) select 1 from a t1 diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index 450bd5bbf2c..c0ff6c945b0 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -2385,6 +2385,18 @@ explain (costs off) select d.* from d left join (select distinct * from b) s on d.a = s.id; +-- join removal is not possible when the subquery has DISTINCT ON and a +-- set-returning function that is not a DISTINCT ON column +explain (costs off) +select d.* from d left join + (select distinct on (id) id, generate_series(1, 2) as g from b order by id) s + on d.a = s.id + order by 1, 2; +select d.* from d left join + (select distinct on (id) id, generate_series(1, 2) as g from b order by id) s + on d.a = s.id + order by 1, 2; + -- join removal is not possible here explain (costs off) select 1 from a t1 From 2c654c4ea1b6a960dd6cda1387dd1dd335e6e651 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Tue, 25 Aug 2026 20:16:52 +1200 Subject: [PATCH 442/481] Fix incorrect cast in Assert This was introduced in e3e26d04b, so backpatch to v19. Reported-by: Lev Nikolaev Discussion: https://postgr.es/m/3e991e23-2260-459f-b3d0-e84fb48d353a@tantorlabs.com Backpatch-through: 19 --- src/backend/nodes/bitmapset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c index f053d8c4d64..b303dcf7e9a 100644 --- a/src/backend/nodes/bitmapset.c +++ b/src/backend/nodes/bitmapset.c @@ -1365,7 +1365,7 @@ bms_prev_member(const Bitmapset *a, int prevbit) return -2; /* Validate callers didn't give us something out of range */ - Assert(prevbit < 0 || prevbit <= (unsigned int) (a->nwords * BITS_PER_BITMAPWORD)); + Assert(prevbit < 0 || prevbit <= (unsigned int) a->nwords * BITS_PER_BITMAPWORD); /* * Transform -1 (or any negative number) to the highest possible bit we From 77027b347cf94b38aa93f86d213002cd608230a4 Mon Sep 17 00:00:00 2001 From: Etsuro Fujita Date: Tue, 25 Aug 2026 17:50:01 +0900 Subject: [PATCH 443/481] Further cleanup related to statistics import support in postgres_fdw. * Reorder the conditions in an if-else block for efficiency. * Reorder struct definitions for readability. * Reorder arguments for some functions for consistency. * Move variables to the required scope. * Rename a variable to match an input argument. * Add/Tweak some comments/docs for clarity. Author: Etsuro Fujita Reviewed-by: Bharath Rupireddy Discussion: https://postgr.es/m/CAPmGK14otpa7XZyBO5GxDABUK9OPWFLsAwoQP3ugNdXq%3DK4J1g%40mail.gmail.com Backpatch-through: 19 --- contrib/postgres_fdw/postgres_fdw.c | 136 ++++++++++++++-------------- doc/src/sgml/fdwhandler.sgml | 2 +- src/backend/commands/analyze.c | 5 + 3 files changed, 76 insertions(+), 67 deletions(-) diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 209ff7b8fef..fde344fb7ea 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -323,25 +323,6 @@ typedef struct List *already_used; /* expressions already dealt with */ } ec_member_foreign_arg; -/* Pairs of remote columns with local columns */ -typedef struct -{ - AttrNumber local_attnum; - char *local_attname; - char *remote_attname; - int res_index; -} RemoteAttributeMapping; - -/* Result sets that are returned from a foreign statistics scan */ -typedef struct -{ - PGresult *rel; - PGresult *att; - double livetuples; - double deadtuples; - int version; -} RemoteStatsResults; - /* Column order in relation stats query */ enum RelStatsColumns { @@ -371,6 +352,25 @@ enum AttStatsColumns ATTSTATS_NUM_FIELDS, }; +/* Result sets that are returned from a foreign statistics scan */ +typedef struct +{ + PGresult *rel; /* result for relation stats query */ + PGresult *att; /* result for attribute stats query */ + double livetuples; /* livetuples estimates, for pgstat report */ + double deadtuples; /* deadtuples estimates, for pgstat report */ + int version; /* version of remote server */ +} RemoteStatsResults; + +/* Pairs of remote columns with local columns */ +typedef struct +{ + AttrNumber local_attnum; /* attribute number of local column */ + char *local_attname; /* attribute name of local column */ + char *remote_attname; /* attribute name of remote column */ + int res_index; /* index of row in attribute stats result */ +} RemoteAttributeMapping; + /* * SQL functions */ @@ -566,12 +566,12 @@ static void analyze_row_processor(PGresult *res, int row, PgFdwAnalyzeState *astate); static bool fetch_remote_statistics(Relation relation, List *va_cols, - ForeignTable *table, const char *local_schemaname, const char *local_relname, - int *p_attrcnt, + ForeignTable *table, + RemoteStatsResults *remstats, RemoteAttributeMapping **p_remattrmap, - RemoteStatsResults *remstats); + int *p_attrcnt); static PGresult *fetch_relstats(PGconn *conn, Relation relation); static PGresult *fetch_attstats(PGconn *conn, int server_version_num, const char *remote_schemaname, const char *remote_relname, @@ -586,14 +586,14 @@ static bool match_attrmap(PGresult *res, const char *local_relname, const char *remote_schemaname, const char *remote_relname, - int attrcnt, - RemoteAttributeMapping *remattrmap); + RemoteAttributeMapping *remattrmap, + int attrcnt); static bool import_fetched_statistics(Relation relation, const char *schemaname, const char *relname, - int attrcnt, + RemoteStatsResults *remstats, const RemoteAttributeMapping *remattrmap, - RemoteStatsResults *remstats); + int attrcnt); static char *get_opt_value(PGresult *res, int row, int col); static void set_text_arg(NullableDatum *arg, const char *s); static void set_int32_arg(NullableDatum *arg, const char *s); @@ -5533,12 +5533,12 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel) starttime = GetCurrentTimestamp(); ok = fetch_remote_statistics(relation, va_cols, - table, schemaname, relname, - &attrcnt, &remattrmap, &remstats); + schemaname, relname, table, + &remstats, &remattrmap, &attrcnt); if (ok) ok = import_fetched_statistics(relation, schemaname, relname, - attrcnt, remattrmap, &remstats); + &remstats, remattrmap, attrcnt); if (ok) { @@ -5564,12 +5564,12 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel) static bool fetch_remote_statistics(Relation relation, List *va_cols, - ForeignTable *table, const char *local_schemaname, const char *local_relname, - int *p_attrcnt, + ForeignTable *table, + RemoteStatsResults *remstats, RemoteAttributeMapping **p_remattrmap, - RemoteStatsResults *remstats) + int *p_attrcnt) { const char *remote_schemaname = NULL; const char *remote_relname = NULL; @@ -5578,15 +5578,13 @@ fetch_remote_statistics(Relation relation, PGresult *relstats = NULL; PGresult *attstats = NULL; int server_version_num; - RemoteAttributeMapping *remattrmap = NULL; - int attrcnt = 0; char relkind; double reltuples; bool ok = false; ListCell *lc; /* - * Assume the remote schema/relation names are the same as the local name + * Assume the remote schema/table names are the same as the local name * unless the foreign table's options tell us otherwise. */ remote_schemaname = local_schemaname; @@ -5604,6 +5602,9 @@ fetch_remote_statistics(Relation relation, /* * Get connection to the foreign server. Connection manager will * establish new connection if necessary. + * + * Note that unlike the sampling case, we only query pg_class and + * pg_stats, so we do the remote access as the current user. */ user = GetUserMapping(GetUserId(), table->serverid); conn = GetConnection(user, false, NULL); @@ -5640,36 +5641,28 @@ fetch_remote_statistics(Relation relation, * If the reltuples value > 0, then we can expect to find attribute stats * for the remote table. * - * In v14 or later, if a reltuples value is -1, it means the table has - * never been analyzed, so we wouldn't expect to find the stats for the - * table; fallback to sampling in that case. If the value is 0, it means - * it was empty; in which case skip the stats and import relation stats - * only. + * In v14 or later, if the value is -1, it means the table had never been + * analyzed, so we wouldn't expect to find the stats; fallback to sampling + * in that case. If the value is 0, it means it was empty, in which case + * we don't need the stats, so import relation stats only. * * In versions prior to v14, a value of 0 was ambiguous; it could mean - * that the table had never been analyzed, or that it was empty. Either - * way, we wouldn't expect to find the stats for the table, so we fallback - * to sampling. + * that the table had never been analyzed, or that it was empty. Assuming + * the former, fallback to sampling. */ reltuples = strtod(PQgetvalue(relstats, 0, RELSTATS_RELTUPLES), NULL); - if (((server_version_num < 140000) && (reltuples == 0)) || - ((server_version_num >= 140000) && (reltuples == -1))) - { - ereport(WARNING, - errmsg("could not import statistics for foreign table \"%s.%s\" --- remote table \"%s.%s\" has no relation statistics to import", - local_schemaname, local_relname, - remote_schemaname, remote_relname)); - goto fetch_cleanup; - } - if (reltuples > 0) { + RemoteAttributeMapping *remattrmap; + int attrcnt; StringInfoData column_list; + /* For columns to analyze, create mappings of local/remote columns. */ *p_remattrmap = remattrmap = build_remattrmap(relation, va_cols, &attrcnt, &column_list); *p_attrcnt = attrcnt; + /* Try to get attribute stats if needed. */ if (attrcnt > 0) { /* Fetch attribute stats. */ @@ -5683,10 +5676,19 @@ fetch_remote_statistics(Relation relation, if (!match_attrmap(attstats, local_schemaname, local_relname, remote_schemaname, remote_relname, - attrcnt, remattrmap)) + remattrmap, attrcnt)) goto fetch_cleanup; } } + else if (((server_version_num < 140000) && (reltuples == 0)) || + ((server_version_num >= 140000) && (reltuples == -1))) + { + ereport(WARNING, + errmsg("could not import statistics for foreign table \"%s.%s\" --- remote table \"%s.%s\" has no relation statistics to import", + local_schemaname, local_relname, + remote_schemaname, remote_relname)); + goto fetch_cleanup; + } /* We assume that we have no dead tuple. */ remstats->deadtuples = 0.0; @@ -5793,8 +5795,9 @@ fetch_attstats(PGconn *conn, int server_version_num, } /* - * Build the mappings of local columns to remote columns and create a column - * list used for constructing the fetch_attstats query. + * For columns to analyze, build the mappings of local columns to remote + * columns, and create a column list used for constructing the fetch_attstats + * query. */ static RemoteAttributeMapping * build_remattrmap(Relation relation, List *va_cols, @@ -5812,7 +5815,7 @@ build_remattrmap(Relation relation, List *va_cols, Form_pg_attribute attr = TupleDescAttr(tupdesc, i); char *attname = NameStr(attr->attname); AttrNumber attnum = attr->attnum; - char *remote_attname; + char *colname; List *fc_options; ListCell *lc; @@ -5824,7 +5827,7 @@ build_remattrmap(Relation relation, List *va_cols, continue; /* If the column_name option is not specified, go with attname. */ - remote_attname = attname; + colname = attname; fc_options = GetForeignColumnOptions(RelationGetRelid(relation), attnum); foreach(lc, fc_options) { @@ -5832,24 +5835,24 @@ build_remattrmap(Relation relation, List *va_cols, if (strcmp(def->defname, "column_name") == 0) { - remote_attname = defGetString(def); + colname = defGetString(def); break; } } if (attrcnt > 0) appendStringInfoString(column_list, ", "); - deparseStringLiteral(column_list, remote_attname); + deparseStringLiteral(column_list, colname); remattrmap[attrcnt].local_attnum = attnum; remattrmap[attrcnt].local_attname = pstrdup(attname); - remattrmap[attrcnt].remote_attname = pstrdup(remote_attname); + remattrmap[attrcnt].remote_attname = pstrdup(colname); remattrmap[attrcnt].res_index = -1; attrcnt++; } appendStringInfoChar(column_list, ']'); - /* Sort mappings by remote attribute name if needed. */ + /* Sort the mappings by remote_attname if needed. */ if (attrcnt > 1) qsort(remattrmap, attrcnt, sizeof(RemoteAttributeMapping), remattrmap_cmp); @@ -5928,8 +5931,8 @@ match_attrmap(PGresult *res, const char *local_relname, const char *remote_schemaname, const char *remote_relname, - int attrcnt, - RemoteAttributeMapping *remattrmap) + RemoteAttributeMapping *remattrmap, + int attrcnt) { int numrows = PQntuples(res); int row = -1; @@ -6016,9 +6019,9 @@ static bool import_fetched_statistics(Relation relation, const char *schemaname, const char *relname, - int attrcnt, + RemoteStatsResults *remstats, const RemoteAttributeMapping *remattrmap, - RemoteStatsResults *remstats) + int attrcnt) { PGresult *res; NullableDatum args[ATTSTATS_NUM_FIELDS]; @@ -6110,6 +6113,7 @@ import_fetched_statistics(Relation relation, Assert(!args[1].isnull); set_float_arg(&args[2], get_opt_value(res, 0, RELSTATS_RELTUPLES)); Assert(!args[2].isnull); + /* We don't import relallvisible/relallfrozen. */ args[3].value = (Datum) 0; args[3].isnull = true; args[4].value = (Datum) 0; diff --git a/doc/src/sgml/fdwhandler.sgml b/doc/src/sgml/fdwhandler.sgml index 0103fdacfdf..502441fefcb 100644 --- a/doc/src/sgml/fdwhandler.sgml +++ b/doc/src/sgml/fdwhandler.sgml @@ -1430,7 +1430,7 @@ ImportForeignStatistics(Relation relation, If the function imports the statistics successfully, it should return true. Otherwise, return false, in which case AnalyzeForeignTable callback function is - called on the foreign table to collect statistics locally, if supported. + called on the foreign table to generate statistics locally, if supported. diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 597f1f16dc6..c4fb2677207 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -1172,6 +1172,11 @@ examine_attribute(Relation onerel, int attnum, Node *index_expr) return stats; } +/* + * Determine whether the column is analyzable. + * + * If the column is analyzable, return its attstattarget value, if asked to. + */ bool attribute_is_analyzable(Relation onerel, int attnum, Form_pg_attribute attr, int *p_attstattarget) From 31ad154242e2dc9fa9bbc4ebbe31f559e2282d9c Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Tue, 25 Aug 2026 14:11:35 +0300 Subject: [PATCH 444/481] Fix crash on trying to expand a shared memory hash table When a hash table grows large enough we try to expand the directory, but we shouldn't try to do that if the hash table is marked as HASH_FIXED_SIZE. Before commit 9fe9ecd516b that was harmless, although it was a little weird to expand the directory when allocating the new element was doomed to fail later anyway. But the new allocator function added in that commit for shared memory hash tables did not expect to be called after hash table creation at all and would just crash. Fix by ensuring that the allocator is not called after hash table creation for HASH_FIXED_SIZE tables. The crash started with commit 9fe9ecd516b in v19, so backpatch to v19. To trigger the crash, you needed a shared memory hash table of just the right size so that we would attempt to resize it: power-of-2 and at least HASH_SEGSIZE (256) elements. With any other size, you would run out of allocated elements first. Author: Konstantin Knizhnik Reviewed-by: Rahila Syed Discussion: https://www.postgresql.org/message-id/d59221f2-b3d2-41ad-8bf0-d581b42e4cba@garret.ru Backpatch-through: 19 --- src/backend/utils/hash/dynahash.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c index dc7ae64a5a9..f6fc6271a2e 100644 --- a/src/backend/utils/hash/dynahash.c +++ b/src/backend/utils/hash/dynahash.c @@ -931,7 +931,7 @@ hash_search_with_hash_value(HTAB *hashp, * table is the subject of any active hash_seq_search scans. */ if (hctl->freeList[0].nentries > (int64) hctl->max_bucket && - !IS_PARTITIONED(hctl) && !hashp->frozen && + !hctl->isfixed && !IS_PARTITIONED(hctl) && !hashp->frozen && !has_seq_scans(hashp)) (void) expand_table(hashp); } @@ -1494,6 +1494,7 @@ expand_table(HTAB *hashp) HASHBUCKET currElement, nextElement; + Assert(!hctl->isfixed); Assert(!IS_PARTITIONED(hctl)); #ifdef HASH_STATISTICS @@ -1583,6 +1584,7 @@ dir_realloc(HTAB *hashp) int64 old_dirsize; int64 new_dirsize; + Assert(!hashp->hctl->isfixed); if (hashp->hctl->max_dsize != NO_MAX_DSIZE) return false; @@ -1618,6 +1620,8 @@ seg_alloc(HTAB *hashp) { HASHSEGMENT segp; + Assert(!hashp->hctl->isfixed); + segp = (HASHSEGMENT) hashp->alloc(sizeof(HASHBUCKET) * HASH_SEGSIZE, hashp->alloc_arg); if (!segp) From dc8628e55d443120f4759a969ec329474a838ee3 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 26 Aug 2026 10:18:07 +0900 Subject: [PATCH 445/481] doc: Update REPACK-related table rewrite documentation Adding REPACK introduced table-rewrite behavior that overlaps with VACUUM FULL and CLUSTER, but some documentation still mentioned only one of these commands or described the progress and locking behavior imprecisely. Clarify that table-rewriting operations, including REPACK, can change CTIDs. Also describe VACUUM FULL, CLUSTER, and REPACK consistently as table-rewriting operations for disk-space recovery where appropriate, document the pg_stat_progress_repack and compatibility pg_stat_progress_cluster views consistently, and clarify the ACCESS EXCLUSIVE locking behavior of REPACK, including CONCURRENTLY. Backpatch to v19, where REPACK was introduced. Author: Marcos Pegoraro Author: Fujii Masao Discussion: https://postgr.es/m/CAB-JLwaLcHyf=OnLnBsJEbdd57WjWPpK5T7iGFJvAQphjTZj_A@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/ddl.sgml | 4 +++- doc/src/sgml/maintenance.sgml | 45 +++++++++++++++++++++-------------- doc/src/sgml/monitoring.sgml | 24 +++++++++++-------- doc/src/sgml/mvcc.sgml | 12 ++++++---- 4 files changed, 52 insertions(+), 33 deletions(-) diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index 160f4eebb35..dadf5e0dcb9 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -1568,7 +1568,9 @@ CREATE TABLE circles ( although the ctid can be used to locate the row version very quickly, a row's ctid will change if it is - updated or moved by VACUUM FULL. Therefore + updated, or moved by a table-rewriting operation such as + VACUUM FULL, CLUSTER, or + REPACK. Therefore ctid should not be used as a row identifier. A primary key should be used to identify logical rows. diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 88350ebbc73..17a306b172c 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -171,11 +171,13 @@ future reuse. However, it will not return the space to the operating system, except in the special case where one or more pages at the end of a table become entirely free and an exclusive table lock can be - easily obtained. In contrast, VACUUM FULL actively compacts - tables by writing a complete new version of the table file with no dead - space. This minimizes the size of the table, but can take a long time. - It also requires extra disk space for the new copy of the table, until - the operation completes. + easily obtained. In contrast, table-rewriting commands such as + VACUUM FULL, CLUSTER, and + REPACK actively compact tables by writing a complete + new version of the table file without the dead space left by old row + versions. This minimizes the size of the table, but can take a long time. + It also requires extra disk space for the new copy of the table, until the + operation completes. @@ -186,12 +188,14 @@ is not to keep tables at their minimum size, but to maintain steady-state usage of disk space: each table occupies space equivalent to its minimum size plus however much space gets used up between vacuum runs. - Although VACUUM FULL can be used to shrink a table back - to its minimum size and return the disk space to the operating system, - there is not much point in this if the table will just grow again in the - future. Thus, moderately-frequent standard VACUUM runs are a - better approach than infrequent VACUUM FULL runs for - maintaining heavily-updated tables. + Although table-rewriting compaction operations such as + VACUUM FULL, CLUSTER, and + REPACK can be used to shrink a table back to its + minimum size and return the disk space to the operating system, there is + not much point in this if the table will just grow again in the future. + Thus, moderately-frequent standard VACUUM runs are a + better approach than infrequent use of such operations for maintaining + heavily-updated tables. @@ -199,7 +203,8 @@ doing all the work at night when load is low. The difficulty with doing vacuuming according to a fixed schedule is that if a table has an unexpected spike in update activity, it may - get bloated to the point that VACUUM FULL is really necessary + get bloated to the point that a table-rewriting compaction operation such + as VACUUM FULL or REPACK may be needed to reclaim space. Using the autovacuum daemon alleviates this problem, since the daemon schedules vacuuming dynamically in response to update activity. It is unwise to disable the daemon completely unless you @@ -227,16 +232,20 @@ a table contains large numbers of dead row versions as a result of massive update or delete activity. If you have such a table and you need to reclaim the excess disk space it occupies, you will need - to use VACUUM FULL, or alternatively - CLUSTER + to use VACUUM FULL, + CLUSTER, + REPACK, or one of the table-rewriting variants of ALTER TABLE. These commands rewrite an entire new copy of the table and build new indexes for it. All these options require an - ACCESS EXCLUSIVE lock. Note that - they also temporarily use extra disk space approximately equal to the size - of the table, since the old copies of the table and indexes can't be - released until the new ones are complete. + ACCESS EXCLUSIVE lock, except that + REPACK can be run with CONCURRENTLY, + in which case the ACCESS EXCLUSIVE lock is held only + while swapping the table and index files. Note that they also + temporarily use extra disk space approximately equal to the size of the + table, since the old copies of the table and indexes can't be released + until the new ones are complete. diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index d60b6710bfd..66f6127a410 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -417,7 +417,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser pg_stat_progress_repackpg_stat_progress_repack One row for each backend running REPACK, CLUSTER or VACUUM FULL, showing current progress. - . + See . @@ -6413,7 +6413,8 @@ FROM pg_stat_get_backend_idset() AS backendid; VACUUM FULL is running, the backwards-compatibility pg_stat_progress_cluster view will - contain a row for each backend that is currently running either command. + contain a row for each backend that is currently running one of these + commands. The tables below describe the information that will be reported and provide information about how to interpret it. @@ -7087,10 +7088,11 @@ FROM pg_stat_get_backend_idset() AS backendid; - Whenever REPACK is running, + Whenever REPACK, CLUSTER, or + VACUUM FULL is running, the pg_stat_progress_repack view will contain a - row for each backend that is currently running the command. The tables - below describe the information that will be reported and provide + row for each backend that is currently running one of these commands. + The tables below describe the information that will be reported and provide information about how to interpret it. @@ -7141,7 +7143,7 @@ FROM pg_stat_get_backend_idset() AS backendid; relid oid - OID of the table being repacked. + OID of the table being processed. @@ -7150,8 +7152,8 @@ FROM pg_stat_get_backend_idset() AS backendid; command text - The command that is running. Either REPACK or - VACUUM FULL, or CLUSTER. + The command that is running. One of CLUSTER, + REPACK, or VACUUM FULL. @@ -7344,10 +7346,12 @@ FROM pg_stat_get_backend_idset() AS backendid; currently vacuuming. The tables below describe the information that will be reported and provide information about how to interpret it. Progress for VACUUM FULL commands is reported via - pg_stat_progress_cluster + pg_stat_progress_repack, and is also visible via + the backwards-compatibility pg_stat_progress_cluster because both VACUUM FULL and CLUSTER rewrite the table, while regular VACUUM only modifies it - in place. See . + in place. See and + . diff --git a/doc/src/sgml/mvcc.sgml b/doc/src/sgml/mvcc.sgml index 241caeb3593..b1874b8aba3 100644 --- a/doc/src/sgml/mvcc.sgml +++ b/doc/src/sgml/mvcc.sgml @@ -1095,10 +1095,14 @@ ERROR: could not serialize access due to read/write dependencies among transact Acquired by the DROP TABLE, TRUNCATE, REINDEX, - CLUSTER, VACUUM FULL, - and REFRESH MATERIALIZED VIEW (without - ) - commands. Many forms of ALTER INDEX and ALTER TABLE also acquire + CLUSTER, VACUUM FULL, and + REFRESH MATERIALIZED VIEW (without + ) commands. + REPACK also acquires this lock mode. When run + with , REPACK acquires + it only while swapping the table and index files. + Many forms of ALTER INDEX and + ALTER TABLE also acquire a lock at this level. This is also the default lock mode for LOCK TABLE statements that do not specify a mode explicitly. From 4680f32d333da51db3034047595dc0f567410625 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Wed, 26 Aug 2026 14:40:23 +0530 Subject: [PATCH 446/481] Skip relations dropped concurrently in GetSubscriptionRelations(). GetSubscriptionRelations() can see a pg_subscription_rel row for a relation whose pg_class row was removed by a concurrent DROP. In this case, get_rel_relkind() returns '\0'. Skip such relations since they no longer exist and do not need synchronization. Replace the assertion on relkind with an error. Once the dropped relation case is handled, any other unexpected relkind indicates a relation kind that cannot be part of a subscription and should be reported rather than ignored. Author: Vignesh C Reviewed-by: Amit Kapila Reviewed-by: Bharath Rupireddy Reviewed-by: Hayato Kuroda Reviewed-by: Kyotaro Horiguchi Backpatch-through: 19 Discussion: https://postgr.es/m/CALDaNm3eeKocRtQyUPdg2kaxJ-VAo5pwcNytDKNT1Yc0t2V_ug%40mail.gmail.com --- src/backend/catalog/pg_subscription.c | 31 +++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c index 3072a39c456..b3cd805c8d2 100644 --- a/src/backend/catalog/pg_subscription.c +++ b/src/backend/catalog/pg_subscription.c @@ -677,19 +677,32 @@ GetSubscriptionRelations(Oid subid, bool tables, bool sequences, subrel = (Form_pg_subscription_rel) GETSTRUCT(tup); - /* Relation is either a sequence or a table */ relkind = get_rel_relkind(subrel->srrelid); - Assert(relkind == RELKIND_SEQUENCE || relkind == RELKIND_RELATION || - relkind == RELKIND_PARTITIONED_TABLE); - /* Skip sequences if they were not requested */ - if ((relkind == RELKIND_SEQUENCE) && !sequences) + /* The relation may have been dropped concurrently. */ + if (relkind == '\0') continue; - /* Skip tables if they were not requested */ - if ((relkind == RELKIND_RELATION || - relkind == RELKIND_PARTITIONED_TABLE) && !tables) - continue; + /* + * The relation must be either a sequence or a table. Anything else + * indicates an unexpected relation kind for a subscription relation. + */ + if (relkind == RELKIND_SEQUENCE) + { + /* Skip sequences if they were not requested */ + if (!sequences) + continue; + } + else if (relkind == RELKIND_RELATION || + relkind == RELKIND_PARTITIONED_TABLE) + { + /* Skip tables if they were not requested */ + if (!tables) + continue; + } + else + elog(ERROR, "unexpected relkind \"%c\" for relation %u in subscription %u", + relkind, subrel->srrelid, subid); relstate = palloc_object(SubscriptionRelState); relstate->relid = subrel->srrelid; From b259ece92a951e799d8ace7a865d6269cc1cdd71 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Wed, 26 Aug 2026 12:59:18 +0300 Subject: [PATCH 447/481] Fix registering shmem callbacks in single-user mode RegisterShmemCallbacks() should not be called from the postmaster process after postmaster startup. Add an assertion for that, and fix the check for whether it's being called for "after startup" allocations to take single-user mode into account. Author: Ayush Tiwari Discussion: https://www.postgresql.org/message-id/CAJTYsWU7epjUL1-xrpYeOrmkmq20M2Q22Y_SRb8PWQG8KNQyDw@mail.gmail.com Backpatch-through: 19 --- src/backend/storage/ipc/shmem.c | 10 +++++++-- .../test_shmem/t/001_late_shmem_alloc.pl | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index 1fbba9c3a4c..85401f7bff6 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -872,23 +872,29 @@ ShmemAddrIsValid(const void *addr) void RegisterShmemCallbacks(const ShmemCallbacks *callbacks) { - if (shmem_request_state == SRS_DONE && IsUnderPostmaster) + if (shmem_request_state == SRS_DONE) { /* * After-startup initialization or attachment. Call the appropriate * callbacks immediately. + * + * This is not allowed from the postmaster, because the postmaster + * cannot acquire locks. */ if ((callbacks->flags & SHMEM_CALLBACKS_ALLOW_AFTER_STARTUP) == 0) elog(ERROR, "cannot request shared memory at this time"); + Assert(IsUnderPostmaster || !IsPostmasterEnvironment); CallShmemCallbacksAfterStartup(callbacks); } - else + else if (shmem_request_state == SRS_INITIAL) { /* Remember the callbacks for later */ registered_shmem_callbacks = lappend(registered_shmem_callbacks, (void *) callbacks); } + else + elog(ERROR, "cannot request shared memory at this time"); } /* diff --git a/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl b/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl index 5cf07d071ec..546d6a92abe 100644 --- a/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl +++ b/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl @@ -27,6 +27,28 @@ "attach callback is called in each backend"); $node->stop; +### +# Test allocating memory after startup in single-user mode +### +SKIP: +{ + # Skip the test on Windows, as single-user mode would fail on permission + # failure with privileged accounts. + skip 'single-user test is not supported by this platform', 1 + if $windows_os; + my $query = "SELECT get_test_shmem_attach_count();\n"; + my $result = run_log( + [ + 'postgres', '--single', '-F', + '-c' => 'exit_on_error=true', + '-D' => $node->data_dir, + 'postgres' + ], + '<' => \$query); + + ok($result, "shmem area is initialized in single-user mode"); +} + ### # Test that loading via shared_preload_libraries also works ### From 4f0af2635be7963c3250d0469e2c159dd0338574 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Thu, 27 Aug 2026 02:41:21 +1200 Subject: [PATCH 448/481] Close relations opened specifically for AFTER triggers 39dcfda2d fixed an incorrect reuse of ResultRelInfos for AFTER triggers when the ResultRelInfo needed to have a different ri_RootResultRelInfo. That caused an issue in logical replication apply workers as finish_edata() neglects to call ExecCloseResultRelations() and instead relies on ExecCleanupTupleRouting() to close relations opened during partitioning's tuple routing. Since 39dcfda2d, because we may have done some additional table_opens() calls due to having to create an additional ResultRelInfo because of requirements to have a different ri_RootResultRelInfo, we should now be explicitly closing any relations opened on ResultRelInfos in EState's es_trig_target_relations. Since finish_edate() seems to want to avoid calling ExecCloseResultRelations(), add a new external function named ExecCloseTrigTargetRelations(). Reported-by: Hayato Kuroda (Fujitsu) Author: Hayato Kuroda (Fujitsu) Author: David Rowley Reviewed-by: Zhijie Hou (Fujitsu) Discussion: https://postgr.es/m/OS9PR01MB121491E7E05950D108AF9A6D8F5A72@OS9PR01MB12149.jpnprd01.prod.outlook.com Backpatch-through: 15 --- src/backend/executor/execMain.c | 16 ++++++++++++++++ src/backend/replication/logical/worker.c | 12 ++++++++---- src/include/executor/executor.h | 1 + src/test/subscription/t/013_partition.pl | 7 +++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index c3af96989ba..d8bbe467a70 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -1642,6 +1642,22 @@ ExecCloseResultRelations(EState *estate) } } + /* + * Now close any relations that we opened for trigger target + * ResultRelInfos. + */ + ExecCloseTrigTargetRelations(estate); +} + +/* + * Close any relations that have been opened for ResultRelInfos opened + * specifically for trigger target relations. + */ +void +ExecCloseTrigTargetRelations(EState *estate) +{ + ListCell *l; + /* Close any relations that have been opened by ExecGetTriggerResultRel(). */ foreach(l, estate->es_trig_target_relations) { diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index b3cdbce8d10..52c6cc8c596 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -945,12 +945,16 @@ finish_edata(ApplyExecutionData *edata) ExecCleanupTupleRouting(edata->mtstate, edata->proute); /* - * Cleanup. It might seem that we should call ExecCloseResultRelations() - * here, but we intentionally don't. It would close the rel we added to + * Close relations opened specifically for trigger targets. It might seem + * that we should call ExecCloseResultRelations() here, but we + * intentionally don't as that would close the rel we added to * es_opened_result_relations above, which is wrong because we took no - * corresponding refcount. We rely on ExecCleanupTupleRouting() to close - * any other relations opened during execution. + * corresponding refcount. ExecCleanupTupleRouting() closes relations + * opened for tuple routing, while ExecCloseTrigTargetRelations() closes + * any relations we opened for AFTER triggers. */ + ExecCloseTrigTargetRelations(estate); + ExecResetTupleTable(estate->es_tupleTable, false); FreeExecutorState(estate); pfree(edata); diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 1798e6027d4..190e8a4897a 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -703,6 +703,7 @@ extern void ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos Bitmapset *unpruned_relids); extern void ExecCloseRangeTableRelations(EState *estate); extern void ExecCloseResultRelations(EState *estate); +extern void ExecCloseTrigTargetRelations(EState *estate); static inline RangeTblEntry * exec_rt_fetch(Index rti, EState *estate) diff --git a/src/test/subscription/t/013_partition.pl b/src/test/subscription/t/013_partition.pl index 234d4f003b7..21c3a9e261b 100644 --- a/src/test/subscription/t/013_partition.pl +++ b/src/test/subscription/t/013_partition.pl @@ -897,4 +897,11 @@ BEGIN "SELECT a, b, c FROM tab5_1 ORDER BY 1"); is($result, qq(4||1), 'updates of tab5 replicated correctly'); +# Validate we didn't neglect to cleanup any resources on either subscriber. +foreach my $node ($node_subscriber1, $node_subscriber2) +{ + ok(!$node->log_contains(qr/resource was not closed/), + 'check for resource leaks on ' . $node->name); +} + done_testing(); From 4d9224a436f0e728b0b1bdd70e72c798bf4bbe98 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Wed, 26 Aug 2026 12:03:54 -0700 Subject: [PATCH 449/481] Fix crash in subscription refresh on concurrent relation drop. Commit 46b4f5c11b0 made the logical replication origin checks quote the schema and relation names they interpolate into the query sent to the publisher. Those names can be NULL, which that commit overlooked. AlterSubscription_refresh() collects the OIDs of the relations already present in pg_subscription_rel and hands them to check_publications_origin_tables() and check_publications_origin_sequences(), which append the schema-qualified name of each one to the query so that already-subscribed relations are excluded from the check. The relations are never locked, so one of them can be dropped concurrently before its name is read, and get_rel_name() and get_namespace_name() return NULL. quote_literal_cstr() dereferences it and crashes the backend. This commit fixes this by skipping a relation whose name is no longer available. A dropped relation is not synchronized anyway, and the appended clauses only exclude relations from a check whose sole effect is a WARNING, so omitting one can at most produce a spurious WARNING. The window is reachable from ALTER SUBSCRIPTION ... REFRESH PUBLICATION and from SET, ADD and DROP PUBLICATION, which refresh by default, but only when copy_data is true and origin is none. Backpatch to v16 as commit 46b4f5c11b0 was back-patched that far. The sequence path exists only in v19 and later. The test is applied to v19 and later only. Adding it to v17 and v18 would require enabling injection point support in src/test/subscription there, and v16 predates injection points entirely. That is more test infrastructure churn on stable branches than this fix warrants. Reported-by: SATYANARAYANA NARLAPURAM Author: SATYANARAYANA NARLAPURAM Co-authored-by: Bharath Rupireddy Reviewed-by: Ajin Cherian Reviewed-by: Masahiko Sawada Discussion: https://postgr.es/m/CAHg+QDcd_o3707Ey8c8b7HkE-t14g8c0tk8ME3ctywDsh3ut8g@mail.gmail.com Backpatch-through: 16 --- src/backend/commands/subscriptioncmds.c | 44 ++++++++++--- src/test/subscription/t/100_bugs.pl | 86 +++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 8 deletions(-) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index cff86dd57ab..4f682cf0ec6 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -52,6 +52,7 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/guc.h" +#include "utils/injection_point.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/pg_lsn.h" @@ -1107,6 +1108,9 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data, subrel_states = GetSubscriptionRelations(sub->oid, true, true, false); subrel_count = list_length(subrel_states); + /* Allow a test to drop a subscribed relation before the origin check. */ + INJECTION_POINT("subscription-refresh-before-origin-check", NULL); + /* * Build qsorted arrays of local table oids and sequence oids for * faster lookup. This can potentially contain all tables and @@ -2980,10 +2984,22 @@ check_publications_origin_tables(WalReceiverConn *wrconn, List *publications, for (i = 0; i < subrel_count; i++) { Oid relid = subrel_local_oids[i]; - char *schemaname = get_namespace_name(get_rel_namespace(relid)); - char *tablename = get_rel_name(relid); - char *schemaname_lit = quote_literal_cstr(schemaname); - char *tablename_lit = quote_literal_cstr(tablename); + char *schemaname; + char *tablename; + char *schemaname_lit; + char *tablename_lit; + + /* The table may have been dropped concurrently; skip if gone. */ + tablename = get_rel_name(relid); + if (tablename == NULL) + continue; + + schemaname = get_namespace_name(get_rel_namespace(relid)); + if (schemaname == NULL) + continue; + + schemaname_lit = quote_literal_cstr(schemaname); + tablename_lit = quote_literal_cstr(tablename); appendStringInfo(&cmd, "AND NOT (N.nspname = %s AND C.relname = %s)\n", schemaname_lit, tablename_lit); @@ -3107,10 +3123,22 @@ check_publications_origin_sequences(WalReceiverConn *wrconn, List *publications, for (int i = 0; i < subrel_count; i++) { Oid relid = subrel_local_oids[i]; - char *schemaname = get_namespace_name(get_rel_namespace(relid)); - char *seqname = get_rel_name(relid); - char *schemaname_lit = quote_literal_cstr(schemaname); - char *seqname_lit = quote_literal_cstr(seqname); + char *schemaname; + char *seqname; + char *schemaname_lit; + char *seqname_lit; + + /* The sequence may have been dropped concurrently; skip if gone. */ + seqname = get_rel_name(relid); + if (seqname == NULL) + continue; + + schemaname = get_namespace_name(get_rel_namespace(relid)); + if (schemaname == NULL) + continue; + + schemaname_lit = quote_literal_cstr(schemaname); + seqname_lit = quote_literal_cstr(seqname); appendStringInfo(&cmd, "AND NOT (N.nspname = %s AND C.relname = %s)\n", diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl index 335efd86bca..06c032a8e64 100644 --- a/src/test/subscription/t/100_bugs.pl +++ b/src/test/subscription/t/100_bugs.pl @@ -673,4 +673,90 @@ BEGIN $node_publisher->stop('fast'); +$node_publisher->start; +$node_subscriber->start; + +SKIP: +{ + skip "injection points not supported by this build", 1 + if $node_subscriber->check_extension('injection_points') == 0; + + # Test that ALTER SUBSCRIPTION ... REFRESH PUBLICATION skips a subscribed + # relation that is dropped concurrently during the refresh. + + $node_publisher->rotate_logfile(); + $node_subscriber->rotate_logfile(); + + # Subscribe to a table and a sequence. + $node_publisher->safe_psql( + 'postgres', qq{ +CREATE TABLE tab_drop_refresh (a int); +CREATE SEQUENCE seq_drop_refresh; +CREATE PUBLICATION pub_drop_refresh FOR TABLE tab_drop_refresh; +CREATE PUBLICATION pub_seq_drop_refresh FOR ALL SEQUENCES; + }); + + $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; + $node_subscriber->safe_psql( + 'postgres', qq{ +CREATE EXTENSION IF NOT EXISTS injection_points; +CREATE TABLE tab_drop_refresh (a int); +CREATE SEQUENCE seq_drop_refresh; +CREATE SUBSCRIPTION sub_drop_refresh + CONNECTION '$publisher_connstr' + PUBLICATION pub_drop_refresh, pub_seq_drop_refresh + WITH (copy_data = false, origin = none); + }); + $node_subscriber->wait_for_subscription_sync($node_publisher, + 'sub_drop_refresh'); + + $node_publisher->safe_psql( + 'postgres', + qq{ +ALTER PUBLICATION pub_drop_refresh DROP TABLE tab_drop_refresh; +DROP SEQUENCE seq_drop_refresh; + }); + + # Pause the refresh after it collects the relation list, drop the table + # and the sequence, then wake it. + $node_subscriber->safe_psql('postgres', + qq{SELECT injection_points_attach('subscription-refresh-before-origin-check', 'wait');} + ); + + my $psql = $node_subscriber->background_psql('postgres'); + $psql->query_until( + qr/starting_refresh/, q{ + \echo starting_refresh + ALTER SUBSCRIPTION sub_drop_refresh REFRESH PUBLICATION; + }); + + $node_subscriber->wait_for_event('client backend', + 'subscription-refresh-before-origin-check'); + + $node_subscriber->safe_psql( + 'postgres', qq{ +DROP TABLE tab_drop_refresh; +DROP SEQUENCE seq_drop_refresh; + }); + + $node_subscriber->safe_psql('postgres', + qq{SELECT injection_points_wakeup('subscription-refresh-before-origin-check');} + ); + + # quit() returns false unless psql exited cleanly, which it does not if the + # refresh errored out or the backend crashed. + ok($psql->quit, 'refresh completed without crashing the server'); + + $node_subscriber->safe_psql( + 'postgres', qq{ +SELECT injection_points_detach('subscription-refresh-before-origin-check'); +DROP SUBSCRIPTION sub_drop_refresh; + }); + $node_publisher->safe_psql('postgres', + qq{DROP PUBLICATION pub_drop_refresh, pub_seq_drop_refresh;}); +} + +$node_publisher->stop('fast'); +$node_subscriber->stop('fast'); + done_testing(); From ef89c839cdc8398095be0d24e65a688115e38b72 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Wed, 26 Aug 2026 15:38:15 -0400 Subject: [PATCH 450/481] Export subxip[] for snapshots taken during recovery. A snapshot taken during recovery stores all of its in-progress XIDs in subxip, every running top-level XID included, leaving xip empty. Unlike with other snapshots, its suboverflowed flag does not mean that subxip is redundant. We nevertheless treated it that way during snapshot export, so an importing session could see in-progress transactions as aborted. This misbehavior could also lead to hint bits being incorrectly set on the standby; affected tuples then wrongly appeared visible or invisible to sessions that never imported the snapshot. To fix, teach snapshot export to include the subxip[] array regardless of the overflow flag when the snapshot is taken during recovery. This is in line with how CopySnapshot() and SerializeSnapshot() already handle the same issue. Claude Code diagnosed this problem. The committed TAP test is a simplified version of the one that it wrote to demonstrate this bug. Oversight in commit 6c2003f8a, which enabled snapshot export and import during recovery. Author: Peter Geoghegan Author: Bertrand Drouvot Bug: #17846 Discussion: https://postgr.es/m/CAH2-WzmHVeYY%3Dpjz9x8DhhxVjXHX0pvoQ-MdiB1Tt6%3Do2GTiKg%40mail.gmail.com Discussion: https://postgr.es/m/17846-1a0e5ce976f4c01a@postgresql.org Backpatch-through: 14 --- src/backend/utils/time/snapmgr.c | 58 +++++++--- src/test/recovery/meson.build | 1 + .../recovery/t/056_standby_snapshot_export.pl | 104 ++++++++++++++++++ 3 files changed, 147 insertions(+), 16 deletions(-) create mode 100644 src/test/recovery/t/056_standby_snapshot_export.pl diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c index 10fe18df2e7..73894eeecec 100644 --- a/src/backend/utils/time/snapmgr.c +++ b/src/backend/utils/time/snapmgr.c @@ -1117,8 +1117,10 @@ ExportSnapshot(Snapshot snapshot) TransactionId topXid; TransactionId *children; ExportedSnapshot *esnap; + int nsubxids; int nchildren; int addTopXid; + bool suboverflowed; StringInfoData buf; FILE *f; int i; @@ -1162,6 +1164,22 @@ ExportSnapshot(Snapshot snapshot) */ nchildren = xactGetCommittedChildren(&children); + /* + * We export a recovery snapshot's subxip whole (see below), so refuse an + * export that no importer will accept. This rare edge case only happens + * when a snapshot taken during recovery is imported after its standby is + * promoted, the importing transaction subcommits many subtransactions, + * and then attempts to export the same snapshot a second time. + */ + if (snapshot->takenDuringRecovery && + snapshot->subxcnt + nchildren > GetMaxSnapshotSubxidCount()) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("cannot export snapshot with %d running transaction IDs", + snapshot->subxcnt + nchildren), + errdetail("A snapshot taken during recovery is exported with every transaction ID that it treats as running, and at most %d can be stored.", + GetMaxSnapshotSubxidCount()))); + /* * Generate file path for the snapshot. We start numbering of snapshots * inside the transaction from 1. @@ -1224,16 +1242,29 @@ ExportSnapshot(Snapshot snapshot) appendStringInfo(&buf, "xip:%u\n", topXid); /* - * Similarly, we add our subcommitted child XIDs to the subxid data. Here, - * we have to cope with possible overflow. + * Similarly, we add our subcommitted child XIDs to the subxid data. + * + * Report overflow when the snapshot overflowed, and also when our subxids + * won't fit in what a snapshot can hold. For a snapshot taken outside + * recovery, claiming overflow is always safe, since it just makes + * importers fall back on pg_subtrans. */ - if (snapshot->suboverflowed || - snapshot->subxcnt + nchildren > GetMaxSnapshotSubxidCount()) - appendStringInfoString(&buf, "sof:1\n"); - else + nsubxids = snapshot->subxcnt + nchildren; + suboverflowed = snapshot->suboverflowed || + nsubxids > GetMaxSnapshotSubxidCount(); + + /* + * Ignore the subxid array if it has overflowed, unless the snapshot was + * taken during recovery - in that case, top-level XIDs are in subxip as + * well, and we mustn't lose them. + */ + if (suboverflowed && !snapshot->takenDuringRecovery) + nsubxids = 0; + + appendStringInfo(&buf, "sof:%u\n", suboverflowed); + appendStringInfo(&buf, "sxcnt:%d\n", nsubxids); + if (nsubxids > 0) { - appendStringInfoString(&buf, "sof:0\n"); - appendStringInfo(&buf, "sxcnt:%d\n", snapshot->subxcnt + nchildren); for (i = 0; i < snapshot->subxcnt; i++) appendStringInfo(&buf, "sxp:%u\n", snapshot->subxip[i]); for (i = 0; i < nchildren; i++) @@ -1494,11 +1525,11 @@ ImportSnapshot(const char *idstr) snapshot.xip[i] = parseXidFromText("xip:", &filebuf, path); snapshot.suboverflowed = parseIntFromText("sof:", &filebuf, path); + snapshot.subxcnt = xcnt = parseIntFromText("sxcnt:", &filebuf, path); + snapshot.subxip = NULL; - if (!snapshot.suboverflowed) + if (snapshot.subxcnt) { - snapshot.subxcnt = xcnt = parseIntFromText("sxcnt:", &filebuf, path); - /* sanity-check the xid count before palloc */ if (xcnt < 0 || xcnt > GetMaxSnapshotSubxidCount()) ereport(ERROR, @@ -1509,11 +1540,6 @@ ImportSnapshot(const char *idstr) for (i = 0; i < xcnt; i++) snapshot.subxip[i] = parseXidFromText("sxp:", &filebuf, path); } - else - { - snapshot.subxcnt = 0; - snapshot.subxip = NULL; - } snapshot.takenDuringRecovery = parseIntFromText("rec:", &filebuf, path); diff --git a/src/test/recovery/meson.build b/src/test/recovery/meson.build index 39ec8c4946d..72113c5ac6e 100644 --- a/src/test/recovery/meson.build +++ b/src/test/recovery/meson.build @@ -64,6 +64,7 @@ tests += { 't/053_standby_login_event_trigger.pl', 't/054_unlogged_sequence_promotion.pl', 't/055_cascade_reconnect.pl', + 't/056_standby_snapshot_export.pl', ], }, } diff --git a/src/test/recovery/t/056_standby_snapshot_export.pl b/src/test/recovery/t/056_standby_snapshot_export.pl new file mode 100644 index 00000000000..73abb9c49b8 --- /dev/null +++ b/src/test/recovery/t/056_standby_snapshot_export.pl @@ -0,0 +1,104 @@ +# Copyright (c) 2026, PostgreSQL Global Development Group +# +# Test snapshot export and import on a standby. +# +# A snapshot taken during recovery holds its whole in-progress set in subxip, +# so export must write subxip out even when the snapshot is suboverflowed. +# Otherwise, a session that imports the snapshot treats running transactions +# as aborted, incorrectly setting hint bits. + +use strict; +use warnings FATAL => 'all'; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +# We must use at least enough subxacts to overflow the primary's subxid cache +my $nsubxacts = 80; + +my $primary = PostgreSQL::Test::Cluster->new('primary'); +$primary->init(allows_streaming => 1); +$primary->append_conf('postgresql.conf', 'autovacuum = off'); +$primary->start; + +$primary->backup('backup'); +my $standby = PostgreSQL::Test::Cluster->new('standby'); +$standby->init_from_backup($primary, 'backup', has_streaming => 1); +$standby->start; + +$primary->safe_psql( + 'postgres', q[ +CREATE TABLE vistest AS SELECT g AS k FROM generate_series(1, 10) g; +CREATE TABLE xid_burner(i int); +]); + +# This transaction deletes a row and stays open, so every snapshot taken from +# here on must report its XID as running +my $deleter = $primary->background_psql('postgres'); +$deleter->query_safe('BEGIN'); +$deleter->query_safe('DELETE FROM vistest WHERE k = 7'); +my $deleter_xid = $deleter->query_safe('SELECT pg_current_xact_id()'); + +# This one deletes another row in an early subtransaction, then overflows its +# subxid cache and stays open. Recovery removes the deleting subtransaction's +# XID from KnownAssignedXids, so reaching that tuple's xmax has to map the +# child XID back to its parent through pg_subtrans. +my $subxact_deleter = $primary->background_psql('postgres'); +$subxact_deleter->query_safe('BEGIN'); +$subxact_deleter->query_safe('SAVEPOINT early'); +$subxact_deleter->query_safe('DELETE FROM vistest WHERE k = 8'); +$subxact_deleter->query_safe('RELEASE early'); + +# Burn $nsubxacts-many subxact XIDs to make exported snapshot suboverflowed +$subxact_deleter->query_safe( + qq[DO \$\$ BEGIN + FOR i IN 1..$nsubxacts LOOP + BEGIN INSERT INTO xid_burner VALUES (i); + EXCEPTION WHEN OTHERS THEN NULL; END; + END LOOP; END \$\$]); + +# Commit a transaction that writes WAL of its own. That advances +# latestCompletedXid on the standby past the deleting XID, and flushes the +# xid-assignment WAL that those subtransactions wrote. +$primary->safe_psql('postgres', 'INSERT INTO xid_burner VALUES (0)'); +$primary->wait_for_replay_catchup($standby); + +my $exporter = $standby->background_psql('postgres'); +$exporter->query_safe('BEGIN ISOLATION LEVEL REPEATABLE READ'); +my $snap = $exporter->query_safe('SELECT pg_export_snapshot()'); + +my $snapfile = slurp_file($standby->data_dir . "/pg_snapshots/$snap"); +note("exported snapshot $snap:\n$snapfile"); + +like($snapfile, qr/^rec:1$/m, 'snapshot was taken during recovery'); +like($snapfile, qr/^sof:1$/m, 'snapshot is suboverflowed'); + +my ($xmin) = $snapfile =~ /^xmin:(\d+)$/m; +my ($xmax) = $snapfile =~ /^xmax:(\d+)$/m; +ok( $xmin <= $deleter_xid && $deleter_xid < $xmax, + 'running XID falls inside the exported xmin/xmax range'); + +like($snapfile, qr/^sxp:$deleter_xid$/m, + 'running XID appears in exported subxip array'); + +# Let both deleters commit, and let the standby replay that +$deleter->query_safe('COMMIT'); +$subxact_deleter->query_safe('COMMIT'); +$primary->wait_for_replay_catchup($standby); + +is( $standby->safe_psql( + 'postgres', qq[BEGIN ISOLATION LEVEL REPEATABLE READ; + SET TRANSACTION SNAPSHOT '$snap'; + SELECT count(*) FROM vistest]), + 10, + 'imported recovery snapshot still sees the deleted rows'); + +$exporter->query_safe('COMMIT'); + +$subxact_deleter->quit; +$deleter->quit; +$exporter->quit; +$standby->stop; +$primary->stop; + +done_testing(); From 073bd832772fa9ee2460d8420d2275687fbe88bc Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sat, 22 Aug 2026 17:47:24 -0400 Subject: [PATCH 451/481] Pin two ctype-dependent test_regex_utf8 cases to pg_c_utf8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test_regex_utf8 decides whether to run by looking at the database encoding alone, but two of its cases, [[:graph:]] and [[:print:]] over E'xᔀሷ', depend on the ctype as well. In a database with encoding UTF8 and locale C they match just the x, because isgraph() and isprint() are false for anything outside ASCII, and the file fails. No buildfarm animal builds such a cluster, which is why this went unnoticed, and why the to_date() crash in 18.5 went undetected for want of exactly this coverage. A pending buildfarm client change will let an animal be configured that way. Fix by giving the two cases an explicit collation, so that they exercise a fixed Unicode ctype instead of whatever the database happened to be initialized with. test_regex() already passes its input collation down to the regex compiler. The expected results are unchanged; only the echoed queries differ. Backpatch-through: 17 (15 and 16 get a different fix) Reviewed-by: Jonathan Gonzalez V. --- src/test/modules/test_regex/expected/test_regex_utf8.out | 6 ++++-- src/test/modules/test_regex/sql/test_regex_utf8.sql | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/test/modules/test_regex/expected/test_regex_utf8.out b/src/test/modules/test_regex/expected/test_regex_utf8.out index 329780ef400..177eb1cacec 100644 --- a/src/test/modules/test_regex/expected/test_regex_utf8.out +++ b/src/test/modules/test_regex/expected/test_regex_utf8.out @@ -147,7 +147,9 @@ select * from test_regex('[[:digit:]]+', E'x9\u1500\u1237', 'L'); {9} (2 rows) -select * from test_regex('[[:graph:]]+', E'x\u1500\u1237', 'L'); +-- graph and print depend on the ctype and not just the encoding, so pin them +-- to a Unicode-aware collation rather than the database's +select * from test_regex('[[:graph:]]+', E'x\u1500\u1237' COLLATE pg_c_utf8, 'L'); test_regex ----------------- {0,REG_ULOCALE} @@ -161,7 +163,7 @@ select * from test_regex('[[:lower:]]+', E'x\u1500\u1237', 'L'); {x} (2 rows) -select * from test_regex('[[:print:]]+', E'x\u1500\u1237', 'L'); +select * from test_regex('[[:print:]]+', E'x\u1500\u1237' COLLATE pg_c_utf8, 'L'); test_regex ----------------- {0,REG_ULOCALE} diff --git a/src/test/modules/test_regex/sql/test_regex_utf8.sql b/src/test/modules/test_regex/sql/test_regex_utf8.sql index 1f69f105fd7..d00599b3490 100644 --- a/src/test/modules/test_regex/sql/test_regex_utf8.sql +++ b/src/test/modules/test_regex/sql/test_regex_utf8.sql @@ -66,9 +66,11 @@ select * from test_regex('[[:ascii:]]+', E'x\u1500\u1237', 'L'); select * from test_regex('[[:blank:]]+', E'x \t\u1500\u1237', 'L'); select * from test_regex('[[:cntrl:]]+', E'x\u1500\u1237', 'L'); select * from test_regex('[[:digit:]]+', E'x9\u1500\u1237', 'L'); -select * from test_regex('[[:graph:]]+', E'x\u1500\u1237', 'L'); +-- graph and print depend on the ctype and not just the encoding, so pin them +-- to a Unicode-aware collation rather than the database's +select * from test_regex('[[:graph:]]+', E'x\u1500\u1237' COLLATE pg_c_utf8, 'L'); select * from test_regex('[[:lower:]]+', E'x\u1500\u1237', 'L'); -select * from test_regex('[[:print:]]+', E'x\u1500\u1237', 'L'); +select * from test_regex('[[:print:]]+', E'x\u1500\u1237' COLLATE pg_c_utf8, 'L'); select * from test_regex('[[:punct:]]+', E'x.\u1500\u1237', 'L'); select * from test_regex('[[:space:]]+', E'x \t\u1500\u1237', 'L'); select * from test_regex('[[:upper:]]+', E'xX\u1500\u1237', 'L'); From 3c73b272b42ecad68ad5c970bfd62d714ae03828 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Thu, 27 Aug 2026 10:05:51 +0530 Subject: [PATCH 452/481] Don't choose an invalid index for REPLICA IDENTITY FULL lookups. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For a REPLICA IDENTITY FULL remote relation whose local counterpart has no primary key or replica identity, FindUsableIndexForReplicaIdentityFull() chooses the first index of a suitable shape from RelationGetIndexList(). That list excludes only indexes that are not indislive, so an invalid index left behind by a failed CREATE INDEX CONCURRENTLY can be selected. Such an index need not contain every row. Consequently, changes for rows that it fails to find can be silently dropped as missing-tuple conflicts. If the index contains no rows at all, the scan can instead error out and cause the apply worker to exit. Skip invalid indexes, as the planner does. Author: Mikhail Nikalayeu Reviewed-by: Miłosz Bieniek Reviewed-by: Amit Kapila Reviewed-by: Shlok Kyal Reviewed-by: Vignesh C Reviewed-by: Ajin Cherian Discussion: https://postgr.es/m/CADzfLwWuubcbJBDRZ_J1SSqHDNjNmUYSAgf5y=17LxmP401xbw@mail.gmail.com Backpatch-through: 16, where it was introduced --- src/backend/replication/logical/relation.c | 16 ++++- .../subscription/t/032_subscribe_use_index.pl | 59 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c index 296cbaede30..40544cf8d25 100644 --- a/src/backend/replication/logical/relation.c +++ b/src/backend/replication/logical/relation.c @@ -796,7 +796,17 @@ FindUsableIndexForReplicaIdentityFull(Relation localrel, AttrMap *attrmap) Relation idxRel; idxRel = index_open(idxoid, AccessShareLock); - isUsableIdx = IsIndexUsableForReplicaIdentityFull(idxRel, attrmap); + + /* + * indisvalid is checked here, not in + * IsIndexUsableForReplicaIdentityFull(), since that function's other + * caller (an assertion) must tolerate an index made transiently + * invalid by a concurrent DROP INDEX CONCURRENTLY, whereas a + * permanently invalid leftover of a failed CREATE INDEX CONCURRENTLY + * must never be chosen here. + */ + isUsableIdx = idxRel->rd_index->indisvalid && + IsIndexUsableForReplicaIdentityFull(idxRel, attrmap); index_close(idxRel, AccessShareLock); /* Return the first eligible index found */ @@ -819,6 +829,10 @@ FindUsableIndexForReplicaIdentityFull(Relation localrel, AttrMap *attrmap) * map to check whether the local index attribute has a corresponding remote * attribute. * + * Note that this function does not check indisvalid. Callers that are + * selecting an index to use for future lookups must check indisvalid + * themselves and reject invalid indexes. + * * Note that the limitations of index scans for replica identity full only * adheres to a subset of the limitations of PK/RI. For example, we support * columns that are marked as [NULL] or we are not interested in the [NOT diff --git a/src/test/subscription/t/032_subscribe_use_index.pl b/src/test/subscription/t/032_subscribe_use_index.pl index c755c1a7518..1ccd36ac227 100644 --- a/src/test/subscription/t/032_subscribe_use_index.pl +++ b/src/test/subscription/t/032_subscribe_use_index.pl @@ -478,6 +478,65 @@ # data # ============================================================================= +# ============================================================================= +# Testcase start: Subscription does not use an invalid index +# +# A failed CREATE INDEX CONCURRENTLY leaves behind a live but invalid +# index, which is not required to contain every row. The apply worker +# must not choose it for REPLICA IDENTITY FULL lookups. +# + +# create tables pub and sub +$node_publisher->safe_psql('postgres', + "CREATE TABLE test_invalid (x int, y int)"); +$node_publisher->safe_psql('postgres', + "ALTER TABLE test_invalid REPLICA IDENTITY FULL"); +$node_subscriber->safe_psql('postgres', + "CREATE TABLE test_invalid (x int, y int)"); + +# insert some initial data, including the row the index build trips over +$node_publisher->safe_psql('postgres', + "INSERT INTO test_invalid SELECT i, i FROM generate_series(1,10) i"); + +# create pub/sub +$node_publisher->safe_psql('postgres', + "CREATE PUBLICATION tap_pub_invalid FOR TABLE test_invalid"); +$node_subscriber->safe_psql('postgres', + "CREATE SUBSCRIPTION tap_sub_invalid CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub_invalid" +); + +# wait for initial table synchronization to finish +$node_subscriber->wait_for_subscription_sync($node_publisher, $appname); + +# leave an invalid index behind: the build fails on the y = 5 row +my ($cic_ret, $cic_out, $cic_err) = $node_subscriber->psql('postgres', + "CREATE INDEX CONCURRENTLY test_invalid_idx ON test_invalid (x, (1/(y-5)))" +); +isnt($cic_ret, 0, 'CREATE INDEX CONCURRENTLY fails'); +$result = $node_subscriber->safe_psql('postgres', + "SELECT indisvalid FROM pg_index" + . " WHERE indexrelid = 'test_invalid_idx'::regclass"); +is($result, qq(f), 'and leaves an invalid index behind'); + +# the update must still be applied +$node_publisher->safe_psql('postgres', + "UPDATE test_invalid SET y = 99 WHERE x = 7"); +$node_publisher->wait_for_catchup($appname); +$result = $node_subscriber->safe_psql('postgres', + "SELECT y FROM test_invalid WHERE x = 7"); +is($result, qq(99), + 'ensure subscriber has the correct data at the end of the test'); + +# cleanup pub +$node_publisher->safe_psql('postgres', "DROP PUBLICATION tap_pub_invalid"); +$node_publisher->safe_psql('postgres', "DROP TABLE test_invalid"); +# cleanup sub +$node_subscriber->safe_psql('postgres', "DROP SUBSCRIPTION tap_sub_invalid"); +$node_subscriber->safe_psql('postgres', "DROP TABLE test_invalid"); + +# Testcase end: Subscription does not use an invalid index +# ============================================================================= + # ============================================================================= # Testcase start: Subscription can use hash index # From 3e8bcc8644feaa9ca1cc954197b6994817af4290 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Thu, 27 Aug 2026 00:56:41 +0300 Subject: [PATCH 453/481] Revert support for ALTER TABLE ... MERGE/SPLIT PARTITION(S) commands This commit reverts f2e4cc4279 and 4b3d173629, and the subsequent fixes and improvements c5ae07a90a, 713e553e32, 52e629be95, ecb2508aaf, 9354896920, 971017c495, 83df16f1fa, e64a9ba2b4, ff8bec8c46, cdae794af3, 57f19774d6, and 881033ae8b. d8af730100 and 0392fb900e cancelled each other out and are not reverted separately. The feature is reverted due to multiple design issues which are too late to address in this release cycle. Discussion: https://postgr.es/m/CAN4CZFNCU%3Dt09M%3D%2Br2t9hHLJuujdM4oQ8hCK_Sx-GpfiwMAicw%40mail.gmail.com --- doc/src/sgml/ddl.sgml | 38 - doc/src/sgml/ref/alter_table.sgml | 272 +-- src/backend/catalog/dependency.c | 54 +- src/backend/catalog/pg_constraint.c | 2 +- src/backend/commands/tablecmds.c | 1649 +--------------- src/backend/parser/gram.y | 60 +- src/backend/parser/parse_utilcmd.c | 338 +--- src/backend/partitioning/partbounds.c | 1054 ---------- src/bin/psql/tab-complete.in.c | 18 +- src/include/catalog/dependency.h | 2 - src/include/nodes/parsenodes.h | 34 +- src/include/parser/kwlist.h | 2 - src/include/partitioning/partbounds.h | 10 - .../isolation/expected/partition-merge.out | 243 --- .../isolation/expected/partition-split.out | 230 --- src/test/isolation/isolation_schedule | 2 - src/test/isolation/specs/partition-merge.spec | 62 - src/test/isolation/specs/partition-split.spec | 62 - .../test_ddl_deparse/expected/alter_table.out | 10 - .../test_ddl_deparse/sql/alter_table.sql | 7 - .../test_ddl_deparse/test_ddl_deparse.c | 6 - .../expected/test_extdepend.out | 120 -- .../test_extensions/sql/test_extdepend.sql | 104 - src/test/regress/expected/partition_merge.out | 1174 ----------- src/test/regress/expected/partition_split.out | 1758 ----------------- src/test/regress/parallel_schedule | 2 +- src/test/regress/sql/partition_merge.sql | 846 -------- src/test/regress/sql/partition_split.sql | 1263 ------------ src/tools/pgindent/typedefs.list | 3 - 29 files changed, 46 insertions(+), 9379 deletions(-) delete mode 100644 src/test/isolation/expected/partition-merge.out delete mode 100644 src/test/isolation/expected/partition-split.out delete mode 100644 src/test/isolation/specs/partition-merge.spec delete mode 100644 src/test/isolation/specs/partition-split.spec delete mode 100644 src/test/regress/expected/partition_merge.out delete mode 100644 src/test/regress/expected/partition_split.out delete mode 100644 src/test/regress/sql/partition_merge.sql delete mode 100644 src/test/regress/sql/partition_split.sql diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index dadf5e0dcb9..291545ee008 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -4779,44 +4779,6 @@ ALTER INDEX measurement_city_id_logdate_key ... - - - There is also an option for merging multiple table partitions into - a single partition using the - ALTER TABLE ... MERGE PARTITIONS. - This feature simplifies the management of partitioned tables by allowing - users to combine partitions that are no longer needed as - separate entities. It's important to note that this operation is not - supported for hash-partitioned tables and acquires an - ACCESS EXCLUSIVE lock, which could impact high-load - systems due to the lock's restrictive nature. For example, we can - merge three monthly partitions into one quarter partition: - -ALTER TABLE measurement - MERGE PARTITIONS (measurement_y2006m01, - measurement_y2006m02, - measurement_y2006m03) INTO measurement_y2006q1; - - - - - Similarly to merging multiple table partitions, there is an option for - splitting a single partition into multiple using the - ALTER TABLE ... SPLIT PARTITION. - This feature could come in handy when one partition grows too big - and needs to be split into multiple. It's important to note that - this operation is not supported for hash-partitioned tables and acquires - an ACCESS EXCLUSIVE lock, which could impact high-load - systems due to the lock's restrictive nature. For example, we can split - the quarter partition back to monthly partitions: - -ALTER TABLE measurement SPLIT PARTITION measurement_y2006q1 INTO - (PARTITION measurement_y2006m01 FOR VALUES FROM ('2006-01-01') TO ('2006-02-01'), - PARTITION measurement_y2006m02 FOR VALUES FROM ('2006-02-01') TO ('2006-03-01'), - PARTITION measurement_y2006m03 FOR VALUES FROM ('2006-03-01') TO ('2006-04-01')); - - - diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index ff7071bef5b..0f9d698d170 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -37,12 +37,6 @@ ALTER TABLE [ IF EXISTS ] name ATTACH PARTITION partition_name { FOR VALUES partition_bound_spec | DEFAULT } ALTER TABLE [ IF EXISTS ] name DETACH PARTITION partition_name [ CONCURRENTLY | FINALIZE ] -ALTER TABLE [ IF EXISTS ] name - MERGE PARTITIONS (partition_name1, partition_name2 [, ...]) INTO partition_name -ALTER TABLE [ IF EXISTS ] name - SPLIT PARTITION partition_name INTO - (PARTITION partition_name1 { FOR VALUES partition_bound_spec | DEFAULT }, - PARTITION partition_name2 { FOR VALUES partition_bound_spec | DEFAULT } [, ...]) where action is one of: @@ -1185,239 +1179,18 @@ WITH ( MODULUS numeric_literal, REM - - MERGE PARTITIONS (partition_name1, partition_name2 [, ...]) INTO partition_name - - - - This form merges several partitions of the target table into a new partition. - Hash-partitioned target table is not supported. - Only simple, non-partitioned partitions can be merged. - The new partition (partition_name) - can have the same name as one of the merged partitions - (partition_name1, - partition_name2 [, ...]). - - - - If the DEFAULT partition is not in the - list of merged partitions: - - - - For range-partitioned tables, the ranges of merged partitions - must be adjacent; this applies even if the partitioned table - has no default partition. - The partition bounds of merged partitions are combined to form the new partition bound for - partition_name. - - - - - For list-partitioned tables, the partition bounds of - merged partitions are combined to form the new partition bound for - partition_name. - - - - If the DEFAULT partition is in the list of merged partitions: - - - - The partition partition_name - will be the new DEFAULT partition of the target table. - - - - - The partition bound specifications for merged partitions can be arbitrary. - - - - - - All merged partitions must have the same owner. - The owner of merged partitions will be the owner of the new partition. - It is the user's responsibility to setup ACL on - the new partition. - - - - ALTER TABLE MERGE PARTITION uses the partitioned - table itself as the template to construct the new partition. - The new partition inherits the table access method and persistence type - of the partitioned table. Its tablespace is selected as for a - CREATE TABLE ... PARTITION OF command issued - without a TABLESPACE clause: if the partitioned - table has an explicit tablespace, the new partition uses it; - otherwise the value of is - taken into account, falling back to the database's default tablespace. - - Constraints, column defaults, column generation expressions, identity - columns, indexes, and triggers are copied from the partitioned table to - the new partition. But extended statistics, security policies, etc, - won't be copied from the partitioned table. - Indexes and identity columns copied from the partitioned table will be - created afterward, once the data has been moved into the new partition. - - - - When partitions are merged, any objects depending on this partition, - such as constraints, triggers, extended statistics, etc, will be - dropped. - Eventually, we will drop all the merged partitions - (using RESTRICT mode) too; therefore, if any objects - are still dependent on them, - ALTER TABLE MERGE PARTITION would fail. - (see ). - - - - Extension dependencies on partition indexes (created via - ALTER INDEX ... DEPENDS ON - EXTENSION) are preserved during merge operations. - All source partition indexes must have the same extension dependencies; - if they differ, an error is raised. This ensures that extension - dependencies are not silently lost during merge. - - - - - Merging partitions acquires an ACCESS EXCLUSIVE lock on - the parent table, in addition to the ACCESS EXCLUSIVE - locks on the tables being merged and on the default partition (if any). - - - - - ALTER TABLE MERGE PARTITIONS creates a new partition and - moves data from all merging partitions into it, which can take a long time. - So it is not recommended to use the command to merge very big partitions - with small ones. - - - - - - - - SPLIT PARTITION partition_name INTO ( - PARTITION partition_name1 { FOR VALUES partition_bound_spec | DEFAULT }, - PARTITION partition_name2 { FOR VALUES partition_bound_spec | DEFAULT } - [, ...]) - - - - - This form splits a single partition of the target table into new - partitions. Hash-partitioned target tables are not supported. - Only a simple, non-partitioned partition can be split. - If the split partition is the DEFAULT partition, - one of the new partitions must be DEFAULT. - If the partitioned table does not have a DEFAULT - partition, a DEFAULT partition can be defined as one - of the new partitions. - - - - The bounds of new non-DEFAULT partitions must not - overlap with those of new or existing partitions, except - partition_name, and must be - contained within the bounds of the split partition - partition_name. - If no new DEFAULT partition is specified, the - combined bounds of the new partitions - - partition_name1, - partition_name2[, ...] - must exactly match the bounds of the split partition - partition_name. - One of the new partitions can have the same name as the split partition - partition_name. - This is useful when splitting the DEFAULT partition, - so that after the split, the DEFAULT partition - keeps the same name but its partition bound changes. - - - - New partitions will have the same owner as the parent partition. - It is the user's responsibility to setup ACL on new - partitions. - - - - ALTER TABLE SPLIT PARTITION uses the partitioned - table itself as the template to construct new partitions. - New partitions inherit the table access method and persistence type of - the partitioned table. Their tablespace is selected as for a - CREATE TABLE ... PARTITION OF command issued - without a TABLESPACE clause: if the partitioned - table has an explicit tablespace, the new partitions use it; - otherwise the value of is - taken into account, falling back to the database's default tablespace. - - - - Constraints, column defaults, column generation expressions, - identity columns, indexes, and triggers are copied from the partitioned - table to the new partitions. But extended statistics, security - policies, etc, won't be copied from the partitioned table. - Indexes and identity columns copied from the partitioned table will be - created afterward, once the data has been moved into the new partitions. - - - - When a partition is split, any objects that depend on this partition, - such as constraints, triggers, extended statistics, etc, will be dropped. - This occurs because ALTER TABLE SPLIT PARTITION uses - the partitioned table itself as the template to reconstruct these - objects later. - Eventually, we will drop the split partition - (using RESTRICT mode) too; therefore, if any objects - are still dependent on it, ALTER TABLE SPLIT PARTITION - would fail (see ). - - - - Extension dependencies on partition indexes (created via - ALTER INDEX ... DEPENDS ON - EXTENSION) are preserved during split operations. - The new partitions' indexes will inherit the extension dependencies - from the source partition's indexes. - - - - - Split partition acquires an ACCESS EXCLUSIVE lock on - the parent table, in addition to the ACCESS EXCLUSIVE - lock on the table being split. - - - - - - ALTER TABLE SPLIT PARTITION creates new partitions and - moves data from the split partition into them, which can take a long - time. So it is not recommended to use the command for splitting a - small fraction of rows out of a very big partition. - - - - - All the forms of ALTER TABLE that act on a single table, except RENAME, SET SCHEMA, - ATTACH PARTITION, DETACH PARTITION, - MERGE PARTITIONS, and SPLIT PARTITION - can be combined into + ATTACH PARTITION, and + DETACH PARTITION can be combined into a list of multiple alterations to be applied together. For example, it is possible to add several columns and/or alter the type of several columns in a single command. This is particularly useful with large - tables, since only one pass over the table needs to be made. + tables, since only one pass over the table need be made. @@ -1656,19 +1429,7 @@ WITH ( MODULUS numeric_literal, REM partition_name - The name of the table to attach as a new partition or to detach from this table, - or the name of split partition, or the name of the new merged partition. - - - - - - partition_name1 - partition_name2 - - - The names of the tables being merged into the new partition or split into - new partitions. + The name of the table to attach as a new partition or to detach from this table. @@ -2101,31 +1862,6 @@ ALTER TABLE measurement DETACH PARTITION measurement_y2015m12; - - To split a single partition of the range-partitioned table: - -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2023 INTO - (PARTITION sales_feb2023 FOR VALUES FROM ('2023-02-01') TO ('2023-03-01'), - PARTITION sales_mar2023 FOR VALUES FROM ('2023-03-01') TO ('2023-04-01'), - PARTITION sales_apr2023 FOR VALUES FROM ('2023-04-01') TO ('2023-05-01')); - - - - To split a single partition of the list-partitioned table: - -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')); - - - - To merge several partitions into one partition of the target table: - -ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_central) - INTO sales_all; - - diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 026b743275f..40114d2ddb3 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -326,63 +326,13 @@ performDeletion(const ObjectAddress *object, } /* - * performDeletionCheck: Check whether a specific object can be safely deleted. - * This function does not perform any deletion; instead, it raises an error - * if the object cannot be deleted due to existing dependencies. - * - * It can be useful when you need to delete some objects later. See comments - * in performDeletion too. - * The behavior must be specified as DROP_RESTRICT. - */ -void -performDeletionCheck(const ObjectAddress *object, - DropBehavior behavior, int flags) -{ - Relation depRel; - ObjectAddresses *targetObjects; - - Assert(behavior == DROP_RESTRICT); - - depRel = table_open(DependRelationId, RowExclusiveLock); - - AcquireDeletionLock(object, 0); - - /* - * Construct a list of objects we want to delete later (ie, the given - * object plus everything directly or indirectly dependent on it). - */ - targetObjects = new_object_addresses(); - - findDependentObjects(object, - DEPFLAG_ORIGINAL, - flags, - NULL, /* empty stack */ - targetObjects, - NULL, /* no pendingObjects */ - &depRel); - - /* - * Check if deletion is allowed. - */ - reportDependentObjects(targetObjects, - behavior, - flags, - object); - - /* And clean up */ - free_object_addresses(targetObjects); - - table_close(depRel, RowExclusiveLock); -} - -/* - * performMultipleDeletions: Similar to performDeletion, but acts on multiple + * performMultipleDeletions: Similar to performDeletion, but act on multiple * objects at once. * * The main difference from issuing multiple performDeletion calls is that the * list of objects that would be implicitly dropped, for each object to be * dropped, is the union of the implicit-object list for all objects. This - * makes each check more relaxed. + * makes each check be more relaxed. */ void performMultipleDeletions(const ObjectAddresses *objects, diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index 8aba9cbbc57..c2fcc81a24a 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -895,7 +895,7 @@ RelationGetNotNullConstraints(Oid relid, bool cooked, bool include_noinh) false))); constr->is_enforced = true; constr->skip_validation = !conForm->convalidated; - constr->initially_valid = conForm->convalidated; + constr->initially_valid = true; constr->is_no_inherit = conForm->connoinherit; notnulls = lappend(notnulls, constr); } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index cad394b3540..2680acf4d94 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -40,7 +40,6 @@ #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" #include "catalog/pg_depend.h" -#include "catalog/pg_extension_d.h" #include "catalog/pg_foreign_table.h" #include "catalog/pg_inherits.h" #include "catalog/pg_largeobject.h" @@ -61,7 +60,6 @@ #include "commands/comment.h" #include "commands/defrem.h" #include "commands/event_trigger.h" -#include "commands/extension.h" #include "commands/repack.h" #include "commands/sequence.h" #include "commands/tablecmds.h" @@ -368,27 +366,6 @@ typedef enum addFkConstraintSides addFkBothSides, } addFkConstraintSides; -/* - * Hold extension dependencies of one partition index, during - * MERGE/SPLIT PARTITION processing. - * - * collectPartitionIndexExtDeps() builds a list of these entries sorted by - * parentIndexOid with exactly one entry per parent partitioned index; the - * list is then consumed by applyPartitionIndexExtDeps() to re-record the - * same dependencies on the newly created partition's indexes. - * - * extensionOids is kept sorted ascending so that equality checks between - * entries from different partitions can be done in a single pass. - * indexOid is carried only so that conflict errors can cite specific - * partition index names. - */ -typedef struct PartitionIndexExtDepEntry -{ - Oid parentIndexOid; /* OID of the parent partitioned index */ - Oid indexOid; /* OID of a representative partition index */ - List *extensionOids; /* OIDs of dependent extensions, sorted asc */ -} PartitionIndexExtDepEntry; - /* * Partition tables are expected to be dropped when the parent partitioned * table gets dropped. Hence for partitioning we use AUTO dependency. @@ -787,14 +764,6 @@ static void ATDetachCheckNoForeignKeyRefs(Relation partition); static char GetAttributeCompression(Oid atttypid, const char *compression); static char GetAttributeStorage(Oid atttypid, const char *storagemode); -static void ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel, - PartitionCmd *cmd, AlterTableUtilityContext *context); -static void ATExecSplitPartition(List **wqueue, AlteredTableInfo *tab, - Relation rel, PartitionCmd *cmd, - AlterTableUtilityContext *context); -static List *collectPartitionIndexExtDeps(List *partitionOids); -static void applyPartitionIndexExtDeps(Oid newPartOid, List *extDepState); -static void freePartitionIndexExtDeps(List *extDepState); /* ---------------------------------------------------------------- * DefineRelation @@ -4918,11 +4887,6 @@ AlterTableGetLockLevel(List *cmds) cmd_lockmode = ShareUpdateExclusiveLock; break; - case AT_MergePartitions: - case AT_SplitPartition: - cmd_lockmode = AccessExclusiveLock; - break; - default: /* oops */ elog(ERROR, "unrecognized alter table type: %d", (int) cmd->subtype); @@ -5358,12 +5322,6 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, /* No command-specific prep needed */ pass = AT_PASS_MISC; break; - case AT_MergePartitions: - case AT_SplitPartition: - ATSimplePermissions(cmd->subtype, rel, ATT_PARTITIONED_TABLE); - /* No command-specific prep needed */ - pass = AT_PASS_MISC; - break; default: /* oops */ elog(ERROR, "unrecognized alter table type: %d", (int) cmd->subtype); @@ -5760,22 +5718,6 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, case AT_DetachPartitionFinalize: address = ATExecDetachPartitionFinalize(rel, ((PartitionCmd *) cmd->def)->name); break; - case AT_MergePartitions: - cmd = ATParseTransformCmd(wqueue, tab, rel, cmd, false, lockmode, - cur_pass, context); - Assert(cmd != NULL); - Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); - ATExecMergePartitions(wqueue, tab, rel, (PartitionCmd *) cmd->def, - context); - break; - case AT_SplitPartition: - cmd = ATParseTransformCmd(wqueue, tab, rel, cmd, false, lockmode, - cur_pass, context); - Assert(cmd != NULL); - Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); - ATExecSplitPartition(wqueue, tab, rel, (PartitionCmd *) cmd->def, - context); - break; default: /* oops */ elog(ERROR, "unrecognized alter table type: %d", (int) cmd->subtype); @@ -6818,10 +6760,6 @@ alter_table_type_to_string(AlterTableType cmdtype) return "DETACH PARTITION"; case AT_DetachPartitionFinalize: return "DETACH PARTITION ... FINALIZE"; - case AT_MergePartitions: - return "MERGE PARTITIONS"; - case AT_SplitPartition: - return "SPLIT PARTITION"; case AT_AddIdentity: return "ALTER COLUMN ... ADD IDENTITY"; case AT_SetIdentity: @@ -20948,40 +20886,6 @@ QueuePartitionConstraintValidation(List **wqueue, Relation scanrel, } } -/* - * attachPartitionTable: attach a new partition to the partitioned table - * - * wqueue: the ALTER TABLE work queue; can be NULL when not running as part - * of an ALTER TABLE sequence. - * rel: partitioned relation; - * attachrel: relation of attached partition; - * bound: bounds of attached relation. - */ -static void -attachPartitionTable(List **wqueue, Relation rel, Relation attachrel, PartitionBoundSpec *bound) -{ - /* - * Create an inheritance; the relevant checks are performed inside the - * function. - */ - CreateInheritance(attachrel, rel, true); - - /* Update the pg_class entry. */ - StorePartitionBound(attachrel, rel, bound); - - /* Ensure there exists a correct set of indexes in the partition. */ - AttachPartitionEnsureIndexes(wqueue, rel, attachrel); - - /* and triggers */ - CloneRowTriggersToPartition(rel, attachrel); - - /* - * Clone foreign key constraints. Callee is responsible for setting up - * for phase 3 constraint verification. - */ - CloneForeignKeyConstraints(wqueue, rel, attachrel); -} - /* * ALTER TABLE ATTACH PARTITION FOR VALUES * @@ -21221,10 +21125,26 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd, check_new_partition_bound(RelationGetRelationName(attachrel), rel, cmd->bound, pstate); - attachPartitionTable(wqueue, rel, attachrel, cmd->bound); + /* OK to create inheritance. Rest of the checks performed there */ + CreateInheritance(attachrel, rel, true); + + /* Update the pg_class entry. */ + StorePartitionBound(attachrel, rel, cmd->bound); + + /* Ensure there exists a correct set of indexes in the partition. */ + AttachPartitionEnsureIndexes(wqueue, rel, attachrel); + + /* and triggers */ + CloneRowTriggersToPartition(rel, attachrel); + + /* + * Clone foreign key constraints. Callee is responsible for setting up + * for phase 3 constraint verification. + */ + CloneForeignKeyConstraints(wqueue, rel, attachrel); /* - * Generate a partition constraint from the partition bound specification. + * Generate partition constraint from the partition bound specification. * If the parent itself is a partition, make sure to include its * constraint as well. */ @@ -22832,1536 +22752,3 @@ GetAttributeStorage(Oid atttypid, const char *storagemode) return cstorage; } - -/* - * buildExpressionExecutionStates: build the needed expression execution states - * for new partition (newPartRel) checks and initialize expressions for - * generated columns. All expressions should be created in "tab" - * (AlteredTableInfo structure). - */ -static void -buildExpressionExecutionStates(AlteredTableInfo *tab, Relation newPartRel, EState *estate) -{ - /* - * Build the needed expression execution states. Here, we expect only NOT - * NULL and CHECK constraint. - */ - foreach_ptr(NewConstraint, con, tab->constraints) - { - switch (con->contype) - { - case CONSTR_CHECK: - - /* - * We already expanded virtual expression in - * createTableConstraints. - */ - con->qualstate = ExecPrepareExpr((Expr *) con->qual, estate); - break; - case CONSTR_NOTNULL: - /* Nothing to do here. */ - break; - default: - elog(ERROR, "unrecognized constraint type: %d", - (int) con->contype); - } - } - - /* Expression already planned in createTableConstraints */ - foreach_ptr(NewColumnValue, ex, tab->newvals) - ex->exprstate = ExecInitExpr((Expr *) ex->expr, NULL); -} - -/* - * evaluateGeneratedExpressionsAndCheckConstraints: evaluate any generated - * expressions for "tab" (AlteredTableInfo structure) whose inputs come from - * the new tuple (insertslot) of the new partition (newPartRel). - */ -static void -evaluateGeneratedExpressionsAndCheckConstraints(AlteredTableInfo *tab, - Relation newPartRel, - TupleTableSlot *insertslot, - ExprContext *econtext) -{ - econtext->ecxt_scantuple = insertslot; - - foreach_ptr(NewColumnValue, ex, tab->newvals) - { - if (!ex->is_generated) - continue; - - insertslot->tts_values[ex->attnum - 1] - = ExecEvalExpr(ex->exprstate, - econtext, - &insertslot->tts_isnull[ex->attnum - 1]); - } - - foreach_ptr(NewConstraint, con, tab->constraints) - { - switch (con->contype) - { - case CONSTR_CHECK: - if (!ExecCheck(con->qualstate, econtext)) - ereport(ERROR, - errcode(ERRCODE_CHECK_VIOLATION), - errmsg("check constraint \"%s\" of relation \"%s\" is violated by some row", - con->name, RelationGetRelationName(newPartRel)), - errtableconstraint(newPartRel, con->name)); - break; - case CONSTR_NOTNULL: - case CONSTR_FOREIGN: - /* Nothing to do here */ - break; - default: - elog(ERROR, "unrecognized constraint type: %d", - (int) con->contype); - } - } -} - -/* - * getAttributesList: build a list of columns (ColumnDef) based on parent_rel - */ -static List * -getAttributesList(Relation parent_rel) -{ - AttrNumber parent_attno; - TupleDesc modelDesc; - List *colList = NIL; - - modelDesc = RelationGetDescr(parent_rel); - - for (parent_attno = 1; parent_attno <= modelDesc->natts; - parent_attno++) - { - Form_pg_attribute attribute = TupleDescAttr(modelDesc, - parent_attno - 1); - ColumnDef *def; - - /* Ignore dropped columns in the parent. */ - if (attribute->attisdropped) - continue; - - def = makeColumnDef(NameStr(attribute->attname), attribute->atttypid, - attribute->atttypmod, attribute->attcollation); - - def->is_not_null = attribute->attnotnull; - - /* Copy identity. */ - def->identity = attribute->attidentity; - - /* Copy attgenerated. */ - def->generated = attribute->attgenerated; - - def->storage = attribute->attstorage; - - /* Likewise, copy compression. */ - if (CompressionMethodIsValid(attribute->attcompression)) - def->compression = - pstrdup(GetCompressionMethodName(attribute->attcompression)); - else - def->compression = NULL; - - /* Add to column list. */ - colList = lappend(colList, def); - } - - return colList; -} - -/* - * createTableConstraints: - * create check constraints, default values, and generated values for newRel - * based on parent_rel. tab is pending-work queue for newRel, we may need it in - * MergePartitionsMoveRows. - */ -static void -createTableConstraints(List **wqueue, AlteredTableInfo *tab, - Relation parent_rel, Relation newRel) -{ - TupleDesc tupleDesc; - TupleConstr *constr; - AttrMap *attmap; - AttrNumber parent_attno; - int ccnum; - List *constraints = NIL; - List *cookedConstraints = NIL; - - tupleDesc = RelationGetDescr(parent_rel); - constr = tupleDesc->constr; - - if (!constr) - return; - - /* - * Construct a map from the parent relation's attnos to the child rel's. - * This re-checks type match, etc, although it shouldn't be possible to - * have a failure since both tables are locked. - */ - attmap = build_attrmap_by_name(RelationGetDescr(newRel), - tupleDesc, - false); - - /* Cycle for default values. */ - for (parent_attno = 1; parent_attno <= tupleDesc->natts; parent_attno++) - { - Form_pg_attribute attribute = TupleDescAttr(tupleDesc, - parent_attno - 1); - - /* Ignore dropped columns in the parent. */ - if (attribute->attisdropped) - continue; - - /* Copy the default, if present, and it should be copied. */ - if (attribute->atthasdef) - { - Node *this_default = NULL; - bool found_whole_row; - AttrNumber num; - Node *def; - NewColumnValue *newval; - - if (attribute->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL) - this_default = build_generation_expression(parent_rel, attribute->attnum); - else - { - this_default = TupleDescGetDefault(tupleDesc, attribute->attnum); - if (this_default == NULL) - elog(ERROR, "default expression not found for attribute %d of relation \"%s\"", - attribute->attnum, RelationGetRelationName(parent_rel)); - } - - num = attmap->attnums[parent_attno - 1]; - def = map_variable_attnos(this_default, 1, 0, attmap, InvalidOid, &found_whole_row); - - if (found_whole_row && attribute->attgenerated != '\0') - elog(ERROR, "cannot convert whole-row table reference"); - - /* Add a pre-cooked default expression. */ - StoreAttrDefault(newRel, num, def, false); - - /* - * Stored generated column expressions in parent_rel might - * reference the tableoid. newRel, parent_rel tableoid clear is - * not the same. If so, these stored generated columns require - * recomputation for newRel within MergePartitionsMoveRows. - */ - if (attribute->attgenerated == ATTRIBUTE_GENERATED_STORED) - { - newval = palloc0_object(NewColumnValue); - newval->attnum = num; - newval->expr = expression_planner((Expr *) def); - newval->is_generated = (attribute->attgenerated != '\0'); - tab->newvals = lappend(tab->newvals, newval); - } - } - } - - /* Cycle for CHECK constraints. */ - for (ccnum = 0; ccnum < constr->num_check; ccnum++) - { - char *ccname = constr->check[ccnum].ccname; - char *ccbin = constr->check[ccnum].ccbin; - bool ccenforced = constr->check[ccnum].ccenforced; - bool ccnoinherit = constr->check[ccnum].ccnoinherit; - bool ccvalid = constr->check[ccnum].ccvalid; - Node *ccbin_node; - bool found_whole_row; - Constraint *con; - - /* - * The partitioned table can not have a NO INHERIT check constraint - * (see StoreRelCheck function for details). - */ - Assert(!ccnoinherit); - - ccbin_node = map_variable_attnos(stringToNode(ccbin), - 1, 0, - attmap, - InvalidOid, &found_whole_row); - - /* - * For the moment we have to reject whole-row variables (as for CREATE - * TABLE LIKE and inheritances). - */ - if (found_whole_row) - elog(ERROR, "Constraint \"%s\" contains a whole-row reference to table \"%s\".", - ccname, - RelationGetRelationName(parent_rel)); - - con = makeNode(Constraint); - con->contype = CONSTR_CHECK; - con->conname = pstrdup(ccname); - con->deferrable = false; - con->initdeferred = false; - con->is_enforced = ccenforced; - con->skip_validation = !ccvalid; - con->initially_valid = ccvalid; - con->is_no_inherit = ccnoinherit; - con->raw_expr = NULL; - con->cooked_expr = nodeToString(ccbin_node); - con->location = -1; - constraints = lappend(constraints, con); - } - - /* Install all CHECK constraints. */ - cookedConstraints = AddRelationNewConstraints(newRel, NIL, constraints, - false, true, false, NULL); - - /* Make the additional catalog changes visible. */ - CommandCounterIncrement(); - - /* - * parent_rel check constraint expression may reference tableoid, so later - * in MergePartitionsMoveRows, we need to evaluate the check constraint - * again for the newRel. We can check whether the check constraint - * contains a tableoid reference via pull_varattnos. - */ - foreach_ptr(CookedConstraint, ccon, cookedConstraints) - { - if (!ccon->skip_validation) - { - Node *qual; - Bitmapset *attnums = NULL; - - Assert(ccon->contype == CONSTR_CHECK); - qual = expand_generated_columns_in_expr(ccon->expr, newRel, 1); - pull_varattnos(qual, 1, &attnums); - - /* - * Add a check only if it contains a tableoid - * (TableOidAttributeNumber). - */ - if (bms_is_member(TableOidAttributeNumber - FirstLowInvalidHeapAttributeNumber, - attnums)) - { - NewConstraint *newcon; - - newcon = palloc0_object(NewConstraint); - newcon->name = ccon->name; - newcon->contype = CONSTR_CHECK; - newcon->qual = qual; - - tab->constraints = lappend(tab->constraints, newcon); - } - } - } - - /* Don't need the cookedConstraints anymore. */ - list_free_deep(cookedConstraints); - - /* Reproduce not-null constraints. */ - if (constr->has_not_null) - { - List *nnconstraints; - - /* - * The "include_noinh" argument is false because a partitioned table - * can't have NO INHERIT constraint. - */ - nnconstraints = RelationGetNotNullConstraints(RelationGetRelid(parent_rel), - false, false); - - Assert(list_length(nnconstraints) > 0); - - /* - * We already set pg_attribute.attnotnull in createPartitionTable. No - * need call set_attnotnull again. - */ - AddRelationNewConstraints(newRel, NIL, nnconstraints, false, true, false, NULL); - } -} - -/* - * createPartitionTable: - * - * Create a new partition (newPartName) for the partitioned table (parent_rel). - * ownerId is determined by the partition on which the operation is performed, - * so it is passed separately. The new partition will inherit the access method - * and persistence type from the parent table. - * - * Returns the created relation (locked in AccessExclusiveLock mode). - */ -static Relation -createPartitionTable(List **wqueue, RangeVar *newPartName, - Relation parent_rel, Oid ownerId) -{ - Relation newRel; - Oid newRelId; - Oid existingRelid; - Oid tablespaceId; - TupleDesc descriptor; - List *colList = NIL; - Oid relamId; - Oid namespaceId; - AlteredTableInfo *new_partrel_tab; - Form_pg_class parent_relform = parent_rel->rd_rel; - - /* If the existing rel is temp, it must belong to this session. */ - if (RELATION_IS_OTHER_TEMP(parent_rel)) - ereport(ERROR, - errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot create as partition of temporary relation of another session")); - - /* Look up inheritance ancestors and generate the relation schema. */ - colList = getAttributesList(parent_rel); - - /* Create a tuple descriptor from the relation schema. */ - descriptor = BuildDescForRelation(colList); - - /* Look up the access method for the new relation. */ - relamId = (parent_relform->relam != InvalidOid) ? parent_relform->relam : HEAP_TABLE_AM_OID; - - /* Look up the namespace in which we are supposed to create the relation. */ - namespaceId = - RangeVarGetAndCheckCreationNamespace(newPartName, NoLock, &existingRelid); - if (OidIsValid(existingRelid)) - ereport(ERROR, - errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("relation \"%s\" already exists", newPartName->relname)); - - /* - * We intended to create the partition with the same persistence as the - * parent table, but we still need to recheck because that might be - * affected by the search_path. If the parent is permanent, so must be - * all of its partitions. - */ - if (parent_relform->relpersistence != RELPERSISTENCE_TEMP && - newPartName->relpersistence == RELPERSISTENCE_TEMP) - ereport(ERROR, - errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot create a temporary relation as partition of permanent relation \"%s\"", - RelationGetRelationName(parent_rel))); - - /* Permanent rels cannot be partitions belonging to a temporary parent. */ - if (newPartName->relpersistence != RELPERSISTENCE_TEMP && - parent_relform->relpersistence == RELPERSISTENCE_TEMP) - ereport(ERROR, - errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot create a permanent relation as partition of temporary relation \"%s\"", - RelationGetRelationName(parent_rel))); - - /* - * Select the tablespace for the new partition. Mirror the logic that - * CREATE TABLE foo PARTITION OF ... uses in DefineRelation: take the - * partitioned parent's explicit tablespace if it has one, otherwise take - * default_tablespace into account, and finally use the database default. - */ - tablespaceId = parent_relform->reltablespace; - if (!OidIsValid(tablespaceId)) - tablespaceId = GetDefaultTablespace(newPartName->relpersistence, false); - - /* Check permissions except when using database's default */ - if (OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace) - { - AclResult aclresult; - - aclresult = object_aclcheck(TableSpaceRelationId, tablespaceId, - GetUserId(), ACL_CREATE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, OBJECT_TABLESPACE, - get_tablespace_name(tablespaceId)); - } - - /* In all cases disallow placing user relations in pg_global */ - if (tablespaceId == GLOBALTABLESPACE_OID) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("only shared relations can be placed in pg_global tablespace"))); - - /* Create the relation. */ - newRelId = heap_create_with_catalog(newPartName->relname, - namespaceId, - tablespaceId, - InvalidOid, - InvalidOid, - InvalidOid, - ownerId, - relamId, - descriptor, - NIL, - RELKIND_RELATION, - newPartName->relpersistence, - false, - false, - ONCOMMIT_NOOP, - (Datum) 0, - true, - allowSystemTableMods, - false, /* is_internal */ - InvalidOid, - NULL); - - /* - * We must bump the command counter to make the newly-created relation - * tuple visible for opening. - */ - CommandCounterIncrement(); - - /* - * Create a TOAST table if the table needs one. MERGE/SPLIT PARTITION - * moves rows from existing partition(s) into new partition(s), which may - * carry out-of-line varlena values that the new relation must be able to - * store. Also, the new partition must be able to receive out-of-line - * varlena values after the DDL operation is complete. - */ - NewRelationCreateToastTable(newRelId, (Datum) 0); - - /* - * Open the new partition with no lock, because we already have an - * AccessExclusiveLock placed there after creation. - */ - newRel = table_open(newRelId, NoLock); - - /* Find or create a work queue entry for the newly created table. */ - new_partrel_tab = ATGetQueueEntry(wqueue, newRel); - - /* Create constraints, default values, and generated values. */ - createTableConstraints(wqueue, new_partrel_tab, parent_rel, newRel); - - /* - * Need to call CommandCounterIncrement, so a fresh relcache entry has - * newly installed constraint info. - */ - CommandCounterIncrement(); - - return newRel; -} - -/* - * MergePartitionsMoveRows: scan partitions to be merged (mergingPartitions) - * of the partitioned table and move rows into the new partition - * (newPartRel). We also verify check constraints against these rows. - */ -static void -MergePartitionsMoveRows(List **wqueue, List *mergingPartitions, Relation newPartRel) -{ - CommandId mycid; - EState *estate; - AlteredTableInfo *tab; - ListCell *ltab; - - /* The FSM is empty, so don't bother using it. */ - uint32 ti_options = TABLE_INSERT_SKIP_FSM; - BulkInsertState bistate; /* state of bulk inserts for partition */ - TupleTableSlot *dstslot; - - /* Find the work queue entry for the new partition table: newPartRel. */ - tab = ATGetQueueEntry(wqueue, newPartRel); - - /* Generate the constraint and default execution states. */ - estate = CreateExecutorState(); - - buildExpressionExecutionStates(tab, newPartRel, estate); - - mycid = GetCurrentCommandId(true); - - /* Prepare a BulkInsertState for table_tuple_insert. */ - bistate = GetBulkInsertState(); - - /* Create the necessary tuple slot. */ - dstslot = table_slot_create(newPartRel, NULL); - - foreach_oid(merging_oid, mergingPartitions) - { - ExprContext *econtext; - TupleTableSlot *srcslot; - TupleConversionMap *tuple_map; - TableScanDesc scan; - MemoryContext oldCxt; - Snapshot snapshot; - Relation mergingPartition; - - econtext = GetPerTupleExprContext(estate); - - /* - * Partition is already locked in the transformPartitionCmdForMerge - * function. - */ - mergingPartition = table_open(merging_oid, NoLock); - - /* Create a source tuple slot for the partition being merged. */ - srcslot = table_slot_create(mergingPartition, NULL); - - /* - * Map computing for moving attributes of the merged partition to the - * new partition. - */ - tuple_map = convert_tuples_by_name(RelationGetDescr(mergingPartition), - RelationGetDescr(newPartRel)); - - /* Scan through the rows. */ - snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = table_beginscan(mergingPartition, snapshot, 0, NULL, - SO_NONE); - - /* - * Switch to per-tuple memory context and reset it for each tuple - * produced, so we don't leak memory. - */ - oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - - while (table_scan_getnextslot(scan, ForwardScanDirection, srcslot)) - { - TupleTableSlot *insertslot; - - CHECK_FOR_INTERRUPTS(); - - if (tuple_map) - { - /* Need to use a map to copy attributes. */ - insertslot = execute_attr_map_slot(tuple_map->attrMap, srcslot, dstslot); - } - else - { - slot_getallattrs(srcslot); - - /* Copy attributes directly. */ - insertslot = dstslot; - - ExecClearTuple(insertslot); - - memcpy(insertslot->tts_values, srcslot->tts_values, - sizeof(Datum) * srcslot->tts_nvalid); - memcpy(insertslot->tts_isnull, srcslot->tts_isnull, - sizeof(bool) * srcslot->tts_nvalid); - - ExecStoreVirtualTuple(insertslot); - } - - /* - * Constraints and GENERATED expressions might reference the - * tableoid column, so fill tts_tableOid with the desired value. - * (We must do this each time, because it gets overwritten with - * newrel's OID during storing.) - */ - insertslot->tts_tableOid = RelationGetRelid(newPartRel); - - /* - * Now, evaluate any generated expressions whose inputs come from - * the new tuple. We assume these columns won't reference each - * other, so that there's no ordering dependency. - */ - evaluateGeneratedExpressionsAndCheckConstraints(tab, newPartRel, - insertslot, econtext); - - /* Write the tuple out to the new relation. */ - table_tuple_insert(newPartRel, insertslot, mycid, - ti_options, bistate); - - ResetExprContext(econtext); - } - - MemoryContextSwitchTo(oldCxt); - table_endscan(scan); - UnregisterSnapshot(snapshot); - - if (tuple_map) - free_conversion_map(tuple_map); - - ExecDropSingleTupleTableSlot(srcslot); - table_close(mergingPartition, NoLock); - } - - FreeExecutorState(estate); - ExecDropSingleTupleTableSlot(dstslot); - FreeBulkInsertState(bistate); - - table_finish_bulk_insert(newPartRel, ti_options); - - /* - * We don't need to process this newPartRel since we already processed it - * here, so delete the ALTER TABLE queue for it. - */ - foreach(ltab, *wqueue) - { - tab = (AlteredTableInfo *) lfirst(ltab); - if (tab->relid == RelationGetRelid(newPartRel)) - { - *wqueue = list_delete_cell(*wqueue, ltab); - break; - } - } -} - -/* - * detachPartitionTable: detach partition "child_rel" from partitioned table - * "parent_rel" with default partition identifier "defaultPartOid" - */ -static void -detachPartitionTable(Relation parent_rel, Relation child_rel, Oid defaultPartOid) -{ - /* Remove the pg_inherits row first. */ - RemoveInheritance(child_rel, parent_rel, false); - - /* - * Detaching the partition might involve TOAST table access, so ensure we - * have a valid snapshot. - */ - PushActiveSnapshot(GetTransactionSnapshot()); - - /* Do the final part of detaching. */ - DetachPartitionFinalize(parent_rel, child_rel, false, defaultPartOid); - - PopActiveSnapshot(); -} - -/* - * equal_oid_lists: return true if two OID lists, each sorted in ascending - * order, contain the same OIDs in the same order. - */ -static bool -equal_oid_lists(const List *a, const List *b) -{ - ListCell *la, - *lb; - - if (list_length(a) != list_length(b)) - return false; - - forboth(la, a, lb, b) - { - if (lfirst_oid(la) != lfirst_oid(lb)) - return false; - } - return true; -} - -/* - * Comparator for list_sort() on a list of PartitionIndexExtDepEntry *. - * Orders by parentIndexOid, then by indexOid as a tiebreaker so conflict - * reports for different parent indexes are deterministic. - */ -static int -cmp_partition_index_ext_dep(const ListCell *a, const ListCell *b) -{ - const PartitionIndexExtDepEntry *ea = lfirst(a); - const PartitionIndexExtDepEntry *eb = lfirst(b); - - if (ea->parentIndexOid != eb->parentIndexOid) - return pg_cmp_u32(ea->parentIndexOid, eb->parentIndexOid); - return pg_cmp_u32(ea->indexOid, eb->indexOid); -} - -/* - * collectPartitionIndexExtDeps: collect extension dependencies from indexes - * on the given partitions. - * - * For each partition index that has a parent partitioned index, we collect - * extension dependencies. All source partition indexes sharing the same - * parent partitioned index must depend on exactly the same set of - * extensions; otherwise an error is raised so that we neither silently drop - * nor silently add dependencies on the merged partition's index. - * - * Indexes that don't have a parent partitioned index (i.e., indexes created - * directly on a partition without a corresponding parent index) are skipped. - * - * The returned list is sorted by parentIndexOid with exactly one entry per - * parent partitioned index, so applyPartitionIndexExtDeps() can scan it - * linearly. - */ -static List * -collectPartitionIndexExtDeps(List *partitionOids) -{ - List *collected = NIL; - List *result = NIL; - PartitionIndexExtDepEntry *prev = NULL; - - /* - * Phase 1: collect one entry per (partition index -> parent index) pair, - * with its extension dependency OIDs sorted ascending. - */ - foreach_oid(partOid, partitionOids) - { - Relation partRel; - List *indexList; - - /* - * Use NoLock since the caller already holds AccessExclusiveLock on - * these partitions. - */ - partRel = table_open(partOid, NoLock); - indexList = RelationGetIndexList(partRel); - - foreach_oid(indexOid, indexList) - { - Oid parentIndexOid; - PartitionIndexExtDepEntry *entry; - - if (!get_rel_relispartition(indexOid)) - continue; - - parentIndexOid = get_partition_parent(indexOid, true); - if (!OidIsValid(parentIndexOid)) - continue; - - entry = palloc(sizeof(PartitionIndexExtDepEntry)); - entry->parentIndexOid = parentIndexOid; - entry->indexOid = indexOid; - entry->extensionOids = getAutoExtensionsOfObject(RelationRelationId, - indexOid); - list_sort(entry->extensionOids, list_oid_cmp); - - collected = lappend(collected, entry); - } - - list_free(indexList); - table_close(partRel, NoLock); - } - - /* - * Phase 2: sort by parentIndexOid so entries sharing a parent index sit - * adjacent. - */ - list_sort(collected, cmp_partition_index_ext_dep); - - /* - * Phase 3: single linear pass verifying that adjacent entries sharing a - * parent index have identical extension dependencies, and keeping one - * representative entry per parent index. - */ - foreach_ptr(PartitionIndexExtDepEntry, entry, collected) - { - if (prev != NULL && prev->parentIndexOid == entry->parentIndexOid) - { - if (!equal_oid_lists(prev->extensionOids, entry->extensionOids)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot merge partitions with conflicting extension dependencies"), - errdetail("Partition indexes \"%s\" and \"%s\" depend on different extensions.", - get_rel_name(prev->indexOid), - get_rel_name(entry->indexOid)))); - - /* Duplicate entry for the same parent index; discard. */ - list_free(entry->extensionOids); - pfree(entry); - continue; - } - - result = lappend(result, entry); - prev = entry; - } - - list_free(collected); - - return result; -} - -/* - * applyPartitionIndexExtDeps: apply collected extension dependencies to - * indexes on a new partition. - * - * For each index on the new partition, look up its parent index in the - * extDepState list. If found, record extension dependencies on the new index. - * extDepState is sorted by parentIndexOid, so the inner scan can bail out - * as soon as it passes the target OID. - */ -static void -applyPartitionIndexExtDeps(Oid newPartOid, List *extDepState) -{ - Relation partRel; - List *indexList; - - if (extDepState == NIL) - return; - - /* - * Use NoLock since the caller already holds AccessExclusiveLock on the - * new partition. - */ - partRel = table_open(newPartOid, NoLock); - indexList = RelationGetIndexList(partRel); - - foreach_oid(indexOid, indexList) - { - Oid parentIdxOid; - - if (!get_rel_relispartition(indexOid)) - continue; - - parentIdxOid = get_partition_parent(indexOid, true); - if (!OidIsValid(parentIdxOid)) - continue; - - foreach_ptr(PartitionIndexExtDepEntry, entry, extDepState) - { - ObjectAddress indexAddr; - - if (entry->parentIndexOid > parentIdxOid) - break; - if (entry->parentIndexOid < parentIdxOid) - continue; - - ObjectAddressSet(indexAddr, RelationRelationId, indexOid); - - foreach_oid(extOid, entry->extensionOids) - { - ObjectAddress extAddr; - - ObjectAddressSet(extAddr, ExtensionRelationId, extOid); - recordDependencyOn(&indexAddr, &extAddr, - DEPENDENCY_AUTO_EXTENSION); - } - break; - } - } - - list_free(indexList); - table_close(partRel, NoLock); -} - -/* - * freePartitionIndexExtDeps: free memory allocated by collectPartitionIndexExtDeps. - */ -static void -freePartitionIndexExtDeps(List *extDepState) -{ - foreach_ptr(PartitionIndexExtDepEntry, entry, extDepState) - { - list_free(entry->extensionOids); - pfree(entry); - } - list_free(extDepState); -} - -/* - * ALTER TABLE MERGE PARTITIONS INTO - */ -static void -ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel, - PartitionCmd *cmd, AlterTableUtilityContext *context) -{ - Relation newPartRel; - List *mergingPartitions = NIL; - List *extDepState = NIL; - Oid defaultPartOid; - Oid existingRelid; - Oid ownerId = InvalidOid; - Oid save_userid; - int save_sec_context; - int save_nestlevel; - - /* - * Check ownership of merged partitions - partitions with different owners - * cannot be merged. Also, collect the OIDs of these partitions during the - * check. - */ - foreach_node(RangeVar, name, cmd->partlist) - { - Relation mergingPartition; - - /* - * We are going to detach and remove this partition. We already took - * AccessExclusiveLock lock on transformPartitionCmdForMerge, so here, - * NoLock is fine. - */ - mergingPartition = table_openrv_extended(name, NoLock, false); - Assert(CheckRelationLockedByMe(mergingPartition, AccessExclusiveLock, false)); - - if (OidIsValid(ownerId)) - { - /* Do the partitions being merged have different owners? */ - if (ownerId != mergingPartition->rd_rel->relowner) - ereport(ERROR, - errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("partitions being merged have different owners")); - } - else - ownerId = mergingPartition->rd_rel->relowner; - - /* Store the next merging partition into the list. */ - mergingPartitions = lappend_oid(mergingPartitions, - RelationGetRelid(mergingPartition)); - - table_close(mergingPartition, NoLock); - } - - /* Look up the existing relation by the new partition name. */ - RangeVarGetAndCheckCreationNamespace(cmd->name, NoLock, &existingRelid); - - /* - * Check if this name is already taken. This helps us to detect the - * situation when one of the merging partitions has the same name as the - * new partition. Otherwise, this would fail later on anyway, but - * catching this here allows us to emit a nicer error message. - */ - if (OidIsValid(existingRelid)) - { - if (list_member_oid(mergingPartitions, existingRelid)) - { - /* - * The new partition has the same name as one of the merging - * partitions. - */ - char tmpRelName[NAMEDATALEN]; - - /* Generate a temporary name. */ - sprintf(tmpRelName, "merge-%u-%X-tmp", RelationGetRelid(rel), MyProcPid); - - /* - * Rename the existing partition with a temporary name, leaving it - * free for the new partition. We don't need to care about this - * in the future because we're going to eventually drop the - * existing partition anyway. - */ - RenameRelationInternal(existingRelid, tmpRelName, true, false); - - /* - * We must bump the command counter to make the new partition - * tuple visible for rename. - */ - CommandCounterIncrement(); - } - else - { - ereport(ERROR, - errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("relation \"%s\" already exists", cmd->name->relname)); - } - } - - defaultPartOid = - get_default_oid_from_partdesc(RelationGetPartitionDesc(rel, true)); - - /* - * Collect extension dependencies from indexes on the merging partitions. - * We must do this before detaching them, so we can restore the - * dependencies on the new partition's indexes later. - */ - extDepState = collectPartitionIndexExtDeps(mergingPartitions); - - /* Detach all merging partitions. */ - foreach_oid(mergingPartitionOid, mergingPartitions) - { - Relation child_rel; - - child_rel = table_open(mergingPartitionOid, NoLock); - - detachPartitionTable(rel, child_rel, defaultPartOid); - - table_close(child_rel, NoLock); - } - - /* - * Perform a preliminary check to determine whether it's safe to drop all - * merging partitions before we actually do so later. After merging rows - * into the new partitions via MergePartitionsMoveRows, all old partitions - * need to be dropped. However, since the drop behavior is DROP_RESTRICT - * and the merge process (MergePartitionsMoveRows) can be time-consuming, - * performing an early check on the drop eligibility of old partitions is - * preferable. - */ - foreach_oid(mergingPartitionOid, mergingPartitions) - { - ObjectAddress object; - - /* Get oid of the later to be dropped relation. */ - object.objectId = mergingPartitionOid; - object.classId = RelationRelationId; - object.objectSubId = 0; - - performDeletionCheck(&object, DROP_RESTRICT, 0); - } - - /* - * Create a table for the new partition, using the partitioned table as a - * model. - */ - Assert(OidIsValid(ownerId)); - newPartRel = createPartitionTable(wqueue, cmd->name, rel, ownerId); - - /* - * Switch to the table owner's userid, so that any index functions are run - * as that user. Also, lockdown security-restricted operations and - * arrange to make GUC variable changes local to this command. - * - * Need to do it after determining the namespace in the - * createPartitionTable() call. - */ - GetUserIdAndSecContext(&save_userid, &save_sec_context); - SetUserIdAndSecContext(ownerId, - save_sec_context | SECURITY_RESTRICTED_OPERATION); - save_nestlevel = NewGUCNestLevel(); - RestrictSearchPath(); - - /* Copy data from merged partitions to the new partition. */ - MergePartitionsMoveRows(wqueue, mergingPartitions, newPartRel); - - /* Drop the current partitions before attaching the new one. */ - foreach_oid(mergingPartitionOid, mergingPartitions) - { - ObjectAddress object; - - object.objectId = mergingPartitionOid; - object.classId = RelationRelationId; - object.objectSubId = 0; - - performDeletion(&object, DROP_RESTRICT, 0); - } - - list_free(mergingPartitions); - - /* - * Attach a new partition to the partitioned table. wqueue = NULL: - * verification for each cloned constraint is not needed. - */ - attachPartitionTable(NULL, rel, newPartRel, cmd->bound); - - /* - * Apply extension dependencies to the new partition's indexes. This - * preserves any "DEPENDS ON EXTENSION" settings from the merged - * partitions. - */ - applyPartitionIndexExtDeps(RelationGetRelid(newPartRel), extDepState); - - freePartitionIndexExtDeps(extDepState); - - /* Keep the lock until commit. */ - table_close(newPartRel, NoLock); - - /* Roll back any GUC changes executed by index functions. */ - AtEOXact_GUC(false, save_nestlevel); - - /* Restore the userid and security context. */ - SetUserIdAndSecContext(save_userid, save_sec_context); -} - -/* - * Struct with the context of the new partition for inserting rows from the - * split partition. - */ -typedef struct SplitPartitionContext -{ - ExprState *partqualstate; /* expression for checking a slot for a - * partition (NULL for DEFAULT partition) */ - BulkInsertState bistate; /* state of bulk inserts for partition */ - TupleTableSlot *dstslot; /* slot for inserting row into partition */ - AlteredTableInfo *tab; /* structure with generated column expressions - * and check constraint expressions. */ - Relation partRel; /* relation for partition */ -} SplitPartitionContext; - -/* - * createSplitPartitionContext: create context for partition and fill it - */ -static SplitPartitionContext * -createSplitPartitionContext(Relation partRel) -{ - SplitPartitionContext *pc; - - pc = palloc0_object(SplitPartitionContext); - pc->partRel = partRel; - - /* - * Prepare a BulkInsertState for table_tuple_insert. The FSM is empty, so - * don't bother using it. - */ - pc->bistate = GetBulkInsertState(); - - /* Create a destination tuple slot for the new partition. */ - pc->dstslot = table_slot_create(pc->partRel, NULL); - - return pc; -} - -/* - * deleteSplitPartitionContext: delete context for partition - */ -static void -deleteSplitPartitionContext(SplitPartitionContext *pc, List **wqueue, uint32 ti_options) -{ - ListCell *ltab; - - ExecDropSingleTupleTableSlot(pc->dstslot); - FreeBulkInsertState(pc->bistate); - - table_finish_bulk_insert(pc->partRel, ti_options); - - /* - * We don't need to process this pc->partRel so delete the ALTER TABLE - * queue of it. - */ - foreach(ltab, *wqueue) - { - AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab); - - if (tab->relid == RelationGetRelid(pc->partRel)) - { - *wqueue = list_delete_cell(*wqueue, ltab); - break; - } - } - - pfree(pc); -} - -/* - * SplitPartitionMoveRows: scan split partition (splitRel) of partitioned table - * (rel) and move rows into new partitions. - * - * New partitions description: - * partlist: list of pointers to SinglePartitionSpec structures. It contains - * the partition specification details for all new partitions. - * newPartRels: list of Relations, new partitions created in - * ATExecSplitPartition. - */ -static void -SplitPartitionMoveRows(List **wqueue, Relation rel, Relation splitRel, - List *partlist, List *newPartRels) -{ - /* The FSM is empty, so don't bother using it. */ - uint32 ti_options = TABLE_INSERT_SKIP_FSM; - CommandId mycid; - EState *estate; - ListCell *listptr, - *listptr2; - TupleTableSlot *srcslot; - ExprContext *econtext; - TableScanDesc scan; - Snapshot snapshot; - MemoryContext oldCxt; - List *partContexts = NIL; - TupleConversionMap *tuple_map; - SplitPartitionContext *defaultPartCtx = NULL, - *pc; - - mycid = GetCurrentCommandId(true); - - estate = CreateExecutorState(); - - forboth(listptr, partlist, listptr2, newPartRels) - { - SinglePartitionSpec *sps = (SinglePartitionSpec *) lfirst(listptr); - - pc = createSplitPartitionContext((Relation) lfirst(listptr2)); - - /* Find the work queue entry for the new partition table: newPartRel. */ - pc->tab = ATGetQueueEntry(wqueue, pc->partRel); - - buildExpressionExecutionStates(pc->tab, pc->partRel, estate); - - if (sps->bound->is_default) - { - /* - * We should not create a structure to check the partition - * constraint for the new DEFAULT partition. - */ - defaultPartCtx = pc; - } - else - { - List *partConstraint; - - /* Build expression execution states for partition check quals. */ - partConstraint = get_qual_from_partbound(rel, sps->bound); - partConstraint = - (List *) eval_const_expressions(NULL, - (Node *) partConstraint); - /* Make a boolean expression for ExecCheck(). */ - partConstraint = list_make1(make_ands_explicit(partConstraint)); - - /* - * Map the vars in the constraint expression from rel's attnos to - * splitRel's. - */ - partConstraint = map_partition_varattnos(partConstraint, - 1, splitRel, rel); - - pc->partqualstate = - ExecPrepareExpr((Expr *) linitial(partConstraint), estate); - Assert(pc->partqualstate != NULL); - } - - /* Store partition context into a list. */ - partContexts = lappend(partContexts, pc); - } - - econtext = GetPerTupleExprContext(estate); - - /* Create the necessary tuple slot. */ - srcslot = table_slot_create(splitRel, NULL); - - /* - * Map computing for moving attributes of the split partition to the new - * partition (for the first new partition, but other new partitions can - * use the same map). - */ - pc = (SplitPartitionContext *) lfirst(list_head(partContexts)); - tuple_map = convert_tuples_by_name(RelationGetDescr(splitRel), - RelationGetDescr(pc->partRel)); - - /* Scan through the rows. */ - snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = table_beginscan(splitRel, snapshot, 0, NULL, - SO_NONE); - - /* - * Switch to per-tuple memory context and reset it for each tuple - * produced, so we don't leak memory. - */ - oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - - while (table_scan_getnextslot(scan, ForwardScanDirection, srcslot)) - { - bool found = false; - TupleTableSlot *insertslot; - - CHECK_FOR_INTERRUPTS(); - - econtext->ecxt_scantuple = srcslot; - - /* Search partition for the current slot, srcslot. */ - foreach(listptr, partContexts) - { - pc = (SplitPartitionContext *) lfirst(listptr); - - /* skip DEFAULT partition */ - if (pc->partqualstate && ExecCheck(pc->partqualstate, econtext)) - { - found = true; - break; - } - } - if (!found) - { - /* Use the DEFAULT partition if it exists. */ - if (defaultPartCtx) - pc = defaultPartCtx; - else - ereport(ERROR, - errcode(ERRCODE_CHECK_VIOLATION), - errmsg("cannot find partition for split partition row"), - errtable(splitRel)); - } - - if (tuple_map) - { - /* Need to use a map to copy attributes. */ - insertslot = execute_attr_map_slot(tuple_map->attrMap, srcslot, pc->dstslot); - } - else - { - /* Extract data from the old tuple. */ - slot_getallattrs(srcslot); - - /* Copy attributes directly. */ - insertslot = pc->dstslot; - - ExecClearTuple(insertslot); - - memcpy(insertslot->tts_values, srcslot->tts_values, - sizeof(Datum) * srcslot->tts_nvalid); - memcpy(insertslot->tts_isnull, srcslot->tts_isnull, - sizeof(bool) * srcslot->tts_nvalid); - - ExecStoreVirtualTuple(insertslot); - } - - /* - * Constraints and GENERATED expressions might reference the tableoid - * column, so fill tts_tableOid with the desired value. (We must do - * this each time, because it gets overwritten with newrel's OID - * during storing.) - */ - insertslot->tts_tableOid = RelationGetRelid(pc->partRel); - - /* - * Now, evaluate any generated expressions whose inputs come from the - * new tuple. We assume these columns won't reference each other, so - * that there's no ordering dependency. - */ - evaluateGeneratedExpressionsAndCheckConstraints(pc->tab, pc->partRel, - insertslot, econtext); - - /* Write the tuple out to the new relation. */ - table_tuple_insert(pc->partRel, insertslot, mycid, - ti_options, pc->bistate); - - ResetExprContext(econtext); - } - - MemoryContextSwitchTo(oldCxt); - - table_endscan(scan); - UnregisterSnapshot(snapshot); - - if (tuple_map) - free_conversion_map(tuple_map); - - ExecDropSingleTupleTableSlot(srcslot); - - FreeExecutorState(estate); - - foreach_ptr(SplitPartitionContext, spc, partContexts) - deleteSplitPartitionContext(spc, wqueue, ti_options); -} - -/* - * ALTER TABLE SPLIT PARTITION INTO - */ -static void -ATExecSplitPartition(List **wqueue, AlteredTableInfo *tab, Relation rel, - PartitionCmd *cmd, AlterTableUtilityContext *context) -{ - Relation splitRel; - Oid splitRelOid; - ListCell *listptr, - *listptr2; - bool isSameName = false; - char tmpRelName[NAMEDATALEN]; - List *newPartRels = NIL; - List *extDepState = NIL; - ObjectAddress object; - Oid defaultPartOid; - Oid save_userid; - int save_sec_context; - int save_nestlevel; - List *splitPartList; - - defaultPartOid = get_default_oid_from_partdesc(RelationGetPartitionDesc(rel, true)); - - /* - * Partition is already locked in the transformPartitionCmdForSplit - * function. - */ - splitRel = table_openrv(cmd->name, NoLock); - - splitRelOid = RelationGetRelid(splitRel); - - /* Check descriptions of new partitions. */ - foreach_node(SinglePartitionSpec, sps, cmd->partlist) - { - Oid existingRelid; - - /* Look up the existing relation by the new partition name. */ - RangeVarGetAndCheckCreationNamespace(sps->name, NoLock, &existingRelid); - - /* - * This would fail later on anyway if the relation already exists. But - * by catching it here, we can emit a nicer error message. - */ - if (existingRelid == splitRelOid && !isSameName) - /* One new partition can have the same name as a split partition. */ - isSameName = true; - else if (OidIsValid(existingRelid)) - ereport(ERROR, - errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("relation \"%s\" already exists", sps->name->relname)); - } - - /* - * Collect extension dependencies from indexes on the split partition. We - * must do this before detaching it, so we can restore the dependencies on - * the new partitions' indexes later. - */ - splitPartList = list_make1_oid(splitRelOid); - - extDepState = collectPartitionIndexExtDeps(splitPartList); - list_free(splitPartList); - - /* Detach the split partition. */ - detachPartitionTable(rel, splitRel, defaultPartOid); - - /* - * Perform a preliminary check to determine whether it's safe to drop the - * split partition before we actually do so later. After merging rows into - * the new partitions via SplitPartitionMoveRows, all old partitions need - * to be dropped. However, since the drop behavior is DROP_RESTRICT and - * the merge process (SplitPartitionMoveRows) can be time-consuming, - * performing an early check on the drop eligibility of old partitions is - * preferable. - */ - object.objectId = splitRelOid; - object.classId = RelationRelationId; - object.objectSubId = 0; - performDeletionCheck(&object, DROP_RESTRICT, 0); - - /* - * If a new partition has the same name as the split partition, then we - * should rename the split partition to reuse its name. - */ - if (isSameName) - { - /* - * We must bump the command counter to make the split partition tuple - * visible for renaming. - */ - CommandCounterIncrement(); - /* Rename partition. */ - sprintf(tmpRelName, "split-%u-%X-tmp", RelationGetRelid(rel), MyProcPid); - RenameRelationInternal(splitRelOid, tmpRelName, true, false); - - /* - * We must bump the command counter to make the split partition tuple - * visible after renaming. - */ - CommandCounterIncrement(); - } - - /* Create new partitions (like a split partition), without indexes. */ - foreach_node(SinglePartitionSpec, sps, cmd->partlist) - { - Relation newPartRel; - - newPartRel = createPartitionTable(wqueue, sps->name, rel, - splitRel->rd_rel->relowner); - newPartRels = lappend(newPartRels, newPartRel); - } - - /* - * Switch to the table owner's userid, so that any index functions are run - * as that user. Also, lockdown security-restricted operations and - * arrange to make GUC variable changes local to this command. - * - * Need to do it after determining the namespace in the - * createPartitionTable() call. - */ - GetUserIdAndSecContext(&save_userid, &save_sec_context); - SetUserIdAndSecContext(splitRel->rd_rel->relowner, - save_sec_context | SECURITY_RESTRICTED_OPERATION); - save_nestlevel = NewGUCNestLevel(); - RestrictSearchPath(); - - /* Copy data from the split partition to the new partitions. */ - SplitPartitionMoveRows(wqueue, rel, splitRel, cmd->partlist, newPartRels); - /* Keep the lock until commit. */ - table_close(splitRel, NoLock); - - /* Attach new partitions to the partitioned table. */ - forboth(listptr, cmd->partlist, listptr2, newPartRels) - { - SinglePartitionSpec *sps = (SinglePartitionSpec *) lfirst(listptr); - Relation newPartRel = (Relation) lfirst(listptr2); - - /* - * wqueue = NULL: verification for each cloned constraint is not - * needed. - */ - attachPartitionTable(NULL, rel, newPartRel, sps->bound); - - /* - * Apply extension dependencies to the new partition's indexes. This - * preserves any "DEPENDS ON EXTENSION" settings from the split - * partition. - */ - applyPartitionIndexExtDeps(RelationGetRelid(newPartRel), extDepState); - - /* Keep the lock until commit. */ - table_close(newPartRel, NoLock); - } - - freePartitionIndexExtDeps(extDepState); - - /* Drop the split partition. */ - object.classId = RelationRelationId; - object.objectId = splitRelOid; - object.objectSubId = 0; - /* Probably DROP_CASCADE is not needed. */ - performDeletion(&object, DROP_RESTRICT, 0); - - /* Roll back any GUC changes executed by index functions. */ - AtEOXact_GUC(false, save_nestlevel); - - /* Restore the userid and security context. */ - SetUserIdAndSecContext(save_userid, save_sec_context); -} diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 4b152c294ca..091d4423592 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -262,7 +262,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); PartitionElem *partelem; PartitionSpec *partspec; PartitionBoundSpec *partboundspec; - SinglePartitionSpec *singlepartspec; RoleSpec *rolespec; PublicationObjSpec *publicationobjectspec; PublicationAllObjSpec *publicationallobjectspec; @@ -654,8 +653,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type part_elem %type part_params %type PartitionBoundSpec -%type SinglePartitionSpec -%type partitions_list %type hash_partbound %type hash_partbound_elem @@ -800,7 +797,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); ORDER ORDINALITY OTHERS OUT_P OUTER_P OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER - PARALLEL PARAMETER PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PATH + PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PATH PERIOD PLACING PLAN PLANS POLICY PORTION POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PROPERTIES PROPERTY PUBLICATION @@ -815,7 +812,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW - SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SPLIT SOURCE SQL_P STABLE STANDALONE_P + SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SOURCE SQL_P STABLE STANDALONE_P START STATEMENT STATISTICS STDIN STDOUT STORAGE STORED STRICT_P STRING_P STRIP_P SUBSCRIPTION SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P SYSTEM_USER @@ -2436,23 +2433,6 @@ alter_table_cmds: | alter_table_cmds ',' alter_table_cmd { $$ = lappend($1, $3); } ; -partitions_list: - SinglePartitionSpec { $$ = list_make1($1); } - | partitions_list ',' SinglePartitionSpec { $$ = lappend($1, $3); } - ; - -SinglePartitionSpec: - PARTITION qualified_name PartitionBoundSpec - { - SinglePartitionSpec *n = makeNode(SinglePartitionSpec); - - n->name = $2; - n->bound = $3; - - $$ = n; - } - ; - partition_cmd: /* ALTER TABLE ATTACH PARTITION FOR VALUES */ ATTACH PARTITION qualified_name PartitionBoundSpec @@ -2463,7 +2443,6 @@ partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = $4; - cmd->partlist = NIL; cmd->concurrent = false; n->def = (Node *) cmd; @@ -2478,7 +2457,6 @@ partition_cmd: n->subtype = AT_DetachPartition; cmd->name = $3; cmd->bound = NULL; - cmd->partlist = NIL; cmd->concurrent = $4; n->def = (Node *) cmd; @@ -2492,35 +2470,6 @@ partition_cmd: n->subtype = AT_DetachPartitionFinalize; cmd->name = $3; cmd->bound = NULL; - cmd->partlist = NIL; - cmd->concurrent = false; - n->def = (Node *) cmd; - $$ = (Node *) n; - } - /* ALTER TABLE SPLIT PARTITION INTO () */ - | SPLIT PARTITION qualified_name INTO '(' partitions_list ')' - { - AlterTableCmd *n = makeNode(AlterTableCmd); - PartitionCmd *cmd = makeNode(PartitionCmd); - - n->subtype = AT_SplitPartition; - cmd->name = $3; - cmd->bound = NULL; - cmd->partlist = $6; - cmd->concurrent = false; - n->def = (Node *) cmd; - $$ = (Node *) n; - } - /* ALTER TABLE MERGE PARTITIONS () INTO */ - | MERGE PARTITIONS '(' qualified_name_list ')' INTO qualified_name - { - AlterTableCmd *n = makeNode(AlterTableCmd); - PartitionCmd *cmd = makeNode(PartitionCmd); - - n->subtype = AT_MergePartitions; - cmd->name = $7; - cmd->bound = NULL; - cmd->partlist = $4; cmd->concurrent = false; n->def = (Node *) cmd; $$ = (Node *) n; @@ -2537,7 +2486,6 @@ index_partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = NULL; - cmd->partlist = NIL; cmd->concurrent = false; n->def = (Node *) cmd; @@ -19020,7 +18968,6 @@ unreserved_keyword: | PARSER | PARTIAL | PARTITION - | PARTITIONS | PASSING | PASSWORD | PATH @@ -19095,7 +19042,6 @@ unreserved_keyword: | SKIP | SNAPSHOT | SOURCE - | SPLIT | SQL_P | STABLE | STANDALONE_P @@ -19664,7 +19610,6 @@ bare_label_keyword: | PARSER | PARTIAL | PARTITION - | PARTITIONS | PASSING | PASSWORD | PATH @@ -19750,7 +19695,6 @@ bare_label_keyword: | SNAPSHOT | SOME | SOURCE - | SPLIT | SQL_P | STABLE | STANDALONE_P diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 5d90c6692c5..424cb1dc878 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -33,7 +33,6 @@ #include "catalog/heap.h" #include "catalog/index.h" #include "catalog/namespace.h" -#include "catalog/partition.h" #include "catalog/pg_am.h" #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" @@ -60,8 +59,6 @@ #include "parser/parse_type.h" #include "parser/parse_utilcmd.h" #include "parser/parser.h" -#include "partitioning/partbounds.h" -#include "partitioning/partdesc.h" #include "rewrite/rewriteManip.h" #include "utils/acl.h" #include "utils/builtins.h" @@ -132,7 +129,7 @@ static void checkSchemaNameList(const char *context_schema, static CreateStmt *transformCreateSchemaCreateTable(ParseState *pstate, CreateStmt *stmt, List **fk_elements); -static void transformPartitionCmd(CreateStmtContext *cxt, PartitionBoundSpec *bound); +static void transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd); static List *transformPartitionRangeBounds(ParseState *pstate, List *blist, Relation parent); static void validateInfiniteBounds(ParseState *pstate, List *blist); @@ -3532,287 +3529,6 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, } -/* - * checkPartition - * Check whether partRelOid is a leaf partition of the parent table (rel). - * isMerge: true indicates the operation is "ALTER TABLE ... MERGE PARTITIONS"; - * false indicates the operation is "ALTER TABLE ... SPLIT PARTITION". - */ -static void -checkPartition(Relation rel, Oid partRelOid, bool isMerge) -{ - Relation partRel; - - partRel = table_open(partRelOid, NoLock); - - if (partRel->rd_rel->relkind != RELKIND_RELATION) - ereport(ERROR, - errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a table", RelationGetRelationName(partRel)), - isMerge - ? errhint("ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions.") - : errhint("ALTER TABLE ... SPLIT PARTITION can only split partitions that don't have sub-partitions.")); - - if (!partRel->rd_rel->relispartition) - ereport(ERROR, - errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a partition of partitioned table \"%s\"", - RelationGetRelationName(partRel), RelationGetRelationName(rel)), - isMerge - ? errhint("ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions.") - : errhint("ALTER TABLE ... SPLIT PARTITION can only split partitions that don't have sub-partitions.")); - - if (get_partition_parent(partRelOid, false) != RelationGetRelid(rel)) - ereport(ERROR, - errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("relation \"%s\" is not a partition of relation \"%s\"", - RelationGetRelationName(partRel), RelationGetRelationName(rel)), - isMerge - ? errhint("ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions.") - : errhint("ALTER TABLE ... SPLIT PARTITION can only split partitions that don't have sub-partitions.")); - - table_close(partRel, NoLock); -} - -/* - * transformPartitionCmdForSplit - - * analyze the ALTER TABLE ... SPLIT PARTITION command - * - * For each new partition, sps->bound is set to the transformed value of bound. - * Does checks for bounds of new partitions. - */ -static void -transformPartitionCmdForSplit(CreateStmtContext *cxt, PartitionCmd *partcmd) -{ - Relation parent = cxt->rel; - PartitionKey key; - char strategy; - Oid splitPartOid; - Oid defaultPartOid; - int default_index = -1; - bool isSplitPartDefault; - ListCell *listptr, - *listptr2; - List *splitlist; - - splitlist = partcmd->partlist; - key = RelationGetPartitionKey(parent); - strategy = get_partition_strategy(key); - defaultPartOid = get_default_oid_from_partdesc(RelationGetPartitionDesc(parent, true)); - - /* Transform partition bounds for all partitions in the list: */ - foreach_node(SinglePartitionSpec, sps, splitlist) - { - cxt->partbound = NULL; - transformPartitionCmd(cxt, sps->bound); - /* Assign the transformed value of the partition bound. */ - sps->bound = cxt->partbound; - } - - /* - * Open and lock the partition, check ownership along the way. We need to - * use AccessExclusiveLock here because this split partition will be - * detached, then dropped in ATExecSplitPartition. - */ - splitPartOid = RangeVarGetRelidExtended(partcmd->name, AccessExclusiveLock, - 0, RangeVarCallbackOwnsRelation, - NULL); - - checkPartition(parent, splitPartOid, false); - - switch (strategy) - { - case PARTITION_STRATEGY_LIST: - case PARTITION_STRATEGY_RANGE: - { - foreach_node(SinglePartitionSpec, sps, splitlist) - { - if (sps->bound->is_default) - { - if (default_index != -1) - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("cannot specify more than one DEFAULT partition"), - parser_errposition(cxt->pstate, sps->name->location)); - - default_index = foreach_current_index(sps); - } - } - } - break; - - case PARTITION_STRATEGY_HASH: - ereport(ERROR, - errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("partition of hash-partitioned table cannot be split")); - break; - - default: - elog(ERROR, "unexpected partition strategy: %d", - (int) key->strategy); - break; - } - - /* isSplitPartDefault: is the being split partition a DEFAULT partition? */ - isSplitPartDefault = (defaultPartOid == splitPartOid); - - if (isSplitPartDefault && default_index == -1) - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("cannot split DEFAULT partition \"%s\"", - get_rel_name(splitPartOid)), - errhint("To split a DEFAULT partition, one of the new partitions must be DEFAULT.")); - - /* - * If the partition being split is not the DEFAULT partition, but the - * DEFAULT partition exists, then none of the resulting split partitions - * can be the DEFAULT. - */ - if (!isSplitPartDefault && (default_index != -1) && OidIsValid(defaultPartOid)) - { - SinglePartitionSpec *spsDef = - (SinglePartitionSpec *) list_nth(splitlist, default_index); - - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("cannot split non-DEFAULT partition \"%s\"", - get_rel_name(splitPartOid)), - errdetail("New partition cannot be DEFAULT because DEFAULT partition \"%s\" already exists.", - get_rel_name(defaultPartOid)), - parser_errposition(cxt->pstate, spsDef->name->location)); - } - - foreach(listptr, splitlist) - { - Oid nspid; - SinglePartitionSpec *sps = (SinglePartitionSpec *) lfirst(listptr); - RangeVar *name = sps->name; - - nspid = RangeVarGetCreationNamespace(sps->name); - - /* Partitions in the list should have different names. */ - for_each_cell(listptr2, splitlist, lnext(splitlist, listptr)) - { - Oid nspid2; - SinglePartitionSpec *sps2 = (SinglePartitionSpec *) lfirst(listptr2); - RangeVar *name2 = sps2->name; - - if (equal(name, name2)) - ereport(ERROR, - errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("partition with name \"%s\" is already used", name->relname), - parser_errposition(cxt->pstate, name2->location)); - - nspid2 = RangeVarGetCreationNamespace(sps2->name); - - if (nspid2 == nspid && strcmp(name->relname, name2->relname) == 0) - ereport(ERROR, - errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("partition with name \"%s\" is already used", name->relname), - parser_errposition(cxt->pstate, name2->location)); - } - } - - /* Then we should check partitions with transformed bounds. */ - check_partitions_for_split(parent, splitPartOid, splitlist, cxt->pstate); -} - - -/* - * transformPartitionCmdForMerge - - * analyze the ALTER TABLE ... MERGE PARTITIONS command - * - * Does simple checks for merged partitions. Calculates bound of the resulting - * partition. - */ -static void -transformPartitionCmdForMerge(CreateStmtContext *cxt, PartitionCmd *partcmd) -{ - Oid defaultPartOid; - Oid partOid; - Relation parent = cxt->rel; - PartitionKey key; - char strategy; - ListCell *listptr, - *listptr2; - bool isDefaultPart = false; - List *partOids = NIL; - - key = RelationGetPartitionKey(parent); - strategy = get_partition_strategy(key); - - if (strategy == PARTITION_STRATEGY_HASH) - ereport(ERROR, - errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("partition of hash-partitioned table cannot be merged")); - - /* Does the partitioned table (parent) have a default partition? */ - defaultPartOid = get_default_oid_from_partdesc(RelationGetPartitionDesc(parent, true)); - - foreach(listptr, partcmd->partlist) - { - RangeVar *name = (RangeVar *) lfirst(listptr); - - /* Partitions in the list should have different names. */ - for_each_cell(listptr2, partcmd->partlist, lnext(partcmd->partlist, listptr)) - { - RangeVar *name2 = (RangeVar *) lfirst(listptr2); - - if (equal(name, name2)) - ereport(ERROR, - errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("partition with name \"%s\" is already used", name->relname), - parser_errposition(cxt->pstate, name2->location)); - } - - /* - * Search the DEFAULT partition in the list. Open and lock partitions - * before calculating the boundary for resulting partition, we also - * check for ownership along the way. We need to use - * AccessExclusiveLock here, because these merged partitions will be - * detached and then dropped in ATExecMergePartitions. - */ - partOid = RangeVarGetRelidExtended(name, AccessExclusiveLock, 0, - RangeVarCallbackOwnsRelation, - NULL); - /* Is the current partition a DEFAULT partition? */ - if (partOid == defaultPartOid) - isDefaultPart = true; - - /* - * Extended check because the same partition can have different names - * (for example, "part_name" and "public.part_name"). - */ - foreach(listptr2, partOids) - { - Oid curOid = lfirst_oid(listptr2); - - if (curOid == partOid) - ereport(ERROR, - errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("partition with name \"%s\" is already used", name->relname), - parser_errposition(cxt->pstate, name->location)); - } - - checkPartition(parent, partOid, true); - - partOids = lappend_oid(partOids, partOid); - } - - /* Allocate the bound of the resulting partition. */ - Assert(partcmd->bound == NULL); - partcmd->bound = makeNode(PartitionBoundSpec); - - /* Fill the partition bound. */ - partcmd->bound->strategy = strategy; - partcmd->bound->location = -1; - partcmd->bound->is_default = isDefaultPart; - if (!isDefaultPart) - calculate_partition_bound_for_merge(parent, partcmd->partlist, - partOids, partcmd->bound, - cxt->pstate); -} - /* * transformAlterTableStmt - * parse analysis for ALTER TABLE @@ -4082,48 +3798,20 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, { PartitionCmd *partcmd = (PartitionCmd *) cmd->def; - transformPartitionCmd(&cxt, partcmd->bound); - /* assign the transformed value of the partition bound */ + transformPartitionCmd(&cxt, partcmd); + /* assign transformed value of the partition bound */ partcmd->bound = cxt.partbound; } newcmds = lappend(newcmds, cmd); break; - case AT_MergePartitions: - { - PartitionCmd *partcmd = (PartitionCmd *) cmd->def; - - if (list_length(partcmd->partlist) < 2) - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("list of partitions to be merged should include at least two partitions")); - - transformPartitionCmdForMerge(&cxt, partcmd); - newcmds = lappend(newcmds, cmd); - break; - } - - case AT_SplitPartition: - { - PartitionCmd *partcmd = (PartitionCmd *) cmd->def; - - if (list_length(partcmd->partlist) < 2) - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("list of new partitions must contain at least two partitions")); - - transformPartitionCmdForSplit(&cxt, partcmd); - newcmds = lappend(newcmds, cmd); - break; - } - default: /* - * Currently, we shouldn't actually get here for the - * subcommand types that don't require transformation; but if - * we do, just emit them unchanged. + * Currently, we shouldn't actually get here for subcommand + * types that don't require transformation; but if we do, just + * emit them unchanged. */ newcmds = lappend(newcmds, cmd); break; @@ -4791,13 +4479,13 @@ transformCreateSchemaCreateTable(ParseState *pstate, /* * transformPartitionCmd - * Analyze the ATTACH/DETACH/SPLIT PARTITION command + * Analyze the ATTACH/DETACH PARTITION command * - * In case of the ATTACH/SPLIT PARTITION command, cxt->partbound is set to the - * transformed value of bound. + * In case of the ATTACH PARTITION command, cxt->partbound is set to the + * transformed value of cmd->bound. */ static void -transformPartitionCmd(CreateStmtContext *cxt, PartitionBoundSpec *bound) +transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd) { Relation parentRel = cxt->rel; @@ -4806,9 +4494,9 @@ transformPartitionCmd(CreateStmtContext *cxt, PartitionBoundSpec *bound) case RELKIND_PARTITIONED_TABLE: /* transform the partition bound, if any */ Assert(RelationGetPartitionKey(parentRel) != NULL); - if (bound != NULL) + if (cmd->bound != NULL) cxt->partbound = transformPartitionBound(cxt->pstate, parentRel, - bound); + cmd->bound); break; case RELKIND_PARTITIONED_INDEX: @@ -4816,7 +4504,7 @@ transformPartitionCmd(CreateStmtContext *cxt, PartitionBoundSpec *bound) * A partitioned index cannot have a partition bound set. ALTER * INDEX prevents that with its grammar, but not ALTER TABLE. */ - if (bound != NULL) + if (cmd->bound != NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("\"%s\" is not a partitioned table", diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index a7822a4192b..c400ba206c4 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -17,7 +17,6 @@ #include "access/relation.h" #include "access/table.h" #include "access/tableam.h" -#include "catalog/namespace.h" #include "catalog/partition.h" #include "catalog/pg_inherits.h" #include "catalog/pg_type.h" @@ -4982,1056 +4981,3 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) PG_RETURN_BOOL(rowHash % modulus == remainder); } - -/* - * check_two_partitions_bounds_range - * - * (function for BY RANGE partitioning) - * - * This is a helper function for check_partitions_for_split() and - * calculate_partition_bound_for_merge(). This function compares the upper - * bound of first_bound and the lower bound of second_bound. These bounds - * should be equal except when "defaultPart == true" (this means that one of - * the split partitions is DEFAULT). In this case, the upper bound of - * first_bound can be less than the lower bound of second_bound because - * the space between these bounds will be included in the DEFAULT partition. - * - * parent: partitioned table - * first_name: name of the first partition - * first_bound: bound of the first partition - * second_name: name of the second partition - * second_bound: bound of the second partition - * defaultPart: true if one of the new partitions is DEFAULT - * is_merge: true indicates the operation is MERGE PARTITIONS; - * false indicates the operation is SPLIT PARTITION. - * pstate: pointer to ParseState struct for determining error position - */ -static void -check_two_partitions_bounds_range(Relation parent, - RangeVar *first_name, - PartitionBoundSpec *first_bound, - RangeVar *second_name, - PartitionBoundSpec *second_bound, - bool defaultPart, - bool is_merge, - ParseState *pstate) -{ - PartitionKey key = RelationGetPartitionKey(parent); - PartitionRangeBound *first_upper; - PartitionRangeBound *second_lower; - int cmpval; - - Assert(key->strategy == PARTITION_STRATEGY_RANGE); - - first_upper = make_one_partition_rbound(key, -1, first_bound->upperdatums, false); - second_lower = make_one_partition_rbound(key, -1, second_bound->lowerdatums, true); - - /* - * lower1 argument of partition_rbound_cmp() is set to false for the - * correct comparison result of the lower and upper bounds. - */ - cmpval = partition_rbound_cmp(key->partnatts, - key->partsupfunc, - key->partcollation, - second_lower->datums, second_lower->kind, - false, first_upper); - if ((!defaultPart && cmpval) || (defaultPart && cmpval < 0)) - { - PartitionRangeDatum *datum = linitial(second_bound->lowerdatums); - - if (is_merge) - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("cannot merge partition \"%s\" together with partition \"%s\"", - second_name->relname, first_name->relname), - errdetail("The lower bound of partition \"%s\" is not equal to the upper bound of partition \"%s\".", - second_name->relname, first_name->relname), - errhint("ALTER TABLE ... MERGE PARTITIONS requires the partition bounds to be adjacent."), - parser_errposition(pstate, datum->location)); - else - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("cannot split to partition \"%s\" together with partition \"%s\"", - second_name->relname, first_name->relname), - errdetail("The lower bound of partition \"%s\" is not equal to the upper bound of partition \"%s\".", - second_name->relname, first_name->relname), - errhint("ALTER TABLE ... SPLIT PARTITION requires the partition bounds to be adjacent."), - parser_errposition(pstate, datum->location)); - } -} - -/* - * get_partition_bound_spec - * - * Returns the PartitionBoundSpec for the partition with the given OID partOid. - */ -static PartitionBoundSpec * -get_partition_bound_spec(Oid partOid) -{ - HeapTuple tuple; - Datum datum; - bool isnull; - PartitionBoundSpec *boundspec = NULL; - - /* Try fetching the tuple from the catcache, for speed. */ - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(partOid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", partOid); - - datum = SysCacheGetAttr(RELOID, tuple, - Anum_pg_class_relpartbound, - &isnull); - if (isnull) - elog(ERROR, "partition bound for relation %u is null", - partOid); - - boundspec = stringToNode(TextDatumGetCString(datum)); - - if (!IsA(boundspec, PartitionBoundSpec)) - elog(ERROR, "expected PartitionBoundSpec for relation %u", - partOid); - - ReleaseSysCache(tuple); - return boundspec; -} - -/* - * calculate_partition_bound_for_merge - * - * Calculates the bound of the merged partition "spec" by using the bounds of - * the partitions to be merged. - * - * parent: partitioned table - * partNames: names of partitions to be merged - * partOids: Oids of partitions to be merged - * spec (out): bounds specification of the merged partition - * pstate: pointer to ParseState struct to determine error position - */ -void -calculate_partition_bound_for_merge(Relation parent, - List *partNames, - List *partOids, - PartitionBoundSpec *spec, - ParseState *pstate) -{ - PartitionKey key = RelationGetPartitionKey(parent); - PartitionBoundSpec *bound; - - Assert(!spec->is_default); - - switch (key->strategy) - { - case PARTITION_STRATEGY_RANGE: - { - int i; - PartitionRangeBound **lower_bounds; - int nparts = list_length(partOids); - List *bounds = NIL; - - lower_bounds = palloc0_array(PartitionRangeBound *, nparts); - - /* - * Create an array of lower bounds and a list of - * PartitionBoundSpec. - */ - foreach_oid(partoid, partOids) - { - bound = get_partition_bound_spec(partoid); - i = foreach_current_index(partoid); - - lower_bounds[i] = make_one_partition_rbound(key, i, bound->lowerdatums, true); - bounds = lappend(bounds, bound); - } - - /* Sort the array of lower bounds. */ - qsort_arg(lower_bounds, nparts, sizeof(PartitionRangeBound *), - qsort_partition_rbound_cmp, key); - - /* Ranges of partitions should be adjacent. */ - for (i = 1; i < nparts; i++) - { - int index = lower_bounds[i]->index; - int prev_index = lower_bounds[i - 1]->index; - - check_two_partitions_bounds_range(parent, - (RangeVar *) list_nth(partNames, prev_index), - (PartitionBoundSpec *) list_nth(bounds, prev_index), - (RangeVar *) list_nth(partNames, index), - (PartitionBoundSpec *) list_nth(bounds, index), - false, - true, - pstate); - } - - /* - * The lower bound of the first partition is the lower bound - * of the merged partition. - */ - spec->lowerdatums = - ((PartitionBoundSpec *) list_nth(bounds, lower_bounds[0]->index))->lowerdatums; - - /* - * The upper bound of the last partition is the upper bound of - * the merged partition. - */ - spec->upperdatums = - ((PartitionBoundSpec *) list_nth(bounds, lower_bounds[nparts - 1]->index))->upperdatums; - - pfree(lower_bounds); - list_free(bounds); - break; - } - - case PARTITION_STRATEGY_LIST: - { - /* Consolidate bounds for all partitions in the list. */ - foreach_oid(partoid, partOids) - { - bound = get_partition_bound_spec(partoid); - spec->listdatums = list_concat(spec->listdatums, bound->listdatums); - } - break; - } - - default: - elog(ERROR, "unexpected partition strategy: %d", - (int) key->strategy); - } -} - -/* - * partitions_listdatum_intersection - * - * (function for BY LIST partitioning) - * - * Function compares lists of values for different partitions. - * Return a list that contains *one* cell that is present in both list1 and - * list2. The returned list is freshly allocated via palloc(), but the - * cells themselves point to the same objects as the cells of the - * input lists. - * - * Currently, there is no need to collect all common partition datums from the - * two lists. - */ -static List * -partitions_listdatum_intersection(FmgrInfo *partsupfunc, Oid *partcollation, - const List *list1, const List *list2) -{ - List *result = NIL; - - if (list1 == NIL || list2 == NIL) - return result; - - foreach_node(Const, val1, list1) - { - bool isnull1 = val1->constisnull; - - foreach_node(Const, val2, list2) - { - if (val2->constisnull) - { - if (isnull1) - { - result = lappend(result, val1); - return result; - } - continue; - } - else if (isnull1) - continue; - - /* Compare two datum values. */ - if (DatumGetInt32(FunctionCall2Coll(&partsupfunc[0], - partcollation[0], - val1->constvalue, - val2->constvalue)) == 0) - { - result = lappend(result, val1); - return result; - } - } - } - - return result; -} - -/* - * check_partitions_not_overlap_list - * - * (function for BY LIST partitioning) - * - * This is a helper function for check_partitions_for_split(). - * Checks that the values of the new partitions do not overlap. - * - * parent: partitioned table - * parts: array of SinglePartitionSpec structs with info about split partitions - * nparts: size of array "parts" - */ -static void -check_partitions_not_overlap_list(Relation parent, - SinglePartitionSpec **parts, - int nparts, - ParseState *pstate) -{ - PartitionKey key PG_USED_FOR_ASSERTS_ONLY = RelationGetPartitionKey(parent); - int i, - j; - SinglePartitionSpec *sps1, - *sps2; - List *overlap; - - Assert(key->strategy == PARTITION_STRATEGY_LIST); - - for (i = 0; i < nparts; i++) - { - sps1 = parts[i]; - - for (j = i + 1; j < nparts; j++) - { - sps2 = parts[j]; - - overlap = partitions_listdatum_intersection(&key->partsupfunc[0], - key->partcollation, - sps1->bound->listdatums, - sps2->bound->listdatums); - if (list_length(overlap) > 0) - { - Const *val = (Const *) linitial_node(Const, overlap); - - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("new partition \"%s\" would overlap with another new partition \"%s\"", - sps1->name->relname, sps2->name->relname), - parser_errposition(pstate, exprLocation((Node *) val))); - } - } - } -} - -/* - * check_partition_bounds_for_split_range - * - * (function for BY RANGE partitioning) - * - * Checks that bounds of new partition "spec" are inside bounds of split - * partition (with Oid splitPartOid). If first=true (this means that "spec" is - * the first of the new partitions), then the lower bound of "spec" should be - * equal (or greater than or equal in case defaultPart=true) to the lower - * bound of the split partition. If last=true (this means that "spec" is the - * last of the new partitions), then the upper bound of "spec" should be - * equal (or less than or equal in case defaultPart=true) to the upper bound - * of the split partition. - * - * parent: partitioned table - * relname: name of the new partition - * spec: bounds specification of the new partition - * splitPartOid: split partition Oid - * first: true iff the new partition "spec" is the first of the - * new partitions - * last: true iff the new partition "spec" is the last of the - * new partitions - * defaultPart: true iff new partitions contain the DEFAULT partition - * pstate: pointer to ParseState struct to determine error position - */ -static void -check_partition_bounds_for_split_range(Relation parent, - char *relname, - PartitionBoundSpec *spec, - Oid splitPartOid, - bool first, - bool last, - bool defaultPart, - ParseState *pstate) -{ - PartitionKey key = RelationGetPartitionKey(parent); - PartitionRangeBound *lower, - *upper; - int cmpval; - - Assert(key->strategy == PARTITION_STRATEGY_RANGE); - Assert(spec->strategy == PARTITION_STRATEGY_RANGE); - - lower = make_one_partition_rbound(key, -1, spec->lowerdatums, true); - upper = make_one_partition_rbound(key, -1, spec->upperdatums, false); - - /* - * First, check if the resulting range would be empty with the specified - * lower and upper bounds. partition_rbound_cmp cannot return zero here, - * since the lower-bound flags are different. - */ - cmpval = partition_rbound_cmp(key->partnatts, - key->partsupfunc, - key->partcollation, - lower->datums, lower->kind, - true, upper); - Assert(cmpval != 0); - if (cmpval > 0) - { - /* Point to the problematic key in the lower datums list. */ - PartitionRangeDatum *datum = list_nth(spec->lowerdatums, cmpval - 1); - - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("empty range bound specified for partition \"%s\"", - relname), - errdetail("Specified lower bound %s is greater than or equal to upper bound %s.", - get_range_partbound_string(spec->lowerdatums), - get_range_partbound_string(spec->upperdatums)), - parser_errposition(pstate, exprLocation((Node *) datum))); - } - - /* - * Need to check first and last partitions (from the set of new - * partitions) - */ - if (first || last) - { - PartitionBoundSpec *split_spec = get_partition_bound_spec(splitPartOid); - PartitionRangeDatum *datum; - - if (first) - { - PartitionRangeBound *split_lower; - - split_lower = make_one_partition_rbound(key, -1, split_spec->lowerdatums, true); - - cmpval = partition_rbound_cmp(key->partnatts, - key->partsupfunc, - key->partcollation, - lower->datums, lower->kind, - true, split_lower); - if (cmpval != 0) - datum = list_nth(spec->lowerdatums, abs(cmpval) - 1); - - /* - * The lower bound of "spec" must equal the lower bound of the - * split partition. However, if one of the new partitions is - * DEFAULT, then it is ok for the new partition's lower bound to - * be greater than that of the split partition. - */ - if (!defaultPart) - { - if (cmpval != 0) - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("lower bound of partition \"%s\" is not equal to lower bound of split partition \"%s\"", - relname, - get_rel_name(splitPartOid)), - errhint("%s requires the combined bounds of the new partitions to exactly match the bound of the split partition.", - "ALTER TABLE ... SPLIT PARTITION"), - parser_errposition(pstate, exprLocation((Node *) datum))); - } - else if (cmpval < 0) - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("lower bound of partition \"%s\" is less than lower bound of split partition \"%s\"", - relname, - get_rel_name(splitPartOid)), - errhint("Explicit partition bounds must be contained within the bounds of the split partition when a DEFAULT partition is specified."), - parser_errposition(pstate, exprLocation((Node *) datum))); - } - - if (last) - { - PartitionRangeBound *split_upper; - - split_upper = make_one_partition_rbound(key, -1, split_spec->upperdatums, false); - - cmpval = partition_rbound_cmp(key->partnatts, - key->partsupfunc, - key->partcollation, - upper->datums, upper->kind, - false, split_upper); - if (cmpval != 0) - datum = list_nth(spec->upperdatums, abs(cmpval) - 1); - - /* - * The upper bound of "spec" must equal the upper bound of the - * split partition. However, if one of the new partitions is - * DEFAULT, then it is ok for the new partition's upper bound to - * be less than that of the split partition. - */ - if (!defaultPart) - { - if (cmpval != 0) - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("upper bound of partition \"%s\" is not equal to upper bound of split partition \"%s\"", - relname, - get_rel_name(splitPartOid)), - errhint("%s requires the combined bounds of the new partitions to exactly match the bound of the split partition.", - "ALTER TABLE ... SPLIT PARTITION"), - parser_errposition(pstate, exprLocation((Node *) datum))); - } - else if (cmpval > 0) - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("upper bound of partition \"%s\" is greater than upper bound of split partition \"%s\"", - relname, - get_rel_name(splitPartOid)), - errhint("Explicit partition bounds must be contained within the bounds of the split partition when a DEFAULT partition is specified."), - parser_errposition(pstate, exprLocation((Node *) datum))); - } - } -} - -/* - * check_partition_bounds_for_split_list - * - * (function for BY LIST partitioning) - * - * Checks that the bounds of the new partition are inside the bounds of the - * split partition (with Oid splitPartOid). - * - * parent: partitioned table - * relname: name of the new partition - * spec: bounds specification of the new partition - * splitPartOid: split partition Oid - * pstate: pointer to ParseState struct to determine error position - */ -static void -check_partition_bounds_for_split_list(Relation parent, char *relname, - PartitionBoundSpec *spec, - Oid splitPartOid, - ParseState *pstate) -{ - PartitionKey key = RelationGetPartitionKey(parent); - PartitionDesc partdesc = RelationGetPartitionDesc(parent, false); - PartitionBoundInfo boundinfo = partdesc->boundinfo; - int with = -1; - bool overlap = false; - int overlap_location = -1; - - Assert(key->strategy == PARTITION_STRATEGY_LIST); - Assert(spec->strategy == PARTITION_STRATEGY_LIST); - Assert(boundinfo && boundinfo->strategy == PARTITION_STRATEGY_LIST); - - /* - * Search each value of the new partition "spec" in the existing - * partitions. All of them should be in the split partition (with Oid - * splitPartOid). - */ - foreach_node(Const, val, spec->listdatums) - { - overlap_location = exprLocation((Node *) val); - if (!val->constisnull) - { - int offset; - bool equal; - - offset = partition_list_bsearch(&key->partsupfunc[0], - key->partcollation, - boundinfo, - val->constvalue, - &equal); - if (offset >= 0 && equal) - { - with = boundinfo->indexes[offset]; - if (partdesc->oids[with] != splitPartOid) - { - overlap = true; - break; - } - } - else - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("new partition \"%s\" cannot have this value because split partition \"%s\" does not have it", - relname, - get_rel_name(splitPartOid)), - parser_errposition(pstate, overlap_location)); - } - else if (partition_bound_accepts_nulls(boundinfo)) - { - with = boundinfo->null_index; - if (partdesc->oids[with] != splitPartOid) - { - overlap = true; - break; - } - } - else - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("new partition \"%s\" cannot have NULL value because split partition \"%s\" does not have it", - relname, - get_rel_name(splitPartOid)), - parser_errposition(pstate, overlap_location)); - } - - if (overlap) - { - Assert(with >= 0); - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("new partition \"%s\" would overlap with another (not split) partition \"%s\"", - relname, get_rel_name(partdesc->oids[with])), - parser_errposition(pstate, overlap_location)); - } -} - -/* - * find_value_in_new_partitions_list - * - * (function for BY LIST partitioning) - * - * Function returns true iff any of the new partitions contains the value - * "value". - * - * partsupfunc: information about the comparison function associated with - * the partition key - * partcollation: partitioning collation - * parts: pointer to an array with new partition descriptions - * nparts: number of new partitions - * value: the value that we are looking for - * isnull: true if the value that we are looking for is NULL - */ -static bool -find_value_in_new_partitions_list(FmgrInfo *partsupfunc, - Oid *partcollation, - SinglePartitionSpec **parts, - int nparts, - Datum value, - bool isnull) -{ - for (int i = 0; i < nparts; i++) - { - SinglePartitionSpec *sps = parts[i]; - - foreach_node(Const, val, sps->bound->listdatums) - { - if (isnull && val->constisnull) - return true; - - if (!isnull && !val->constisnull) - { - if (DatumGetInt32(FunctionCall2Coll(&partsupfunc[0], - partcollation[0], - val->constvalue, - value)) == 0) - return true; - } - } - } - return false; -} - -/* - * check_parent_values_in_new_partitions - * - * (function for BY LIST partitioning) - * - * Checks that all values of split partition (with Oid partOid) are contained - * in new partitions. - * - * parent: partitioned table - * partOid: split partition Oid - * parts: pointer to an array with new partition descriptions - * nparts: number of new partitions - * pstate: pointer to ParseState struct to determine error position - */ -static void -check_parent_values_in_new_partitions(Relation parent, - Oid partOid, - SinglePartitionSpec **parts, - int nparts, - ParseState *pstate) -{ - PartitionKey key = RelationGetPartitionKey(parent); - PartitionDesc partdesc = RelationGetPartitionDesc(parent, false); - PartitionBoundInfo boundinfo = partdesc->boundinfo; - int i; - bool found = true; - Datum datum = PointerGetDatum(NULL); - - Assert(key->strategy == PARTITION_STRATEGY_LIST); - - /* - * Special processing for NULL value. Search for a NULL value if the split - * partition (partOid) contains it. - */ - if (partition_bound_accepts_nulls(boundinfo) && - partdesc->oids[boundinfo->null_index] == partOid) - { - if (!find_value_in_new_partitions_list(&key->partsupfunc[0], - key->partcollation, parts, nparts, datum, true)) - found = false; - } - - if (!found) - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("new partitions' combined partition bounds do not contain value (%s) but split partition \"%s\" does", - "NULL", - get_rel_name(partOid)), - errhint("%s requires the combined bounds of the new partitions to exactly match the bound of the split partition.", - "ALTER TABLE ... SPLIT PARTITION")); - - /* - * Search all values of split partition with partOid in the PartitionDesc - * of partitioned table. - */ - for (i = 0; i < boundinfo->ndatums; i++) - { - if (partdesc->oids[boundinfo->indexes[i]] == partOid) - { - /* We found the value that the split partition contains. */ - datum = boundinfo->datums[i][0]; - if (!find_value_in_new_partitions_list(&key->partsupfunc[0], - key->partcollation, parts, nparts, datum, false)) - { - found = false; - break; - } - } - } - - if (!found) - { - Const *notFoundVal; - - /* - * Make a Const for getting the string representation of the missing - * value. - */ - notFoundVal = makeConst(key->parttypid[0], - key->parttypmod[0], - key->parttypcoll[0], - key->parttyplen[0], - datum, - false, /* isnull */ - key->parttypbyval[0]); - - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("new partitions' combined partition bounds do not contain value (%s) but split partition \"%s\" does", - deparse_expression((Node *) notFoundVal, NIL, false, false), - get_rel_name(partOid)), - errhint("%s requires the combined bounds of the new partitions to exactly match the bound of the split partition.", - "ALTER TABLE ... SPLIT PARTITION")); - } -} - -/* - * split_partition_values_contained_in_new_part - * - * (function for BY LIST partitioning) - * - * Returns true if all values in the LIST bound of the partition being split - * are contained in the specified non-DEFAULT replacement partition's bound. - * - * The caller must already have verified containment in the other direction, - * so this check is sufficient to prove that the two LIST bounds are equal. - */ -static bool -split_partition_values_contained_in_new_part(Relation parent, - Oid splitPartOid, - SinglePartitionSpec *part) -{ - PartitionKey key = RelationGetPartitionKey(parent); - PartitionDesc partdesc = RelationGetPartitionDesc(parent, false); - PartitionBoundInfo boundinfo = partdesc->boundinfo; - SinglePartitionSpec *parts[1]; - Datum datum = PointerGetDatum(NULL); - - Assert(key->strategy == PARTITION_STRATEGY_LIST); - - parts[0] = part; - - /* - * Special processing for NULL value. Search for a NULL value if the - * split partition contains it. - */ - if (partition_bound_accepts_nulls(boundinfo) && - partdesc->oids[boundinfo->null_index] == splitPartOid) - { - if (!find_value_in_new_partitions_list(&key->partsupfunc[0], - key->partcollation, parts, 1, - datum, true)) - return false; - } - - /* - * Search all values of the split partition in the single non-DEFAULT - * replacement partition. - */ - for (int i = 0; i < boundinfo->ndatums; i++) - { - if (partdesc->oids[boundinfo->indexes[i]] == splitPartOid) - { - datum = boundinfo->datums[i][0]; - - if (!find_value_in_new_partitions_list(&key->partsupfunc[0], - key->partcollation, parts, 1, - datum, false)) - return false; - } - } - - return true; -} - -/* - * check_split_partition_not_same_bound - * - * Reject splitting a non-DEFAULT partition into one non-DEFAULT partition - * with the original bound plus a DEFAULT partition. That form does not - * perform a real split; it merely adds a DEFAULT partition to the parent - * table through the split-partition path. Users should use - * CREATE TABLE ... PARTITION OF ... DEFAULT or ALTER TABLE ... ATTACH - * PARTITION ... DEFAULT for that. - * - * Must be called after the per-partition bound validation in - * check_partitions_for_split() so that containment of new bounds within the - * split partition is already established. Given containment, RANGE bounds - * are equal iff their lower and upper rbounds match; LIST bound sets are - * equal iff the split partition's values are also contained in the new - * partition (the containment is then bidirectional). Both checks go - * through the partition operator family (partition_rbound_cmp / - * find_value_in_new_partitions_list) rather than byte equality, so e.g. - * -0.0 and 0.0 -- which have different bit patterns but compare equal - * under float8 -- are correctly recognised as the same bound. - */ -static void -check_split_partition_not_same_bound(Relation parent, - Oid splitPartOid, - SinglePartitionSpec **parts, - int nparts, - ParseState *pstate) -{ - PartitionKey key = RelationGetPartitionKey(parent); - PartitionBoundSpec *new_spec; - PartitionBoundSpec *split_spec; - - if (nparts != 1) - return; - - new_spec = parts[0]->bound; - split_spec = get_partition_bound_spec(splitPartOid); - - Assert(new_spec->strategy == split_spec->strategy); - - if (key->strategy == PARTITION_STRATEGY_RANGE) - { - PartitionRangeBound *new_lower; - PartitionRangeBound *new_upper; - PartitionRangeBound *split_lower; - PartitionRangeBound *split_upper; - - new_lower = make_one_partition_rbound(key, -1, new_spec->lowerdatums, true); - new_upper = make_one_partition_rbound(key, -1, new_spec->upperdatums, false); - split_lower = make_one_partition_rbound(key, -1, split_spec->lowerdatums, true); - split_upper = make_one_partition_rbound(key, -1, split_spec->upperdatums, false); - - if (partition_rbound_cmp(key->partnatts, key->partsupfunc, - key->partcollation, - new_lower->datums, new_lower->kind, true, - split_lower) != 0) - return; - if (partition_rbound_cmp(key->partnatts, key->partsupfunc, - key->partcollation, - new_upper->datums, new_upper->kind, false, - split_upper) != 0) - return; - } - else - { - Assert(key->strategy == PARTITION_STRATEGY_LIST); - - if (!split_partition_values_contained_in_new_part(parent, splitPartOid, - parts[0])) - return; - } - - ereport(ERROR, - errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("cannot split partition \"%s\" only to add a DEFAULT partition", - get_rel_name(splitPartOid)), - errdetail("The non-DEFAULT partition would keep the same partition bound."), - errhint("Use CREATE TABLE ... PARTITION OF ... DEFAULT to add a DEFAULT partition."), - parser_errposition(pstate, parts[0]->name->location)); -} - -/* - * check_partitions_for_split - * - * Checks new partitions for the SPLIT PARTITION command: - * 1. Bounds of new partitions should not overlap with new and existing - * partitions. - * 2. In the case when new or existing partitions contain the DEFAULT - * partition, new partitions can have any bounds inside the split partition - * bound (can be spaces between partition bounds). - * 3. In case new partitions don't contain the DEFAULT partition and the - * partitioned table does not have the DEFAULT partition, the following - * should be true: the sum of the bounds of new partitions should be equal - * to the bound of the split partition. - * - * parent: partitioned table - * splitPartOid: split partition Oid - * partlist: list of new partitions after partition split - * pstate: pointer to ParseState struct for determine error position - */ -void -check_partitions_for_split(Relation parent, - Oid splitPartOid, - List *partlist, - ParseState *pstate) -{ - PartitionKey key; - char strategy; - Oid defaultPartOid; - bool isSplitPartDefault; - bool createDefaultPart = false; - int default_index = -1; - int i; - SinglePartitionSpec **new_parts; - SinglePartitionSpec *spsPrev = NULL; - - /* - * nparts counts the number of split partitions, but it exclude the - * default partition. - */ - int nparts = 0; - - key = RelationGetPartitionKey(parent); - strategy = get_partition_strategy(key); - - defaultPartOid = - get_default_oid_from_partdesc(RelationGetPartitionDesc(parent, true)); - - Assert(strategy == PARTITION_STRATEGY_RANGE || - strategy == PARTITION_STRATEGY_LIST); - - /* - * Make an array new_parts with new partitions except the DEFAULT - * partition. - */ - new_parts = palloc0_array(SinglePartitionSpec *, list_length(partlist)); - - /* isSplitPartDefault flag: is split partition a DEFAULT partition? */ - isSplitPartDefault = (defaultPartOid == splitPartOid); - - foreach_node(SinglePartitionSpec, sps, partlist) - { - if (sps->bound->is_default) - default_index = foreach_current_index(sps); - else - new_parts[nparts++] = sps; - } - - /* An indicator that the DEFAULT partition will be created. */ - if (default_index != -1) - { - createDefaultPart = true; - Assert(nparts == list_length(partlist) - 1); - } - - if (strategy == PARTITION_STRATEGY_RANGE) - { - PartitionRangeBound **lower_bounds; - SinglePartitionSpec **tmp_new_parts; - - /* - * To simplify the check for ranges of new partitions, we need to sort - * all partitions in ascending order of their bounds (we compare the - * lower bound only). - */ - lower_bounds = palloc0_array(PartitionRangeBound *, nparts); - - /* Create an array of lower bounds. */ - for (i = 0; i < nparts; i++) - { - lower_bounds[i] = make_one_partition_rbound(key, i, - new_parts[i]->bound->lowerdatums, true); - } - - /* Sort the array of lower bounds. */ - qsort_arg(lower_bounds, nparts, sizeof(PartitionRangeBound *), - qsort_partition_rbound_cmp, (void *) key); - - /* Reorder the array of partitions. */ - tmp_new_parts = new_parts; - new_parts = palloc0_array(SinglePartitionSpec *, nparts); - for (i = 0; i < nparts; i++) - new_parts[i] = tmp_new_parts[lower_bounds[i]->index]; - - pfree(tmp_new_parts); - pfree(lower_bounds); - } - - for (i = 0; i < nparts; i++) - { - SinglePartitionSpec *sps = new_parts[i]; - - if (isSplitPartDefault) - { - /* - * When the split partition is the DEFAULT partition, we can use - * any free ranges - as when creating a new partition. - */ - check_new_partition_bound(sps->name->relname, parent, sps->bound, - pstate); - } - else - { - /* - * Checks that the bounds of the current partition are inside the - * bounds of the split partition. For range partitioning: checks - * that the upper bound of the previous partition is equal to the - * lower bound of the current partition. For list partitioning: - * checks that the split partition contains all values of the - * current partition. - */ - if (strategy == PARTITION_STRATEGY_RANGE) - { - bool first = (i == 0); - bool last = (i == (nparts - 1)); - - check_partition_bounds_for_split_range(parent, sps->name->relname, sps->bound, - splitPartOid, first, last, - createDefaultPart, pstate); - } - else - check_partition_bounds_for_split_list(parent, sps->name->relname, - sps->bound, splitPartOid, pstate); - } - - /* Ranges of new partitions should not overlap. */ - if (strategy == PARTITION_STRATEGY_RANGE && spsPrev) - check_two_partitions_bounds_range(parent, spsPrev->name, spsPrev->bound, - sps->name, sps->bound, - createDefaultPart, - false, - pstate); - - spsPrev = sps; - } - - if (strategy == PARTITION_STRATEGY_LIST) - { - /* Values of new partitions should not overlap. */ - check_partitions_not_overlap_list(parent, new_parts, nparts, - pstate); - - /* - * Need to check that all values of the split partition are contained - * in the new partitions. Skip this check if the DEFAULT partition - * exists. - */ - if (!createDefaultPart) - check_parent_values_in_new_partitions(parent, splitPartOid, - new_parts, nparts, pstate); - } - - /* - * Reject the degenerate form where the single non-DEFAULT replacement - * partition keeps the bound of the split partition; the command then does - * nothing beyond adding a DEFAULT partition. Containment was established - * by the per-partition validation above, so an equality check is enough. - */ - if (!isSplitPartDefault && createDefaultPart) - check_split_partition_not_same_bound(parent, splitPartOid, new_parts, - nparts, pstate); - - pfree(new_parts); -} diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index 807d1d3b527..5b914d603bb 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -2835,7 +2835,6 @@ match_previous_words(int pattern_id, "OWNER TO", "SET", "VALIDATE CONSTRAINT", "REPLICA IDENTITY", "ATTACH PARTITION", "DETACH PARTITION", "FORCE ROW LEVEL SECURITY", - "SPLIT PARTITION", "MERGE PARTITIONS (", "OF", "NOT OF"); /* ALTER TABLE xxx ADD */ else if (Matches("ALTER", "TABLE", MatchAny, "ADD")) @@ -3098,10 +3097,10 @@ match_previous_words(int pattern_id, COMPLETE_WITH("FROM (", "IN (", "WITH ("); /* - * If we have ALTER TABLE DETACH|SPLIT PARTITION, provide a list of + * If we have ALTER TABLE DETACH PARTITION, provide a list of * partitions of . */ - else if (Matches("ALTER", "TABLE", MatchAny, "DETACH|SPLIT", "PARTITION")) + else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION")) { set_completion_reference(prev3_wd); COMPLETE_WITH_SCHEMA_QUERY(Query_for_partition_of_table); @@ -3109,19 +3108,6 @@ match_previous_words(int pattern_id, else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION", MatchAny)) COMPLETE_WITH("CONCURRENTLY", "FINALIZE"); - /* ALTER TABLE SPLIT PARTITION */ - else if (Matches("ALTER", "TABLE", MatchAny, "SPLIT", "PARTITION", MatchAny)) - COMPLETE_WITH("INTO ( PARTITION"); - - /* ALTER TABLE MERGE PARTITIONS ( */ - else if (Matches("ALTER", "TABLE", MatchAny, "MERGE", "PARTITIONS", "(")) - { - set_completion_reference(prev4_wd); - COMPLETE_WITH_SCHEMA_QUERY(Query_for_partition_of_table); - } - else if (Matches("ALTER", "TABLE", MatchAny, "MERGE", "PARTITIONS", "(*)")) - COMPLETE_WITH("INTO"); - /* ALTER TABLE OF */ else if (Matches("ALTER", "TABLE", MatchAny, "OF")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_composite_datatypes); diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index 214ef1e7e2d..7da6a3942e1 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -107,8 +107,6 @@ extern void ReleaseDeletionLock(const ObjectAddress *object); extern void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags); -extern void performDeletionCheck(const ObjectAddress *object, - DropBehavior behavior, int flags); extern void performMultipleDeletions(const ObjectAddresses *objects, DropBehavior behavior, int flags); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 2fcea826003..f48a0c62d49 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -984,39 +984,13 @@ typedef struct PartitionRangeDatum } PartitionRangeDatum; /* - * PartitionDesc - info about a single partition for the ALTER TABLE SPLIT - * PARTITION command - */ -typedef struct SinglePartitionSpec -{ - NodeTag type; - - RangeVar *name; /* name of partition */ - PartitionBoundSpec *bound; /* FOR VALUES, if attaching */ -} SinglePartitionSpec; - -/* - * PartitionCmd - info for ALTER TABLE/INDEX ATTACH/DETACH PARTITION and for - * ALTER TABLE SPLIT/MERGE PARTITION(S) commands + * PartitionCmd - info for ALTER TABLE/INDEX ATTACH/DETACH PARTITION commands */ typedef struct PartitionCmd { NodeTag type; - - /* name of partition to attach/detach/merge/split */ - RangeVar *name; - - /* FOR VALUES, if attaching */ - PartitionBoundSpec *bound; - - /* - * list of partitions to be split/merged, used in ALTER TABLE MERGE - * PARTITIONS and ALTER TABLE SPLIT PARTITIONS. For merge partitions, - * partlist is a list of RangeVar; For split partition, it is a list of - * SinglePartitionSpec. - */ - List *partlist; - + RangeVar *name; /* name of partition to attach/detach */ + PartitionBoundSpec *bound; /* FOR VALUES, if attaching */ bool concurrent; } PartitionCmd; @@ -2578,8 +2552,6 @@ typedef enum AlterTableType AT_AttachPartition, /* ATTACH PARTITION */ AT_DetachPartition, /* DETACH PARTITION */ AT_DetachPartitionFinalize, /* DETACH PARTITION FINALIZE */ - AT_SplitPartition, /* SPLIT PARTITION */ - AT_MergePartitions, /* MERGE PARTITIONS */ AT_AddIdentity, /* ADD IDENTITY */ AT_SetIdentity, /* SET identity column options */ AT_DropIdentity, /* DROP IDENTITY */ diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 51ead54f015..a12d550ef60 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -344,7 +344,6 @@ PG_KEYWORD("parameter", PARAMETER, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("parser", PARSER, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("partitions", PARTITIONS, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("path", PATH, UNRESERVED_KEYWORD, BARE_LABEL) @@ -434,7 +433,6 @@ PG_KEYWORD("smallint", SMALLINT, COL_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("snapshot", SNAPSHOT, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("some", SOME, RESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("source", SOURCE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("split", SPLIT, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("sql", SQL_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("stable", STABLE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("standalone", STANDALONE_P, UNRESERVED_KEYWORD, BARE_LABEL) diff --git a/src/include/partitioning/partbounds.h b/src/include/partitioning/partbounds.h index 25c926f4c8b..d66918f89c1 100644 --- a/src/include/partitioning/partbounds.h +++ b/src/include/partitioning/partbounds.h @@ -143,14 +143,4 @@ extern int partition_range_datum_bsearch(FmgrInfo *partsupfunc, extern int partition_hash_bsearch(PartitionBoundInfo boundinfo, int modulus, int remainder); -extern void check_partitions_for_split(Relation parent, - Oid splitPartOid, - List *partlist, - ParseState *pstate); -extern void calculate_partition_bound_for_merge(Relation parent, - List *partNames, - List *partOids, - PartitionBoundSpec *spec, - ParseState *pstate); - #endif /* PARTBOUNDS_H */ diff --git a/src/test/isolation/expected/partition-merge.out b/src/test/isolation/expected/partition-merge.out deleted file mode 100644 index 5f6472671b9..00000000000 --- a/src/test/isolation/expected/partition-merge.out +++ /dev/null @@ -1,243 +0,0 @@ -Parsed test spec with 2 sessions - -starting permutation: s2b s2i s2c s1b s1merg s2b s2u s1c s2c s2s -step s2b: BEGIN; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s2c: COMMIT; -step s1b: BEGIN; -step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; -step s2b: BEGIN; -step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; -step s1c: COMMIT; -step s2u: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+----------- -tpart_00_20 | 1|text01modif -tpart_00_20 | 5|text05 -tpart_00_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s2b s2i s2c s1brr s1merg s2b s2u s1c s2c s2s -step s2b: BEGIN; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s2c: COMMIT; -step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; -step s2b: BEGIN; -step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; -step s1c: COMMIT; -step s2u: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+----------- -tpart_00_20 | 1|text01modif -tpart_00_20 | 5|text05 -tpart_00_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s2b s2i s2c s1bs s1merg s2b s2u s1c s2c s2s -step s2b: BEGIN; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s2c: COMMIT; -step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; -step s2b: BEGIN; -step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; -step s1c: COMMIT; -step s2u: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+----------- -tpart_00_20 | 1|text01modif -tpart_00_20 | 5|text05 -tpart_00_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s2brr s2i s2c s1b s1merg s2b s2u s1c s2c s2s -step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s2c: COMMIT; -step s1b: BEGIN; -step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; -step s2b: BEGIN; -step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; -step s1c: COMMIT; -step s2u: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+----------- -tpart_00_20 | 1|text01modif -tpart_00_20 | 5|text05 -tpart_00_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s2brr s2i s2c s1brr s1merg s2b s2u s1c s2c s2s -step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s2c: COMMIT; -step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; -step s2b: BEGIN; -step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; -step s1c: COMMIT; -step s2u: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+----------- -tpart_00_20 | 1|text01modif -tpart_00_20 | 5|text05 -tpart_00_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s2brr s2i s2c s1bs s1merg s2b s2u s1c s2c s2s -step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s2c: COMMIT; -step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; -step s2b: BEGIN; -step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; -step s1c: COMMIT; -step s2u: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+----------- -tpart_00_20 | 1|text01modif -tpart_00_20 | 5|text05 -tpart_00_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s2bs s2i s2c s1b s1merg s2b s2u s1c s2c s2s -step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s2c: COMMIT; -step s1b: BEGIN; -step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; -step s2b: BEGIN; -step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; -step s1c: COMMIT; -step s2u: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+----------- -tpart_00_20 | 1|text01modif -tpart_00_20 | 5|text05 -tpart_00_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s2bs s2i s2c s1brr s1merg s2b s2u s1c s2c s2s -step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s2c: COMMIT; -step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; -step s2b: BEGIN; -step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; -step s1c: COMMIT; -step s2u: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+----------- -tpart_00_20 | 1|text01modif -tpart_00_20 | 5|text05 -tpart_00_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s2bs s2i s2c s1bs s1merg s2b s2u s1c s2c s2s -step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s2c: COMMIT; -step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; -step s2b: BEGIN; -step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; -step s1c: COMMIT; -step s2u: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+----------- -tpart_00_20 | 1|text01modif -tpart_00_20 | 5|text05 -tpart_00_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s2b s2i s2c s1b s1merg s2b s2u2 s1c s2c s2s -step s2b: BEGIN; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s2c: COMMIT; -step s1b: BEGIN; -step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; -step s2b: BEGIN; -step s2u2: UPDATE tpart SET i = 21 where i = 1; -step s1c: COMMIT; -step s2u2: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_20 | 5|text05 -tpart_00_20 |15|text15 -tpart_20_30 |21|text01 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s2b s2i s2c s1b s1merg s2b s2u3 s1c s2c s2s -step s2b: BEGIN; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s2c: COMMIT; -step s1b: BEGIN; -step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; -step s2b: BEGIN; -step s2u3: UPDATE tpart SET i = 11 where i = 1; -step s1c: COMMIT; -step s2u3: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_20 | 5|text05 -tpart_00_20 |11|text01 -tpart_00_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - diff --git a/src/test/isolation/expected/partition-split.out b/src/test/isolation/expected/partition-split.out deleted file mode 100644 index 02a5bb4f1f5..00000000000 --- a/src/test/isolation/expected/partition-split.out +++ /dev/null @@ -1,230 +0,0 @@ -Parsed test spec with 2 sessions - -starting permutation: s1b s1splt s2b s2i s1c s2c s2s -step s1b: BEGIN; -step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); -step s2b: BEGIN; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s1c: COMMIT; -step s2i: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_10 | 1|text01 -tpart_00_10 | 5|text05 -tpart_15_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s1b s1splt s2brr s2i s1c s2c s2s -step s1b: BEGIN; -step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); -step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s1c: COMMIT; -step s2i: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_10 | 1|text01 -tpart_00_10 | 5|text05 -tpart_15_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s1b s1splt s2bs s2i s1c s2c s2s -step s1b: BEGIN; -step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); -step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s1c: COMMIT; -step s2i: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_10 | 1|text01 -tpart_00_10 | 5|text05 -tpart_15_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s1brr s1splt s2b s2i s1c s2c s2s -step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); -step s2b: BEGIN; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s1c: COMMIT; -step s2i: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_10 | 1|text01 -tpart_00_10 | 5|text05 -tpart_15_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s1brr s1splt s2brr s2i s1c s2c s2s -step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); -step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s1c: COMMIT; -step s2i: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_10 | 1|text01 -tpart_00_10 | 5|text05 -tpart_15_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s1brr s1splt s2bs s2i s1c s2c s2s -step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); -step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s1c: COMMIT; -step s2i: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_10 | 1|text01 -tpart_00_10 | 5|text05 -tpart_15_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s1bs s1splt s2b s2i s1c s2c s2s -step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); -step s2b: BEGIN; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s1c: COMMIT; -step s2i: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_10 | 1|text01 -tpart_00_10 | 5|text05 -tpart_15_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s1bs s1splt s2brr s2i s1c s2c s2s -step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); -step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s1c: COMMIT; -step s2i: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_10 | 1|text01 -tpart_00_10 | 5|text05 -tpart_15_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s1bs s1splt s2bs s2i s1c s2c s2s -step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); -step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE; -step s2i: INSERT INTO tpart VALUES (1, 'text01'); -step s1c: COMMIT; -step s2i: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_10 | 1|text01 -tpart_00_10 | 5|text05 -tpart_15_20 |15|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(5 rows) - - -starting permutation: s1b s1splt s2b s2u s1c s2c s2s -step s1b: BEGIN; -step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); -step s2b: BEGIN; -step s2u: UPDATE tpart SET i = 16 where i = 5; -step s1c: COMMIT; -step s2u: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_15_20 |15|text15 -tpart_15_20 |16|text05 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(4 rows) - - -starting permutation: s1b s1splt s2b s2u2 s1c s2c s2s -step s1b: BEGIN; -step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); -step s2b: BEGIN; -step s2u2: UPDATE tpart SET i = 11 where i = 15; -step s1c: COMMIT; -step s2u2: <... completed> -step s2c: COMMIT; -step s2s: SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; -tableoid | i|t --------------+--+------ -tpart_00_10 | 5|text05 -tpart_10_15 |11|text15 -tpart_20_30 |25|text25 -tpart_default|35|text35 -(4 rows) - diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 6469aafa2e1..1fcf4e63238 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -116,8 +116,6 @@ test: partition-key-update-1 test: partition-key-update-2 test: partition-key-update-3 test: partition-key-update-4 -test: partition-merge -test: partition-split test: plpgsql-toast test: cluster-conflict test: cluster-conflict-partition diff --git a/src/test/isolation/specs/partition-merge.spec b/src/test/isolation/specs/partition-merge.spec deleted file mode 100644 index f3c5ce2fbf1..00000000000 --- a/src/test/isolation/specs/partition-merge.spec +++ /dev/null @@ -1,62 +0,0 @@ -# Verify that MERGE operation locks DML operations with partitioned table - -setup -{ - DROP TABLE IF EXISTS tpart; - CREATE TABLE tpart(i int, t text) partition by range(i); - CREATE TABLE tpart_00_10 PARTITION OF tpart FOR VALUES FROM (0) TO (10); - CREATE TABLE tpart_10_20 PARTITION OF tpart FOR VALUES FROM (10) TO (20); - CREATE TABLE tpart_20_30 PARTITION OF tpart FOR VALUES FROM (20) TO (30); - CREATE TABLE tpart_default PARTITION OF tpart DEFAULT; - INSERT INTO tpart VALUES (5, 'text05'); - INSERT INTO tpart VALUES (15, 'text15'); - INSERT INTO tpart VALUES (25, 'text25'); - INSERT INTO tpart VALUES (35, 'text35'); -} - -teardown -{ - DROP TABLE tpart; -} - -session s1 -step s1b { BEGIN; } -step s1brr { BEGIN ISOLATION LEVEL REPEATABLE READ; } -step s1bs { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step s1merg { ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; } -step s1c { COMMIT; } - - -session s2 -step s2b { BEGIN; } -step s2brr { BEGIN ISOLATION LEVEL REPEATABLE READ; } -step s2bs { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step s2i { INSERT INTO tpart VALUES (1, 'text01'); } -step s2u { UPDATE tpart SET t = 'text01modif' where i = 1; } -step s2u2 { UPDATE tpart SET i = 21 where i = 1; } -step s2u3 { UPDATE tpart SET i = 11 where i = 1; } -step s2c { COMMIT; } -step s2s { SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; } - - -# s2 inserts row into table. s1 starts MERGE PARTITIONS then -# s2 is trying to update inserted row and waits until s1 finishes -# MERGE operation. - -permutation s2b s2i s2c s1b s1merg s2b s2u s1c s2c s2s -permutation s2b s2i s2c s1brr s1merg s2b s2u s1c s2c s2s -permutation s2b s2i s2c s1bs s1merg s2b s2u s1c s2c s2s - -permutation s2brr s2i s2c s1b s1merg s2b s2u s1c s2c s2s -permutation s2brr s2i s2c s1brr s1merg s2b s2u s1c s2c s2s -permutation s2brr s2i s2c s1bs s1merg s2b s2u s1c s2c s2s - -permutation s2bs s2i s2c s1b s1merg s2b s2u s1c s2c s2s -permutation s2bs s2i s2c s1brr s1merg s2b s2u s1c s2c s2s -permutation s2bs s2i s2c s1bs s1merg s2b s2u s1c s2c s2s - -# Tuple routing between partitions. -permutation s2b s2i s2c s1b s1merg s2b s2u2 s1c s2c s2s - -# Tuple routing between merging partitions. -permutation s2b s2i s2c s1b s1merg s2b s2u3 s1c s2c s2s diff --git a/src/test/isolation/specs/partition-split.spec b/src/test/isolation/specs/partition-split.spec deleted file mode 100644 index af954be5dc0..00000000000 --- a/src/test/isolation/specs/partition-split.spec +++ /dev/null @@ -1,62 +0,0 @@ -# Verify that SPLIT operation locks DML operations with partitioned table - -setup -{ - DROP TABLE IF EXISTS tpart; - CREATE TABLE tpart(i int, t text) partition by range(i); - CREATE TABLE tpart_00_10 PARTITION OF tpart FOR VALUES FROM (0) TO (10); - CREATE TABLE tpart_10_20 PARTITION OF tpart FOR VALUES FROM (10) TO (20); - CREATE TABLE tpart_20_30 PARTITION OF tpart FOR VALUES FROM (20) TO (30); - CREATE TABLE tpart_default PARTITION OF tpart DEFAULT; - INSERT INTO tpart VALUES (5, 'text05'); - INSERT INTO tpart VALUES (15, 'text15'); - INSERT INTO tpart VALUES (25, 'text25'); - INSERT INTO tpart VALUES (35, 'text35'); -} - -teardown -{ - DROP TABLE tpart; -} - -session s1 -step s1b { BEGIN; } -step s1brr { BEGIN ISOLATION LEVEL REPEATABLE READ; } -step s1bs { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step s1splt { ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO - (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); } -step s1c { COMMIT; } - - -session s2 -step s2b { BEGIN; } -step s2brr { BEGIN ISOLATION LEVEL REPEATABLE READ; } -step s2bs { BEGIN ISOLATION LEVEL SERIALIZABLE; } -step s2i { INSERT INTO tpart VALUES (1, 'text01'); } -step s2c { COMMIT; } -step s2s { SELECT tableoid::regclass, * FROM tpart ORDER BY tableoid::regclass::text COLLATE "C", i; } -step s2u { UPDATE tpart SET i = 16 where i = 5; } -step s2u2 { UPDATE tpart SET i = 11 where i = 15; } - - -# s1 starts SPLIT PARTITION then s2 trying to insert row and -# waits until s1 finished SPLIT operation. - -permutation s1b s1splt s2b s2i s1c s2c s2s -permutation s1b s1splt s2brr s2i s1c s2c s2s -permutation s1b s1splt s2bs s2i s1c s2c s2s - -permutation s1brr s1splt s2b s2i s1c s2c s2s -permutation s1brr s1splt s2brr s2i s1c s2c s2s -permutation s1brr s1splt s2bs s2i s1c s2c s2s - -permutation s1bs s1splt s2b s2i s1c s2c s2s -permutation s1bs s1splt s2brr s2i s1c s2c s2s -permutation s1bs s1splt s2bs s2i s1c s2c s2s - -# Tuple routing between partitions. -permutation s1b s1splt s2b s2u s1c s2c s2s - -# Tuple routing inside splitting partition. -permutation s1b s1splt s2b s2u2 s1c s2c s2s diff --git a/src/test/modules/test_ddl_deparse/expected/alter_table.out b/src/test/modules/test_ddl_deparse/expected/alter_table.out index 3a2f576f3b6..f1c6f05fe17 100644 --- a/src/test/modules/test_ddl_deparse/expected/alter_table.out +++ b/src/test/modules/test_ddl_deparse/expected/alter_table.out @@ -113,16 +113,6 @@ ALTER TABLE part DETACH PARTITION part2; NOTICE: DDL test: type alter table, tag ALTER TABLE NOTICE: subcommand: type DETACH PARTITION desc table part2 DROP TABLE part2; -CREATE TABLE part2 PARTITION OF part FOR VALUES FROM (100) to (200); -NOTICE: DDL test: type simple, tag CREATE TABLE -ALTER TABLE part MERGE PARTITIONS (part1, part2) INTO part1; -NOTICE: DDL test: type alter table, tag ALTER TABLE -NOTICE: subcommand: type MERGE PARTITIONS desc -ALTER TABLE part SPLIT PARTITION part1 INTO - (PARTITION part1 FOR VALUES FROM (1) to (100), - PARTITION part2 FOR VALUES FROM (100) to (200)); -NOTICE: DDL test: type alter table, tag ALTER TABLE -NOTICE: subcommand: type SPLIT PARTITION desc ALTER TABLE part ADD PRIMARY KEY (a); NOTICE: DDL test: type alter table, tag ALTER TABLE NOTICE: subcommand: type ADD CONSTRAINT (and recurse) desc constraint part_a_not_null on table part diff --git a/src/test/modules/test_ddl_deparse/sql/alter_table.sql b/src/test/modules/test_ddl_deparse/sql/alter_table.sql index 0980097048e..380ba266075 100644 --- a/src/test/modules/test_ddl_deparse/sql/alter_table.sql +++ b/src/test/modules/test_ddl_deparse/sql/alter_table.sql @@ -60,13 +60,6 @@ ALTER TABLE part ATTACH PARTITION part2 FOR VALUES FROM (101) to (200); ALTER TABLE part DETACH PARTITION part2; DROP TABLE part2; -CREATE TABLE part2 PARTITION OF part FOR VALUES FROM (100) to (200); -ALTER TABLE part MERGE PARTITIONS (part1, part2) INTO part1; - -ALTER TABLE part SPLIT PARTITION part1 INTO - (PARTITION part1 FOR VALUES FROM (1) to (100), - PARTITION part2 FOR VALUES FROM (100) to (200)); - ALTER TABLE part ADD PRIMARY KEY (a); CREATE TABLE tbl ( diff --git a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c index 64a1dfa9f79..105872a3517 100644 --- a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c +++ b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c @@ -297,12 +297,6 @@ get_altertable_subcmdinfo(PG_FUNCTION_ARGS) case AT_DetachPartitionFinalize: strtype = "DETACH PARTITION ... FINALIZE"; break; - case AT_SplitPartition: - strtype = "SPLIT PARTITION"; - break; - case AT_MergePartitions: - strtype = "MERGE PARTITIONS"; - break; case AT_AddIdentity: strtype = "ADD IDENTITY"; break; diff --git a/src/test/modules/test_extensions/expected/test_extdepend.out b/src/test/modules/test_extensions/expected/test_extdepend.out index ede5dc64c04..0b62015d18c 100644 --- a/src/test/modules/test_extensions/expected/test_extdepend.out +++ b/src/test/modules/test_extensions/expected/test_extdepend.out @@ -186,123 +186,3 @@ DROP MATERIALIZED VIEW d; DROP INDEX e; DROP SCHEMA test_ext CASCADE; NOTICE: drop cascades to table a --- Fifth test: extension dependencies on partition indexes survive MERGE and --- SPLIT PARTITION operations, and mismatches between source partitions are --- reported. -RESET search_path; -CREATE EXTENSION test_ext3; -CREATE EXTENSION test_ext5; -CREATE TABLE part_extdep (i int, x int) PARTITION BY RANGE (i); -CREATE TABLE part_extdep_1 PARTITION OF part_extdep FOR VALUES FROM (1) TO (2); -CREATE TABLE part_extdep_2 PARTITION OF part_extdep FOR VALUES FROM (2) TO (3); -CREATE TABLE part_extdep_3 PARTITION OF part_extdep FOR VALUES FROM (3) TO (4); -CREATE TABLE part_extdep_4 PARTITION OF part_extdep FOR VALUES FROM (4) TO (5); -CREATE TABLE part_extdep_5 PARTITION OF part_extdep FOR VALUES FROM (5) TO (6); -CREATE INDEX part_extdep_i_idx ON part_extdep(i); -CREATE INDEX part_extdep_x_idx ON part_extdep(x); --- Partitions 1, 2, 3 depend on the same two extensions. -ALTER INDEX part_extdep_1_i_idx DEPENDS ON EXTENSION test_ext3; -ALTER INDEX part_extdep_1_x_idx DEPENDS ON EXTENSION test_ext5; -ALTER INDEX part_extdep_2_i_idx DEPENDS ON EXTENSION test_ext3; -ALTER INDEX part_extdep_2_x_idx DEPENDS ON EXTENSION test_ext5; -ALTER INDEX part_extdep_3_i_idx DEPENDS ON EXTENSION test_ext3; -ALTER INDEX part_extdep_3_x_idx DEPENDS ON EXTENSION test_ext5; --- Partition 4 depends on a different extension on one index. -ALTER INDEX part_extdep_4_i_idx DEPENDS ON EXTENSION test_ext5; --- Partition 5 has no dependency at all. --- Merge matching partitions: should succeed and preserve dependencies on the --- new partition's indexes (DROP EXTENSION must fail, naming the new index). -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_1, part_extdep_2) - INTO part_extdep_merged; -DROP EXTENSION test_ext3; -ERROR: cannot drop index part_extdep_merged_i_idx because index part_extdep_i_idx requires it -HINT: You can drop index part_extdep_i_idx instead. -SELECT c.relname, e.extname -FROM pg_depend d -JOIN pg_class c ON d.objid = c.oid -JOIN pg_extension e ON d.refobjid = e.oid -WHERE c.relname IN ('part_extdep_merged_i_idx', 'part_extdep_merged_x_idx') - AND e.extname IN ('test_ext3', 'test_ext5') - AND d.deptype = 'x' -ORDER BY c.relname, e.extname; - relname | extname ---------------------------+----------- - part_extdep_merged_i_idx | test_ext3 - part_extdep_merged_x_idx | test_ext5 -(2 rows) - --- An index created directly on a partition has no parent in the partitioned --- index tree. Such an index is dropped with its old partition during merge, --- and any extension dependency it carries goes away with it: the dep is not --- promoted to the merged partition. Verify by attaching test_ext9 to such --- an orphan index, merging, and observing that test_ext9 becomes droppable. -CREATE EXTENSION test_ext9; -CREATE INDEX part_extdep_3_extra_idx ON part_extdep_3(x); -ALTER INDEX part_extdep_3_extra_idx DEPENDS ON EXTENSION test_ext9; -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_merged, part_extdep_3) - INTO part_extdep_merged2; -DROP EXTENSION test_ext9; --- Mismatched dependencies: partition 4's index depends on a different --- extension than partition_merged2's. Both orderings must fail, and the --- error must cite both partition indexes. -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_merged2, part_extdep_4) - INTO part_extdep_bad; -ERROR: cannot merge partitions with conflicting extension dependencies -DETAIL: Partition indexes "part_extdep_4_i_idx" and "part_extdep_merged2_i_idx" depend on different extensions. -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_4, part_extdep_merged2) - INTO part_extdep_bad; -ERROR: cannot merge partitions with conflicting extension dependencies -DETAIL: Partition indexes "part_extdep_4_i_idx" and "part_extdep_merged2_i_idx" depend on different extensions. --- Empty vs non-empty dependency set (the subset case the earlier linear --- check missed in one direction). -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_4, part_extdep_5) - INTO part_extdep_bad; -ERROR: cannot merge partitions with conflicting extension dependencies -DETAIL: Partition indexes "part_extdep_4_i_idx" and "part_extdep_5_i_idx" depend on different extensions. -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_5, part_extdep_4) - INTO part_extdep_bad; -ERROR: cannot merge partitions with conflicting extension dependencies -DETAIL: Partition indexes "part_extdep_4_i_idx" and "part_extdep_5_i_idx" depend on different extensions. --- Subset: partition 5's i_idx depends on a strict superset of partition 4's --- i_idx dependencies. Partition 4 = {test_ext5}, partition 5 will be --- {test_ext3, test_ext5}. Both orderings must fail; in particular the case --- where the first partition we walk has fewer extensions than the second --- must still be rejected. -ALTER INDEX part_extdep_5_i_idx DEPENDS ON EXTENSION test_ext3; -ALTER INDEX part_extdep_5_i_idx DEPENDS ON EXTENSION test_ext5; -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_4, part_extdep_5) - INTO part_extdep_bad; -ERROR: cannot merge partitions with conflicting extension dependencies -DETAIL: Partition indexes "part_extdep_4_i_idx" and "part_extdep_5_i_idx" depend on different extensions. -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_5, part_extdep_4) - INTO part_extdep_bad; -ERROR: cannot merge partitions with conflicting extension dependencies -DETAIL: Partition indexes "part_extdep_4_i_idx" and "part_extdep_5_i_idx" depend on different extensions. --- Reset partition 5 so it doesn't interfere with the SPLIT test below. -ALTER INDEX part_extdep_5_i_idx NO DEPENDS ON EXTENSION test_ext3; -ALTER INDEX part_extdep_5_i_idx NO DEPENDS ON EXTENSION test_ext5; --- Split: the single source partition's dependencies must appear on every --- new partition's matching index, identified by extension name. -ALTER TABLE part_extdep SPLIT PARTITION part_extdep_merged2 INTO - (PARTITION part_extdep_s1 FOR VALUES FROM (1) TO (3), - PARTITION part_extdep_s2 FOR VALUES FROM (3) TO (4)); -SELECT c.relname, e.extname -FROM pg_depend d -JOIN pg_class c ON d.objid = c.oid -JOIN pg_extension e ON d.refobjid = e.oid -WHERE c.relname IN ('part_extdep_s1_i_idx', 'part_extdep_s1_x_idx', - 'part_extdep_s2_i_idx', 'part_extdep_s2_x_idx') - AND e.extname IN ('test_ext3', 'test_ext5') - AND d.deptype = 'x' -ORDER BY c.relname, e.extname; - relname | extname -----------------------+----------- - part_extdep_s1_i_idx | test_ext3 - part_extdep_s1_x_idx | test_ext5 - part_extdep_s2_i_idx | test_ext3 - part_extdep_s2_x_idx | test_ext5 -(4 rows) - -DROP TABLE part_extdep; -DROP EXTENSION test_ext3; -DROP EXTENSION test_ext5; diff --git a/src/test/modules/test_extensions/sql/test_extdepend.sql b/src/test/modules/test_extensions/sql/test_extdepend.sql index ad734af1e71..63240a1af5d 100644 --- a/src/test/modules/test_extensions/sql/test_extdepend.sql +++ b/src/test/modules/test_extensions/sql/test_extdepend.sql @@ -88,107 +88,3 @@ DROP FUNCTION b(); DROP MATERIALIZED VIEW d; DROP INDEX e; DROP SCHEMA test_ext CASCADE; - --- Fifth test: extension dependencies on partition indexes survive MERGE and --- SPLIT PARTITION operations, and mismatches between source partitions are --- reported. -RESET search_path; -CREATE EXTENSION test_ext3; -CREATE EXTENSION test_ext5; - -CREATE TABLE part_extdep (i int, x int) PARTITION BY RANGE (i); -CREATE TABLE part_extdep_1 PARTITION OF part_extdep FOR VALUES FROM (1) TO (2); -CREATE TABLE part_extdep_2 PARTITION OF part_extdep FOR VALUES FROM (2) TO (3); -CREATE TABLE part_extdep_3 PARTITION OF part_extdep FOR VALUES FROM (3) TO (4); -CREATE TABLE part_extdep_4 PARTITION OF part_extdep FOR VALUES FROM (4) TO (5); -CREATE TABLE part_extdep_5 PARTITION OF part_extdep FOR VALUES FROM (5) TO (6); -CREATE INDEX part_extdep_i_idx ON part_extdep(i); -CREATE INDEX part_extdep_x_idx ON part_extdep(x); - --- Partitions 1, 2, 3 depend on the same two extensions. -ALTER INDEX part_extdep_1_i_idx DEPENDS ON EXTENSION test_ext3; -ALTER INDEX part_extdep_1_x_idx DEPENDS ON EXTENSION test_ext5; -ALTER INDEX part_extdep_2_i_idx DEPENDS ON EXTENSION test_ext3; -ALTER INDEX part_extdep_2_x_idx DEPENDS ON EXTENSION test_ext5; -ALTER INDEX part_extdep_3_i_idx DEPENDS ON EXTENSION test_ext3; -ALTER INDEX part_extdep_3_x_idx DEPENDS ON EXTENSION test_ext5; - --- Partition 4 depends on a different extension on one index. -ALTER INDEX part_extdep_4_i_idx DEPENDS ON EXTENSION test_ext5; - --- Partition 5 has no dependency at all. - --- Merge matching partitions: should succeed and preserve dependencies on the --- new partition's indexes (DROP EXTENSION must fail, naming the new index). -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_1, part_extdep_2) - INTO part_extdep_merged; -DROP EXTENSION test_ext3; -SELECT c.relname, e.extname -FROM pg_depend d -JOIN pg_class c ON d.objid = c.oid -JOIN pg_extension e ON d.refobjid = e.oid -WHERE c.relname IN ('part_extdep_merged_i_idx', 'part_extdep_merged_x_idx') - AND e.extname IN ('test_ext3', 'test_ext5') - AND d.deptype = 'x' -ORDER BY c.relname, e.extname; - --- An index created directly on a partition has no parent in the partitioned --- index tree. Such an index is dropped with its old partition during merge, --- and any extension dependency it carries goes away with it: the dep is not --- promoted to the merged partition. Verify by attaching test_ext9 to such --- an orphan index, merging, and observing that test_ext9 becomes droppable. -CREATE EXTENSION test_ext9; -CREATE INDEX part_extdep_3_extra_idx ON part_extdep_3(x); -ALTER INDEX part_extdep_3_extra_idx DEPENDS ON EXTENSION test_ext9; -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_merged, part_extdep_3) - INTO part_extdep_merged2; -DROP EXTENSION test_ext9; - --- Mismatched dependencies: partition 4's index depends on a different --- extension than partition_merged2's. Both orderings must fail, and the --- error must cite both partition indexes. -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_merged2, part_extdep_4) - INTO part_extdep_bad; -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_4, part_extdep_merged2) - INTO part_extdep_bad; - --- Empty vs non-empty dependency set (the subset case the earlier linear --- check missed in one direction). -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_4, part_extdep_5) - INTO part_extdep_bad; -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_5, part_extdep_4) - INTO part_extdep_bad; - --- Subset: partition 5's i_idx depends on a strict superset of partition 4's --- i_idx dependencies. Partition 4 = {test_ext5}, partition 5 will be --- {test_ext3, test_ext5}. Both orderings must fail; in particular the case --- where the first partition we walk has fewer extensions than the second --- must still be rejected. -ALTER INDEX part_extdep_5_i_idx DEPENDS ON EXTENSION test_ext3; -ALTER INDEX part_extdep_5_i_idx DEPENDS ON EXTENSION test_ext5; -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_4, part_extdep_5) - INTO part_extdep_bad; -ALTER TABLE part_extdep MERGE PARTITIONS (part_extdep_5, part_extdep_4) - INTO part_extdep_bad; --- Reset partition 5 so it doesn't interfere with the SPLIT test below. -ALTER INDEX part_extdep_5_i_idx NO DEPENDS ON EXTENSION test_ext3; -ALTER INDEX part_extdep_5_i_idx NO DEPENDS ON EXTENSION test_ext5; - --- Split: the single source partition's dependencies must appear on every --- new partition's matching index, identified by extension name. -ALTER TABLE part_extdep SPLIT PARTITION part_extdep_merged2 INTO - (PARTITION part_extdep_s1 FOR VALUES FROM (1) TO (3), - PARTITION part_extdep_s2 FOR VALUES FROM (3) TO (4)); -SELECT c.relname, e.extname -FROM pg_depend d -JOIN pg_class c ON d.objid = c.oid -JOIN pg_extension e ON d.refobjid = e.oid -WHERE c.relname IN ('part_extdep_s1_i_idx', 'part_extdep_s1_x_idx', - 'part_extdep_s2_i_idx', 'part_extdep_s2_x_idx') - AND e.extname IN ('test_ext3', 'test_ext5') - AND d.deptype = 'x' -ORDER BY c.relname, e.extname; - -DROP TABLE part_extdep; -DROP EXTENSION test_ext3; -DROP EXTENSION test_ext5; diff --git a/src/test/regress/expected/partition_merge.out b/src/test/regress/expected/partition_merge.out deleted file mode 100644 index ccda2b5843b..00000000000 --- a/src/test/regress/expected/partition_merge.out +++ /dev/null @@ -1,1174 +0,0 @@ --- --- PARTITIONS_MERGE --- Tests for "ALTER TABLE ... MERGE PARTITIONS ..." command --- -CREATE SCHEMA partitions_merge_schema; -CREATE SCHEMA partitions_merge_schema2; -SET search_path = partitions_merge_schema, public; --- --- BY RANGE partitioning --- --- --- Test for error codes --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_dec2021 PARTITION OF sales_range FOR VALUES FROM ('2021-12-01') TO ('2021-12-31'); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'); -CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'); -CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_apr_1 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-04-15'); -CREATE TABLE sales_apr_2 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-15') TO ('2022-05-01'); -ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; --- ERROR -ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_feb2022) INTO sales_feb_mar_apr2022; -ERROR: partition with name "sales_feb2022" is already used -LINE 1: ...e MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_feb2... - ^ --- ERROR -ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_apr2022) INTO sales_feb_mar_apr2022; -ERROR: "sales_apr2022" is not a table -HINT: ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions. --- ERROR --- (space between sections sales_jan2022 and sales_mar2022) -ALTER TABLE sales_range MERGE PARTITIONS (sales_jan2022, sales_mar2022) INTO sales_jan_mar2022; -ERROR: cannot merge partition "sales_mar2022" together with partition "sales_jan2022" -DETAIL: The lower bound of partition "sales_mar2022" is not equal to the upper bound of partition "sales_jan2022". -HINT: ALTER TABLE ... MERGE PARTITIONS requires the partition bounds to be adjacent. --- ERROR --- (space between sections sales_dec2021 and sales_jan2022) -ALTER TABLE sales_range MERGE PARTITIONS (sales_dec2021, sales_jan2022, sales_feb2022) INTO sales_dec_jan_feb2022; -ERROR: cannot merge partition "sales_jan2022" together with partition "sales_dec2021" -DETAIL: The lower bound of partition "sales_jan2022" is not equal to the upper bound of partition "sales_dec2021". -HINT: ALTER TABLE ... MERGE PARTITIONS requires the partition bounds to be adjacent. --- ERROR -ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, partitions_merge_schema.sales_feb2022) INTO sales_feb_mar_apr2022; -ERROR: partition with name "sales_feb2022" is already used -LINE 1: ...e MERGE PARTITIONS (sales_feb2022, sales_mar2022, partitions... - ^ --- ERROR -ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_jan2022) INTO sales_apr_2; -ERROR: relation "sales_apr_2" already exists -CREATE VIEW jan2022v as SELECT * FROM sales_jan2022; -ALTER TABLE sales_range MERGE PARTITIONS (sales_jan2022, sales_feb2022) INTO sales_dec_jan_feb2022; -ERROR: cannot drop table sales_jan2022 because other objects depend on it -DETAIL: view jan2022v depends on table sales_jan2022 -HINT: Use DROP ... CASCADE to drop the dependent objects too. -DROP VIEW jan2022v; --- NO ERROR: test for custom partitions order, source partitions not in the search_path -SET search_path = partitions_merge_schema2, public; -ALTER TABLE partitions_merge_schema.sales_range MERGE PARTITIONS ( - partitions_merge_schema.sales_feb2022, - partitions_merge_schema.sales_mar2022, - partitions_merge_schema.sales_jan2022) INTO sales_jan_feb_mar2022; -SET search_path = partitions_merge_schema, public; -PREPARE get_partition_info(regclass[]) AS -SELECT c.oid::pg_catalog.regclass, - c.relpersistence, - c.relkind, - i.inhdetachpending, - pg_catalog.pg_get_expr(c.relpartbound, c.oid) -FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i -WHERE c.oid = i.inhrelid AND i.inhparent = ANY($1) -ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', - c.oid::regclass::text COLLATE "C"; -EXECUTE get_partition_info('{sales_range}'); - oid | relpersistence | relkind | inhdetachpending | pg_get_expr -------------------------------------------------+----------------+---------+------------------+-------------------------------------------------- - partitions_merge_schema2.sales_jan_feb_mar2022 | p | r | f | FOR VALUES FROM ('01-01-2022') TO ('04-01-2022') - sales_apr2022 | p | p | f | FOR VALUES FROM ('04-01-2022') TO ('05-01-2022') - sales_dec2021 | p | r | f | FOR VALUES FROM ('12-01-2021') TO ('12-31-2021') - sales_others | p | r | f | DEFAULT -(4 rows) - -DROP TABLE sales_range; --- --- Add rows into partitioned table, then merge partitions --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'); -CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'); -CREATE TABLE sales_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date); -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); -SELECT pg_catalog.pg_get_partkeydef('sales_range'::regclass); - pg_get_partkeydef --------------------- - RANGE (sales_date) -(1 row) - --- show partitions with conditions: -EXECUTE get_partition_info('{sales_range}'); - oid | relpersistence | relkind | inhdetachpending | pg_get_expr ----------------+----------------+---------+------------------+-------------------------------------------------- - sales_apr2022 | p | r | f | FOR VALUES FROM ('04-01-2022') TO ('05-01-2022') - sales_feb2022 | p | r | f | FOR VALUES FROM ('02-01-2022') TO ('03-01-2022') - sales_jan2022 | p | r | f | FOR VALUES FROM ('01-01-2022') TO ('02-01-2022') - sales_mar2022 | p | r | f | FOR VALUES FROM ('03-01-2022') TO ('04-01-2022') - sales_others | p | r | f | DEFAULT -(5 rows) - --- check schema-qualified name of the new partition -ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_apr2022) INTO partitions_merge_schema2.sales_feb_mar_apr2022; --- show partitions with conditions: -EXECUTE get_partition_info('{sales_range}'); - oid | relpersistence | relkind | inhdetachpending | pg_get_expr -------------------------------------------------+----------------+---------+------------------+-------------------------------------------------- - partitions_merge_schema2.sales_feb_mar_apr2022 | p | r | f | FOR VALUES FROM ('02-01-2022') TO ('05-01-2022') - sales_jan2022 | p | r | f | FOR VALUES FROM ('01-01-2022') TO ('02-01-2022') - sales_others | p | r | f | DEFAULT -(3 rows) - -SELECT * FROM pg_indexes WHERE tablename = 'sales_feb_mar_apr2022' and schemaname = 'partitions_merge_schema2'; - schemaname | tablename | indexname | tablespace | indexdef ---------------------------+-----------------------+--------------------------------------+------------+------------------------------------------------------------------------------------------------------------------------------ - partitions_merge_schema2 | sales_feb_mar_apr2022 | sales_feb_mar_apr2022_sales_date_idx | | CREATE INDEX sales_feb_mar_apr2022_sales_date_idx ON partitions_merge_schema2.sales_feb_mar_apr2022 USING btree (sales_date) -(1 row) - -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_amount | sales_date -------------------------------------------------+----------------+------------------+--------------+------------ - partitions_merge_schema2.sales_feb_mar_apr2022 | 2 | Smirnoff | 500 | 02-10-2022 - partitions_merge_schema2.sales_feb_mar_apr2022 | 3 | Ford | 2000 | 04-30-2022 - partitions_merge_schema2.sales_feb_mar_apr2022 | 4 | Ivanov | 750 | 04-13-2022 - partitions_merge_schema2.sales_feb_mar_apr2022 | 5 | Deev | 250 | 04-07-2022 - partitions_merge_schema2.sales_feb_mar_apr2022 | 6 | Poirot | 150 | 02-11-2022 - partitions_merge_schema2.sales_feb_mar_apr2022 | 7 | Li | 175 | 03-08-2022 - partitions_merge_schema2.sales_feb_mar_apr2022 | 8 | Ericsson | 185 | 02-23-2022 - partitions_merge_schema2.sales_feb_mar_apr2022 | 9 | Muller | 250 | 03-11-2022 - partitions_merge_schema2.sales_feb_mar_apr2022 | 11 | Trump | 380 | 04-06-2022 - partitions_merge_schema2.sales_feb_mar_apr2022 | 12 | Plato | 350 | 03-19-2022 - sales_jan2022 | 1 | May | 1000 | 01-31-2022 - sales_jan2022 | 10 | Halder | 350 | 01-28-2022 - sales_jan2022 | 13 | Gandi | 377 | 01-09-2022 - sales_others | 14 | Smith | 510 | 05-04-2022 -(14 rows) - --- Use indexscan for testing indexes -SET enable_seqscan = OFF; -EXPLAIN (COSTS OFF) SELECT * FROM partitions_merge_schema2.sales_feb_mar_apr2022 where sales_date > '2022-01-01'; - QUERY PLAN --------------------------------------------------------------------------------- - Index Scan using sales_feb_mar_apr2022_sales_date_idx on sales_feb_mar_apr2022 - Index Cond: (sales_date > '01-01-2022'::date) -(2 rows) - -SELECT * FROM partitions_merge_schema2.sales_feb_mar_apr2022 where sales_date > '2022-01-01'; - salesperson_id | salesperson_name | sales_amount | sales_date -----------------+------------------+--------------+------------ - 2 | Smirnoff | 500 | 02-10-2022 - 6 | Poirot | 150 | 02-11-2022 - 8 | Ericsson | 185 | 02-23-2022 - 7 | Li | 175 | 03-08-2022 - 9 | Muller | 250 | 03-11-2022 - 12 | Plato | 350 | 03-19-2022 - 11 | Trump | 380 | 04-06-2022 - 5 | Deev | 250 | 04-07-2022 - 4 | Ivanov | 750 | 04-13-2022 - 3 | Ford | 2000 | 04-30-2022 -(10 rows) - -RESET enable_seqscan; -DROP TABLE sales_range; --- --- Merge some partitions into DEFAULT partition --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'); -CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'); -CREATE TABLE sales_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date); -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); --- Merge partitions (include DEFAULT partition) into partition with the same --- name -ALTER TABLE sales_range MERGE PARTITIONS - (sales_jan2022, sales_mar2022, partitions_merge_schema.sales_others) INTO sales_others; -SELECT * FROM sales_others ORDER BY salesperson_id; - salesperson_id | salesperson_name | sales_amount | sales_date -----------------+------------------+--------------+------------ - 1 | May | 1000 | 01-31-2022 - 7 | Li | 175 | 03-08-2022 - 9 | Muller | 250 | 03-11-2022 - 10 | Halder | 350 | 01-28-2022 - 12 | Plato | 350 | 03-19-2022 - 13 | Gandi | 377 | 01-09-2022 - 14 | Smith | 510 | 05-04-2022 -(7 rows) - --- show partitions with conditions: -EXECUTE get_partition_info('{sales_range}'); - oid | relpersistence | relkind | inhdetachpending | pg_get_expr ----------------+----------------+---------+------------------+-------------------------------------------------- - sales_apr2022 | p | r | f | FOR VALUES FROM ('04-01-2022') TO ('05-01-2022') - sales_feb2022 | p | r | f | FOR VALUES FROM ('02-01-2022') TO ('03-01-2022') - sales_others | p | r | f | DEFAULT -(3 rows) - -DROP TABLE sales_range; --- --- Test for: --- * composite partition key; --- * GENERATED column; --- * column with DEFAULT value. --- -CREATE TABLE sales_date (salesperson_name VARCHAR(30), sales_year INT, sales_month INT, sales_day INT, - sales_date VARCHAR(10) GENERATED ALWAYS AS - (LPAD(sales_year::text, 4, '0') || '.' || LPAD(sales_month::text, 2, '0') || '.' || LPAD(sales_day::text, 2, '0')) STORED, - sales_department VARCHAR(30) DEFAULT 'Sales department') - PARTITION BY RANGE (sales_year, sales_month, sales_day); -CREATE TABLE sales_dec2022 PARTITION OF sales_date FOR VALUES FROM (2021, 12, 1) TO (2022, 1, 1); -CREATE TABLE sales_jan2022 PARTITION OF sales_date FOR VALUES FROM (2022, 1, 1) TO (2022, 2, 1); -CREATE TABLE sales_feb2022 PARTITION OF sales_date FOR VALUES FROM (2022, 2, 1) TO (2022, 3, 1); -CREATE TABLE sales_other PARTITION OF sales_date FOR VALUES FROM (2022, 3, 1) TO (MAXVALUE, MAXVALUE, MAXVALUE); -INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES - ('Manager1', 2021, 12, 7), - ('Manager2', 2021, 12, 8), - ('Manager3', 2022, 1, 1), - ('Manager1', 2022, 2, 4), - ('Manager2', 2022, 1, 2), - ('Manager3', 2022, 2, 1), - ('Manager1', 2022, 3, 3), - ('Manager2', 2022, 3, 4), - ('Manager3', 2022, 5, 1); -SELECT tableoid::regclass, * FROM sales_date; - tableoid | salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department ----------------+------------------+------------+-------------+-----------+------------+------------------ - sales_dec2022 | Manager1 | 2021 | 12 | 7 | 2021.12.07 | Sales department - sales_dec2022 | Manager2 | 2021 | 12 | 8 | 2021.12.08 | Sales department - sales_jan2022 | Manager3 | 2022 | 1 | 1 | 2022.01.01 | Sales department - sales_jan2022 | Manager2 | 2022 | 1 | 2 | 2022.01.02 | Sales department - sales_feb2022 | Manager1 | 2022 | 2 | 4 | 2022.02.04 | Sales department - sales_feb2022 | Manager3 | 2022 | 2 | 1 | 2022.02.01 | Sales department - sales_other | Manager1 | 2022 | 3 | 3 | 2022.03.03 | Sales department - sales_other | Manager2 | 2022 | 3 | 4 | 2022.03.04 | Sales department - sales_other | Manager3 | 2022 | 5 | 1 | 2022.05.01 | Sales department -(9 rows) - -ALTER TABLE sales_date MERGE PARTITIONS (sales_jan2022, sales_feb2022) INTO sales_jan_feb2022; -INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES - ('Manager1', 2022, 1, 10), - ('Manager2', 2022, 2, 10); -SELECT tableoid::regclass, * FROM sales_date; - tableoid | salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department --------------------+------------------+------------+-------------+-----------+------------+------------------ - sales_dec2022 | Manager1 | 2021 | 12 | 7 | 2021.12.07 | Sales department - sales_dec2022 | Manager2 | 2021 | 12 | 8 | 2021.12.08 | Sales department - sales_jan_feb2022 | Manager3 | 2022 | 1 | 1 | 2022.01.01 | Sales department - sales_jan_feb2022 | Manager2 | 2022 | 1 | 2 | 2022.01.02 | Sales department - sales_jan_feb2022 | Manager1 | 2022 | 2 | 4 | 2022.02.04 | Sales department - sales_jan_feb2022 | Manager3 | 2022 | 2 | 1 | 2022.02.01 | Sales department - sales_jan_feb2022 | Manager1 | 2022 | 1 | 10 | 2022.01.10 | Sales department - sales_jan_feb2022 | Manager2 | 2022 | 2 | 10 | 2022.02.10 | Sales department - sales_other | Manager1 | 2022 | 3 | 3 | 2022.03.03 | Sales department - sales_other | Manager2 | 2022 | 3 | 4 | 2022.03.04 | Sales department - sales_other | Manager3 | 2022 | 5 | 1 | 2022.05.01 | Sales department -(11 rows) - -DROP TABLE sales_date; --- --- Test: merge partitions of partitioned table with triggers --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); -CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10); -CREATE TABLE salespeople10_20 PARTITION OF salespeople FOR VALUES FROM (10) TO (20); -CREATE TABLE salespeople20_30 PARTITION OF salespeople FOR VALUES FROM (20) TO (30); -CREATE TABLE salespeople30_40 PARTITION OF salespeople FOR VALUES FROM (30) TO (40); -INSERT INTO salespeople VALUES (1, 'Poirot'); -CREATE OR REPLACE FUNCTION after_insert_row_trigger() RETURNS trigger LANGUAGE 'plpgsql' AS $BODY$ -BEGIN - RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; - RETURN NULL; -END; -$BODY$; -CREATE TRIGGER salespeople_after_insert_statement_trigger - AFTER INSERT - ON salespeople - FOR EACH STATEMENT - EXECUTE PROCEDURE after_insert_row_trigger('salespeople'); -CREATE TRIGGER salespeople_after_insert_row_trigger - AFTER INSERT - ON salespeople - FOR EACH ROW - EXECUTE PROCEDURE after_insert_row_trigger('salespeople'); --- 2 triggers should fire here (row + statement): -INSERT INTO salespeople VALUES (10, 'May'); -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = STATEMENT --- 1 trigger should fire here (row): -INSERT INTO salespeople10_20 VALUES (19, 'Ivanov'); -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW -ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40; --- 2 triggers should fire here (row + statement): -INSERT INTO salespeople VALUES (20, 'Smirnoff'); -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = STATEMENT --- 1 trigger should fire here (row): -INSERT INTO salespeople10_40 VALUES (30, 'Ford'); -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW -SELECT * FROM salespeople01_10; - salesperson_id | salesperson_name -----------------+------------------ - 1 | Poirot -(1 row) - -SELECT * FROM salespeople10_40; - salesperson_id | salesperson_name -----------------+------------------ - 10 | May - 19 | Ivanov - 20 | Smirnoff - 30 | Ford -(4 rows) - -DROP TABLE salespeople; -DROP FUNCTION after_insert_row_trigger(); --- --- Test: merge partitions with deleted columns --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); -CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10); --- Create partitions with some deleted columns: -CREATE TABLE salespeople10_20(d1 VARCHAR(30), salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)); -CREATE TABLE salespeople20_30(salesperson_id INT PRIMARY KEY, d2 INT, salesperson_name VARCHAR(30)); -CREATE TABLE salespeople30_40(salesperson_id INT PRIMARY KEY, d3 DATE, salesperson_name VARCHAR(30)); -INSERT INTO salespeople10_20 VALUES ('dummy value 1', 19, 'Ivanov'); -INSERT INTO salespeople20_30 VALUES (20, 101, 'Smirnoff'); -INSERT INTO salespeople30_40 VALUES (31, now(), 'Popov'); -ALTER TABLE salespeople10_20 DROP COLUMN d1; -ALTER TABLE salespeople20_30 DROP COLUMN d2; -ALTER TABLE salespeople30_40 DROP COLUMN d3; -ALTER TABLE salespeople ATTACH PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20); -ALTER TABLE salespeople ATTACH PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30); -ALTER TABLE salespeople ATTACH PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40); -INSERT INTO salespeople VALUES - (1, 'Poirot'), - (10, 'May'), - (30, 'Ford'); -ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40; -select * from salespeople; - salesperson_id | salesperson_name -----------------+------------------ - 1 | Poirot - 19 | Ivanov - 10 | May - 20 | Smirnoff - 31 | Popov - 30 | Ford -(6 rows) - -select * from salespeople01_10; - salesperson_id | salesperson_name -----------------+------------------ - 1 | Poirot -(1 row) - -select * from salespeople10_40; - salesperson_id | salesperson_name -----------------+------------------ - 19 | Ivanov - 10 | May - 20 | Smirnoff - 31 | Popov - 30 | Ford -(5 rows) - -DROP TABLE salespeople; --- --- Test: merge sub-partitions --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'); -CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'); -CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_apr2022_01_10 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'); -CREATE TABLE sales_apr2022_10_20 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-10') TO ('2022-04-20'); -CREATE TABLE sales_apr2022_20_30 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-20') TO ('2022-05-01'); -ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date); -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); -SELECT tableoid::regclass, * FROM sales_apr2022 ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_amount | sales_date ----------------------+----------------+------------------+--------------+------------ - sales_apr2022_01_10 | 5 | Deev | 250 | 04-07-2022 - sales_apr2022_01_10 | 11 | Trump | 380 | 04-06-2022 - sales_apr2022_10_20 | 4 | Ivanov | 750 | 04-13-2022 - sales_apr2022_20_30 | 3 | Ford | 2000 | 04-30-2022 -(4 rows) - -ALTER TABLE sales_apr2022 MERGE PARTITIONS (sales_apr2022_01_10, sales_apr2022_10_20, sales_apr2022_20_30) INTO sales_apr_all; -SELECT tableoid::regclass, * FROM sales_apr2022 ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_amount | sales_date ----------------+----------------+------------------+--------------+------------ - sales_apr_all | 3 | Ford | 2000 | 04-30-2022 - sales_apr_all | 4 | Ivanov | 750 | 04-13-2022 - sales_apr_all | 5 | Deev | 250 | 04-07-2022 - sales_apr_all | 11 | Trump | 380 | 04-06-2022 -(4 rows) - -DROP TABLE sales_range; --- --- BY LIST partitioning --- --- --- Test: specific errors for BY LIST partitioning --- -CREATE TABLE sales_list -(salesperson_id INT GENERATED ALWAYS AS IDENTITY, - salesperson_name VARCHAR(30), - sales_state VARCHAR(20), - sales_amount INT, - sales_date DATE) -PARTITION BY LIST (sales_state); -CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki'); -CREATE TABLE sales_west PARTITION OF sales_list FOR VALUES IN ('Lisbon', 'New York', 'Madrid'); -CREATE TABLE sales_east PARTITION OF sales_list FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'); -CREATE TABLE sales_central PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'); -CREATE TABLE sales_others PARTITION OF sales_list DEFAULT; -CREATE TABLE sales_list2 (LIKE sales_list) PARTITION BY LIST (sales_state); -CREATE TABLE sales_nord2 PARTITION OF sales_list2 FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki'); -CREATE TABLE sales_others2 PARTITION OF sales_list2 DEFAULT; -CREATE TABLE sales_external (LIKE sales_list); -CREATE TABLE sales_external2 (vch VARCHAR(5)); --- ERROR -ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_external) INTO sales_all; -ERROR: "sales_external" is not a partition of partitioned table "sales_list" -HINT: ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions. --- ERROR -ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_external2) INTO sales_all; -ERROR: "sales_external2" is not a partition of partitioned table "sales_list" -HINT: ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions. --- ERROR -ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_nord2, sales_east) INTO sales_all; -ERROR: relation "sales_nord2" is not a partition of relation "sales_list" -HINT: ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions. -DROP TABLE sales_external2; -DROP TABLE sales_external; -DROP TABLE sales_list2; -DROP TABLE sales_list; --- --- Test: BY LIST partitioning, MERGE PARTITIONS with data --- -CREATE TABLE sales_list -(salesperson_id INT GENERATED ALWAYS AS IDENTITY, - salesperson_name VARCHAR(30), - sales_state VARCHAR(20), - sales_amount INT, - sales_date DATE) -PARTITION BY LIST (sales_state); -CREATE INDEX sales_list_salesperson_name_idx ON sales_list USING btree (salesperson_name); -CREATE INDEX sales_list_sales_state_idx ON sales_list USING btree (sales_state); -CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki'); -CREATE TABLE sales_west PARTITION OF sales_list FOR VALUES IN ('Lisbon', 'New York', 'Madrid'); -CREATE TABLE sales_east PARTITION OF sales_list FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'); -CREATE TABLE sales_central PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'); -CREATE TABLE sales_others PARTITION OF sales_list DEFAULT; -INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES - ('Trump', 'Beijing', 1000, '2022-03-01'), - ('Smirnoff', 'New York', 500, '2022-03-03'), - ('Ford', 'St. Petersburg', 2000, '2022-03-05'), - ('Ivanov', 'Warsaw', 750, '2022-03-04'), - ('Deev', 'Lisbon', 250, '2022-03-07'), - ('Poirot', 'Berlin', 1000, '2022-03-01'), - ('May', 'Helsinki', 1200, '2022-03-06'), - ('Li', 'Vladivostok', 1150, '2022-03-09'), - ('May', 'Helsinki', 1200, '2022-03-11'), - ('Halder', 'Oslo', 800, '2022-03-02'), - ('Muller', 'Madrid', 650, '2022-03-05'), - ('Smith', 'Kyiv', 350, '2022-03-10'), - ('Gandi', 'Warsaw', 150, '2022-03-08'), - ('Plato', 'Lisbon', 950, '2022-03-05'); --- show partitions with conditions: -EXECUTE get_partition_info('{sales_list}'); - oid | relpersistence | relkind | inhdetachpending | pg_get_expr ----------------+----------------+---------+------------------+------------------------------------------------------ - sales_central | p | r | f | FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv') - sales_east | p | r | f | FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok') - sales_nord | p | r | f | FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki') - sales_west | p | r | f | FOR VALUES IN ('Lisbon', 'New York', 'Madrid') - sales_others | p | r | f | DEFAULT -(5 rows) - -ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_central) INTO sales_all; --- show partitions with conditions: -EXECUTE get_partition_info('{sales_list}'); - oid | relpersistence | relkind | inhdetachpending | pg_get_expr ---------------+----------------+---------+------------------+--------------------------------------------------------------------------------------------------------------- - sales_all | p | r | f | FOR VALUES IN ('Lisbon', 'New York', 'Madrid', 'Beijing', 'Delhi', 'Vladivostok', 'Warsaw', 'Berlin', 'Kyiv') - sales_nord | p | r | f | FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki') - sales_others | p | r | f | DEFAULT -(3 rows) - -SELECT tableoid::regclass, * FROM sales_list ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_state | sales_amount | sales_date -------------+----------------+------------------+----------------+--------------+------------ - sales_all | 1 | Trump | Beijing | 1000 | 03-01-2022 - sales_all | 2 | Smirnoff | New York | 500 | 03-03-2022 - sales_all | 4 | Ivanov | Warsaw | 750 | 03-04-2022 - sales_all | 5 | Deev | Lisbon | 250 | 03-07-2022 - sales_all | 6 | Poirot | Berlin | 1000 | 03-01-2022 - sales_all | 8 | Li | Vladivostok | 1150 | 03-09-2022 - sales_all | 11 | Muller | Madrid | 650 | 03-05-2022 - sales_all | 12 | Smith | Kyiv | 350 | 03-10-2022 - sales_all | 13 | Gandi | Warsaw | 150 | 03-08-2022 - sales_all | 14 | Plato | Lisbon | 950 | 03-05-2022 - sales_nord | 3 | Ford | St. Petersburg | 2000 | 03-05-2022 - sales_nord | 7 | May | Helsinki | 1200 | 03-06-2022 - sales_nord | 9 | May | Helsinki | 1200 | 03-11-2022 - sales_nord | 10 | Halder | Oslo | 800 | 03-02-2022 -(14 rows) - --- Use indexscan for testing indexes after merging partitions -SET enable_seqscan = OFF; -EXPLAIN (COSTS OFF) SELECT * FROM sales_all WHERE sales_state = 'Warsaw'; - QUERY PLAN ---------------------------------------------------------- - Index Scan using sales_all_sales_state_idx on sales_all - Index Cond: ((sales_state)::text = 'Warsaw'::text) -(2 rows) - -SELECT * FROM sales_all WHERE sales_state = 'Warsaw'; - salesperson_id | salesperson_name | sales_state | sales_amount | sales_date -----------------+------------------+-------------+--------------+------------ - 4 | Ivanov | Warsaw | 750 | 03-04-2022 - 13 | Gandi | Warsaw | 150 | 03-08-2022 -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM sales_list WHERE sales_state = 'Warsaw'; - QUERY PLAN --------------------------------------------------------------------- - Index Scan using sales_all_sales_state_idx on sales_all sales_list - Index Cond: ((sales_state)::text = 'Warsaw'::text) -(2 rows) - -SELECT * FROM sales_list WHERE sales_state = 'Warsaw'; - salesperson_id | salesperson_name | sales_state | sales_amount | sales_date -----------------+------------------+-------------+--------------+------------ - 4 | Ivanov | Warsaw | 750 | 03-04-2022 - 13 | Gandi | Warsaw | 150 | 03-08-2022 -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov'; - QUERY PLAN ---------------------------------------------------------------------------------- - Append - -> Index Scan using sales_all_salesperson_name_idx on sales_all sales_list_1 - Index Cond: ((salesperson_name)::text = 'Ivanov'::text) - -> Bitmap Heap Scan on sales_nord sales_list_2 - Recheck Cond: ((salesperson_name)::text = 'Ivanov'::text) - -> Bitmap Index Scan on sales_nord_salesperson_name_idx - Index Cond: ((salesperson_name)::text = 'Ivanov'::text) - -> Bitmap Heap Scan on sales_others sales_list_3 - Recheck Cond: ((salesperson_name)::text = 'Ivanov'::text) - -> Bitmap Index Scan on sales_others_salesperson_name_idx - Index Cond: ((salesperson_name)::text = 'Ivanov'::text) -(11 rows) - -SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov'; - salesperson_id | salesperson_name | sales_state | sales_amount | sales_date -----------------+------------------+-------------+--------------+------------ - 4 | Ivanov | Warsaw | 750 | 03-04-2022 -(1 row) - -RESET enable_seqscan; -DROP TABLE sales_list; --- --- Try to MERGE partitions of another table. --- -CREATE TABLE t1 (i int, a int, b int, c int) PARTITION BY RANGE (a, b); -CREATE TABLE t1p1 PARTITION OF t1 FOR VALUES FROM (1, 1) TO (1, 2); -CREATE TABLE t2 (i int, t text) PARTITION BY RANGE (t); -CREATE TABLE t2pa PARTITION OF t2 FOR VALUES FROM ('A') TO ('C'); -CREATE TABLE t3 (i int, t text); --- ERROR -ALTER TABLE t2 MERGE PARTITIONS (t1p1, t2pa) INTO t2p; -ERROR: relation "t1p1" is not a partition of relation "t2" -HINT: ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions. --- ERROR -ALTER TABLE t2 MERGE PARTITIONS (t2pa, t3) INTO t2p; -ERROR: "t3" is not a partition of partitioned table "t2" -HINT: ALTER TABLE ... MERGE PARTITIONS can only merge partitions that don't have sub-partitions. -DROP TABLE t3; -DROP TABLE t2; -DROP TABLE t1; --- --- Check the partition index name if the partition name is the same as one --- of the merged partitions. --- -CREATE TABLE t (i int, PRIMARY KEY(i)) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -CREATE INDEX tidx ON t(i); -ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2; --- Indexname values should be 'tp_1_2_pkey' and 'tp_1_2_i_idx'. -\d+ tp_1_2 - Table "partitions_merge_schema.tp_1_2" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - i | integer | | not null | | plain | | -Partition of: t FOR VALUES FROM (0) TO (2) -Partition constraint: ((i IS NOT NULL) AND (i >= 0) AND (i < 2)) -Indexes: - "tp_1_2_pkey" PRIMARY KEY, btree (i) - "tp_1_2_i_idx" btree (i) -Not-null constraints: - "t_i_not_null" NOT NULL "i" (inherited) - -DROP TABLE t; --- --- Try to MERGE partitions of temporary table. --- -BEGIN; -SHOW search_path; - search_path ---------------------------------- - partitions_merge_schema, public -(1 row) - -CREATE TEMP TABLE t (i int) PARTITION BY RANGE (i) ON COMMIT DROP; -CREATE TEMP TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TEMP TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -CREATE TEMP TABLE tp_2_3 PARTITION OF t FOR VALUES FROM (2) TO (3); -CREATE TEMP TABLE tp_3_4 PARTITION OF t FOR VALUES FROM (3) TO (4); -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO pg_temp.tp_0_2; -ALTER TABLE t MERGE PARTITIONS (tp_0_2, tp_2_3) INTO pg_temp.tp_0_3; --- Partition should be temporary. -EXECUTE get_partition_info('{t}'); - oid | relpersistence | relkind | inhdetachpending | pg_get_expr ---------+----------------+---------+------------------+---------------------------- - tp_0_3 | t | r | f | FOR VALUES FROM (0) TO (3) - tp_3_4 | t | r | f | FOR VALUES FROM (3) TO (4) -(2 rows) - --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp_0_3, tp_3_4) INTO tp_0_4; -ERROR: cannot create a permanent relation as partition of temporary relation "t" -ROLLBACK; --- --- Try mixing permanent and temporary partitions. --- -BEGIN; -SET search_path = partitions_merge_schema, pg_temp, public; -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass; - oid | relpersistence ------+---------------- - t | p -(1 row) - -EXECUTE get_partition_info('{t}'); - oid | relpersistence | relkind | inhdetachpending | pg_get_expr ---------+----------------+---------+------------------+---------------------------- - tp_0_1 | p | r | f | FOR VALUES FROM (0) TO (1) - tp_1_2 | p | r | f | FOR VALUES FROM (1) TO (2) -(2 rows) - -SAVEPOINT s; -SET search_path = pg_temp, partitions_merge_schema, public; --- Can't merge persistent partitions into a temporary partition -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -ERROR: cannot create a temporary relation as partition of permanent relation "t" -ROLLBACK TO SAVEPOINT s; -SET search_path = partitions_merge_schema, public; --- Can't merge persistent partitions into a temporary partition -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO pg_temp.tp_0_2; -ERROR: cannot create a temporary relation as partition of permanent relation "t" -ROLLBACK; -BEGIN; -SET search_path = pg_temp, partitions_merge_schema, public; -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass; - oid | relpersistence ------+---------------- - t | t -(1 row) - -EXECUTE get_partition_info('{t}'); - oid | relpersistence | relkind | inhdetachpending | pg_get_expr ---------+----------------+---------+------------------+---------------------------- - tp_0_1 | t | r | f | FOR VALUES FROM (0) TO (1) - tp_1_2 | t | r | f | FOR VALUES FROM (1) TO (2) -(2 rows) - -SET search_path = partitions_merge_schema, pg_temp, public; --- Can't merge temporary partitions into a persistent partition -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -ERROR: cannot create a permanent relation as partition of temporary relation "t" -ROLLBACK; -DEALLOCATE get_partition_info; --- Check the new partition inherits parent's tablespace -SET search_path = partitions_merge_schema, public; -CREATE TABLE t (i int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) - PARTITION BY RANGE (i) TABLESPACE regress_tblspace; -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -SELECT tablename, tablespace FROM pg_tables - WHERE tablename IN ('t', 'tp_0_2') AND schemaname = 'partitions_merge_schema' - ORDER BY tablename COLLATE "C", tablespace COLLATE "C"; - tablename | tablespace ------------+------------------ - t | regress_tblspace - tp_0_2 | regress_tblspace -(2 rows) - -SELECT tablename, indexname, tablespace FROM pg_indexes - WHERE tablename IN ('t', 'tp_0_2') AND schemaname = 'partitions_merge_schema' - ORDER BY tablename COLLATE "C", indexname COLLATE "C", tablespace COLLATE "C"; - tablename | indexname | tablespace ------------+-------------+------------------ - t | t_pkey | regress_tblspace - tp_0_2 | tp_0_2_pkey | regress_tblspace -(2 rows) - -DROP TABLE t; --- Check the new partition inherits parent's table access method -SET search_path = partitions_merge_schema, public; -CREATE ACCESS METHOD partitions_merge_heap TYPE TABLE HANDLER heap_tableam_handler; -CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partitions_merge_heap; -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -SELECT c.relname, a.amname -FROM pg_class c JOIN pg_am a ON c.relam = a.oid -WHERE c.oid IN ('t'::regclass, 'tp_0_2'::regclass) -ORDER BY c.relname COLLATE "C"; - relname | amname ----------+----------------------- - t | partitions_merge_heap - tp_0_2 | partitions_merge_heap -(2 rows) - -DROP TABLE t; -DROP ACCESS METHOD partitions_merge_heap; --- Test permission checks. The user needs to own the parent table and all --- the merging partitions to do the merge. -CREATE ROLE regress_partition_merge_alice; -CREATE ROLE regress_partition_merge_bob; -GRANT ALL ON SCHEMA partitions_merge_schema TO regress_partition_merge_alice; -GRANT ALL ON SCHEMA partitions_merge_schema TO regress_partition_merge_bob; -SET SESSION AUTHORIZATION regress_partition_merge_alice; -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -SET SESSION AUTHORIZATION regress_partition_merge_bob; --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -ERROR: must be owner of table t -RESET SESSION AUTHORIZATION; -ALTER TABLE t OWNER TO regress_partition_merge_bob; -SET SESSION AUTHORIZATION regress_partition_merge_bob; --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -ERROR: must be owner of table tp_0_1 -RESET SESSION AUTHORIZATION; -ALTER TABLE tp_0_1 OWNER TO regress_partition_merge_bob; -SET SESSION AUTHORIZATION regress_partition_merge_bob; --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -ERROR: must be owner of table tp_1_2 -RESET SESSION AUTHORIZATION; -ALTER TABLE tp_1_2 OWNER TO regress_partition_merge_bob; -SET SESSION AUTHORIZATION regress_partition_merge_bob; --- Ok: -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -RESET SESSION AUTHORIZATION; -DROP TABLE t; --- Test: we can't merge partitions with different owners -CREATE TABLE tp_0_1(i int); -ALTER TABLE tp_0_1 OWNER TO regress_partition_merge_alice; -CREATE TABLE tp_1_2(i int); -ALTER TABLE tp_1_2 OWNER TO regress_partition_merge_bob; -CREATE TABLE t (i int) PARTITION BY RANGE (i); -ALTER TABLE t ATTACH PARTITION tp_0_1 FOR VALUES FROM (0) TO (1); -ALTER TABLE t ATTACH PARTITION tp_1_2 FOR VALUES FROM (1) TO (2); --- Owner is 'regress_partition_merge_alice': -\dt tp_0_1 - List of tables - Schema | Name | Type | Owner --------------------------+--------+-------+------------------------------- - partitions_merge_schema | tp_0_1 | table | regress_partition_merge_alice -(1 row) - --- Owner is 'regress_partition_merge_bob': -\dt tp_1_2 - List of tables - Schema | Name | Type | Owner --------------------------+--------+-------+----------------------------- - partitions_merge_schema | tp_1_2 | table | regress_partition_merge_bob -(1 row) - --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -ERROR: partitions being merged have different owners -DROP TABLE t; -REVOKE ALL ON SCHEMA partitions_merge_schema FROM regress_partition_merge_alice; -REVOKE ALL ON SCHEMA partitions_merge_schema FROM regress_partition_merge_bob; -DROP ROLE regress_partition_merge_alice; -DROP ROLE regress_partition_merge_bob; --- Test for hash partitioned table -CREATE TABLE t (i int) PARTITION BY HASH(i); -CREATE TABLE tp1 PARTITION OF t FOR VALUES WITH (MODULUS 2, REMAINDER 0); -CREATE TABLE tp2 PARTITION OF t FOR VALUES WITH (MODULUS 2, REMAINDER 1); --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp1, tp2) INTO tp3; -ERROR: partition of hash-partitioned table cannot be merged --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp1) INTO tp3; -ERROR: list of partitions to be merged should include at least two partitions -DROP TABLE t; --- Test for merged partition properties: --- * STATISTICS is empty --- * COMMENT is empty --- * DEFAULTS are the same as DEFAULTS for partitioned table --- * STORAGE is the same as STORAGE for partitioned table --- * GENERATED and CONSTRAINTS are the same as GENERATED and CONSTRAINTS for partitioned table --- * TRIGGERS are the same as TRIGGERS for partitioned table -\set HIDE_TOAST_COMPRESSION false -CREATE TABLE t -(i int NOT NULL, - t text STORAGE EXTENDED COMPRESSION pglz DEFAULT 'default_t', - b bigint, - d date GENERATED ALWAYS as ('2022-01-01') STORED) PARTITION BY RANGE (abs(i)); -COMMENT ON COLUMN t.i IS 't1.i'; -CREATE TABLE tp_0_1 -(i int NOT NULL, - t text STORAGE MAIN DEFAULT 'default_tp_0_1', - b bigint, - d date GENERATED ALWAYS as ('2022-02-02') STORED); -ALTER TABLE t ATTACH PARTITION tp_0_1 FOR VALUES FROM (0) TO (1); -COMMENT ON COLUMN tp_0_1.i IS 'tp_0_1.i'; -CREATE TABLE tp_1_2 -(i int NOT NULL, - t text STORAGE MAIN DEFAULT 'default_tp_1_2', - b bigint, - d date GENERATED ALWAYS as ('2022-03-03') STORED); -ALTER TABLE t ATTACH PARTITION tp_1_2 FOR VALUES FROM (1) TO (2); -COMMENT ON COLUMN tp_1_2.i IS 'tp_1_2.i'; -CREATE STATISTICS t_stat (DEPENDENCIES) on i, b from t; -CREATE STATISTICS tp_0_1_stat (DEPENDENCIES) on i, b from tp_0_1; -CREATE STATISTICS tp_1_2_stat (DEPENDENCIES) on i, b from tp_1_2; -ALTER TABLE t ADD CONSTRAINT t_b_check CHECK (b > 0); -ALTER TABLE t ADD CONSTRAINT t_b_check1 CHECK (b > 0) NOT ENFORCED; -ALTER TABLE t ADD CONSTRAINT t_b_check2 CHECK (b > 0) NOT VALID; -ALTER TABLE t ADD CONSTRAINT t_b_nn NOT NULL b NOT VALID; -INSERT INTO tp_0_1(i, t, b) VALUES(0, DEFAULT, 1); -INSERT INTO tp_1_2(i, t, b) VALUES(1, DEFAULT, 2); -CREATE OR REPLACE FUNCTION trigger_function() RETURNS trigger LANGUAGE 'plpgsql' AS -$BODY$ -BEGIN - RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; - RETURN new; -END; -$BODY$; -CREATE TRIGGER t_before_insert_row_trigger BEFORE INSERT ON t FOR EACH ROW - EXECUTE PROCEDURE trigger_function('t'); -CREATE TRIGGER tp_0_1_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW - EXECUTE PROCEDURE trigger_function('tp_0_1'); -CREATE TRIGGER tp_1_2_before_insert_row_trigger BEFORE INSERT ON tp_1_2 FOR EACH ROW - EXECUTE PROCEDURE trigger_function('tp_1_2'); -\d+ tp_0_1 - Table "partitions_merge_schema.tp_0_1" - Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description ---------+---------+-----------+----------+-------------------------------------------------+---------+-------------+--------------+------------- - i | integer | | not null | | plain | | | tp_0_1.i - t | text | | | 'default_tp_0_1'::text | main | | | - b | bigint | | not null | | plain | | | - d | date | | | generated always as ('02-02-2022'::date) stored | plain | | | -Partition of: t FOR VALUES FROM (0) TO (1) -Partition constraint: ((abs(i) IS NOT NULL) AND (abs(i) >= 0) AND (abs(i) < 1)) -Check constraints: - "t_b_check" CHECK (b > 0) - "t_b_check1" CHECK (b > 0) NOT ENFORCED - "t_b_check2" CHECK (b > 0) NOT VALID -Statistics objects: - "partitions_merge_schema.tp_0_1_stat" (dependencies) ON i, b FROM tp_0_1 -Not-null constraints: - "tp_0_1_i_not_null" NOT NULL "i" (inherited) - "t_b_nn" NOT NULL "b" (inherited) NOT VALID -Triggers: - t_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW EXECUTE FUNCTION trigger_function('t'), ON TABLE t - tp_0_1_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW EXECUTE FUNCTION trigger_function('tp_0_1') - -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_1; -\d+ tp_0_1 - Table "partitions_merge_schema.tp_0_1" - Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description ---------+---------+-----------+----------+-------------------------------------------------+----------+-------------+--------------+------------- - i | integer | | not null | | plain | | | - t | text | | | 'default_t'::text | extended | pglz | | - b | bigint | | not null | | plain | | | - d | date | | | generated always as ('01-01-2022'::date) stored | plain | | | -Partition of: t FOR VALUES FROM (0) TO (2) -Partition constraint: ((abs(i) IS NOT NULL) AND (abs(i) >= 0) AND (abs(i) < 2)) -Check constraints: - "t_b_check" CHECK (b > 0) - "t_b_check1" CHECK (b > 0) NOT ENFORCED - "t_b_check2" CHECK (b > 0) NOT VALID -Not-null constraints: - "t_i_not_null" NOT NULL "i" (inherited) - "t_b_nn" NOT NULL "b" (inherited) NOT VALID -Triggers: - t_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW EXECUTE FUNCTION trigger_function('t'), ON TABLE t - -INSERT INTO t(i, t, b) VALUES(1, DEFAULT, 3); -NOTICE: trigger(t) called: action = INSERT, when = BEFORE, level = ROW -SELECT tableoid::regclass, * FROM t ORDER BY b; - tableoid | i | t | b | d -----------+---+----------------+---+------------ - tp_0_1 | 0 | default_tp_0_1 | 1 | 01-01-2022 - tp_0_1 | 1 | default_tp_1_2 | 2 | 01-01-2022 - tp_0_1 | 1 | default_t | 3 | 01-01-2022 -(3 rows) - -DROP TABLE t; -DROP FUNCTION trigger_function(); -\set HIDE_TOAST_COMPRESSION true --- Test MERGE PARTITIONS with not valid foreign key constraint -CREATE TABLE t (i INT PRIMARY KEY) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -INSERT INTO t VALUES (0), (1); -CREATE TABLE t_fk (i INT); -INSERT INTO t_fk VALUES (1), (2); -ALTER TABLE t_fk ADD CONSTRAINT t_fk_i_fkey FOREIGN KEY (i) REFERENCES t NOT VALID; -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; --- Should be NOT VALID FOREIGN KEY -\d tp_0_2 - Table "partitions_merge_schema.tp_0_2" - Column | Type | Collation | Nullable | Default ---------+---------+-----------+----------+--------- - i | integer | | not null | -Partition of: t FOR VALUES FROM (0) TO (2) -Indexes: - "tp_0_2_pkey" PRIMARY KEY, btree (i) -Referenced by: - TABLE "t_fk" CONSTRAINT "t_fk_i_fkey" FOREIGN KEY (i) REFERENCES t(i) NOT VALID - --- ERROR -ALTER TABLE t_fk VALIDATE CONSTRAINT t_fk_i_fkey; -ERROR: insert or update on table "t_fk" violates foreign key constraint "t_fk_i_fkey" -DETAIL: Key (i)=(2) is not present in table "t". -DROP TABLE t_fk; -DROP TABLE t; --- Test MERGE PARTITIONS with not enforced foreign key constraint -CREATE TABLE t (i INT PRIMARY KEY) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -INSERT INTO t VALUES (0), (1); -CREATE TABLE t_fk (i INT); -INSERT INTO t_fk VALUES (1), (2); -ALTER TABLE t_fk ADD CONSTRAINT t_fk_i_fkey FOREIGN KEY (i) REFERENCES t NOT ENFORCED; -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; --- Should be NOT ENFORCED FOREIGN KEY -\d tp_0_2 - Table "partitions_merge_schema.tp_0_2" - Column | Type | Collation | Nullable | Default ---------+---------+-----------+----------+--------- - i | integer | | not null | -Partition of: t FOR VALUES FROM (0) TO (2) -Indexes: - "tp_0_2_pkey" PRIMARY KEY, btree (i) -Referenced by: - TABLE "t_fk" CONSTRAINT "t_fk_i_fkey" FOREIGN KEY (i) REFERENCES t(i) NOT ENFORCED - --- ERROR -ALTER TABLE t_fk ALTER CONSTRAINT t_fk_i_fkey ENFORCED; -ERROR: insert or update on table "t_fk" violates foreign key constraint "t_fk_i_fkey" -DETAIL: Key (i)=(2) is not present in table "t". -DROP TABLE t_fk; -DROP TABLE t; --- Test for recomputation of stored generated columns. -CREATE TABLE t (i int, tab_id int generated always as (tableoid) stored) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -ALTER TABLE t ADD CONSTRAINT cc CHECK(tableoid <> 123456789); -INSERT INTO t VALUES (0), (1); --- Should be 0 because partition identifier for row with i=0 is different from --- partition identifier for row with i=1. -SELECT count(*) FROM t WHERE i = 0 AND tab_id IN (SELECT tab_id FROM t WHERE i = 1); - count -------- - 0 -(1 row) - --- "tab_id" column (stored generated column) with "tableoid" attribute requires --- recomputation here. -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; --- Should be 1 because partition identifier for row with i=0 is the same as --- partition identifier for row with i=1. -SELECT count(*) FROM t WHERE i = 0 AND tab_id IN (SELECT tab_id FROM t WHERE i = 1); - count -------- - 1 -(1 row) - -DROP TABLE t; --- Test for generated columns (different order of columns in partitioned table --- and partitions). -CREATE TABLE t (i int, g int GENERATED ALWAYS AS (i + tableoid::int)) PARTITION BY RANGE (i); -CREATE TABLE tp_1 (g int GENERATED ALWAYS AS (i + tableoid::int), i int); -CREATE TABLE tp_2 (g int GENERATED ALWAYS AS (i + tableoid::int), i int); -ALTER TABLE t ATTACH PARTITION tp_1 FOR VALUES FROM (-1) TO (10); -ALTER TABLE t ATTACH PARTITION tp_2 FOR VALUES FROM (10) TO (20); -ALTER TABLE t ADD CHECK (g > 0); -ALTER TABLE t ADD CHECK (i > 0); -INSERT INTO t VALUES (5), (15); -ALTER TABLE t MERGE PARTITIONS (tp_1, tp_2) INTO tp_12; -INSERT INTO t VALUES (16); --- ERROR -INSERT INTO t VALUES (0); -ERROR: new row for relation "tp_12" violates check constraint "t_i_check" -DETAIL: Failing row contains (0, virtual). --- Should be 3 rows: (5), (15), (16): -SELECT i FROM t ORDER BY i; - i ----- - 5 - 15 - 16 -(3 rows) - --- Should be 1 because for the same tableoid (15 + tableoid) = (5 + tableoid) + 10: -SELECT count(*) FROM t WHERE i = 15 AND g IN (SELECT g + 10 FROM t WHERE i = 5); - count -------- - 1 -(1 row) - -DROP TABLE t; --- A merged partition needs its own TOAST table; otherwise an out-of-line --- varlena value carried over from one of the merging partitions has --- nowhere to be stored. SET STORAGE EXTERNAL forces externalization --- for any value over the TOAST threshold, so a string over that threshold --- suffices to exercise the toast-table dependency. -CREATE TABLE t (a text) PARTITION BY RANGE(a); -ALTER TABLE t ALTER COLUMN a SET STORAGE EXTERNAL; -CREATE TABLE tp_def PARTITION OF t DEFAULT; -CREATE TABLE tp_2_3 PARTITION OF t FOR VALUES FROM ('2') TO ('3'); -INSERT INTO t SELECT repeat('1', 10000); -ALTER TABLE t MERGE PARTITIONS (tp_def, tp_2_3) INTO tp_merged; -SELECT reltoastrelid <> 0 AS has_toast, - pg_relation_size(reltoastrelid) > 0 AS toast_used - FROM pg_class WHERE relname = 'tp_merged'; - has_toast | toast_used ------------+------------ - t | t -(1 row) - -SELECT length(a) FROM t; - length --------- - 10000 -(1 row) - -DROP TABLE t; --- Tablespace selection for the new merged partition mirrors --- CREATE TABLE ... PARTITION OF: the partitioned root's explicit --- tablespace wins; otherwise default_tablespace applies; otherwise the --- database default is used. -CREATE TABLE t (i int) PARTITION BY RANGE(i) TABLESPACE regress_tblspace; -CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); -CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); -INSERT INTO t SELECT generate_series(0, 9); -ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; -SELECT spcname FROM pg_class c LEFT JOIN pg_tablespace s - ON c.reltablespace = s.oid WHERE c.relname = 'tp_merged'; - spcname ------------------- - regress_tblspace -(1 row) - -DROP TABLE t; --- Parent has no explicit tablespace, but default_tablespace is set: the --- new partition lands on default_tablespace. -CREATE TABLE t (i int) PARTITION BY RANGE(i); -CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); -CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); -INSERT INTO t SELECT generate_series(0, 9); -SET default_tablespace TO regress_tblspace; -ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; -RESET default_tablespace; -SELECT spcname FROM pg_class c LEFT JOIN pg_tablespace s - ON c.reltablespace = s.oid WHERE c.relname = 'tp_merged'; - spcname ------------------- - regress_tblspace -(1 row) - -DROP TABLE t; -CREATE TABLE t (i int) PARTITION BY RANGE(i); -CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); -CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); -INSERT INTO t SELECT generate_series(0, 9); --- pg_global is rejected when picked up from default_tablespace. -SET default_tablespace TO pg_global; -ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; -- fails -ERROR: only shared relations can be placed in pg_global tablespace -RESET default_tablespace; --- Parent has no explicit tablespace and default_tablespace is empty: the --- new partition uses the database default (reltablespace = 0). -ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; -SELECT reltablespace FROM pg_class WHERE relname = 'tp_merged'; - reltablespace ---------------- - 0 -(1 row) - -DROP TABLE t; -RESET search_path; --- -DROP SCHEMA partitions_merge_schema; -DROP SCHEMA partitions_merge_schema2; diff --git a/src/test/regress/expected/partition_split.out b/src/test/regress/expected/partition_split.out deleted file mode 100644 index 089f89ed6ac..00000000000 --- a/src/test/regress/expected/partition_split.out +++ /dev/null @@ -1,1758 +0,0 @@ --- --- PARTITION_SPLIT --- Tests for "ALTER TABLE ... SPLIT PARTITION ..." command --- -CREATE SCHEMA partition_split_schema; -CREATE SCHEMA partition_split_schema2; -SET search_path = partition_split_schema, public; --- --- BY RANGE partitioning --- --- --- Test for error codes --- -CREATE TABLE sales_range (salesperson_id int, sales_date date) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_xxx INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: relation "sales_xxx" does not exist --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_jan2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: relation "sales_jan2022" already exists --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_jan2022 FOR VALUES IN ('2022-05-01', '2022-06-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: invalid bound specification for a range partition -LINE 2: (PARTITION sales_jan2022 FOR VALUES IN ('2022-05-01', '202... - ^ --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-02-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: empty range bound specified for partition "sales_mar2022" -LINE 3: PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO... - ^ -DETAIL: Specified lower bound ('03-01-2022') is greater than or equal to upper bound ('02-01-2022'). --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-10-01')); -ERROR: list of new partitions must contain at least two partitions --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-01-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: lower bound of partition "sales_feb2022" is not equal to lower bound of split partition "sales_feb_mar_apr2022" -LINE 2: (PARTITION sales_feb2022 FOR VALUES FROM ('2022-01-01') TO... - ^ -HINT: ALTER TABLE ... SPLIT PARTITION requires the combined bounds of the new partitions to exactly match the bound of the split partition. --- ERROR --- (We can create partition with the same name as split partition, but can't create two partitions with the same name) -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb_mar_apr2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_feb_mar_apr2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: partition with name "sales_feb_mar_apr2022" is already used -LINE 3: PARTITION sales_feb_mar_apr2022 FOR VALUES FROM ('2022-03... - ^ --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: partition with name "sales_feb2022" is already used -LINE 3: PARTITION sales_feb2022 FOR VALUES FROM ('2022-03-01') TO... - ^ --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION partition_split_schema.sales_feb2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: partition with name "sales_feb2022" is already used -LINE 3: PARTITION partition_split_schema.sales_feb2022 FOR VALUES... - ^ --- ERROR -ALTER TABLE sales_feb_mar_apr2022 SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_jan2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: ALTER action SPLIT PARTITION cannot be performed on relation "sales_feb_mar_apr2022" -DETAIL: This operation is not supported for tables. --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-01')); -ERROR: upper bound of partition "sales_apr2022" is not equal to upper bound of split partition "sales_feb_mar_apr2022" -LINE 4: ... sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-0... - ^ -HINT: ALTER TABLE ... SPLIT PARTITION requires the combined bounds of the new partitions to exactly match the bound of the split partition. --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-02-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: cannot split to partition "sales_mar2022" together with partition "sales_feb2022" -LINE 3: PARTITION sales_mar2022 FOR VALUES FROM ('2022-02-01') TO... - ^ -DETAIL: The lower bound of partition "sales_mar2022" is not equal to the upper bound of partition "sales_feb2022". -HINT: ALTER TABLE ... SPLIT PARTITION requires the partition bounds to be adjacent. --- Tests for spaces between partitions, them should be executed without DEFAULT partition -ALTER TABLE sales_range DETACH PARTITION sales_others; --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-02') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -ERROR: lower bound of partition "sales_feb2022" is not equal to lower bound of split partition "sales_feb_mar_apr2022" -LINE 2: (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-02') TO... - ^ -HINT: ALTER TABLE ... SPLIT PARTITION requires the combined bounds of the new partitions to exactly match the bound of the split partition. --- Check the source partition not in the search path -SET search_path = partition_split_schema2, public; -ALTER TABLE partition_split_schema.sales_range -SPLIT PARTITION partition_split_schema.sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -SET search_path = partition_split_schema, public; -\d+ sales_range - Partitioned table "partition_split_schema.sales_range" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description -----------------+---------+-----------+----------+---------+---------+--------------+------------- - salesperson_id | integer | | | | plain | | - sales_date | date | | | | plain | | -Partition key: RANGE (sales_date) -Partitions: - partition_split_schema2.sales_apr2022 FOR VALUES FROM ('04-01-2022') TO ('05-01-2022') - partition_split_schema2.sales_feb2022 FOR VALUES FROM ('02-01-2022') TO ('03-01-2022') - partition_split_schema2.sales_mar2022 FOR VALUES FROM ('03-01-2022') TO ('04-01-2022') - sales_jan2022 FOR VALUES FROM ('01-01-2022') TO ('02-01-2022') - -DROP TABLE sales_range; -DROP TABLE sales_others; --- Additional tests for error messages, no default partition -CREATE TABLE sales_range (sales_date date) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-01')); -ERROR: upper bound of partition "sales_apr2022" is not equal to upper bound of split partition "sales_feb_mar_apr2022" -LINE 4: ... sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-0... - ^ -HINT: ALTER TABLE ... SPLIT PARTITION requires the combined bounds of the new partitions to exactly match the bound of the split partition. -DROP TABLE sales_range; --- --- Add rows into partitioned table then split partition --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_amount | sales_date ----------------+----------------+------------------+--------------+------------ - sales_apr2022 | 3 | Ford | 2000 | 04-30-2022 - sales_apr2022 | 4 | Ivanov | 750 | 04-13-2022 - sales_apr2022 | 5 | Deev | 250 | 04-07-2022 - sales_apr2022 | 11 | Trump | 380 | 04-06-2022 - sales_feb2022 | 2 | Smirnoff | 500 | 02-10-2022 - sales_feb2022 | 6 | Poirot | 150 | 02-11-2022 - sales_feb2022 | 8 | Ericsson | 185 | 02-23-2022 - sales_jan2022 | 1 | May | 1000 | 01-31-2022 - sales_jan2022 | 10 | Halder | 350 | 01-28-2022 - sales_jan2022 | 13 | Gandi | 377 | 01-09-2022 - sales_mar2022 | 7 | Li | 175 | 03-08-2022 - sales_mar2022 | 9 | Muller | 250 | 03-11-2022 - sales_mar2022 | 12 | Plato | 350 | 03-19-2022 - sales_others | 14 | Smith | 510 | 05-04-2022 -(14 rows) - -DROP TABLE sales_range CASCADE; --- --- Add split partition, then add rows into partitioned table --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); --- Split partition, also check schema qualification of new partitions -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION partition_split_schema.sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION partition_split_schema2.sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -\d+ sales_range - Partitioned table "partition_split_schema.sales_range" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description -------------------+-----------------------+-----------+----------+---------+----------+--------------+------------- - salesperson_id | integer | | | | plain | | - salesperson_name | character varying(30) | | | | extended | | - sales_amount | integer | | | | plain | | - sales_date | date | | | | plain | | -Partition key: RANGE (sales_date) -Partitions: - partition_split_schema2.sales_mar2022 FOR VALUES FROM ('03-01-2022') TO ('04-01-2022') - sales_apr2022 FOR VALUES FROM ('04-01-2022') TO ('05-01-2022') - sales_feb2022 FOR VALUES FROM ('02-01-2022') TO ('03-01-2022') - sales_jan2022 FOR VALUES FROM ('01-01-2022') TO ('02-01-2022') - sales_others DEFAULT - -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_amount | sales_date ----------------------------------------+----------------+------------------+--------------+------------ - partition_split_schema2.sales_mar2022 | 7 | Li | 175 | 03-08-2022 - partition_split_schema2.sales_mar2022 | 9 | Muller | 250 | 03-11-2022 - partition_split_schema2.sales_mar2022 | 12 | Plato | 350 | 03-19-2022 - sales_apr2022 | 3 | Ford | 2000 | 04-30-2022 - sales_apr2022 | 4 | Ivanov | 750 | 04-13-2022 - sales_apr2022 | 5 | Deev | 250 | 04-07-2022 - sales_apr2022 | 11 | Trump | 380 | 04-06-2022 - sales_feb2022 | 2 | Smirnoff | 500 | 02-10-2022 - sales_feb2022 | 6 | Poirot | 150 | 02-11-2022 - sales_feb2022 | 8 | Ericsson | 185 | 02-23-2022 - sales_jan2022 | 1 | May | 1000 | 01-31-2022 - sales_jan2022 | 10 | Halder | 350 | 01-28-2022 - sales_jan2022 | 13 | Gandi | 377 | 01-09-2022 - sales_others | 14 | Smith | 510 | 05-04-2022 -(14 rows) - -DROP TABLE sales_range CASCADE; --- --- Test for: --- * composite partition key; --- * GENERATED column; --- * column with DEFAULT value. --- -CREATE TABLE sales_date (salesperson_name VARCHAR(30), sales_year INT, sales_month INT, sales_day INT, - sales_date VARCHAR(10) GENERATED ALWAYS AS - (LPAD(sales_year::text, 4, '0') || '.' || LPAD(sales_month::text, 2, '0') || '.' || LPAD(sales_day::text, 2, '0')) STORED, - sales_department VARCHAR(30) DEFAULT 'Sales department') - PARTITION BY RANGE (sales_year, sales_month, sales_day); -CREATE TABLE sales_dec2021 PARTITION OF sales_date FOR VALUES FROM (2021, 12, 1) TO (2022, 1, 1); -CREATE TABLE sales_jan_feb2022 PARTITION OF sales_date FOR VALUES FROM (2022, 1, 1) TO (2022, 3, 1); -CREATE TABLE sales_other PARTITION OF sales_date FOR VALUES FROM (2022, 3, 1) TO (MAXVALUE, MAXVALUE, MAXVALUE); -INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES - ('Manager1', 2021, 12, 7), - ('Manager2', 2021, 12, 8), - ('Manager3', 2022, 1, 1), - ('Manager1', 2022, 2, 4), - ('Manager2', 2022, 1, 2), - ('Manager3', 2022, 2, 1), - ('Manager1', 2022, 3, 3), - ('Manager2', 2022, 3, 4), - ('Manager3', 2022, 5, 1); -SELECT tableoid::regclass, * FROM sales_date ORDER BY tableoid::regclass::text COLLATE "C", sales_year, sales_month, sales_day; - tableoid | salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department --------------------+------------------+------------+-------------+-----------+------------+------------------ - sales_dec2021 | Manager1 | 2021 | 12 | 7 | 2021.12.07 | Sales department - sales_dec2021 | Manager2 | 2021 | 12 | 8 | 2021.12.08 | Sales department - sales_jan_feb2022 | Manager3 | 2022 | 1 | 1 | 2022.01.01 | Sales department - sales_jan_feb2022 | Manager2 | 2022 | 1 | 2 | 2022.01.02 | Sales department - sales_jan_feb2022 | Manager3 | 2022 | 2 | 1 | 2022.02.01 | Sales department - sales_jan_feb2022 | Manager1 | 2022 | 2 | 4 | 2022.02.04 | Sales department - sales_other | Manager1 | 2022 | 3 | 3 | 2022.03.03 | Sales department - sales_other | Manager2 | 2022 | 3 | 4 | 2022.03.04 | Sales department - sales_other | Manager3 | 2022 | 5 | 1 | 2022.05.01 | Sales department -(9 rows) - -ALTER TABLE sales_date SPLIT PARTITION sales_jan_feb2022 INTO - (PARTITION sales_jan2022 FOR VALUES FROM (2022, 1, 1) TO (2022, 2, 1), - PARTITION sales_feb2022 FOR VALUES FROM (2022, 2, 1) TO (2022, 3, 1)); -INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES - ('Manager1', 2022, 1, 10), - ('Manager2', 2022, 2, 10); -SELECT tableoid::regclass, * FROM sales_date ORDER BY tableoid::regclass::text COLLATE "C", sales_year, sales_month, sales_day; - tableoid | salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department ----------------+------------------+------------+-------------+-----------+------------+------------------ - sales_dec2021 | Manager1 | 2021 | 12 | 7 | 2021.12.07 | Sales department - sales_dec2021 | Manager2 | 2021 | 12 | 8 | 2021.12.08 | Sales department - sales_feb2022 | Manager3 | 2022 | 2 | 1 | 2022.02.01 | Sales department - sales_feb2022 | Manager1 | 2022 | 2 | 4 | 2022.02.04 | Sales department - sales_feb2022 | Manager2 | 2022 | 2 | 10 | 2022.02.10 | Sales department - sales_jan2022 | Manager3 | 2022 | 1 | 1 | 2022.01.01 | Sales department - sales_jan2022 | Manager2 | 2022 | 1 | 2 | 2022.01.02 | Sales department - sales_jan2022 | Manager1 | 2022 | 1 | 10 | 2022.01.10 | Sales department - sales_other | Manager1 | 2022 | 3 | 3 | 2022.03.03 | Sales department - sales_other | Manager2 | 2022 | 3 | 4 | 2022.03.04 | Sales department - sales_other | Manager3 | 2022 | 5 | 1 | 2022.05.01 | Sales department -(11 rows) - -DROP TABLE sales_date CASCADE; --- --- Test: split DEFAULT partition; use an index on partition key; check index after split --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date); -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); -SELECT * FROM sales_others; - salesperson_id | salesperson_name | sales_amount | sales_date -----------------+------------------+--------------+------------ - 2 | Smirnoff | 500 | 02-10-2022 - 3 | Ford | 2000 | 04-30-2022 - 4 | Ivanov | 750 | 04-13-2022 - 5 | Deev | 250 | 04-07-2022 - 6 | Poirot | 150 | 02-11-2022 - 7 | Li | 175 | 03-08-2022 - 8 | Ericsson | 185 | 02-23-2022 - 9 | Muller | 250 | 03-11-2022 - 11 | Trump | 380 | 04-06-2022 - 12 | Plato | 350 | 03-19-2022 - 14 | Smith | 510 | 05-04-2022 -(11 rows) - -SELECT * FROM pg_indexes WHERE tablename = 'sales_others' and schemaname = 'partition_split_schema' ORDER BY indexname COLLATE "C"; - schemaname | tablename | indexname | tablespace | indexdef -------------------------+--------------+-----------------------------+------------+---------------------------------------------------------------------------------------------------------- - partition_split_schema | sales_others | sales_others_sales_date_idx | | CREATE INDEX sales_others_sales_date_idx ON partition_split_schema.sales_others USING btree (sales_date) -(1 row) - -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'), - PARTITION sales_others DEFAULT); --- Use indexscan for testing indexes -SET enable_seqscan = OFF; -EXPLAIN (COSTS OFF) SELECT * FROM sales_feb2022 where sales_date > '2022-01-01'; - QUERY PLAN ----------------------------------------------------------------- - Index Scan using sales_feb2022_sales_date_idx on sales_feb2022 - Index Cond: (sales_date > '01-01-2022'::date) -(2 rows) - -SELECT * FROM sales_feb2022 where sales_date > '2022-01-01'; - salesperson_id | salesperson_name | sales_amount | sales_date -----------------+------------------+--------------+------------ - 2 | Smirnoff | 500 | 02-10-2022 - 6 | Poirot | 150 | 02-11-2022 - 8 | Ericsson | 185 | 02-23-2022 -(3 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM sales_mar2022 where sales_date > '2022-01-01'; - QUERY PLAN ----------------------------------------------------------------- - Index Scan using sales_mar2022_sales_date_idx on sales_mar2022 - Index Cond: (sales_date > '01-01-2022'::date) -(2 rows) - -SELECT * FROM sales_mar2022 where sales_date > '2022-01-01'; - salesperson_id | salesperson_name | sales_amount | sales_date -----------------+------------------+--------------+------------ - 7 | Li | 175 | 03-08-2022 - 9 | Muller | 250 | 03-11-2022 - 12 | Plato | 350 | 03-19-2022 -(3 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM sales_apr2022 where sales_date > '2022-01-01'; - QUERY PLAN ----------------------------------------------------------------- - Index Scan using sales_apr2022_sales_date_idx on sales_apr2022 - Index Cond: (sales_date > '01-01-2022'::date) -(2 rows) - -SELECT * FROM sales_apr2022 where sales_date > '2022-01-01'; - salesperson_id | salesperson_name | sales_amount | sales_date -----------------+------------------+--------------+------------ - 11 | Trump | 380 | 04-06-2022 - 5 | Deev | 250 | 04-07-2022 - 4 | Ivanov | 750 | 04-13-2022 - 3 | Ford | 2000 | 04-30-2022 -(4 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM sales_others where sales_date > '2022-01-01'; - QUERY PLAN ---------------------------------------------------------------- - Index Scan using sales_others_sales_date_idx1 on sales_others - Index Cond: (sales_date > '01-01-2022'::date) -(2 rows) - -SELECT * FROM sales_others where sales_date > '2022-01-01'; - salesperson_id | salesperson_name | sales_amount | sales_date -----------------+------------------+--------------+------------ - 14 | Smith | 510 | 05-04-2022 -(1 row) - -RESET enable_seqscan; -SELECT * FROM pg_indexes -WHERE tablename in ('sales_feb2022', 'sales_mar2022', 'sales_apr2022', 'sales_others') -AND schemaname = 'partition_split_schema' -ORDER BY indexname COLLATE "C"; - schemaname | tablename | indexname | tablespace | indexdef -------------------------+---------------+------------------------------+------------+------------------------------------------------------------------------------------------------------------ - partition_split_schema | sales_apr2022 | sales_apr2022_sales_date_idx | | CREATE INDEX sales_apr2022_sales_date_idx ON partition_split_schema.sales_apr2022 USING btree (sales_date) - partition_split_schema | sales_feb2022 | sales_feb2022_sales_date_idx | | CREATE INDEX sales_feb2022_sales_date_idx ON partition_split_schema.sales_feb2022 USING btree (sales_date) - partition_split_schema | sales_mar2022 | sales_mar2022_sales_date_idx | | CREATE INDEX sales_mar2022_sales_date_idx ON partition_split_schema.sales_mar2022 USING btree (sales_date) - partition_split_schema | sales_others | sales_others_sales_date_idx1 | | CREATE INDEX sales_others_sales_date_idx1 ON partition_split_schema.sales_others USING btree (sales_date) -(4 rows) - -DROP TABLE sales_range CASCADE; --- --- Test: some cases for splitting DEFAULT partition (different bounds) --- -CREATE TABLE sales_range (salesperson_id INT, sales_date date) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; --- sales_error intersects with sales_dec2021 (lower bound) --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_error FOR VALUES FROM ('2021-12-30') TO ('2022-02-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); -ERROR: cannot split to partition "sales_error" together with partition "sales_dec2021" -LINE 3: PARTITION sales_error FOR VALUES FROM ('2021-12-30') TO (... - ^ -DETAIL: The lower bound of partition "sales_error" is not equal to the upper bound of partition "sales_dec2021". -HINT: ALTER TABLE ... SPLIT PARTITION requires the partition bounds to be adjacent. --- sales_error intersects with sales_feb2022 (upper bound) --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_error FOR VALUES FROM ('2022-01-01') TO ('2022-02-02'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); -ERROR: cannot split to partition "sales_feb2022" together with partition "sales_error" -LINE 4: PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO... - ^ -DETAIL: The lower bound of partition "sales_feb2022" is not equal to the upper bound of partition "sales_error". -HINT: ALTER TABLE ... SPLIT PARTITION requires the partition bounds to be adjacent. --- sales_error intersects with sales_dec2021 (inside bound) --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_error FOR VALUES FROM ('2021-12-10') TO ('2021-12-20'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); -ERROR: cannot split to partition "sales_error" together with partition "sales_dec2021" -LINE 3: PARTITION sales_error FOR VALUES FROM ('2021-12-10') TO (... - ^ -DETAIL: The lower bound of partition "sales_error" is not equal to the upper bound of partition "sales_dec2021". -HINT: ALTER TABLE ... SPLIT PARTITION requires the partition bounds to be adjacent. --- sales_error intersects with sales_dec2021 (exactly the same bounds) --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_error FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); -ERROR: cannot split to partition "sales_error" together with partition "sales_dec2021" -LINE 3: PARTITION sales_error FOR VALUES FROM ('2021-12-01') TO (... - ^ -DETAIL: The lower bound of partition "sales_error" is not equal to the upper bound of partition "sales_dec2021". -HINT: ALTER TABLE ... SPLIT PARTITION requires the partition bounds to be adjacent. --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_jan2022 FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01')); -ERROR: cannot split DEFAULT partition "sales_others" -HINT: To split a DEFAULT partition, one of the new partitions must be DEFAULT. --- no error: bounds of sales_noerror are between sales_dec2021 and sales_feb2022 -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_noerror FOR VALUES FROM ('2022-01-10') TO ('2022-01-20'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); -DROP TABLE sales_range; -CREATE TABLE sales_range (sales_date date) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; --- no error: bounds of sales_noerror are equal to lower and upper bounds of sales_dec2021 and sales_feb2022 -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_noerror FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); -DROP TABLE sales_range; --- --- Test: split partition with CHECK and FOREIGN KEY CONSTRAINTs on partitioned table --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)); -INSERT INTO salespeople VALUES (1, 'Poirot'); -CREATE TABLE sales_range ( -salesperson_id INT REFERENCES salespeople(salesperson_id), -sales_amount INT CHECK (sales_amount > 1), -sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_feb_mar_apr2022'::regclass::oid ORDER BY conname COLLATE "C"; - pg_get_constraintdef | conname | conkey ----------------------------------------------------------------------+---------------------------------+-------- - CHECK ((sales_amount > 1)) | sales_range_sales_amount_check | {2} - FOREIGN KEY (salesperson_id) REFERENCES salespeople(salesperson_id) | sales_range_salesperson_id_fkey | {1} -(2 rows) - -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); --- We should see the same CONSTRAINTs as on sales_feb_mar_apr2022 partition -SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_feb2022'::regclass::oid ORDER BY conname COLLATE "C"; - pg_get_constraintdef | conname | conkey ----------------------------------------------------------------------+---------------------------------+-------- - CHECK ((sales_amount > 1)) | sales_range_sales_amount_check | {2} - FOREIGN KEY (salesperson_id) REFERENCES salespeople(salesperson_id) | sales_range_salesperson_id_fkey | {1} -(2 rows) - -SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_mar2022'::regclass::oid ORDER BY conname COLLATE "C"; - pg_get_constraintdef | conname | conkey ----------------------------------------------------------------------+---------------------------------+-------- - CHECK ((sales_amount > 1)) | sales_range_sales_amount_check | {2} - FOREIGN KEY (salesperson_id) REFERENCES salespeople(salesperson_id) | sales_range_salesperson_id_fkey | {1} -(2 rows) - -SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_apr2022'::regclass::oid ORDER BY conname COLLATE "C"; - pg_get_constraintdef | conname | conkey ----------------------------------------------------------------------+---------------------------------+-------- - CHECK ((sales_amount > 1)) | sales_range_sales_amount_check | {2} - FOREIGN KEY (salesperson_id) REFERENCES salespeople(salesperson_id) | sales_range_salesperson_id_fkey | {1} -(2 rows) - --- ERROR -INSERT INTO sales_range VALUES (1, 0, '2022-03-11'); -ERROR: new row for relation "sales_mar2022" violates check constraint "sales_range_sales_amount_check" -DETAIL: Failing row contains (1, 0, 03-11-2022). --- ERROR -INSERT INTO sales_range VALUES (-1, 10, '2022-03-11'); -ERROR: insert or update on table "sales_mar2022" violates foreign key constraint "sales_range_salesperson_id_fkey" -DETAIL: Key (salesperson_id)=(-1) is not present in table "salespeople". --- ok -INSERT INTO sales_range VALUES (1, 10, '2022-03-11'); -DROP TABLE sales_range CASCADE; -DROP TABLE salespeople CASCADE; --- --- Test: split partition on partitioned table in case of existing FOREIGN KEY reference from another table --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); -CREATE TABLE sales (salesperson_id INT REFERENCES salespeople(salesperson_id), sales_amount INT, sales_date DATE); -CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10); -CREATE TABLE salespeople10_40 PARTITION OF salespeople FOR VALUES FROM (10) TO (40); -INSERT INTO salespeople VALUES - (1, 'Poirot'), - (10, 'May'), - (19, 'Ivanov'), - (20, 'Smirnoff'), - (30, 'Ford'); -INSERT INTO sales VALUES - (1, 100, '2022-03-01'), - (1, 110, '2022-03-02'), - (10, 150, '2022-03-01'), - (10, 90, '2022-03-03'), - (19, 200, '2022-03-04'), - (20, 50, '2022-03-12'), - (20, 170, '2022-03-02'), - (30, 30, '2022-03-04'); -SELECT tableoid::regclass, * FROM salespeople ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name -------------------+----------------+------------------ - salespeople01_10 | 1 | Poirot - salespeople10_40 | 10 | May - salespeople10_40 | 19 | Ivanov - salespeople10_40 | 20 | Smirnoff - salespeople10_40 | 30 | Ford -(5 rows) - -ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO - (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20), - PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30), - PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40)); -SELECT tableoid::regclass, * FROM salespeople ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name -------------------+----------------+------------------ - salespeople01_10 | 1 | Poirot - salespeople10_20 | 10 | May - salespeople10_20 | 19 | Ivanov - salespeople20_30 | 20 | Smirnoff - salespeople30_40 | 30 | Ford -(5 rows) - --- ERROR -INSERT INTO sales VALUES (40, 50, '2022-03-04'); -ERROR: insert or update on table "sales" violates foreign key constraint "sales_salesperson_id_fkey" -DETAIL: Key (salesperson_id)=(40) is not present in table "salespeople". --- ok -INSERT INTO sales VALUES (30, 50, '2022-03-04'); -DROP TABLE sales CASCADE; -DROP TABLE salespeople CASCADE; --- --- Test: split partition of partitioned table with triggers --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); -CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10); -CREATE TABLE salespeople10_40 PARTITION OF salespeople FOR VALUES FROM (10) TO (40); -INSERT INTO salespeople VALUES (1, 'Poirot'); -CREATE OR REPLACE FUNCTION after_insert_row_trigger() RETURNS trigger LANGUAGE 'plpgsql' AS $BODY$ -BEGIN - RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; - RETURN NULL; -END; -$BODY$; -CREATE TRIGGER salespeople_after_insert_statement_trigger - AFTER INSERT - ON salespeople - FOR EACH STATEMENT - EXECUTE PROCEDURE after_insert_row_trigger('salespeople'); -CREATE TRIGGER salespeople_after_insert_row_trigger - AFTER INSERT - ON salespeople - FOR EACH ROW - EXECUTE PROCEDURE after_insert_row_trigger('salespeople'); --- 2 triggers should fire here (row + statement): -INSERT INTO salespeople VALUES (10, 'May'); -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = STATEMENT --- 1 trigger should fire here (row): -INSERT INTO salespeople10_40 VALUES (19, 'Ivanov'); -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW -ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO - (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20), - PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30), - PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40)); --- 2 triggers should fire here (row + statement): -INSERT INTO salespeople VALUES (20, 'Smirnoff'); -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = STATEMENT --- 1 trigger should fire here (row): -INSERT INTO salespeople30_40 VALUES (30, 'Ford'); -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW -SELECT tableoid::regclass, * FROM salespeople ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name -------------------+----------------+------------------ - salespeople01_10 | 1 | Poirot - salespeople10_20 | 10 | May - salespeople10_20 | 19 | Ivanov - salespeople20_30 | 20 | Smirnoff - salespeople30_40 | 30 | Ford -(5 rows) - -DROP TABLE salespeople CASCADE; -DROP FUNCTION after_insert_row_trigger(); --- --- Test: split partition witch identity column --- If split partition column is identity column, columns of new partitions are identity columns too. --- -CREATE TABLE salespeople(salesperson_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); -CREATE TABLE salespeople1_2 PARTITION OF salespeople FOR VALUES FROM (1) TO (2); --- Create new partition with identity column: -CREATE TABLE salespeople2_5(salesperson_id INT NOT NULL, salesperson_name VARCHAR(30)); -ALTER TABLE salespeople ATTACH PARTITION salespeople2_5 FOR VALUES FROM (2) TO (5); -INSERT INTO salespeople (salesperson_name) VALUES ('Poirot'), ('Ivanov'); -ALTER TABLE salespeople SPLIT PARTITION salespeople2_5 INTO - (PARTITION salespeople2_3 FOR VALUES FROM (2) TO (3), - PARTITION salespeople3_4 FOR VALUES FROM (3) TO (4), - PARTITION salespeople4_5 FOR VALUES FROM (4) TO (5)); -INSERT INTO salespeople (salesperson_name) VALUES ('May'), ('Ford'); -SELECT tableoid::regclass, * FROM salespeople ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name -----------------+----------------+------------------ - salespeople1_2 | 1 | Poirot - salespeople2_3 | 2 | Ivanov - salespeople3_4 | 3 | May - salespeople4_5 | 4 | Ford -(4 rows) - --- check new partitions have identity or not after split partition -SELECT attrelid::regclass, attname, attidentity, attgenerated FROM pg_attribute -WHERE attnum > 0 -AND attrelid::regclass IN ( - 'salespeople2_3'::regclass, 'salespeople', 'salespeople2_3', - 'salespeople1_2', 'salespeople3_4', 'salespeople4_5') -ORDER BY attrelid::regclass::text COLLATE "C", attnum; - attrelid | attname | attidentity | attgenerated -----------------+------------------+-------------+-------------- - salespeople | salesperson_id | a | - salespeople | salesperson_name | | - salespeople1_2 | salesperson_id | a | - salespeople1_2 | salesperson_name | | - salespeople2_3 | salesperson_id | a | - salespeople2_3 | salesperson_name | | - salespeople3_4 | salesperson_id | a | - salespeople3_4 | salesperson_name | | - salespeople4_5 | salesperson_id | a | - salespeople4_5 | salesperson_name | | -(10 rows) - -DROP TABLE salespeople CASCADE; --- --- Test: split partition with deleted columns --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); -CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10); --- Create new partition with some deleted columns: -CREATE TABLE salespeople10_40(d1 VARCHAR(30), salesperson_id INT PRIMARY KEY, d2 INT, d3 DATE, salesperson_name VARCHAR(30)); -INSERT INTO salespeople10_40 VALUES - ('dummy value 1', 19, 100, now(), 'Ivanov'), - ('dummy value 2', 20, 101, now(), 'Smirnoff'); -ALTER TABLE salespeople10_40 DROP COLUMN d1; -ALTER TABLE salespeople10_40 DROP COLUMN d2; -ALTER TABLE salespeople10_40 DROP COLUMN d3; -ALTER TABLE salespeople ATTACH PARTITION salespeople10_40 FOR VALUES FROM (10) TO (40); -INSERT INTO salespeople VALUES - (1, 'Poirot'), - (10, 'May'), - (30, 'Ford'); -ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO - (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20), - PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30), - PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40)); -SELECT tableoid::regclass, * FROM salespeople ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name -------------------+----------------+------------------ - salespeople01_10 | 1 | Poirot - salespeople10_20 | 10 | May - salespeople10_20 | 19 | Ivanov - salespeople20_30 | 20 | Smirnoff - salespeople30_40 | 30 | Ford -(5 rows) - -DROP TABLE salespeople CASCADE; --- --- Test: split sub-partition --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'); -CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'); -CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_apr_all PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); -ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date); -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_amount | sales_date ----------------+----------------+------------------+--------------+------------ - sales_apr_all | 3 | Ford | 2000 | 04-30-2022 - sales_apr_all | 4 | Ivanov | 750 | 04-13-2022 - sales_apr_all | 5 | Deev | 250 | 04-07-2022 - sales_apr_all | 11 | Trump | 380 | 04-06-2022 - sales_feb2022 | 2 | Smirnoff | 500 | 02-10-2022 - sales_feb2022 | 6 | Poirot | 150 | 02-11-2022 - sales_feb2022 | 8 | Ericsson | 185 | 02-23-2022 - sales_jan2022 | 1 | May | 1000 | 01-31-2022 - sales_jan2022 | 10 | Halder | 350 | 01-28-2022 - sales_jan2022 | 13 | Gandi | 377 | 01-09-2022 - sales_mar2022 | 7 | Li | 175 | 03-08-2022 - sales_mar2022 | 9 | Muller | 250 | 03-11-2022 - sales_mar2022 | 12 | Plato | 350 | 03-19-2022 - sales_others | 14 | Smith | 510 | 05-04-2022 -(14 rows) - -ALTER TABLE sales_apr2022 SPLIT PARTITION sales_apr_all INTO - (PARTITION sales_apr2022_01_10 FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'), - PARTITION sales_apr2022_10_20 FOR VALUES FROM ('2022-04-10') TO ('2022-04-20'), - PARTITION sales_apr2022_20_30 FOR VALUES FROM ('2022-04-20') TO ('2022-05-01')); -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_amount | sales_date ----------------------+----------------+------------------+--------------+------------ - sales_apr2022_01_10 | 5 | Deev | 250 | 04-07-2022 - sales_apr2022_01_10 | 11 | Trump | 380 | 04-06-2022 - sales_apr2022_10_20 | 4 | Ivanov | 750 | 04-13-2022 - sales_apr2022_20_30 | 3 | Ford | 2000 | 04-30-2022 - sales_feb2022 | 2 | Smirnoff | 500 | 02-10-2022 - sales_feb2022 | 6 | Poirot | 150 | 02-11-2022 - sales_feb2022 | 8 | Ericsson | 185 | 02-23-2022 - sales_jan2022 | 1 | May | 1000 | 01-31-2022 - sales_jan2022 | 10 | Halder | 350 | 01-28-2022 - sales_jan2022 | 13 | Gandi | 377 | 01-09-2022 - sales_mar2022 | 7 | Li | 175 | 03-08-2022 - sales_mar2022 | 9 | Muller | 250 | 03-11-2022 - sales_mar2022 | 12 | Plato | 350 | 03-19-2022 - sales_others | 14 | Smith | 510 | 05-04-2022 -(14 rows) - -DROP TABLE sales_range; --- --- BY LIST partitioning --- --- --- Test: specific errors for BY LIST partitioning --- -CREATE TABLE sales_list (sales_state VARCHAR(20)) PARTITION BY LIST (sales_state); -CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki'); -CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Beijing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok'); -CREATE TABLE sales_others PARTITION OF sales_list DEFAULT; --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok', 'Helsinki'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')); -ERROR: new partition "sales_east" would overlap with another (not split) partition "sales_nord" -LINE 3: ...FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok', 'Helsinki'... - ^ --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Lisbon', 'Kyiv')); -ERROR: new partition "sales_west" would overlap with another new partition "sales_central" -LINE 2: (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York',... - ^ --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid', NULL), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')); -ERROR: new partition "sales_west" cannot have NULL value because split partition "sales_all" does not have it -LINE 2: ...s_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid', NULL), - ^ --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid', 'Melbourne'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')); -ERROR: new partition "sales_west" cannot have this value because split partition "sales_all" does not have it -LINE 2: ...st FOR VALUES IN ('Lisbon', 'New York', 'Madrid', 'Melbourne... - ^ --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid', 'Melbourne'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'), - PARTITION sales_others2 DEFAULT); -ERROR: cannot split non-DEFAULT partition "sales_all" -LINE 5: PARTITION sales_others2 DEFAULT); - ^ -DETAIL: New partition cannot be DEFAULT because DEFAULT partition "sales_others" already exists. -DROP TABLE sales_list; --- Test for non-symbolic comparison of values (numeric values '0' and '0.0' are equal). -CREATE TABLE t (a numeric) PARTITION BY LIST (a); -CREATE TABLE t1 PARTITION OF t FOR VALUES in ('0', '1'); --- ERROR -ALTER TABLE t SPLIT PARTITION t1 INTO - (PARTITION x FOR VALUES IN ('0'), - PARTITION x1 FOR VALUES IN ('0.0', '1')); -ERROR: new partition "x" would overlap with another new partition "x1" -LINE 2: (PARTITION x FOR VALUES IN ('0'), - ^ -DROP TABLE t; --- --- Test: two specific errors for BY LIST partitioning: --- * new partitions do not have NULL value, which split partition has. --- * new partitions do not have a value that split partition has. --- -CREATE TABLE sales_list(sales_state VARCHAR(20)) PARTITION BY LIST (sales_state); -CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Helsinki', 'St. Petersburg', 'Oslo'); -CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Beijing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok', NULL); --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')); -ERROR: new partitions' combined partition bounds do not contain value (NULL) but split partition "sales_all" does -HINT: ALTER TABLE ... SPLIT PARTITION requires the combined bounds of the new partitions to exactly match the bound of the split partition. --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', NULL)); -ERROR: new partitions' combined partition bounds do not contain value ('Kyiv'::character varying(20)) but split partition "sales_all" does -HINT: ALTER TABLE ... SPLIT PARTITION requires the combined bounds of the new partitions to exactly match the bound of the split partition. --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'), - PARTITION sales_others DEFAULT, - PARTITION sales_others2 DEFAULT); -ERROR: cannot specify more than one DEFAULT partition -LINE 6: PARTITION sales_others2 DEFAULT); - ^ -DROP TABLE sales_list; --- --- Test: BY LIST partitioning, SPLIT PARTITION with data --- -CREATE TABLE sales_list -(salesperson_id SERIAL, - salesperson_name VARCHAR(30), - sales_state VARCHAR(20), - sales_amount INT, - sales_date DATE) -PARTITION BY LIST (sales_state); -CREATE INDEX sales_list_salesperson_name_idx ON sales_list USING btree (salesperson_name); -CREATE INDEX sales_list_sales_state_idx ON sales_list USING btree (sales_state); -CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Helsinki', 'St. Petersburg', 'Oslo'); -CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Beijing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok'); -CREATE TABLE sales_others PARTITION OF sales_list DEFAULT; -INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES - ('Trump', 'Beijing', 1000, '2022-03-01'), - ('Smirnoff', 'New York', 500, '2022-03-03'), - ('Ford', 'St. Petersburg', 2000, '2022-03-05'), - ('Ivanov', 'Warsaw', 750, '2022-03-04'), - ('Deev', 'Lisbon', 250, '2022-03-07'), - ('Poirot', 'Berlin', 1000, '2022-03-01'), - ('May', 'Oslo', 1200, '2022-03-06'), - ('Li', 'Vladivostok', 1150, '2022-03-09'), - ('May', 'Oslo', 1200, '2022-03-11'), - ('Halder', 'Helsinki', 800, '2022-03-02'), - ('Muller', 'Madrid', 650, '2022-03-05'), - ('Smith', 'Kyiv', 350, '2022-03-10'), - ('Gandi', 'Warsaw', 150, '2022-03-08'), - ('Plato', 'Lisbon', 950, '2022-03-05'); -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')); -SELECT tableoid::regclass, * FROM sales_list ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_state | sales_amount | sales_date ----------------+----------------+------------------+----------------+--------------+------------ - sales_central | 4 | Ivanov | Warsaw | 750 | 03-04-2022 - sales_central | 6 | Poirot | Berlin | 1000 | 03-01-2022 - sales_central | 12 | Smith | Kyiv | 350 | 03-10-2022 - sales_central | 13 | Gandi | Warsaw | 150 | 03-08-2022 - sales_east | 1 | Trump | Beijing | 1000 | 03-01-2022 - sales_east | 8 | Li | Vladivostok | 1150 | 03-09-2022 - sales_nord | 3 | Ford | St. Petersburg | 2000 | 03-05-2022 - sales_nord | 7 | May | Oslo | 1200 | 03-06-2022 - sales_nord | 9 | May | Oslo | 1200 | 03-11-2022 - sales_nord | 10 | Halder | Helsinki | 800 | 03-02-2022 - sales_west | 2 | Smirnoff | New York | 500 | 03-03-2022 - sales_west | 5 | Deev | Lisbon | 250 | 03-07-2022 - sales_west | 11 | Muller | Madrid | 650 | 03-05-2022 - sales_west | 14 | Plato | Lisbon | 950 | 03-05-2022 -(14 rows) - --- Use indexscan for testing indexes after splitting partition -SET enable_seqscan = OFF; -EXPLAIN (COSTS OFF) SELECT * FROM sales_central WHERE sales_state = 'Warsaw'; - QUERY PLAN ------------------------------------------------------------------ - Index Scan using sales_central_sales_state_idx on sales_central - Index Cond: ((sales_state)::text = 'Warsaw'::text) -(2 rows) - -SELECT * FROM sales_central WHERE sales_state = 'Warsaw'; - salesperson_id | salesperson_name | sales_state | sales_amount | sales_date -----------------+------------------+-------------+--------------+------------ - 4 | Ivanov | Warsaw | 750 | 03-04-2022 - 13 | Gandi | Warsaw | 150 | 03-08-2022 -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM sales_list WHERE sales_state = 'Warsaw'; - QUERY PLAN ----------------------------------------------------------------------------- - Index Scan using sales_central_sales_state_idx on sales_central sales_list - Index Cond: ((sales_state)::text = 'Warsaw'::text) -(2 rows) - -SELECT * FROM sales_list WHERE sales_state = 'Warsaw'; - salesperson_id | salesperson_name | sales_state | sales_amount | sales_date -----------------+------------------+-------------+--------------+------------ - 4 | Ivanov | Warsaw | 750 | 03-04-2022 - 13 | Gandi | Warsaw | 150 | 03-08-2022 -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov'; - QUERY PLAN ------------------------------------------------------------------------------------------ - Append - -> Index Scan using sales_east_salesperson_name_idx on sales_east sales_list_1 - Index Cond: ((salesperson_name)::text = 'Ivanov'::text) - -> Index Scan using sales_central_salesperson_name_idx on sales_central sales_list_2 - Index Cond: ((salesperson_name)::text = 'Ivanov'::text) - -> Bitmap Heap Scan on sales_nord sales_list_3 - Recheck Cond: ((salesperson_name)::text = 'Ivanov'::text) - -> Bitmap Index Scan on sales_nord_salesperson_name_idx - Index Cond: ((salesperson_name)::text = 'Ivanov'::text) - -> Index Scan using sales_west_salesperson_name_idx on sales_west sales_list_4 - Index Cond: ((salesperson_name)::text = 'Ivanov'::text) - -> Bitmap Heap Scan on sales_others sales_list_5 - Recheck Cond: ((salesperson_name)::text = 'Ivanov'::text) - -> Bitmap Index Scan on sales_others_salesperson_name_idx - Index Cond: ((salesperson_name)::text = 'Ivanov'::text) -(15 rows) - -SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov'; - salesperson_id | salesperson_name | sales_state | sales_amount | sales_date -----------------+------------------+-------------+--------------+------------ - 4 | Ivanov | Warsaw | 750 | 03-04-2022 -(1 row) - -RESET enable_seqscan; -DROP TABLE sales_list; --- --- Test for: --- * split DEFAULT partition to partitions with spaces between bounds; --- * random order of partitions in SPLIT PARTITION command. --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-09'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-07'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_others DEFAULT, - PARTITION sales_mar2022_1decade FOR VALUES FROM ('2022-03-01') TO ('2022-03-10'), - PARTITION sales_jan2022_1decade FOR VALUES FROM ('2022-01-01') TO ('2022-01-10'), - PARTITION sales_feb2022_1decade FOR VALUES FROM ('2022-02-01') TO ('2022-02-10'), - PARTITION sales_apr2022_1decade FOR VALUES FROM ('2022-04-01') TO ('2022-04-10')); -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_amount | sales_date ------------------------+----------------+------------------+--------------+------------ - sales_apr2022_1decade | 5 | Deev | 250 | 04-07-2022 - sales_apr2022_1decade | 11 | Trump | 380 | 04-06-2022 - sales_feb2022_1decade | 2 | Smirnoff | 500 | 02-09-2022 - sales_feb2022_1decade | 6 | Poirot | 150 | 02-07-2022 - sales_jan2022_1decade | 13 | Gandi | 377 | 01-09-2022 - sales_mar2022_1decade | 7 | Li | 175 | 03-08-2022 - sales_others | 1 | May | 1000 | 01-31-2022 - sales_others | 3 | Ford | 2000 | 04-30-2022 - sales_others | 4 | Ivanov | 750 | 04-13-2022 - sales_others | 8 | Ericsson | 185 | 02-23-2022 - sales_others | 9 | Muller | 250 | 03-11-2022 - sales_others | 10 | Halder | 350 | 01-28-2022 - sales_others | 12 | Plato | 350 | 03-19-2022 - sales_others | 14 | Smith | 510 | 05-04-2022 -(14 rows) - -DROP TABLE sales_range; --- --- Test for: --- * split non-DEFAULT partition to partitions with spaces between bounds; --- * random order of partitions in SPLIT PARTITION command. --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_all PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-05-01'); -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-09'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-07'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'); -ALTER TABLE sales_range SPLIT PARTITION sales_all INTO - (PARTITION sales_mar2022_1decade FOR VALUES FROM ('2022-03-01') TO ('2022-03-10'), - PARTITION sales_jan2022_1decade FOR VALUES FROM ('2022-01-01') TO ('2022-01-10'), - PARTITION sales_feb2022_1decade FOR VALUES FROM ('2022-02-01') TO ('2022-02-10'), - PARTITION sales_apr2022_1decade FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'), - PARTITION sales_others DEFAULT); -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_amount | sales_date ------------------------+----------------+------------------+--------------+------------ - sales_apr2022_1decade | 5 | Deev | 250 | 04-07-2022 - sales_apr2022_1decade | 11 | Trump | 380 | 04-06-2022 - sales_feb2022_1decade | 2 | Smirnoff | 500 | 02-09-2022 - sales_feb2022_1decade | 6 | Poirot | 150 | 02-07-2022 - sales_jan2022_1decade | 13 | Gandi | 377 | 01-09-2022 - sales_mar2022_1decade | 7 | Li | 175 | 03-08-2022 - sales_others | 1 | May | 1000 | 01-31-2022 - sales_others | 3 | Ford | 2000 | 04-30-2022 - sales_others | 4 | Ivanov | 750 | 04-13-2022 - sales_others | 8 | Ericsson | 185 | 02-23-2022 - sales_others | 9 | Muller | 250 | 03-11-2022 - sales_others | 10 | Halder | 350 | 01-28-2022 - sales_others | 12 | Plato | 350 | 03-19-2022 -(13 rows) - -DROP TABLE sales_range; --- --- Test for split non-DEFAULT partition to DEFAULT partition + partitions --- with spaces between bounds. --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_all PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'); -ALTER TABLE sales_range SPLIT PARTITION sales_all INTO - (PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); -INSERT INTO sales_range VALUES (14, 'Smith', 510, '2022-05-04'); -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - tableoid | salesperson_id | salesperson_name | sales_amount | sales_date ----------------+----------------+------------------+--------------+------------ - sales_apr2022 | 3 | Ford | 2000 | 04-30-2022 - sales_apr2022 | 4 | Ivanov | 750 | 04-13-2022 - sales_apr2022 | 5 | Deev | 250 | 04-07-2022 - sales_apr2022 | 11 | Trump | 380 | 04-06-2022 - sales_feb2022 | 2 | Smirnoff | 500 | 02-10-2022 - sales_feb2022 | 6 | Poirot | 150 | 02-11-2022 - sales_feb2022 | 8 | Ericsson | 185 | 02-23-2022 - sales_jan2022 | 1 | May | 1000 | 01-31-2022 - sales_jan2022 | 10 | Halder | 350 | 01-28-2022 - sales_jan2022 | 13 | Gandi | 377 | 01-09-2022 - sales_others | 7 | Li | 175 | 03-08-2022 - sales_others | 9 | Muller | 250 | 03-11-2022 - sales_others | 12 | Plato | 350 | 03-19-2022 - sales_others | 14 | Smith | 510 | 05-04-2022 -(14 rows) - -DROP TABLE sales_range; --- --- Test that SPLIT PARTITION rejects the degenerate case where the only --- non-DEFAULT replacement partition keeps the original bound and the command --- merely adds a DEFAULT partition. --- -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_50 PARTITION OF t FOR VALUES FROM (0) TO (50); -INSERT INTO t VALUES (1); --- ERROR -ALTER TABLE t SPLIT PARTITION tp_0_50 INTO - (PARTITION tp_0_50 FOR VALUES FROM (0) TO (50), - PARTITION tp_default DEFAULT); -ERROR: cannot split partition "tp_0_50" only to add a DEFAULT partition -LINE 2: (PARTITION tp_0_50 FOR VALUES FROM (0) TO (50), - ^ -DETAIL: The non-DEFAULT partition would keep the same partition bound. -HINT: Use CREATE TABLE ... PARTITION OF ... DEFAULT to add a DEFAULT partition. -DROP TABLE t; --- --- Test that a LIST split with DEFAULT is not considered degenerate when --- only NULL is removed from the explicit replacement partition. --- -CREATE TABLE t (i int) PARTITION BY LIST (i); -CREATE TABLE tp_null_1 PARTITION OF t FOR VALUES IN (NULL, 1); -ALTER TABLE t SPLIT PARTITION tp_null_1 INTO - (PARTITION tp_1 FOR VALUES IN (1), - PARTITION tp_default DEFAULT); -INSERT INTO t VALUES (NULL), (1), (2); -SELECT tableoid::regclass, i FROM t ORDER BY tableoid::regclass::text COLLATE "C", i NULLS FIRST; - tableoid | i -------------+--- - tp_1 | 1 - tp_default | - tp_default | 2 -(3 rows) - -DROP TABLE t; --- --- Test that the same-bound check for LIST partitioning uses the --- partition operator family, not byte equality. -0.0 and 0.0 have --- different bit patterns but compare equal under float8, so the --- replacement bound (-0.0, 1.0) is the same set as the original --- (0.0, 1.0) and the SPLIT is degenerate. A datumIsEqual()-based --- check would let this through; the partsupfunc-based check correctly --- rejects it. --- -CREATE TABLE t (v float8) PARTITION BY LIST (v); -CREATE TABLE tp_zero_one PARTITION OF t FOR VALUES IN (0.0, 1.0); --- ERROR -ALTER TABLE t SPLIT PARTITION tp_zero_one INTO - (PARTITION tp_zero_one FOR VALUES IN (-0.0, 1.0), - PARTITION tp_default DEFAULT); -ERROR: cannot split partition "tp_zero_one" only to add a DEFAULT partition -LINE 2: (PARTITION tp_zero_one FOR VALUES IN (-0.0, 1.0), - ^ -DETAIL: The non-DEFAULT partition would keep the same partition bound. -HINT: Use CREATE TABLE ... PARTITION OF ... DEFAULT to add a DEFAULT partition. -DROP TABLE t; --- --- Test that the explicit partition bound cannot extend outside the split --- partition's bound when a DEFAULT partition is specified. --- -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_51 PARTITION OF t FOR VALUES FROM (0) TO (51); -CREATE TABLE tp_51_100 PARTITION OF t FOR VALUES FROM (51) TO (100); --- ERROR -ALTER TABLE t SPLIT PARTITION tp_0_51 INTO - (PARTITION tp_0_51 FOR VALUES FROM (0) TO (53), - PARTITION tp_default DEFAULT); -ERROR: upper bound of partition "tp_0_51" is greater than upper bound of split partition "tp_0_51" -LINE 2: (PARTITION tp_0_51 FOR VALUES FROM (0) TO (53), - ^ -HINT: Explicit partition bounds must be contained within the bounds of the split partition when a DEFAULT partition is specified. -DROP TABLE t; --- --- Try to SPLIT partition of another table. --- -CREATE TABLE t1(i int, t text) PARTITION BY LIST (t); -CREATE TABLE t1pa PARTITION OF t1 FOR VALUES IN ('A'); -CREATE TABLE t2 (i int, t text) PARTITION BY RANGE (t); --- ERROR -ALTER TABLE t2 SPLIT PARTITION t1pa INTO - (PARTITION t2a FOR VALUES FROM ('A') TO ('B'), - PARTITION t2b FOR VALUES FROM ('B') TO ('C')); -ERROR: relation "t1pa" is not a partition of relation "t2" -HINT: ALTER TABLE ... SPLIT PARTITION can only split partitions that don't have sub-partitions. -DROP TABLE t2; -DROP TABLE t1; --- --- Try to SPLIT partition of temporary table. --- -CREATE TEMP TABLE t (i int) PARTITION BY RANGE (i); -CREATE TEMP TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); -SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence - FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i - WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass - ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text COLLATE "C"; - oid | pg_get_expr | relpersistence ---------+----------------------------+---------------- - tp_0_2 | FOR VALUES FROM (0) TO (2) | t -(1 row) - --- ERROR -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); -ERROR: cannot create a permanent relation as partition of temporary relation "t" -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION pg_temp.tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION pg_temp.tp_1_2 FOR VALUES FROM (1) TO (2)); --- Partitions should be temporary. -SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence - FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i - WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass - ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text COLLATE "C"; - oid | pg_get_expr | relpersistence ---------+----------------------------+---------------- - tp_0_1 | FOR VALUES FROM (0) TO (1) | t - tp_1_2 | FOR VALUES FROM (1) TO (2) | t -(2 rows) - -DROP TABLE t; --- Check the new partitions inherit parent's tablespace -CREATE TABLE t (i int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) - PARTITION BY RANGE (i) TABLESPACE regress_tblspace; -CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); -SELECT tablename, tablespace FROM pg_tables - WHERE tablename IN ('t', 'tp_0_1', 'tp_1_2') AND schemaname = 'partition_split_schema' - ORDER BY tablename COLLATE "C", tablespace COLLATE "C"; - tablename | tablespace ------------+------------------ - t | regress_tblspace - tp_0_1 | regress_tblspace - tp_1_2 | regress_tblspace -(3 rows) - -SELECT tablename, indexname, tablespace FROM pg_indexes - WHERE tablename IN ('t', 'tp_0_1', 'tp_1_2') AND schemaname = 'partition_split_schema' - ORDER BY tablename COLLATE "C", indexname COLLATE "C", tablespace COLLATE "C"; - tablename | indexname | tablespace ------------+-------------+------------------ - t | t_pkey | regress_tblspace - tp_0_1 | tp_0_1_pkey | regress_tblspace - tp_1_2 | tp_1_2_pkey | regress_tblspace -(3 rows) - -DROP TABLE t; --- Check new partitions inherits parent's table access method -CREATE ACCESS METHOD partition_split_heap TYPE TABLE HANDLER heap_tableam_handler; -CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partition_split_heap; -CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); -SELECT c.relname, a.amname -FROM pg_class c JOIN pg_am a ON c.relam = a.oid -WHERE c.oid IN ('t'::regclass, 'tp_0_1'::regclass, 'tp_1_2'::regclass) -ORDER BY c.relname COLLATE "C"; - relname | amname ----------+---------------------- - t | partition_split_heap - tp_0_1 | partition_split_heap - tp_1_2 | partition_split_heap -(3 rows) - -DROP TABLE t; -DROP ACCESS METHOD partition_split_heap; --- Split partition of a temporary table when one of the partitions after --- split has the same name as the partition being split -CREATE TEMP TABLE t (a int) PARTITION BY RANGE (a); -CREATE TEMP TABLE tp_0 PARTITION OF t FOR VALUES FROM (0) TO (2); -ALTER TABLE t SPLIT PARTITION tp_0 INTO - (PARTITION pg_temp.tp_0 FOR VALUES FROM (0) TO (1), - PARTITION pg_temp.tp_1 FOR VALUES FROM (1) TO (2)); -DROP TABLE t; --- Check defaults and constraints of new partitions -CREATE TABLE t_bigint ( - b bigint, - i int DEFAULT (3+10), - j int DEFAULT 101, - k int GENERATED ALWAYS AS (b+10) STORED -) -PARTITION BY RANGE (b); -CREATE TABLE t_bigint_default PARTITION OF t_bigint DEFAULT; --- Show defaults/constraints before SPLIT PARTITION -\d+ t_bigint - Partitioned table "partition_split_schema.t_bigint" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------------------------------------+---------+--------------+------------- - b | bigint | | | | plain | | - i | integer | | | 3 + 10 | plain | | - j | integer | | | 101 | plain | | - k | integer | | | generated always as ((b + 10)) stored | plain | | -Partition key: RANGE (b) -Partitions: - t_bigint_default DEFAULT - -\d+ t_bigint_default - Table "partition_split_schema.t_bigint_default" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------------------------------------+---------+--------------+------------- - b | bigint | | | | plain | | - i | integer | | | 3 + 10 | plain | | - j | integer | | | 101 | plain | | - k | integer | | | generated always as ((b + 10)) stored | plain | | -Partition of: t_bigint DEFAULT -No partition constraint - -ALTER TABLE t_bigint SPLIT PARTITION t_bigint_default INTO - (PARTITION t_bigint_01_10 FOR VALUES FROM (0) TO (10), - PARTITION t_bigint_default DEFAULT); --- Show defaults/constraints after SPLIT PARTITION -\d+ t_bigint_default - Table "partition_split_schema.t_bigint_default" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------------------------------------+---------+--------------+------------- - b | bigint | | | | plain | | - i | integer | | | 3 + 10 | plain | | - j | integer | | | 101 | plain | | - k | integer | | | generated always as ((b + 10)) stored | plain | | -Partition of: t_bigint DEFAULT -Partition constraint: (NOT ((b IS NOT NULL) AND ((b >= '0'::bigint) AND (b < '10'::bigint)))) - -\d+ t_bigint_01_10 - Table "partition_split_schema.t_bigint_01_10" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------------------------------------+---------+--------------+------------- - b | bigint | | | | plain | | - i | integer | | | 3 + 10 | plain | | - j | integer | | | 101 | plain | | - k | integer | | | generated always as ((b + 10)) stored | plain | | -Partition of: t_bigint FOR VALUES FROM ('0') TO ('10') -Partition constraint: ((b IS NOT NULL) AND (b >= '0'::bigint) AND (b < '10'::bigint)) - -DROP TABLE t_bigint; --- Test permission checks. The user needs to own the parent table and the --- the partition to split to do the split. -CREATE ROLE regress_partition_split_alice; -CREATE ROLE regress_partition_split_bob; -GRANT ALL ON SCHEMA partition_split_schema TO regress_partition_split_alice; -GRANT ALL ON SCHEMA partition_split_schema TO regress_partition_split_bob; -SET SESSION AUTHORIZATION regress_partition_split_alice; -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); -SET SESSION AUTHORIZATION regress_partition_split_bob; -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); --error -ERROR: must be owner of table t -RESET SESSION AUTHORIZATION; -ALTER TABLE t OWNER TO regress_partition_split_bob; -SET SESSION AUTHORIZATION regress_partition_split_bob; -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); --error -ERROR: must be owner of table tp_0_2 -RESET SESSION AUTHORIZATION; -ALTER TABLE tp_0_2 OWNER TO regress_partition_split_bob; -SET SESSION AUTHORIZATION regress_partition_split_bob; -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); --ok -RESET SESSION AUTHORIZATION; -DROP TABLE t; --- Test: owner of new partitions should be the same as owner of split partition -CREATE TABLE t (i int) PARTITION BY RANGE (i); -SET SESSION AUTHORIZATION regress_partition_split_alice; -CREATE TABLE tp_0_2(i int); -RESET SESSION AUTHORIZATION; -ALTER TABLE t ATTACH PARTITION tp_0_2 FOR VALUES FROM (0) TO (2); --- Owner is 'regress_partition_split_alice': -\dt tp_0_2 - List of tables - Schema | Name | Type | Owner -------------------------+--------+-------+------------------------------- - partition_split_schema | tp_0_2 | table | regress_partition_split_alice -(1 row) - -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); --- Owner should be 'regress_partition_split_alice': -\dt tp_0_1 - List of tables - Schema | Name | Type | Owner -------------------------+--------+-------+------------------------------- - partition_split_schema | tp_0_1 | table | regress_partition_split_alice -(1 row) - -\dt tp_1_2 - List of tables - Schema | Name | Type | Owner -------------------------+--------+-------+------------------------------- - partition_split_schema | tp_1_2 | table | regress_partition_split_alice -(1 row) - -DROP TABLE t; --- Test: index of new partitions should be created with same owner as split --- partition -SET SESSION AUTHORIZATION regress_partition_split_alice; -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_10_20 PARTITION OF t FOR VALUES FROM (10) TO (20); -INSERT INTO t VALUES (11), (16); -CREATE OR REPLACE FUNCTION run_me(integer) RETURNS integer AS $$ -BEGIN - RAISE NOTICE 'you are running me as %', CURRENT_USER; - RETURN $1; -END -$$ LANGUAGE PLPGSQL IMMUTABLE; --- Owner is 'regress_partition_split_alice': -CREATE INDEX ON t (run_me(i)); -NOTICE: you are running me as regress_partition_split_alice -NOTICE: you are running me as regress_partition_split_alice -RESET SESSION AUTHORIZATION; --- Owner should be 'regress_partition_split_alice': -ALTER TABLE t SPLIT PARTITION tp_10_20 INTO - (PARTITION tp_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tp_15_20 FOR VALUES FROM (15) TO (20)); -NOTICE: you are running me as regress_partition_split_alice -NOTICE: you are running me as regress_partition_split_alice -DROP TABLE t; -DROP FUNCTION run_me(integer); -REVOKE ALL ON SCHEMA partition_split_schema FROM regress_partition_split_alice; -REVOKE ALL ON SCHEMA partition_split_schema FROM regress_partition_split_bob; -DROP ROLE regress_partition_split_alice; -DROP ROLE regress_partition_split_bob; --- Test for hash partitioned table -CREATE TABLE t (i int) PARTITION BY HASH(i); -CREATE TABLE tp1 PARTITION OF t FOR VALUES WITH (MODULUS 2, REMAINDER 0); -CREATE TABLE tp2 PARTITION OF t FOR VALUES WITH (MODULUS 2, REMAINDER 1); --- ERROR -ALTER TABLE t SPLIT PARTITION tp1 INTO - (PARTITION tp1_1 FOR VALUES WITH (MODULUS 4, REMAINDER 0), - PARTITION tp1_2 FOR VALUES WITH (MODULUS 4, REMAINDER 2)); -ERROR: partition of hash-partitioned table cannot be split --- ERROR -ALTER TABLE t SPLIT PARTITION tp1 INTO - (PARTITION tp1_1 FOR VALUES WITH (MODULUS 4, REMAINDER 0)); -ERROR: list of new partitions must contain at least two partitions -DROP TABLE t; --- Test for split partition properties: --- * STATISTICS is empty --- * COMMENT is empty --- * DEFAULTS are the same as DEFAULTS for partitioned table --- * STORAGE is the same as STORAGE for partitioned table --- * GENERATED and CONSTRAINTS are the same as GENERATED and CONSTRAINTS for partitioned table --- * TRIGGERS are the same as TRIGGERS for partitioned table -CREATE TABLE t -(i int NOT NULL, - t text STORAGE EXTENDED COMPRESSION pglz DEFAULT 'default_t', - b bigint, - d date GENERATED ALWAYS as ('2022-01-01') STORED) PARTITION BY RANGE (abs(i)); -COMMENT ON COLUMN t.i IS 't1.i'; -CREATE TABLE tp_x -(i int NOT NULL, - t text STORAGE MAIN DEFAULT 'default_tp_x', - b bigint, - d date GENERATED ALWAYS as ('2022-02-02') STORED); -ALTER TABLE t ATTACH PARTITION tp_x FOR VALUES FROM (0) TO (2); -COMMENT ON COLUMN tp_x.i IS 'tp_x.i'; -CREATE STATISTICS t_stat (DEPENDENCIES) on i, b from t; -CREATE STATISTICS tp_x_stat (DEPENDENCIES) on i, b from tp_x; -ALTER TABLE t ADD CONSTRAINT t_b_check CHECK (b > 0); -ALTER TABLE t ADD CONSTRAINT t_b_check1 CHECK (b > 0) NOT ENFORCED; -ALTER TABLE t ADD CONSTRAINT t_b_check2 CHECK (b > 0) NOT VALID; -ALTER TABLE t ADD CONSTRAINT t_b_nn NOT NULL b NOT VALID; -INSERT INTO tp_x(i, t, b) VALUES(0, DEFAULT, 1); -INSERT INTO tp_x(i, t, b) VALUES(1, DEFAULT, 2); -CREATE OR REPLACE FUNCTION trigger_function() RETURNS trigger LANGUAGE 'plpgsql' AS -$BODY$ -BEGIN - RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; - RETURN new; -END; -$BODY$; -CREATE TRIGGER t_before_insert_row_trigger BEFORE INSERT ON t FOR EACH ROW - EXECUTE PROCEDURE trigger_function('t'); -CREATE TRIGGER tp_x_before_insert_row_trigger BEFORE INSERT ON tp_x FOR EACH ROW - EXECUTE PROCEDURE trigger_function('tp_x'); -\d+ tp_x - Table "partition_split_schema.tp_x" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+-------------------------------------------------+---------+--------------+------------- - i | integer | | not null | | plain | | tp_x.i - t | text | | | 'default_tp_x'::text | main | | - b | bigint | | not null | | plain | | - d | date | | | generated always as ('02-02-2022'::date) stored | plain | | -Partition of: t FOR VALUES FROM (0) TO (2) -Partition constraint: ((abs(i) IS NOT NULL) AND (abs(i) >= 0) AND (abs(i) < 2)) -Check constraints: - "t_b_check" CHECK (b > 0) - "t_b_check1" CHECK (b > 0) NOT ENFORCED - "t_b_check2" CHECK (b > 0) NOT VALID -Statistics objects: - "partition_split_schema.tp_x_stat" (dependencies) ON i, b FROM tp_x -Not-null constraints: - "tp_x_i_not_null" NOT NULL "i" (inherited) - "t_b_nn" NOT NULL "b" (inherited) NOT VALID -Triggers: - t_before_insert_row_trigger BEFORE INSERT ON tp_x FOR EACH ROW EXECUTE FUNCTION trigger_function('t'), ON TABLE t - tp_x_before_insert_row_trigger BEFORE INSERT ON tp_x FOR EACH ROW EXECUTE FUNCTION trigger_function('tp_x') - -ALTER TABLE t SPLIT PARTITION tp_x INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_x FOR VALUES FROM (1) TO (2)); -\d+ tp_x - Table "partition_split_schema.tp_x" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+-------------------------------------------------+----------+--------------+------------- - i | integer | | not null | | plain | | - t | text | | | 'default_t'::text | extended | | - b | bigint | | not null | | plain | | - d | date | | | generated always as ('01-01-2022'::date) stored | plain | | -Partition of: t FOR VALUES FROM (1) TO (2) -Partition constraint: ((abs(i) IS NOT NULL) AND (abs(i) >= 1) AND (abs(i) < 2)) -Check constraints: - "t_b_check" CHECK (b > 0) - "t_b_check1" CHECK (b > 0) NOT ENFORCED - "t_b_check2" CHECK (b > 0) NOT VALID -Not-null constraints: - "t_i_not_null" NOT NULL "i" (inherited) - "t_b_nn" NOT NULL "b" (inherited) NOT VALID -Triggers: - t_before_insert_row_trigger BEFORE INSERT ON tp_x FOR EACH ROW EXECUTE FUNCTION trigger_function('t'), ON TABLE t - -INSERT INTO t(i, t, b) VALUES(1, DEFAULT, 3); -NOTICE: trigger(t) called: action = INSERT, when = BEFORE, level = ROW -SELECT tableoid::regclass, * FROM t ORDER BY tableoid::regclass::text COLLATE "C", b; - tableoid | i | t | b | d -----------+---+--------------+---+------------ - tp_0_1 | 0 | default_tp_x | 1 | 01-01-2022 - tp_x | 1 | default_tp_x | 2 | 01-01-2022 - tp_x | 1 | default_t | 3 | 01-01-2022 -(3 rows) - -DROP TABLE t; -DROP FUNCTION trigger_function(); --- Test for recomputation of stored generated columns. -CREATE TABLE t (i int, tab_id int generated always as (tableoid) stored) PARTITION BY RANGE (i); -CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); -ALTER TABLE t ADD CONSTRAINT cc CHECK(tableoid <> 123456789); -INSERT INTO t VALUES (0), (1); --- Should be 1 because partition identifier for row with i=0 is the same as --- partition identifier for row with i=1. -SELECT count(*) FROM t WHERE i = 0 AND tab_id IN (SELECT tab_id FROM t WHERE i = 1); - count -------- - 1 -(1 row) - --- "tab_id" column (stored generated column) with "tableoid" attribute requires --- recomputation here. -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); --- Should be 0 because partition identifier for row with i=0 is different from --- partition identifier for row with i=1. -SELECT count(*) FROM t WHERE i = 0 AND tab_id IN (SELECT tab_id FROM t WHERE i = 1); - count -------- - 0 -(1 row) - -DROP TABLE t; --- Each new partition produced by SPLIT must get its own TOAST table so --- that out-of-line varlena attributes coming from the source partition --- can be stored. SET STORAGE EXTERNAL forces externalization for any --- value over the TOAST threshold, so a string over that threshold --- suffices to exercise the toast-table dependency. -CREATE TABLE t (a text) PARTITION BY RANGE(a); -ALTER TABLE t ALTER COLUMN a SET STORAGE EXTERNAL; -CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (MINVALUE) TO (MAXVALUE); -INSERT INTO t SELECT repeat('1', 10000); -ALTER TABLE t SPLIT PARTITION tp_all INTO ( - PARTITION tp_lo FOR VALUES FROM (MINVALUE) TO ('2'), - PARTITION tp_hi FOR VALUES FROM ('2') TO (MAXVALUE) -); -SELECT relname, - reltoastrelid <> 0 AS has_toast, - pg_relation_size(reltoastrelid) > 0 AS toast_used - FROM pg_class WHERE relname IN ('tp_lo', 'tp_hi') ORDER BY relname; - relname | has_toast | toast_used ----------+-----------+------------ - tp_hi | t | f - tp_lo | t | t -(2 rows) - -SELECT length(a) FROM t; - length --------- - 10000 -(1 row) - -DROP TABLE t; --- Tablespace selection for the new partitions mirrors --- CREATE TABLE ... PARTITION OF: the partitioned root's explicit --- tablespace wins; otherwise default_tablespace applies; otherwise the --- database default is used. -CREATE TABLE t (i int) PARTITION BY RANGE(i) TABLESPACE regress_tblspace; -CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); -INSERT INTO t SELECT generate_series(0, 9); -ALTER TABLE t SPLIT PARTITION tp_all INTO ( - PARTITION tp_lo FOR VALUES FROM (0) TO (5), - PARTITION tp_hi FOR VALUES FROM (5) TO (10) -); -SELECT c.relname, s.spcname FROM pg_class c LEFT JOIN pg_tablespace s - ON c.reltablespace = s.oid WHERE c.relname IN ('tp_lo', 'tp_hi') - ORDER BY c.relname; - relname | spcname ----------+------------------ - tp_hi | regress_tblspace - tp_lo | regress_tblspace -(2 rows) - -DROP TABLE t; --- Parent has no explicit tablespace, but default_tablespace is set: the --- new partitions land on default_tablespace. -CREATE TABLE t (i int) PARTITION BY RANGE(i); -CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); -INSERT INTO t SELECT generate_series(0, 9); -SET default_tablespace TO regress_tblspace; -ALTER TABLE t SPLIT PARTITION tp_all INTO ( - PARTITION tp_lo FOR VALUES FROM (0) TO (5), - PARTITION tp_hi FOR VALUES FROM (5) TO (10) -); -RESET default_tablespace; -SELECT c.relname, s.spcname FROM pg_class c LEFT JOIN pg_tablespace s - ON c.reltablespace = s.oid WHERE c.relname IN ('tp_lo', 'tp_hi') - ORDER BY c.relname; - relname | spcname ----------+------------------ - tp_hi | regress_tblspace - tp_lo | regress_tblspace -(2 rows) - -DROP TABLE t; -CREATE TABLE t (i int) PARTITION BY RANGE(i); -CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); -INSERT INTO t SELECT generate_series(0, 9); --- pg_global is rejected when picked up from default_tablespace. -SET default_tablespace TO pg_global; -ALTER TABLE t SPLIT PARTITION tp_all INTO ( - PARTITION tp_lo FOR VALUES FROM (0) TO (5), - PARTITION tp_hi FOR VALUES FROM (5) TO (10) -); -- fails -ERROR: only shared relations can be placed in pg_global tablespace -RESET default_tablespace; --- Parent has no explicit tablespace and default_tablespace is empty: new --- partitions use the database default (reltablespace = 0). -ALTER TABLE t SPLIT PARTITION tp_all INTO ( - PARTITION tp_lo FOR VALUES FROM (0) TO (5), - PARTITION tp_hi FOR VALUES FROM (5) TO (10) -); -SELECT relname, reltablespace FROM pg_class - WHERE relname IN ('tp_lo', 'tp_hi') ORDER BY relname; - relname | reltablespace ----------+--------------- - tp_hi | 0 - tp_lo | 0 -(2 rows) - -DROP TABLE t; -RESET search_path; --- -DROP SCHEMA partition_split_schema; -DROP SCHEMA partition_split_schema2; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 8fa0a6c47fb..8356ca98ef2 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -123,7 +123,7 @@ test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion tr # The stats test resets stats, so nothing else needing stats access can be in # this group. # ---------- -test: partition_merge partition_split partition_join partition_prune reloptions hash_part indexing partition_aggregate partition_info tuplesort explain memoize stats predicate numa eager_aggregate graph_table_rls planner_est +test: partition_join partition_prune reloptions hash_part indexing partition_aggregate partition_info tuplesort explain memoize stats predicate numa eager_aggregate graph_table_rls planner_est # ---------- # Another group of parallel tests (compression) diff --git a/src/test/regress/sql/partition_merge.sql b/src/test/regress/sql/partition_merge.sql deleted file mode 100644 index 80dc365b0ce..00000000000 --- a/src/test/regress/sql/partition_merge.sql +++ /dev/null @@ -1,846 +0,0 @@ --- --- PARTITIONS_MERGE --- Tests for "ALTER TABLE ... MERGE PARTITIONS ..." command --- - -CREATE SCHEMA partitions_merge_schema; -CREATE SCHEMA partitions_merge_schema2; -SET search_path = partitions_merge_schema, public; - --- --- BY RANGE partitioning --- - --- --- Test for error codes --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_dec2021 PARTITION OF sales_range FOR VALUES FROM ('2021-12-01') TO ('2021-12-31'); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'); -CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'); - -CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_apr_1 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-04-15'); -CREATE TABLE sales_apr_2 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-15') TO ('2022-05-01'); -ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); - -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; - --- ERROR -ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_feb2022) INTO sales_feb_mar_apr2022; --- ERROR -ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_apr2022) INTO sales_feb_mar_apr2022; --- ERROR --- (space between sections sales_jan2022 and sales_mar2022) -ALTER TABLE sales_range MERGE PARTITIONS (sales_jan2022, sales_mar2022) INTO sales_jan_mar2022; --- ERROR --- (space between sections sales_dec2021 and sales_jan2022) -ALTER TABLE sales_range MERGE PARTITIONS (sales_dec2021, sales_jan2022, sales_feb2022) INTO sales_dec_jan_feb2022; --- ERROR -ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, partitions_merge_schema.sales_feb2022) INTO sales_feb_mar_apr2022; --- ERROR -ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_jan2022) INTO sales_apr_2; - -CREATE VIEW jan2022v as SELECT * FROM sales_jan2022; -ALTER TABLE sales_range MERGE PARTITIONS (sales_jan2022, sales_feb2022) INTO sales_dec_jan_feb2022; -DROP VIEW jan2022v; - --- NO ERROR: test for custom partitions order, source partitions not in the search_path -SET search_path = partitions_merge_schema2, public; -ALTER TABLE partitions_merge_schema.sales_range MERGE PARTITIONS ( - partitions_merge_schema.sales_feb2022, - partitions_merge_schema.sales_mar2022, - partitions_merge_schema.sales_jan2022) INTO sales_jan_feb_mar2022; -SET search_path = partitions_merge_schema, public; - -PREPARE get_partition_info(regclass[]) AS -SELECT c.oid::pg_catalog.regclass, - c.relpersistence, - c.relkind, - i.inhdetachpending, - pg_catalog.pg_get_expr(c.relpartbound, c.oid) -FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i -WHERE c.oid = i.inhrelid AND i.inhparent = ANY($1) -ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', - c.oid::regclass::text COLLATE "C"; - -EXECUTE get_partition_info('{sales_range}'); - -DROP TABLE sales_range; - --- --- Add rows into partitioned table, then merge partitions --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'); -CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'); -CREATE TABLE sales_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date); - -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); - -SELECT pg_catalog.pg_get_partkeydef('sales_range'::regclass); - --- show partitions with conditions: -EXECUTE get_partition_info('{sales_range}'); - --- check schema-qualified name of the new partition -ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_apr2022) INTO partitions_merge_schema2.sales_feb_mar_apr2022; - --- show partitions with conditions: -EXECUTE get_partition_info('{sales_range}'); - -SELECT * FROM pg_indexes WHERE tablename = 'sales_feb_mar_apr2022' and schemaname = 'partitions_merge_schema2'; - -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - --- Use indexscan for testing indexes -SET enable_seqscan = OFF; - -EXPLAIN (COSTS OFF) SELECT * FROM partitions_merge_schema2.sales_feb_mar_apr2022 where sales_date > '2022-01-01'; -SELECT * FROM partitions_merge_schema2.sales_feb_mar_apr2022 where sales_date > '2022-01-01'; - -RESET enable_seqscan; - -DROP TABLE sales_range; - --- --- Merge some partitions into DEFAULT partition --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'); -CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'); -CREATE TABLE sales_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date); - -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); - --- Merge partitions (include DEFAULT partition) into partition with the same --- name -ALTER TABLE sales_range MERGE PARTITIONS - (sales_jan2022, sales_mar2022, partitions_merge_schema.sales_others) INTO sales_others; - -SELECT * FROM sales_others ORDER BY salesperson_id; - --- show partitions with conditions: -EXECUTE get_partition_info('{sales_range}'); - -DROP TABLE sales_range; - --- --- Test for: --- * composite partition key; --- * GENERATED column; --- * column with DEFAULT value. --- -CREATE TABLE sales_date (salesperson_name VARCHAR(30), sales_year INT, sales_month INT, sales_day INT, - sales_date VARCHAR(10) GENERATED ALWAYS AS - (LPAD(sales_year::text, 4, '0') || '.' || LPAD(sales_month::text, 2, '0') || '.' || LPAD(sales_day::text, 2, '0')) STORED, - sales_department VARCHAR(30) DEFAULT 'Sales department') - PARTITION BY RANGE (sales_year, sales_month, sales_day); - -CREATE TABLE sales_dec2022 PARTITION OF sales_date FOR VALUES FROM (2021, 12, 1) TO (2022, 1, 1); -CREATE TABLE sales_jan2022 PARTITION OF sales_date FOR VALUES FROM (2022, 1, 1) TO (2022, 2, 1); -CREATE TABLE sales_feb2022 PARTITION OF sales_date FOR VALUES FROM (2022, 2, 1) TO (2022, 3, 1); -CREATE TABLE sales_other PARTITION OF sales_date FOR VALUES FROM (2022, 3, 1) TO (MAXVALUE, MAXVALUE, MAXVALUE); - -INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES - ('Manager1', 2021, 12, 7), - ('Manager2', 2021, 12, 8), - ('Manager3', 2022, 1, 1), - ('Manager1', 2022, 2, 4), - ('Manager2', 2022, 1, 2), - ('Manager3', 2022, 2, 1), - ('Manager1', 2022, 3, 3), - ('Manager2', 2022, 3, 4), - ('Manager3', 2022, 5, 1); - -SELECT tableoid::regclass, * FROM sales_date; - -ALTER TABLE sales_date MERGE PARTITIONS (sales_jan2022, sales_feb2022) INTO sales_jan_feb2022; - -INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES - ('Manager1', 2022, 1, 10), - ('Manager2', 2022, 2, 10); - -SELECT tableoid::regclass, * FROM sales_date; -DROP TABLE sales_date; - --- --- Test: merge partitions of partitioned table with triggers --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); - -CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10); -CREATE TABLE salespeople10_20 PARTITION OF salespeople FOR VALUES FROM (10) TO (20); -CREATE TABLE salespeople20_30 PARTITION OF salespeople FOR VALUES FROM (20) TO (30); -CREATE TABLE salespeople30_40 PARTITION OF salespeople FOR VALUES FROM (30) TO (40); - -INSERT INTO salespeople VALUES (1, 'Poirot'); - -CREATE OR REPLACE FUNCTION after_insert_row_trigger() RETURNS trigger LANGUAGE 'plpgsql' AS $BODY$ -BEGIN - RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; - RETURN NULL; -END; -$BODY$; - -CREATE TRIGGER salespeople_after_insert_statement_trigger - AFTER INSERT - ON salespeople - FOR EACH STATEMENT - EXECUTE PROCEDURE after_insert_row_trigger('salespeople'); - -CREATE TRIGGER salespeople_after_insert_row_trigger - AFTER INSERT - ON salespeople - FOR EACH ROW - EXECUTE PROCEDURE after_insert_row_trigger('salespeople'); - --- 2 triggers should fire here (row + statement): -INSERT INTO salespeople VALUES (10, 'May'); --- 1 trigger should fire here (row): -INSERT INTO salespeople10_20 VALUES (19, 'Ivanov'); - -ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40; - --- 2 triggers should fire here (row + statement): -INSERT INTO salespeople VALUES (20, 'Smirnoff'); --- 1 trigger should fire here (row): -INSERT INTO salespeople10_40 VALUES (30, 'Ford'); - -SELECT * FROM salespeople01_10; -SELECT * FROM salespeople10_40; - -DROP TABLE salespeople; -DROP FUNCTION after_insert_row_trigger(); - --- --- Test: merge partitions with deleted columns --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); - -CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10); --- Create partitions with some deleted columns: -CREATE TABLE salespeople10_20(d1 VARCHAR(30), salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)); -CREATE TABLE salespeople20_30(salesperson_id INT PRIMARY KEY, d2 INT, salesperson_name VARCHAR(30)); -CREATE TABLE salespeople30_40(salesperson_id INT PRIMARY KEY, d3 DATE, salesperson_name VARCHAR(30)); - -INSERT INTO salespeople10_20 VALUES ('dummy value 1', 19, 'Ivanov'); -INSERT INTO salespeople20_30 VALUES (20, 101, 'Smirnoff'); -INSERT INTO salespeople30_40 VALUES (31, now(), 'Popov'); - -ALTER TABLE salespeople10_20 DROP COLUMN d1; -ALTER TABLE salespeople20_30 DROP COLUMN d2; -ALTER TABLE salespeople30_40 DROP COLUMN d3; - -ALTER TABLE salespeople ATTACH PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20); -ALTER TABLE salespeople ATTACH PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30); -ALTER TABLE salespeople ATTACH PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40); - -INSERT INTO salespeople VALUES - (1, 'Poirot'), - (10, 'May'), - (30, 'Ford'); - -ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40; - -select * from salespeople; -select * from salespeople01_10; -select * from salespeople10_40; - -DROP TABLE salespeople; - --- --- Test: merge sub-partitions --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'); -CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'); - -CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_apr2022_01_10 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'); -CREATE TABLE sales_apr2022_10_20 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-10') TO ('2022-04-20'); -CREATE TABLE sales_apr2022_20_30 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-20') TO ('2022-05-01'); -ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); - -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; - -CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date); - -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); - -SELECT tableoid::regclass, * FROM sales_apr2022 ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - -ALTER TABLE sales_apr2022 MERGE PARTITIONS (sales_apr2022_01_10, sales_apr2022_10_20, sales_apr2022_20_30) INTO sales_apr_all; - -SELECT tableoid::regclass, * FROM sales_apr2022 ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - -DROP TABLE sales_range; - --- --- BY LIST partitioning --- - --- --- Test: specific errors for BY LIST partitioning --- -CREATE TABLE sales_list -(salesperson_id INT GENERATED ALWAYS AS IDENTITY, - salesperson_name VARCHAR(30), - sales_state VARCHAR(20), - sales_amount INT, - sales_date DATE) -PARTITION BY LIST (sales_state); -CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki'); -CREATE TABLE sales_west PARTITION OF sales_list FOR VALUES IN ('Lisbon', 'New York', 'Madrid'); -CREATE TABLE sales_east PARTITION OF sales_list FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'); -CREATE TABLE sales_central PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'); -CREATE TABLE sales_others PARTITION OF sales_list DEFAULT; - - -CREATE TABLE sales_list2 (LIKE sales_list) PARTITION BY LIST (sales_state); -CREATE TABLE sales_nord2 PARTITION OF sales_list2 FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki'); -CREATE TABLE sales_others2 PARTITION OF sales_list2 DEFAULT; - - -CREATE TABLE sales_external (LIKE sales_list); -CREATE TABLE sales_external2 (vch VARCHAR(5)); - --- ERROR -ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_external) INTO sales_all; --- ERROR -ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_external2) INTO sales_all; --- ERROR -ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_nord2, sales_east) INTO sales_all; - -DROP TABLE sales_external2; -DROP TABLE sales_external; -DROP TABLE sales_list2; -DROP TABLE sales_list; - --- --- Test: BY LIST partitioning, MERGE PARTITIONS with data --- -CREATE TABLE sales_list -(salesperson_id INT GENERATED ALWAYS AS IDENTITY, - salesperson_name VARCHAR(30), - sales_state VARCHAR(20), - sales_amount INT, - sales_date DATE) -PARTITION BY LIST (sales_state); - -CREATE INDEX sales_list_salesperson_name_idx ON sales_list USING btree (salesperson_name); -CREATE INDEX sales_list_sales_state_idx ON sales_list USING btree (sales_state); - -CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki'); -CREATE TABLE sales_west PARTITION OF sales_list FOR VALUES IN ('Lisbon', 'New York', 'Madrid'); -CREATE TABLE sales_east PARTITION OF sales_list FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'); -CREATE TABLE sales_central PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'); -CREATE TABLE sales_others PARTITION OF sales_list DEFAULT; - -INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES - ('Trump', 'Beijing', 1000, '2022-03-01'), - ('Smirnoff', 'New York', 500, '2022-03-03'), - ('Ford', 'St. Petersburg', 2000, '2022-03-05'), - ('Ivanov', 'Warsaw', 750, '2022-03-04'), - ('Deev', 'Lisbon', 250, '2022-03-07'), - ('Poirot', 'Berlin', 1000, '2022-03-01'), - ('May', 'Helsinki', 1200, '2022-03-06'), - ('Li', 'Vladivostok', 1150, '2022-03-09'), - ('May', 'Helsinki', 1200, '2022-03-11'), - ('Halder', 'Oslo', 800, '2022-03-02'), - ('Muller', 'Madrid', 650, '2022-03-05'), - ('Smith', 'Kyiv', 350, '2022-03-10'), - ('Gandi', 'Warsaw', 150, '2022-03-08'), - ('Plato', 'Lisbon', 950, '2022-03-05'); - --- show partitions with conditions: -EXECUTE get_partition_info('{sales_list}'); - -ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_central) INTO sales_all; - --- show partitions with conditions: -EXECUTE get_partition_info('{sales_list}'); - -SELECT tableoid::regclass, * FROM sales_list ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - --- Use indexscan for testing indexes after merging partitions -SET enable_seqscan = OFF; - -EXPLAIN (COSTS OFF) SELECT * FROM sales_all WHERE sales_state = 'Warsaw'; -SELECT * FROM sales_all WHERE sales_state = 'Warsaw'; -EXPLAIN (COSTS OFF) SELECT * FROM sales_list WHERE sales_state = 'Warsaw'; -SELECT * FROM sales_list WHERE sales_state = 'Warsaw'; -EXPLAIN (COSTS OFF) SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov'; -SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov'; - -RESET enable_seqscan; - -DROP TABLE sales_list; - --- --- Try to MERGE partitions of another table. --- -CREATE TABLE t1 (i int, a int, b int, c int) PARTITION BY RANGE (a, b); -CREATE TABLE t1p1 PARTITION OF t1 FOR VALUES FROM (1, 1) TO (1, 2); -CREATE TABLE t2 (i int, t text) PARTITION BY RANGE (t); -CREATE TABLE t2pa PARTITION OF t2 FOR VALUES FROM ('A') TO ('C'); -CREATE TABLE t3 (i int, t text); - --- ERROR -ALTER TABLE t2 MERGE PARTITIONS (t1p1, t2pa) INTO t2p; --- ERROR -ALTER TABLE t2 MERGE PARTITIONS (t2pa, t3) INTO t2p; - -DROP TABLE t3; -DROP TABLE t2; -DROP TABLE t1; - - --- --- Check the partition index name if the partition name is the same as one --- of the merged partitions. --- -CREATE TABLE t (i int, PRIMARY KEY(i)) PARTITION BY RANGE (i); - -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); - -CREATE INDEX tidx ON t(i); -ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2; - --- Indexname values should be 'tp_1_2_pkey' and 'tp_1_2_i_idx'. -\d+ tp_1_2 - -DROP TABLE t; - --- --- Try to MERGE partitions of temporary table. --- -BEGIN; -SHOW search_path; -CREATE TEMP TABLE t (i int) PARTITION BY RANGE (i) ON COMMIT DROP; -CREATE TEMP TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TEMP TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -CREATE TEMP TABLE tp_2_3 PARTITION OF t FOR VALUES FROM (2) TO (3); -CREATE TEMP TABLE tp_3_4 PARTITION OF t FOR VALUES FROM (3) TO (4); - -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO pg_temp.tp_0_2; -ALTER TABLE t MERGE PARTITIONS (tp_0_2, tp_2_3) INTO pg_temp.tp_0_3; - --- Partition should be temporary. -EXECUTE get_partition_info('{t}'); --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp_0_3, tp_3_4) INTO tp_0_4; -ROLLBACK; - --- --- Try mixing permanent and temporary partitions. --- -BEGIN; -SET search_path = partitions_merge_schema, pg_temp, public; -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); - -SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass; -EXECUTE get_partition_info('{t}'); -SAVEPOINT s; - -SET search_path = pg_temp, partitions_merge_schema, public; --- Can't merge persistent partitions into a temporary partition -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; - -ROLLBACK TO SAVEPOINT s; -SET search_path = partitions_merge_schema, public; --- Can't merge persistent partitions into a temporary partition -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO pg_temp.tp_0_2; -ROLLBACK; - -BEGIN; -SET search_path = pg_temp, partitions_merge_schema, public; -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); - -SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass; -EXECUTE get_partition_info('{t}'); - -SET search_path = partitions_merge_schema, pg_temp, public; - --- Can't merge temporary partitions into a persistent partition -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -ROLLBACK; - -DEALLOCATE get_partition_info; - --- Check the new partition inherits parent's tablespace -SET search_path = partitions_merge_schema, public; -CREATE TABLE t (i int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) - PARTITION BY RANGE (i) TABLESPACE regress_tblspace; -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -SELECT tablename, tablespace FROM pg_tables - WHERE tablename IN ('t', 'tp_0_2') AND schemaname = 'partitions_merge_schema' - ORDER BY tablename COLLATE "C", tablespace COLLATE "C"; -SELECT tablename, indexname, tablespace FROM pg_indexes - WHERE tablename IN ('t', 'tp_0_2') AND schemaname = 'partitions_merge_schema' - ORDER BY tablename COLLATE "C", indexname COLLATE "C", tablespace COLLATE "C"; -DROP TABLE t; - --- Check the new partition inherits parent's table access method -SET search_path = partitions_merge_schema, public; -CREATE ACCESS METHOD partitions_merge_heap TYPE TABLE HANDLER heap_tableam_handler; -CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partitions_merge_heap; -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -SELECT c.relname, a.amname -FROM pg_class c JOIN pg_am a ON c.relam = a.oid -WHERE c.oid IN ('t'::regclass, 'tp_0_2'::regclass) -ORDER BY c.relname COLLATE "C"; -DROP TABLE t; -DROP ACCESS METHOD partitions_merge_heap; - --- Test permission checks. The user needs to own the parent table and all --- the merging partitions to do the merge. -CREATE ROLE regress_partition_merge_alice; -CREATE ROLE regress_partition_merge_bob; -GRANT ALL ON SCHEMA partitions_merge_schema TO regress_partition_merge_alice; -GRANT ALL ON SCHEMA partitions_merge_schema TO regress_partition_merge_bob; - -SET SESSION AUTHORIZATION regress_partition_merge_alice; -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); - -SET SESSION AUTHORIZATION regress_partition_merge_bob; --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -RESET SESSION AUTHORIZATION; - -ALTER TABLE t OWNER TO regress_partition_merge_bob; -SET SESSION AUTHORIZATION regress_partition_merge_bob; --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -RESET SESSION AUTHORIZATION; - -ALTER TABLE tp_0_1 OWNER TO regress_partition_merge_bob; -SET SESSION AUTHORIZATION regress_partition_merge_bob; --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -RESET SESSION AUTHORIZATION; - -ALTER TABLE tp_1_2 OWNER TO regress_partition_merge_bob; -SET SESSION AUTHORIZATION regress_partition_merge_bob; --- Ok: -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; -RESET SESSION AUTHORIZATION; - -DROP TABLE t; - --- Test: we can't merge partitions with different owners -CREATE TABLE tp_0_1(i int); -ALTER TABLE tp_0_1 OWNER TO regress_partition_merge_alice; -CREATE TABLE tp_1_2(i int); -ALTER TABLE tp_1_2 OWNER TO regress_partition_merge_bob; - -CREATE TABLE t (i int) PARTITION BY RANGE (i); - -ALTER TABLE t ATTACH PARTITION tp_0_1 FOR VALUES FROM (0) TO (1); -ALTER TABLE t ATTACH PARTITION tp_1_2 FOR VALUES FROM (1) TO (2); - --- Owner is 'regress_partition_merge_alice': -\dt tp_0_1 --- Owner is 'regress_partition_merge_bob': -\dt tp_1_2 - --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; - -DROP TABLE t; -REVOKE ALL ON SCHEMA partitions_merge_schema FROM regress_partition_merge_alice; -REVOKE ALL ON SCHEMA partitions_merge_schema FROM regress_partition_merge_bob; -DROP ROLE regress_partition_merge_alice; -DROP ROLE regress_partition_merge_bob; - - --- Test for hash partitioned table -CREATE TABLE t (i int) PARTITION BY HASH(i); -CREATE TABLE tp1 PARTITION OF t FOR VALUES WITH (MODULUS 2, REMAINDER 0); -CREATE TABLE tp2 PARTITION OF t FOR VALUES WITH (MODULUS 2, REMAINDER 1); - --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp1, tp2) INTO tp3; - --- ERROR -ALTER TABLE t MERGE PARTITIONS (tp1) INTO tp3; - -DROP TABLE t; - - --- Test for merged partition properties: --- * STATISTICS is empty --- * COMMENT is empty --- * DEFAULTS are the same as DEFAULTS for partitioned table --- * STORAGE is the same as STORAGE for partitioned table --- * GENERATED and CONSTRAINTS are the same as GENERATED and CONSTRAINTS for partitioned table --- * TRIGGERS are the same as TRIGGERS for partitioned table -\set HIDE_TOAST_COMPRESSION false - -CREATE TABLE t -(i int NOT NULL, - t text STORAGE EXTENDED COMPRESSION pglz DEFAULT 'default_t', - b bigint, - d date GENERATED ALWAYS as ('2022-01-01') STORED) PARTITION BY RANGE (abs(i)); -COMMENT ON COLUMN t.i IS 't1.i'; - -CREATE TABLE tp_0_1 -(i int NOT NULL, - t text STORAGE MAIN DEFAULT 'default_tp_0_1', - b bigint, - d date GENERATED ALWAYS as ('2022-02-02') STORED); -ALTER TABLE t ATTACH PARTITION tp_0_1 FOR VALUES FROM (0) TO (1); -COMMENT ON COLUMN tp_0_1.i IS 'tp_0_1.i'; - -CREATE TABLE tp_1_2 -(i int NOT NULL, - t text STORAGE MAIN DEFAULT 'default_tp_1_2', - b bigint, - d date GENERATED ALWAYS as ('2022-03-03') STORED); -ALTER TABLE t ATTACH PARTITION tp_1_2 FOR VALUES FROM (1) TO (2); -COMMENT ON COLUMN tp_1_2.i IS 'tp_1_2.i'; - -CREATE STATISTICS t_stat (DEPENDENCIES) on i, b from t; -CREATE STATISTICS tp_0_1_stat (DEPENDENCIES) on i, b from tp_0_1; -CREATE STATISTICS tp_1_2_stat (DEPENDENCIES) on i, b from tp_1_2; - -ALTER TABLE t ADD CONSTRAINT t_b_check CHECK (b > 0); -ALTER TABLE t ADD CONSTRAINT t_b_check1 CHECK (b > 0) NOT ENFORCED; -ALTER TABLE t ADD CONSTRAINT t_b_check2 CHECK (b > 0) NOT VALID; -ALTER TABLE t ADD CONSTRAINT t_b_nn NOT NULL b NOT VALID; - -INSERT INTO tp_0_1(i, t, b) VALUES(0, DEFAULT, 1); -INSERT INTO tp_1_2(i, t, b) VALUES(1, DEFAULT, 2); -CREATE OR REPLACE FUNCTION trigger_function() RETURNS trigger LANGUAGE 'plpgsql' AS -$BODY$ -BEGIN - RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; - RETURN new; -END; -$BODY$; - -CREATE TRIGGER t_before_insert_row_trigger BEFORE INSERT ON t FOR EACH ROW - EXECUTE PROCEDURE trigger_function('t'); -CREATE TRIGGER tp_0_1_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW - EXECUTE PROCEDURE trigger_function('tp_0_1'); -CREATE TRIGGER tp_1_2_before_insert_row_trigger BEFORE INSERT ON tp_1_2 FOR EACH ROW - EXECUTE PROCEDURE trigger_function('tp_1_2'); - -\d+ tp_0_1 -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_1; -\d+ tp_0_1 - -INSERT INTO t(i, t, b) VALUES(1, DEFAULT, 3); -SELECT tableoid::regclass, * FROM t ORDER BY b; -DROP TABLE t; -DROP FUNCTION trigger_function(); -\set HIDE_TOAST_COMPRESSION true - - --- Test MERGE PARTITIONS with not valid foreign key constraint -CREATE TABLE t (i INT PRIMARY KEY) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -INSERT INTO t VALUES (0), (1); -CREATE TABLE t_fk (i INT); -INSERT INTO t_fk VALUES (1), (2); -ALTER TABLE t_fk ADD CONSTRAINT t_fk_i_fkey FOREIGN KEY (i) REFERENCES t NOT VALID; -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; - --- Should be NOT VALID FOREIGN KEY -\d tp_0_2 --- ERROR -ALTER TABLE t_fk VALIDATE CONSTRAINT t_fk_i_fkey; - -DROP TABLE t_fk; -DROP TABLE t; - --- Test MERGE PARTITIONS with not enforced foreign key constraint -CREATE TABLE t (i INT PRIMARY KEY) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -INSERT INTO t VALUES (0), (1); -CREATE TABLE t_fk (i INT); -INSERT INTO t_fk VALUES (1), (2); - -ALTER TABLE t_fk ADD CONSTRAINT t_fk_i_fkey FOREIGN KEY (i) REFERENCES t NOT ENFORCED; -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; - --- Should be NOT ENFORCED FOREIGN KEY -\d tp_0_2 --- ERROR -ALTER TABLE t_fk ALTER CONSTRAINT t_fk_i_fkey ENFORCED; - -DROP TABLE t_fk; -DROP TABLE t; - - --- Test for recomputation of stored generated columns. -CREATE TABLE t (i int, tab_id int generated always as (tableoid) stored) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -ALTER TABLE t ADD CONSTRAINT cc CHECK(tableoid <> 123456789); -INSERT INTO t VALUES (0), (1); - --- Should be 0 because partition identifier for row with i=0 is different from --- partition identifier for row with i=1. -SELECT count(*) FROM t WHERE i = 0 AND tab_id IN (SELECT tab_id FROM t WHERE i = 1); - --- "tab_id" column (stored generated column) with "tableoid" attribute requires --- recomputation here. -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; - --- Should be 1 because partition identifier for row with i=0 is the same as --- partition identifier for row with i=1. -SELECT count(*) FROM t WHERE i = 0 AND tab_id IN (SELECT tab_id FROM t WHERE i = 1); - -DROP TABLE t; - - --- Test for generated columns (different order of columns in partitioned table --- and partitions). -CREATE TABLE t (i int, g int GENERATED ALWAYS AS (i + tableoid::int)) PARTITION BY RANGE (i); -CREATE TABLE tp_1 (g int GENERATED ALWAYS AS (i + tableoid::int), i int); -CREATE TABLE tp_2 (g int GENERATED ALWAYS AS (i + tableoid::int), i int); -ALTER TABLE t ATTACH PARTITION tp_1 FOR VALUES FROM (-1) TO (10); -ALTER TABLE t ATTACH PARTITION tp_2 FOR VALUES FROM (10) TO (20); -ALTER TABLE t ADD CHECK (g > 0); -ALTER TABLE t ADD CHECK (i > 0); -INSERT INTO t VALUES (5), (15); - -ALTER TABLE t MERGE PARTITIONS (tp_1, tp_2) INTO tp_12; - -INSERT INTO t VALUES (16); --- ERROR -INSERT INTO t VALUES (0); --- Should be 3 rows: (5), (15), (16): -SELECT i FROM t ORDER BY i; --- Should be 1 because for the same tableoid (15 + tableoid) = (5 + tableoid) + 10: -SELECT count(*) FROM t WHERE i = 15 AND g IN (SELECT g + 10 FROM t WHERE i = 5); - -DROP TABLE t; - --- A merged partition needs its own TOAST table; otherwise an out-of-line --- varlena value carried over from one of the merging partitions has --- nowhere to be stored. SET STORAGE EXTERNAL forces externalization --- for any value over the TOAST threshold, so a string over that threshold --- suffices to exercise the toast-table dependency. -CREATE TABLE t (a text) PARTITION BY RANGE(a); -ALTER TABLE t ALTER COLUMN a SET STORAGE EXTERNAL; -CREATE TABLE tp_def PARTITION OF t DEFAULT; -CREATE TABLE tp_2_3 PARTITION OF t FOR VALUES FROM ('2') TO ('3'); -INSERT INTO t SELECT repeat('1', 10000); -ALTER TABLE t MERGE PARTITIONS (tp_def, tp_2_3) INTO tp_merged; -SELECT reltoastrelid <> 0 AS has_toast, - pg_relation_size(reltoastrelid) > 0 AS toast_used - FROM pg_class WHERE relname = 'tp_merged'; -SELECT length(a) FROM t; -DROP TABLE t; - --- Tablespace selection for the new merged partition mirrors --- CREATE TABLE ... PARTITION OF: the partitioned root's explicit --- tablespace wins; otherwise default_tablespace applies; otherwise the --- database default is used. -CREATE TABLE t (i int) PARTITION BY RANGE(i) TABLESPACE regress_tblspace; -CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); -CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); -INSERT INTO t SELECT generate_series(0, 9); -ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; -SELECT spcname FROM pg_class c LEFT JOIN pg_tablespace s - ON c.reltablespace = s.oid WHERE c.relname = 'tp_merged'; -DROP TABLE t; - --- Parent has no explicit tablespace, but default_tablespace is set: the --- new partition lands on default_tablespace. -CREATE TABLE t (i int) PARTITION BY RANGE(i); -CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); -CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); -INSERT INTO t SELECT generate_series(0, 9); -SET default_tablespace TO regress_tblspace; -ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; -RESET default_tablespace; -SELECT spcname FROM pg_class c LEFT JOIN pg_tablespace s - ON c.reltablespace = s.oid WHERE c.relname = 'tp_merged'; -DROP TABLE t; - -CREATE TABLE t (i int) PARTITION BY RANGE(i); -CREATE TABLE tp_0_5 PARTITION OF t FOR VALUES FROM (0) TO (5); -CREATE TABLE tp_5_10 PARTITION OF t FOR VALUES FROM (5) TO (10); -INSERT INTO t SELECT generate_series(0, 9); --- pg_global is rejected when picked up from default_tablespace. -SET default_tablespace TO pg_global; -ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; -- fails -RESET default_tablespace; --- Parent has no explicit tablespace and default_tablespace is empty: the --- new partition uses the database default (reltablespace = 0). -ALTER TABLE t MERGE PARTITIONS (tp_0_5, tp_5_10) INTO tp_merged; -SELECT reltablespace FROM pg_class WHERE relname = 'tp_merged'; -DROP TABLE t; - - -RESET search_path; - --- -DROP SCHEMA partitions_merge_schema; -DROP SCHEMA partitions_merge_schema2; diff --git a/src/test/regress/sql/partition_split.sql b/src/test/regress/sql/partition_split.sql deleted file mode 100644 index ffd15e7f969..00000000000 --- a/src/test/regress/sql/partition_split.sql +++ /dev/null @@ -1,1263 +0,0 @@ --- --- PARTITION_SPLIT --- Tests for "ALTER TABLE ... SPLIT PARTITION ..." command --- - -CREATE SCHEMA partition_split_schema; -CREATE SCHEMA partition_split_schema2; -SET search_path = partition_split_schema, public; - --- --- BY RANGE partitioning --- - --- --- Test for error codes --- -CREATE TABLE sales_range (salesperson_id int, sales_date date) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_xxx INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_jan2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_jan2022 FOR VALUES IN ('2022-05-01', '2022-06-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-02-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-10-01')); - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-01-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- ERROR --- (We can create partition with the same name as split partition, but can't create two partitions with the same name) -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb_mar_apr2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_feb_mar_apr2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION partition_split_schema.sales_feb2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- ERROR -ALTER TABLE sales_feb_mar_apr2022 SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_jan2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-01')); - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-02-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- Tests for spaces between partitions, them should be executed without DEFAULT partition -ALTER TABLE sales_range DETACH PARTITION sales_others; - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-02') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- Check the source partition not in the search path -SET search_path = partition_split_schema2, public; -ALTER TABLE partition_split_schema.sales_range -SPLIT PARTITION partition_split_schema.sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -SET search_path = partition_split_schema, public; -\d+ sales_range - -DROP TABLE sales_range; -DROP TABLE sales_others; - --- Additional tests for error messages, no default partition -CREATE TABLE sales_range (sales_date date) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-01')); - -DROP TABLE sales_range; - --- --- Add rows into partitioned table then split partition --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; - -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); - -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; -DROP TABLE sales_range CASCADE; - --- --- Add split partition, then add rows into partitioned table --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; - -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); - --- Split partition, also check schema qualification of new partitions -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION partition_split_schema.sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION partition_split_schema2.sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); -\d+ sales_range - -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - -DROP TABLE sales_range CASCADE; - --- --- Test for: --- * composite partition key; --- * GENERATED column; --- * column with DEFAULT value. --- -CREATE TABLE sales_date (salesperson_name VARCHAR(30), sales_year INT, sales_month INT, sales_day INT, - sales_date VARCHAR(10) GENERATED ALWAYS AS - (LPAD(sales_year::text, 4, '0') || '.' || LPAD(sales_month::text, 2, '0') || '.' || LPAD(sales_day::text, 2, '0')) STORED, - sales_department VARCHAR(30) DEFAULT 'Sales department') - PARTITION BY RANGE (sales_year, sales_month, sales_day); - -CREATE TABLE sales_dec2021 PARTITION OF sales_date FOR VALUES FROM (2021, 12, 1) TO (2022, 1, 1); -CREATE TABLE sales_jan_feb2022 PARTITION OF sales_date FOR VALUES FROM (2022, 1, 1) TO (2022, 3, 1); -CREATE TABLE sales_other PARTITION OF sales_date FOR VALUES FROM (2022, 3, 1) TO (MAXVALUE, MAXVALUE, MAXVALUE); - -INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES - ('Manager1', 2021, 12, 7), - ('Manager2', 2021, 12, 8), - ('Manager3', 2022, 1, 1), - ('Manager1', 2022, 2, 4), - ('Manager2', 2022, 1, 2), - ('Manager3', 2022, 2, 1), - ('Manager1', 2022, 3, 3), - ('Manager2', 2022, 3, 4), - ('Manager3', 2022, 5, 1); - -SELECT tableoid::regclass, * FROM sales_date ORDER BY tableoid::regclass::text COLLATE "C", sales_year, sales_month, sales_day; - -ALTER TABLE sales_date SPLIT PARTITION sales_jan_feb2022 INTO - (PARTITION sales_jan2022 FOR VALUES FROM (2022, 1, 1) TO (2022, 2, 1), - PARTITION sales_feb2022 FOR VALUES FROM (2022, 2, 1) TO (2022, 3, 1)); - -INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES - ('Manager1', 2022, 1, 10), - ('Manager2', 2022, 2, 10); - -SELECT tableoid::regclass, * FROM sales_date ORDER BY tableoid::regclass::text COLLATE "C", sales_year, sales_month, sales_day; - -DROP TABLE sales_date CASCADE; - --- --- Test: split DEFAULT partition; use an index on partition key; check index after split --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; -CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date); - -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); - -SELECT * FROM sales_others; -SELECT * FROM pg_indexes WHERE tablename = 'sales_others' and schemaname = 'partition_split_schema' ORDER BY indexname COLLATE "C"; - -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'), - PARTITION sales_others DEFAULT); - --- Use indexscan for testing indexes -SET enable_seqscan = OFF; - -EXPLAIN (COSTS OFF) SELECT * FROM sales_feb2022 where sales_date > '2022-01-01'; -SELECT * FROM sales_feb2022 where sales_date > '2022-01-01'; -EXPLAIN (COSTS OFF) SELECT * FROM sales_mar2022 where sales_date > '2022-01-01'; -SELECT * FROM sales_mar2022 where sales_date > '2022-01-01'; -EXPLAIN (COSTS OFF) SELECT * FROM sales_apr2022 where sales_date > '2022-01-01'; -SELECT * FROM sales_apr2022 where sales_date > '2022-01-01'; -EXPLAIN (COSTS OFF) SELECT * FROM sales_others where sales_date > '2022-01-01'; -SELECT * FROM sales_others where sales_date > '2022-01-01'; - -RESET enable_seqscan; - -SELECT * FROM pg_indexes -WHERE tablename in ('sales_feb2022', 'sales_mar2022', 'sales_apr2022', 'sales_others') -AND schemaname = 'partition_split_schema' -ORDER BY indexname COLLATE "C"; - -DROP TABLE sales_range CASCADE; - --- --- Test: some cases for splitting DEFAULT partition (different bounds) --- -CREATE TABLE sales_range (salesperson_id INT, sales_date date) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; - --- sales_error intersects with sales_dec2021 (lower bound) --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_error FOR VALUES FROM ('2021-12-30') TO ('2022-02-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); - --- sales_error intersects with sales_feb2022 (upper bound) --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_error FOR VALUES FROM ('2022-01-01') TO ('2022-02-02'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); - --- sales_error intersects with sales_dec2021 (inside bound) --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_error FOR VALUES FROM ('2021-12-10') TO ('2021-12-20'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); - --- sales_error intersects with sales_dec2021 (exactly the same bounds) --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_error FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); - --- ERROR -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_jan2022 FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01')); - --- no error: bounds of sales_noerror are between sales_dec2021 and sales_feb2022 -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_noerror FOR VALUES FROM ('2022-01-10') TO ('2022-01-20'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); - -DROP TABLE sales_range; - -CREATE TABLE sales_range (sales_date date) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; - --- no error: bounds of sales_noerror are equal to lower and upper bounds of sales_dec2021 and sales_feb2022 -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_dec2021 FOR VALUES FROM ('2021-12-01') TO ('2022-01-01'), - PARTITION sales_noerror FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); - -DROP TABLE sales_range; - --- --- Test: split partition with CHECK and FOREIGN KEY CONSTRAINTs on partitioned table --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)); -INSERT INTO salespeople VALUES (1, 'Poirot'); - -CREATE TABLE sales_range ( -salesperson_id INT REFERENCES salespeople(salesperson_id), -sales_amount INT CHECK (sales_amount > 1), -sales_date DATE) PARTITION BY RANGE (sales_date); - -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; - -SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_feb_mar_apr2022'::regclass::oid ORDER BY conname COLLATE "C"; - -ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO - (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'), - PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01')); - --- We should see the same CONSTRAINTs as on sales_feb_mar_apr2022 partition -SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_feb2022'::regclass::oid ORDER BY conname COLLATE "C"; -SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_mar2022'::regclass::oid ORDER BY conname COLLATE "C"; -SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_apr2022'::regclass::oid ORDER BY conname COLLATE "C"; - --- ERROR -INSERT INTO sales_range VALUES (1, 0, '2022-03-11'); --- ERROR -INSERT INTO sales_range VALUES (-1, 10, '2022-03-11'); --- ok -INSERT INTO sales_range VALUES (1, 10, '2022-03-11'); - -DROP TABLE sales_range CASCADE; -DROP TABLE salespeople CASCADE; - --- --- Test: split partition on partitioned table in case of existing FOREIGN KEY reference from another table --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); -CREATE TABLE sales (salesperson_id INT REFERENCES salespeople(salesperson_id), sales_amount INT, sales_date DATE); - -CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10); -CREATE TABLE salespeople10_40 PARTITION OF salespeople FOR VALUES FROM (10) TO (40); - -INSERT INTO salespeople VALUES - (1, 'Poirot'), - (10, 'May'), - (19, 'Ivanov'), - (20, 'Smirnoff'), - (30, 'Ford'); - -INSERT INTO sales VALUES - (1, 100, '2022-03-01'), - (1, 110, '2022-03-02'), - (10, 150, '2022-03-01'), - (10, 90, '2022-03-03'), - (19, 200, '2022-03-04'), - (20, 50, '2022-03-12'), - (20, 170, '2022-03-02'), - (30, 30, '2022-03-04'); - -SELECT tableoid::regclass, * FROM salespeople ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - -ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO - (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20), - PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30), - PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40)); - -SELECT tableoid::regclass, * FROM salespeople ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - --- ERROR -INSERT INTO sales VALUES (40, 50, '2022-03-04'); --- ok -INSERT INTO sales VALUES (30, 50, '2022-03-04'); - -DROP TABLE sales CASCADE; -DROP TABLE salespeople CASCADE; - --- --- Test: split partition of partitioned table with triggers --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); - -CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10); -CREATE TABLE salespeople10_40 PARTITION OF salespeople FOR VALUES FROM (10) TO (40); - -INSERT INTO salespeople VALUES (1, 'Poirot'); - -CREATE OR REPLACE FUNCTION after_insert_row_trigger() RETURNS trigger LANGUAGE 'plpgsql' AS $BODY$ -BEGIN - RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; - RETURN NULL; -END; -$BODY$; - -CREATE TRIGGER salespeople_after_insert_statement_trigger - AFTER INSERT - ON salespeople - FOR EACH STATEMENT - EXECUTE PROCEDURE after_insert_row_trigger('salespeople'); - -CREATE TRIGGER salespeople_after_insert_row_trigger - AFTER INSERT - ON salespeople - FOR EACH ROW - EXECUTE PROCEDURE after_insert_row_trigger('salespeople'); - --- 2 triggers should fire here (row + statement): -INSERT INTO salespeople VALUES (10, 'May'); --- 1 trigger should fire here (row): -INSERT INTO salespeople10_40 VALUES (19, 'Ivanov'); - -ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO - (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20), - PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30), - PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40)); - --- 2 triggers should fire here (row + statement): -INSERT INTO salespeople VALUES (20, 'Smirnoff'); --- 1 trigger should fire here (row): -INSERT INTO salespeople30_40 VALUES (30, 'Ford'); - -SELECT tableoid::regclass, * FROM salespeople ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - -DROP TABLE salespeople CASCADE; -DROP FUNCTION after_insert_row_trigger(); - --- --- Test: split partition witch identity column --- If split partition column is identity column, columns of new partitions are identity columns too. --- -CREATE TABLE salespeople(salesperson_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); - -CREATE TABLE salespeople1_2 PARTITION OF salespeople FOR VALUES FROM (1) TO (2); --- Create new partition with identity column: -CREATE TABLE salespeople2_5(salesperson_id INT NOT NULL, salesperson_name VARCHAR(30)); -ALTER TABLE salespeople ATTACH PARTITION salespeople2_5 FOR VALUES FROM (2) TO (5); - -INSERT INTO salespeople (salesperson_name) VALUES ('Poirot'), ('Ivanov'); - -ALTER TABLE salespeople SPLIT PARTITION salespeople2_5 INTO - (PARTITION salespeople2_3 FOR VALUES FROM (2) TO (3), - PARTITION salespeople3_4 FOR VALUES FROM (3) TO (4), - PARTITION salespeople4_5 FOR VALUES FROM (4) TO (5)); - -INSERT INTO salespeople (salesperson_name) VALUES ('May'), ('Ford'); - -SELECT tableoid::regclass, * FROM salespeople ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - --- check new partitions have identity or not after split partition -SELECT attrelid::regclass, attname, attidentity, attgenerated FROM pg_attribute -WHERE attnum > 0 -AND attrelid::regclass IN ( - 'salespeople2_3'::regclass, 'salespeople', 'salespeople2_3', - 'salespeople1_2', 'salespeople3_4', 'salespeople4_5') -ORDER BY attrelid::regclass::text COLLATE "C", attnum; - -DROP TABLE salespeople CASCADE; - --- --- Test: split partition with deleted columns --- -CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id); - -CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10); --- Create new partition with some deleted columns: -CREATE TABLE salespeople10_40(d1 VARCHAR(30), salesperson_id INT PRIMARY KEY, d2 INT, d3 DATE, salesperson_name VARCHAR(30)); - -INSERT INTO salespeople10_40 VALUES - ('dummy value 1', 19, 100, now(), 'Ivanov'), - ('dummy value 2', 20, 101, now(), 'Smirnoff'); - -ALTER TABLE salespeople10_40 DROP COLUMN d1; -ALTER TABLE salespeople10_40 DROP COLUMN d2; -ALTER TABLE salespeople10_40 DROP COLUMN d3; - -ALTER TABLE salespeople ATTACH PARTITION salespeople10_40 FOR VALUES FROM (10) TO (40); - -INSERT INTO salespeople VALUES - (1, 'Poirot'), - (10, 'May'), - (30, 'Ford'); - -ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO - (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20), - PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30), - PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40)); - -SELECT tableoid::regclass, * FROM salespeople ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - -DROP TABLE salespeople CASCADE; - --- --- Test: split sub-partition --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'); -CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'); - -CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_apr_all PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); -ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'); - -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; - -CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date); - -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); - -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - -ALTER TABLE sales_apr2022 SPLIT PARTITION sales_apr_all INTO - (PARTITION sales_apr2022_01_10 FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'), - PARTITION sales_apr2022_10_20 FOR VALUES FROM ('2022-04-10') TO ('2022-04-20'), - PARTITION sales_apr2022_20_30 FOR VALUES FROM ('2022-04-20') TO ('2022-05-01')); - -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - -DROP TABLE sales_range; - --- --- BY LIST partitioning --- - --- --- Test: specific errors for BY LIST partitioning --- -CREATE TABLE sales_list (sales_state VARCHAR(20)) PARTITION BY LIST (sales_state); - -CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki'); -CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Beijing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok'); -CREATE TABLE sales_others PARTITION OF sales_list DEFAULT; - --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok', 'Helsinki'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')); - --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Lisbon', 'Kyiv')); - --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid', NULL), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')); - --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid', 'Melbourne'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')); - --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid', 'Melbourne'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'), - PARTITION sales_others2 DEFAULT); - -DROP TABLE sales_list; - --- Test for non-symbolic comparison of values (numeric values '0' and '0.0' are equal). -CREATE TABLE t (a numeric) PARTITION BY LIST (a); -CREATE TABLE t1 PARTITION OF t FOR VALUES in ('0', '1'); --- ERROR -ALTER TABLE t SPLIT PARTITION t1 INTO - (PARTITION x FOR VALUES IN ('0'), - PARTITION x1 FOR VALUES IN ('0.0', '1')); -DROP TABLE t; - --- --- Test: two specific errors for BY LIST partitioning: --- * new partitions do not have NULL value, which split partition has. --- * new partitions do not have a value that split partition has. --- -CREATE TABLE sales_list(sales_state VARCHAR(20)) PARTITION BY LIST (sales_state); - -CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Helsinki', 'St. Petersburg', 'Oslo'); -CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Beijing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok', NULL); - --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')); - --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', NULL)); - --- ERROR -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'), - PARTITION sales_others DEFAULT, - PARTITION sales_others2 DEFAULT); - -DROP TABLE sales_list; - --- --- Test: BY LIST partitioning, SPLIT PARTITION with data --- -CREATE TABLE sales_list -(salesperson_id SERIAL, - salesperson_name VARCHAR(30), - sales_state VARCHAR(20), - sales_amount INT, - sales_date DATE) -PARTITION BY LIST (sales_state); - -CREATE INDEX sales_list_salesperson_name_idx ON sales_list USING btree (salesperson_name); -CREATE INDEX sales_list_sales_state_idx ON sales_list USING btree (sales_state); - -CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Helsinki', 'St. Petersburg', 'Oslo'); -CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Beijing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok'); -CREATE TABLE sales_others PARTITION OF sales_list DEFAULT; - -INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES - ('Trump', 'Beijing', 1000, '2022-03-01'), - ('Smirnoff', 'New York', 500, '2022-03-03'), - ('Ford', 'St. Petersburg', 2000, '2022-03-05'), - ('Ivanov', 'Warsaw', 750, '2022-03-04'), - ('Deev', 'Lisbon', 250, '2022-03-07'), - ('Poirot', 'Berlin', 1000, '2022-03-01'), - ('May', 'Oslo', 1200, '2022-03-06'), - ('Li', 'Vladivostok', 1150, '2022-03-09'), - ('May', 'Oslo', 1200, '2022-03-11'), - ('Halder', 'Helsinki', 800, '2022-03-02'), - ('Muller', 'Madrid', 650, '2022-03-05'), - ('Smith', 'Kyiv', 350, '2022-03-10'), - ('Gandi', 'Warsaw', 150, '2022-03-08'), - ('Plato', 'Lisbon', 950, '2022-03-05'); - -ALTER TABLE sales_list SPLIT PARTITION sales_all INTO - (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'), - PARTITION sales_east FOR VALUES IN ('Beijing', 'Delhi', 'Vladivostok'), - PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')); - -SELECT tableoid::regclass, * FROM sales_list ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - --- Use indexscan for testing indexes after splitting partition -SET enable_seqscan = OFF; - -EXPLAIN (COSTS OFF) SELECT * FROM sales_central WHERE sales_state = 'Warsaw'; -SELECT * FROM sales_central WHERE sales_state = 'Warsaw'; -EXPLAIN (COSTS OFF) SELECT * FROM sales_list WHERE sales_state = 'Warsaw'; -SELECT * FROM sales_list WHERE sales_state = 'Warsaw'; -EXPLAIN (COSTS OFF) SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov'; -SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov'; - -RESET enable_seqscan; - -DROP TABLE sales_list; - --- --- Test for: --- * split DEFAULT partition to partitions with spaces between bounds; --- * random order of partitions in SPLIT PARTITION command. --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_others PARTITION OF sales_range DEFAULT; - -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-09'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-07'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'), - (14, 'Smith', 510, '2022-05-04'); - -ALTER TABLE sales_range SPLIT PARTITION sales_others INTO - (PARTITION sales_others DEFAULT, - PARTITION sales_mar2022_1decade FOR VALUES FROM ('2022-03-01') TO ('2022-03-10'), - PARTITION sales_jan2022_1decade FOR VALUES FROM ('2022-01-01') TO ('2022-01-10'), - PARTITION sales_feb2022_1decade FOR VALUES FROM ('2022-02-01') TO ('2022-02-10'), - PARTITION sales_apr2022_1decade FOR VALUES FROM ('2022-04-01') TO ('2022-04-10')); - -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - -DROP TABLE sales_range; - --- --- Test for: --- * split non-DEFAULT partition to partitions with spaces between bounds; --- * random order of partitions in SPLIT PARTITION command. --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_all PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-05-01'); - -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-09'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-07'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'); - -ALTER TABLE sales_range SPLIT PARTITION sales_all INTO - (PARTITION sales_mar2022_1decade FOR VALUES FROM ('2022-03-01') TO ('2022-03-10'), - PARTITION sales_jan2022_1decade FOR VALUES FROM ('2022-01-01') TO ('2022-01-10'), - PARTITION sales_feb2022_1decade FOR VALUES FROM ('2022-02-01') TO ('2022-02-10'), - PARTITION sales_apr2022_1decade FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'), - PARTITION sales_others DEFAULT); - -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - -DROP TABLE sales_range; - --- --- Test for split non-DEFAULT partition to DEFAULT partition + partitions --- with spaces between bounds. --- -CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date); -CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01'); -CREATE TABLE sales_all PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01'); - -INSERT INTO sales_range VALUES - (1, 'May', 1000, '2022-01-31'), - (2, 'Smirnoff', 500, '2022-02-10'), - (3, 'Ford', 2000, '2022-04-30'), - (4, 'Ivanov', 750, '2022-04-13'), - (5, 'Deev', 250, '2022-04-07'), - (6, 'Poirot', 150, '2022-02-11'), - (7, 'Li', 175, '2022-03-08'), - (8, 'Ericsson', 185, '2022-02-23'), - (9, 'Muller', 250, '2022-03-11'), - (10, 'Halder', 350, '2022-01-28'), - (11, 'Trump', 380, '2022-04-06'), - (12, 'Plato', 350, '2022-03-19'), - (13, 'Gandi', 377, '2022-01-09'); - -ALTER TABLE sales_range SPLIT PARTITION sales_all INTO - (PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'), - PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'), - PARTITION sales_others DEFAULT); - -INSERT INTO sales_range VALUES (14, 'Smith', 510, '2022-05-04'); - -SELECT tableoid::regclass, * FROM sales_range ORDER BY tableoid::regclass::text COLLATE "C", salesperson_id; - -DROP TABLE sales_range; - --- --- Test that SPLIT PARTITION rejects the degenerate case where the only --- non-DEFAULT replacement partition keeps the original bound and the command --- merely adds a DEFAULT partition. --- -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_50 PARTITION OF t FOR VALUES FROM (0) TO (50); -INSERT INTO t VALUES (1); - --- ERROR -ALTER TABLE t SPLIT PARTITION tp_0_50 INTO - (PARTITION tp_0_50 FOR VALUES FROM (0) TO (50), - PARTITION tp_default DEFAULT); - -DROP TABLE t; - --- --- Test that a LIST split with DEFAULT is not considered degenerate when --- only NULL is removed from the explicit replacement partition. --- -CREATE TABLE t (i int) PARTITION BY LIST (i); -CREATE TABLE tp_null_1 PARTITION OF t FOR VALUES IN (NULL, 1); - -ALTER TABLE t SPLIT PARTITION tp_null_1 INTO - (PARTITION tp_1 FOR VALUES IN (1), - PARTITION tp_default DEFAULT); - -INSERT INTO t VALUES (NULL), (1), (2); -SELECT tableoid::regclass, i FROM t ORDER BY tableoid::regclass::text COLLATE "C", i NULLS FIRST; - -DROP TABLE t; - --- --- Test that the same-bound check for LIST partitioning uses the --- partition operator family, not byte equality. -0.0 and 0.0 have --- different bit patterns but compare equal under float8, so the --- replacement bound (-0.0, 1.0) is the same set as the original --- (0.0, 1.0) and the SPLIT is degenerate. A datumIsEqual()-based --- check would let this through; the partsupfunc-based check correctly --- rejects it. --- -CREATE TABLE t (v float8) PARTITION BY LIST (v); -CREATE TABLE tp_zero_one PARTITION OF t FOR VALUES IN (0.0, 1.0); - --- ERROR -ALTER TABLE t SPLIT PARTITION tp_zero_one INTO - (PARTITION tp_zero_one FOR VALUES IN (-0.0, 1.0), - PARTITION tp_default DEFAULT); - -DROP TABLE t; - --- --- Test that the explicit partition bound cannot extend outside the split --- partition's bound when a DEFAULT partition is specified. --- -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_51 PARTITION OF t FOR VALUES FROM (0) TO (51); -CREATE TABLE tp_51_100 PARTITION OF t FOR VALUES FROM (51) TO (100); - --- ERROR -ALTER TABLE t SPLIT PARTITION tp_0_51 INTO - (PARTITION tp_0_51 FOR VALUES FROM (0) TO (53), - PARTITION tp_default DEFAULT); - -DROP TABLE t; - --- --- Try to SPLIT partition of another table. --- -CREATE TABLE t1(i int, t text) PARTITION BY LIST (t); -CREATE TABLE t1pa PARTITION OF t1 FOR VALUES IN ('A'); -CREATE TABLE t2 (i int, t text) PARTITION BY RANGE (t); - --- ERROR -ALTER TABLE t2 SPLIT PARTITION t1pa INTO - (PARTITION t2a FOR VALUES FROM ('A') TO ('B'), - PARTITION t2b FOR VALUES FROM ('B') TO ('C')); - -DROP TABLE t2; -DROP TABLE t1; - --- --- Try to SPLIT partition of temporary table. --- -CREATE TEMP TABLE t (i int) PARTITION BY RANGE (i); -CREATE TEMP TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); - -SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence - FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i - WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass - ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text COLLATE "C"; - --- ERROR -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); - -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION pg_temp.tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION pg_temp.tp_1_2 FOR VALUES FROM (1) TO (2)); - --- Partitions should be temporary. -SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence - FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i - WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass - ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text COLLATE "C"; - -DROP TABLE t; - --- Check the new partitions inherit parent's tablespace -CREATE TABLE t (i int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) - PARTITION BY RANGE (i) TABLESPACE regress_tblspace; -CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); -SELECT tablename, tablespace FROM pg_tables - WHERE tablename IN ('t', 'tp_0_1', 'tp_1_2') AND schemaname = 'partition_split_schema' - ORDER BY tablename COLLATE "C", tablespace COLLATE "C"; -SELECT tablename, indexname, tablespace FROM pg_indexes - WHERE tablename IN ('t', 'tp_0_1', 'tp_1_2') AND schemaname = 'partition_split_schema' - ORDER BY tablename COLLATE "C", indexname COLLATE "C", tablespace COLLATE "C"; -DROP TABLE t; - --- Check new partitions inherits parent's table access method -CREATE ACCESS METHOD partition_split_heap TYPE TABLE HANDLER heap_tableam_handler; -CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partition_split_heap; -CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); -SELECT c.relname, a.amname -FROM pg_class c JOIN pg_am a ON c.relam = a.oid -WHERE c.oid IN ('t'::regclass, 'tp_0_1'::regclass, 'tp_1_2'::regclass) -ORDER BY c.relname COLLATE "C"; -DROP TABLE t; -DROP ACCESS METHOD partition_split_heap; - --- Split partition of a temporary table when one of the partitions after --- split has the same name as the partition being split -CREATE TEMP TABLE t (a int) PARTITION BY RANGE (a); -CREATE TEMP TABLE tp_0 PARTITION OF t FOR VALUES FROM (0) TO (2); -ALTER TABLE t SPLIT PARTITION tp_0 INTO - (PARTITION pg_temp.tp_0 FOR VALUES FROM (0) TO (1), - PARTITION pg_temp.tp_1 FOR VALUES FROM (1) TO (2)); -DROP TABLE t; - --- Check defaults and constraints of new partitions -CREATE TABLE t_bigint ( - b bigint, - i int DEFAULT (3+10), - j int DEFAULT 101, - k int GENERATED ALWAYS AS (b+10) STORED -) -PARTITION BY RANGE (b); -CREATE TABLE t_bigint_default PARTITION OF t_bigint DEFAULT; --- Show defaults/constraints before SPLIT PARTITION -\d+ t_bigint -\d+ t_bigint_default -ALTER TABLE t_bigint SPLIT PARTITION t_bigint_default INTO - (PARTITION t_bigint_01_10 FOR VALUES FROM (0) TO (10), - PARTITION t_bigint_default DEFAULT); --- Show defaults/constraints after SPLIT PARTITION -\d+ t_bigint_default -\d+ t_bigint_01_10 -DROP TABLE t_bigint; - --- Test permission checks. The user needs to own the parent table and the --- the partition to split to do the split. -CREATE ROLE regress_partition_split_alice; -CREATE ROLE regress_partition_split_bob; -GRANT ALL ON SCHEMA partition_split_schema TO regress_partition_split_alice; -GRANT ALL ON SCHEMA partition_split_schema TO regress_partition_split_bob; - -SET SESSION AUTHORIZATION regress_partition_split_alice; -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); - -SET SESSION AUTHORIZATION regress_partition_split_bob; -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); --error -RESET SESSION AUTHORIZATION; - -ALTER TABLE t OWNER TO regress_partition_split_bob; -SET SESSION AUTHORIZATION regress_partition_split_bob; -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); --error -RESET SESSION AUTHORIZATION; - -ALTER TABLE tp_0_2 OWNER TO regress_partition_split_bob; -SET SESSION AUTHORIZATION regress_partition_split_bob; -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); --ok -RESET SESSION AUTHORIZATION; - -DROP TABLE t; - --- Test: owner of new partitions should be the same as owner of split partition -CREATE TABLE t (i int) PARTITION BY RANGE (i); - -SET SESSION AUTHORIZATION regress_partition_split_alice; -CREATE TABLE tp_0_2(i int); -RESET SESSION AUTHORIZATION; - -ALTER TABLE t ATTACH PARTITION tp_0_2 FOR VALUES FROM (0) TO (2); - --- Owner is 'regress_partition_split_alice': -\dt tp_0_2 - -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); - --- Owner should be 'regress_partition_split_alice': -\dt tp_0_1 -\dt tp_1_2 - -DROP TABLE t; - --- Test: index of new partitions should be created with same owner as split --- partition -SET SESSION AUTHORIZATION regress_partition_split_alice; -CREATE TABLE t (i int) PARTITION BY RANGE (i); -CREATE TABLE tp_10_20 PARTITION OF t FOR VALUES FROM (10) TO (20); -INSERT INTO t VALUES (11), (16); -CREATE OR REPLACE FUNCTION run_me(integer) RETURNS integer AS $$ -BEGIN - RAISE NOTICE 'you are running me as %', CURRENT_USER; - RETURN $1; -END -$$ LANGUAGE PLPGSQL IMMUTABLE; - --- Owner is 'regress_partition_split_alice': -CREATE INDEX ON t (run_me(i)); -RESET SESSION AUTHORIZATION; - --- Owner should be 'regress_partition_split_alice': -ALTER TABLE t SPLIT PARTITION tp_10_20 INTO - (PARTITION tp_10_15 FOR VALUES FROM (10) TO (15), - PARTITION tp_15_20 FOR VALUES FROM (15) TO (20)); - -DROP TABLE t; -DROP FUNCTION run_me(integer); - -REVOKE ALL ON SCHEMA partition_split_schema FROM regress_partition_split_alice; -REVOKE ALL ON SCHEMA partition_split_schema FROM regress_partition_split_bob; -DROP ROLE regress_partition_split_alice; -DROP ROLE regress_partition_split_bob; - --- Test for hash partitioned table -CREATE TABLE t (i int) PARTITION BY HASH(i); -CREATE TABLE tp1 PARTITION OF t FOR VALUES WITH (MODULUS 2, REMAINDER 0); -CREATE TABLE tp2 PARTITION OF t FOR VALUES WITH (MODULUS 2, REMAINDER 1); - --- ERROR -ALTER TABLE t SPLIT PARTITION tp1 INTO - (PARTITION tp1_1 FOR VALUES WITH (MODULUS 4, REMAINDER 0), - PARTITION tp1_2 FOR VALUES WITH (MODULUS 4, REMAINDER 2)); - --- ERROR -ALTER TABLE t SPLIT PARTITION tp1 INTO - (PARTITION tp1_1 FOR VALUES WITH (MODULUS 4, REMAINDER 0)); - -DROP TABLE t; - - --- Test for split partition properties: --- * STATISTICS is empty --- * COMMENT is empty --- * DEFAULTS are the same as DEFAULTS for partitioned table --- * STORAGE is the same as STORAGE for partitioned table --- * GENERATED and CONSTRAINTS are the same as GENERATED and CONSTRAINTS for partitioned table --- * TRIGGERS are the same as TRIGGERS for partitioned table - -CREATE TABLE t -(i int NOT NULL, - t text STORAGE EXTENDED COMPRESSION pglz DEFAULT 'default_t', - b bigint, - d date GENERATED ALWAYS as ('2022-01-01') STORED) PARTITION BY RANGE (abs(i)); -COMMENT ON COLUMN t.i IS 't1.i'; - -CREATE TABLE tp_x -(i int NOT NULL, - t text STORAGE MAIN DEFAULT 'default_tp_x', - b bigint, - d date GENERATED ALWAYS as ('2022-02-02') STORED); -ALTER TABLE t ATTACH PARTITION tp_x FOR VALUES FROM (0) TO (2); -COMMENT ON COLUMN tp_x.i IS 'tp_x.i'; - -CREATE STATISTICS t_stat (DEPENDENCIES) on i, b from t; -CREATE STATISTICS tp_x_stat (DEPENDENCIES) on i, b from tp_x; - -ALTER TABLE t ADD CONSTRAINT t_b_check CHECK (b > 0); -ALTER TABLE t ADD CONSTRAINT t_b_check1 CHECK (b > 0) NOT ENFORCED; -ALTER TABLE t ADD CONSTRAINT t_b_check2 CHECK (b > 0) NOT VALID; -ALTER TABLE t ADD CONSTRAINT t_b_nn NOT NULL b NOT VALID; - -INSERT INTO tp_x(i, t, b) VALUES(0, DEFAULT, 1); -INSERT INTO tp_x(i, t, b) VALUES(1, DEFAULT, 2); - -CREATE OR REPLACE FUNCTION trigger_function() RETURNS trigger LANGUAGE 'plpgsql' AS -$BODY$ -BEGIN - RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; - RETURN new; -END; -$BODY$; - -CREATE TRIGGER t_before_insert_row_trigger BEFORE INSERT ON t FOR EACH ROW - EXECUTE PROCEDURE trigger_function('t'); -CREATE TRIGGER tp_x_before_insert_row_trigger BEFORE INSERT ON tp_x FOR EACH ROW - EXECUTE PROCEDURE trigger_function('tp_x'); - -\d+ tp_x -ALTER TABLE t SPLIT PARTITION tp_x INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_x FOR VALUES FROM (1) TO (2)); -\d+ tp_x - -INSERT INTO t(i, t, b) VALUES(1, DEFAULT, 3); -SELECT tableoid::regclass, * FROM t ORDER BY tableoid::regclass::text COLLATE "C", b; -DROP TABLE t; -DROP FUNCTION trigger_function(); - - --- Test for recomputation of stored generated columns. -CREATE TABLE t (i int, tab_id int generated always as (tableoid) stored) PARTITION BY RANGE (i); -CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2); -ALTER TABLE t ADD CONSTRAINT cc CHECK(tableoid <> 123456789); -INSERT INTO t VALUES (0), (1); - --- Should be 1 because partition identifier for row with i=0 is the same as --- partition identifier for row with i=1. -SELECT count(*) FROM t WHERE i = 0 AND tab_id IN (SELECT tab_id FROM t WHERE i = 1); - --- "tab_id" column (stored generated column) with "tableoid" attribute requires --- recomputation here. -ALTER TABLE t SPLIT PARTITION tp_0_2 INTO - (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1), - PARTITION tp_1_2 FOR VALUES FROM (1) TO (2)); - --- Should be 0 because partition identifier for row with i=0 is different from --- partition identifier for row with i=1. -SELECT count(*) FROM t WHERE i = 0 AND tab_id IN (SELECT tab_id FROM t WHERE i = 1); - -DROP TABLE t; - --- Each new partition produced by SPLIT must get its own TOAST table so --- that out-of-line varlena attributes coming from the source partition --- can be stored. SET STORAGE EXTERNAL forces externalization for any --- value over the TOAST threshold, so a string over that threshold --- suffices to exercise the toast-table dependency. -CREATE TABLE t (a text) PARTITION BY RANGE(a); -ALTER TABLE t ALTER COLUMN a SET STORAGE EXTERNAL; -CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (MINVALUE) TO (MAXVALUE); -INSERT INTO t SELECT repeat('1', 10000); -ALTER TABLE t SPLIT PARTITION tp_all INTO ( - PARTITION tp_lo FOR VALUES FROM (MINVALUE) TO ('2'), - PARTITION tp_hi FOR VALUES FROM ('2') TO (MAXVALUE) -); -SELECT relname, - reltoastrelid <> 0 AS has_toast, - pg_relation_size(reltoastrelid) > 0 AS toast_used - FROM pg_class WHERE relname IN ('tp_lo', 'tp_hi') ORDER BY relname; -SELECT length(a) FROM t; -DROP TABLE t; - --- Tablespace selection for the new partitions mirrors --- CREATE TABLE ... PARTITION OF: the partitioned root's explicit --- tablespace wins; otherwise default_tablespace applies; otherwise the --- database default is used. -CREATE TABLE t (i int) PARTITION BY RANGE(i) TABLESPACE regress_tblspace; -CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); -INSERT INTO t SELECT generate_series(0, 9); -ALTER TABLE t SPLIT PARTITION tp_all INTO ( - PARTITION tp_lo FOR VALUES FROM (0) TO (5), - PARTITION tp_hi FOR VALUES FROM (5) TO (10) -); -SELECT c.relname, s.spcname FROM pg_class c LEFT JOIN pg_tablespace s - ON c.reltablespace = s.oid WHERE c.relname IN ('tp_lo', 'tp_hi') - ORDER BY c.relname; -DROP TABLE t; - --- Parent has no explicit tablespace, but default_tablespace is set: the --- new partitions land on default_tablespace. -CREATE TABLE t (i int) PARTITION BY RANGE(i); -CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); -INSERT INTO t SELECT generate_series(0, 9); -SET default_tablespace TO regress_tblspace; -ALTER TABLE t SPLIT PARTITION tp_all INTO ( - PARTITION tp_lo FOR VALUES FROM (0) TO (5), - PARTITION tp_hi FOR VALUES FROM (5) TO (10) -); -RESET default_tablespace; -SELECT c.relname, s.spcname FROM pg_class c LEFT JOIN pg_tablespace s - ON c.reltablespace = s.oid WHERE c.relname IN ('tp_lo', 'tp_hi') - ORDER BY c.relname; -DROP TABLE t; - -CREATE TABLE t (i int) PARTITION BY RANGE(i); -CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (0) TO (10); -INSERT INTO t SELECT generate_series(0, 9); --- pg_global is rejected when picked up from default_tablespace. -SET default_tablespace TO pg_global; -ALTER TABLE t SPLIT PARTITION tp_all INTO ( - PARTITION tp_lo FOR VALUES FROM (0) TO (5), - PARTITION tp_hi FOR VALUES FROM (5) TO (10) -); -- fails -RESET default_tablespace; --- Parent has no explicit tablespace and default_tablespace is empty: new --- partitions use the database default (reltablespace = 0). -ALTER TABLE t SPLIT PARTITION tp_all INTO ( - PARTITION tp_lo FOR VALUES FROM (0) TO (5), - PARTITION tp_hi FOR VALUES FROM (5) TO (10) -); -SELECT relname, reltablespace FROM pg_class - WHERE relname IN ('tp_lo', 'tp_hi') ORDER BY relname; -DROP TABLE t; - -RESET search_path; - --- -DROP SCHEMA partition_split_schema; -DROP SCHEMA partition_split_schema2; diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 23d4e6c0651..bcf981a02a2 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -2211,7 +2211,6 @@ PartitionDirectoryEntry PartitionDispatch PartitionElem PartitionHashBound -PartitionIndexExtDepEntry PartitionKey PartitionListValue PartitionMap @@ -2924,7 +2923,6 @@ SimpleStats SimpleStringList SimpleStringListCell SingleBoundSortItem -SinglePartitionSpec Size SkipPages SkipSupport @@ -2996,7 +2994,6 @@ SpinDelayStatus SplitInterval SplitLR SplitPageLayout -SplitPartitionContext SplitPoint SplitTextOutputData SplitVar From 58af2138740b3da0c866f1e20045c43bb7bacc0b Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 27 Aug 2026 10:42:14 +0200 Subject: [PATCH 454/481] Fix inferred property graph keys with INCLUDE columns Inferred property graph keys used all attributes stored in the primary key index, causing non-key INCLUDE columns to become part of the graph key. Use only the index's key attributes. Author: Muhammad Taha Naveed Discussion: https://www.postgresql.org/message-id/flat/CAPTqav%2BVUjYgm1jZy0Scy%3D1-PfdgznVj2%3DPwH8disiXF76HEow%40mail.gmail.com --- src/backend/commands/propgraphcmds.c | 3 ++- src/test/regress/expected/create_property_graph.out | 3 ++- src/test/regress/sql/create_property_graph.sql | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/backend/commands/propgraphcmds.c b/src/backend/commands/propgraphcmds.c index 076005226f2..2bdce331c49 100644 --- a/src/backend/commands/propgraphcmds.c +++ b/src/backend/commands/propgraphcmds.c @@ -342,7 +342,8 @@ propgraph_element_get_key(ParseState *pstate, const List *key_clause, Relation e Relation indexDesc; indexDesc = index_open(pkidx, AccessShareLock); - a = array_from_attnums(indexDesc->rd_index->indkey.dim1, indexDesc->rd_index->indkey.values); + a = array_from_attnums(IndexRelationGetNumberOfKeyAttributes(indexDesc), + indexDesc->rd_index->indkey.values); index_close(indexDesc, NoLock); } } diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out index 646e5fed5e2..5bbd6477ed6 100644 --- a/src/test/regress/expected/create_property_graph.out +++ b/src/test/regress/expected/create_property_graph.out @@ -12,7 +12,8 @@ ERROR: relation "g1" already exists CREATE TABLE t1 (a int, b text); CREATE TABLE t2 (i int PRIMARY KEY, j int, k int); CREATE TABLE t3 (x int, y text, z text); -CREATE TABLE e1 (a int, i int, t text, PRIMARY KEY (a, i)); +-- INCLUDE column must not become part of the inferred element key +CREATE TABLE e1 (a int, i int, t text, PRIMARY KEY (a, i) INCLUDE (t)); CREATE TABLE e2 (a int, x int, t text); CREATE PROPERTY GRAPH g2 VERTEX TABLES (t1 KEY (a), t2 DEFAULT LABEL, t3 KEY (x) LABEL t3l1 LABEL t3l2) diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql index b1a8d12a040..2b8269d66ec 100644 --- a/src/test/regress/sql/create_property_graph.sql +++ b/src/test/regress/sql/create_property_graph.sql @@ -17,7 +17,8 @@ CREATE TABLE t1 (a int, b text); CREATE TABLE t2 (i int PRIMARY KEY, j int, k int); CREATE TABLE t3 (x int, y text, z text); -CREATE TABLE e1 (a int, i int, t text, PRIMARY KEY (a, i)); +-- INCLUDE column must not become part of the inferred element key +CREATE TABLE e1 (a int, i int, t text, PRIMARY KEY (a, i) INCLUDE (t)); CREATE TABLE e2 (a int, x int, t text); CREATE PROPERTY GRAPH g2 From 63f8e9773aadba37661f70629a0a0e8f5933afc8 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 27 Aug 2026 11:32:55 +0200 Subject: [PATCH 455/481] Fix pg_event_trigger_ddl_commands for GRANT ON PROPERTY GRAPH stringify_grant_objtype() treated OBJECT_PROPGRAPH as unused, so pg_event_trigger_ddl_commands() failed with "unsupported object type" when a ddl_command_end trigger inspected GRANT/REVOKE on a property graph. Return "PROPERTY GRAPH" like the GRANT command syntax. Bug: #19637 Reported-by: Alexander Lakhin Author: Andrey Rachitskiy Reviewed-by: Fujii Masao Discussion: https://www.postgresql.org/message-id/flat/19637-4446f72945492ed8%40postgresql.org --- src/backend/commands/event_trigger.c | 3 ++- src/test/regress/expected/event_trigger.out | 21 ++++++++++++++++----- src/test/regress/sql/event_trigger.sql | 11 ++++++++--- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c index adc6eabc0f4..4edc83cdf7d 100644 --- a/src/backend/commands/event_trigger.c +++ b/src/backend/commands/event_trigger.c @@ -2288,6 +2288,8 @@ stringify_grant_objtype(ObjectType objtype) return "PARAMETER"; case OBJECT_PROCEDURE: return "PROCEDURE"; + case OBJECT_PROPGRAPH: + return "PROPERTY GRAPH"; case OBJECT_ROUTINE: return "ROUTINE"; case OBJECT_TABLESPACE: @@ -2315,7 +2317,6 @@ stringify_grant_objtype(ObjectType objtype) case OBJECT_OPERATOR: case OBJECT_OPFAMILY: case OBJECT_POLICY: - case OBJECT_PROPGRAPH: case OBJECT_PUBLICATION: case OBJECT_PUBLICATION_NAMESPACE: case OBJECT_PUBLICATION_REL: diff --git a/src/test/regress/expected/event_trigger.out b/src/test/regress/expected/event_trigger.out index 86ae50ce531..2fb925fc0ff 100644 --- a/src/test/regress/expected/event_trigger.out +++ b/src/test/regress/expected/event_trigger.out @@ -173,7 +173,8 @@ NOTICE: test_event_trigger: ddl_command_end CREATE USER MAPPING alter default privileges for role regress_evt_user revoke delete on tables from regress_evt_user; NOTICE: test_event_trigger: ddl_command_end ALTER DEFAULT PRIVILEGES --- DROP PROPERTY GRAPH should work with event trigger in place +-- property graph DDL should work with event trigger in place; these +-- objects are dropped further down, under the sql_drop trigger CREATE TABLE tv1 (a int PRIMARY KEY, b text); NOTICE: test_event_trigger: ddl_command_start CREATE TABLE NOTICE: test_event_trigger: ddl_command_end CREATE TABLE @@ -191,10 +192,6 @@ CREATE PROPERTY GRAPH gx NOTICE: test_event_trigger: ddl_command_end CREATE PROPERTY GRAPH ALTER PROPERTY GRAPH gx ALTER EDGE TABLE te1 ALTER LABEL e1 DROP PROPERTIES (p1); NOTICE: test_event_trigger: ddl_command_end ALTER PROPERTY GRAPH -DROP PROPERTY GRAPH gx; -NOTICE: test_event_trigger: ddl_command_end DROP PROPERTY GRAPH -DROP TABLE tv1, tv2, te1; -NOTICE: test_event_trigger: ddl_command_end DROP TABLE -- alter owner to non-superuser should fail alter event trigger regress_event_trigger owner to regress_evt_user; ERROR: permission denied to change owner of event trigger "regress_event_trigger" @@ -434,6 +431,20 @@ BEGIN END; $$; CREATE EVENT TRIGGER regress_event_trigger_report_end ON ddl_command_end EXECUTE PROCEDURE event_trigger_report_end(); +-- GRANT/REVOKE ON PROPERTY GRAPH with pg_event_trigger_ddl_commands() +GRANT SELECT ON PROPERTY GRAPH gx TO public; +NOTICE: END: command_tag=GRANT type=PROPERTY GRAPH identity= +REVOKE SELECT ON PROPERTY GRAPH gx FROM public; +NOTICE: END: command_tag=REVOKE type=PROPERTY GRAPH identity= +DROP PROPERTY GRAPH gx; +NOTICE: NORMAL: orig=t normal=f istemp=f type=property graph identity=public.gx schema=public name=gx addr={public,gx} args={} +NOTICE: NORMAL: orig=f normal=t istemp=f type=property graph element identity=te1 of property graph public.gx schema= name= addr={public,gx,te1} args={} +DROP TABLE tv1, tv2, te1; +NOTICE: NORMAL: orig=t normal=f istemp=f type=table identity=public.te1 schema=public name=te1 addr={public,te1} args={} +NOTICE: NORMAL: orig=t normal=f istemp=f type=table identity=public.tv2 schema=public name=tv2 addr={public,tv2} args={} +NOTICE: NORMAL: orig=f normal=t istemp=f type=table constraint identity=te1_b_fkey on public.te1 schema=public name= addr={public,te1,te1_b_fkey} args={} +NOTICE: NORMAL: orig=t normal=f istemp=f type=table identity=public.tv1 schema=public name=tv1 addr={public,tv1} args={} +NOTICE: NORMAL: orig=f normal=t istemp=f type=table constraint identity=te1_a_fkey on public.te1 schema=public name= addr={public,te1,te1_a_fkey} args={} CREATE SCHEMA evttrig CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two', col_c SERIAL) CREATE INDEX one_idx ON one (col_b) diff --git a/src/test/regress/sql/event_trigger.sql b/src/test/regress/sql/event_trigger.sql index d0e6ba295fe..c1deac2d628 100644 --- a/src/test/regress/sql/event_trigger.sql +++ b/src/test/regress/sql/event_trigger.sql @@ -143,7 +143,8 @@ create user mapping for regress_evt_user server useless_server; alter default privileges for role regress_evt_user revoke delete on tables from regress_evt_user; --- DROP PROPERTY GRAPH should work with event trigger in place +-- property graph DDL should work with event trigger in place; these +-- objects are dropped further down, under the sql_drop trigger CREATE TABLE tv1 (a int PRIMARY KEY, b text); CREATE TABLE tv2 (i int PRIMARY KEY, j text); CREATE TABLE te1 (p int PRIMARY KEY, a int REFERENCES tv1(a), b int REFERENCES tv2(i), q text); @@ -155,8 +156,6 @@ CREATE PROPERTY GRAPH gx EDGE TABLES (te1 SOURCE tv1 DESTINATION tv2 LABEL e1 PROPERTIES (q as p1)); ALTER PROPERTY GRAPH gx ALTER EDGE TABLE te1 ALTER LABEL e1 DROP PROPERTIES (p1); -DROP PROPERTY GRAPH gx; -DROP TABLE tv1, tv2, te1; -- alter owner to non-superuser should fail alter event trigger regress_event_trigger owner to regress_evt_user; @@ -335,6 +334,12 @@ END; $$; CREATE EVENT TRIGGER regress_event_trigger_report_end ON ddl_command_end EXECUTE PROCEDURE event_trigger_report_end(); +-- GRANT/REVOKE ON PROPERTY GRAPH with pg_event_trigger_ddl_commands() +GRANT SELECT ON PROPERTY GRAPH gx TO public; +REVOKE SELECT ON PROPERTY GRAPH gx FROM public; +DROP PROPERTY GRAPH gx; +DROP TABLE tv1, tv2, te1; + CREATE SCHEMA evttrig CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two', col_c SERIAL) CREATE INDEX one_idx ON one (col_b) From ba12a202ce1b5581dc0ed149cf3f637d7897ad5d Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 27 Aug 2026 14:31:44 +0300 Subject: [PATCH 456/481] Don't create a shell type for function returning an array Refactor the checks in the function to move all the conditions for when to attempt creating a shell type into one place. Add a check for the array syntax. In addition to rejecting array syntax, another user-visible effect is that the error message is now different if the type specified a typmod. You now get "type does not exist" instead of the more specific "type modifier cannot be specified for shell type". That seems better; the implicit shell type creation exists only for backwards compatibility, and it never worked with type modifiers, so if there's a type modifier it's most likely not because the user tried to create a shell type, Add test for the array syntax, the type modifier, and some other cases for which we don't create shell types. Discussion: https://www.postgresql.org/message-id/de673feb-41b4-4685-b24b-6408b95e58ab@iki.fi Backpatch-through: 14 --- src/backend/commands/functioncmds.c | 58 ++++++++++++++--------- src/test/regress/expected/create_type.out | 50 ++++++++++++++++++- src/test/regress/sql/create_type.sql | 42 ++++++++++++++++ 3 files changed, 126 insertions(+), 24 deletions(-) diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 3afd762e9dc..5a6ea0f3286 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -92,11 +92,32 @@ compute_return_type(TypeName *returnType, Oid languageOid, Oid rettype; Type typtup; AclResult aclresult; + bool attempt_shell_creation; - typtup = LookupTypeName(NULL, returnType, NULL, false); + /* + * If this looks like it could be an input function, and the type doesn't + * exist, we'll create it as a shell type. + * + * If the type name contains any modifiers like %TYPE, type[] array + * syntax, or typmod decoration, it's not an input function, or at least + * not one for which we'd want to automatically create a shell type. + * + * Only C-coded functions can be I/O functions. We enforce this + * restriction here mainly to prevent littering the catalogs with shell + * types due to simple typos in user-defined function definitions. + */ + attempt_shell_creation = + !returnType->pct_type && returnType->arrayBounds == NULL && + returnType->typmods == NIL && + (languageOid == INTERNALlanguageId || languageOid == ClanguageId); + typtup = LookupTypeName(NULL, returnType, NULL, false); if (typtup) { + /* + * Found an existing type with the given name. Check if it's a shell + * type. + */ if (!((Form_pg_type) GETSTRUCT(typtup))->typisdefined) { if (languageOid == SQLlanguageId) @@ -113,37 +134,27 @@ compute_return_type(TypeName *returnType, Oid languageOid, rettype = typeTypeId(typtup); ReleaseSysCache(typtup); } + else if (!attempt_shell_creation) + { + /* Type not found and we don't want to create a shell type */ + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("type \"%s\" does not exist", + TypeNameToString(returnType)))); + } else { - char *typnam = TypeNameToString(returnType); + /* Make a shell type */ Oid namespaceId; char *typname; ObjectAddress address; - /* - * Only C-coded functions can be I/O functions. We enforce this - * restriction here mainly to prevent littering the catalogs with - * shell types due to simple typos in user-defined function - * definitions. - */ - if (languageOid != INTERNALlanguageId && - languageOid != ClanguageId) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("type \"%s\" does not exist", typnam))); - - /* Reject if there's typmod decoration, too */ - if (returnType->typmods != NIL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("type modifier cannot be specified for shell type \"%s\"", - typnam))); - - /* Otherwise, go ahead and make a shell type */ ereport(NOTICE, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("type \"%s\" is not yet defined", typnam), + errmsg("type \"%s\" is not yet defined", + TypeNameToString(returnType)), errdetail("Creating a shell type definition."))); + namespaceId = QualifiedNameGetCreationNamespace(returnType->names, &typname); aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), @@ -151,6 +162,7 @@ compute_return_type(TypeName *returnType, Oid languageOid, if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, OBJECT_SCHEMA, get_namespace_name(namespaceId)); + address = TypeShellMake(typname, namespaceId, GetUserId()); rettype = address.objectId; Assert(OidIsValid(rettype)); diff --git a/src/test/regress/expected/create_type.out b/src/test/regress/expected/create_type.out index 5181c4290b4..09cfa8da22c 100644 --- a/src/test/regress/expected/create_type.out +++ b/src/test/regress/expected/create_type.out @@ -51,6 +51,30 @@ CREATE TYPE city_budget ( category = 'x', -- just to verify the system will take it preferred = true -- ditto ); +-- If the specified type includes typmods or array syntax, don't create a shell type +CREATE FUNCTION bogus_in(cstring) + RETURNS bogus_shell(123) + AS :'regresslib', 'widget_in' + LANGUAGE C STRICT IMMUTABLE; +ERROR: type "bogus_shell" does not exist +CREATE FUNCTION bogus_in(cstring) + RETURNS bogus_shell[] + AS :'regresslib', 'widget_in' + LANGUAGE C STRICT IMMUTABLE; +ERROR: type "bogus_shell[]" does not exist +-- If the column specified with %TYPE does not exist, don't try to create a shell type +CREATE TEMP TABLE bogus_tbl (col int); +CREATE FUNCTION bogus_in(cstring) + RETURNS bogus_tbl.nonexistent_col%TYPE + AS :'regresslib', 'widget_in' + LANGUAGE C STRICT IMMUTABLE; +ERROR: column "nonexistent_col" of relation "bogus_tbl" does not exist +-- If the schema does not exist, don't try to create a shell type +CREATE FUNCTION bogus_in(cstring) + RETURNS nonexistent_schema.bogus_shell + AS :'regresslib', 'widget_in' + LANGUAGE C STRICT IMMUTABLE; +ERROR: schema "nonexistent_schema" does not exist -- Test creation and destruction of shell types CREATE TYPE shell; CREATE TYPE shell; -- fail, type already present @@ -343,12 +367,30 @@ NOTICE: return type myvarchar is only a shell -- fail, it's still a shell: ALTER TYPE myvarchar SET (storage = extended); ERROR: type "myvarchar" is only a shell +-- fail: typmods not allowed for a shell type +CREATE FUNCTION myvarchar_lower(text) RETURNS myvarchar(100) +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'lower'; +ERROR: type modifier cannot be specified for shell type "myvarchar" +CREATE FUNCTION myvarchar_lower(myvarchar(100)) RETURNS text +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'lower'; +ERROR: type modifier cannot be specified for shell type "myvarchar" +LINE 1: CREATE FUNCTION myvarchar_lower(myvarchar(100)) RETURNS text + ^ CREATE TYPE myvarchar ( input = myvarcharin, output = myvarcharout, alignment = integer, storage = main ); +-- fail: typmods not allowed because 'typmod_in' / 'typmod_out' were not specified. +CREATE FUNCTION myvarchar_lower(text) RETURNS myvarchar(100) +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'lower'; +ERROR: type modifier is not allowed for type "myvarchar" +CREATE FUNCTION myvarchar_lower(myvarchar(100)) RETURNS text +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'lower'; +ERROR: type modifier is not allowed for type "myvarchar" +LINE 1: CREATE FUNCTION myvarchar_lower(myvarchar(100)) RETURNS text + ^ -- want to check updating of a domain over the target type, too CREATE DOMAIN myvarchardom AS myvarchar; ALTER TYPE myvarchar SET (storage = plain); -- not allowed @@ -395,6 +437,9 @@ FROM pg_type WHERE typname = '_myvarchardom'; array_in | array_out | array_recv | array_send | - | - | array_typanalyze | array_subscript_handler | x (1 row) +-- typmods are now accepted in CREATE FUNCTION, although they are not stored +CREATE FUNCTION myvarchar_lower(myvarchar(100)) RETURNS myvarchar(100) +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'lower'; -- ensure dependencies are straight DROP FUNCTION myvarcharsend(myvarchar); -- fail ERROR: cannot drop function myvarcharsend(myvarchar) because other objects depend on it @@ -402,6 +447,7 @@ DETAIL: type myvarchar depends on function myvarcharsend(myvarchar) function myvarcharin(cstring,oid,integer) depends on type myvarchar function myvarcharout(myvarchar) depends on type myvarchar function myvarcharrecv(internal,oid,integer) depends on type myvarchar +function myvarchar_lower(myvarchar) depends on type myvarchar type myvarchardom depends on function myvarcharsend(myvarchar) HINT: Use DROP ... CASCADE to drop the dependent objects too. DROP TYPE myvarchar; -- fail @@ -411,11 +457,13 @@ function myvarcharout(myvarchar) depends on type myvarchar function myvarcharsend(myvarchar) depends on type myvarchar function myvarcharrecv(internal,oid,integer) depends on type myvarchar type myvarchardom depends on type myvarchar +function myvarchar_lower(myvarchar) depends on type myvarchar HINT: Use DROP ... CASCADE to drop the dependent objects too. DROP TYPE myvarchar CASCADE; -NOTICE: drop cascades to 5 other objects +NOTICE: drop cascades to 6 other objects DETAIL: drop cascades to function myvarcharin(cstring,oid,integer) drop cascades to function myvarcharout(myvarchar) drop cascades to function myvarcharsend(myvarchar) drop cascades to function myvarcharrecv(internal,oid,integer) drop cascades to type myvarchardom +drop cascades to function myvarchar_lower(myvarchar) diff --git a/src/test/regress/sql/create_type.sql b/src/test/regress/sql/create_type.sql index c25018029c2..4fd1facdffe 100644 --- a/src/test/regress/sql/create_type.sql +++ b/src/test/regress/sql/create_type.sql @@ -50,6 +50,32 @@ CREATE TYPE city_budget ( preferred = true -- ditto ); + +-- If the specified type includes typmods or array syntax, don't create a shell type +CREATE FUNCTION bogus_in(cstring) + RETURNS bogus_shell(123) + AS :'regresslib', 'widget_in' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION bogus_in(cstring) + RETURNS bogus_shell[] + AS :'regresslib', 'widget_in' + LANGUAGE C STRICT IMMUTABLE; + +-- If the column specified with %TYPE does not exist, don't try to create a shell type +CREATE TEMP TABLE bogus_tbl (col int); +CREATE FUNCTION bogus_in(cstring) + RETURNS bogus_tbl.nonexistent_col%TYPE + AS :'regresslib', 'widget_in' + LANGUAGE C STRICT IMMUTABLE; + +-- If the schema does not exist, don't try to create a shell type +CREATE FUNCTION bogus_in(cstring) + RETURNS nonexistent_schema.bogus_shell + AS :'regresslib', 'widget_in' + LANGUAGE C STRICT IMMUTABLE; + + -- Test creation and destruction of shell types CREATE TYPE shell; CREATE TYPE shell; -- fail, type already present @@ -252,6 +278,12 @@ LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharrecv'; -- fail, it's still a shell: ALTER TYPE myvarchar SET (storage = extended); +-- fail: typmods not allowed for a shell type +CREATE FUNCTION myvarchar_lower(text) RETURNS myvarchar(100) +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'lower'; +CREATE FUNCTION myvarchar_lower(myvarchar(100)) RETURNS text +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'lower'; + CREATE TYPE myvarchar ( input = myvarcharin, output = myvarcharout, @@ -259,6 +291,12 @@ CREATE TYPE myvarchar ( storage = main ); +-- fail: typmods not allowed because 'typmod_in' / 'typmod_out' were not specified. +CREATE FUNCTION myvarchar_lower(text) RETURNS myvarchar(100) +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'lower'; +CREATE FUNCTION myvarchar_lower(myvarchar(100)) RETURNS text +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'lower'; + -- want to check updating of a domain over the target type, too CREATE DOMAIN myvarchardom AS myvarchar; @@ -292,6 +330,10 @@ SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, typanalyze, typsubscript, typstorage FROM pg_type WHERE typname = '_myvarchardom'; +-- typmods are now accepted in CREATE FUNCTION, although they are not stored +CREATE FUNCTION myvarchar_lower(myvarchar(100)) RETURNS myvarchar(100) +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'lower'; + -- ensure dependencies are straight DROP FUNCTION myvarcharsend(myvarchar); -- fail DROP TYPE myvarchar; -- fail From 4c5291435d40a0cf02b131b680a71e42243fcd04 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Thu, 27 Aug 2026 23:40:20 +0900 Subject: [PATCH 457/481] Report specific SQLSTATEs for stats restore errors The pg_restore_*_stats() functions could report SQLSTATE XX000 for invalid variadic arguments, such as an unmatched name/value pair, a NULL argument name, or a non-text argument name. Attribute and extended statistics restores could also report XX000 when the supplied statistics exceed the number of slots PostgreSQL can store. These are not internal errors. They result from invalid caller input or a PostgreSQL implementation limit, but the lack of specific SQLSTATEs made clients treat them as internal errors. Assign appropriate SQLSTATEs to these errors so that applications and tests can classify them correctly. Backpatch to v19, but no further; changing ERRCODE assignments in released stable branches doesn't seem like a good idea. Bug: #19629 Reported-by: Zheng Wang Reported-by: Yanjie Zhao Reported-by: Yiyang Liu Author: Fujii Masao Discussion: https://postgr.es/m/19629-76babc04b683594d@postgresql.org Backpatch-through: 19 --- src/backend/statistics/stat_utils.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/backend/statistics/stat_utils.c b/src/backend/statistics/stat_utils.c index ba204cd5e77..b03b33de4f1 100644 --- a/src/backend/statistics/stat_utils.c +++ b/src/backend/statistics/stat_utils.c @@ -369,8 +369,9 @@ stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo, if (nargs % 2 != 0) ereport(ERROR, - errmsg("variadic arguments must be name/value pairs"), - errhint("Provide an even number of variadic arguments that can be divided into pairs.")); + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("variadic arguments must be name/value pairs"), + errhint("Provide an even number of variadic arguments that can be divided into pairs."))); /* * For each argument name/value pair, find corresponding positional @@ -384,11 +385,13 @@ stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo, if (argnulls[i]) ereport(ERROR, - (errmsg("name at variadic position %d is null", i + 1))); + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("name at variadic position %d is null", i + 1))); if (types[i] != TEXTOID) ereport(ERROR, - (errmsg("name at variadic position %d has type %s, expected type %s", + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("name at variadic position %d has type %s, expected type %s", i + 1, format_type_be(types[i]), format_type_be(TEXTOID)))); @@ -653,7 +656,8 @@ statatt_set_slot(Datum *values, bool *nulls, bool *replaces, if (slotidx >= STATISTIC_NUM_SLOTS) ereport(ERROR, - (errmsg("maximum number of statistics slots exceeded: %d", + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("maximum number of statistics slots exceeded: %d", slotidx + 1))); stakind_attnum = Anum_pg_statistic_stakind1 - 1 + slotidx; From d225057849e2d4e013f1cd828f04084d004feb8f Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Thu, 27 Aug 2026 23:51:21 +0900 Subject: [PATCH 458/481] Stabilize 019_replslot_limit The test assumed that advancing WAL would lead to a checkpoint that invalidates the obsolete replication slot. If a checkpoint that started before the WAL switch completes first, the following checkpoint can be skipped as idle, so the expected walsender termination is not logged. Force a CHECKPOINT in a background psql session after advancing WAL, so the slot invalidation is exercised deterministically. This has been observed on buildfarm members alligator and partridge: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=alligator&dt=2024-12-13%2001%3A24%3A58 https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=partridge&dt=2026-08-06%2018%3A00%3A11 Backpatch to all supported versions. Reported-by: Alexander Lakhin Author: Hayato Kuroda Reviewed-by: Alexander Lakhin Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/0b07ead5-a5da-445e-9698-a7d340708bdf@gmail.com Backpatch-through: 14 --- src/test/recovery/t/019_replslot_limit.pl | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/test/recovery/t/019_replslot_limit.pl b/src/test/recovery/t/019_replslot_limit.pl index a412faf51c6..aa4217864a1 100644 --- a/src/test/recovery/t/019_replslot_limit.pl +++ b/src/test/recovery/t/019_replslot_limit.pl @@ -306,8 +306,6 @@ $node_primary3->init(allows_streaming => 1, extra => ['--wal-segsize=1']); $node_primary3->append_conf( 'postgresql.conf', qq( - min_wal_size = 2MB - max_wal_size = 2MB log_checkpoints = yes max_slot_wal_keep_size = 1MB )); @@ -374,6 +372,16 @@ kill 'STOP', $senderpid, $receiverpid; $node_primary3->advance_wal(2); +# Run CHECKPOINT in the background. It is expected to reach slot +# invalidation, signal the stopped walsender, and then wait until the +# walsender releases the slot. +my $checkpoint = $node_primary3->background_psql('postgres'); +$checkpoint->query_until( + qr/starting_checkpoint/, q( + \echo starting_checkpoint + CHECKPOINT; +)); + my $msg_logged = 0; my $max_attempts = $PostgreSQL::Test::Utils::timeout_default; while ($max_attempts-- >= 0) @@ -397,6 +405,7 @@ "SELECT wal_status FROM pg_replication_slots WHERE slot_name = 'rep3'", "lost") or die "timed out waiting for slot to be lost"; +$checkpoint->quit; $msg_logged = 0; $max_attempts = $PostgreSQL::Test::Utils::timeout_default; From 764d31b8ae360685b06913c7c6195ec1bfefcd33 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Fri, 28 Aug 2026 01:15:23 +0900 Subject: [PATCH 459/481] Fix temporary WAL receiver slot handling on timeline switches Previously, when wal_receiver_create_temp_slot was enabled, a timeline switch could cause the walreceiver to try to create the same temporary replication slot again on the same connection. The slot had already been created before the first streaming attempt and still existed, so the second creation attempt failed with a FATAL error such as "could not create replication slot ...". The walreceiver would later be restarted and streaming replication could continue, so this did not permanently break replication. Nevertheless, the unexpected failure is a bug and should be fixed. Fix this by tracking whether the temporary replication slot has already been created for the lifetime of the walreceiver and skipping subsequent creation attempts. Also copy the retained slot name to shared memory on each streaming attempt, since RequestXLogStreaming() clears it when streaming is restarted without a configured primary slot. This also keeps pg_stat_wal_receiver.slot_name populated after timeline switches. Backpatch to all supported versions. Author: ChangAo Chen Reviewed-by: Quan Zongliang Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/tencent_628FDAF814231923BC8E8357BBBC50F94207@qq.com Backpatch-through: 14 --- src/backend/replication/walreceiver.c | 23 ++++++++---- src/test/recovery/t/004_timeline_switch.pl | 43 ++++++++++++++++++++++ 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 7167c02d73d..7ffa9187eb8 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -158,6 +158,7 @@ WalReceiverMain(const void *startup_data, size_t startup_data_len) char *tmp_conninfo; char slotname[NAMEDATALEN]; bool is_temp_slot; + bool temp_slot_created = false; XLogRecPtr startpoint; TimeLineID startpointTLI; TimeLineID primaryTLI; @@ -431,17 +432,25 @@ WalReceiverMain(const void *startup_data, size_t startup_data_len) WalRcvFetchTimeLineHistoryFiles(startpointTLI, primaryTLI); /* - * Create temporary replication slot if requested, and update slot - * name in shared memory. (Note the slot name cannot already be set - * in this case.) + * Create a temporary replication slot if requested. This only needs + * to be done for the first streaming attempt on this connection + * because the slot remains available while this connection is reused + * for later streaming attempts. Update the slot name in shared + * memory each time because RequestXLogStreaming() clears it when + * restarting streaming. */ if (is_temp_slot) { - snprintf(slotname, sizeof(slotname), - "pg_walreceiver_%lld", - (long long int) walrcv_get_backend_pid(wrconn)); + if (!temp_slot_created) + { + snprintf(slotname, sizeof(slotname), + "pg_walreceiver_%lld", + (long long int) walrcv_get_backend_pid(wrconn)); + + walrcv_create_slot(wrconn, slotname, true, false, false, 0, NULL); - walrcv_create_slot(wrconn, slotname, true, false, false, 0, NULL); + temp_slot_created = true; + } SpinLockAcquire(&walrcv->mutex); strlcpy(walrcv->slotname, slotname, NAMEDATALEN); diff --git a/src/test/recovery/t/004_timeline_switch.pl b/src/test/recovery/t/004_timeline_switch.pl index f9955b2b4eb..4bf111346e7 100644 --- a/src/test/recovery/t/004_timeline_switch.pl +++ b/src/test/recovery/t/004_timeline_switch.pl @@ -145,4 +145,47 @@ $node_standby_3->safe_psql('postgres', "SELECT count(*) FROM tab_int"); is($result_2, qq(1), 'check content of standby 3'); +# Ensure that a WAL receiver creates a temporary replication slot only once +# when following an upstream across a timeline switch. + +# Initialize primary node +my $node_primary_3 = PostgreSQL::Test::Cluster->new('primary_3'); +$node_primary_3->init(allows_streaming => 1); +$node_primary_3->start; + +# Take backup +$node_primary_3->backup($backup_name); + +# Create standby node +my $node_standby_4 = PostgreSQL::Test::Cluster->new('standby_4'); +$node_standby_4->init_from_backup($node_primary_3, $backup_name, + has_streaming => 1); +$node_standby_4->append_conf( + 'postgresql.conf', qq( +wal_receiver_create_temp_slot = on +)); + +# Restart primary node in standby mode and promote it, switching it +# to a new timeline. +$node_primary_3->set_standby_mode; +$node_primary_3->restart; +$node_primary_3->promote; + +# Start standby node, create some content on primary and check its presence +# in standby, to ensure that the timeline switch has been done. +$node_standby_4->start; +$node_primary_3->safe_psql('postgres', + "CREATE TABLE tab_int AS SELECT 1 AS a"); +$node_primary_3->wait_for_catchup($node_standby_4); + +ok( !$node_standby_4->log_contains( + 'could not create replication slot "pg_walreceiver_[0-9]+".*already exists' + ), + 'temporary replication slot is not recreated across timeline jumps'); + +my $temp_slot_name = $node_standby_4->safe_psql('postgres', + "SELECT slot_name FROM pg_stat_wal_receiver"); +like($temp_slot_name, qr/^pg_walreceiver_[0-9]+$/, + 'pg_stat_wal_receiver.slot_name remains set across timeline jumps'); + done_testing(); From 400c810ddbd7890f751913977e4442d71a0ebfc4 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Thu, 27 Aug 2026 14:14:15 -0400 Subject: [PATCH 460/481] Fix empty FOREIGN_JOIN sublist validation FOREIGN_JOIN target sublists must contain at least two relation identifiers. However, the parser checked only for sublists with exactly one identifier, so FOREIGN_JOIN(()) was accepted. Reject sublists with fewer than two relation identifiers, and add regression coverage. Author: Chao Li Discussion: http://postgr.es/m/BEDC04E0-6732-4310-95BA-6EC34BC1442C@gmail.com --- contrib/pg_plan_advice/expected/syntax.out | 3 +++ contrib/pg_plan_advice/pgpa_parser.y | 2 +- contrib/pg_plan_advice/sql/syntax.sql | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/pg_plan_advice/expected/syntax.out b/contrib/pg_plan_advice/expected/syntax.out index 3b57bb2bf57..d53d9598634 100644 --- a/contrib/pg_plan_advice/expected/syntax.out +++ b/contrib/pg_plan_advice/expected/syntax.out @@ -209,6 +209,9 @@ DETAIL: Could not parse advice: FOREIGN_JOIN targets must contain more than one SET pg_plan_advice.advice = 'FOREIGN_JOIN((a))'; ERROR: invalid value for parameter "pg_plan_advice.advice": "FOREIGN_JOIN((a))" DETAIL: Could not parse advice: FOREIGN_JOIN targets must contain more than one relation identifier at or near ")" +SET pg_plan_advice.advice = 'FOREIGN_JOIN(())'; +ERROR: invalid value for parameter "pg_plan_advice.advice": "FOREIGN_JOIN(())" +DETAIL: Could not parse advice: FOREIGN_JOIN targets must contain more than one relation identifier at or near ")" -- Tag keywords used as alias names work fine, because the 'identifier' -- nonterminal accepts all token types. SET pg_plan_advice.advice = 'SEQ_SCAN(hash_join)'; diff --git a/contrib/pg_plan_advice/pgpa_parser.y b/contrib/pg_plan_advice/pgpa_parser.y index 5811a6e5e56..295f16ad064 100644 --- a/contrib/pg_plan_advice/pgpa_parser.y +++ b/contrib/pg_plan_advice/pgpa_parser.y @@ -135,7 +135,7 @@ advice_item: TOK_TAG_JOIN_ORDER '(' join_order_target_list ')' foreach_ptr(pgpa_advice_target, target, $3) { if (target->ttype == PGPA_TARGET_IDENTIFIER || - list_length(target->children) == 1) + list_length(target->children) < 2) pgpa_yyerror(result, parse_error_msg_p, yyscanner, "FOREIGN_JOIN targets must contain more than one relation identifier"); } diff --git a/contrib/pg_plan_advice/sql/syntax.sql b/contrib/pg_plan_advice/sql/syntax.sql index 5af7607db42..de11e8c6fc2 100644 --- a/contrib/pg_plan_advice/sql/syntax.sql +++ b/contrib/pg_plan_advice/sql/syntax.sql @@ -73,6 +73,7 @@ SET pg_plan_advice.advice = '/*/* stuff */*/'; -- Foreign join requires multiple relation identifiers. SET pg_plan_advice.advice = 'FOREIGN_JOIN(a)'; SET pg_plan_advice.advice = 'FOREIGN_JOIN((a))'; +SET pg_plan_advice.advice = 'FOREIGN_JOIN(())'; -- Tag keywords used as alias names work fine, because the 'identifier' -- nonterminal accepts all token types. From e721ce48dc78b58827c35d6a13f9f72a591e68f2 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 27 Aug 2026 12:10:49 -0700 Subject: [PATCH 461/481] pg_upgrade: Read nextMultiOffset as a 64-bit value. Commit bd8d9c9bdfa widened MultiXactOffset to 64 bits and widened ControlData.chkpnt_nxtmxoff accordingly, but get_control_data() still read the "Latest checkpoint's NextMultiOffset" line with str2uint(), which returns unsigned int. This commit adds str2uint64(), mirroring the str2uint() helper used for the other control file fields, and reads the offset with it. Backpatch to v19, where MultiXactOffset was widened. Reviewed-by: Heikki Linnakangas Reviewed-by: Chao Li Discussion: https://postgr.es/m/CAD21AoCvzerscfU8o4ARQ793yAGHpQ72r2x5apeC_W2-k=SLCQ@mail.gmail.com Backpatch-through: 19 --- src/bin/pg_upgrade/controldata.c | 2 +- src/bin/pg_upgrade/pg_upgrade.h | 1 + src/bin/pg_upgrade/util.c | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c index fd772ba4f38..8c69329805b 100644 --- a/src/bin/pg_upgrade/controldata.c +++ b/src/bin/pg_upgrade/controldata.c @@ -352,7 +352,7 @@ get_control_data(ClusterInfo *cluster) pg_fatal("%d: controldata retrieval problem", __LINE__); p++; /* remove ':' char */ - cluster->controldata.chkpnt_nxtmxoff = str2uint(p); + cluster->controldata.chkpnt_nxtmxoff = str2uint64(p); got_mxoff = true; } else if ((p = strstr(bufin, "First log segment after reset:")) != NULL) diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h index ccd1ac0d013..92607daace5 100644 --- a/src/bin/pg_upgrade/pg_upgrade.h +++ b/src/bin/pg_upgrade/pg_upgrade.h @@ -496,6 +496,7 @@ void cleanup_output_dirs(void); void prep_status(const char *fmt, ...) pg_attribute_printf(1, 2); void prep_status_progress(const char *fmt, ...) pg_attribute_printf(1, 2); unsigned int str2uint(const char *str); +uint64 str2uint64(const char *str); /* version.c */ diff --git a/src/bin/pg_upgrade/util.c b/src/bin/pg_upgrade/util.c index 08d6385b512..e7d7ab56445 100644 --- a/src/bin/pg_upgrade/util.c +++ b/src/bin/pg_upgrade/util.c @@ -353,3 +353,14 @@ str2uint(const char *str) { return strtoul(str, NULL, 10); } + +/* + * str2uint64() + * + * convert string to uint64 + */ +uint64 +str2uint64(const char *str) +{ + return strtou64(str, NULL, 10); +} From 3fcb7167198e1b2ecf8cc0d934c8ffe53755e0ae Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 27 Aug 2026 12:25:04 -0700 Subject: [PATCH 462/481] Report next_multi_offset as bigint in pg_control_checkpoint(). Commit bd8d9c9bdfa widened MultiXactOffset to 64 bits, but pg_control_checkpoint() still handle checkPointCopy.nextMultiOffset as xid type and declared next_multi_offset column as xid. Since xid is 32 bits wide, an offset above 2^32 was reported truncated, while pg_controldata printed the full value of the same field. This commit reports the column as bigint instead. That matches pg_get_multixact_stats(), which already reports num_members and members_size, both derived from these same offsets, as int8. Backpatch to v19, where MultiXactOffset was widened. Bump catalog version. Reviewed-by: Heikki Linnakangas Reviewed-by: Chao Li Discussion: https://postgr.es/m/CAD21AoCvzerscfU8o4ARQ793yAGHpQ72r2x5apeC_W2-k=SLCQ@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/func/func-info.sgml | 2 +- src/backend/utils/misc/pg_controldata.c | 2 +- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml index e3c05e8b933..2f03766b67a 100644 --- a/doc/src/sgml/func/func-info.sgml +++ b/doc/src/sgml/func/func-info.sgml @@ -3458,7 +3458,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} next_multi_offset - xid + bigint diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c index ab74d169c96..9014f0953e9 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -130,7 +130,7 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti); nulls[9] = false; - values[10] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset); + values[10] = Int64GetDatum(ControlFile->checkPointCopy.nextMultiOffset); nulls[10] = false; values[11] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 8b5dd160cdf..f11e244899e 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202608182 +#define CATALOG_VERSION_NO 202608271 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f5867349d14..805a579080d 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -12346,7 +12346,7 @@ descr => 'pg_controldata checkpoint state information as a function', proname => 'pg_control_checkpoint', provolatile => 'v', prorettype => 'record', proargtypes => '', - proallargtypes => '{pg_lsn,pg_lsn,text,int4,int4,bool,bool,text,oid,xid,xid,xid,oid,xid,xid,oid,xid,xid,int4,timestamptz}', + proallargtypes => '{pg_lsn,pg_lsn,text,int4,int4,bool,bool,text,oid,xid,int8,xid,oid,xid,xid,oid,xid,xid,int4,timestamptz}', proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', proargnames => '{checkpoint_lsn,redo_lsn,redo_wal_file,timeline_id,prev_timeline_id,full_page_writes,logical_decoding,next_xid,next_oid,next_multixact_id,next_multi_offset,oldest_xid,oldest_xid_dbid,oldest_active_xid,oldest_multi_xid,oldest_multi_dbid,oldest_commit_ts_xid,newest_commit_ts_xid,data_page_checksum_version,checkpoint_time}', prosrc => 'pg_control_checkpoint' }, From 7a74e5ed92d4e36f5b8da3db66457d6f32cf80f3 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Fri, 28 Aug 2026 13:10:56 +1200 Subject: [PATCH 463/481] Fix incorrect multi-column RANGE partition pruning When performing partition pruning with a RANGE partitioned table where the pruning quals are only present for a leading prefix of the partition key, it was possible that partition pruning would accidentally prune away some partitions which shouldn't be pruned and include some partitions that were not needed. This happened due to an incorrectly coded loop bound which was terminating the loop when the bound reached the first or last element in the partition bound array. This resulted in those end elements not being checked in cases where they should be checked. It appears that it might have been coded this way to avoid stepping off the array, but that was done incorrectly as it failed to take into account the direction of travel through the array (the loop can go forwards or backwards). I.e., it's valid to loop when 'off' is the last element if we're going backwards through the array, and valid to loop if 'off' is 0 and we're looping forward through the array, but the code as it was didn't allow that. Here we fix this by moving the loop condition check to after we've calculated the array element to process, and break from the loop if that element is beyond either end of the array. Example of accidentally pruned partition: p: partition by range (a, b); p1: for values from (1, 4) to (1, 7); p2: for values from (1, 7) to (3, 8); p3: for values from (4, 8) to (6, 9); def: default; select * from p where a <= 1; Here p2 was pruned by mistake. Example of accidentally not pruning a partition: p: partition by range (a, b); p1: for values from (7, 2) to (7, 7); def: default; select * from p where a > 7; No partitions would be pruned in this case, despite it being impossible for matching rows to exist in p1. Author: David Rowley Reviewed-by: Ayush Tiwari Reviewed-by: Tender Wang Discussion: https://postgr.es/m/CAApHDvp5ne9AWaH-tG1Lke-USLz3NwWLWTUdP5NT7ypKtcFqcg@mail.gmail.com Backpatch-through: 14 --- src/backend/partitioning/partprune.c | 14 ++++++-- src/test/regress/expected/partition_prune.out | 33 +++++++++++++++++++ src/test/regress/sql/partition_prune.sql | 20 +++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c index afe57ac297d..86fa13b3e05 100644 --- a/src/backend/partitioning/partprune.c +++ b/src/backend/partitioning/partprune.c @@ -3207,12 +3207,15 @@ get_matching_range_bounds(PartitionPruneContext *context, * of smallest such bound) or find the smallest one that's * greater than the lookup values and set minoff to that. */ - while (off >= 1 && off < boundinfo->ndatums - 1) + while (true) { int32 cmpval; int nextoff; nextoff = inclusive ? off - 1 : off + 1; + + if (nextoff < 0 || nextoff >= boundinfo->ndatums) + break; cmpval = partition_rbound_datum_cmp(partsupfunc, partcollation, @@ -3266,16 +3269,21 @@ get_matching_range_bounds(PartitionPruneContext *context, if (off >= 0) { /* - * See the comment above. + * As above, check adjacent bounds to see if the bound is + * equal to the lookup value. */ if (is_equal && nvalues < partnatts) { - while (off >= 1 && off < boundinfo->ndatums - 1) + while (true) { int32 cmpval; int nextoff; nextoff = inclusive ? off + 1 : off - 1; + + if (nextoff < 0 || nextoff >= boundinfo->ndatums) + break; + cmpval = partition_rbound_datum_cmp(partsupfunc, partcollation, boundinfo->datums[nextoff], diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out index aa821646011..8f1119a026d 100644 --- a/src/test/regress/expected/partition_prune.out +++ b/src/test/regress/expected/partition_prune.out @@ -1099,6 +1099,39 @@ explain (costs off) select * from mc2p where b is null; Filter: (b IS NULL) (2 rows) +create table mc2ap (a int, b int) partition by range (a, b); +create table mc2ap1 partition of mc2ap for values from (1, 4) to (1, 7); +create table mc2ap2 partition of mc2ap for values from (1, 7) to (3, 8); +create table mc2ap3 partition of mc2ap for values from (4, 8) to (6, 9); +create table mc2ap_def partition of mc2ap default; +-- Ensure we scan all partitions apart from mc2ap3 +explain (costs off) select count(*) from mc2ap where a <= 1; + QUERY PLAN +------------------------------------------- + Aggregate + -> Append + -> Seq Scan on mc2ap1 mc2ap_1 + Filter: (a <= 1) + -> Seq Scan on mc2ap2 mc2ap_2 + Filter: (a <= 1) + -> Seq Scan on mc2ap_def mc2ap_3 + Filter: (a <= 1) +(8 rows) + +drop table mc2ap; +create table mc2bp (c1 int, c2 int) partition by range (c1, c2); +create table mc2bp1 partition of mc2bp for values from (7, 2) to (7, 7); +create table mc2bp_def partition of mc2bp default; +-- Ensure mc2bp1 is pruned and we only scan mc2bp_def +explain (costs off) select count(*) from mc2bp where c1 > 7; + QUERY PLAN +----------------------------------- + Aggregate + -> Seq Scan on mc2bp_def mc2bp + Filter: (c1 > 7) +(3 rows) + +drop table mc2bp; -- boolean partitioning create table boolpart (a bool) partition by list (a); create table boolpart_default partition of boolpart default; diff --git a/src/test/regress/sql/partition_prune.sql b/src/test/regress/sql/partition_prune.sql index dac673ef80a..f967658d4b5 100644 --- a/src/test/regress/sql/partition_prune.sql +++ b/src/test/regress/sql/partition_prune.sql @@ -192,6 +192,26 @@ explain (costs off) select * from mc2p where a is null and b = 1; explain (costs off) select * from mc2p where a is null; explain (costs off) select * from mc2p where b is null; +create table mc2ap (a int, b int) partition by range (a, b); +create table mc2ap1 partition of mc2ap for values from (1, 4) to (1, 7); +create table mc2ap2 partition of mc2ap for values from (1, 7) to (3, 8); +create table mc2ap3 partition of mc2ap for values from (4, 8) to (6, 9); +create table mc2ap_def partition of mc2ap default; + +-- Ensure we scan all partitions apart from mc2ap3 +explain (costs off) select count(*) from mc2ap where a <= 1; + +drop table mc2ap; + +create table mc2bp (c1 int, c2 int) partition by range (c1, c2); +create table mc2bp1 partition of mc2bp for values from (7, 2) to (7, 7); +create table mc2bp_def partition of mc2bp default; + +-- Ensure mc2bp1 is pruned and we only scan mc2bp_def +explain (costs off) select count(*) from mc2bp where c1 > 7; + +drop table mc2bp; + -- boolean partitioning create table boolpart (a bool) partition by list (a); create table boolpart_default partition of boolpart default; From 15ccc2041ee864cccc8b72de4a1f21e9b51ccc47 Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Fri, 28 Aug 2026 14:51:36 +0900 Subject: [PATCH 464/481] Propagate disabled_nodes to single-child Append paths create_append_path() skips cost_append() when an Append has exactly one child whose parallel awareness matches its own, since setrefs.c strips such an Append out entirely. In that case it copies the child's rowcount and costs directly, but it failed to copy disabled_nodes. An Append over a disabled child therefore claimed to contain no disabled nodes, letting a disabled path win over one that is not disabled. This is a regression in v18; before e22253467, disable_cost was folded into a path's startup and total costs, so it rode along in the fields this shortcut already copies. Back-patch to v18. This can change plans in stable branches, but only for installations that have explicitly disabled a node type, and only to stop using the node they asked us to avoid. Reported-by: Man Zeng Author: Tender Wang Reviewed-by: Richard Guo Reviewed-by: David Rowley Discussion: https://postgr.es/m/CAHewXNm_Zx5EDoaD7wo7bq6cfRroNznS+RBCzT_p2-CWQXpgSw@mail.gmail.com Backpatch-through: 18 --- src/backend/optimizer/util/pathnode.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 73518c8f870..ece2fb7568f 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -1442,9 +1442,9 @@ create_append_path(PlannerInfo *root, * child's pathkeys if any, overriding whatever the caller might've said. * Furthermore, if the child's parallel awareness matches the Append's, * then the Append is a no-op and will be discarded later (in setrefs.c). - * Then we can inherit the child's size and cost too, effectively charging - * zero for the Append. Otherwise, we must do the normal costsize - * calculation. + * Then we can inherit the child's size, cost and disabled-node count too, + * effectively charging zero for the Append. Otherwise, we must do the + * normal costsize calculation. */ if (list_length(pathnode->subpaths) == 1) { @@ -1453,6 +1453,7 @@ create_append_path(PlannerInfo *root, if (child->parallel_aware == parallel_aware) { pathnode->path.rows = child->rows; + pathnode->path.disabled_nodes = child->disabled_nodes; pathnode->path.startup_cost = child->startup_cost; pathnode->path.total_cost = child->total_cost; } From 5523e4d9add7379398b5a998b83ddce3f64d72a4 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Fri, 28 Aug 2026 09:36:13 -0400 Subject: [PATCH 465/481] Make platform guards in two regression tests match meson builds collate.linux.utf8 skips itself unless version() matches "linux-gnu", and infinite_recurse skips itself when version() matches "powerpc64[^,]*-linux-gnu". configure substitutes the GNU host triplet into that string, but the meson build composes it from host_machine.cpu_family() and host_system, which never carries the ABI suffix. So ever since meson support arrived in 16, collate.linux.utf8 has not run at all on a meson build, and infinite_recurse has been running on ppc64 Linux the very case it means to stay away from. Meson documentation says it reports 'ppc64' instead of 'powerpc64'. Fix by matching "-linux[-,]" and "p(ower)?pc64[^,]*-linux", which match all spellings. Keeping the punctuation on either side confines the match to the platform field. Neither pattern excludes musl, but collate.linux.utf8's other conditions already require a set of glibc locales to be present. Backpatch to 16, where the meson build was introduced. Discussion: https://postgr.es/m/a40b19da-9a02-47b4-8afd-2bbbde8db1e8@dunslane.net Reviewed-By: Jonathan Gonzalez V. Reviewed-By: Nazir Bilal Yavuz --- src/test/regress/expected/collate.linux.utf8.out | 2 +- src/test/regress/expected/collate.linux.utf8_1.out | 2 +- src/test/regress/expected/infinite_recurse.out | 2 +- src/test/regress/expected/infinite_recurse_1.out | 2 +- src/test/regress/sql/collate.linux.utf8.sql | 2 +- src/test/regress/sql/infinite_recurse.sql | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/regress/expected/collate.linux.utf8.out b/src/test/regress/expected/collate.linux.utf8.out index e0a39e4c300..27b5e57f6db 100644 --- a/src/test/regress/expected/collate.linux.utf8.out +++ b/src/test/regress/expected/collate.linux.utf8.out @@ -5,7 +5,7 @@ */ SELECT getdatabaseencoding() <> 'UTF8' OR (SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR - version() !~ 'linux-gnu' + version() !~ '-linux[-,]' AS skip_test \gset \if :skip_test \quit diff --git a/src/test/regress/expected/collate.linux.utf8_1.out b/src/test/regress/expected/collate.linux.utf8_1.out index ede5fdb5dcc..01faaa9fd1d 100644 --- a/src/test/regress/expected/collate.linux.utf8_1.out +++ b/src/test/regress/expected/collate.linux.utf8_1.out @@ -5,7 +5,7 @@ */ SELECT getdatabaseencoding() <> 'UTF8' OR (SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR - version() !~ 'linux-gnu' + version() !~ '-linux[-,]' AS skip_test \gset \if :skip_test \quit diff --git a/src/test/regress/expected/infinite_recurse.out b/src/test/regress/expected/infinite_recurse.out index aa102fadd83..b85467170a7 100644 --- a/src/test/regress/expected/infinite_recurse.out +++ b/src/test/regress/expected/infinite_recurse.out @@ -10,7 +10,7 @@ create function infinite_recurse() returns int as -- production kernels, so disable this test on such platforms. -- (We still create the function, so as not to have a cross-platform -- difference in the end state of the regression database.) -SELECT version() ~ 'powerpc64[^,]*-linux-gnu' +SELECT version() ~ 'p(ower)?pc64[^,]*-linux' AS skip_test \gset \if :skip_test \quit diff --git a/src/test/regress/expected/infinite_recurse_1.out b/src/test/regress/expected/infinite_recurse_1.out index b2c99a0d0d4..6aa194657cc 100644 --- a/src/test/regress/expected/infinite_recurse_1.out +++ b/src/test/regress/expected/infinite_recurse_1.out @@ -10,7 +10,7 @@ create function infinite_recurse() returns int as -- production kernels, so disable this test on such platforms. -- (We still create the function, so as not to have a cross-platform -- difference in the end state of the regression database.) -SELECT version() ~ 'powerpc64[^,]*-linux-gnu' +SELECT version() ~ 'p(ower)?pc64[^,]*-linux' AS skip_test \gset \if :skip_test \quit diff --git a/src/test/regress/sql/collate.linux.utf8.sql b/src/test/regress/sql/collate.linux.utf8.sql index 6d726ee9c99..9e627db3abb 100644 --- a/src/test/regress/sql/collate.linux.utf8.sql +++ b/src/test/regress/sql/collate.linux.utf8.sql @@ -6,7 +6,7 @@ SELECT getdatabaseencoding() <> 'UTF8' OR (SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR - version() !~ 'linux-gnu' + version() !~ '-linux[-,]' AS skip_test \gset \if :skip_test \quit diff --git a/src/test/regress/sql/infinite_recurse.sql b/src/test/regress/sql/infinite_recurse.sql index 151dba4a7ae..7516ae5b10f 100644 --- a/src/test/regress/sql/infinite_recurse.sql +++ b/src/test/regress/sql/infinite_recurse.sql @@ -13,7 +13,7 @@ create function infinite_recurse() returns int as -- (We still create the function, so as not to have a cross-platform -- difference in the end state of the regression database.) -SELECT version() ~ 'powerpc64[^,]*-linux-gnu' +SELECT version() ~ 'p(ower)?pc64[^,]*-linux' AS skip_test \gset \if :skip_test \quit From da8da39102788aabe2d479354cb146651825b094 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 28 Aug 2026 10:04:58 -0400 Subject: [PATCH 466/481] doc PG 19 relnotes: move replication items to logical replicat. Reported-by: Masahiko Sawada Author: Masahiko Sawada Discussion: https://postgr.es/m/CAD21AoC1dJGqngg_cdT_ayQjOdw6gmSBfVOTtAWOq-5C+XeLZQ@mail.gmail.com Backpatch-through: 19 only --- doc/src/sgml/release-19.sgml | 62 ++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/doc/src/sgml/release-19.sgml b/doc/src/sgml/release-19.sgml index a8046ab41f0..2cb8d4da3fe 100644 --- a/doc/src/sgml/release-19.sgml +++ b/doc/src/sgml/release-19.sgml @@ -1568,37 +1568,6 @@ Add server variable wal By default, senders still wait forever for synchronization. - - - - - - -Allow wal_receiver_timeout to be set per-subscription and user (Fujii Masao) -§ -§ - - - -This allows subscribers to use different wal_receiver_timeout values. - - - - - - - -Add optional pid parameter to pg_replication_origin_session_setup() to allow parallelization of SQL-level replication solutions (Doruk Yilmaz, Hayato Kuroda) -§ - @@ -1742,6 +1711,37 @@ When server variable wal_level< New server variable effective_wal_level, application pg_controldata, and function pg_control_checkpoint() report the effective WAL level. + + + + + + +Allow wal_receiver_timeout to be set per-subscription and user (Fujii Masao) +§ +§ + + + +This allows subscribers to use different wal_receiver_timeout values. + + + + + + + +Add optional pid parameter to pg_replication_origin_session_setup() to allow parallelization of SQL-level replication solutions (Doruk Yilmaz, Hayato Kuroda) +§ + From 92d44b200e12c7ecbaee57d37fcd5e8803811358 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 28 Aug 2026 17:48:46 +0300 Subject: [PATCH 467/481] Fix backend state after a failed after-startup shmem request RegisterShmemCallbacks() left the backend in a bad state, if an error occurred in the callbacks or if an allocation failed. Firstly, 'shmem_request_state' was left in wrong state, causing a subsequent call to RegisterShmemCallbacks() to wrongly take the postmaster startup codepath or assertion failures in some other functions. Secondly, the 'pending_shmem_requests' list was not properly cleaned up, causing a subsequent RegisterShmemCallbacks() to try to process the stale, already-freed requests. To fix, add a PG_TRY() block to clean those things up on error. Author: Ayush Tiwari Reviewed-by: Ashutosh Bapat Discussion: https://www.postgresql.org/message-id/CAJTYsWVRRWH48=PcuAo_2Y4Ap6M0QRmzxgUfFkNRtdWK74LjBQ@mail.gmail.com Backpatch-through: 19 --- src/backend/storage/ipc/shmem.c | 74 +++++++++++++------ .../test_shmem/t/001_late_shmem_alloc.pl | 28 +++++++ src/test/modules/test_shmem/test_shmem.c | 28 ++++++- 3 files changed, 105 insertions(+), 25 deletions(-) diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index 85401f7bff6..10742788dcc 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -158,7 +158,9 @@ static List *registered_shmem_callbacks; /* * In the shmem request phase, all the shmem areas requested with the - * ShmemRequest*() functions are accumulated here. + * ShmemRequest*() functions are accumulated in the 'pending_shmem_requests' + * list. The List, the ShmemRequest structs, and the 'options' are all + * allocated in TopMemoryContext. */ typedef struct { @@ -166,7 +168,7 @@ typedef struct ShmemRequestKind kind; } ShmemRequest; -static List *pending_shmem_requests; +static List *pending_shmem_requests; /* List of ShmemRequests */ /* * Per-process state machine, for sanity checking that we do things in the @@ -274,6 +276,7 @@ typedef struct static bool firstNumaTouch = true; static void CallShmemCallbacksAfterStartup(const ShmemCallbacks *callbacks); +static void ProcessShmemRequestsAfterStartup(const ShmemCallbacks *callbacks); static void InitShmemIndexEntry(ShmemRequest *request); static bool AttachShmemIndexEntry(ShmemRequest *request, bool missing_ok); @@ -335,6 +338,7 @@ ShmemRequestStructWithOpts(const ShmemStructOpts *options) void ShmemRequestInternal(ShmemStructOpts *options, ShmemRequestKind kind) { + MemoryContext oldcontext; ShmemRequest *request; /* Check the options */ @@ -374,10 +378,12 @@ ShmemRequestInternal(ShmemStructOpts *options, ShmemRequestKind kind) } /* Request looks valid, remember it */ - request = palloc(sizeof(ShmemRequest)); + oldcontext = MemoryContextSwitchTo(TopMemoryContext); + request = palloc_object(ShmemRequest); request->options = options; request->kind = kind; pending_shmem_requests = lappend(pending_shmem_requests, request); + MemoryContextSwitchTo(oldcontext); } /* @@ -903,26 +909,49 @@ RegisterShmemCallbacks(const ShmemCallbacks *callbacks) static void CallShmemCallbacksAfterStartup(const ShmemCallbacks *callbacks) { - bool found_any; - bool notfound_any; - Assert(shmem_request_state == SRS_DONE); - shmem_request_state = SRS_REQUESTING; - - /* - * Call the request callback first. The callback makes ShmemRequest*() - * calls for each shmem area, adding them to pending_shmem_requests. - */ Assert(pending_shmem_requests == NIL); - if (callbacks->request_fn) - callbacks->request_fn(callbacks->opaque_arg); - shmem_request_state = SRS_AFTER_STARTUP_ATTACH_OR_INIT; - if (pending_shmem_requests == NIL) + PG_TRY(); + { + shmem_request_state = SRS_REQUESTING; + + /* + * Call the request callback first. The callback makes + * ShmemRequest*() calls for each shmem area, adding them to + * pending_shmem_requests. + */ + if (callbacks->request_fn) + callbacks->request_fn(callbacks->opaque_arg); + + /* Process all the requests */ + shmem_request_state = SRS_AFTER_STARTUP_ATTACH_OR_INIT; + if (pending_shmem_requests != NIL) + ProcessShmemRequestsAfterStartup(callbacks); + } + PG_FINALLY(); { + foreach_ptr(ShmemRequest, request, pending_shmem_requests) + pfree(request->options); + list_free_deep(pending_shmem_requests); + pending_shmem_requests = NIL; + shmem_request_state = SRS_DONE; - return; } + PG_END_TRY(); +} + +static void +ProcessShmemRequestsAfterStartup(const ShmemCallbacks *callbacks) +{ + bool found_any; + bool notfound_any; + + /* There should be some requests to process */ + Assert(pending_shmem_requests != NIL); + + /* Caller manages the global state variable */ + Assert(shmem_request_state == SRS_AFTER_STARTUP_ATTACH_OR_INIT); /* * Hold ShmemIndexLock while we allocate all the shmem entries and run all @@ -940,7 +969,11 @@ CallShmemCallbacksAfterStartup(const ShmemCallbacks *callbacks) found_any = notfound_any = false; foreach_ptr(ShmemRequest, request, pending_shmem_requests) { - if (hash_search(ShmemIndex, request->options->name, HASH_FIND, NULL)) + ShmemIndexEnt *index_entry; + + index_entry = (ShmemIndexEnt *) + hash_search(ShmemIndex, request->options->name, HASH_FIND, NULL); + if (index_entry) found_any = true; else notfound_any = true; @@ -958,11 +991,7 @@ CallShmemCallbacksAfterStartup(const ShmemCallbacks *callbacks) AttachShmemIndexEntry(request, false); else InitShmemIndexEntry(request); - - pfree(request->options); } - list_free_deep(pending_shmem_requests); - pending_shmem_requests = NIL; /* Finish by calling the appropriate subsystem-specific callback */ if (found_any) @@ -977,7 +1006,6 @@ CallShmemCallbacksAfterStartup(const ShmemCallbacks *callbacks) } LWLockRelease(ShmemIndexLock); - shmem_request_state = SRS_DONE; } /* diff --git a/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl b/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl index 546d6a92abe..6ea409f3c63 100644 --- a/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl +++ b/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl @@ -78,5 +78,33 @@ ); } +# clean up $node->stop; +$node->adjust_conf('postgresql.conf', "shared_preload_libraries", undef); + +### +# Test "out of shared memory" in an after-startup request +### +$node->start; +my $session = $node->background_psql('postgres', on_error_stop => 0); + +# make the request larger than the memory reserved for after-startup +# requests. +$session->query(q[SET test_shmem.area_size = '128kB';]); + +$session->query("SELECT get_test_shmem_attach_count();"); +like( + $session->{stderr}, + qr/not enough shared memory/, + "an after-startup request larger than the reserve fails"); + +# The server and the backend keep running. Since only one area was +# requested, it gets cleaned up on allocation failure. Verify that a +# request for a smaller area succeeds in the same session. +$session->{stderr} = ''; +$session->query("SET test_shmem.area_size = default;"); +$session->query_safe("SELECT get_test_shmem_attach_count();"); +$session->quit; +$node->stop; + done_testing(); diff --git a/src/test/modules/test_shmem/test_shmem.c b/src/test/modules/test_shmem/test_shmem.c index 9bd4012b435..231ad9a0027 100644 --- a/src/test/modules/test_shmem/test_shmem.c +++ b/src/test/modules/test_shmem/test_shmem.c @@ -20,20 +20,28 @@ #include "fmgr.h" #include "miscadmin.h" #include "storage/shmem.h" +#include "utils/guc.h" +#include "utils/injection_point.h" PG_MODULE_MAGIC; typedef struct TestShmemData { - int value; bool initialized; int attach_count; + char dummy_data[FLEXIBLE_ARRAY_MEMBER]; } TestShmemData; static TestShmemData *TestShmem; +#define MIN_TEST_AREA_BYTES sizeof(TestShmemData) +#define DEFAULT_TEST_AREA_BYTES MIN_TEST_AREA_BYTES +#define MAX_TEST_AREA_BYTES 1000000 + static bool attached_or_initialized = false; +static int test_shmem_area_size = MIN_TEST_AREA_BYTES; +static bool test_shmem_guc_defined = false; static void test_shmem_request(void *arg); static void test_shmem_init(void *arg); @@ -52,7 +60,7 @@ test_shmem_request(void *arg) elog(LOG, "test_shmem_request callback called"); ShmemRequestStruct(.name = "test_shmem area", - .size = sizeof(TestShmemData), + .size = test_shmem_area_size, .ptr = (void **) &TestShmem); } @@ -86,6 +94,22 @@ void _PG_init(void) { elog(LOG, "test_shmem module's _PG_init called"); + + if (!test_shmem_guc_defined) + { + DefineCustomIntVariable("test_shmem.area_size", + "Size of the shmem area to request.", + NULL, + &test_shmem_area_size, + DEFAULT_TEST_AREA_BYTES, + MIN_TEST_AREA_BYTES, + MAX_TEST_AREA_BYTES, + PGC_USERSET, + GUC_UNIT_BYTE, + NULL, NULL, NULL); + MarkGUCPrefixReserved("test_shmem"); + test_shmem_guc_defined = true; + } RegisterShmemCallbacks(&TestShmemCallbacks); } From 9d888cd3f34c4e9a8f7fbe7e78c70bbd84a481de Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 28 Aug 2026 17:49:38 +0300 Subject: [PATCH 468/481] Track which shmem areas have been fully initialized If SHMEM_CALLBACKS_ALLOW_AFTER_STARTUP is used to allocate shared memory after startup, but the initialization fails half-way through, the shmem area is left in an indeterminate state. Furthermore, if multiple shmem areas are registered in one RegisterShmemCallbacks() call, some might be allocated while others are not. This commit adds an explicit 'initialized' flag to each shmem area. We still leave behind an uninitialized area on error, but at least they are now clearly marked, and you get a slightly nicer error message if you try to re-register them. It'd be nice to clean up more thoroughly and support actually retrying the allocations, but in practice, the most likely reason for a shmem allocation or initialization to fail is that you are out of shared memory and retrying wouldn't help with that. This isn't exactly a new problem, the old ShmemInitStruct() interface had similar issues if the initialization code failed, or if you allocated multiple structs and some allocations failed. It was just left to the calling code to deal with it. Author: Ayush Tiwari Reviewed-by: Ashutosh Bapat Discussion: https://www.postgresql.org/message-id/CAJTYsWVRRWH48=PcuAo_2Y4Ap6M0QRmzxgUfFkNRtdWK74LjBQ@mail.gmail.com Backpatch-through: 19 --- doc/src/sgml/xfunc.sgml | 5 +- src/backend/storage/ipc/shmem.c | 67 +++++++++++++++++-- src/test/modules/test_shmem/Makefile | 3 + src/test/modules/test_shmem/meson.build | 3 + .../test_shmem/t/001_late_shmem_alloc.pl | 50 ++++++++++++-- src/test/modules/test_shmem/test_shmem.c | 3 + 6 files changed, 120 insertions(+), 11 deletions(-) diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 35916a1c25c..a27f061642e 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -3740,7 +3740,10 @@ my_shmem_init(void *arg) on whether the requested memory areas were already initialized by another backend. The callbacks will be called while holding an internal lock (ShmemIndexLock), which prevents the race condition of two backends - trying to initialize the memory area at the same time. + trying to initialize the memory area at the same time. If the + allocation or initialization fails for any reason, the shared memory + areas are left in an abandoned state and any attempt to attach or + re-initialize them will fail until the server is restarted. diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index 10742788dcc..444ff0e81bd 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -144,6 +144,8 @@ #include "utils/builtins.h" #include "utils/tuplestore.h" +typedef struct ShmemIndexEnt ShmemIndexEnt; + /* * Registered callbacks. * @@ -166,6 +168,9 @@ typedef struct { ShmemStructOpts *options; ShmemRequestKind kind; + + /* InitShmemIndexEntry() sets this pointer when the area is allocated */ + ShmemIndexEnt *index_entry; } ShmemRequest; static List *pending_shmem_requests; /* List of ShmemRequests */ @@ -264,12 +269,13 @@ static HTAB *ShmemIndex; #define SHMEM_INDEX_ADDITIONAL_SIZE (128) /* this is a hash bucket in the shmem index table */ -typedef struct +typedef struct ShmemIndexEnt { char key[SHMEM_INDEX_KEYSIZE]; /* string name */ void *location; /* location in shared mem */ Size size; /* # bytes requested for the structure */ Size allocated_size; /* # bytes actually allocated */ + bool initialized; /* has the init callback been run? */ } ShmemIndexEnt; /* To get reliable results for NUMA inquiry we need to "touch pages" once */ @@ -382,6 +388,7 @@ ShmemRequestInternal(ShmemStructOpts *options, ShmemRequestKind kind) request = palloc_object(ShmemRequest); request->options = options; request->kind = kind; + request->index_entry = NULL; pending_shmem_requests = lappend(pending_shmem_requests, request); MemoryContextSwitchTo(oldcontext); } @@ -441,10 +448,7 @@ ShmemInitRequested(void) foreach_ptr(ShmemRequest, request, pending_shmem_requests) { InitShmemIndexEntry(request); - pfree(request->options); } - list_free_deep(pending_shmem_requests); - pending_shmem_requests = NIL; /* * Call the subsystem-specific init callbacks to finish initialization of @@ -456,6 +460,15 @@ ShmemInitRequested(void) callbacks->init_fn(callbacks->opaque_arg); } + /* Now we can mark all the areas as initialized and free the requests */ + foreach_ptr(ShmemRequest, request, pending_shmem_requests) + { + request->index_entry->initialized = true; + pfree(request->options); + } + list_free_deep(pending_shmem_requests); + pending_shmem_requests = NIL; + shmem_request_state = SRS_DONE; } @@ -557,7 +570,12 @@ InitShmemIndexEntry(ShmemRequest *request) index_entry->allocated_size = allocated_size; index_entry->location = structPtr; - /* Initialize depending on the kind of shmem area it is */ + /* + * The area is considered fully initialized only after the subsystem's + * init callback has been called. For now, perform only basic + * initialization based on the kind of shmem area it is. + */ + index_entry->initialized = false; switch (request->kind) { case SHMEM_KIND_STRUCT: @@ -571,6 +589,9 @@ InitShmemIndexEntry(ShmemRequest *request) shmem_slru_init(structPtr, request->options); break; } + + /* return the pointer to the entry to the caller */ + request->index_entry = index_entry; } /* @@ -600,6 +621,20 @@ AttachShmemIndexEntry(ShmemRequest *request, bool missing_ok) return false; } + /* + * If it was previously allocated but not fully initialized, error out. + * There is currently no way of retrying or cleaning up an uninitialized + * entry, it just lingers until the server is shut down. But this can + * only happen when allocating areas after postmaster startup, and it's + * unlikely that you could successfully retry anyway. The most likely + * reason for failed initialization is that you are out of shared memory + * and retrying won't help with that. + */ + if (!index_entry->initialized) + ereport(ERROR, + (errmsg("cannot attach to shared memory struct \"%s\" because it was not fully initialized", + request->options->name))); + /* Check that the size in the index matches the request */ if (index_entry->size != request->options->size && request->options->size != SHMEM_ATTACH_UNKNOWN_SIZE) @@ -628,6 +663,8 @@ AttachShmemIndexEntry(ShmemRequest *request, bool missing_ok) break; } + request->index_entry = index_entry; + return true; } @@ -738,6 +775,7 @@ InitShmemAllocator(PGShmemHeader *seghdr) result->size = ShmemAllocator->index_size; result->allocated_size = ShmemAllocator->index_size; result->location = ShmemAllocator->index; + result->initialized = true; } } @@ -974,7 +1012,17 @@ ProcessShmemRequestsAfterStartup(const ShmemCallbacks *callbacks) index_entry = (ShmemIndexEnt *) hash_search(ShmemIndex, request->options->name, HASH_FIND, NULL); if (index_entry) + { + /* + * Check for a half-initialized area. (See also similar check in + * AttachShmemIndexEntry()) + */ + if (!index_entry->initialized) + ereport(ERROR, + (errmsg("cannot attach to shared memory struct \"%s\" because it was not fully initialized", + request->options->name))); found_any = true; + } else notfound_any = true; } @@ -1005,6 +1053,11 @@ ProcessShmemRequestsAfterStartup(const ShmemCallbacks *callbacks) callbacks->init_fn(callbacks->opaque_arg); } + foreach_ptr(ShmemRequest, request, pending_shmem_requests) + { + request->index_entry->initialized = true; + } + LWLockRelease(ShmemIndexLock); } @@ -1069,7 +1122,11 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr) /* Initialize it if not found */ if (!*foundPtr) + { InitShmemIndexEntry(&request); + /* no additional initialization needed */ + request.index_entry->initialized = true; + } LWLockRelease(ShmemIndexLock); diff --git a/src/test/modules/test_shmem/Makefile b/src/test/modules/test_shmem/Makefile index 2407f7462fe..fed8e29c8f5 100644 --- a/src/test/modules/test_shmem/Makefile +++ b/src/test/modules/test_shmem/Makefile @@ -2,6 +2,9 @@ PGFILEDESC = "test_shmem - test code for shmem allocations" +EXTRA_INSTALL = src/test/modules/injection_points +export enable_injection_points + MODULE_big = test_shmem OBJS = \ $(WIN32RES) \ diff --git a/src/test/modules/test_shmem/meson.build b/src/test/modules/test_shmem/meson.build index fb4bf328b8f..8f98f2c4e31 100644 --- a/src/test/modules/test_shmem/meson.build +++ b/src/test/modules/test_shmem/meson.build @@ -26,6 +26,9 @@ tests += { 'sd': meson.current_source_dir(), 'bd': meson.current_build_dir(), 'tap': { + 'env': { + 'enable_injection_points': get_option('injection_points') ? 'yes' : 'no', + }, 'tests': [ 't/001_late_shmem_alloc.pl', ], diff --git a/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl b/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl index 6ea409f3c63..a7126ebce3f 100644 --- a/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl +++ b/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl @@ -7,17 +7,20 @@ use PostgreSQL::Test::Utils; use Test::More; +# Initialize a cluster with the extension installed. The tests will +# call the function that comes with the extension to load it. +my $node = PostgreSQL::Test::Cluster->new('main'); +$node->init; +$node->start; +$node->safe_psql("postgres", "CREATE EXTENSION test_shmem"); +$node->stop; + ### # Test allocating memory after startup, i.e. when the library is not # in shared_preload_libraries ### -my $node = PostgreSQL::Test::Cluster->new('main'); -$node->init; $node->start; - -$node->safe_psql("postgres", "CREATE EXTENSION test_shmem;"); - # Check that the attach counter is incremented on a new connection my $attach_count1 = $node->safe_psql("postgres", "SELECT get_test_shmem_attach_count();"); @@ -25,6 +28,7 @@ $node->safe_psql("postgres", "SELECT get_test_shmem_attach_count();"); cmp_ok($attach_count2, '>', $attach_count1, "attach callback is called in each backend"); + $node->stop; ### @@ -82,6 +86,42 @@ $node->stop; $node->adjust_conf('postgresql.conf', "shared_preload_libraries", undef); +### +# Test a failure in initializing the shared memory area +### +SKIP: +{ + skip "injection points not supported by this build", + if $ENV{enable_injection_points} ne 'yes'; + $node->start; + $node->safe_psql("postgres", "CREATE EXTENSION injection_points;"); + $node->safe_psql("postgres", + "SELECT injection_points_attach('test-shmem-init', 'error');"); + + # Try to load the extension library. It will hit the injected + # error in the init callback. + my (undef, undef, $stderr) = + $node->psql("postgres", "SELECT get_test_shmem_attach_count();"); + like( + $stderr, + qr/error triggered for injection point test-shmem-init/, + "failure in initialization is reported"); + $node->safe_psql("postgres", + "SELECT injection_points_detach('test-shmem-init');"); + + # The error leaves the shared memory area in a broken state. + # Attempting to initialize or attach it again will fail, until the + # server is restarted. + (undef, undef, $stderr) = + $node->psql("postgres", "SELECT get_test_shmem_attach_count();"); + like( + $stderr, + qr/cannot attach to shared memory/, + "post-init extension creation fails"); + + $node->stop; +} + ### # Test "out of shared memory" in an after-startup request ### diff --git a/src/test/modules/test_shmem/test_shmem.c b/src/test/modules/test_shmem/test_shmem.c index 231ad9a0027..6cf47dc8968 100644 --- a/src/test/modules/test_shmem/test_shmem.c +++ b/src/test/modules/test_shmem/test_shmem.c @@ -68,6 +68,9 @@ static void test_shmem_init(void *arg) { elog(LOG, "init callback called"); + + INJECTION_POINT("test-shmem-init", NULL); + if (TestShmem->initialized) elog(ERROR, "shmem area already initialized"); TestShmem->initialized = true; From 0ab90a5c94188ab0a2113e36c73f093f741129c1 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 28 Aug 2026 15:12:26 -0400 Subject: [PATCH 469/481] Perform join removal by editing the query's jointree. analyzejoins.c decided which joins could be dropped by consulting the planner's derived data structures, but then implemented the removal by updating those structures in-place. That is a lot of fiddly work, and nothing keeps it in step with the rest of the planner: remove_leftjoinrel_from_query only bothered to update "parts of the planner's data structures that will actually be consulted later", with no good way to know what those are. Bug #19560 is one consequence. In that report, removing a join leaves an EquivalenceClass that now gives rise to a base restriction clause, but base restriction clauses have already been generated and nothing reconsiders them, so the WHERE condition disappears from the plan and we return wrong answers. The self-join elimination code has the same design and the same type of hazard. We have seen many related bugs over the years too, so it's time to do something drastic. To fix, do the removals by editing root->parse->jointree (which is a far simpler and more stable representation than the derived data), and then have query_planner() discard everything it computed from the jointree and derive it over again. This requires quite a bit less code, and doesn't require touching analyzejoins.c every time we change the data derived by query_planner(). For typical cases it can actually save a bit of planning time, though in cases where we have to iterate the derivation loop many times it does add some time. reduce_unique_semijoins() gets the same treatment: rather than deleting the semijoin's SpecialJoinInfo and relying on the jointree not being consulted again, it now changes the JoinExpr's jointype to JOIN_INNER and recalculates everything. Some plans change in the join regression test. Qual evaluation order shifts in a few cases, because the conditions now reach later planning in jointree order rather than in whatever order the removal code re-distributed them. A few plans improve, since the rebuilt relation targetlists no longer carry columns that only a removed join needed. We also detect a constant-false filter condition whose test used to carry a FIXME label. One plan gets marginally worse, because the old code recomputed attr_needed from equivalence classes after a join removal; that is more accurate than what deconstruct_jointree() derives from the original clauses, but we no longer do that. Making that recomputation happen anyway could be worth doing, but it should be considered independently and perhaps implemented differently. Back-patch to v16, on the grounds that the introduction of varnullingrels in v16 made the old approach significantly more complex and bug-prone; notably, bug #19560 does not manifest before v16. In released branches, do not remove externally-visible fixup functions such as remove_join_clause_from_rels, in case any extensions are relying on them; but they're no longer used by core code. But we must nonetheless break API/ABI for remove_useless_joins, reduce_unique_semijoins, and remove_useless_self_joins, as those now have different outputs and very different behavior than before. It seems unlikely that any extensions are calling those; but just in case, make the breakage more obvious by renaming remove_useless_joins to remove_useless_outer_joins, which is a more sensible name for it anyway since the addition of remove_useless_self_joins. Full disclosure: initial drafts of this patch were made with Claude Opus 4.8. Bug: #19560 Reported-by: Orestis Markou Author: Tom Lane Reviewed-by: Richard Guo Reviewed-by: Thom Brown Reviewed-by: Jacob Brazeal Discussion: https://postgr.es/m/1186816.1784573544@sss.pgh.pa.us Backpatch-through: 16 --- src/backend/optimizer/path/equivclass.c | 51 +- src/backend/optimizer/plan/analyzejoins.c | 1878 +++++++-------------- src/backend/optimizer/plan/initsplan.c | 185 +- src/backend/optimizer/plan/planmain.c | 98 +- src/backend/optimizer/plan/planner.c | 18 +- src/backend/optimizer/util/joininfo.c | 36 - src/backend/optimizer/util/placeholder.c | 27 - src/backend/rewrite/rewriteManip.c | 109 +- src/include/nodes/primnodes.h | 4 + src/include/optimizer/joininfo.h | 3 - src/include/optimizer/paths.h | 2 - src/include/optimizer/placeholder.h | 1 - src/include/optimizer/planmain.h | 14 +- src/include/rewrite/rewriteManip.h | 19 - src/test/regress/expected/join.out | 159 +- src/test/regress/expected/rowsecurity.out | 11 + src/test/regress/sql/join.sql | 58 +- src/test/regress/sql/rowsecurity.sql | 4 + src/tools/pgindent/typedefs.list | 1 - 19 files changed, 1005 insertions(+), 1673 deletions(-) diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c index e3697df51a2..66fe1c24a58 100644 --- a/src/backend/optimizer/path/equivclass.c +++ b/src/backend/optimizer/path/equivclass.c @@ -89,6 +89,7 @@ static void ec_build_derives_hash(PlannerInfo *root, EquivalenceClass *ec); static void ec_add_derived_clauses(EquivalenceClass *ec, List *clauses); static void ec_add_derived_clause(EquivalenceClass *ec, RestrictInfo *clause); static void ec_add_clause_to_derives_hash(EquivalenceClass *ec, RestrictInfo *rinfo); +static void ec_clear_derived_clauses(EquivalenceClass *ec); static RestrictInfo *ec_search_clause_for_ems(PlannerInfo *root, EquivalenceClass *ec, EquivalenceMember *leftem, EquivalenceMember *rightem, @@ -1452,8 +1453,7 @@ generate_base_implied_equalities_no_const(PlannerInfo *root, * For the moment we force all the Vars to be available at all join nodes * for this eclass. Perhaps this could be improved by doing some * pre-analysis of which members we prefer to join, but it's no worse than - * what happened in the pre-8.3 code. (Note: rebuild_eclass_attr_needed - * needs to match this code.) + * what happened in the pre-8.3 code. */ foreach(lc, ec->ec_members) { @@ -2560,51 +2560,6 @@ reconsider_full_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo) return false; /* failed to make any deduction */ } -/* - * rebuild_eclass_attr_needed - * Put back attr_needed bits for Vars/PHVs needed for join eclasses. - * - * This is used to rebuild attr_needed/ph_needed sets after removal of a - * useless outer join. It should match what - * generate_base_implied_equalities_no_const did, except that we call - * add_vars_to_attr_needed not add_vars_to_targetlist. - */ -void -rebuild_eclass_attr_needed(PlannerInfo *root) -{ - ListCell *lc; - - foreach(lc, root->eq_classes) - { - EquivalenceClass *ec = (EquivalenceClass *) lfirst(lc); - - /* - * We don't expect any EC child members to exist at this point. Ensure - * that's the case, otherwise, we might be getting asked to do - * something this function hasn't been coded for. - */ - Assert(ec->ec_childmembers == NULL); - - /* Need do anything only for a multi-member, no-const EC. */ - if (list_length(ec->ec_members) > 1 && !ec->ec_has_const) - { - ListCell *lc2; - - foreach(lc2, ec->ec_members) - { - EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc2); - List *vars = pull_var_clause((Node *) cur_em->em_expr, - PVC_RECURSE_AGGREGATES | - PVC_RECURSE_WINDOWFUNCS | - PVC_INCLUDE_PLACEHOLDERS); - - add_vars_to_attr_needed(root, vars, ec->ec_relids); - list_free(vars); - } - } - } -} - /* * find_join_domain * Find the highest JoinDomain enclosed within the given relid set. @@ -3826,7 +3781,7 @@ ec_add_clause_to_derives_hash(EquivalenceClass *ec, RestrictInfo *rinfo) * when thousands of partitions are involved, so we free it as well -- even * though we do not typically free lists. */ -void +static void ec_clear_derived_clauses(EquivalenceClass *ec) { list_free(ec->ec_derives_list); diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c index 9b694104aa3..c22a04d1751 100644 --- a/src/backend/optimizer/plan/analyzejoins.c +++ b/src/backend/optimizer/plan/analyzejoins.c @@ -7,9 +7,14 @@ * certain optimizations cannot be performed at that stage for lack of * detailed information about the query. The routines here are invoked * after initsplan.c has done its work, and can do additional join removal - * and simplification steps based on the information extracted. The penalty - * is that we have to work harder to clean up after ourselves when we modify - * the query, since the derived data structures have to be updated too. + * and simplification steps based on the information extracted. + * + * Although the decisions about what can be removed are made using the + * planner's derived data structures, the removals themselves are implemented + * by editing the query's jointree, which is a far simpler and more stable + * representation. We make no attempt to update the derived data structures + * to match; instead, query_planner() throws them all away and recomputes them + * whenever we report having removed something. * * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California @@ -23,13 +28,13 @@ #include "postgres.h" #include "catalog/pg_class.h" +#include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/joininfo.h" #include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" -#include "optimizer/placeholder.h" #include "optimizer/planmain.h" +#include "optimizer/prep.h" #include "optimizer/restrictinfo.h" #include "parser/parse_agg.h" #include "rewrite/rewriteManip.h" @@ -55,24 +60,23 @@ bool enable_self_join_elimination; /* local functions */ static bool join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo); -static void remove_leftjoinrel_from_query(PlannerInfo *root, int relid, - SpecialJoinInfo *sjinfo); -static void remove_rel_from_query(PlannerInfo *root, int relid, - int subst, SpecialJoinInfo *sjinfo, - Relids joinrelids); -static void remove_rel_from_restrictinfo(RestrictInfo *rinfo, - int relid, int ojrelid); -static void remove_rel_from_eclass(PlannerInfo *root, EquivalenceClass *ec, - int relid, int ojrelid); -static void remove_rel_from_restrictinfo_phvs(RestrictInfo *rinfo, - int relid, int ojrelid); -static Node *remove_rel_from_phvs(Node *node, int relid, int ojrelid); -static Node *remove_rel_from_phvs_mutator(Node *node, Relids removable); -static List *remove_rel_from_joinlist(List *joinlist, int relid, int *nremoved); +static Node *remove_join_from_jointree(Node *jtnode, int ojrelid, + int *nremoved); +static void remove_rels_from_query_tree(PlannerInfo *root, + Relids removed_relids); +static bool reduce_semijoin_in_jointree(Node *jtnode, Relids syn_righthand); static bool rel_supports_distinctness(PlannerInfo *root, RelOptInfo *rel); static bool rel_is_distinct_for(PlannerInfo *root, RelOptInfo *rel, List *clause_list, List **extra_clauses); static DistinctColInfo *distinct_col_search(int colno, List *distinct_cols); +static bool innerrel_is_unique_ext(PlannerInfo *root, + Relids joinrelids, + Relids outerrelids, + RelOptInfo *innerrel, + JoinType jointype, + List *restrictlist, + bool force_cache, + List **extra_clauses); static bool is_innerrel_unique_for(PlannerInfo *root, Relids joinrelids, Relids outerrelids, @@ -80,71 +84,100 @@ static bool is_innerrel_unique_for(PlannerInfo *root, JoinType jointype, List *restrictlist, List **extra_clauses); +static Node *remove_rel_from_jointree(Node *jtnode, int relid, + Node **orphan_quals, int *nremoved); +static Node *merge_quals(Node *quals1, Node *quals2); +static void fixup_selfjoin_jointree(PlannerInfo *root, Node *jtnode, int relid, + Node **hoist_quals, bool *found_relid); +static List *fixup_selfjoin_quals(PlannerInfo *root, List *quals, int relid); +static Node *replace_selfjoin_qual(Node *qual); static int self_join_candidates_cmp(const void *a, const void *b); -static bool replace_relid_callback(Node *node, - ChangeVarNodes_context *context); /* - * remove_useless_joins + * remove_useless_outer_joins * Check for relations that don't actually need to be joined at all, - * and remove them from the query. + * and remove them from the query's jointree. * - * We are passed the current joinlist and return the updated list. Other - * data structures that have to be updated are accessible via "root". + * Returns true if we removed anything. In that case the caller must discard + * everything it has derived from the jointree and compute it over again, + * since we don't try to update any of that here. */ -List * -remove_useless_joins(PlannerInfo *root, List *joinlist) +bool +remove_useless_outer_joins(PlannerInfo *root) { + Relids removed_relids = NULL; ListCell *lc; /* * We are only interested in relations that are left-joined to, so we can * scan the join_info_list to find them easily. */ -restart: foreach(lc, root->join_info_list) { SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc); int innerrelid; int nremoved; + RangeTblEntry *rte; /* Skip if not removable */ if (!join_is_removable(root, sjinfo)) continue; /* - * Currently, join_is_removable can only succeed when the sjinfo's - * righthand is a single baserel. Remove that rel from the query and - * joinlist. + * join_is_removable insists that the join's syntactic righthand side + * be a single baserel, so we can implement the removal by dropping + * the JoinExpr and everything below its righthand side. */ - innerrelid = bms_singleton_member(sjinfo->min_righthand); - - remove_leftjoinrel_from_query(root, innerrelid, sjinfo); + innerrelid = bms_singleton_member(sjinfo->syn_righthand); - /* We verify that exactly one reference gets removed from joinlist */ + /* We verify that exactly one JoinExpr gets removed */ nremoved = 0; - joinlist = remove_rel_from_joinlist(joinlist, innerrelid, &nremoved); + root->parse->jointree = (FromExpr *) + remove_join_from_jointree((Node *) root->parse->jointree, + sjinfo->ojrelid, &nremoved); if (nremoved != 1) - elog(ERROR, "failed to find relation %d in joinlist", innerrelid); + elog(ERROR, "failed to find join %d in jointree", sjinfo->ojrelid); + + /* Track all the relids we've removed, for use below */ + removed_relids = bms_add_member(removed_relids, innerrelid); + removed_relids = bms_add_member(removed_relids, sjinfo->ojrelid); /* - * We can delete this SpecialJoinInfo from the list too, since it's no - * longer of interest. (Since we'll restart the foreach loop - * immediately, we don't bother with foreach_delete_current.) + * As in pull_up_simple_subquery, discard no-longer-needed subqueries. + * This is not just an optimization, but is necessary to prevent + * subsequent processing from descending into stale subtrees and + * seeing inconsistent data. Likewise discard any securityQuals of + * the removed rel. (Although simple_rte_array[] will be rebuilt + * shortly, we can still use it to find the RTE in the parse tree.) */ - root->join_info_list = list_delete_cell(root->join_info_list, lc); + rte = root->simple_rte_array[innerrelid]; + if (rte->rtekind == RTE_SUBQUERY) + rte->subquery = NULL; + rte->securityQuals = NIL; /* - * Restart the scan. This is necessary to ensure we find all - * removable joins independently of ordering of the join_info_list - * (note that removal of attr_needed bits may make a join appear - * removable that did not before). + * It's okay to keep scanning join_info_list for more removable joins, + * even though the data that join_is_removable consults is now + * slightly out of date. Removing a join can only delete attr_needed + * bits and join clauses, and any attr_needed bit or join clause that + * mentions the removed rel above its own join level would have + * prevented that rel from being removable. So what remains to be + * examined is unchanged by what we just did. + * + * The converse doesn't hold: dropping a join can make some other join + * removable that didn't look so before. That's why our caller loops + * until we report finding nothing more to remove. */ - goto restart; } - return joinlist; + if (bms_is_empty(removed_relids)) + return false; + + /* Clean up the traces that the removed rels have left elsewhere */ + remove_rels_from_query_tree(root, removed_relids); + + return true; } /* @@ -176,8 +209,15 @@ join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo) if (sjinfo->jointype != JOIN_LEFT) return false; - if (!bms_get_singleton_member(sjinfo->min_righthand, &innerrelid)) + /* + * We test the syntactic righthand side, not min_righthand, because the + * removal is done by deleting the whole righthand subtree of the join. + * (min_righthand can be a singleton when syn_righthand is not, but in + * such a case the attr_needed tests below would reject the join anyway.) + */ + if (!bms_get_singleton_member(sjinfo->syn_righthand, &innerrelid)) return false; + Assert(bms_equal(sjinfo->min_righthand, sjinfo->syn_righthand)); /* * Never try to eliminate a left join to the query result rel. Although @@ -319,712 +359,90 @@ join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo) } /* - * Remove the target relid and references to the target join from the - * planner's data structures, having determined that there is no need - * to include them in the query. - * - * We are not terribly thorough here. We only bother to update parts of - * the planner's data structures that will actually be consulted later. - */ -static void -remove_leftjoinrel_from_query(PlannerInfo *root, int relid, - SpecialJoinInfo *sjinfo) -{ - RelOptInfo *rel = find_base_rel(root, relid); - int ojrelid = sjinfo->ojrelid; - Relids joinrelids; - Relids join_plus_commute; - List *joininfos; - ListCell *l; - - /* Compute the relid set for the join we are considering */ - joinrelids = bms_union(sjinfo->min_lefthand, sjinfo->min_righthand); - Assert(ojrelid != 0); - joinrelids = bms_add_member(joinrelids, ojrelid); - - remove_rel_from_query(root, relid, -1, sjinfo, joinrelids); - - /* - * Remove any joinquals referencing the rel from the joininfo lists. - * - * In some cases, a joinqual has to be put back after deleting its - * reference to the target rel. This can occur for pseudoconstant and - * outerjoin-delayed quals, which can get marked as requiring the rel in - * order to force them to be evaluated at or above the join. We can't - * just discard them, though. Only quals that logically belonged to the - * outer join being discarded should be removed from the query. - * - * We might encounter a qual that is a clone of a deletable qual with some - * outer-join relids added (see deconstruct_distribute_oj_quals). To - * ensure we get rid of such clones as well, add the relids of all OJs - * commutable with this one to the set we test against for - * pushed-down-ness. - */ - join_plus_commute = bms_union(joinrelids, - sjinfo->commute_above_r); - join_plus_commute = bms_add_members(join_plus_commute, - sjinfo->commute_below_l); - - /* - * We must make a copy of the rel's old joininfo list before starting the - * loop, because otherwise remove_join_clause_from_rels would destroy the - * list while we're scanning it. - */ - joininfos = list_copy(rel->joininfo); - foreach(l, joininfos) - { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); - - remove_join_clause_from_rels(root, rinfo, rinfo->required_relids); - - if (RINFO_IS_PUSHED_DOWN(rinfo, join_plus_commute)) - { - /* - * There might be references to relid or ojrelid in the - * RestrictInfo's relid sets, as a consequence of PHVs having had - * ph_eval_at sets that include those. We already checked above - * that any such PHV is safe (and updated its ph_eval_at), so we - * can just drop those references. - */ - remove_rel_from_restrictinfo(rinfo, relid, ojrelid); - - /* - * Cross-check that the clause itself does not reference the - * target rel or join. - */ -#ifdef USE_ASSERT_CHECKING - { - Relids clause_varnos = pull_varnos(root, - (Node *) rinfo->clause); - - Assert(!bms_is_member(relid, clause_varnos)); - Assert(!bms_is_member(ojrelid, clause_varnos)); - } -#endif - /* Now throw it back into the joininfo lists */ - distribute_restrictinfo_to_rels(root, rinfo); - } - } - - /* - * There may be references to the rel in root->fkey_list, but if so, - * match_foreign_keys_to_quals() will get rid of them. - */ - - /* - * Now remove the rel from the baserel array to prevent it from being - * referenced again. (We can't do this earlier because - * remove_join_clause_from_rels will touch it.) - */ - root->simple_rel_array[relid] = NULL; - root->simple_rte_array[relid] = NULL; - - /* And nuke the RelOptInfo, just in case there's another access path */ - pfree(rel); - - /* - * Now repeat construction of attr_needed bits coming from all other - * sources. - */ - rebuild_placeholder_attr_needed(root); - rebuild_joinclause_attr_needed(root); - rebuild_eclass_attr_needed(root); - rebuild_lateral_attr_needed(root); -} - -/* - * Remove the target relid and references to the target join from the - * planner's data structures, having determined that there is no need - * to include them in the query. Optionally replace references to the - * removed relid with subst if this is a self-join removal. + * remove_join_from_jointree + * Delete the JoinExpr with the given RT index, along with everything + * below its righthand side, from the query's jointree. * - * This function serves as the common infrastructure for left-join removal - * and self-join elimination. It is intentionally scoped to update only the - * shared planner data structures that are universally affected by relation - * removal. Each specific caller remains responsible for updating any - * remaining data structures required by its unique removal logic. + * The JoinExpr is replaced by its lefthand input. Its ON conditions can just + * be dropped: since this is a left join, they could only have determined + * which righthand rows join to a given lefthand row, and there are no + * righthand rows anymore. * - * The specific type of removal being performed is dictated by the combination - * of the sjinfo and subst parameters. A non-NULL sjinfo indicates left-join - * removal. When sjinfo is NULL, a positive subst value indicates self-join - * elimination (where references are replaced with subst). + * *nremoved is incremented by the number of JoinExprs removed (there should + * be exactly one, but the caller checks that). */ -static void -remove_rel_from_query(PlannerInfo *root, int relid, - int subst, SpecialJoinInfo *sjinfo, - Relids joinrelids) +static Node * +remove_join_from_jointree(Node *jtnode, int ojrelid, int *nremoved) { - int ojrelid = sjinfo ? sjinfo->ojrelid : 0; - Index rti; - ListCell *l; - bool is_outer_join = (sjinfo != NULL); - bool is_self_join = (!is_outer_join && subst > 0); - Bitmapset *seen_serials = NULL; - - Assert(is_outer_join || is_self_join); - Assert(!is_outer_join || ojrelid > 0); - Assert(!is_outer_join || joinrelids != NULL); - - /* - * Update all_baserels and related relid sets. - */ - root->all_baserels = adjust_relid_set(root->all_baserels, relid, subst); - root->all_query_rels = adjust_relid_set(root->all_query_rels, relid, subst); - - if (is_outer_join) - { - root->outer_join_rels = bms_del_member(root->outer_join_rels, ojrelid); - root->all_query_rels = bms_del_member(root->all_query_rels, ojrelid); - } - - /* - * Likewise remove references from SpecialJoinInfo data structures. - * - * This is relevant in case the relation we're deleting is part of the - * relid sets of special joins: those sets have to be adjusted. If we are - * removing an outer join, the RHS of the target outer join will be made - * empty here, but that's OK since the caller will delete that - * SpecialJoinInfo entirely. - */ - foreach(l, root->join_info_list) - { - SpecialJoinInfo *sjinf = (SpecialJoinInfo *) lfirst(l); - - /* - * initsplan.c is fairly cavalier about allowing SpecialJoinInfos' - * lefthand/righthand relid sets to be shared with other data - * structures. Ensure that we don't modify the original relid sets. - * (The commute_xxx sets are always per-SpecialJoinInfo though.) - */ - sjinf->min_lefthand = bms_copy(sjinf->min_lefthand); - sjinf->min_righthand = bms_copy(sjinf->min_righthand); - sjinf->syn_lefthand = bms_copy(sjinf->syn_lefthand); - sjinf->syn_righthand = bms_copy(sjinf->syn_righthand); - - /* Now adjust relid bit in the sets: */ - sjinf->min_lefthand = adjust_relid_set(sjinf->min_lefthand, relid, subst); - sjinf->min_righthand = adjust_relid_set(sjinf->min_righthand, relid, subst); - sjinf->syn_lefthand = adjust_relid_set(sjinf->syn_lefthand, relid, subst); - sjinf->syn_righthand = adjust_relid_set(sjinf->syn_righthand, relid, subst); - - if (is_outer_join) - { - /* Remove ojrelid bit from the sets: */ - sjinf->min_lefthand = bms_del_member(sjinf->min_lefthand, ojrelid); - sjinf->min_righthand = bms_del_member(sjinf->min_righthand, ojrelid); - sjinf->syn_lefthand = bms_del_member(sjinf->syn_lefthand, ojrelid); - sjinf->syn_righthand = bms_del_member(sjinf->syn_righthand, ojrelid); - /* relid cannot appear in these fields, but ojrelid can: */ - sjinf->commute_above_l = bms_del_member(sjinf->commute_above_l, ojrelid); - sjinf->commute_above_r = bms_del_member(sjinf->commute_above_r, ojrelid); - sjinf->commute_below_l = bms_del_member(sjinf->commute_below_l, ojrelid); - sjinf->commute_below_r = bms_del_member(sjinf->commute_below_r, ojrelid); - } - else - { - /* - * For self-join removal, replace relid references in - * semi_rhs_exprs. - */ - ChangeVarNodesExtended((Node *) sjinf->semi_rhs_exprs, relid, subst, - 0, replace_relid_callback); - } - } - - /* - * Likewise remove references from PlaceHolderVar data structures, - * removing any no-longer-needed placeholders entirely. We only remove - * PHVs for left-join removal. With self-join elimination, PHVs already - * get moved to the remaining relation, where they might still be needed. - * It might also happen that we skip the removal of some PHVs that could - * be removed. However, the overhead of extra PHVs is small compared to - * the complexity of analysis needed to remove them. - * - * Removal is a bit trickier than it might seem: we can remove PHVs that - * are used at the target rel and/or in the join qual, but not those that - * are used at join partner rels or above the join. It's not that easy to - * distinguish PHVs used at partner rels from those used in the join qual, - * since they will both have ph_needed sets that are subsets of - * joinrelids. However, a PHV used at a partner rel could not have the - * target rel in ph_eval_at, so we check that while deciding whether to - * remove or just update the PHV. There is no corresponding test in - * join_is_removable because it doesn't need to distinguish those cases. - */ - foreach(l, root->placeholder_list) - { - PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l); - - Assert(!is_outer_join || !bms_is_member(relid, phinfo->ph_lateral)); - - if (is_outer_join && - bms_is_subset(phinfo->ph_needed, joinrelids) && - bms_is_member(relid, phinfo->ph_eval_at) && - !bms_is_member(ojrelid, phinfo->ph_eval_at)) - { - root->placeholder_list = foreach_delete_current(root->placeholder_list, - l); - root->placeholder_array[phinfo->phid] = NULL; - } - else - { - PlaceHolderVar *phv = phinfo->ph_var; - - phinfo->ph_eval_at = adjust_relid_set(phinfo->ph_eval_at, relid, subst); - if (is_outer_join) - phinfo->ph_eval_at = bms_del_member(phinfo->ph_eval_at, ojrelid); - Assert(!bms_is_empty(phinfo->ph_eval_at)); /* checked previously */ - - /* Reduce ph_needed to contain only "relation 0"; see below */ - if (bms_is_member(0, phinfo->ph_needed)) - phinfo->ph_needed = bms_make_singleton(0); - else - phinfo->ph_needed = NULL; - - phv->phrels = adjust_relid_set(phv->phrels, relid, subst); - if (is_outer_join) - phv->phrels = bms_del_member(phv->phrels, ojrelid); - Assert(!bms_is_empty(phv->phrels)); - - /* - * For self-join removal, update Var nodes within the PHV's - * expression to reference the replacement relid, and adjust - * ph_lateral for the relid substitution. (For left-join removal, - * we're removing rather than replacing, and any surviving PHV - * shouldn't reference the removed rel in its expression. Also, - * relid can't appear in ph_lateral for outer joins.) - */ - if (is_self_join) - { - ChangeVarNodesExtended((Node *) phv->phexpr, relid, subst, 0, - replace_relid_callback); - phinfo->ph_lateral = adjust_relid_set(phinfo->ph_lateral, relid, subst); - - /* - * ph_lateral might contain rels mentioned in ph_eval_at after - * the replacement, remove them. - */ - phinfo->ph_lateral = bms_difference(phinfo->ph_lateral, phinfo->ph_eval_at); - /* ph_lateral might or might not be empty */ - } - - Assert(phv->phnullingrels == NULL); /* no need to adjust */ - } - } - - /* - * Likewise remove references from EquivalenceClasses. - * - * For self-join removal, the caller has already updated the - * EquivalenceClasses, so we can skip this step. - */ - if (is_outer_join) + if (jtnode == NULL) + return NULL; + if (IsA(jtnode, RangeTblRef)) { - foreach(l, root->eq_classes) - { - EquivalenceClass *ec = (EquivalenceClass *) lfirst(l); - - remove_rel_from_eclass(root, ec, relid, ojrelid); - } + /* nothing to do here */ } - - /* - * Finally, we must prepare for the caller to recompute per-Var - * attr_needed and per-PlaceHolderVar ph_needed relid sets. These have to - * be known accurately, else we may fail to remove other now-removable - * joins. Because the caller removes the join clause(s) associated with - * the removed join, Vars that were formerly needed may no longer be. - * - * The actual reconstruction of these relid sets is performed by the - * specific caller. Here, we simply clear out the existing attr_needed - * sets (we already did this above for ph_needed) to ensure they are - * rebuilt from scratch. We can cheat to one small extent: we can avoid - * re-examining the targetlist and HAVING qual by preserving "relation 0" - * bits from the existing relid sets. This is safe because we'd never - * remove such references. - * - * Additionally, if we are performing self-join elimination, we must - * replace references to the removed relid with subst within the - * lateral_vars lists. - * - * Also, for left-join removal, we strip the removed rel and join from any - * PlaceHolderVar embedded in the surviving rels' restriction clauses and - * join clauses; we needn't bother with the rel being removed, nor when - * the query has no PlaceHolderVars. - */ - for (rti = 1; rti < root->simple_rel_array_size; rti++) + else if (IsA(jtnode, FromExpr)) { - RelOptInfo *otherrel = root->simple_rel_array[rti]; - int attroff; - - /* there may be empty slots corresponding to non-baserel RTEs */ - if (otherrel == NULL) - continue; - - Assert(otherrel->relid == rti); /* sanity check on array */ - - for (attroff = otherrel->max_attr - otherrel->min_attr; - attroff >= 0; - attroff--) - { - if (bms_is_member(0, otherrel->attr_needed[attroff])) - otherrel->attr_needed[attroff] = bms_make_singleton(0); - else - otherrel->attr_needed[attroff] = NULL; - } - - if (is_self_join) - ChangeVarNodesExtended((Node *) otherrel->lateral_vars, relid, - subst, 0, replace_relid_callback); - - if (is_outer_join && rti != relid && root->glob->lastPHId != 0) - { - foreach_node(RestrictInfo, rinfo, otherrel->baserestrictinfo) - remove_rel_from_restrictinfo_phvs(rinfo, relid, ojrelid); - - /* - * Join clauses need the same treatment, but there's no value in - * processing any join clause more than once. So it's slightly - * annoying that we have to find them via the per-base-relation - * joininfo lists. Avoid duplicate processing by tracking the - * rinfo_serial numbers of join clauses we've already seen. (This - * doesn't work for is_clone clauses, so we must waste effort on - * them.) - */ - foreach_node(RestrictInfo, rinfo, otherrel->joininfo) - { - if (!rinfo->is_clone) /* else serial number is not unique */ - { - if (bms_is_member(rinfo->rinfo_serial, seen_serials)) - continue; /* saw it already */ - seen_serials = bms_add_member(seen_serials, - rinfo->rinfo_serial); - } - remove_rel_from_restrictinfo_phvs(rinfo, relid, ojrelid); - } - } - } -} - -/* - * Remove any references to relid or ojrelid from the RestrictInfo. - * - * We only bother to clean out bits in the RestrictInfo's various relid sets, - * not nullingrel bits in contained Vars and PHVs. (This might have to be - * improved sometime.) However, if the RestrictInfo contains an OR clause - * we have to also clean up the sub-clauses. - */ -static void -remove_rel_from_restrictinfo(RestrictInfo *rinfo, int relid, int ojrelid) -{ - /* - * initsplan.c is fairly cavalier about allowing RestrictInfos to share - * relid sets with other RestrictInfos, and SpecialJoinInfos too. Make - * sure this RestrictInfo has its own relid sets before we modify them. - * (In present usage, clause_relids is probably not shared, but - * required_relids could be; let's not assume anything.) - */ - rinfo->clause_relids = bms_copy(rinfo->clause_relids); - rinfo->clause_relids = bms_del_member(rinfo->clause_relids, relid); - rinfo->clause_relids = bms_del_member(rinfo->clause_relids, ojrelid); - /* Likewise for required_relids */ - rinfo->required_relids = bms_copy(rinfo->required_relids); - rinfo->required_relids = bms_del_member(rinfo->required_relids, relid); - rinfo->required_relids = bms_del_member(rinfo->required_relids, ojrelid); - /* Likewise for incompatible_relids */ - rinfo->incompatible_relids = bms_copy(rinfo->incompatible_relids); - rinfo->incompatible_relids = bms_del_member(rinfo->incompatible_relids, relid); - rinfo->incompatible_relids = bms_del_member(rinfo->incompatible_relids, ojrelid); - /* Likewise for outer_relids */ - rinfo->outer_relids = bms_copy(rinfo->outer_relids); - rinfo->outer_relids = bms_del_member(rinfo->outer_relids, relid); - rinfo->outer_relids = bms_del_member(rinfo->outer_relids, ojrelid); - /* Likewise for left_relids */ - rinfo->left_relids = bms_copy(rinfo->left_relids); - rinfo->left_relids = bms_del_member(rinfo->left_relids, relid); - rinfo->left_relids = bms_del_member(rinfo->left_relids, ojrelid); - /* Likewise for right_relids */ - rinfo->right_relids = bms_copy(rinfo->right_relids); - rinfo->right_relids = bms_del_member(rinfo->right_relids, relid); - rinfo->right_relids = bms_del_member(rinfo->right_relids, ojrelid); - - /* If it's an OR, recurse to clean up sub-clauses */ - if (restriction_is_or_clause(rinfo)) - { - ListCell *lc; - - Assert(is_orclause(rinfo->orclause)); - foreach(lc, ((BoolExpr *) rinfo->orclause)->args) - { - Node *orarg = (Node *) lfirst(lc); - - /* OR arguments should be ANDs or sub-RestrictInfos */ - if (is_andclause(orarg)) - { - List *andargs = ((BoolExpr *) orarg)->args; - ListCell *lc2; - - foreach(lc2, andargs) - { - RestrictInfo *rinfo2 = lfirst_node(RestrictInfo, lc2); - - remove_rel_from_restrictinfo(rinfo2, relid, ojrelid); - } - } - else - { - RestrictInfo *rinfo2 = castNode(RestrictInfo, orarg); - - remove_rel_from_restrictinfo(rinfo2, relid, ojrelid); - } - } - } -} - -/* - * Remove any references to relid or ojrelid from the EquivalenceClass. - * - * We fix the EC and EM relid sets to ensure that implied join equalities will - * be generated at the appropriate join level(s). We also strip the removed - * rel from PlaceHolderVars embedded in member expressions; a member's - * em_relids reflects ph_eval_at rather than the PHV's phrels, so the latter - * can still mention the removed rel even when em_relids does not. Like - * remove_rel_from_restrictinfo, we don't bother with nullingrel bits in - * contained plain Vars. - */ -static void -remove_rel_from_eclass(PlannerInfo *root, EquivalenceClass *ec, - int relid, int ojrelid) -{ - ListCell *lc; + FromExpr *f = (FromExpr *) jtnode; + ListCell *l; - /* - * Strip the removed rel/join from PlaceHolderVars in member expressions. - * This is needed even when the EC's relids don't mention the removed rel. - * Plain Vars and Consts can't contain a PlaceHolderVar, so skip them. - */ - if (root->glob->lastPHId != 0) - { - foreach_node(EquivalenceMember, em, ec->ec_members) - { - if (!IsA(em->em_expr, Var) && !IsA(em->em_expr, Const)) - em->em_expr = (Expr *) - remove_rel_from_phvs((Node *) em->em_expr, relid, ojrelid); - } + foreach(l, f->fromlist) + lfirst(l) = remove_join_from_jointree((Node *) lfirst(l), + ojrelid, nremoved); } - - if (!bms_is_member(relid, ec->ec_relids) && - !bms_is_member(ojrelid, ec->ec_relids)) - return; - - /* Fix up the EC's overall relids */ - ec->ec_relids = bms_del_member(ec->ec_relids, relid); - ec->ec_relids = bms_del_member(ec->ec_relids, ojrelid); - - /* - * We don't expect any EC child members to exist at this point. Ensure - * that's the case, otherwise, we might be getting asked to do something - * this function hasn't been coded for. - */ - Assert(ec->ec_childmembers == NULL); - - /* - * Fix up the member expressions. Any non-const member that ends with - * empty em_relids must be a Var or PHV of the removed relation. We don't - * need it anymore, so we can drop it. - */ - foreach(lc, ec->ec_members) + else if (IsA(jtnode, JoinExpr)) { - EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc); + JoinExpr *j = (JoinExpr *) jtnode; - if (bms_is_member(relid, cur_em->em_relids) || - bms_is_member(ojrelid, cur_em->em_relids)) + if (j->rtindex == ojrelid) { - Assert(!cur_em->em_is_const); - /* em_relids is likely to be shared with some RestrictInfo */ - cur_em->em_relids = bms_copy(cur_em->em_relids); - cur_em->em_relids = bms_del_member(cur_em->em_relids, relid); - cur_em->em_relids = bms_del_member(cur_em->em_relids, ojrelid); - if (bms_is_empty(cur_em->em_relids)) - ec->ec_members = foreach_delete_current(ec->ec_members, lc); + (*nremoved)++; + return j->larg; } + j->larg = remove_join_from_jointree(j->larg, ojrelid, nremoved); + j->rarg = remove_join_from_jointree(j->rarg, ojrelid, nremoved); } + else + elog(ERROR, "unrecognized jointree node type: %d", + (int) nodeTag(jtnode)); - /* Fix up the source clauses, in case we can re-use them later */ - foreach(lc, ec->ec_sources) - { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); - - remove_rel_from_restrictinfo(rinfo, relid, ojrelid); - } - - /* - * Rather than expend code on fixing up any already-derived clauses, just - * drop them. (At this point, any such clauses would be base restriction - * clauses, which we'd not need anymore anyway.) - */ - ec_clear_derived_clauses(ec); + return jtnode; } /* - * Remove any references to relid or ojrelid from the PlaceHolderVars embedded - * in a RestrictInfo's clause. + * remove_rels_from_query_tree + * Delete all remaining references to the given relids from the query. * - * If it's an OR clause, we must also fix up the orclause, which is a parallel - * representation built from its own sub-RestrictInfos. We recurse into the - * sub-clauses for that, mirroring remove_rel_from_restrictinfo. + * Having removed some relations and outer joins from the jointree, we must + * get rid of any references to them that are left behind elsewhere. There + * should be no ordinary Vars of a removed relation left, but OJ relids can + * still appear in the nullingrels sets of surviving Vars and PlaceHolderVars, + * and both regular and OJ relids can appear in the phrels sets of + * PlaceHolderVars. ChangeVarNodes knows how to strip a relid out of all of + * those. */ static void -remove_rel_from_restrictinfo_phvs(RestrictInfo *rinfo, int relid, int ojrelid) +remove_rels_from_query_tree(PlannerInfo *root, Relids removed_relids) { - rinfo->clause = (Expr *) - remove_rel_from_phvs((Node *) rinfo->clause, relid, ojrelid); - - /* If it's an OR, recurse to clean up sub-clauses */ - if (restriction_is_or_clause(rinfo)) - { - ListCell *lc; - - Assert(is_orclause(rinfo->orclause)); - foreach(lc, ((BoolExpr *) rinfo->orclause)->args) - { - Node *orarg = (Node *) lfirst(lc); - - /* OR arguments should be ANDs or sub-RestrictInfos */ - if (is_andclause(orarg)) - { - List *andargs = ((BoolExpr *) orarg)->args; - ListCell *lc2; - - foreach(lc2, andargs) - { - RestrictInfo *rinfo2 = lfirst_node(RestrictInfo, lc2); - - remove_rel_from_restrictinfo_phvs(rinfo2, relid, ojrelid); - } - } - else - { - RestrictInfo *rinfo2 = castNode(RestrictInfo, orarg); - - remove_rel_from_restrictinfo_phvs(rinfo2, relid, ojrelid); - } - } - } -} - -/* - * Remove any references to the specified RT index(es) from the phrels (and - * phnullingrels) of every PlaceHolderVar in the given expression. - * - * remove_rel_from_query() fixes up the relid sets of RestrictInfos and - * EquivalenceMembers, but not the PlaceHolderVars embedded in their - * expressions. That's normally fine, but such an expression may later be - * translated for an appendrel child and have its relids recomputed by - * pull_varnos(). A leftover removed relid in phrels would then make - * pull_varnos() reference a nonexistent rel, so we strip it here to match the - * canonical PlaceHolderVar. - */ -static Node * -remove_rel_from_phvs(Node *node, int relid, int ojrelid) -{ - Relids removable = bms_add_member(bms_make_singleton(relid), ojrelid); - - return remove_rel_from_phvs_mutator(node, removable); -} + int relid = -1; -static Node * -remove_rel_from_phvs_mutator(Node *node, Relids removable) -{ - if (node == NULL) - return NULL; - if (IsA(node, PlaceHolderVar)) + while ((relid = bms_next_member(removed_relids, relid)) >= 0) { - PlaceHolderVar *phv = (PlaceHolderVar *) node; - Relids newphrels; - - /* Upper-level PlaceHolderVars should be long gone at this point */ - Assert(phv->phlevelsup == 0); - - /* Copy the PlaceHolderVar and mutate what's below ... */ - phv = (PlaceHolderVar *) - expression_tree_mutator(node, - remove_rel_from_phvs_mutator, - removable); + ChangeVarNodes((Node *) root->parse, relid, INVALID_VAR, 0); /* - * ... then strip the removed rels from its relid sets. - * - * If stripping would empty phrels, the PHV is evaluated only at the - * removed relation(s); it then belongs to an EquivalenceMember that - * the caller drops immediately afterwards. Leave such a PHV - * untouched rather than build one with empty phrels, which the rest - * of the planner assumes never occurs. + * processed_tlist shares some but not all of its nodes with + * parse->targetList, so it has to be processed separately. (That's + * harmless: ChangeVarNodes works in-place, and removing a relid that + * isn't there is idempotent.) */ - newphrels = bms_difference(phv->phrels, removable); - if (!bms_is_empty(newphrels)) - { - phv->phrels = newphrels; - phv->phnullingrels = bms_difference(phv->phnullingrels, - removable); - } + ChangeVarNodes((Node *) root->processed_tlist, relid, INVALID_VAR, 0); - return (Node *) phv; + /* There could be references in the append_rel_list, too */ + if (root->append_rel_list != NIL) + ChangeVarNodes((Node *) root->append_rel_list, relid, INVALID_VAR, 0); } - return expression_tree_mutator(node, - remove_rel_from_phvs_mutator, - removable); } -/* - * Remove any occurrences of the target relid from a joinlist structure. - * - * It's easiest to build a whole new list structure, so we handle it that - * way. Efficiency is not a big deal here. - * - * *nremoved is incremented by the number of occurrences removed (there - * should be exactly one, but the caller checks that). - */ -static List * -remove_rel_from_joinlist(List *joinlist, int relid, int *nremoved) -{ - List *result = NIL; - ListCell *jl; - - foreach(jl, joinlist) - { - Node *jlnode = (Node *) lfirst(jl); - - if (IsA(jlnode, RangeTblRef)) - { - int varno = ((RangeTblRef *) jlnode)->rtindex; - - if (varno == relid) - (*nremoved)++; - else - result = lappend(result, jlnode); - } - else if (IsA(jlnode, List)) - { - /* Recurse to handle subproblem */ - List *sublist; - - sublist = remove_rel_from_joinlist((List *) jlnode, - relid, nremoved); - /* Avoid including empty sub-lists in the result */ - if (sublist) - result = lappend(result, sublist); - } - else - { - elog(ERROR, "unrecognized joinlist node type: %d", - (int) nodeTag(jlnode)); - } - } - - return result; -} - - /* * reduce_unique_semijoins * Check for semijoins that can be simplified to plain inner joins @@ -1033,14 +451,13 @@ remove_rel_from_joinlist(List *joinlist, int relid, int *nremoved) * Ideally this would happen during reduce_outer_joins, but we don't have * enough information at that point. * - * To perform the strength reduction when applicable, we need only delete - * the semijoin's SpecialJoinInfo from root->join_info_list. (We don't - * bother fixing the join type attributed to it in the query jointree, - * since that won't be consulted again.) + * Like the join removal cases, we do this on the query's jointree, so + * returning true means the caller must recompute the derived data. */ -void +bool reduce_unique_semijoins(PlannerInfo *root) { + bool changed = false; ListCell *lc; /* @@ -1061,8 +478,13 @@ reduce_unique_semijoins(PlannerInfo *root) if (sjinfo->jointype != JOIN_SEMI) continue; - if (!bms_get_singleton_member(sjinfo->min_righthand, &innerrelid)) + /* + * We test the syntactic righthand side, since that's what identifies + * the JoinExpr we'll modify. + */ + if (!bms_get_singleton_member(sjinfo->syn_righthand, &innerrelid)) continue; + Assert(bms_equal(sjinfo->min_righthand, sjinfo->syn_righthand)); innerrel = find_base_rel(root, innerrelid); @@ -1091,15 +513,71 @@ reduce_unique_semijoins(PlannerInfo *root) NULL), innerrel->joininfo); - /* Test whether the innerrel is unique for those clauses. */ - if (!innerrel_is_unique(root, - joinrelids, sjinfo->min_lefthand, innerrel, - JOIN_SEMI, restrictlist, true)) - continue; + /* Test whether the innerrel is unique for those clauses. */ + if (!innerrel_is_unique(root, + joinrelids, sjinfo->min_lefthand, innerrel, + JOIN_SEMI, restrictlist, true)) + continue; + + /* OK, reduce the join to a plain inner join in the jointree. */ + if (!reduce_semijoin_in_jointree((Node *) root->parse->jointree, + sjinfo->syn_righthand)) + elog(ERROR, "failed to find semijoin in jointree"); + changed = true; + } + + return changed; +} + +/* + * reduce_semijoin_in_jointree + * Find the JoinExpr for the semijoin with the given syntactic righthand + * side, and turn it into an inner join. + * + * Semijoins have no RT index of their own, so we have to identify the one + * we want by the set of relids on its righthand side. + */ +static bool +reduce_semijoin_in_jointree(Node *jtnode, Relids syn_righthand) +{ + if (jtnode == NULL) + return false; + if (IsA(jtnode, RangeTblRef)) + { + /* nothing to do here */ + } + else if (IsA(jtnode, FromExpr)) + { + FromExpr *f = (FromExpr *) jtnode; + ListCell *l; + + foreach(l, f->fromlist) + { + if (reduce_semijoin_in_jointree((Node *) lfirst(l), syn_righthand)) + return true; + } + } + else if (IsA(jtnode, JoinExpr)) + { + JoinExpr *j = (JoinExpr *) jtnode; - /* OK, remove the SpecialJoinInfo from the list. */ - root->join_info_list = foreach_delete_current(root->join_info_list, lc); + if (j->jointype == JOIN_SEMI && + bms_equal(get_relids_in_jointree(j->rarg, true, false), + syn_righthand)) + { + j->jointype = JOIN_INNER; + return true; + } + if (reduce_semijoin_in_jointree(j->larg, syn_righthand)) + return true; + if (reduce_semijoin_in_jointree(j->rarg, syn_righthand)) + return true; } + else + elog(ERROR, "unrecognized jointree node type: %d", + (int) nodeTag(jtnode)); + + return false; } @@ -1548,7 +1026,7 @@ innerrel_is_unique(PlannerInfo *root, * A non-NULL extra_clauses indicates that we're checking for self-join and * correspondingly dealing with filtered clauses. */ -bool +static bool innerrel_is_unique_ext(PlannerInfo *root, Relids joinrelids, Relids outerrelids, @@ -1728,498 +1206,430 @@ is_innerrel_unique_for(PlannerInfo *root, } /* - * Update EC members to point to the remaining relation instead of the removed - * one, removing duplicates. + * Remove the toRemove relation after we have proven that it participates only + * in an unneeded unique self-join with toKeep. * - * Restriction clauses for base relations are already distributed to - * the respective baserestrictinfo lists (see - * generate_implied_equalities_for_column). The above code has already processed - * this list and updated these clauses to reference the remaining - * relation, so that we can skip them here based on their relids. + * The removal is done by deleting the relation's RangeTblRef from the + * jointree and then pointing everything that referenced it at the relation we + * are keeping. All the conditions that were attached to the removed relation + * thereby become conditions on the remaining one, which is what we want: + * we've proven that the two relations select the same rows. Note that + * this change requires us to hoist those conditions up to someplace + * syntactically enclosing toKeep. * - * Likewise, we have already processed the join clauses that join the - * removed relation to the remaining one. - * - * Finally, there might be join clauses tying the removed relation to - * some third relation. We can't just delete the source clauses and - * regenerate them from the EC because the corresponding equality - * operators might be missing (see the handling of ec_broken). - * Therefore, we will update the references in the source clauses. - * - * Derived clauses can be generated again, so it is simpler just to - * delete them. + * kmark and rmark are the PlanRowMarks (if any) for the kept and removed + * relations. We could re-locate those, but the caller already found them. */ static void -update_eclasses(EquivalenceClass *ec, int from, int to) +remove_self_join_rel(PlannerInfo *root, + RelOptInfo *toKeep, RelOptInfo *toRemove, + PlanRowMark *kmark, PlanRowMark *rmark) { - List *new_members = NIL; - List *new_sources = NIL; + Node *orphan_quals = NULL; + int nremoved = 0; + Node *hoist_quals = NULL; + bool found_relid = false; + + Assert(toKeep->relid > 0); + Assert(toRemove->relid > 0); + + /* We verify that exactly one reference gets removed from the jointree */ + root->parse->jointree = (FromExpr *) + remove_rel_from_jointree((Node *) root->parse->jointree, + toRemove->relid, + &orphan_quals, &nremoved); + if (nremoved != 1) + elog(ERROR, "failed to find relation %d in jointree", toRemove->relid); + /* The topmost FromExpr can't have gone away, so nothing can be orphaned */ + Assert(root->parse->jointree != NULL); + Assert(orphan_quals == NULL); /* - * We don't expect any EC child members to exist at this point. Ensure - * that's the case, otherwise, we might be getting asked to do something - * this function hasn't been coded for. + * Replace all references to the removed relation. Note that this must + * happen after the jointree surgery, else we'd not be able to tell the + * two relations' RangeTblRefs apart. */ - Assert(ec->ec_childmembers == NULL); + ChangeVarNodes((Node *) root->parse, toRemove->relid, toKeep->relid, 0); - foreach_node(EquivalenceMember, em, ec->ec_members) - { - bool is_redundant = false; + /* + * processed_tlist shares some but not all of its nodes with + * parse->targetList, so it has to be processed separately. (That's + * harmless: ChangeVarNodes works in-place, and the second visit to a + * shared node finds nothing to change.) + */ + ChangeVarNodes((Node *) root->processed_tlist, toRemove->relid, + toKeep->relid, 0); + + /* There could be references in the append_rel_list, too */ + if (root->append_rel_list != NIL) + ChangeVarNodes((Node *) root->append_rel_list, toRemove->relid, + toKeep->relid, 0); + + /* Clean up the quals that the substitution has messed with */ + fixup_selfjoin_jointree(root, (Node *) root->parse->jointree, + toKeep->relid, + &hoist_quals, &found_relid); + /* We shouldn't have any leftover quals, and we must have found toKeep */ + Assert(hoist_quals == NULL); + Assert(found_relid); - if (!bms_is_member(from, em->em_relids)) + /* + * If the removed relation has a row mark, transfer it to the remaining + * one. + * + * If both rels have row marks, just keep the one corresponding to the + * remaining relation because we verified earlier that they have the same + * strength. + */ + if (rmark) + { + if (kmark) { - new_members = lappend(new_members, em); - continue; - } - - em->em_relids = adjust_relid_set(em->em_relids, from, to); - em->em_jdomain->jd_relids = adjust_relid_set(em->em_jdomain->jd_relids, from, to); - - /* We only process inner joins */ - ChangeVarNodesExtended((Node *) em->em_expr, from, to, 0, - replace_relid_callback); + Assert(kmark->markType == rmark->markType); - foreach_node(EquivalenceMember, other, new_members) + root->rowMarks = list_delete_ptr(root->rowMarks, rmark); + } + else { - if (!equal(em->em_relids, other->em_relids)) - continue; + /* Shouldn't have inheritance children yet. */ + Assert(rmark->rti == rmark->prti); - if (equal(em->em_expr, other->em_expr)) - { - is_redundant = true; - break; - } + rmark->rti = rmark->prti = toKeep->relid; } - - if (!is_redundant) - new_members = lappend(new_members, em); } +} - list_free(ec->ec_members); - ec->ec_members = new_members; - - ec_clear_derived_clauses(ec); - - /* Update EC source expressions */ - foreach_node(RestrictInfo, rinfo, ec->ec_sources) +/* + * remove_rel_from_jointree + * Delete the RangeTblRef for the given relation from the query's + * jointree. + * + * This is used for self-join elimination, where the removed relation's + * qual conditions must all be preserved (they will be transposed onto the + * remaining relation afterwards). Hence, if dropping the RangeTblRef leaves + * a JoinExpr or FromExpr with nothing under it, we can't simply drop that + * node; we hand its quals back to the caller in *orphan_quals, to be merged + * into the nearest enclosing node that still has some content. That's a + * valid transformation only for inner joins, but a jointree node can't become + * empty at an outer join here: remove_self_joins_one_group() insists that the + * two relations be on the same side of every outer join, so the relation we + * are keeping would have to be in the emptied subtree too. + * + * *nremoved is incremented by the number of RangeTblRefs removed (there + * should be exactly one, but the caller checks that). + */ +static Node * +remove_rel_from_jointree(Node *jtnode, int relid, + Node **orphan_quals, int *nremoved) +{ + if (jtnode == NULL) + return NULL; + if (IsA(jtnode, RangeTblRef)) { - bool is_redundant = false; + RangeTblRef *rtr = (RangeTblRef *) jtnode; - if (!bms_is_member(from, rinfo->required_relids)) + if (rtr->rtindex == relid) { - new_sources = lappend(new_sources, rinfo); - continue; + (*nremoved)++; + return NULL; } + } + else if (IsA(jtnode, FromExpr)) + { + FromExpr *f = (FromExpr *) jtnode; + List *newfromlist = NIL; + Node *sub_orphans = NULL; + ListCell *l; - ChangeVarNodesExtended((Node *) rinfo, from, to, 0, - replace_relid_callback); - - /* - * After switching the clause to the remaining relation, check it for - * redundancy with existing ones. We don't have to check for - * redundancy with derived clauses, because we've just deleted them. - */ - foreach_node(RestrictInfo, other, new_sources) + foreach(l, f->fromlist) { - if (!equal(rinfo->clause_relids, other->clause_relids)) - continue; + Node *newchild; - if (equal(rinfo->clause, other->clause)) - { - is_redundant = true; - break; - } + newchild = remove_rel_from_jointree((Node *) lfirst(l), relid, + &sub_orphans, nremoved); + if (newchild != NULL) + newfromlist = lappend(newfromlist, newchild); + } + f->fromlist = newfromlist; + f->quals = merge_quals(sub_orphans, f->quals); + if (newfromlist == NIL) + { + /* Nothing left here, so pass our quals up to the parent */ + *orphan_quals = merge_quals(f->quals, *orphan_quals); + return NULL; } + } + else if (IsA(jtnode, JoinExpr)) + { + JoinExpr *j = (JoinExpr *) jtnode; + Node *sub_orphans = NULL; + + j->larg = remove_rel_from_jointree(j->larg, relid, + &sub_orphans, nremoved); + j->rarg = remove_rel_from_jointree(j->rarg, relid, + &sub_orphans, nremoved); + if (j->larg == NULL || j->rarg == NULL) + { + Node *surviving = (j->larg != NULL) ? j->larg : j->rarg; + Node *quals = merge_quals(sub_orphans, j->quals); + + /* As explained above, this can only happen for an inner join */ + Assert(j->jointype == JOIN_INNER); + /* We can't have removed both children */ + Assert(surviving != NULL); - if (!is_redundant) - new_sources = lappend(new_sources, rinfo); + /* + * Replace the join by a FromExpr, so that the surviving side's + * rows are still filtered by the join's conditions. + */ + return (Node *) makeFromExpr(list_make1(surviving), quals); + } + /* A subtree that survives never hands any quals back to us */ + Assert(sub_orphans == NULL); } + else + elog(ERROR, "unrecognized jointree node type: %d", + (int) nodeTag(jtnode)); - list_free(ec->ec_sources); - ec->ec_sources = new_sources; - ec->ec_relids = adjust_relid_set(ec->ec_relids, from, to); + return jtnode; } /* - * "Logically" compares two RestrictInfo's ignoring the 'rinfo_serial' field, - * which makes almost every RestrictInfo unique. This type of comparison is - * useful when removing duplicates while moving RestrictInfo's from removed - * relation to remaining relation during self-join elimination. + * merge_quals + * Combine two jointree qual conditions. * - * XXX: In the future, we might remove the 'rinfo_serial' field completely and - * get rid of this function. + * quals1 should be the quals from the lower of the two jointree levels, + * so that those quals get applied first. + * + * Jointree quals have been through preprocess_expression() by now, so each + * one is either NULL or an implicitly-ANDed List. */ -static bool -restrict_infos_logically_equal(RestrictInfo *a, RestrictInfo *b) +static Node * +merge_quals(Node *quals1, Node *quals2) { - int saved_rinfo_serial = a->rinfo_serial; - bool result; - - a->rinfo_serial = b->rinfo_serial; - result = equal(a, b); - a->rinfo_serial = saved_rinfo_serial; - - return result; + if (quals1 == NULL) + return quals2; + if (quals2 == NULL) + return quals1; + return (Node *) list_concat(castNode(List, quals1), + castNode(List, quals2)); } /* - * This function adds all non-redundant clauses to the keeping relation - * during self-join elimination. That is a contradictory operation. On the - * one hand, we reduce the length of the `restrict` lists, which can - * impact planning or executing time. Additionally, we improve the - * accuracy of cardinality estimation. On the other hand, it is one more - * place that can make planning time much longer in specific cases. It - * would have been better to avoid calling the equal() function here, but - * it's the only way to detect duplicated inequality expressions. + * fixup_selfjoin_jointree + * Clean up the query's jointree quals after self-join elimination has + * merged one relation into another. (relid is the kept relation.) * - * (*keep_rinfo_list) is given by pointer because it might be altered by - * distribute_restrictinfo_to_rels(). + * See fixup_selfjoin_quals() for what needs fixing locally to each qual list. + * In addition, we need to check quals to see if they refer to relid, and if + * so make sure they get hoisted to someplace syntactically above relid. + * Do that using a "hoist_quals" in/out parameter similar to "orphan_quals" + * in remove_rel_from_jointree. (We can't readily merge these concerns into + * a single pass, since remove_rel_from_jointree must run before we relabel + * the removed rel's Vars.) In addition, *found_relid is set true if + * the subtree rooted at jtnode is found to contain relid's RangeTblRef, + * so that we can tell when to stop hoisting quals. + * If a qual gets hoisted up, we apply fixup_selfjoin_quals() to it only + * after it reaches its final level. This rule improves the odds of + * detecting duplicate quals. */ static void -add_non_redundant_clauses(PlannerInfo *root, - List *rinfo_candidates, - List **keep_rinfo_list, - Index removed_relid) +fixup_selfjoin_jointree(PlannerInfo *root, Node *jtnode, int relid, + Node **hoist_quals, bool *found_relid) { - foreach_node(RestrictInfo, rinfo, rinfo_candidates) + if (jtnode == NULL) + return; + if (IsA(jtnode, RangeTblRef)) { - bool is_redundant = false; + RangeTblRef *rtr = (RangeTblRef *) jtnode; - Assert(!bms_is_member(removed_relid, rinfo->required_relids)); + if (rtr->rtindex == relid) + { + Assert(!*found_relid); + *found_relid = true; + } + } + else if (IsA(jtnode, FromExpr)) + { + FromExpr *f = (FromExpr *) jtnode; + Node *sub_hoist_quals = NULL; + bool sub_found_relid = false; + ListCell *l; - foreach_node(RestrictInfo, src, (*keep_rinfo_list)) + foreach(l, f->fromlist) + fixup_selfjoin_jointree(root, (Node *) lfirst(l), relid, + &sub_hoist_quals, &sub_found_relid); + if (sub_found_relid) { - if (!bms_equal(src->clause_relids, rinfo->clause_relids)) - /* Can't compare trivially different clauses */ - continue; + /* This FromExpr covers relid, so OK to stop hoisting quals here */ + f->quals = merge_quals(sub_hoist_quals, f->quals); + Assert(!*found_relid); + *found_relid = true; + } + else + { + /* We might need to hoist some of our own quals too */ + List *hoistable = NIL; + List *keepable = NIL; - if (src == rinfo || - (rinfo->parent_ec != NULL && - src->parent_ec == rinfo->parent_ec) || - restrict_infos_logically_equal(rinfo, src)) + foreach_ptr(Node, qual, castNode(List, f->quals)) { - is_redundant = true; - break; + if (bms_is_member(relid, pull_varnos(root, qual))) + hoistable = lappend(hoistable, qual); + else + keepable = lappend(keepable, qual); } + f->quals = (Node *) keepable; + sub_hoist_quals = merge_quals(sub_hoist_quals, (Node *) hoistable); + *hoist_quals = merge_quals(sub_hoist_quals, *hoist_quals); } - if (!is_redundant) - distribute_restrictinfo_to_rels(root, rinfo); - } -} - -/* - * A custom callback for ChangeVarNodesExtended() providing Self-join - * elimination (SJE) related functionality - * - * SJE needs to skip the RangeTblRef node type. During SJE's last - * step, remove_rel_from_joinlist() removes remaining RangeTblRefs - * with target relid. If ChangeVarNodes() replaces the target relid - * before, remove_rel_from_joinlist() would fail to identify the nodes - * to delete. - * - * SJE also needs to change the relids within RestrictInfo's. - */ -static bool -replace_relid_callback(Node *node, ChangeVarNodes_context *context) -{ - if (IsA(node, RangeTblRef)) - { - return true; + f->quals = (Node *) fixup_selfjoin_quals(root, + castNode(List, f->quals), + relid); } - else if (IsA(node, RestrictInfo)) + else if (IsA(jtnode, JoinExpr)) { - RestrictInfo *rinfo = (RestrictInfo *) node; - int relid = -1; - bool is_req_equal = - (rinfo->required_relids == rinfo->clause_relids); - bool clause_relids_is_multiple = - (bms_membership(rinfo->clause_relids) == BMS_MULTIPLE); - - /* - * Recurse down into clauses if the target relation is present in - * clause_relids or required_relids. We must check required_relids - * because the relation not present in clause_relids might still be - * present somewhere in orclause. - */ - if (bms_is_member(context->rt_index, rinfo->clause_relids) || - bms_is_member(context->rt_index, rinfo->required_relids)) + JoinExpr *j = (JoinExpr *) jtnode; + Node *sub_hoist_quals = NULL; + bool sub_found_relid = false; + + fixup_selfjoin_jointree(root, j->larg, relid, + &sub_hoist_quals, &sub_found_relid); + fixup_selfjoin_jointree(root, j->rarg, relid, + &sub_hoist_quals, &sub_found_relid); + if (sub_found_relid) { - Relids new_clause_relids; - - ChangeVarNodesWalkExpression((Node *) rinfo->clause, context); - ChangeVarNodesWalkExpression((Node *) rinfo->orclause, context); - - new_clause_relids = adjust_relid_set(rinfo->clause_relids, - context->rt_index, - context->new_index); - - /* - * Incrementally adjust num_base_rels based on the change of - * clause_relids, which could contain both base relids and - * outer-join relids. This operation is legal until we remove - * only baserels. - */ - rinfo->num_base_rels -= bms_num_members(rinfo->clause_relids) - - bms_num_members(new_clause_relids); - - rinfo->clause_relids = new_clause_relids; - rinfo->left_relids = - adjust_relid_set(rinfo->left_relids, context->rt_index, context->new_index); - rinfo->right_relids = - adjust_relid_set(rinfo->right_relids, context->rt_index, context->new_index); + /* This JoinExpr covers relid, so OK to stop hoisting quals here */ + j->quals = merge_quals(sub_hoist_quals, j->quals); + Assert(!*found_relid); + *found_relid = true; } - - if (is_req_equal) - rinfo->required_relids = rinfo->clause_relids; else - rinfo->required_relids = - adjust_relid_set(rinfo->required_relids, context->rt_index, context->new_index); - - rinfo->outer_relids = - adjust_relid_set(rinfo->outer_relids, context->rt_index, context->new_index); - rinfo->incompatible_relids = - adjust_relid_set(rinfo->incompatible_relids, context->rt_index, context->new_index); - - if (rinfo->mergeopfamilies && - bms_get_singleton_member(rinfo->clause_relids, &relid) && - clause_relids_is_multiple && - relid == context->new_index && IsA(rinfo->clause, OpExpr)) { - Expr *leftOp; - Expr *rightOp; - - leftOp = (Expr *) get_leftop(rinfo->clause); - rightOp = (Expr *) get_rightop(rinfo->clause); + /* We might need to hoist some of our own quals too */ + List *hoistable = NIL; + List *keepable = NIL; - /* - * For self-join elimination, changing varnos could transform - * "t1.a = t2.a" into "t1.a = t1.a". That is always true as long - * as "t1.a" is not null. We use equal() to check for such a - * case, and then we replace the qual with a check for not null - * (NullTest). - */ - if (leftOp != NULL && equal(leftOp, rightOp)) + foreach_ptr(Node, qual, castNode(List, j->quals)) { - NullTest *ntest = makeNode(NullTest); - - ntest->arg = leftOp; - ntest->nulltesttype = IS_NOT_NULL; - ntest->argisrow = false; - ntest->location = -1; - rinfo->clause = (Expr *) ntest; - rinfo->mergeopfamilies = NIL; - rinfo->left_em = NULL; - rinfo->right_em = NULL; + if (bms_is_member(relid, pull_varnos(root, qual))) + hoistable = lappend(hoistable, qual); + else + keepable = lappend(keepable, qual); } - Assert(rinfo->orclause == NULL); + j->quals = (Node *) keepable; + sub_hoist_quals = merge_quals(sub_hoist_quals, (Node *) hoistable); + /* We should never need to hoist quals above an outer join */ + Assert(sub_hoist_quals == NULL || j->jointype == JOIN_INNER); + *hoist_quals = merge_quals(sub_hoist_quals, *hoist_quals); } - return true; + j->quals = (Node *) fixup_selfjoin_quals(root, + castNode(List, j->quals), + relid); } - - return false; + else + elog(ERROR, "unrecognized jointree node type: %d", + (int) nodeTag(jtnode)); } /* - * Remove a relation after we have proven that it participates only in an - * unneeded unique self-join. + * fixup_selfjoin_quals + * Clean up one qual list after self-join elimination. * - * Replace any links in planner info structures. + * Two things need fixing here. First, a join clause such as "t1.a = t2.a" + * has turned into "t1.a = t1.a". For a strict mergejoinable operator that + * means "t1.a IS NOT NULL", and we should make the substitution, for two + * reasons: + * 1. It will typically result in better selectivity estimates. + * 2. EquivalenceClass processing is likely to make the substitution + * if we don't. While not directly harmful, we'd then fail to + * recognize it as a duplicate of a user-written "t1.a IS NOT NULL" + * clause, again leading to bad selectivity estimates. + * Second, conditions that were written against the two relations separately + * may now be identical, and we don't want to apply the same condition twice + * (much less double-count its selectivity). * - * Transfer join and restriction clauses from the removed relation to the - * remaining one. We change the Vars of the clause to point to the - * remaining relation instead of the removed one. The clauses that require - * a subset of joinrelids become restriction clauses of the remaining - * relation, and others remain join clauses. We append them to - * baserestrictinfo and joininfo, respectively, trying not to introduce - * duplicates. + * We only touch the top-level conjuncts of the list. There, turning a NULL + * result into FALSE makes no difference, whereas below a NOT it would, + * invalidating the IS NOT NULL substitution. EquivalenceClass processing + * will not be applied to sub-clauses, and cleaning up duplicates in them + * seems like more trouble than it's worth. Also, we only consider clauses + * that mention the relation we merged into, so that we don't change the + * treatment of anything we didn't touch. * - * We also have to process the 'joinclauses' list here, because it - * contains EC-derived join clauses which must become filter clauses. It - * is not enough to just correct the ECs because the EC-derived - * restrictions are generated before join removal (see - * generate_base_implied_equalities). - * - * NOTE: Remember to keep the code in sync with PlannerInfo to be sure all - * cached relids and relid bitmapsets can be correctly cleaned during the - * self-join elimination procedure. + * Since this is not a correctness issue but just an optimization opportunity, + * we likewise don't worry about recognizing duplicates that appear in + * different qual lists. */ -static void -remove_self_join_rel(PlannerInfo *root, PlanRowMark *kmark, PlanRowMark *rmark, - RelOptInfo *toKeep, RelOptInfo *toRemove, - List *restrictlist) +static List * +fixup_selfjoin_quals(PlannerInfo *root, List *quals, int relid) { - List *joininfos; - ListCell *lc; - int i; - List *jinfo_candidates = NIL; - List *binfo_candidates = NIL; - - Assert(toKeep->relid > 0); - Assert(toRemove->relid > 0); - - /* - * Replace the index of the removing table with the keeping one. The - * technique of removing/distributing restrictinfo is used here to attach - * just appeared (for keeping relation) join clauses and avoid adding - * duplicates of those that already exist in the joininfo list. - */ - joininfos = list_copy(toRemove->joininfo); - foreach_node(RestrictInfo, rinfo, joininfos) - { - remove_join_clause_from_rels(root, rinfo, rinfo->required_relids); - ChangeVarNodesExtended((Node *) rinfo, toRemove->relid, toKeep->relid, - 0, replace_relid_callback); - - if (bms_membership(rinfo->required_relids) == BMS_MULTIPLE) - jinfo_candidates = lappend(jinfo_candidates, rinfo); - else - binfo_candidates = lappend(binfo_candidates, rinfo); - } - - /* - * Concatenate restrictlist to the list of base restrictions of the - * removing table just to simplify the replacement procedure: all of them - * weren't connected to any keeping relations and need to be added to some - * rels. - */ - toRemove->baserestrictinfo = list_concat(toRemove->baserestrictinfo, - restrictlist); - foreach_node(RestrictInfo, rinfo, toRemove->baserestrictinfo) - { - ChangeVarNodesExtended((Node *) rinfo, toRemove->relid, toKeep->relid, - 0, replace_relid_callback); - - if (bms_membership(rinfo->required_relids) == BMS_MULTIPLE) - jinfo_candidates = lappend(jinfo_candidates, rinfo); - else - binfo_candidates = lappend(binfo_candidates, rinfo); - } - - /* - * Now, add all non-redundant clauses to the keeping relation. - */ - add_non_redundant_clauses(root, binfo_candidates, - &toKeep->baserestrictinfo, toRemove->relid); - add_non_redundant_clauses(root, jinfo_candidates, - &toKeep->joininfo, toRemove->relid); - - list_free(binfo_candidates); - list_free(jinfo_candidates); - - /* - * Arrange equivalence classes, mentioned removing a table, with the - * keeping one: varno of removing table should be replaced in members and - * sources lists. Also, remove duplicated elements if this replacement - * procedure created them. - */ - i = -1; - while ((i = bms_next_member(toRemove->eclass_indexes, i)) >= 0) - { - EquivalenceClass *ec = (EquivalenceClass *) list_nth(root->eq_classes, i); - - update_eclasses(ec, toRemove->relid, toKeep->relid); - toKeep->eclass_indexes = bms_add_member(toKeep->eclass_indexes, i); - } - - /* - * Transfer the targetlist and attr_needed flags. - */ - - foreach(lc, toRemove->reltarget->exprs) - { - Node *node = lfirst(lc); - - ChangeVarNodesExtended(node, toRemove->relid, toKeep->relid, 0, - replace_relid_callback); - if (!list_member(toKeep->reltarget->exprs, node)) - toKeep->reltarget->exprs = lappend(toKeep->reltarget->exprs, node); - } - - for (i = toKeep->min_attr; i <= toKeep->max_attr; i++) - { - int attno = i - toKeep->min_attr; - - toRemove->attr_needed[attno] = adjust_relid_set(toRemove->attr_needed[attno], - toRemove->relid, toKeep->relid); - toKeep->attr_needed[attno] = bms_add_members(toKeep->attr_needed[attno], - toRemove->attr_needed[attno]); - } + List *result = NIL; + ListCell *l; - /* - * If the removed relation has a row mark, transfer it to the remaining - * one. - * - * If both rels have row marks, just keep the one corresponding to the - * remaining relation because we verified earlier that they have the same - * strength. - */ - if (rmark) + foreach(l, quals) { - if (kmark) - { - Assert(kmark->markType == rmark->markType); + Node *qual = (Node *) lfirst(l); - root->rowMarks = list_delete_ptr(root->rowMarks, rmark); - } - else + if (bms_is_member(relid, pull_varnos(root, qual))) { - /* Shouldn't have inheritance children here. */ - Assert(rmark->rti == rmark->prti); - - rmark->rti = rmark->prti = toKeep->relid; + qual = replace_selfjoin_qual(qual); + /* Drop it if the substitution has made it a duplicate */ + if (list_member(result, qual)) + continue; } + result = lappend(result, qual); } - /* - * Replace varno in all the query structures, except nodes RangeTblRef - * otherwise later remove_rel_from_joinlist will yield errors. - */ - ChangeVarNodesExtended((Node *) root->parse, toRemove->relid, toKeep->relid, - 0, replace_relid_callback); - - /* Replace links in the planner info */ - remove_rel_from_query(root, toRemove->relid, toKeep->relid, NULL, NULL); - - /* Replace varno in the fully-processed targetlist */ - ChangeVarNodesExtended((Node *) root->processed_tlist, toRemove->relid, - toKeep->relid, 0, replace_relid_callback); - - /* - * No need to touch all_result_relids or leaf_result_relids: at this point - * those sets contain only parse->resultRelation; inheritance children - * have not been added yet; that happens later in add_other_rels_to_query. - * And remove_self_joins_recurse rejects parse->resultRelation as an SJE - * candidate to preserve the EPQ mechanism. So toRemove->relid cannot be - * a member. - */ - Assert(!bms_is_member(toRemove->relid, root->all_result_relids)); - Assert(!bms_is_member(toRemove->relid, root->leaf_result_relids)); - - /* - * There may be references to the rel in root->fkey_list, but if so, - * match_foreign_keys_to_quals() will get rid of them. - */ - - /* - * Finally, remove the rel from the baserel array to prevent it from being - * referenced again. (We can't do this earlier because - * remove_join_clause_from_rels will touch it.) - */ - root->simple_rel_array[toRemove->relid] = NULL; - root->simple_rte_array[toRemove->relid] = NULL; - - /* And nuke the RelOptInfo, just in case there's another access path. */ - pfree(toRemove); + return result; +} +/* + * replace_selfjoin_qual + * Replace one "X = X" qual by "X IS NOT NULL", if it is one. + */ +static Node * +replace_selfjoin_qual(Node *qual) +{ + OpExpr *opexpr; + Node *leftop; + Node *rightop; + NullTest *ntest; + + /* See if it looks like "X op X" */ + if (!is_opclause(qual)) + return qual; + opexpr = (OpExpr *) qual; + if (list_length(opexpr->args) != 2) + return qual; + leftop = get_leftop((Expr *) opexpr); + rightop = get_rightop((Expr *) opexpr); + if (!equal(leftop, rightop)) + return qual; /* - * Now repeat construction of attr_needed bits coming from all other - * sources. + * The operator must be strict and behave like btree equality, else we + * can't conclude that it yields true for any non-null input. And the + * input had better not be volatile, else the two evaluations might not + * agree. If either condition doesn't hold, the clause is not a candidate + * to be an equivalence, so we needn't worry about it getting replaced by + * equivclass.c. */ - rebuild_placeholder_attr_needed(root); - rebuild_joinclause_attr_needed(root); - rebuild_eclass_attr_needed(root); - rebuild_lateral_attr_needed(root); + set_opfuncid(opexpr); + if (!func_strict(opexpr->opfuncid)) + return qual; + if (!op_mergejoinable(opexpr->opno, exprType(leftop))) + return qual; + if (contain_volatile_functions(leftop)) + return qual; + + /* OK, replace it */ + ntest = makeNode(NullTest); + ntest->arg = (Expr *) leftop; + ntest->nulltesttype = IS_NOT_NULL; + ntest->argisrow = false; /* correct even if composite arg */ + ntest->location = -1; + return (Node *) ntest; } /* @@ -2244,7 +1654,12 @@ split_selfjoin_quals(PlannerInfo *root, List *joinquals, List **selfjoinquals, Node *leftexpr; Node *rightexpr; - /* In general, clause looks like F(arg1) = G(arg2) */ + /* + * Since the given joinquals all came from + * generate_join_implied_equalities, they ought to look like equality + * operators on single-relation expressions. But let's check that. + * Anything that doesn't look like that can be dumped into ojoinquals. + */ if (!rinfo->mergeopfamilies || bms_num_members(rinfo->clause_relids) != 2 || bms_membership(rinfo->left_relids) != BMS_SINGLETON || @@ -2275,10 +1690,9 @@ split_selfjoin_quals(PlannerInfo *root, List *joinquals, List **selfjoinquals, * when we have cast of the same var to different (but compatible) * types. */ - ChangeVarNodesExtended(rightexpr, - bms_singleton_member(rinfo->right_relids), - bms_singleton_member(rinfo->left_relids), 0, - replace_relid_callback); + ChangeVarNodes(rightexpr, + bms_singleton_member(rinfo->right_relids), + bms_singleton_member(rinfo->left_relids), 0); if (equal(leftexpr, rightexpr)) sjoinquals = lappend(sjoinquals, rinfo); @@ -2314,8 +1728,7 @@ match_unique_clauses(PlannerInfo *root, RelOptInfo *outer, List *uclauses, bms_is_empty(rinfo->right_relids)); clause = (Expr *) copyObject(rinfo->clause); - ChangeVarNodesExtended((Node *) clause, relid, outer->relid, 0, - replace_relid_callback); + ChangeVarNodes((Node *) clause, relid, outer->relid, 0); iclause = bms_is_empty(rinfo->left_relids) ? get_rightop(clause) : get_leftop(clause); @@ -2360,12 +1773,23 @@ match_unique_clauses(PlannerInfo *root, RelOptInfo *outer, List *uclauses, * Find and remove unique self-joins in a group of base relations that have * the same Oid. * - * Returns a set of relids that were removed. + * Return true if we removed any joins. + * + * After a removal, we continue searching for more removals, even though the + * tests will be using derived data that is now partially stale. That is safe + * because we are trying to prove that a candidate pair of relations must + * match the same row, and the stale data can only omit quals, never invent + * them. The removed relation's quals are moved onto the kept relation in + * the jointree but not into its baserestrictinfo, and no other derived data + * changes. A proof made from a subset of the applicable quals remains valid + * when the rest are added, since extra quals can only remove rows from the + * join. So a pass may miss a removal that a later pass will find, but it + * cannot make one that isn't justified. */ -static Relids +static bool remove_self_joins_one_group(PlannerInfo *root, Relids relids) { - Relids result = NULL; + bool removed = false; int k; /* Index of kept relation */ int r = -1; /* Index of removed relation */ @@ -2373,8 +1797,8 @@ remove_self_joins_one_group(PlannerInfo *root, Relids relids) { RelOptInfo *rrel = root->simple_rel_array[r]; + /* k iterates over the relids after r */ k = r; - while ((k = bms_next_member(relids, k)) > 0) { Relids joinrelids = NULL; @@ -2394,8 +1818,8 @@ remove_self_joins_one_group(PlannerInfo *root, Relids relids) /* * It is impossible to eliminate the join of two relations if they - * belong to different rules of order. Otherwise, the planner - * can't find any variants of the correct query plan. + * are not on the same side of every outer join. Otherwise, the + * planner can't find any variants of the correct query plan. */ foreach(lc, root->join_info_list) { @@ -2509,32 +1933,35 @@ remove_self_joins_one_group(PlannerInfo *root, Relids relids) if (!match_unique_clauses(root, rrel, uclauses, krel->relid)) continue; + /* OK, remove rrel from the query */ + remove_self_join_rel(root, krel, rrel, kmark, rmark); + removed = true; + /* - * Remove rrel RelOptInfo from the planner structures and the - * corresponding row mark. + * Since relation r is now gone, we mustn't keep looking for + * matches to it. But we can keep scanning later relids members + * for additional join pairs. */ - remove_self_join_rel(root, kmark, rmark, krel, rrel, restrictlist); - - result = bms_add_member(result, r); - - /* We have removed the outer relation, try the next one. */ break; } } - return result; + return removed; } /* - * Gather indexes of base relations from the joinlist and try to eliminate self - * joins. + * Gather indexes of base relations from the joinlist and try to eliminate + * self-joins. + * + * Return true if we removed any joins. */ -static Relids -remove_self_joins_recurse(PlannerInfo *root, List *joinlist, Relids toRemove) +static bool +remove_self_joins_recurse(PlannerInfo *root, List *joinlist) { + bool removed = false; ListCell *jl; Relids relids = NULL; - SelfJoinCandidate *candidates = NULL; + SelfJoinCandidate *candidates; int i; int j; int numRels; @@ -2553,7 +1980,7 @@ remove_self_joins_recurse(PlannerInfo *root, List *joinlist, Relids toRemove) * We only consider ordinary relations as candidates to be * removed, and these relations should not have TABLESAMPLE * clauses specified. Removing a relation with TABLESAMPLE clause - * could potentially change the syntax of the query. Because of + * could potentially change the semantics of the query. Because of * UPDATE/DELETE EPQ mechanism, currently Query->resultRelation or * Query->mergeTargetRelation associated rel cannot be eliminated. */ @@ -2569,9 +1996,8 @@ remove_self_joins_recurse(PlannerInfo *root, List *joinlist, Relids toRemove) } else if (IsA(jlnode, List)) { - /* Recursively go inside the sub-joinlist */ - toRemove = remove_self_joins_recurse(root, (List *) jlnode, - toRemove); + /* Recursively perform SJE within the sub-joinlist */ + removed |= remove_self_joins_recurse(root, (List *) jlnode); } else elog(ERROR, "unrecognized joinlist node type: %d", @@ -2580,9 +2006,9 @@ remove_self_joins_recurse(PlannerInfo *root, List *joinlist, Relids toRemove) numRels = bms_num_members(relids); - /* Need at least two relations for the join */ + /* No work if not at least two relations at this level */ if (numRels < 2) - return toRemove; + return removed; /* ... but don't fail to report sub-removals */ /* * In order to find relations with the same oid we first build an array of @@ -2603,15 +2029,13 @@ remove_self_joins_recurse(PlannerInfo *root, List *joinlist, Relids toRemove) /* * Iteratively form a group of relation indexes with the same oid and - * launch the routine that detects self-joins in this group and removes - * excessive range table entries. + * launch the routine that detects self-joins in this group. * - * At the end of the iteration, exclude the group from the overall relids - * list. So each next iteration of the cycle will involve less and less - * value of relids. + * We remove considered relations from relids as we scan, so that that set + * should be empty at the end. */ i = 0; - for (j = 1; j < numRels + 1; j++) + for (j = 1; j <= numRels; j++) { if (j == numRels || candidates[j].reloid != candidates[i].reloid) { @@ -2619,7 +2043,6 @@ remove_self_joins_recurse(PlannerInfo *root, List *joinlist, Relids toRemove) { /* Create a group of relation indexes with the same oid */ Relids group = NULL; - Relids removed; while (i < j) { @@ -2628,35 +2051,25 @@ remove_self_joins_recurse(PlannerInfo *root, List *joinlist, Relids toRemove) } relids = bms_del_members(relids, group); - /* - * Try to remove self-joins from a group of identical entries. - * Make the next attempt iteratively - if something is deleted - * from a group, changes in clauses and equivalence classes - * can give us a chance to find more candidates. - */ - do - { - Assert(!bms_overlap(group, toRemove)); - removed = remove_self_joins_one_group(root, group); - toRemove = bms_add_members(toRemove, removed); - group = bms_del_members(group, removed); - } while (!bms_is_empty(removed) && - bms_membership(group) == BMS_MULTIPLE); - bms_free(removed); + /* Try to remove self-joins from the group */ + removed |= remove_self_joins_one_group(root, group); bms_free(group); } else { - /* Single relation, just remove it from the set */ - relids = bms_del_member(relids, candidates[i].relid); - i = j; + /* Nothing to do with this group, just drop it from the set */ + while (i < j) + { + relids = bms_del_member(relids, candidates[i].relid); + i++; + } } } } Assert(bms_is_empty(relids)); - return toRemove; + return removed; } /* @@ -2698,45 +2111,26 @@ self_join_candidates_cmp(const void *a, const void *b) * go over each set with the same Oid, and consider each pair of relations * in this set. * - * To remove the join, we mark one of the participating relations as dead - * and rewrite all references to it to point to the remaining relation. - * This includes modifying RestrictInfos, EquivalenceClasses, and - * EquivalenceMembers. We also have to modify the row marks. The join clauses - * of the removed relation become either restriction or join clauses, based on - * whether they reference any relations not participating in the removed join. + * To remove the join, we delete one of the participating relations from the + * query's jointree and rewrite all references to it to point to the remaining + * relation. We also have to modify their row marks. * - * 'joinlist' is the top-level joinlist of the query. If it has any - * references to the removed relations, we update them to point to the - * remaining ones. + * 'joinlist' is the top-level joinlist of the query; we use it to identify + * groups of relations that could be joined to each other. + * + * We return true if we removed any self-joins. If so, the caller must + * recompute everything that was derived from the jointree, and should then + * try join simplifications again since we might have exposed opportunities + * for additional simplifications. */ -List * +bool remove_useless_self_joins(PlannerInfo *root, List *joinlist) { - Relids toRemove = NULL; - int relid = -1; - + /* Skip if SJE is disabled, or if the joinlist has less than 2 members. */ if (!enable_self_join_elimination || joinlist == NIL || (list_length(joinlist) == 1 && !IsA(linitial(joinlist), List))) - return joinlist; - - /* - * Merge pairs of relations participated in self-join. Remove unnecessary - * range table entries. - */ - toRemove = remove_self_joins_recurse(root, joinlist, toRemove); - - if (unlikely(toRemove != NULL)) - { - /* At the end, remove orphaned relation links */ - while ((relid = bms_next_member(toRemove, relid)) >= 0) - { - int nremoved = 0; - - joinlist = remove_rel_from_joinlist(joinlist, relid, &nremoved); - if (nremoved != 1) - elog(ERROR, "failed to find relation %d in joinlist", relid); - } - } + return false; - return joinlist; + /* Try to merge pairs of self-joined relations. */ + return remove_self_joins_recurse(root, joinlist); } diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index b38422c47a4..d8a5c242eef 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -295,8 +295,6 @@ build_base_rel_tlists(PlannerInfo *root, List *final_tlist) * have a single owning relation; we keep their attr_needed info in * root->placeholder_list instead. Find or create the associated * PlaceHolderInfo entry, and update its ph_needed. - * - * See also add_vars_to_attr_needed. */ void add_vars_to_targetlist(PlannerInfo *root, List *vars, @@ -350,63 +348,6 @@ add_vars_to_targetlist(PlannerInfo *root, List *vars, } } -/* - * add_vars_to_attr_needed - * This does a subset of what add_vars_to_targetlist does: it just - * updates attr_needed for Vars and ph_needed for PlaceHolderVars. - * We assume the Vars are already in their relations' targetlists. - * - * This is used to rebuild attr_needed/ph_needed sets after removal - * of a useless outer join. The removed join clause might have been - * the only upper-level use of some other relation's Var, in which - * case we can reduce that Var's attr_needed and thereby possibly - * open the door to further join removals. But we can't tell that - * without tedious reconstruction of the attr_needed data. - * - * Note that if a Var's attr_needed is successfully reduced to empty, - * it will still be in the relation's targetlist even though we do - * not really need the scan plan node to emit it. The extra plan - * inefficiency seems tiny enough to not be worth spending planner - * cycles to get rid of it. - */ -void -add_vars_to_attr_needed(PlannerInfo *root, List *vars, - Relids where_needed) -{ - ListCell *temp; - - Assert(!bms_is_empty(where_needed)); - - foreach(temp, vars) - { - Node *node = (Node *) lfirst(temp); - - if (IsA(node, Var)) - { - Var *var = (Var *) node; - RelOptInfo *rel = find_base_rel(root, var->varno); - int attno = var->varattno; - - if (bms_is_subset(where_needed, rel->relids)) - continue; - Assert(attno >= rel->min_attr && attno <= rel->max_attr); - attno -= rel->min_attr; - rel->attr_needed[attno] = bms_add_members(rel->attr_needed[attno], - where_needed); - } - else if (IsA(node, PlaceHolderVar)) - { - PlaceHolderVar *phv = (PlaceHolderVar *) node; - PlaceHolderInfo *phinfo = find_placeholder_info(root, phv); - - phinfo->ph_needed = bms_add_members(phinfo->ph_needed, - where_needed); - } - else - elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); - } -} - /***************************************************************************** * * GROUP BY @@ -1226,54 +1167,10 @@ extract_lateral_references(PlannerInfo *root, RelOptInfo *brel, Index rtindex) */ add_vars_to_targetlist(root, newvars, where_needed); - /* - * Remember the lateral references for rebuild_lateral_attr_needed and - * create_lateral_join_info. - */ + /* Remember the lateral references for create_lateral_join_info */ brel->lateral_vars = newvars; } -/* - * rebuild_lateral_attr_needed - * Put back attr_needed bits for Vars/PHVs needed for lateral references. - * - * This is used to rebuild attr_needed/ph_needed sets after removal of a - * useless outer join. It should match what find_lateral_references did, - * except that we call add_vars_to_attr_needed not add_vars_to_targetlist. - */ -void -rebuild_lateral_attr_needed(PlannerInfo *root) -{ - Index rti; - - /* We need do nothing if the query contains no LATERAL RTEs */ - if (!root->hasLateralRTEs) - return; - - /* Examine the same baserels that find_lateral_references did */ - for (rti = 1; rti < root->simple_rel_array_size; rti++) - { - RelOptInfo *brel = root->simple_rel_array[rti]; - Relids where_needed; - - if (brel == NULL) - continue; - if (brel->reloptkind != RELOPT_BASEREL) - continue; - - /* - * We don't need to repeat all of extract_lateral_references, since it - * kindly saved the extracted Vars/PHVs in lateral_vars. - */ - if (brel->lateral_vars == NIL) - continue; - - where_needed = bms_make_singleton(rti); - - add_vars_to_attr_needed(root, brel->lateral_vars, where_needed); - } -} - /* * create_lateral_join_info * Fill in the per-base-relation direct_lateral_relids, lateral_relids @@ -3227,9 +3124,6 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause, * var propagation is ensured by making ojscope include input rels from * both sides of the join. * - * See also rebuild_joinclause_attr_needed, which has to partially repeat - * this work after removal of an outer join. - * * Note: if the clause gets absorbed into an EquivalenceClass then this * may be unnecessary, but for now we have to do it to cover the case * where the EC becomes ec_broken and we end up reinserting the original @@ -3803,11 +3697,6 @@ process_implied_equality(PlannerInfo *root, * some of the Vars could have missed having that done because they only * appeared in single-relation clauses originally. So do it here for * safety. - * - * See also rebuild_joinclause_attr_needed, which has to partially repeat - * this work after removal of an outer join. (Since we will put this - * clause into the joininfo lists, that function needn't do any extra work - * to find it.) */ if (bms_membership(relids) == BMS_MULTIPLE) { @@ -3949,72 +3838,6 @@ get_join_domain_min_rels(PlannerInfo *root, Relids domain_relids) } -/* - * rebuild_joinclause_attr_needed - * Put back attr_needed bits for Vars/PHVs needed for join clauses. - * - * This is used to rebuild attr_needed/ph_needed sets after removal of a - * useless outer join. It should match what distribute_qual_to_rels did, - * except that we call add_vars_to_attr_needed not add_vars_to_targetlist. - */ -void -rebuild_joinclause_attr_needed(PlannerInfo *root) -{ - /* - * We must examine all join clauses, but there's no value in processing - * any join clause more than once. So it's slightly annoying that we have - * to find them via the per-base-relation joininfo lists. Avoid duplicate - * processing by tracking the rinfo_serial numbers of join clauses we've - * already seen. (This doesn't work for is_clone clauses, so we must - * waste effort on them.) - */ - Bitmapset *seen_serials = NULL; - Index rti; - - /* Scan all baserels for join clauses */ - for (rti = 1; rti < root->simple_rel_array_size; rti++) - { - RelOptInfo *brel = root->simple_rel_array[rti]; - ListCell *lc; - - if (brel == NULL) - continue; - if (brel->reloptkind != RELOPT_BASEREL) - continue; - - foreach(lc, brel->joininfo) - { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); - Relids relids = rinfo->required_relids; - - if (!rinfo->is_clone) /* else serial number is not unique */ - { - if (bms_is_member(rinfo->rinfo_serial, seen_serials)) - continue; /* saw it already */ - seen_serials = bms_add_member(seen_serials, - rinfo->rinfo_serial); - } - - if (bms_membership(relids) == BMS_MULTIPLE) - { - List *vars = pull_var_clause((Node *) rinfo->clause, - PVC_RECURSE_AGGREGATES | - PVC_RECURSE_WINDOWFUNCS | - PVC_INCLUDE_PLACEHOLDERS); - Relids where_needed; - - if (rinfo->is_clone) - where_needed = bms_intersect(relids, root->all_baserels); - else - where_needed = relids; - add_vars_to_attr_needed(root, vars, where_needed); - list_free(vars); - } - } - } -} - - /* * match_foreign_keys_to_quals * Match foreign-key constraints to equivalence classes and join quals @@ -4044,9 +3867,9 @@ match_foreign_keys_to_quals(PlannerInfo *root) /* * Either relid might identify a rel that is in the query's rtable but - * isn't referenced by the jointree, or has been removed by join - * removal, so that it won't have a RelOptInfo. Hence don't use - * find_base_rel() here. We can ignore such FKs. + * isn't referenced by the jointree (typically because it's been + * removed by join removal), so that it won't have a RelOptInfo. Hence + * don't use find_base_rel() here. We can ignore such FKs. */ if (fkinfo->con_relid >= root->simple_rel_array_size || fkinfo->ref_relid >= root->simple_rel_array_size) diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index 02495e22e24..68d3409476c 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -54,33 +54,71 @@ RelOptInfo * query_planner(PlannerInfo *root, query_pathkeys_callback qp_callback, void *qp_extra) { - Query *parse = root->parse; + Query *parse; List *joinlist; RelOptInfo *final_rel; /* - * Init planner lists to empty. + * The join simplification steps below work by modifying parse->jointree, + * and they make no attempt to update the information we derive from it. + * So whenever one of them succeeds, we must throw away all that derived + * information and recompute it from scratch, which we do by looping back + * to "restart". We cannot loop indefinitely, because each successful + * simplification either deletes a base relation from the jointree or + * turns a semijoin into an inner join, and neither of those can be undone + * by a later pass. * - * NOTE: append_rel_list was set up by subquery_planner, so do not touch - * here. + * These initial Asserts check that the state at entry is not too complex + * for the code below to restore. There mustn't be any EquivalenceClasses + * yet, and we should have only the top-level JoinDomain. */ + Assert(root->eq_classes == NIL); + Assert(list_length(root->join_domains) == 1); + +restart: + parse = root->parse; + + /* + * Initialize information derived from the jointree to empty. + * + * It's critical that this reset every field that the steps below will + * fill in, since we may be going around this loop more than once. + * + * NOTE: append_rel_list was created earlier, so do not clear it here; + * rowMarks ditto. Join simplification must update those if necessary. + */ + root->all_baserels = NULL; + root->outer_join_rels = NULL; + root->all_query_rels = NULL; root->join_rel_list = NIL; root->join_rel_hash = NULL; root->join_rel_level = NULL; root->join_cur_level = 0; + root->eq_classes = NIL; + root->ec_merging_done = false; root->canon_pathkeys = NIL; root->left_join_clauses = NIL; root->right_join_clauses = NIL; root->full_join_clauses = NIL; root->join_info_list = NIL; + root->last_rinfo_serial = 0; root->placeholder_list = NIL; root->placeholder_array = NULL; root->placeholder_array_size = 0; + root->placeholdersFrozen = false; root->agg_clause_list = NIL; root->group_expr_list = NIL; root->tlist_vars = NIL; root->fkey_list = NIL; root->initial_rels = NIL; + root->hasPseudoConstantQuals = false; + + /* + * We don't want to delete the top-level join domain, but get rid of other + * ones so as to reset the list to initial state. deconstruct_jointree + * will take care of (re)computing the top level's jd_relids. + */ + root->join_domains = list_truncate(root->join_domains, 1); /* * Set up arrays for accessing base relations and AppendRelInfos. @@ -144,6 +182,21 @@ query_planner(PlannerInfo *root, /* Select cheapest path (pretty easy in this case...) */ set_cheapest(final_rel); + /* + * Fill in all_result_relids and leaf_result_relids, just in + * case something looks at them (at this writing, the core + * code won't). This must match the similar stanza below. + */ + if (parse->resultRelation) + { + int rti = parse->resultRelation; + RangeTblEntry *res_rte = root->simple_rte_array[rti]; + + root->all_result_relids = bms_make_singleton(rti); + if (!res_rte->inh) + root->leaf_result_relids = bms_make_singleton(rti); + } + /* * We don't need to run generate_base_implied_equalities, but * we do need to pretend that EC merging is complete. @@ -227,19 +280,30 @@ query_planner(PlannerInfo *root, * Remove any useless outer joins. Ideally this would be done during * jointree preprocessing, but the necessary information isn't available * until we've built baserel data structures and classified qual clauses. + * If we remove a join, loop back to the top and redo what we did so far. */ - joinlist = remove_useless_joins(root, joinlist); + if (remove_useless_outer_joins(root)) + goto restart; /* * Also, reduce any semijoins with unique inner rels to plain inner joins. - * Likewise, this can't be done until now for lack of needed info. + * Likewise, this can't be done until now for lack of needed info, and we + * must loop around if we find any simplifications. + */ + if (reduce_unique_semijoins(root)) + goto restart; + + /* + * Remove self joins on a unique column. Again, this couldn't be done any + * earlier, and we must loop around if we find anything to remove. */ - reduce_unique_semijoins(root); + if (remove_useless_self_joins(root, joinlist)) + goto restart; /* - * Remove self joins on a unique column. + * No more join simplifications apply, so we're done looping. Code below + * this point does not need to be able to restart. */ - joinlist = remove_useless_self_joins(root, joinlist); /* * Now distribute "placeholders" to base rels as needed. This has to be @@ -274,6 +338,22 @@ query_planner(PlannerInfo *root, */ setup_eager_aggregation(root); + /* + * If there's a result relation, initialize all_result_relids to include + * it; and if we've verified that it is non-inheriting, mark it as a leaf + * target. add_other_rels_to_query() will expand these sets if the result + * relation has children. + */ + if (parse->resultRelation) + { + int rti = parse->resultRelation; + RangeTblEntry *rte = root->simple_rte_array[rti]; + + root->all_result_relids = bms_make_singleton(rti); + if (!rte->inh) + root->leaf_result_relids = bms_make_singleton(rti); + } + /* * Now expand appendrels by adding "otherrels" for their children. We * delay this to the end so that we have as much information as possible diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index a0ff9159ae0..24d964c993d 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -803,9 +803,8 @@ subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, root->eq_classes = NIL; root->ec_merging_done = false; root->last_rinfo_serial = 0; - root->all_result_relids = - parse->resultRelation ? bms_make_singleton(parse->resultRelation) : NULL; - root->leaf_result_relids = NULL; /* we'll find out leaf-ness later */ + root->all_result_relids = NULL; + root->leaf_result_relids = NULL; root->append_rel_list = NIL; root->row_identity_vars = NIL; root->rowMarks = NIL; @@ -978,19 +977,6 @@ subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, list_length(rte->securityQuals)); } - /* - * If we have now verified that the query target relation is - * non-inheriting, mark it as a leaf target. - */ - if (parse->resultRelation) - { - RangeTblEntry *rte = rt_fetch(parse->resultRelation, parse->rtable); - - if (!rte->inh) - root->leaf_result_relids = - bms_make_singleton(parse->resultRelation); - } - /* * This would be a convenient time to check access permissions for all * relations mentioned in the query, since it would be better to fail now, diff --git a/src/backend/optimizer/util/joininfo.c b/src/backend/optimizer/util/joininfo.c index ef2f054c39e..f75e35f22ae 100644 --- a/src/backend/optimizer/util/joininfo.c +++ b/src/backend/optimizer/util/joininfo.c @@ -145,39 +145,3 @@ add_join_clause_to_rels(PlannerInfo *root, rel->joininfo = lappend(rel->joininfo, restrictinfo); } } - -/* - * remove_join_clause_from_rels - * Delete 'restrictinfo' from all the joininfo lists it is in - * - * This reverses the effect of add_join_clause_to_rels. It's used when we - * discover that a relation need not be joined at all. - * - * 'restrictinfo' describes the join clause - * 'join_relids' is the set of relations participating in the join clause - * (some of these could be outer joins) - */ -void -remove_join_clause_from_rels(PlannerInfo *root, - RestrictInfo *restrictinfo, - Relids join_relids) -{ - int cur_relid; - - cur_relid = -1; - while ((cur_relid = bms_next_member(join_relids, cur_relid)) >= 0) - { - RelOptInfo *rel = find_base_rel_ignore_join(root, cur_relid); - - /* We would only have added the clause to baserels */ - if (rel == NULL) - continue; - - /* - * Remove the restrictinfo from the list. Pointer comparison is - * sufficient. - */ - Assert(list_member_ptr(rel->joininfo, restrictinfo)); - rel->joininfo = list_delete_ptr(rel->joininfo, restrictinfo); - } -} diff --git a/src/backend/optimizer/util/placeholder.c b/src/backend/optimizer/util/placeholder.c index dd9b11885af..07171f84f61 100644 --- a/src/backend/optimizer/util/placeholder.c +++ b/src/backend/optimizer/util/placeholder.c @@ -316,33 +316,6 @@ fix_placeholder_input_needed_levels(PlannerInfo *root) } } -/* - * rebuild_placeholder_attr_needed - * Put back attr_needed bits for Vars/PHVs needed in PlaceHolderVars. - * - * This is used to rebuild attr_needed/ph_needed sets after removal of a - * useless outer join. It should match what - * fix_placeholder_input_needed_levels did, except that we call - * add_vars_to_attr_needed not add_vars_to_targetlist. - */ -void -rebuild_placeholder_attr_needed(PlannerInfo *root) -{ - ListCell *lc; - - foreach(lc, root->placeholder_list) - { - PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc); - List *vars = pull_var_clause((Node *) phinfo->ph_var->phexpr, - PVC_RECURSE_AGGREGATES | - PVC_RECURSE_WINDOWFUNCS | - PVC_INCLUDE_PLACEHOLDERS); - - add_vars_to_attr_needed(root, vars, phinfo->ph_eval_at); - list_free(vars); - } -} - /* * add_placeholders_to_base_rels * Add any required PlaceHolderVars to base rels' targetlists. diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c index 9aa7ef60475..1be6daf3cdf 100644 --- a/src/backend/rewrite/rewriteManip.c +++ b/src/backend/rewrite/rewriteManip.c @@ -65,6 +65,7 @@ static bool locate_windowfunc_walker(Node *node, locate_windowfunc_context *context); static bool checkExprHasSubLink_walker(Node *node, void *context); static Relids offset_relid_set(Relids relids, int offset); +static Relids adjust_relid_set(Relids relids, int oldrelid, int newrelid); static Node *add_nulling_relids_mutator(Node *node, add_nulling_relids_context *context); static Node *remove_nulling_relids_mutator(Node *node, @@ -541,23 +542,32 @@ offset_relid_set(Relids relids, int offset) * * Find all Var nodes in the given tree belonging to a specific relation * (identified by sublevels_up and rt_index), and change their varno fields - * to 'new_index'. The varnosyn fields are changed too. Also, adjust other - * nodes that contain rangetable indexes, such as RangeTblRef and JoinExpr. + * to 'new_index', and update varnosyn and varnullingrels fields similarly. + * Also adjust other nodes that contain rangetable indexes, such as + * RangeTblRef and JoinExpr. + * + * Also, new_index can be INVALID_VAR to indicate that we are deleting the + * given relid from the tree. In this case we expect to find rt_index only + * in Relids fields (varnullingrels, phnullingrels, phrels), never in any + * field that identifies a single relation. * * NOTE: although this has the form of a walker, we cheat and modify the * nodes in-place. The given expression tree should have been copied * earlier to ensure that no unwanted side-effects occur! */ +typedef struct +{ + int rt_index; + int new_index; + int sublevels_up; +} ChangeVarNodes_context; + static bool ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context) { if (node == NULL) return false; - - if (context->callback && context->callback(node, context)) - return false; - if (IsA(node, Var)) { Var *var = (Var *) node; @@ -565,12 +575,18 @@ ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context) if (var->varlevelsup == context->sublevels_up) { if (var->varno == context->rt_index) + { + Assert(context->new_index != INVALID_VAR); var->varno = context->new_index; + } var->varnullingrels = adjust_relid_set(var->varnullingrels, context->rt_index, context->new_index); if (var->varnosyn == context->rt_index) + { + Assert(context->new_index != INVALID_VAR); var->varnosyn = context->new_index; + } } return false; } @@ -580,7 +596,10 @@ ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context) if (context->sublevels_up == 0 && cexpr->cvarno == context->rt_index) + { + Assert(context->new_index != INVALID_VAR); cexpr->cvarno = context->new_index; + } return false; } if (IsA(node, RangeTblRef)) @@ -589,7 +608,10 @@ ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context) if (context->sublevels_up == 0 && rtr->rtindex == context->rt_index) + { + Assert(context->new_index != INVALID_VAR); rtr->rtindex = context->new_index; + } /* the subquery itself is visited separately */ return false; } @@ -599,7 +621,10 @@ ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context) if (context->sublevels_up == 0 && j->rtindex == context->rt_index) + { + Assert(context->new_index != INVALID_VAR); j->rtindex = context->new_index; + } /* fall through to examine children */ } if (IsA(node, PlaceHolderVar)) @@ -624,9 +649,15 @@ ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context) if (context->sublevels_up == 0) { if (rowmark->rti == context->rt_index) + { + Assert(context->new_index != INVALID_VAR); rowmark->rti = context->new_index; + } if (rowmark->prti == context->rt_index) + { + Assert(context->new_index != INVALID_VAR); rowmark->prti = context->new_index; + } } return false; } @@ -637,9 +668,15 @@ ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context) if (context->sublevels_up == 0) { if (appinfo->parent_relid == context->rt_index) + { + Assert(context->new_index != INVALID_VAR); appinfo->parent_relid = context->new_index; + } if (appinfo->child_relid == context->rt_index) + { + Assert(context->new_index != INVALID_VAR); appinfo->child_relid = context->new_index; + } } /* fall through to examine children */ } @@ -662,28 +699,14 @@ ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context) return expression_tree_walker(node, ChangeVarNodes_walker, context); } -/* - * ChangeVarNodesExtended - similar to ChangeVarNodes, but with an additional - * 'callback' param - * - * ChangeVarNodes changes a given node and all of its underlying nodes. This - * version of function additionally takes a callback, which has a chance to - * process a node before ChangeVarNodes_walker. A callback returns a boolean - * value indicating if the given node should be skipped from further processing - * by ChangeVarNodes_walker. The callback is called only for expressions and - * other children nodes of a Query processed by a walker. Initial processing - * of the root Query node doesn't invoke the callback. - */ void -ChangeVarNodesExtended(Node *node, int rt_index, int new_index, - int sublevels_up, ChangeVarNodes_callback callback) +ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up) { ChangeVarNodes_context context; context.rt_index = rt_index; context.new_index = new_index; context.sublevels_up = sublevels_up; - context.callback = callback; /* * Must be prepared to start with a Query or a bare expression tree; if @@ -707,21 +730,33 @@ ChangeVarNodesExtended(Node *node, int rt_index, int new_index, ListCell *l; if (qry->resultRelation == rt_index) + { + Assert(new_index != INVALID_VAR); qry->resultRelation = new_index; + } if (qry->mergeTargetRelation == rt_index) + { + Assert(new_index != INVALID_VAR); qry->mergeTargetRelation = new_index; + } /* this is unlikely to ever be used, but ... */ if (qry->onConflict && qry->onConflict->exclRelIndex == rt_index) + { + Assert(new_index != INVALID_VAR); qry->onConflict->exclRelIndex = new_index; + } foreach(l, qry->rowMarks) { RowMarkClause *rc = (RowMarkClause *) lfirst(l); if (rc->rti == rt_index) + { + Assert(new_index != INVALID_VAR); rc->rti = new_index; + } } } query_tree_walker(qry, ChangeVarNodes_walker, &context, 0); @@ -730,36 +765,6 @@ ChangeVarNodesExtended(Node *node, int rt_index, int new_index, ChangeVarNodes_walker(node, &context); } -void -ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up) -{ - ChangeVarNodesExtended(node, rt_index, new_index, sublevels_up, NULL); -} - -/* - * ChangeVarNodesWalkExpression - process subexpression within a callback - * function passed to ChangeVarNodesExtended. - * - * This is intended to be used by a callback that needs to recursively - * process subexpressions of some node being visited by an outer - * ChangeVarNodesExtended call, instead of relying on ChangeVarNodes_walker's - * default recursion. We invoke ChangeVarNodes_walker directly rather than - * via expression_tree_walker, because expression_tree_walker only visits - * child nodes and would fail to process the passed node itself -- - * for example, a bare Var node would not get its varno adjusted. - * - * Because this calls ChangeVarNodes_walker directly, if the passed node is - * a Query, it will be treated as a sub-Query: sublevels_up is incremented - * before recursing into it, and Query-level fields (resultRelation, - * mergeTargetRelation, rowMarks, etc.) will not be adjusted. Do not apply - * this to a top-level Query node; use ChangeVarNodesExtended for that. - */ -bool -ChangeVarNodesWalkExpression(Node *node, ChangeVarNodes_context *context) -{ - return ChangeVarNodes_walker(node, context); -} - /* * adjust_relid_set - substitute newrelid for oldrelid in a Relid set * @@ -769,7 +774,7 @@ ChangeVarNodesWalkExpression(Node *node, ChangeVarNodes_context *context) * a special varno, this function does nothing. When newrelid is a special * varno, this function behaves as delete. */ -Relids +static Relids adjust_relid_set(Relids relids, int oldrelid, int newrelid) { if (!IS_SPECIAL_VARNO(oldrelid) && bms_is_member(oldrelid, relids)) diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 0b27c96c7a8..5fbeae2f954 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -217,6 +217,9 @@ typedef struct Expr * row identity information during UPDATE/DELETE/MERGE. This value should * never be seen outside the planner. * + * INVALID_VAR should never appear as anything's varno. We use it in a + * few APIs to denote removal of an RTE. + * * varnullingrels is the set of RT indexes of outer joins that can force * the Var's value to null (at the point where it appears in the query). * See optimizer/README for discussion of that. @@ -244,6 +247,7 @@ typedef struct Expr #define OUTER_VAR (-2) /* reference to outer subplan */ #define INDEX_VAR (-3) /* reference to index column */ #define ROWID_VAR (-4) /* row identity column during planning */ +#define INVALID_VAR (-5) /* this is not a valid varno! */ #define IS_SPECIAL_VARNO(varno) ((int) (varno) < 0) diff --git a/src/include/optimizer/joininfo.h b/src/include/optimizer/joininfo.h index 117195fbcfa..aa26cc670f9 100644 --- a/src/include/optimizer/joininfo.h +++ b/src/include/optimizer/joininfo.h @@ -23,8 +23,5 @@ extern bool have_relevant_joinclause(PlannerInfo *root, extern void add_join_clause_to_rels(PlannerInfo *root, RestrictInfo *restrictinfo, Relids join_relids); -extern void remove_join_clause_from_rels(PlannerInfo *root, - RestrictInfo *restrictinfo, - Relids join_relids); #endif /* JOININFO_H */ diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index 17f2099ec3b..051e38c1189 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -137,7 +137,6 @@ extern bool process_equivalence(PlannerInfo *root, extern Expr *canonicalize_ec_expression(Expr *expr, Oid req_type, Oid req_collation); extern void reconsider_outer_join_clauses(PlannerInfo *root); -extern void rebuild_eclass_attr_needed(PlannerInfo *root); extern EquivalenceClass *get_eclass_for_sort_expr(PlannerInfo *root, Expr *expr, List *opfamilies, @@ -208,7 +207,6 @@ extern bool eclass_useful_for_merging(PlannerInfo *root, extern bool is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist); extern bool is_redundant_with_indexclauses(RestrictInfo *rinfo, List *indexclauses); -extern void ec_clear_derived_clauses(EquivalenceClass *ec); /* * pathkeys.c diff --git a/src/include/optimizer/placeholder.h b/src/include/optimizer/placeholder.h index 60798281090..2099075e670 100644 --- a/src/include/optimizer/placeholder.h +++ b/src/include/optimizer/placeholder.h @@ -23,7 +23,6 @@ extern PlaceHolderInfo *find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv); extern void find_placeholders_in_jointree(PlannerInfo *root); extern void fix_placeholder_input_needed_levels(PlannerInfo *root); -extern void rebuild_placeholder_attr_needed(PlannerInfo *root); extern void add_placeholders_to_base_rels(PlannerInfo *root); extern void add_placeholders_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h index 71c043a25e8..c23ab568b98 100644 --- a/src/include/optimizer/planmain.h +++ b/src/include/optimizer/planmain.h @@ -73,12 +73,9 @@ extern void add_other_rels_to_query(PlannerInfo *root); extern void build_base_rel_tlists(PlannerInfo *root, List *final_tlist); extern void add_vars_to_targetlist(PlannerInfo *root, List *vars, Relids where_needed); -extern void add_vars_to_attr_needed(PlannerInfo *root, List *vars, - Relids where_needed); extern void remove_useless_groupby_columns(PlannerInfo *root); extern void setup_eager_aggregation(PlannerInfo *root); extern void find_lateral_references(PlannerInfo *root); -extern void rebuild_lateral_attr_needed(PlannerInfo *root); extern void create_lateral_join_info(PlannerInfo *root); extern List *deconstruct_jointree(PlannerInfo *root); extern bool restriction_is_always_true(PlannerInfo *root, @@ -102,24 +99,19 @@ extern RestrictInfo *build_implied_join_equality(PlannerInfo *root, Expr *item2, Relids qualscope, Index security_level); -extern void rebuild_joinclause_attr_needed(PlannerInfo *root); extern void match_foreign_keys_to_quals(PlannerInfo *root); /* * prototypes for plan/analyzejoins.c */ -extern List *remove_useless_joins(PlannerInfo *root, List *joinlist); -extern void reduce_unique_semijoins(PlannerInfo *root); +extern bool remove_useless_outer_joins(PlannerInfo *root); +extern bool reduce_unique_semijoins(PlannerInfo *root); extern bool query_supports_distinctness(Query *query); extern bool query_is_distinct_for(Query *query, List *distinct_cols); extern bool innerrel_is_unique(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, bool force_cache); -extern bool innerrel_is_unique_ext(PlannerInfo *root, Relids joinrelids, - Relids outerrelids, RelOptInfo *innerrel, - JoinType jointype, List *restrictlist, - bool force_cache, List **extra_clauses); -extern List *remove_useless_self_joins(PlannerInfo *root, List *joinlist); +extern bool remove_useless_self_joins(PlannerInfo *root, List *joinlist); /* * prototypes for plan/setrefs.c diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h index 9d234cb8741..2d15d8f8f95 100644 --- a/src/include/rewrite/rewriteManip.h +++ b/src/include/rewrite/rewriteManip.h @@ -41,30 +41,11 @@ typedef enum ReplaceVarsNoMatchOption REPLACEVARS_SUBSTITUTE_NULL, /* replace with a NULL Const */ } ReplaceVarsNoMatchOption; -typedef struct ChangeVarNodes_context ChangeVarNodes_context; - -typedef bool (*ChangeVarNodes_callback) (Node *node, - ChangeVarNodes_context *arg); - -struct ChangeVarNodes_context -{ - int rt_index; - int new_index; - int sublevels_up; - ChangeVarNodes_callback callback; -}; - -pg_nodiscard extern Relids adjust_relid_set(Relids relids, int oldrelid, int newrelid); extern void CombineRangeTables(List **dst_rtable, List **dst_perminfos, List *src_rtable, List *src_perminfos); extern void OffsetVarNodes(Node *node, int offset, int sublevels_up); extern void ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up); -extern void ChangeVarNodesExtended(Node *node, int rt_index, int new_index, - int sublevels_up, - ChangeVarNodes_callback callback); -extern bool ChangeVarNodesWalkExpression(Node *node, - ChangeVarNodes_context *context); extern void IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, int min_sublevels_up); extern void IncrementVarSublevelsUp_rtable(List *rtable, diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index deca5617ac8..38b91724703 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -6934,6 +6934,38 @@ where t1.a = s.c; ---------- (0 rows) +rollback; +-- join removal bug #19560: removing a join can leave an EquivalenceClass that +-- now yields a base restriction clause, so we must redo equivalence +-- processing from scratch +begin; +create temp table items (id text, owner text); +create temp table follows (item_id text, user_id text, + unique (user_id, item_id)); +insert into items values ('item1', 'alice'); +explain (costs off) +with viewer as (select 'bob' as id) +select count(*) from items + left join follows on follows.item_id = items.id and follows.user_id = 'bob' + left join viewer on true +where items.owner = viewer.id; + QUERY PLAN +--------------------------------------- + Aggregate + -> Seq Scan on items + Filter: (owner = 'bob'::text) +(3 rows) + +with viewer as (select 'bob' as id) +select count(*) from items + left join follows on follows.item_id = items.id and follows.user_id = 'bob' + left join viewer on true +where items.owner = viewer.id; + count +------- + 0 +(1 row) + rollback; -- check handling of semijoins after join removal: we must suppress -- unique-ification of known-constant values @@ -6959,17 +6991,17 @@ where exists (select 1 from t t4 Output: t1.a Index Cond: (t1.a = 1) -> HashAggregate - Output: t5.a + Output: t4.a, t5.a Group Key: t5.a -> Hash Join - Output: t5.a + Output: t4.a, t5.a Hash Cond: (t6.b = t4.b) -> Seq Scan on pg_temp.t t6 Output: t6.a, t6.b -> Hash - Output: t4.b, t5.b, t5.a + Output: t4.b, t4.a, t5.b, t5.a -> Hash Join - Output: t4.b, t5.b, t5.a + Output: t4.b, t4.a, t5.b, t5.a Inner Unique: true Hash Cond: (t5.b = t4.b) -> Seq Scan on pg_temp.t t5 @@ -7401,7 +7433,7 @@ on q1.ax = q2.a; Nested Loop Left Join Join Filter: (t2.a = t4.a) -> Seq Scan on sj t2 - Filter: ((b IS NULL) AND (a IS NOT NULL) AND ((c * c) = (c + 2))) + Filter: ((a IS NOT NULL) AND (b IS NULL) AND ((c * c) = (c + 2))) -> Seq Scan on sj t4 Filter: (c IS NOT NULL) (6 rows) @@ -7484,12 +7516,70 @@ select t1.a from sj t1 where t1.b in ( -> Seq Scan on public.sj t1 Output: t1.a, t1.b, t1.c -> Materialize - Output: t3.c, t3.b + Output: t3.b -> Seq Scan on public.sj t3 - Output: t3.c, t3.b + Output: t3.b Filter: (t3.c IS NOT NULL) (10 rows) +-- Check that quals get hoisted to the appropriate join level after SJE removal +explain (verbose, costs off) +select a2.a +from sj b1 + join sj a1 on b1.b = a1.a + join sj a2 on a2.a = a1.a and a2.b = a1.b; + QUERY PLAN +------------------------------------------------------------- + Nested Loop + Output: a2.a + Join Filter: (b1.b = a2.a) + -> Seq Scan on public.sj a2 + Output: a2.a, a2.b, a2.c + Filter: ((a2.a IS NOT NULL) AND (a2.b IS NOT NULL)) + -> Seq Scan on public.sj b1 + Output: b1.a, b1.b, b1.c +(8 rows) + +-- Same, when a semijoin removal happens first +explain (verbose, costs off) +select a1.a from sj b1 join sj a1 on a1.a = b1.b + where exists (select 1 from sj s where s.a = a1.a); + QUERY PLAN +----------------------------------------- + Nested Loop + Output: s.a + Inner Unique: true + Join Filter: (b1.b = s.a) + -> Seq Scan on public.sj b1 + Output: b1.a, b1.b, b1.c + -> Materialize + Output: s.a + -> Seq Scan on public.sj s + Output: s.a + Filter: (s.a IS NOT NULL) +(11 rows) + +-- A different case, where modified qual is on a lower join level +explain (verbose, costs off) +select a2.a +from ((sj b1 join sj a1 on true) join sj c1 on c1.b = a1.a) + join sj a2 on a2.a = a1.a and a2.b = a1.b; + QUERY PLAN +------------------------------------------------------------------- + Nested Loop + Output: a2.a + -> Nested Loop + Output: a2.a + Join Filter: (c1.b = a2.a) + -> Seq Scan on public.sj a2 + Output: a2.a, a2.b, a2.c + Filter: ((a2.a IS NOT NULL) AND (a2.b IS NOT NULL)) + -> Seq Scan on public.sj c1 + Output: c1.a, c1.b, c1.c + -> Seq Scan on public.sj b1 + Output: b1.a, b1.b, b1.c +(12 rows) + -- -- SJE corner case: uniqueness of an inner is [partially] derived from -- baserestrictinfo clauses. @@ -7820,15 +7910,15 @@ explain (costs off) select * from sj p join sj q on p.a = q.a -> Seq Scan on sj r (6 rows) --- FIXME this constant false filter doesn't look good. Should we merge --- equivalence classes? +-- Check that we detect constant-false condition after merging ECs. explain (costs off) select * from sj p, sj q where p.a = q.a and p.b = 1 and q.b = 2; - QUERY PLAN ------------------------------------------------------ - Seq Scan on sj q - Filter: ((a IS NOT NULL) AND (b = 2) AND (b = 1)) -(2 rows) + QUERY PLAN +-------------------------- + Result + Replaces: Scan on q + One-Time Filter: false +(3 rows) -- Check that attr_needed is updated correctly after self-join removal. In this -- test, the join of j1 with j2 is removed. k1.b is required at either j1 or j2. @@ -7964,11 +8054,9 @@ where s1.x = 1; -> Seq Scan on public.emp1 t1 Output: t1.id, t1.code -> Materialize - Output: t3.id -> Seq Scan on public.emp1 t3 - Output: t3.id Filter: (1 = 1) -(9 rows) +(7 rows) -- Check that PHVs do not impose any constraints on removing self joins explain (verbose, costs off) @@ -8018,14 +8106,14 @@ SELECT 1 FROM tbl_phv t1 LEFT JOIN (SELECT y FROM tbl_phv tr) t4 ON t4.y = t3.y ON true WHERE t3.extra IS NOT NULL AND t3.x = t1.x % 2; - QUERY PLAN ---------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------- Nested Loop Output: 1 -> Seq Scan on public.tbl_phv t1 Output: t1.x, t1.y - -> Index Scan using tbl_phv_idx on public.tbl_phv tr - Output: tr.x, tr.y + -> Index Only Scan using tbl_phv_idx on public.tbl_phv tr + Output: tr.x Index Cond: (tr.x = (t1.x % 2)) Filter: (1 IS NOT NULL) (8 rows) @@ -8206,7 +8294,7 @@ where t1.b = t2.b and t2.a = 3 and t1.a = 3 --------------------------------------------------------------------------------------------- Seq Scan on public.sl t2 Output: t2.a, t2.b, t2.c, t2.a, t2.b, t2.c - Filter: ((t2.c IS NOT NULL) AND (t2.b IS NOT NULL) AND (t2.a IS NOT NULL) AND (t2.a = 3)) + Filter: ((t2.b IS NOT NULL) AND (t2.c IS NOT NULL) AND (t2.a IS NOT NULL) AND (t2.a = 3)) (3 rows) -- Join qual isn't mergejoinable, but inner is unique. @@ -8248,10 +8336,35 @@ SELECT 1 AS c1 FROM sl sl1 LEFT JOIN (sl AS sl2 NATURAL JOIN sl AS sl3) -> Nested Loop Left Join Join Filter: sl3.bool_col -> Seq Scan on sl sl3 - Filter: (bool_col AND (a IS NOT NULL) AND (b IS NOT NULL) AND (c IS NOT NULL) AND (bool_col IS NOT NULL)) + Filter: ((a IS NOT NULL) AND (b IS NOT NULL) AND (c IS NOT NULL) AND (bool_col IS NOT NULL) AND bool_col) -> Seq Scan on sl sl4 (7 rows) +-- Check that quals of a jointree node that becomes empty when the self-join +-- is removed are not lost, and that they don't migrate above an outer join +EXPLAIN (COSTS OFF) +SELECT s.a FROM (SELECT * FROM sl WHERE c IS NOT NULL) s, sl t +WHERE t.a = s.a AND t.b = s.b; + QUERY PLAN +--------------------------------------------------------------------- + Seq Scan on sl + Filter: ((c IS NOT NULL) AND (a IS NOT NULL) AND (b IS NOT NULL)) +(2 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.a, ss.a FROM sl t1 + LEFT JOIN (SELECT s.a FROM (SELECT * FROM sl WHERE c IS NOT NULL) s + JOIN sl t ON t.a = s.a AND t.b = s.b) ss + ON ss.a = t1.a; + QUERY PLAN +--------------------------------------------------------------------------- + Nested Loop Left Join + Join Filter: (sl.a = t1.a) + -> Seq Scan on sl t1 + -> Seq Scan on sl + Filter: ((c IS NOT NULL) AND (a IS NOT NULL) AND (b IS NOT NULL)) +(5 rows) + -- Check optimization disabling if it will violate special join conditions. -- Two identical joined relations satisfies self join removal conditions but -- stay in different special join infos. diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out index f42085e53a0..356f118a366 100644 --- a/src/test/regress/expected/rowsecurity.out +++ b/src/test/regress/expected/rowsecurity.out @@ -536,6 +536,17 @@ NOTICE: f_leak => awesome science fiction 9 | 22 | 1 | regress_rls_dave | awesome science fiction (4 rows) +-- a rel with RLS quals can still be removed by outer-join removal +EXPLAIN (COSTS OFF) +SELECT c.cid FROM category c LEFT JOIN document d ON c.cid = d.did; + QUERY PLAN +---------------------------------------------------- + Seq Scan on category c + InitPlan expr_1 + -> Index Scan using uaccount_pkey on uaccount + Index Cond: (pguser = CURRENT_USER) +(4 rows) + -- viewpoint from regress_rls_carol SET SESSION AUTHORIZATION regress_rls_carol; SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did; diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index c0ff6c945b0..f3ba371b7e4 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -2621,6 +2621,31 @@ where t1.a = s.c; rollback; +-- join removal bug #19560: removing a join can leave an EquivalenceClass that +-- now yields a base restriction clause, so we must redo equivalence +-- processing from scratch +begin; + +create temp table items (id text, owner text); +create temp table follows (item_id text, user_id text, + unique (user_id, item_id)); +insert into items values ('item1', 'alice'); + +explain (costs off) +with viewer as (select 'bob' as id) +select count(*) from items + left join follows on follows.item_id = items.id and follows.user_id = 'bob' + left join viewer on true +where items.owner = viewer.id; + +with viewer as (select 'bob' as id) +select count(*) from items + left join follows on follows.item_id = items.id and follows.user_id = 'bob' + left join viewer on true +where items.owner = viewer.id; + +rollback; + -- check handling of semijoins after join removal: we must suppress -- unique-ification of known-constant values begin; @@ -2887,6 +2912,24 @@ explain (verbose, costs off) select t1.a from sj t1 where t1.b in ( select t2.b from sj t2 join sj t3 on t2.c=t3.c); +-- Check that quals get hoisted to the appropriate join level after SJE removal +explain (verbose, costs off) +select a2.a +from sj b1 + join sj a1 on b1.b = a1.a + join sj a2 on a2.a = a1.a and a2.b = a1.b; + +-- Same, when a semijoin removal happens first +explain (verbose, costs off) +select a1.a from sj b1 join sj a1 on a1.a = b1.b + where exists (select 1 from sj s where s.a = a1.a); + +-- A different case, where modified qual is on a lower join level +explain (verbose, costs off) +select a2.a +from ((sj b1 join sj a1 on true) join sj c1 on c1.b = a1.a) + join sj a2 on a2.a = a1.a and a2.b = a1.b; + -- -- SJE corner case: uniqueness of an inner is [partially] derived from -- baserestrictinfo clauses. @@ -3035,8 +3078,7 @@ select 1 from (select y.* from sj x, sj y where x.a = y.a) q, explain (costs off) select * from sj p join sj q on p.a = q.a left join sj r on p.a + q.a = r.a; --- FIXME this constant false filter doesn't look good. Should we merge --- equivalence classes? +-- Check that we detect constant-false condition after merging ECs. explain (costs off) select * from sj p, sj q where p.a = q.a and p.b = 1 and q.b = 2; @@ -3234,6 +3276,18 @@ EXPLAIN (COSTS OFF) SELECT 1 AS c1 FROM sl sl1 LEFT JOIN (sl AS sl2 NATURAL JOIN sl AS sl3) ON sl2.bool_col LEFT JOIN sl AS sl4 ON sl2.bool_col; +-- Check that quals of a jointree node that becomes empty when the self-join +-- is removed are not lost, and that they don't migrate above an outer join +EXPLAIN (COSTS OFF) +SELECT s.a FROM (SELECT * FROM sl WHERE c IS NOT NULL) s, sl t +WHERE t.a = s.a AND t.b = s.b; + +EXPLAIN (COSTS OFF) +SELECT t1.a, ss.a FROM sl t1 + LEFT JOIN (SELECT s.a FROM (SELECT * FROM sl WHERE c IS NOT NULL) s + JOIN sl t ON t.a = s.a AND t.b = s.b) ss + ON ss.a = t1.a; + -- Check optimization disabling if it will violate special join conditions. -- Two identical joined relations satisfies self join removal conditions but -- stay in different special join infos. diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql index ed70b1b229e..99eaba28f5a 100644 --- a/src/test/regress/sql/rowsecurity.sql +++ b/src/test/regress/sql/rowsecurity.sql @@ -307,6 +307,10 @@ SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did; SELECT * FROM document TABLESAMPLE BERNOULLI(50) REPEATABLE(0) WHERE f_leak(dtitle) ORDER BY did; +-- a rel with RLS quals can still be removed by outer-join removal +EXPLAIN (COSTS OFF) +SELECT c.cid FROM category c LEFT JOIN document d ON c.cid = d.did; + -- viewpoint from regress_rls_carol SET SESSION AUTHORIZATION regress_rls_carol; SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did; diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index bcf981a02a2..bb31ca52c0f 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -430,7 +430,6 @@ CatalogId CatalogIdMapEntry CatalogIndexState ChangeContext -ChangeVarNodes_callback ChangeVarNodes_context ChannelName CheckPoint From 7ddb9c41a13534011bb64a856fb5a60e41b82b75 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Fri, 28 Aug 2026 15:11:06 -0500 Subject: [PATCH 470/481] Fix pg_stat_autovacuum_scores for TOAST tables. In v19, pg_stat_autovacuum_scores computes a TOAST table's scores from its own storage parameters alone. On the other hand, autovacuum falls back to the main table's parameters when the TOAST table has none. This means that the view may report scores that don't match what autovacuum would calculate. This contradicts the documented promise that the view generates its results the same way autovacuum workers do. To fix, teach the view to do the same fallback. As in do_autovacuum(), we must make a preliminary pass over pg_class to collect the main tables' parameters, since the pg_class scan may see TOAST tables before their main tables. Commit fad70a09ff for v20 improved autovacuum's handling of TOAST storage parameters and adjusted the view to match, but it was deemed too intrusive to back-patch. This fix is for v19 only. Oversight in commit 87f61f0c82. Reported-by: Masahiko Sawada Reviewed-by: Masahiko Sawada Discussion: https://postgr.es/m/CAD21AoB1CJRVfCDh8qYuD3eueiygXxk7F3nybgjN0RZXSD-QUw%40mail.gmail.com Backpatch-through: 19 only --- src/backend/postmaster/autovacuum.c | 73 ++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 0c975d0eda6..d7ca8e72444 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -3652,6 +3652,8 @@ pg_stat_get_autovacuum_scores(PG_FUNCTION_ARGS) TableScanDesc scan; HeapTuple tup; ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + HTAB *table_toast_map; + HASHCTL ctl; InitMaterializedSRF(fcinfo, 0); @@ -3660,13 +3662,62 @@ pg_stat_get_autovacuum_scores(PG_FUNCTION_ARGS) recentXid = ReadNextTransactionId(); recentMulti = ReadNextMultiXactId(); - /* scan pg_class */ + /* create hash table for toast <-> main relid mapping */ + ctl.keysize = sizeof(Oid); + ctl.entrysize = sizeof(av_relation); + ctl.hcxt = CurrentMemoryContext; + table_toast_map = hash_create("TOAST to main relid map", + 100, + &ctl, + HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + rel = table_open(RelationRelationId, AccessShareLock); + + /* + * Do an initial pass over pg_class to collect the main relations' + * autovacuum parameters. + */ + scan = table_beginscan_catalog(rel, 0, NULL); + while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + Form_pg_class form = (Form_pg_class) GETSTRUCT(tup); + AutoVacOpts *avopts; + av_relation *hentry; + bool found; + + /* skip ineligible entries */ + if (form->relkind != RELKIND_RELATION && + form->relkind != RELKIND_MATVIEW) + continue; + if (form->relpersistence == RELPERSISTENCE_TEMP) + continue; + if (!OidIsValid(form->reltoastrelid)) + continue; + + avopts = extract_autovac_opts(tup, RelationGetDescr(rel)); + if (avopts == NULL) + continue; + + hentry = hash_search(table_toast_map, &form->reltoastrelid, + HASH_ENTER, &found); + Assert(!found); /* rels cannot share a TOAST table */ + + /* hash_search already filled in the key */ + hentry->ar_relid = form->oid; + hentry->ar_hasrelopts = true; + memcpy(&hentry->ar_reloptions, avopts, sizeof(AutoVacOpts)); + + pfree(avopts); + } + table_endscan(scan); + + /* now scan pg_class again to compute the scores */ scan = table_beginscan_catalog(rel, 0, NULL); while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) { Form_pg_class form = (Form_pg_class) GETSTRUCT(tup); AutoVacOpts *avopts; + bool free_avopts = false; bool dovacuum; bool doanalyze; bool wraparound; @@ -3682,13 +3733,30 @@ pg_stat_get_autovacuum_scores(PG_FUNCTION_ARGS) if (form->relpersistence == RELPERSISTENCE_TEMP) continue; + /* + * fetch reloptions -- if this toast table does not have them, try the + * main rel + */ avopts = extract_autovac_opts(tup, RelationGetDescr(rel)); + if (avopts) + free_avopts = true; + else if (form->relkind == RELKIND_TOASTVALUE) + { + av_relation *hentry; + bool found; + + hentry = hash_search(table_toast_map, &form->oid, + HASH_FIND, &found); + if (found && hentry->ar_hasrelopts) + avopts = &hentry->ar_reloptions; + } + relation_needs_vacanalyze(form->oid, avopts, form, effective_multixact_freeze_max_age, LOG_NEVER, &dovacuum, &doanalyze, &wraparound, &scores); - if (avopts) + if (free_avopts) pfree(avopts); vals[0] = ObjectIdGetDatum(form->oid); @@ -3706,6 +3774,7 @@ pg_stat_get_autovacuum_scores(PG_FUNCTION_ARGS) } table_endscan(scan); table_close(rel, AccessShareLock); + hash_destroy(table_toast_map); return (Datum) 0; } From 4af0528a0e49d06b997c443b044cb013503e1546 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Fri, 28 Aug 2026 23:24:47 +0200 Subject: [PATCH 471/481] Propagate rebalanced cost limit to parallel vacuum workers AutoVacuumUpdateCostLimit() runs after each nap in vacuum_delay_point() and follows av_nworkersForBalance, but the new limit never reached the shared cost params in the vacuum DSM: propagation only required config reload. Parallel workers computed their delays from the stale limit, so a parallel autovacuum could run at up to twice the configured budget (or half of it) until the next SIGHUP, contradicting the propagation promise in maintenance.sgml. Call parallel_vacuum_propagate_shared_delay_params() after rebalancing. Gated on the leader: parallel workers take the same nap path and must not overwrite the shared parameters. This also adds a test to validate the behaviour: pause the leader at the existing injection point, start a second autovacuum worker and hold it at a new injection point placed after it joined the balance, then check the first parameter load of the parallel workers reports the balanced limit. The hold is needed because a second worker left running can finish its own vacuum before the leader resumes, which puts the balance back where it started. Autovacuum is disabled for everything but the two test tables via thresholds, as a worker spawned by catalog churn would get trapped at the hold point and starve the test of its second worker slot. Backpatch to v19 where autovacuum gained the ability to use parallel vacuum workers. Author: Zsolt Parragi Reviewed-by: Bharath Rupireddy Reviewed-by: Masahiko Sawada Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/CAN4CZFOZtEPwGQ6oa9LvHvN522zEp8h_dW9hHExSh7pVXofoKQ@mail.gmail.com Backpatch-through: 19 --- src/backend/commands/vacuum.c | 3 + src/backend/postmaster/autovacuum.c | 1 + .../t/001_parallel_autovacuum.pl | 88 ++++++++++++++++++- 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 38539a6fd3d..c17aecce7ad 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2577,6 +2577,9 @@ vacuum_delay_point(bool is_analyze) */ AutoVacuumUpdateCostLimit(); + if (AmAutoVacuumWorkerProcess()) + parallel_vacuum_propagate_shared_delay_params(); + /* Might have gotten an interrupt while sleeping */ CHECK_FOR_INTERRUPTS(); } diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index d7ca8e72444..3adc26c0764 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2485,6 +2485,7 @@ do_autovacuum(void) */ VacuumUpdateCosts(); + INJECTION_POINT("autovacuum-worker-cost-balanced", NULL); /* clean up memory before each iteration */ MemoryContextReset(PortalContext); diff --git a/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl b/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl index 22f40cb1d50..33c86bbdc94 100644 --- a/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl +++ b/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl @@ -33,10 +33,15 @@ sub prepare_for_next_test # Limit to one autovacuum worker and disable autovacuum logging globally # (enabled only on the test table) so that log checks below match only # activity on the expected table. +# +# Effectively disable autovacuum for all tables except the ones the test +# re-enables via reloptions. A worker spawned by catalog churn would skew +# the cost balance, and an injection point attached below would trap it, +# eating the only free worker slot. $node->append_conf( 'postgresql.conf', qq{ autovacuum_max_workers = 1 -autovacuum_worker_slots = 1 +autovacuum_worker_slots = 2 autovacuum_max_parallel_workers = 2 max_worker_processes = 10 max_parallel_workers = 10 @@ -44,6 +49,9 @@ sub prepare_for_next_test autovacuum_naptime = '1s' min_parallel_index_scan_size = 0 log_autovacuum_min_duration = -1 +autovacuum_vacuum_threshold = 100000 +autovacuum_analyze_threshold = 100000 +autovacuum_vacuum_insert_threshold = -1 }); $node->start; @@ -72,6 +80,7 @@ sub prepare_for_next_test id SERIAL PRIMARY KEY, col_1 INTEGER, col_2 INTEGER, col_3 INTEGER, col_4 INTEGER ) WITH (autovacuum_parallel_workers = $autovacuum_parallel_workers, + autovacuum_vacuum_threshold = 50, log_autovacuum_min_duration = 0); INSERT INTO test_autovac @@ -167,5 +176,82 @@ sub prepare_for_next_test "vacuum delay parameter changes are propagated to parallel vacuum workers" ); +# Test 3: +# Check whether a cost limit rebalance reaches the parallel workers. The +# leader pauses right after taking the shared cost param snapshot +# (balance = 1, limit 500), then a second autovacuum worker joins the +# balance (balance = 2, limit 250) and is held there for the rest of the +# test. After resume, the parallel workers' first parameter load must show +# the rebalanced 250, not the snapshotted 500. + +# Second worker's table lives in another database: no cost reloptions, so it +# participates in balancing. +$node->safe_psql('postgres', 'CREATE DATABASE regress_db2'); +$node->safe_psql( + 'regress_db2', qq{ + CREATE TABLE filler (id int) + WITH (autovacuum_enabled = false, autovacuum_vacuum_threshold = 50); + INSERT INTO filler SELECT g FROM generate_series(1, 1000) g; +}); + +# Allow a second autovacuum worker. +$node->safe_psql( + 'postgres', qq{ + ALTER SYSTEM SET autovacuum_max_workers = 2; + SELECT pg_reload_conf(); +}); + +prepare_for_next_test($node, 3); +$node->safe_psql('regress_db2', 'UPDATE filler SET id = id + 1'); + +my $db2oid = $node->safe_psql('postgres', + "SELECT oid FROM pg_database WHERE datname = 'regress_db2'"); +my $filleroid = + $node->safe_psql('regress_db2', "SELECT 'filler'::regclass::oid"); + +$log_offset = -s $node->logfile; + +# Pause the leader after the shared cost param snapshot. The leader is past +# the hold point below by then, so that one only catches the second worker. +$node->safe_psql('postgres', + "SELECT injection_points_attach('autovacuum-start-parallel-vacuum', 'wait')" +); +$node->safe_psql('postgres', + 'ALTER TABLE test_autovac SET (autovacuum_enabled = true)'); +$node->wait_for_event('autovacuum worker', + 'autovacuum-start-parallel-vacuum'); + +# Second worker -> balance = 2. Hold it there: if it were allowed to finish, +# the balance would drop back to 1 before the leader resumes. +$node->safe_psql('postgres', + "SELECT injection_points_attach('autovacuum-worker-cost-balanced', 'wait')" +); +$node->safe_psql('regress_db2', + 'ALTER TABLE filler SET (autovacuum_enabled = true)'); +$node->wait_for_log( + qr/VacuumUpdateCosts\(db=$db2oid, rel=$filleroid, dobalance=yes, cost_limit=250,/, + $log_offset); + +$node->safe_psql('postgres', + "SELECT injection_points_wakeup('autovacuum-start-parallel-vacuum')"); +$node->safe_psql('postgres', + "SELECT injection_points_detach('autovacuum-start-parallel-vacuum')"); + +# First param load must show the rebalanced limit. +$node->wait_for_log( + qr/parallel autovacuum worker updated cost params: cost_limit=\d+,/, + $log_offset); +my $log = slurp_file($node->logfile, $log_offset); +my @limits = + $log =~ /parallel autovacuum worker updated cost params: cost_limit=(\d+),/g; +note("parallel worker cost_limit sequence: @limits"); +is($limits[0], '250', 'parallel workers see the rebalanced cost limit'); + +# Release the second worker. +$node->safe_psql('postgres', + "SELECT injection_points_wakeup('autovacuum-worker-cost-balanced')"); +$node->safe_psql('postgres', + "SELECT injection_points_detach('autovacuum-worker-cost-balanced')"); + $node->stop; done_testing(); From f23de46e15ba3faf38a97915df29ae98a472a16b Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Sat, 29 Aug 2026 10:23:23 -0500 Subject: [PATCH 472/481] Disallow ONLY in REPACK commands. The REPACK grammar accepts ONLY before the table name and * after the table name, but that's neither documented nor handled in the code. Perhaps REPACK should support that syntax, but for now let's just bring it in line with its documentation. Oversight in commit ac58465e06. Reviewed-by: Antonin Houska Discussion: https://postgr.es/m/apBTsWGwkLXVh8Ow%40nathan Backpatch-through: 19 --- src/backend/parser/gram.y | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 091d4423592..be4f16f958a 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -12532,25 +12532,25 @@ CreateConversionStmt: *****************************************************************************/ RepackStmt: - REPACK opt_utility_option_list vacuum_relation USING INDEX name + REPACK opt_utility_option_list qualified_name opt_name_list USING INDEX name { RepackStmt *n = makeNode(RepackStmt); n->command = REPACK_COMMAND_REPACK; - n->relation = (VacuumRelation *) $3; - n->indexname = $6; + n->relation = makeVacuumRelation($3, InvalidOid, $4); + n->indexname = $7; n->usingindex = true; n->params = $2; $$ = (Node *) n; } - | REPACK opt_utility_option_list vacuum_relation opt_usingindex + | REPACK opt_utility_option_list qualified_name opt_name_list opt_usingindex { RepackStmt *n = makeNode(RepackStmt); n->command = REPACK_COMMAND_REPACK; - n->relation = (VacuumRelation *) $3; + n->relation = makeVacuumRelation($3, InvalidOid, $4); n->indexname = NULL; - n->usingindex = $4; + n->usingindex = $5; n->params = $2; $$ = (Node *) n; } From 50daffb0665e31ba9e223e3c9106a49f2c44eab5 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 29 Aug 2026 19:56:49 -0400 Subject: [PATCH 473/481] Harden spell.c against out-of-order FLAG lines in Hunspell files. The compound flags collected from COMPOUNDFLAG and friends are stored in either the string or the integer member of a union, according to the flag mode that the affix file's FLAG line declares. NIImportOOAffixes() converted each flag as soon as it read it, using the mode in effect at that point, and recorded that mode in the entry. Since FLAG may appear anywhere in the file, including after the compound flags, entries written before and after it could disagree about which member of the union holds the flag. In assert-enabled builds, this would result in an assertion failure. Otherwise, cmpcmdflag() takes the mode from its first argument and applies it to both, so it can read an integer as a char pointer and pass that to strcmp(). Depending on which way the mismatch goes, the result is a segfault while sorting the array, a segfault in the bsearch() that later looks flags up (the lookup key is built with the final mode, so this happens even when the array itself is consistent), or, when both members happen to be readable, no crash at all and a compound flag that is never found, which silently disables compound word splitting. This isn't a security bug because we consider dictionary files to be trusted data, but it's still worth fixing. (In practice, dictionary files usually put the FLAG line first, which is why this went unreported for so long.) Fix by keeping the flags as strings while the file is read and converting them once it has been read in full, when the mode is final. This also makes the position of the FLAG line irrelevant, which is how the flags on AF, SFX and PFX lines are already treated: those are parsed in a second pass and so always use the final mode. That precedent is reason for behaving this way rather than throwing an error. The old ispell file format reaches addCompoundAffixFlagValue() too, from NIImportAffixes(), and returns without entering NIImportOOAffixes(), so it needs the conversion step as well. While we're here, also fix some integer width mismatches: store the result of strtol() into a "long", and cast to int only after we've done range checks. Typically a value too wide for int would fail the range checks anyway, but in some cases it would be silently accepted after truncation to int. Author: Ewan Young Reviewed-by: Tom Lane Discussion: https://postgr.es/m/CAON2xHN3QmsaySM6DGWa1gttcbJoFh0wjAE-_ZpSPo=LKN1hYw@mail.gmail.com Backpatch-through: 14 --- src/backend/tsearch/spell.c | 115 +++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 27 deletions(-) diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c index 8ada640f988..c7563da0ef9 100644 --- a/src/backend/tsearch/spell.c +++ b/src/backend/tsearch/spell.c @@ -349,7 +349,7 @@ cmpaffix(const void *s1, const void *s2) static void getNextFlagFromString(IspellDict *Conf, const char **sflagset, char *sflag) { - int32 s; + long sval; char *next; const char *sbuf = *sflagset; int maxstep; @@ -377,17 +377,17 @@ getNextFlagFromString(IspellDict *Conf, const char **sflagset, char *sflag) break; case FM_NUM: errno = 0; - s = strtol(*sflagset, &next, 10); + sval = strtol(*sflagset, &next, 10); if (*sflagset == next || errno == ERANGE) ereport(ERROR, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("invalid affix flag \"%s\"", *sflagset))); - if (s < 0 || s > FLAGNUM_MAXSIZE) + if (sval < 0 || sval > FLAGNUM_MAXSIZE) ereport(ERROR, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("affix flag \"%s\" is out of range", *sflagset))); - sflag += sprintf(sflag, "%0d", s); + sflag += sprintf(sflag, "%0d", (int) sval); /* Go to start of the next flag */ *sflagset = next; @@ -1033,31 +1033,41 @@ parse_affentry(const char *str, char *mask, char *find, char *repl) return (*mask && (*find || *repl)); } +/* + * Parse an affix flag written in the "num" flag mode. + */ +static uint32 +parseNumericAffixFlag(const char *s) +{ + char *next; + long i; + + errno = 0; + i = strtol(s, &next, 10); + if (s == next || errno == ERANGE) + ereport(ERROR, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("invalid affix flag \"%s\"", s))); + if (i < 0 || i > FLAGNUM_MAXSIZE) + ereport(ERROR, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("affix flag \"%s\" is out of range", s))); + + return (uint32) i; +} + /* * Sets a Hunspell options depending on flag type. + * + * Conf->flagMode must already have its final value, since it decides which + * member of the entry's union is written. See finalizeCompoundAffixFlags(). */ static void setCompoundAffixFlagValue(IspellDict *Conf, CompoundAffixFlag *entry, - char *s, uint32 val) + const char *s, uint32 val) { if (Conf->flagMode == FM_NUM) - { - char *next; - int i; - - errno = 0; - i = strtol(s, &next, 10); - if (s == next || errno == ERANGE) - ereport(ERROR, - (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("invalid affix flag \"%s\"", s))); - if (i < 0 || i > FLAGNUM_MAXSIZE) - ereport(ERROR, - (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("affix flag \"%s\" is out of range", s))); - - entry->flag.i = i; - } + entry->flag.i = parseNumericAffixFlag(s); else entry->flag.s = cpstrdup(Conf, s); @@ -1120,12 +1130,54 @@ addCompoundAffixFlagValue(IspellDict *Conf, const char *s, uint32 val) newValue = Conf->CompoundAffixFlags + Conf->nCompoundAffixFlag; - setCompoundAffixFlagValue(Conf, newValue, sbuf, val); + /* + * Only remember the flag as a string for now. The FLAG option that says + * how flags are spelled may appear anywhere in the affix file, including + * after the compound flags themselves, so the final representation cannot + * be chosen until the whole file has been read. See + * finalizeCompoundAffixFlags(), which fills in flagMode as well. + * + * The interim copy goes in the short-lived build context, since the final + * representation may well not be a string at all. + */ + newValue->flag.s = MemoryContextStrdup(Conf->buildCxt, sbuf); + newValue->value = val; Conf->usecompound = true; Conf->nCompoundAffixFlag++; } +/* + * Convert the compound flags collected by addCompoundAffixFlagValue() to the + * representation implied by the flag mode the affix file ended up declaring. + * + * This must run before the flags are sorted or searched. Doing the conversion + * here rather than while reading the file makes the position of the FLAG line + * irrelevant, which is how the flags on AF, SFX and PFX lines are already + * treated: those are parsed in a second pass over the file, and so always use + * the final flag mode. + */ +static void +finalizeCompoundAffixFlags(IspellDict *Conf) +{ + for (int i = 0; i < Conf->nCompoundAffixFlag; i++) + { + CompoundAffixFlag *entry = Conf->CompoundAffixFlags + i; + + /* + * Replace the interim string with the representation the flag mode + * calls for. In both cases the old value is read before the new one + * is stored, so overwriting the union in place is safe. + */ + if (Conf->flagMode == FM_NUM) + entry->flag.i = parseNumericAffixFlag(entry->flag.s); + else + entry->flag.s = cpstrdup(Conf, entry->flag.s); + + entry->flagMode = Conf->flagMode; + } +} + /* * Returns a set of affix parameters which correspondence to the set of affix * flags s. @@ -1171,7 +1223,7 @@ getAffixFlagSet(IspellDict *Conf, char *s) { if (Conf->useFlagAliases && *s != '\0') { - int curaffix; + long curaffix; char *end; errno = 0; @@ -1302,6 +1354,9 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename) } tsearch_readline_end(&trst); + /* Conf->flagMode is final now, so the compound flags can be converted */ + finalizeCompoundAffixFlags(Conf); + if (Conf->nCompoundAffixFlag > 1) qsort(Conf->CompoundAffixFlags, Conf->nCompoundAffixFlag, sizeof(CompoundAffixFlag), cmpcmdflag); @@ -1576,6 +1631,12 @@ NIImportAffixes(IspellDict *Conf, const char *filename) pfree(pstr); } tsearch_readline_end(&trst); + + /* + * The old file format has no FLAG command, so the mode is still FM_CHAR + * here, but the flags collected above must be converted all the same. + */ + finalizeCompoundAffixFlags(Conf); return; isnewformat: @@ -1749,7 +1810,7 @@ NISortDictionary(IspellDict *Conf) { int i; int naffix; - int curaffix; + long curaffix; /* compress affixes */ @@ -1792,7 +1853,7 @@ NISortDictionary(IspellDict *Conf) curaffix = 0; } - Conf->Spell[i]->p.d.affix = curaffix; + Conf->Spell[i]->p.d.affix = (int) curaffix; Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word); } } @@ -1830,7 +1891,7 @@ NISortDictionary(IspellDict *Conf) Conf->Spell[i]->p.flag); } - Conf->Spell[i]->p.d.affix = curaffix; + Conf->Spell[i]->p.d.affix = (int) curaffix; Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word); } From efc3db99c41192be5bbce20be2199448ec227572 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Sun, 30 Aug 2026 09:13:09 -0500 Subject: [PATCH 474/481] doc: Mark up "option" in the CHECKPOINT synopsis. Oversight in commit a4f126516e. Backpatch-through: 19 --- doc/src/sgml/ref/checkpoint.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/ref/checkpoint.sgml b/doc/src/sgml/ref/checkpoint.sgml index 4d39610851d..c2057dacf9b 100644 --- a/doc/src/sgml/ref/checkpoint.sgml +++ b/doc/src/sgml/ref/checkpoint.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -CHECKPOINT [ ( option [, ...] ) ] +CHECKPOINT [ ( option [, ...] ) ] where option can be one of: From 59335b5e71d552229f74ac41f3ef6b5a4d966535 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Sun, 30 Aug 2026 09:40:40 -0500 Subject: [PATCH 475/481] doc: Fix the data type named in the regdatabase entry. Oversight in commit b45137f315. Backpatch-through: 19 only --- doc/src/sgml/release-19.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/release-19.sgml b/doc/src/sgml/release-19.sgml index 2cb8d4da3fe..ba85e9140ec 100644 --- a/doc/src/sgml/release-19.sgml +++ b/doc/src/sgml/release-19.sgml @@ -2209,7 +2209,7 @@ Author: Nathan Bossart -Add ability to cast between database names and oid8s using regdatabase (Ian Lawrence Barwick) +Add ability to cast between database names and oids using regdatabase (Ian Lawrence Barwick) § From 4186d7169b068a3f248e9795702d41ea9842a954 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 31 Aug 2026 12:07:07 -0500 Subject: [PATCH 476/481] doc: Drop stale note about extension LWLock names. Oversight in commit 38b602b028. Backpatch-through: 19 --- doc/src/sgml/monitoring.sgml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 66f6127a410..b5fe179d9ab 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -1206,11 +1206,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage Extensions can add Extension, InjectionPoint, and LWLock events to the lists shown in and - . In some cases, the name - of an LWLock assigned by an extension will not be - available in all server processes. It might be reported as just - extension rather than the - extension-assigned name. + . From 347486775812573f09c79e1f4d26d1f7506d261f Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 31 Aug 2026 12:34:24 -0500 Subject: [PATCH 477/481] doc: Fix link on pg_dsm_registry_allocations page. Oversight in commit 283e823f9d. Backpatch-through: 19 --- doc/src/sgml/system-views.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml index 2ebec6928d5..d066a1a74db 100644 --- a/doc/src/sgml/system-views.sgml +++ b/doc/src/sgml/system-views.sgml @@ -1135,7 +1135,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; The pg_dsm_registry_allocations view shows shared memory allocations tracked in the dynamic shared memory (DSM) registry. This includes memory allocated by extensions using the mechanisms detailed - in . + in .
    From ca8d4bdb047f97f00f03915bcd5fcb3d89534027 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 1 Sep 2026 08:12:38 +0900 Subject: [PATCH 478/481] Fix comment in attribute_stats.c Oversight in ce207d2a7901. Author: Corey Huinker Discussion: https://postgr.es/m/CADkLM=eo7MtuCE=YjovW+=ASw1=q39qQ3qarrsw+EKfU901ztA@mail.gmail.com Backpatch-through: 18 --- src/backend/statistics/attribute_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c index e65c8dac4a4..5649d01ebe7 100644 --- a/src/backend/statistics/attribute_stats.c +++ b/src/backend/statistics/attribute_stats.c @@ -249,8 +249,8 @@ attribute_statistics_update_internal(Oid reloid, bool result = true; /* - * Check argument sanity. If some arguments are unusable, emit a WARNING - * and set the corresponding argument to NULL in fcinfo. + * Check argument sanity. If some arguments are unusable, emit a WARNING + * and skip the corresponding statistics kind, reporting back a failure. */ if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_FREQS_ARG)) From 9efc2f9d8964ec927ccdeb4d461ff8070b0e6255 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Tue, 1 Sep 2026 11:42:13 +0900 Subject: [PATCH 479/481] Fix integer to_char() overflow with V format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When to_char() formatted an integer value with a V pattern, it could return an incorrect result instead of reporting an overflow. V shifts the decimal point by multiplying the input value by a power of ten before formatting it, so, for example, to_char(3, '9V999999999') requires computing 3 * 10^9. This result does not fit in int4, but the integer variant of to_char() performed the multiplication using a plain int32 expression. The intermediate result could therefore overflow, causing the function to output incorrect digits instead of raising "integer out of range". Use dtoi4() and int4mul() for this calculation so that both an out-of-range multiplier and an out-of-range product are detected, as with ordinary integer arithmetic. This also matches the existing int8 implementation, which uses dtoi8() and int8mul() for the same operation. After this change, to_char() with V format either returns the correctly formatted result when the scaled value fits in int4, or raises "integer out of range" when it does not. Backpatch to all supported versions. Reported-by: Andrey Rachitskiy Author: Andrey Rachitskiy Reviewed-by: Miłosz Bieniek Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CAB8bMivEfqZxOVdzc3kZDN++XshmkEz2t7dfGBU8+oUm864EZg@mail.gmail.com Backpatch-through: 14 --- src/backend/utils/adt/formatting.c | 16 +++++++++------- src/test/regress/expected/int4.out | 27 +++++++++++++++++++++++++++ src/test/regress/sql/int4.sql | 9 +++++++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index effad4c37dd..ef5ec3227a1 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -6616,15 +6616,17 @@ int4_to_char(PG_FUNCTION_ARGS) if (IS_MULTI(&Num)) { - orgnum = DatumGetCString(DirectFunctionCall1(int4out, - Int32GetDatum(value * ((int32) pow((double) 10, (double) Num.multi))))); + double multi = pow((double) 10, (double) Num.multi); + + value = DatumGetInt32(DirectFunctionCall2(int4mul, + Int32GetDatum(value), + DirectFunctionCall1(dtoi4, + Float8GetDatum(multi)))); Num.pre += Num.multi; } - else - { - orgnum = DatumGetCString(DirectFunctionCall1(int4out, - Int32GetDatum(value))); - } + + orgnum = DatumGetCString(DirectFunctionCall1(int4out, + Int32GetDatum(value))); if (*orgnum == '-') { diff --git a/src/test/regress/expected/int4.out b/src/test/regress/expected/int4.out index b1a15888ef8..fca591fad84 100644 --- a/src/test/regress/expected/int4.out +++ b/src/test/regress/expected/int4.out @@ -370,6 +370,33 @@ SELECT (-2147483648)::int4 % (-1)::int2; 0 (1 row) +-- check overflow of to_char() with V format +SELECT to_char(2, '9V999999999'); -- 10^9 + to_char +------------- + 2000000000 +(1 row) + +SELECT to_char(3, '9V999999999'); -- 10^9 +ERROR: integer out of range +SELECT to_char(214748364, '999999999V9'); + to_char +------------- + 2147483640 +(1 row) + +SELECT to_char(2147483647, '9V9'); +ERROR: integer out of range +SELECT to_char(-2, '9V999999999'); -- 10^9 + to_char +------------- + -2000000000 +(1 row) + +SELECT to_char((-2147483648)::int4, '9V9'); +ERROR: integer out of range +SELECT to_char(1, '9V9999999999'); -- 10^10 +ERROR: integer out of range -- check rounding when casting from float SELECT x, x::int4 AS int4_value FROM (VALUES (-2.5::float8), diff --git a/src/test/regress/sql/int4.sql b/src/test/regress/sql/int4.sql index e9d89e8111f..d27f5500e01 100644 --- a/src/test/regress/sql/int4.sql +++ b/src/test/regress/sql/int4.sql @@ -126,6 +126,15 @@ SELECT (-2147483648)::int4 * (-1)::int2; SELECT (-2147483648)::int4 / (-1)::int2; SELECT (-2147483648)::int4 % (-1)::int2; +-- check overflow of to_char() with V format +SELECT to_char(2, '9V999999999'); -- 10^9 +SELECT to_char(3, '9V999999999'); -- 10^9 +SELECT to_char(214748364, '999999999V9'); +SELECT to_char(2147483647, '9V9'); +SELECT to_char(-2, '9V999999999'); -- 10^9 +SELECT to_char((-2147483648)::int4, '9V9'); +SELECT to_char(1, '9V9999999999'); -- 10^10 + -- check rounding when casting from float SELECT x, x::int4 AS int4_value FROM (VALUES (-2.5::float8), From 07df2b253277321d68d515615ec6c0a3d70ec591 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Tue, 1 Sep 2026 12:54:31 +0900 Subject: [PATCH 480/481] doc: reformat GRAPH_TABLE examples The GRAPH_TABLE examples in ddl.sgml and queries.sgml were written as single long lines, making their structure harder to read in the generated documentation. Reformat these examples so that the graph name, MATCH clause, and COLUMNS clause appear on separate lines, making them easier to read. Author: Koshino Taiki Reviewed-by: Ashutosh Bapat Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/OS9P286MB64860BD6CD6D4B4B0E1CEDE894A32@OS9P286MB6486.JPNP286.PROD.OUTLOOK.COM Backpatch-through: 19 --- doc/src/sgml/ddl.sgml | 12 +++++++++--- doc/src/sgml/queries.sgml | 13 +++++++++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index 291545ee008..b70924f6e16 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -5788,7 +5788,9 @@ CREATE PROPERTY GRAPH myshop This graph could then be queried like this: -- get list of customers active today -SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers)-[IS customer_orders]->(o IS orders WHERE o.ordered_when = current_date) COLUMNS (c.name AS customer_name)); +SELECT customer_name FROM GRAPH_TABLE (myshop + MATCH (c IS customers)-[IS customer_orders]->(o IS orders WHERE o.ordered_when = current_date) + COLUMNS (c.name AS customer_name)); corresponding approximately to this relational query: @@ -5852,7 +5854,9 @@ CREATE PROPERTY GRAPH myshop With this definition, we can write a query like this: -SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customer)-[IS has_placed]->(o IS "order" WHERE o.ordered_when = current_date) COLUMNS (c.name AS customer_name)); +SELECT customer_name FROM GRAPH_TABLE (myshop + MATCH (c IS customer)-[IS has_placed]->(o IS "order" WHERE o.ordered_when = current_date) + COLUMNS (c.name AS customer_name)); With the new labels the MATCH clause is now more intuitive. @@ -5891,7 +5895,9 @@ CREATE PROPERTY GRAPH myshop employees table to something, but it is allowed like this.) Then we can run a query like this (incomplete): -SELECT ... FROM GRAPH_TABLE (myshop MATCH (IS person WHERE name = '...')-[]->... COLUMNS (...)); +SELECT ... FROM GRAPH_TABLE (myshop + MATCH (IS person WHERE name = '...')-[]->... + COLUMNS (...)); This would automatically consider both the customers and the employees tables when looking for an edge with the diff --git a/doc/src/sgml/queries.sgml b/doc/src/sgml/queries.sgml index 3d729f983b5..bd1497ff80d 100644 --- a/doc/src/sgml/queries.sgml +++ b/doc/src/sgml/queries.sgml @@ -2768,7 +2768,9 @@ SELECT * FROM t; Consider this example from : -- get list of customers active today -SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers)-[IS customer_orders]->(o IS orders WHERE o.ordered_when = current_date) COLUMNS (c.name AS customer_name)); +SELECT customer_name FROM GRAPH_TABLE (myshop + MATCH (c IS customers)-[IS customer_orders]->(o IS orders WHERE o.ordered_when = current_date) + COLUMNS (c.name AS customer_name)); The graph query part happens inside the GRAPH_TABLE construct. As far as the rest of the query is concerned, this acts like a @@ -2777,7 +2779,9 @@ SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers)-[IS custome names can be assigned to the result, and the result can be joined with other tables, subsequently filtered, and so on, for example: -SELECT ... FROM GRAPH_TABLE (mygraph MATCH ... COLUMNS (...)) AS myresult (a, b, c) JOIN othertable USING (a) WHERE b > 0 ORDER BY c; +SELECT ... FROM GRAPH_TABLE (mygraph + MATCH ... + COLUMNS (...)) AS myresult (a, b, c) JOIN othertable USING (a) WHERE b > 0 ORDER BY c; @@ -2893,8 +2897,9 @@ SELECT ... FROM GRAPH_TABLE (mygraph MATCH ... COLUMNS (...)) AS myresult (a, b, For example (assuming appropriate definitions of the property graph as well as the underlying tables): -GRAPH_TABLE (mygraph MATCH (p IS person)-[h IS has]->(a IS account) - COLUMNS (p.name AS person_name, h.since AS has_account_since, a.num AS account_number) +GRAPH_TABLE (mygraph + MATCH (p IS person)-[h IS has]->(a IS account) + COLUMNS (p.name AS person_name, h.since AS has_account_since, a.num AS account_number)) WHERE clauses can be used inside element patterns to filter matches: From 11eb68ea7e8985b327a5a11fc9c25aac48f05d7b Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Fri, 28 Aug 2026 13:27:47 +0900 Subject: [PATCH 481/481] Remove batching from the RI fast-path FK check Commit b7b27eb41a5 added batching on top of the direct-index fast path for foreign key checks introduced by 2da86c1ef9b: FK rows are buffered and probed in groups using SK_SEARCHARRAY, rather than probed one at a time. This removes that layer and leaves the per-row fast path in place. The batching was proposed late in the v19 cycle and its transactional design was completed after feature freeze. The four most recent commits touching it -- 3b70fa6f3d3, f3a52a229ad, d2a710c7e9e and 268958a2e5f -- are not fixes to settled code; they are the state model itself, establishing how a batch relates to a subtransaction and to a trigger firing cycle. The open crash where SET CONSTRAINTS ... IMMEDIATE issued from a trigger body walks the after-trigger event list re-entrantly while an outer batch is live is a defect in the most recent of them. The concern is not the number of follow-up fixes but that new transaction and trigger states were still being identified weeks before release, in a code path whose failure mode is a foreign key check that is buffered and never performed. That produces an INSERT that succeeds and a row that violates its constraint permanently, with no error at any point. Testing can show that the states we have enumerated behave correctly; it cannot show the enumeration is complete, and the commit history suggests it is not yet. Removed: ri_FastPathBatchAdd(), ri_FastPathBatchFlush(), ri_FastPathFlushArray(), ri_FastPathFlushLoop(), ri_FastPathGetEntry(), ri_FastPathEndBatch(), ri_FastPathTeardown(), the RI_FastPathEntry and RI_FastPathKey structures, the fast-path entry cache and its in-flush flag, and AtEOSubXact_RI(), which existed only to drop cache entries belonging to an aborting subtransaction. Retained: the per-row fast path (ri_FastPathCheck(), ri_FastPathProbeOne(), ri_LockPKTuple(), recheck_matched_pk_tuple()) and every fix to it -- 68ace967c16 (domain-typed FK columns), 8c0aa08c159 (btree-only referenced indexes), 18a15b96738 and abca12838fe (fast-path metadata lifetime), and the nullable-referenced-key handling from a05ece57b16, whose ri_FastPathFlushArray() site goes with the flush function while its recheck_matched_pk_tuple() site remains. AtEOXact_RI() is retained but reduced to releasing FastPathMeta objects detached by InvalidateConstraintCacheCallBack(); its cache-not-flushed warning has no subject once the cache is gone. In trigger.c, everything the batching used was introduced for it: at 2da86c1ef9b -- the fast path without batching -- afterTriggers.firing_depth, AfterTriggerIsActive(), AfterTriggerCurrentQueryDepth(), the batch callback list and AfterTriggerBatchCallback do not exist, and none of them exist in v18 either. So all of it goes, including the subtransaction-end restore added by f3a52a229ad, which restores firing_depth and firing_batch_callbacks and has no subject once neither field exists. AfterTriggerFireDeferred()'s loop is restored to its pre-batching form. b7b27eb41a5 removed its "all fired" break so that events queued by a batch callback would be seen on the next iteration; with no callbacks to run inside the loop, the break comes back. Batching remains a reasonable optimisation and should be revisited for v20, developed over a full cycle. --- src/backend/access/transam/xact.c | 2 - src/backend/commands/trigger.c | 206 +----- src/backend/utils/adt/ri_triggers.c | 930 ++-------------------------- src/include/commands/trigger.h | 24 - 4 files changed, 40 insertions(+), 1122 deletions(-) diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 9e2d507c8a9..3a89149016f 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -5245,7 +5245,6 @@ CommitSubTransaction(void) s->parent->subTransactionId); AtEOSubXact_HashTables(true, s->nestingLevel); AtEOSubXact_PgStat(true, s->nestingLevel); - AtEOSubXact_RI(true, s->subTransactionId, s->parent->subTransactionId); AtSubCommit_Snapshot(s->nestingLevel); /* @@ -5420,7 +5419,6 @@ AbortSubTransaction(void) s->parent->subTransactionId); AtEOSubXact_HashTables(false, s->nestingLevel); AtEOSubXact_PgStat(false, s->nestingLevel); - AtEOSubXact_RI(false, s->subTransactionId, s->parent->subTransactionId); AtSubAbort_Snapshot(s->nestingLevel); } diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 911045b9b9d..2555cbb015d 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -3905,18 +3905,6 @@ typedef struct AfterTriggersData /* per-subtransaction-level data: */ AfterTriggersTransData *trans_stack; /* array of structs shown below */ int maxtransdepth; /* allocated len of above array */ - - List *batch_callbacks; /* List of AfterTriggerCallbackItem; for - * deferred constraints */ - bool firing_batch_callbacks; /* true when in - * FireAfterTriggerBatchCallbacks() */ - - /* - * Incremented around the trigger-firing loops in AfterTriggerEndQuery, - * AfterTriggerFireDeferred, and AfterTriggerSetState. Used by - * AfterTriggerIsActive() to signal that after-trigger firing is active. - */ - int firing_depth; } AfterTriggersData; struct AfterTriggersQueryData @@ -3924,7 +3912,6 @@ struct AfterTriggersQueryData AfterTriggerEventList events; /* events pending from this query */ Tuplestorestate *fdw_tuplestore; /* foreign tuples for said events */ List *tables; /* list of AfterTriggersTableData, see below */ - List *batch_callbacks; /* List of AfterTriggerCallbackItem */ }; struct AfterTriggersTransData @@ -3933,8 +3920,6 @@ struct AfterTriggersTransData SetConstraintState state; /* saved S C state, or NULL if not yet saved */ AfterTriggerEventList events; /* saved list pointer */ int query_depth; /* saved query_depth */ - int firing_depth; /* saved firing_depth */ - bool firing_batch_callbacks; /* saved firing_batch_callbacks */ CommandId firing_counter; /* saved firing_counter */ }; @@ -3956,13 +3941,6 @@ struct AfterTriggersTableData TupleTableSlot *storeslot; /* for converting to tuplestore's format */ }; -/* Entry in afterTriggers.batch_callbacks */ -typedef struct AfterTriggerCallbackItem -{ - AfterTriggerBatchCallback callback; - void *arg; -} AfterTriggerCallbackItem; - static AfterTriggersData afterTriggers; static void AfterTriggerExecute(EState *estate, @@ -3998,7 +3976,6 @@ static SetConstraintState SetConstraintStateAddItem(SetConstraintState state, Oid tgoid, bool tgisdeferred); static void cancel_prior_stmt_triggers(Oid relid, CmdType cmdType, int tgevent); -static void FireAfterTriggerBatchCallbacks(List *callbacks); /* * Get the FDW tuplestore for the current trigger query level, creating it @@ -5124,9 +5101,6 @@ AfterTriggerBeginXact(void) */ afterTriggers.firing_counter = (CommandId) 1; /* mustn't be 0 */ afterTriggers.query_depth = -1; - afterTriggers.firing_depth = 0; - afterTriggers.batch_callbacks = NIL; - afterTriggers.firing_batch_callbacks = false; /* * Verify that there is no leftover state remaining. If these assertions @@ -5211,7 +5185,6 @@ AfterTriggerEndQuery(EState *estate) */ qs = &afterTriggers.query_stack[afterTriggers.query_depth]; - afterTriggers.firing_depth++; for (;;) { if (afterTriggerMarkEvents(&qs->events, &afterTriggers.events, true)) @@ -5249,23 +5222,10 @@ AfterTriggerEndQuery(EState *estate) break; } - /* - * Fire batch callbacks before releasing query-level storage and before - * decrementing query_depth. Callbacks may do real work (index probes, - * error reporting). - * - * Recompute qs first: the loop above refreshes it after each - * afterTriggerInvokeEvents() call (see comment there), but the "all - * fired" break exits without doing so, leaving qs potentially stale here. - */ - qs = &afterTriggers.query_stack[afterTriggers.query_depth]; - FireAfterTriggerBatchCallbacks(qs->batch_callbacks); - /* Release query-level-local storage, including tuplestores if any */ AfterTriggerFreeQuery(&afterTriggers.query_stack[afterTriggers.query_depth]); afterTriggers.query_depth--; - afterTriggers.firing_depth--; } @@ -5322,9 +5282,6 @@ AfterTriggerFreeQuery(AfterTriggersQueryData *qs) */ qs->tables = NIL; list_free_deep(tables); - - list_free_deep(qs->batch_callbacks); - qs->batch_callbacks = NIL; } @@ -5364,34 +5321,17 @@ AfterTriggerFireDeferred(void) * Run all the remaining triggers. Loop until they are all gone, in case * some trigger queues more for us to do. */ - afterTriggers.firing_depth++; while (afterTriggerMarkEvents(events, NULL, false)) { CommandId firing_id = afterTriggers.firing_counter++; - (void) afterTriggerInvokeEvents(events, firing_id, NULL, true); - - /* - * Flush any fast-path FK-check batches accumulated by the triggers - * just fired. A batch callback runs user-supplied cast or equality - * functions, whose DML can queue further deferred trigger events. - * Flush inside the loop so afterTriggerMarkEvents() sees any such - * events on the next iteration and fires them; flushing after the - * loop would leave them unfired, silently skipping e.g. a deferred FK - * check and letting a violating row commit. (The former "all fired" - * break is therefore gone: the loop now terminates only when - * afterTriggerMarkEvents() finds nothing left, including events - * queued by the flush.) - */ - FireAfterTriggerBatchCallbacks(afterTriggers.batch_callbacks); + if (afterTriggerInvokeEvents(events, firing_id, NULL, true)) + break; /* all fired */ } - afterTriggers.firing_depth--; - /* - * We don't bother freeing the event list or batch_callbacks, since they - * will go away anyway (and more efficiently than via pfree) in - * AfterTriggerEndXact. + * We don't bother freeing the event list, since it will go away anyway + * (and more efficiently than via pfree) in AfterTriggerEndXact. */ if (snap_pushed) @@ -5453,12 +5393,6 @@ AfterTriggerEndXact(bool isCommit) /* No more afterTriggers manipulation until next transaction starts. */ afterTriggers.query_depth = -1; - - afterTriggers.firing_depth = 0; - - list_free_deep(afterTriggers.batch_callbacks); - afterTriggers.batch_callbacks = NIL; - afterTriggers.firing_batch_callbacks = false; } /* @@ -5506,9 +5440,6 @@ AfterTriggerBeginSubXact(void) afterTriggers.trans_stack[my_level].state = NULL; afterTriggers.trans_stack[my_level].events = afterTriggers.events; afterTriggers.trans_stack[my_level].query_depth = afterTriggers.query_depth; - afterTriggers.trans_stack[my_level].firing_depth = afterTriggers.firing_depth; - afterTriggers.trans_stack[my_level].firing_batch_callbacks = - afterTriggers.firing_batch_callbacks; afterTriggers.trans_stack[my_level].firing_counter = afterTriggers.firing_counter; } @@ -5608,29 +5539,6 @@ AfterTriggerEndSubXact(bool isCommit) } } } - - /* - * Restore firing_depth and firing_batch_callbacks to their values at - * subtransaction start. The matching decrement of firing_depth in - * AfterTriggerEndQuery()/AfterTriggerFireDeferred(), and the clearing of - * firing_batch_callbacks in FireAfterTriggerBatchCallbacks(), run after - * their loops and are not protected by PG_FINALLY. A trigger or batch - * callback error caught by this subtransaction can therefore leave either - * one set; restoring the saved values unwinds only this subtransaction's - * firing. - * - * Restoring (rather than zeroing/clearing) matters because a - * subtransaction can begin and end while an outer query's triggers are - * firing -- for instance a batch callback whose user-supplied cast or - * equality function runs DML in a BEGIN ... EXCEPTION block. There - * firing_depth is positive and firing_batch_callbacks is true; forcing - * them to 0/false would corrupt the outer firing - * (FireAfterTriggerBatchCallbacks() asserts firing_depth > 0, and - * clearing the guard would defeat its re-entrancy check). - */ - afterTriggers.firing_depth = afterTriggers.trans_stack[my_level].firing_depth; - afterTriggers.firing_batch_callbacks = - afterTriggers.trans_stack[my_level].firing_batch_callbacks; } /* @@ -5785,7 +5693,6 @@ AfterTriggerEnlargeQueryState(void) qs->events.tailfree = NULL; qs->fdw_tuplestore = NULL; qs->tables = NIL; - qs->batch_callbacks = NIL; ++init_depth; } @@ -6135,7 +6042,6 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) AfterTriggerEventList *events = &afterTriggers.events; bool snapshot_set = false; - afterTriggers.firing_depth++; while (afterTriggerMarkEvents(events, NULL, true)) { CommandId firing_id = afterTriggers.firing_counter++; @@ -6165,14 +6071,6 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) break; /* all fired */ } - /* - * Flush any fast-path batches accumulated by the triggers just fired. - */ - FireAfterTriggerBatchCallbacks(afterTriggers.batch_callbacks); - afterTriggers.firing_depth--; - list_free_deep(afterTriggers.batch_callbacks); - afterTriggers.batch_callbacks = NIL; - if (snapshot_set) PopActiveSnapshot(); } @@ -6869,99 +6767,3 @@ check_modified_virtual_generated(TupleDesc tupdesc, HeapTuple tuple) return tuple; } - -/* - * RegisterAfterTriggerBatchCallback - * Register a function to be called when the current trigger-firing - * batch completes. - * - * Must be called from within a trigger function's execution context - * (i.e., while afterTriggers state is active). - * - * The callback list is cleared after invocation, so the caller must - * re-register for each new batch if needed. - */ -void -RegisterAfterTriggerBatchCallback(AfterTriggerBatchCallback callback, - void *arg) -{ - AfterTriggerCallbackItem *item; - MemoryContext oldcxt; - - /* - * Allocate in TopTransactionContext so the item survives for the duration - * of the batch, which may span multiple trigger invocations. - * - * Must be called while afterTriggers is active; callbacks registered - * outside a trigger-firing context would never fire. - */ - Assert(afterTriggers.firing_depth > 0); - Assert(!afterTriggers.firing_batch_callbacks); - oldcxt = MemoryContextSwitchTo(TopTransactionContext); - item = palloc(sizeof(AfterTriggerCallbackItem)); - item->callback = callback; - item->arg = arg; - if (afterTriggers.query_depth >= 0) - { - AfterTriggersQueryData *qs = - &afterTriggers.query_stack[afterTriggers.query_depth]; - - qs->batch_callbacks = lappend(qs->batch_callbacks, item); - } - else - afterTriggers.batch_callbacks = - lappend(afterTriggers.batch_callbacks, item); - MemoryContextSwitchTo(oldcxt); -} - -/* - * FireAfterTriggerBatchCallbacks - * Invoke all callbacks in the given list. - * - * Memory cleanup of the list and its items is handled by the caller - * (AfterTriggerFreeQuery for query-level callbacks, AfterTriggerEndXact - * for top-level deferred callbacks). - */ -static void -FireAfterTriggerBatchCallbacks(List *callbacks) -{ - ListCell *lc; - - Assert(afterTriggers.firing_depth > 0); - afterTriggers.firing_batch_callbacks = true; - foreach(lc, callbacks) - { - AfterTriggerCallbackItem *item = lfirst(lc); - - item->callback(item->arg); - } - afterTriggers.firing_batch_callbacks = false; -} - -/* - * AfterTriggerIsActive - * Returns true if we're inside the after-trigger framework where - * registered batch callbacks will actually be invoked. - * - * This is false during validateForeignKeyConstraint(), which calls - * RI trigger functions directly outside the after-trigger framework. - */ -bool -AfterTriggerIsActive(void) -{ - return afterTriggers.firing_depth > 0; -} - -/* - * AfterTriggerCurrentQueryDepth - * Return the current after-trigger query nesting depth. - * - * Lets a batch-callback registrant (e.g. the RI fast path) associate cached - * state with the firing cycle that created it, so a nested cycle's callback - * acts only on its own entries. Returns -1 outside any query level. - */ -int -AfterTriggerCurrentQueryDepth(void) -{ - return afterTriggers.query_depth; -} diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 439376a6cc2..63c8a13b9e3 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -219,84 +219,6 @@ typedef struct RI_CompareHashEntry FmgrInfo cast_func_finfo; /* in case we must coerce input */ } RI_CompareHashEntry; -/* - * Maximum number of FK rows buffered before flushing. - * - * Larger batches amortize per-flush overhead and let the SK_SEARCHARRAY - * path walk more leaf pages in a single sorted traversal. But each - * buffered row is a materialized HeapTuple in flush_cxt, and the matched[] - * scan in ri_FastPathFlushArray() is O(batch_size) per index match. - * Benchmarking showed little difference between 16 and 64, with 256 - * consistently slower. 64 is a reasonable default. - */ -#define RI_FASTPATH_BATCH_SIZE 64 - -/* - * RI_FastPathKey - * Hash key for an RI_FastPathEntry. - * - * A constraint can be checked in nested trigger-firing cycles. Each cycle - * must have a separate entry so that its rows are checked with that cycle's - * snapshot and its resources are released by that cycle's callback. - */ -typedef struct RI_FastPathKey -{ - Oid conoid; /* pg_constraint OID */ - int query_depth; /* after-trigger query depth */ -} RI_FastPathKey; - -/* - * RI_FastPathEntry - * Per-constraint, per-firing-cycle cache of resources needed by - * ri_FastPathBatchFlush(). - * - * Created lazily by ri_FastPathGetEntry() on first use within a - * trigger-firing batch and torn down by ri_FastPathTeardown() at batch end. - * - * FK tuples are buffered in batch[] across trigger invocations and - * flushed when the buffer fills or the batch ends. - * - * RI_FastPathEntry is not subject to cache invalidation. The cached - * relations are held open with locks for the transaction duration, preventing - * relcache invalidation. The entry itself is torn down at batch end by - * ri_FastPathEndBatch(); on abort, ResourceOwner releases the cached - * relations and AtEOXact_RI() NULLs the static cache pointer to prevent - * any subsequent access. - */ -typedef struct RI_FastPathEntry -{ - RI_FastPathKey key; /* hash key */ - Oid fk_relid; /* for ri_FastPathEndBatch() */ - Relation pk_rel; - Relation idx_rel; - TupleTableSlot *pk_slot; - TupleTableSlot *fk_slot; - MemoryContext flush_cxt; /* short-lived context for per-flush work */ - - /* - * TODO: batch[] is HeapTuple[] because the AFTER trigger machinery - * currently passes tuples as HeapTuples. Once trigger infrastructure is - * slotified, this should use a slot array or whatever batched tuple - * storage abstraction exists at that point to be TAM-agnostic. - */ - HeapTuple batch[RI_FASTPATH_BATCH_SIZE]; - int batch_count; - - /* - * true while this entry's batch is being flushed; guards against - * re-entrant ri_FastPathBatchAdd from user code run during the flush. - */ - bool flushing; - - /* - * Subtransaction whose resource owner opened this entry's relations. - * AtEOSubXact_RI() drops only entries matching an aborting subxact, so a - * subxact abort during outer-level trigger firing leaves the outer batch - * intact. - */ - SubTransactionId subid; -} RI_FastPathEntry; - /* * Local data */ @@ -305,9 +227,6 @@ static HTAB *ri_query_cache = NULL; static HTAB *ri_compare_cache = NULL; static dclist_head ri_constraint_cache_valid_list; -static HTAB *ri_fastpath_cache = NULL; -static bool ri_fastpath_flushing = false; - /* * FastPathMeta objects detached from their cache entry by invalidation, but * possibly still referenced by an RI check further up the stack. Released @@ -365,18 +284,6 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_FastPathCheck(RI_ConstraintInfo *riinfo, Relation fk_rel, TupleTableSlot *newslot); -static void ri_FastPathBatchAdd(RI_ConstraintInfo *riinfo, - Relation fk_rel, TupleTableSlot *newslot); -static void ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel, - RI_ConstraintInfo *riinfo); -static int ri_FastPathFlushArray(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, - const RI_ConstraintInfo *riinfo, - FastPathMeta *fpmeta, Relation fk_rel, - Snapshot snapshot, IndexScanDesc scandesc); -static int ri_FastPathFlushLoop(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, - const RI_ConstraintInfo *riinfo, - FastPathMeta *fpmeta, Relation fk_rel, - Snapshot snapshot, IndexScanDesc scandesc); static bool ri_FastPathProbeOne(Relation pk_rel, Relation idx_rel, IndexScanDesc scandesc, TupleTableSlot *slot, Snapshot snapshot, const RI_ConstraintInfo *riinfo, @@ -400,10 +307,6 @@ pg_noreturn static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, int queryno, bool is_restrict, bool partgone); -static RI_FastPathEntry *ri_FastPathGetEntry(const RI_ConstraintInfo *riinfo, - Relation fk_rel); -static void ri_FastPathEndBatch(void *arg); -static void ri_FastPathTeardown(int depth); /* @@ -514,32 +417,12 @@ RI_FKey_check(TriggerData *trigdata) * lock. This is semantically equivalent to the SPI path below but avoids * the per-row executor overhead. * - * ri_FastPathBatchAdd() and ri_FastPathCheck() report the violation - * themselves if no matching PK row is found, so they only return on - * success. + * ri_FastPathCheck() reports the violation itself if no matching PK row + * is found, so it only returns on success. */ if (ri_fastpath_is_applicable(riinfo)) { - if (AfterTriggerIsActive() && !ri_fastpath_flushing) - { - /* Batched path: buffer and probe in groups */ - ri_FastPathBatchAdd(riinfo, fk_rel, newslot); - } - else - { - /* - * Per-row path, used when batching is not applicable: - * - * - ALTER TABLE validation, where no after-trigger firing is - * active; - * - * - a re-entrant check from user cast/operator code running - * during a batch flush, since adding a cache entry while - * ri_FastPathEndBatch is iterating the cache could leave it - * unflushed. - */ - ri_FastPathCheck(riinfo, fk_rel, newslot); - } + ri_FastPathCheck(riinfo, fk_rel, newslot); return PointerGetDatum(NULL); } @@ -2888,7 +2771,7 @@ ri_FastPathCheck(RI_ConstraintInfo *riinfo, pk_rel = table_open(riinfo->pk_relid, RowShareLock); - /* Re-read the constraint under that lock; see ri_FastPathGetEntry(). */ + /* Re-read the constraint under that lock. */ riinfo = ri_LoadConstraintInfo(riinfo->constraint_id); idx_rel = index_open(riinfo->conindid, AccessShareLock); @@ -2939,401 +2822,6 @@ ri_FastPathCheck(RI_ConstraintInfo *riinfo, table_close(pk_rel, NoLock); } -/* - * ri_FastPathBatchAdd - * Buffer a FK row for batched probing. - * - * Adds the row to the batch buffer. When the buffer is full, flushes all - * buffered rows by probing the PK index. Any violation is reported - * immediately during the flush via ri_ReportViolation (which does not return). - * - * Uses the per-batch cache (RI_FastPathEntry) to avoid per-row relation - * open/close, slot creation, etc. - * - * The batch is also flushed at end of trigger-firing cycle via - * ri_FastPathEndBatch(). - */ -static void -ri_FastPathBatchAdd(RI_ConstraintInfo *riinfo, - Relation fk_rel, TupleTableSlot *newslot) -{ - RI_FastPathEntry *fpentry = ri_FastPathGetEntry(riinfo, fk_rel); - - /* - * If this entry is already being flushed, a cast function or an operator - * invoked during the flush has re-entered with DML on the same FK. Fall - * back to the per-row path rather than touching the batch array, which is - * mid-flush. - */ - if (unlikely(fpentry->flushing)) - { - ri_FastPathCheck(riinfo, fk_rel, newslot); - return; - } - - /* - * A batch is filled and flushed within a single trigger-firing cycle, so - * every row added to an entry comes from the subtransaction that created - * it. AtEOSubXact_RI() relies on this to identify an aborting - * subtransaction's entries by the subid stamped at entry creation. - */ - Assert(fpentry->subid == GetCurrentSubTransactionId()); - - /* - * Buffer the row. A full batch is flushed below and re-entry is handled - * above, so there is always room here; the bounds check just guards the - * array write. - */ - if (fpentry->batch_count < RI_FASTPATH_BATCH_SIZE) - { - MemoryContext oldcxt = MemoryContextSwitchTo(fpentry->flush_cxt); - - fpentry->batch[fpentry->batch_count] = - ExecCopySlotHeapTuple(newslot); - fpentry->batch_count++; - MemoryContextSwitchTo(oldcxt); - } - else - elog(ERROR, "RI fast-path batch unexpectedly full"); - - /* Flush as soon as the batch is full. */ - if (fpentry->batch_count == RI_FASTPATH_BATCH_SIZE) - ri_FastPathBatchFlush(fpentry, fk_rel, riinfo); -} - -/* - * ri_FastPathBatchFlush - * Flush all buffered FK rows by probing the PK index. - * - * Dispatches to ri_FastPathFlushArray() for single-column FKs - * (using SK_SEARCHARRAY) or ri_FastPathFlushLoop() for multi-column - * FKs (per-row probing). Violations are reported immediately via - * ri_ReportViolation(), which does not return. - */ -static void -ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel, - RI_ConstraintInfo *riinfo) -{ - Relation pk_rel = fpentry->pk_rel; - Relation idx_rel = fpentry->idx_rel; - TupleTableSlot *fk_slot = fpentry->fk_slot; - Snapshot snapshot; - IndexScanDesc scandesc; - Oid saved_userid; - int saved_sec_context; - MemoryContext oldcxt; - FastPathMeta *fpmeta; - int violation_index; - - if (fpentry->batch_count == 0) - return; - - /* - * CCI and security context switch are done once for the entire batch. - * Per-row CCI is unnecessary because by the time a flush runs, all AFTER - * triggers for the buffered rows have already fired (trigger invocations - * strictly alternate per row), so a single CCI advances past all their - * effects. Per-row security context switch is unnecessary because each - * row's probe runs entirely as the PK table owner, same as the SPI path - * -- the only difference is that the SPI path sets and restores the - * context per row whereas we do it once around the whole batch. - */ - CommandCounterIncrement(); - snapshot = RegisterSnapshot(GetTransactionSnapshot()); - - /* - * build_index_scankeys() may palloc cast results for cross-type FKs. Use - * the entry's short-lived flush context so these don't accumulate across - * batches. - */ - oldcxt = MemoryContextSwitchTo(fpentry->flush_cxt); - - GetUserIdAndSecContext(&saved_userid, &saved_sec_context); - SetUserIdAndSecContext(RelationGetForm(pk_rel)->relowner, - saved_sec_context | - SECURITY_LOCAL_USERID_CHANGE | - SECURITY_NOFORCE_RLS); - - /* - * Check that the current user has permission to access pk_rel. Done here - * rather than at entry creation so that permission changes between - * flushes are respected, matching the per-row behavior of the SPI path, - * albeit checked once per flush rather than once per row, like in - * ri_FastPathCheck(). - */ - ri_CheckPermissions(pk_rel); - - /* - * Begin the scan under the switched user id, so that any access method - * code invoked by index_beginscan() runs as the PK relation's owner. For - * btree this has no functional consequence, but it keeps the ordering - * correct for out-of-tree access methods. - */ - scandesc = index_beginscan(pk_rel, idx_rel, snapshot, NULL, - riinfo->nkeys, 0, SO_NONE); - - if (riinfo->fpmeta == NULL) - { - /* Reload to ensure it's valid. */ - riinfo = ri_LoadConstraintInfo(riinfo->constraint_id); - ri_populate_fastpath_metadata(riinfo, fk_rel, idx_rel); - } - Assert(riinfo->fpmeta); - - /* - * Take our own reference to the metadata for the duration of the flush. - * The probe below runs user-defined cast and equality functions, which - * can accept invalidation messages; InvalidateConstraintCacheCallBack() - * then clears riinfo->fpmeta, so re-reading it partway through the batch - * would find NULL. The object itself stays valid until AtEOXact_RI(). - */ - fpmeta = riinfo->fpmeta; - - /* - * The probe runs user-defined cast and equality functions. Set the - * flushing flag around it so a re-entrant ri_FastPathBatchAdd on this - * entry takes the per-row path, and clear it even on error so the entry - * is reusable if the error is caught by a savepoint. - */ - Assert(!fpentry->flushing); - fpentry->flushing = true; - PG_TRY(); - { - /* Skip array overhead for single-row batches. */ - if (riinfo->nkeys == 1 && fpentry->batch_count > 1) - violation_index = ri_FastPathFlushArray(fpentry, fk_slot, riinfo, - fpmeta, fk_rel, snapshot, - scandesc); - else - violation_index = ri_FastPathFlushLoop(fpentry, fk_slot, riinfo, - fpmeta, fk_rel, snapshot, - scandesc); - } - PG_FINALLY(); - { - fpentry->flushing = false; - fpentry->batch_count = 0; - } - PG_END_TRY(); - - SetUserIdAndSecContext(saved_userid, saved_sec_context); - UnregisterSnapshot(snapshot); - index_endscan(scandesc); - - if (violation_index >= 0) - { - ExecStoreHeapTuple(fpentry->batch[violation_index], fk_slot, false); - ri_ReportViolation(riinfo, pk_rel, fk_rel, - fk_slot, NULL, - RI_PLAN_CHECK_LOOKUPPK, false, false); - } - - MemoryContextReset(fpentry->flush_cxt); - MemoryContextSwitchTo(oldcxt); -} - -/* - * ri_FastPathFlushLoop - * Multi-column fallback: probe the index once per buffered row. - * - * Used for composite foreign keys where SK_SEARCHARRAY does not - * apply, and also for single-row batches of single-column FKs where - * the array overhead is not worth it. - * - * Returns the index of the first violating row in the batch array, or -1 if - * all rows are valid. - */ -static int -ri_FastPathFlushLoop(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, - const RI_ConstraintInfo *riinfo, FastPathMeta *fpmeta, - Relation fk_rel, Snapshot snapshot, - IndexScanDesc scandesc) -{ - Relation pk_rel = fpentry->pk_rel; - Relation idx_rel = fpentry->idx_rel; - TupleTableSlot *pk_slot = fpentry->pk_slot; - Datum pk_vals[INDEX_MAX_KEYS]; - char pk_nulls[INDEX_MAX_KEYS]; - ScanKeyData skey[INDEX_MAX_KEYS]; - bool found = true; - - for (int i = 0; i < fpentry->batch_count; i++) - { - ExecStoreHeapTuple(fpentry->batch[i], fk_slot, false); - ri_ExtractValues(fk_rel, fk_slot, riinfo, false, pk_vals, pk_nulls); - build_index_scankeys(riinfo, fpmeta, idx_rel, pk_vals, pk_nulls, skey); - - found = ri_FastPathProbeOne(pk_rel, idx_rel, scandesc, pk_slot, - snapshot, riinfo, skey, riinfo->nkeys); - - /* Report first unmatched row */ - if (!found) - return i; - } - - /* All pass. */ - return -1; -} - -/* - * ri_FastPathFlushArray - * Single-column fast path using SK_SEARCHARRAY. - * - * Builds an array of FK values and does one index scan with - * SK_SEARCHARRAY. The index AM sorts and deduplicates the array - * internally, then walks matching leaf pages in order. Each - * matched PK tuple is locked and rechecked as before; a matched[] - * bitmap tracks which batch items were satisfied. - * - * Returns the index of the first violating row in the batch array, or -1 if - * all rows are valid. - */ -static int -ri_FastPathFlushArray(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, - const RI_ConstraintInfo *riinfo, FastPathMeta *fpmeta, - Relation fk_rel, Snapshot snapshot, - IndexScanDesc scandesc) -{ - Relation pk_rel = fpentry->pk_rel; - Relation idx_rel = fpentry->idx_rel; - TupleTableSlot *pk_slot = fpentry->pk_slot; - Datum search_vals[RI_FASTPATH_BATCH_SIZE]; - bool matched[RI_FASTPATH_BATCH_SIZE]; - int nvals = fpentry->batch_count; - Datum pk_vals[INDEX_MAX_KEYS]; - char pk_nulls[INDEX_MAX_KEYS]; - ScanKeyData skey[1]; - FmgrInfo *cast_func_finfo; - FmgrInfo *eq_opr_finfo; - Oid elem_type; - int16 elem_len; - bool elem_byval; - char elem_align; - ArrayType *arr; - - Assert(fpmeta); - - memset(matched, 0, nvals * sizeof(bool)); - - /* - * Extract FK values, casting to the operator's expected input type if - * needed (e.g. int8 FK -> int4 for int48eq). - */ - cast_func_finfo = &fpmeta->cast_func_finfo[0]; - eq_opr_finfo = &fpmeta->eq_opr_finfo[0]; - for (int i = 0; i < nvals; i++) - { - ExecStoreHeapTuple(fpentry->batch[i], fk_slot, false); - ri_ExtractValues(fk_rel, fk_slot, riinfo, false, pk_vals, pk_nulls); - - /* Cast if needed (e.g. int8 FK -> numeric PK) */ - if (OidIsValid(cast_func_finfo->fn_oid)) - search_vals[i] = FunctionCall3(cast_func_finfo, - pk_vals[0], - Int32GetDatum(-1), - BoolGetDatum(false)); - else - search_vals[i] = pk_vals[0]; - } - - /* - * Array element type must match the operator's right-hand input type, - * which is what the index comparison expects on the search side. - * ri_populate_fastpath_metadata() stores exactly this via - * get_op_opfamily_properties(), which returns the operator's right-hand - * type as the subtype for cross-type operators (e.g. int8 for int48eq) - * and the common type for same-type operators. - */ - elem_type = fpmeta->subtypes[0]; - Assert(OidIsValid(elem_type)); - get_typlenbyvalalign(elem_type, &elem_len, &elem_byval, &elem_align); - - arr = construct_array(search_vals, nvals, - elem_type, elem_len, elem_byval, elem_align); - - /* - * Build scan key with SK_SEARCHARRAY. The index AM code will internally - * sort and deduplicate, then walk leaf pages in order. - * - * ri_fastpath_is_applicable() restricts the fast path to btree indexes, - * which support SK_SEARCHARRAY. - * - * This path handles single-column FKs only, so index_attnos[0] == 1. - */ - Assert(idx_rel->rd_indam->amsearcharray); - Assert(fpmeta->index_attnos[0] == 1); - ScanKeyEntryInitialize(&skey[0], - SK_SEARCHARRAY, - fpmeta->index_attnos[0], - fpmeta->strats[0], - fpmeta->subtypes[0], - idx_rel->rd_indcollation[fpmeta->index_attnos[0] - 1], - fpmeta->regops[0], - PointerGetDatum(arr)); - - index_rescan(scandesc, skey, 1, NULL, 0); - - /* - * Walk all matches. The index AM returns them in index order. For each - * match, find which batch item(s) it satisfies. - */ - while (index_getnext_slot(scandesc, ForwardScanDirection, pk_slot)) - { - Datum found_val; - bool found_null; - - /* - * No key recheck is needed here, so we have no use for - * concurrently_updated. Unlike ri_FastPathProbeOne(), which takes - * the index scan's word for it that the tuple matches, this path - * compares the key against every buffered FK value below, and it does - * so using found_val, which is read out of the version we actually - * locked. A concurrent key update is therefore caught by that - * comparison: the batch item that led us to this tuple is left - * unmatched and reported as a violation. - */ - if (!ri_LockPKTuple(pk_rel, pk_slot, snapshot, NULL)) - continue; - - /* - * Extract the PK value from the matched and locked tuple. - * - * A foreign key may reference a nullable unique column, not just a - * NOT NULL primary key. If ri_LockPKTuple() chased an update chain - * to a version whose referenced key is now NULL, that version cannot - * equal any buffered (non-null) FK value, so skip it. This mirrors - * the SPI path, where the requalifying "pkatt = $n" yields NULL and - * the row is not returned. - */ - found_val = slot_getattr(pk_slot, riinfo->pk_attnums[0], &found_null); - if (found_null) - continue; - - /* - * Linear scan to mark all batch items matching this PK value. - * O(batch_size) per match, O(batch_size^2) worst case -- fine for the - * current batch size of 64. - */ - for (int i = 0; i < nvals; i++) - { - if (!matched[i] && - DatumGetBool(FunctionCall2Coll(eq_opr_finfo, - idx_rel->rd_indcollation[0], - found_val, - search_vals[i]))) - matched[i] = true; - } - } - - /* Report first unmatched row */ - for (int i = 0; i < nvals; i++) - if (!matched[i]) - return i; - - /* All pass. */ - return -1; -} - /* * ri_FastPathProbeOne * Probe the PK index for one set of scan keys, lock the matching @@ -3684,6 +3172,38 @@ ri_populate_fastpath_metadata(RI_ConstraintInfo *riinfo, MemoryContextSwitchTo(oldcxt); } +/* + * AtEOXact_RI + * End-of-transaction cleanup for referential integrity. + * + * Currently this only releases fast-path metadata detached during the + * transaction. InvalidateConstraintCacheCallBack() cannot free a + * FastPathMeta when it detaches one, because an RI check further up the + * stack may still hold a pointer into it. It queues them on + * ri_fpmeta_dead_list instead, and we release them here, where no such + * reference can exist. isCommit is accepted for consistency with the + * other AtEOXact_* routines but is not used: the release is the same on + * the commit and the abort path. + * + * There is no AtEOSubXact_RI() counterpart. Nothing here is scoped to a + * subtransaction: a detached FastPathMeta stays reachable from the dead + * list whichever subtransaction detached it, and a check holding a pointer + * into one may be running at an outer level, so releasing at subtransaction + * end would be unsafe as well as unnecessary. + */ +void +AtEOXact_RI(bool isCommit) +{ + while (ri_fpmeta_dead_list != NULL) + { + FastPathMeta *dead = ri_fpmeta_dead_list; + + ri_fpmeta_dead_list = dead->next_dead; + MemoryContextDelete(dead->scratch_cxt); + pfree(dead); + } +} + /* * Extract fields from a tuple into Datum/nulls arrays */ @@ -4309,381 +3829,3 @@ RI_FKey_trigger_type(Oid tgfoid) return RI_TRIGGER_NONE; } - -/* - * ri_FastPathEndBatch - * Flush remaining rows and tear down cached state. - * - * Registered as an AfterTriggerBatchCallback. Note: the flush can - * do real work (CCI, security context switch, index probes) and can - * throw ERROR on a constraint violation. If that happens, - * ri_FastPathTeardown never runs; ResourceOwner releases the cached - * relations and AtEOXact_RI() resets the static state on the abort path. - */ -static void -ri_FastPathEndBatch(void *arg) -{ - HASH_SEQ_STATUS status; - RI_FastPathEntry *entry; - int my_depth = (int) (intptr_t) arg; - - if (ri_fastpath_cache == NULL) - return; - - /* - * Set a flag for the duration of the scan so that any FK check triggered - * by user cast or operator code during a flush takes the per-row path - * instead of adding a new entry to the cache we are iterating. A new - * entry could land in an already-scanned bucket and then be torn down - * unflushed below. - * - * The flush can throw ERROR (a reported constraint violation, or an error - * from the user code it runs). In that case ri_FastPathTeardown below is - * skipped; the ResourceOwner and the transaction-end callback handle - * resource cleanup on the abort path. The PG_FINALLY only resets the - * flag and deliberately does not attempt teardown. - */ - Assert(!ri_fastpath_flushing); - ri_fastpath_flushing = true; - PG_TRY(); - { - hash_seq_init(&status, ri_fastpath_cache); - while ((entry = hash_seq_search(&status)) != NULL) - { - /* Flush only entries created in the cycle now ending. */ - if (entry->key.query_depth == my_depth && entry->batch_count > 0) - { - Relation fk_rel = table_open(entry->fk_relid, AccessShareLock); - RI_ConstraintInfo *riinfo; - - riinfo = ri_LoadConstraintInfo(entry->key.conoid); - - ri_FastPathBatchFlush(entry, fk_rel, riinfo); - table_close(fk_rel, NoLock); - } - } - } - PG_FINALLY(); - { - ri_fastpath_flushing = false; - } - PG_END_TRY(); - - /* - * Release this cycle's entries and remove them from the cache; leave - * outer cycles' entries for their own callbacks. Destroy the cache once - * empty. - */ - ri_FastPathTeardown(my_depth); -} - -/* - * ri_FastPathTeardown - * Release and remove the cached entries of one firing cycle, and drop - * the cache once it holds no more entries. - * - * Called from ri_FastPathEndBatch() with the depth of the cycle that is - * ending: it releases only that cycle's entries, leaving an outer cycle's - * still-live entries for their own callbacks. The cache (and its static - * pointer) go away once the last entry is removed. - */ -static void -ri_FastPathTeardown(int depth) -{ - HASH_SEQ_STATUS status; - RI_FastPathEntry *entry; - - if (ri_fastpath_cache == NULL) - return; - - hash_seq_init(&status, ri_fastpath_cache); - while ((entry = hash_seq_search(&status)) != NULL) - { - if (entry->key.query_depth != depth) - continue; - if (entry->idx_rel) - index_close(entry->idx_rel, NoLock); - if (entry->pk_rel) - table_close(entry->pk_rel, NoLock); - if (entry->pk_slot) - ExecDropSingleTupleTableSlot(entry->pk_slot); - if (entry->fk_slot) - ExecDropSingleTupleTableSlot(entry->fk_slot); - if (entry->flush_cxt) - MemoryContextDelete(entry->flush_cxt); - hash_search(ri_fastpath_cache, &entry->key, HASH_REMOVE, NULL); - } - - if (hash_get_num_entries(ri_fastpath_cache) == 0) - { - hash_destroy(ri_fastpath_cache); - ri_fastpath_cache = NULL; - ri_fastpath_flushing = false; - } -} - -/* - * AtEOXact_RI - * Reset fast-path batching state at end of transaction. - * - * Called from CommitTransaction() and PrepareTransaction() with isCommit - * true, and from AbortTransaction() with isCommit false. - * - * By the time we get here on a clean commit or prepare, the fast-path cache - * has already been flushed and torn down by ri_FastPathEndBatch() (an - * AfterTriggerBatchCallback fired from AfterTriggerFireDeferred(), well before - * this point), so the static pointers are already clear and the reset below is - * a no-op. A surviving cache at commit means a trigger batch was never - * flushed, which would have silently skipped FK checks, so we complain. - * - * On abort, ri_FastPathEndBatch()/ri_FastPathTeardown() may not have run (a - * flush can error out partway): the ResourceOwner releases the cached - * relations and the TopTransactionContext reset frees the cache memory, but - * the process-local static pointers below would dangle into the next - * transaction. This resets them so they don't. - * - * The reset touches only backend-local static state (no relations, locks, - * buffers or catalog access), so it has no ordering dependency on the - * surrounding ResourceOwnerRelease() / AtEOXact_* steps. - */ -void -AtEOXact_RI(bool isCommit) -{ - /* - * The cache must be empty on a clean commit or prepare; a survivor means - * a trigger batch went unflushed. Assert for assert-enabled builds and, - * since the transaction is already committed by now and FK checks may - * have been skipped, also warn in production builds. - */ - Assert(ri_fastpath_cache == NULL || !isCommit); - if (isCommit && ri_fastpath_cache != NULL) - elog(WARNING, "RI fast-path cache not flushed at end of transaction"); - - /* - * Clear the static pointers/flags. The cache memory lives in - * TopTransactionContext and is freed by the end-of-transaction - * memory-context reset; here we only drop the references to it. - */ - ri_fastpath_cache = NULL; - - /* - * Also clear the in-flush flag. ri_FastPathEndBatch() already clears it - * via PG_FINALLY, so this is just defensive: it keeps a stale flag from - * surviving into the next transaction should any future path leave it - * set. - */ - ri_fastpath_flushing = false; - - /* - * Release fast-path metadata detached during this transaction by - * InvalidateConstraintCacheCallBack(). We are past every RI check that - * could still hold a pointer into one of these, so freeing here is safe - * on both the commit and the abort path. - */ - while (ri_fpmeta_dead_list != NULL) - { - FastPathMeta *dead = ri_fpmeta_dead_list; - - ri_fpmeta_dead_list = dead->next_dead; - MemoryContextDelete(dead->scratch_cxt); - pfree(dead); - } -} - -/* - * AtEOSubXact_RI - * Reset fast-path batching state at subtransaction end. - * - * Called from CommitSubTransaction() with isCommit true and from - * AbortSubTransaction() with isCommit false, in both cases after the - * subtransaction's ResourceOwnerRelease(). - * - * Fast-path cache entries are normally flushed and removed at the end of - * their trigger-firing cycle, and the cache is destroyed when its last entry - * is removed. Thus, at a normal subtransaction boundary this is a no-op. - * - * The exception is a batch flush that errors out partway and is caught by this - * subtransaction (e.g. a PL/pgSQL EXCEPTION block): ri_FastPathEndBatch()'s - * teardown was skipped, so the cache still contains entries whose relations - * were opened under this subtransaction's resource owner. That owner has - * just released those relations, making the entries stale. Remove those - * entries so a later firing cycle cannot reuse them. Entries belonging to - * outer subtransactions remain valid and are preserved. - * - * The remaining slot storage and per-entry flush contexts are reclaimed when - * TopTransactionContext is reset at top-level transaction end. - */ -void -AtEOSubXact_RI(bool isCommit, SubTransactionId mySubid, - SubTransactionId parentSubid) -{ - HASH_SEQ_STATUS status; - RI_FastPathEntry *entry; - long remaining; - - if (ri_fastpath_cache == NULL) - return; - - /* Process only entries belonging to the ending subtransaction. */ - hash_seq_init(&status, ri_fastpath_cache); - while ((entry = hash_seq_search(&status)) != NULL) - { - if (entry->subid != mySubid) - continue; - - if (isCommit) - { - /* - * A committing subxact's entry should already have been flushed - * and torn down at its statement's end (ri_FastPathEndBatch()), - * so we don't expect to find one here. If we do, reassign it to - * the parent so it's still cleaned up rather than left under a - * subxact id that no longer exists. - */ - Assert(false); - entry->subid = parentSubid; - } - else - hash_search(ri_fastpath_cache, &entry->key, HASH_REMOVE, NULL); - } - - /* If that emptied the cache, drop it so the next batch starts clean. */ - remaining = hash_get_num_entries(ri_fastpath_cache); - if (remaining == 0) - { - hash_destroy(ri_fastpath_cache); - ri_fastpath_cache = NULL; - ri_fastpath_flushing = false; - } -} - -/* - * ri_FastPathGetEntry - * Look up or create a per-batch cache entry for the given constraint. - * - * On first call for a constraint within a batch: opens pk_rel and the index, - * allocates slots for both FK row and the looked up PK row, and registers the - * cleanup callback. - * - * On subsequent calls: returns the existing entry. - */ -static RI_FastPathEntry * -ri_FastPathGetEntry(const RI_ConstraintInfo *riinfo, Relation fk_rel) -{ - RI_FastPathKey key; - RI_FastPathEntry *entry; - bool found; - int cur_depth = AfterTriggerCurrentQueryDepth(); - - key.conoid = riinfo->constraint_id; - key.query_depth = cur_depth; - - /* Create hash table on first use in this batch */ - if (ri_fastpath_cache == NULL) - { - HASHCTL ctl; - - ctl.keysize = sizeof(RI_FastPathKey); - ctl.entrysize = sizeof(RI_FastPathEntry); - ctl.hcxt = TopTransactionContext; - ri_fastpath_cache = hash_create("RI fast-path cache", - 16, - &ctl, - HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); - } - - entry = hash_search(ri_fastpath_cache, &key, - HASH_ENTER, &found); - - if (!found) - { - MemoryContext oldcxt; - - /* - * Zero out non-key fields so ri_FastPathTeardown is safe if we error - * out during partial initialization below. - */ - memset(((char *) entry) + offsetof(RI_FastPathEntry, pk_rel), 0, - sizeof(RI_FastPathEntry) - offsetof(RI_FastPathEntry, pk_rel)); - - oldcxt = MemoryContextSwitchTo(TopTransactionContext); - - entry->fk_relid = RelationGetRelid(fk_rel); - - /* - * Open PK table and its unique index. - * - * RowShareLock on pk_rel matches what the SPI path's SELECT ... FOR - * KEY SHARE would acquire as a relation-level lock. AccessShareLock - * on the index is standard for index scans. - * - * We don't release these locks until end of transaction, matching SPI - * behavior. - */ - - INJECTION_POINT("ri-before-pk-lock", NULL); - - entry->pk_rel = table_open(riinfo->pk_relid, RowShareLock); - - /* - * conindid may have been read before we took that lock, and REINDEX - * CONCURRENTLY moves a constraint to a new index. Re-read it now: - * LockRelationOid() processes invalidation messages after acquiring - * the lock, so we either see the new index, or an old one that cannot - * be marked dead or dropped until this transaction ends. - */ - riinfo = ri_LoadConstraintInfo(riinfo->constraint_id); - - entry->idx_rel = index_open(riinfo->conindid, AccessShareLock); - entry->pk_slot = table_slot_create(entry->pk_rel, NULL); - - /* - * Must be TTSOpsHeapTuple because ExecStoreHeapTuple() is used to - * load entries from batch[] into this slot for value extraction. - */ - entry->fk_slot = MakeSingleTupleTableSlot(RelationGetDescr(fk_rel), - &TTSOpsHeapTuple); - - entry->flush_cxt = AllocSetContextCreate(TopTransactionContext, - "RI fast path flush temporary context", - ALLOCSET_SMALL_SIZES); - MemoryContextSwitchTo(oldcxt); - - /* - * Register an end-of-batch callback once per firing cycle, passing - * the query depth so the callback flushes only entries belonging to - * that cycle. - */ - { - bool depth_registered = false; - HASH_SEQ_STATUS reg_status; - RI_FastPathEntry *other; - - /* - * An existing entry at this depth means its callback is already - * registered. Ignore the just-created entry, which is already in - * the hash. - */ - hash_seq_init(®_status, ri_fastpath_cache); - while ((other = hash_seq_search(®_status)) != NULL) - { - if (other != entry && other->key.query_depth == cur_depth) - { - depth_registered = true; - hash_seq_term(®_status); - break; - } - } - - if (!depth_registered) - RegisterAfterTriggerBatchCallback(ri_FastPathEndBatch, - (void *) (intptr_t) cur_depth); - } - - entry->flushing = false; - entry->batch_count = 0; - entry->subid = GetCurrentSubTransactionId(); - } - - return entry; -} diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h index fecdb785f35..d5cb16597f4 100644 --- a/src/include/commands/trigger.h +++ b/src/include/commands/trigger.h @@ -289,30 +289,6 @@ extern void RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, extern int RI_FKey_trigger_type(Oid tgfoid); -/* - * Callback type for end-of-trigger-batch callbacks. - * - * Currently used by ri_triggers.c to flush fast-path FK batches and - * clean up associated resources. - * - * Registered via RegisterAfterTriggerBatchCallback(). Invoked when - * the current trigger-firing batch completes: - * - AfterTriggerEndQuery() (immediate constraints) - * - AfterTriggerFireDeferred() (deferred constraints at COMMIT) - * - AfterTriggerSetState() (SET CONSTRAINTS IMMEDIATE) - * - * The callback list is cleared after each batch. Callers must - * re-register if they need to be called again in a subsequent batch. - */ -typedef void (*AfterTriggerBatchCallback) (void *arg); - -extern void RegisterAfterTriggerBatchCallback(AfterTriggerBatchCallback callback, - void *arg); -extern bool AfterTriggerIsActive(void); -extern int AfterTriggerCurrentQueryDepth(void); - extern void AtEOXact_RI(bool isCommit); -extern void AtEOSubXact_RI(bool isCommit, SubTransactionId mySubid, - SubTransactionId parentSubid); #endif /* TRIGGER_H */